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

Re: Trap or apply code broken?



On Sat, Jun 17, 2000 at 02:45:27PM -0700, Peter Mardahl wrote:
> Sometime very recently the trap code or the apply code got
> changed.

Both got changed.  move_rune() used to call spring_trap(), and
FLAG_WALK_ON and FLAG_FLY_ON were unimplemented for runes.  Now they're
implemented (move_apply() calls spring_trap()), and move_rune() only
does some visual effects.  But this broke apply_treasure() because
this function only puts everything in a treasure chest on the map and
doesn't call spring_trap().

Actually, this bug didn't show up until I changed apply_treasure() to
set FLAG_NO_APPLY before removing and inserting the player to put it
on top of all objects.  But this could not be relied on anyway, because
stacking of objects should be handled by common/object.c some day, and
the remove+insert player code will then go completely.

> Applying a chest with a trap or a rune in it should immediately
> set that trap/rune off.

The attached patch fixes this.  It's already applied to the CVS tree.
BTW, now you can get the effect of a partially unpacked chest if a
monster unpacking it was killed by a trap (provided that the server
survives this because move_monster() doesn't handle this situation
correctly).

There was also the problem of not checking if the treasure chest and
the one who opened it still exist after inserting something into the
map, because the insertion might (at least theoretically) trigger
something that destroys the chest before the loop in apply_treasure()
was finished.  This might be related to the bug reports about the
dragon hanger in Stoneville.

-- 
Jan
--- orig/crossfire-0.95.5-cvs3-patch29/server/apply.c	Wed Jun 14 19:52:50 2000
+++ crossfire-0.95.5-cvs3/server/apply.c	Sun Jun 18 21:57:47 2000
@@ -1507,6 +1500,7 @@
 static void apply_treasure (object *op, object *tmp)
 {
     object *treas;
+    tag_t tmp_tag = tmp->count, op_tag = op->count;
 
 /*  Nice side effect of new treasure creation method is that the treasure
     for the chest is done when the chest is created, and put into the chest
@@ -1524,16 +1518,24 @@
       remove_ob(treas);
       draw_find(op,treas);
       treas->x=op->x,treas->y=op->y;
-      insert_ob_in_map(treas,op->map,op);
+      treas = insert_ob_in_map (treas, op->map, op);
+      if (treas && treas->type == RUNE && treas->level
+          && QUERY_FLAG (op, FLAG_ALIVE))
+        spring_trap (treas, op);
+      if (was_destroyed (op, op_tag) || was_destroyed (tmp, tmp_tag))
+        break;
     } while ((treas=tmp->inv)!=NULL);
     
-    decrease_ob(tmp);
+    if ( ! was_destroyed (tmp, tmp_tag) && tmp->inv == NULL)
+      decrease_ob (tmp);
 
-    /* Done to re-stack map with player on top? */
-    SET_FLAG (op, FLAG_NO_APPLY);
-    remove_ob(op);
-    insert_ob_in_map(op,op->map,NULL);
-    CLEAR_FLAG (op, FLAG_NO_APPLY);
+    if ( ! was_destroyed (op, op_tag)) {
+      /* Done to re-stack map with player on top? */
+      SET_FLAG (op, FLAG_NO_APPLY);
+      remove_ob (op);
+      insert_ob_in_map (op, op->map, NULL);
+      CLEAR_FLAG (op, FLAG_NO_APPLY);
+    }
 }