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

CF: Minor hit_map() fixes



This patch is already in the CVS tree.  From the CHANGES file:

server/attack.c: hit_map():  Use was_destroyed() to properly check for
destroyed next object.  Use llevError for error messages.  Skip all
objects that are (no longer) at the specified map position.

-- 
Jan
diff -r -c5 orig/crossfire-0.95.5-cvs3/server/attack.c crossfire-0.95.5-cvs3/server/attack.c
*** orig/crossfire-0.95.5-cvs3/server/attack.c	Fri May 26 14:36:49 2000
--- crossfire-0.95.5-cvs3/server/attack.c	Thu Jun  8 00:09:08 2000
***************
*** 165,192 ****
          return;
      }
  }
  
  int hit_map(object *op,int dir,int type) {
!   object *tmp,*next=NULL;
    int retflag=0;  /* added this flag..  will return 1 if it hits a monster */
!   tag_t tag;
  
    if (QUERY_FLAG (op, FLAG_FREED)) {
      LOG (llevError, "BUG: hit_map(): free object\n");
      return 0;
    }
    
    if (op->head) op=op->head;
  
!   tag = op->count;
  
!   if (!op->map) {
!     LOG(llevDebug,"hit_map called, but %s has no map", op->name);
      return 0;
    }
!   if(out_of_map(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir]))
        return 0;
  
   /* peterm:  a few special cases for special attacktypes --counterspell
          must be out here because it strikes things which are not alive*/
    if(type&AT_COUNTERSPELL) {
--- 165,197 ----
          return;
      }
  }
  
  int hit_map(object *op,int dir,int type) {
!   object *tmp, *next;
!   mapstruct *map;
!   sint16 x, y;
    int retflag=0;  /* added this flag..  will return 1 if it hits a monster */
!   tag_t op_tag, next_tag;
  
    if (QUERY_FLAG (op, FLAG_FREED)) {
      LOG (llevError, "BUG: hit_map(): free object\n");
      return 0;
    }
    
    if (op->head) op=op->head;
  
!   op_tag = op->count;
  
!   if ( ! op->map) {
!     LOG (llevError,"BUG: hit_map(): %s has no map", op->name);
      return 0;
    }
!   map = op->map;
!   x = op->x + freearr_x[dir];
!   y = op->y + freearr_y[dir];
!   if (out_of_map (map, x, y))
        return 0;
  
   /* peterm:  a few special cases for special attacktypes --counterspell
          must be out here because it strikes things which are not alive*/
    if(type&AT_COUNTERSPELL) {
***************
*** 205,239 ****
      shuffle_attack(op,1);  /*1 flag tells it to change the face */
      update_object(op);
      type &= ~AT_CHAOS;
    }
  
!   for(tmp=get_map_ob(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir]);
!       tmp!=NULL;tmp=next)
    {
!     next=tmp->above;
  
!     /* Since we are traversing a stack, it is possible that the stack
!      * gets messed up.  So do some checks.
!      */
!     if (QUERY_FLAG(tmp, FLAG_FREED)) {
! 	LOG(llevDebug,"Warning: in hit_map, found free object\n");
  	break;
      }
!     else if(QUERY_FLAG(tmp,FLAG_ALIVE)) {
        hit_player(tmp,op->stats.dam,op,type);
        retflag |=1;
!       if (was_destroyed (op, tag))
          break;
!     } /* It is possible the object has been relocated to know longer be
!        * on the map (ie, in an icecube.)  If we no longer have a map,
!        * just ignore.
!        */
!     else if(tmp->material && tmp->map)
        save_throw_object(tmp,type);
    }
-   /*if(tmp==NULL) return 0;  This doesn't work, of course */
  #ifdef NO_CONE_PROPOGATE
    return retflag;
  #else
    return 0;
  #endif
--- 210,258 ----
      shuffle_attack(op,1);  /*1 flag tells it to change the face */
      update_object(op);
      type &= ~AT_CHAOS;
    }
  
!   next = get_map_ob (map, x, y);
!   if (next)
!     next_tag = next->count;
!   while (next)
    {
!     if (was_destroyed (next, next_tag)) {
!       /* There may still be objects that were above 'next', but there is no
!        * simple way to find out short of copying all object references and
!        * tags into a temporary array before we start processing the first
!        * object.  That's why we just abort.  Doesn't happen very often anyway.
!        */
!       LOG (llevDebug, "hit_map(): next object destroyed\n");
!       break;
!     }
!     tmp = next;
!     next = tmp->above;
!     if (next)
!       next_tag = next->count;
  
!     if (QUERY_FLAG (tmp, FLAG_FREED)) {
! 	LOG (llevError, "BUG: hit_map(): found free object\n");
  	break;
      }
! 
!     /* Something could have happened to 'tmp' while 'tmp->below' was processed.
!      * For example, 'tmp' was put in an icecube.
!      */
!     if (tmp->map != map || tmp->x != x || tmp->y != y)
!       continue;
! 
!     if (QUERY_FLAG (tmp, FLAG_ALIVE)) {
        hit_player(tmp,op->stats.dam,op,type);
        retflag |=1;
!       if (was_destroyed (op, op_tag))
          break;
!     } else if (tmp->material) {
        save_throw_object(tmp,type);
+     }
    }
  #ifdef NO_CONE_PROPOGATE
    return retflag;
  #else
    return 0;
  #endif