Crossfire Mailing List Archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Arrow and thrown objects fixes



Hi,

I'm working on a patch which implements a new stop_item() function that
allows stopping arrows, thrown objects and cones (well, it doesn't stop
cones, but tells the caller that these can't be stopped).  This fixes
the "Arrow had no map" problem, provides a better fix for the "cone
without map" problem and allows picking up arrows and thrown objects
(the FLAG_NO_PICK workaround for these objects isn't necessary
anymore).

It also changes move_arrow() to attack victims before the arrow is
removed.  This fixes a server crash when an arrow attacked a door (with
no_pass 0) that had a spell casting rune in its inventory.

There are other places that still do attacks with removed hitters.  I
think these need to be fixed as well.  On the one hand, I don't see any
reason why removed objects need to be able to attack.  On the other
hand, changing attack_ob(), hit_player(), spring_trap() and all other
functions called from these to handle removed hitters correctly seems
very difficult, especially since future changes must also handle
removed hitters correctly, and a failure to do so is often difficult to
detect.  There is now a check in attack_ob() and hit_player() that the
object is not removed, but it produces a lot of error messages because
there are several places where removed objects attack something.

I'm not sure if objects in inventories should be able to attack.  I
think this is necessary for effects like poison.  But it means that
hit_player() can be called with objects that don't have a map, and not
all code in hit_player() can handle this.

The patch also fixes a bug in thrown_item_effect().  This function
could destroy the hitter, but not tell the caller that it was
destroyed.  Furthermore, it didn't handle destruction of thrown objects
at all, but this is not a problem anymore because move_arrow() now
disassembles thrown objects before attacking.


I'll attach the patch as a unified diff.  The context diff was too
long, it is available from

  http://www.informatik.uni-rostock.de/~echter/cf/patch30b.gz

Changes in current developemnt version of the patch:

common/object.c: get_split_ob():  Fixed handling of removed objects.

common/object.c: decrease_ob_nr():  Added handling of removed objects.

server/apply.c: move_apply():  Modified handling of ARROW and THROWN_OBJ
to use new hit_with_arrow() function.  Skip empty THROWN_OBJs.

server/attack.c: save_throw_object():  Use stop_item().  This fixes
"arrow without map" and "cone without map" errors.

server/attack.c: Split attack_ob() into attack_ob() and
attack_ob_simple().  attack_ob_simple() allows the caller to specify
damage and weapon class independently from the hitter's values (needed
by hit_with_arrow()).

server/attack.c: attack_ob_simple() and hit_player():  Check for removed
attackers.

server/attack.c: hit_with_arrow():  New function.

server/attack.c: thrown_item_effect():  Don't check for objects with
type THROWN_OBJ, hit_with_arrow() handles this now.

server/attack.c: thrown_item_effect():  Bugfix: Check for destroyed
objects.  This fixes a "BUG: hit_player(): freed object" message if the
effect of the thrown item destroyed the thrown item.

server/attack.c: pick_up() and pick_up_object():  Use stop_item().
This allows picking up flying arrows and thrown objects.  Also cleaned
up these functions a bit.
server/player.c: fire_bow(); server/skills.c: do_throw():  Don't set
FLAG_NO_PICK.  Picking up flying arrows and thrown objects is now
implemented correctly by using stop_item().

server/spell_util.c: cast_cone():  Only print debugging message about
cones without walk_on or fly_on if the cone does some damage.

server/spell_util.c: move_cone():  Removed workaround for cones in
inventories.  This is now handled better by stop_item().  If we still
find cone objects without a map, remove these broken objects from the
active list.

server/time.c: stop_item() and fix_stopped_item():  New functions.

server/time.c: fix_stopped_arrow():  New function that does most of what
stop_arrow() did, but in-place (without removing or inserting the arrow).
server/time.c: stop_arrow():  Moved code for sticking objects into the
victim to stick_arrow() in server/attack.c.  Moved code for stopping
an arrow to fix_stopped_arrow().  What's left is a small function that
stops arrows and thrown objects whenever move_arrow() can't move them
anywhere.  Only to be used by move_arrow() now, other code should use
the new functions.

server/time.c: move_arrow():  Skip empty THROWN_OBJs.  Don't hit targets
while moving (when the arrow is removed), but hit them before movement
using new hit_with_arrow() function.  This fixes a server crash if a
thrown object hit a door that had a spell-casting rune in its inventory.
Call hit_with_arrow() before trying to move.  This allows arrows to
attack doors with no_pass 1 and targets sitting on top of a wall, like
the elemental generators in the Tower of Demonology.

socket_item.c: esrv_move_object():  Removed misleading comments.

-- 
Jan

patch30b.unified.gz