Difference for server/move.c from version 1.21 to 1.22


version 1.21 version 1.22
Line 1
 
Line 1
 /*  /*
  * static char *rcsid_move_c =   * static char *rcsid_move_c =
  *    "$Id: move.c,v 1.21 2002/08/26 07:14:11 mwedel Exp $";   *    "$Id: move.c,v 1.22 2002/09/01 06:32:31 mwedel Exp $";
  */   */
   
 /*  /*
Line 31
 
Line 31
 #include <sproto.h>  #include <sproto.h>
 #endif  #endif
   
   /*
    * move_object() tries to move object op in the direction "dir".
    * If it fails (something blocks the passage), it returns 0,
    * otherwise 1.
    * This is an improvement from the previous move_ob(), which
    * removed and inserted objects even if they were unable to move.
    */
   
   int move_object(object *op, int dir) {
       return move_ob(op, dir, op);
   }
   
   
 /* object op is trying to move in direction dir.  /* object op is trying to move in direction dir.
  * originator is typically the same as op, but   * originator is typically the same as op, but
  * can be different if originator is causing op to   * can be different if originator is causing op to
  * move (originator is pushing op)   * move (originator is pushing op)
  * returns 0 if the object is not able to move to the   * returns 0 if the object is not able to move to the
  * desired space, 1 otherwise (in which case we also    * desired space, 1 otherwise (in which case we also
  * move the object accordingly   * move the object accordingly.  This function is
    * very similiar to move_object.
  */   */
 int move_ob (object *op, int dir, object *originator)  int move_ob (object *op, int dir, object *originator)
 {  {
     object *tmp_ob=NULL;      int newx = op->x+freearr_x[dir];
       int newy = op->y+freearr_y[dir];
       object *tmp;
   
     if(op==NULL) {      if(op==NULL) {
  LOG(llevError,"Trying to move NULL.\n");   LOG(llevError,"Trying to move NULL.\n");
  return 0;   return 0;
     }      }
     /* this function should now only be used on the head - it won't call itself  
      * recursively, and people calling us should pass the right part.      /* Is this space blocked?  Players with wizpass are immune to
        * this condition.
      */       */
     if (op->head) {      if(blocked_link(op, newx, newy) &&
  LOG(llevDebug,"move_ob called with non head object: %s %s (%d,%d)\n",         !QUERY_FLAG(op, FLAG_WIZPASS))
      op->head->name, op->map->name, op->x, op->y);   return 0;
  op = op->head;  
     }  
   
     /* If the space the player is trying to is out of the map,      /* If the space the player is trying to is out of the map,
      * bail now - we know it can't work.       * bail now - we know it can't work.
      */       */
     if (out_of_map(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir])) return 0;      if (out_of_map(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir])) return 0;
   
       /* 0.94.2 - we need to set the direction for the new animation code.
     /* Modified these to check for appropriate object anyplace on map       * it uses it to figure out face to use - I can't see it
      * not just the top (stacking is less deterministic now).       * breaking anything, but it might.
      * also now have it return 0 on both of these cases.  The  
      * monster may be able to move there, but hacking the door or  
      * earthwall was their action this tick.  
      * will_apply should only be set for monsters, so players should  
      * never use this code.  These could probably get collapsed into  
      * one while loop, but that won't really save much code.  
      * MSW 2001-07-19  
      */       */
       if(op->more != NULL && !move_ob(op->more, dir, op->more->head))
     if (op->will_apply&4 ) {  
  tmp_ob=get_map_ob(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir]);  
  while(tmp_ob != NULL) {  
      if (tmp_ob->type == EARTHWALL) {  
  hit_player(tmp_ob,5,op,AT_PHYSICAL); /* Tear down the earthwall */  
  return 0;   return 0;
      }  
             tmp_ob = tmp_ob->above; /* To prevent endless loop */  
  }  
     }  
     if (op->will_apply&8 ) {  
  tmp_ob=get_map_ob(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir]);  
  while(tmp_ob != NULL) {  
      if (tmp_ob->type == DOOR) {  
  hit_player(tmp_ob,9998,op,AT_PHYSICAL); /* Tear down the door */  
  return 0;  
      }  
             tmp_ob = tmp_ob->above; /* To prevent endless loop */  
  }  
     }  
   
       op->direction = dir;
   
       if(op->will_apply&4)
    check_earthwalls(op,newx,newy);
       if(op->will_apply&8)
    check_doors(op,newx,newy);
   
     /* Modified logic here.  Split code into one for single part objects      /* 0.94.1 - I got a stack trace that showed it crash with remove_ob trying
      * and one for multi part objects.       * to remove a removed object, and this function was the culprit.  A possible
        * guess I have is that check_doors above ran into a trap, killing the
        * monster.
        *
        * Unfortunately, it doesn't appear that the calling functions of move_object
        * deal very well with op being killed, so all this might do is just
        * migrate the problem someplace else.
      */       */
     if (op->more == NULL) {  
  /* if player does not have wizpass, and the space is blocked and      if (QUERY_FLAG(op, FLAG_REMOVED)) {
  * blocked two, return 0.  We make calls to both blocked and blocked_two   LOG(llevDebug,"move_object: monster has been removed - will not process further\n");
  * because we only want to call blocked_two when necessary (its a costly   /* Was not successful, but don't want to try and move again */
  * operation), so if the space is not blocked (which is a very cheap    return 1;
  * operation), we then don't need to call blocked_two      }
   
       /* If this is a tail portion, just want to tell caller that move is
        * ok - the caller will deal with actual object removal/insertion
  */   */
  if (!QUERY_FLAG(op,FLAG_WIZPASS) &&       if(op->head)
      blocked(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir]) &&    return 1;
      blocked_two(op,op->x+freearr_x[dir],op->y+freearr_y[dir])) return 0;  
   
  /* Else, move this object */  
  remove_ob(op);   remove_ob(op);
  op->x+=freearr_x[dir];  
  op->y+=freearr_y[dir];      for(tmp = op; tmp != NULL; tmp = tmp->more)
    tmp->x+=freearr_x[dir], tmp->y+=freearr_y[dir];
   
  insert_ob_in_map(op,op->map,originator,0);   insert_ob_in_map(op,op->map,originator,0);
  /* Currently, assume that players will only be single space objects */  
       /* Hmmm.  Should be possible for multispace players now */
  if (op->type==PLAYER) {   if (op->type==PLAYER) {
      esrv_map_scroll(&op->contr->socket, freearr_x[dir],freearr_y[dir]);       esrv_map_scroll(&op->contr->socket, freearr_x[dir],freearr_y[dir]);
      op->contr->socket.update_look=1;       op->contr->socket.update_look=1;
      op->contr->socket.look_position=0;       op->contr->socket.look_position=0;
  }   }
  return 1;  
     } else {  
  /* Multipart object handling.  Its my belief that is more efficient  
  * to call blocked_link on each space of the monster than needing  
  * to remove the entire thing and re-insert the entire thing in a case  
  * where it may not be able to move.  MSW 2001-07-19.  
  * If any space is blocked by something other than the object  
  * (which blocked_linked returns), bail out immediately.  Doesn't do  
  * any good if 3 out of 4 spaces are available.  Note also that  
  * some logic for single part monsters is not included here - I presume  
  * that players (and hence wizpass) can only play single space  
  * objects (poor assumption I know)  
  */  
  for (tmp_ob = op; tmp_ob != NULL; tmp_ob = tmp_ob->more) {  
      if (blocked_link(op, tmp_ob->x+freearr_x[dir],tmp_ob->y+freearr_y[dir])) return 0;  
   
  }  
  /* If we got here, it is possible to move this object.  Remove it,  
  * update the coordinates, and re-insert it.  Note that while  
  * remove_ob takes care of removing all parts, but we need to  
  * insert each one by hand.  Also, insert_ob_in_map does special  
  * processing for the head object - for this to work right,  
  * we want to insert that last.  
  */  
  for (tmp_ob = op->more; tmp_ob != NULL; tmp_ob = tmp_ob->more) {  
      tmp_ob->x+=freearr_x[dir];  
      tmp_ob->y+=freearr_y[dir];  
      /* WALK_ON should be handled when head is inserted for all parts.  
       * lets just make sure of that.  
       */  
      insert_ob_in_map(tmp_ob, op->map, originator, INS_NO_WALK_ON);  
  }  
  op->x+=freearr_x[dir];  
  op->y+=freearr_y[dir];  
  insert_ob_in_map(op, op->map, originator, INS_NO_WALK_ON);  
  return 1;  
     }  
     return 1; /* this shouldn't be reached */      return 1; /* this shouldn't be reached */
 }  }
   
Line 410
 
Line 379
  }   }
     }      }
   
     /* now, lets test stand still we NEVER can psuh stand_still monsters. */      /* now, lets test stand still. we NEVER can push stand_still monsters. */
     if(QUERY_FLAG(who,FLAG_STAND_STILL))      if(QUERY_FLAG(who,FLAG_STAND_STILL))
     {      {
  new_draw_info_format(NDI_UNIQUE, 0, pusher,   new_draw_info_format(NDI_UNIQUE, 0, pusher,
Line 430
 
Line 399
     if(QUERY_FLAG(who,FLAG_WIZ) ||      if(QUERY_FLAG(who,FLAG_WIZ) ||
        random_roll(str1, str1/2+str1*2, who, PREFER_HIGH) >=          random_roll(str1, str1/2+str1*2, who, PREFER_HIGH) >=
        random_roll(str2, str2/2+str2*2, pusher, PREFER_HIGH) ||         random_roll(str2, str2/2+str2*2, pusher, PREFER_HIGH) ||
        !move_ob(who,dir,pusher))         !move_object(who,dir))
     {      {
  if (who ->type == PLAYER) {   if (who ->type == PLAYER) {
      new_draw_info_format(NDI_UNIQUE, 0, who,       new_draw_info_format(NDI_UNIQUE, 0, who,


Legend:
line(s) removed in v.1.21 
line(s) changed
 line(s) added in v.1.22

File made using version 1.98 of cvs2html by leaf at 2011-07-21 17:38