Difference for server/monster.c from version 1.47 to 1.48


version 1.47 version 1.48
Line 1
 
Line 1
 /*  /*
  * static char *rcsid_monster_c =   * static char *rcsid_monster_c =
  *    "$Id: monster.c,v 1.47 2002/08/26 07:14:11 mwedel Exp $";   *    "$Id: monster.c,v 1.48 2002/09/01 06:32:31 mwedel Exp $";
  */   */
   
 /*  /*
Line 60
 
Line 60
      * which CAN attack the owner. */       * which CAN attack the owner. */
     if ((npc->move_type & HI4) == PETMOVE)      if ((npc->move_type & HI4) == PETMOVE)
     {      {
         if (npc->owner != NULL)   if (npc->owner == NULL)
          return npc->enemy = npc->owner->enemy;       npc->enemy = NULL;
      else npc->enemy = NULL;   else if (npc->enemy == NULL)
        npc->enemy = npc->owner->enemy;
     }      }
   
     /* periodically, a monster mayu change its target.  Also, if the object      /* periodically, a monster mayu change its target.  Also, if the object
Line 78
 
Line 79
   
     if(npc->enemy)      if(npc->enemy)
     {      {
      if (QUERY_FLAG(npc->enemy,FLAG_REMOVED)||QUERY_FLAG(npc->enemy,FLAG_FREED)   /* I broke these if's apart to better be able to see what
          || !on_same_map(npc, npc->enemy) ||npc == npc->enemy ||    * the grouping checks are.  Code is the same.
             QUERY_FLAG(npc, FLAG_NEUTRAL) || QUERY_FLAG(npc->enemy, FLAG_NEUTRAL) || /* neutral */   */
             (QUERY_FLAG(npc, FLAG_FRIENDLY) && QUERY_FLAG(npc->enemy, FLAG_FRIENDLY)) ||   if ( QUERY_FLAG(npc->enemy,FLAG_REMOVED)    ||
             (!QUERY_FLAG(npc, FLAG_FRIENDLY) &&         QUERY_FLAG(npc->enemy,FLAG_FREED)     ||
             (!QUERY_FLAG(npc->enemy, FLAG_FRIENDLY) && npc->enemy->type!=PLAYER)) )                !on_same_map(npc, npc->enemy)     ||
         npc == npc->enemy     ||
                QUERY_FLAG(npc, FLAG_NEUTRAL)     ||
         QUERY_FLAG(npc->enemy, FLAG_NEUTRAL))
    npc->enemy = NULL;
   
    else if (QUERY_FLAG(npc, FLAG_FRIENDLY) &&
    (QUERY_FLAG(npc->enemy, FLAG_FRIENDLY) ||
      npc->enemy->type == PLAYER || npc->enemy == npc->owner))
        npc->enemy = NULL;
       
    else if (!QUERY_FLAG(npc, FLAG_FRIENDLY) &&
                (!QUERY_FLAG(npc->enemy, FLAG_FRIENDLY) && npc->enemy->type!=PLAYER))
                 npc->enemy=NULL;                  npc->enemy=NULL;
         }              }   
     return can_detect_enemy(npc,npc->enemy,rv)?npc->enemy:NULL;      return can_detect_enemy(npc,npc->enemy,rv)?npc->enemy:NULL;
Line 104
 
Line 117
  * this function is map tile aware.   * this function is map tile aware.
  */   */
 object *find_nearest_living_creature(object *npc) {  object *find_nearest_living_creature(object *npc) {
     int i,j=0,start;      int i;
     int nx,ny;      int nx,ny;
     mapstruct *m;      mapstruct *m;
     object *tmp;      object *tmp;
       int search_arr[SIZEOFFREE];
   
     start = (RANDOM()%8)+1;      get_search_arr(search_arr);
     for(i=start;j<SIZEOFFREE;j++, i=(i+1)%SIZEOFFREE) {      for(i=0;i<SIZEOFFREE;i++) {
  nx = npc->x + freearr_x[i];          /* modified to implement smart searching using search_arr
  ny = npc->y + freearr_y[i];           * guidance array to determine direction of search order
            */
           nx = npc->x + freearr_x[search_arr[i]];
           ny = npc->y + freearr_y[search_arr[i]];
  if (out_of_map(npc->map,nx,ny)) continue;   if (out_of_map(npc->map,nx,ny)) continue;
  m = get_map_from_coord(npc->map, &nx, &ny);   m = get_map_from_coord(npc->map, &nx, &ny);
   
Line 611
 
Line 628
 }  }
   
 int can_hit(object *ob1,object *ob2, rv_vector *rv) {  int can_hit(object *ob1,object *ob2, rv_vector *rv) {
       object *more;
       rv_vector rv1;
   
     if(QUERY_FLAG(ob1,FLAG_CONFUSED)&&!(RANDOM()%3))      if(QUERY_FLAG(ob1,FLAG_CONFUSED)&&!(RANDOM()%3))
  return 0;   return 0;
     return abs(rv->distance_x)<2&&abs(rv->distance_y)<2;  
       if (abs(rv->distance_x)<2&&abs(rv->distance_y)<2) return 1;
   
       /* check all the parts of ob2 - just because we can't get to
        * its head doesn't mean we don't want to pound its feet
        */
       for (more = ob2->more; more!=NULL; more = more->more) {
    get_rangevector(ob1, more, &rv1, 0);
    if (abs(rv1.distance_x)<2&&abs(rv1.distance_y)<2) return 1;
       }
       return 0;
   
 }  }
   
 /* Returns 1 is monster should cast spell sp at an enemy  /* Returns 1 is monster should cast spell sp at an enemy
Line 1369
 
Line 1400
   
 void check_earthwalls(object *op, int x, int y) {  void check_earthwalls(object *op, int x, int y) {
   object *tmp;    object *tmp;
   tmp = get_map_ob(op->map, x, y);      for (tmp = get_map_ob(op->map, x, y); tmp!=NULL; tmp=tmp->above) {
   if (tmp!= NULL)   if (tmp->type == EARTHWALL) {
     while(tmp->above != NULL)  
       tmp=tmp->above;  
   if (tmp!= NULL && tmp->type == EARTHWALL)  
     hit_player(tmp,op->stats.dam,op,AT_PHYSICAL);      hit_player(tmp,op->stats.dam,op,AT_PHYSICAL);
        return;
    }
       }
 }  }
   
 void check_doors(object *op, int x, int y) {  void check_doors(object *op, int x, int y) {
   object *tmp;    object *tmp;
   tmp = get_map_ob(op->map, x, y);      for (tmp = get_map_ob(op->map, x, y); tmp!=NULL; tmp=tmp->above) {
   if (tmp!= NULL)   if (tmp->type == DOOR) {
     while(tmp->above != NULL)  
       tmp=tmp->above;  
   if (tmp!= NULL && tmp->type == DOOR)  
     hit_player(tmp,1000,op,AT_PHYSICAL);      hit_player(tmp,1000,op,AT_PHYSICAL);
        return;
 }  }
   
 /*  
  * 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) {  
     int newx = op->x+freearr_x[dir];  
     int newy = op->y+freearr_y[dir];  
     object *tmp;  
   
     /* 0.94.2 - we need to set the direction for the new animation code.  
      * it uses it to figure out face to use - I can't see it  
      * breaking anything, but it might.  
      */  
     op->direction = dir;  
     if(blocked_link(op, newx, newy)) /* Not all features from blocked_two yet */  
  return 0;                      /* (Not efficient enough yet) */  
     if(op->more != NULL && !move_object(op->more, dir))  
  return 0;  
     if(op->will_apply&4)  
  check_earthwalls(op,newx,newy);  
     if(op->will_apply&8)  
  check_doors(op,newx,newy);  
   
     /* 0.94.1 - I got a stack trace that showed it crash with remove_ob trying  
      * 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 (QUERY_FLAG(op, FLAG_REMOVED)) {  
  LOG(llevDebug,"move_object: monster has been removed - will not process further\n");  
  /* Was not successful, but don't want to try and move again */  
  return 1;  
     }      }
     if(op->head)  
  return 1;  
   
     remove_ob(op);  
   
     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, op,0);  
     return 1;  
 }  }
   
 static void free_messages(msglang *msgs) {  static void free_messages(msglang *msgs) {


Legend:
line(s) removed in v.1.47 
line(s) changed
 line(s) added in v.1.48

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