Difference for server/move.c from version 1.5 to 1.6


version 1.5 version 1.6
Line 1
 
Line 1
 /*  /*
  * static char *rcsid_move_c =   * static char *rcsid_move_c =
  *    "$Id: move.c,v 1.5 2001/07/14 04:11:18 mwedel Exp $";   *    "$Id: move.c,v 1.6 2001/07/31 06:33:23 mwedel Exp $";
  */   */
   
 /*  /*
Line 31
 
Line 31
 #include <sproto.h>  #include <sproto.h>
 #endif  #endif
   
   /* object op is trying to move in direction dir.
    * originator is typically the same as op, but
    * can be different if originator is causing op to
    * move (originator is pushing op)
    * returns 0 if the object is not able to move to the
    * desired space, 1 otherwise (in which case we also
    * move the object accordingly
    */
 int move_ob (object *op, int dir, object *originator)  int move_ob (object *op, int dir, object *originator)
 {  {
   object *tmp=NULL;  
   object *tmp_ob=NULL;    object *tmp_ob=NULL;
   
   if(op==NULL) {    if(op==NULL) {
     LOG(llevError,"Trying to move NULL.\n");      LOG(llevError,"Trying to move NULL.\n");
     return 0;      return 0;
   }    }
       /* If the space the player is trying to is out of the map,
   /* If this is a multipart object and we are dealing with the       * bail now - we know it can't work.
    * head, remove the object.  It needs to be removed, otherwise  
    * it may block itself from moving to that space (You can't  
    * move onto the tail section of the monster, and this is true  
    * even if it is your own tail  
    */     */
   if(op->more!=NULL && op->head==NULL)      if (out_of_map(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir])) return 0;
     remove_ob(op);  
   
 /* Vick's (vick@bern.docs.uu.se) @921108 -> If a monster can apply      /* this function should now only be used on the head - it won't call itself
  * an earthwall (or a door), then walking into it means tearing it down.       * recursively, and people calling us should pass the right part.
  * Note taht a player should never have will_apply set, so thus  
  * the following two sections will not be used for players -  
  * the routines in move_player_attack will be used instead.  
  */   */
       if (op->head) {
    LOG(llevDebug,"move_ob called with non head object: %s %s (%d,%d)\n",
        op->head->name, op->map->name, op->x, op->y);
    op = op->head;
       }
   
   if (op->will_apply&4 &&      /* Modified these to check for appropriate object anyplace on map
       !out_of_map(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir])) {       * not just the top (stacking is less deterministic now).
        * 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->will_apply&4 ) {
     tmp_ob=get_map_ob(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir]);      tmp_ob=get_map_ob(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir]);
    while(tmp_ob->above != NULL) {
     if (tmp_ob!=NULL) {       if (tmp_ob->type == EARTHWALL) {
       while(tmp_ob->above != NULL)  
         tmp_ob=tmp_ob->above;  
   
       if (tmp_ob->type == EARTHWALL)  
  hit_player(tmp_ob,5,op,AT_PHYSICAL); /* Tear down the earthwall */   hit_player(tmp_ob,5,op,AT_PHYSICAL); /* Tear down the earthwall */
    return 0;
     }      }
   }    }
   if (op->will_apply&8 &&      }
       !out_of_map(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir])) {      if (op->will_apply&8 ) {
   
     tmp_ob=get_map_ob(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir]);      tmp_ob=get_map_ob(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir]);
     if (tmp_ob!=NULL) {   while(tmp_ob->above != NULL) {
       while(tmp_ob->above != NULL)       if (tmp_ob->type == DOOR) {
         tmp_ob=tmp_ob->above;   hit_player(tmp_ob,9999,op,AT_PHYSICAL); /* Tear down the earthwall */
       if (tmp_ob->type == DOOR)   return 0;
         hit_player(tmp_ob,9999,op,AT_PHYSICAL); /* Break open the door. */  
     }      }
   }    }
   
   /* Eneq(@csd.uu.se): Use blocked_two when selecting direction.  
    * The following if statement works like this:  If WIZPASS is  
    * set, then the player is prevented from moving to that  
    * space if it is out_of_map.  If non WIZPASS, then  
    * blocked_two is called instead.  
    * This code section is for cases when an object CAN NOT move into  
    * that space.  
    */  
   
   if(QUERY_FLAG(op,FLAG_WIZPASS)?out_of_map(op->map,op->x+freearr_x[dir],  
     op->y+freearr_y[dir]):  
     blocked_two(op,op->x+freearr_x[dir],op->y+freearr_y[dir])) {  
   
     /* Re insert object if we removed it above */  
     if(op->more!=NULL && op->head==NULL)  
       insert_ob_in_map(op,op->map,originator,0);  
     return 0;  
   }    }
   
   /* Following deals with situation when the object can move  
    * into the desired space.      /* Modified logic here.  Split code into one for single part objects
        * and one for multi part objects.
    */     */
       if (op->more == NULL) {
    /* if player does not have wizpass, and the space is blocked and
    * blocked two, return 0.  We make calls to both blocked and blocked_two
    * because we only want to call blocked_two when necessary (its a costly
    * operation), so if the space is not blocked (which is a very cheap
    * operation), we then don't need to call blocked_two
    */
    if (!QUERY_FLAG(op,FLAG_WIZPASS) &&
        blocked(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir]) &&
        blocked_two(op,op->x+freearr_x[dir],op->y+freearr_y[dir])) return 0;
   
   /* this is a single parted object that needs to be removed. */   /* Else, move this object */
   if(op->more==NULL && op->head==NULL)  
     remove_ob(op);      remove_ob(op);
    op->x+=freearr_x[dir];
   /* This handles multipart objects.  It uses recursion to   op->y+=freearr_y[dir];
    * make sure all the parts will fit in the new space.  
    * First, tmp is set the the next segment (op->more), with  
    * that being set to null.  Then call move_ob to see if  
    * that segment (and also all segments beyond it) can  
    * move to taht space.  IF not (!move_ob), then reset op->more.  
    * If it is the head segment, insert back to map.  Clear freeze_look  
    * if player, and return failed result.  
    */  
   if(op->more!=NULL) {  
     tmp=op->more,op->more=NULL;  
     if(!move_ob(tmp,dir,originator)) {  
       op->more=tmp;  
       if(op->head==NULL)  
         insert_ob_in_map(op,op->map,originator,0);  
       return 0;  
     }  
     else op->more=tmp;  
   }  
   op->x+=freearr_x[dir],op->y+=freearr_y[dir];  /* Move this object */  
   
   /* If head of object (or single part object), reinsert into map. */  
   if(op->head==NULL)  
     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 */
   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;    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 */
 }  }
   
   


Legend:
line(s) removed in v.1.5 
line(s) changed
 line(s) added in v.1.6

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