Difference for common/object.c from version 1.111 to 1.112


version 1.111 version 1.112
Line 1
 
Line 1
 /*  /*
  * static char *rcsid_object_c =   * static char *rcsid_object_c =
  *   "$Id: object.c,v 1.111 2005/11/01 10:08:17 akirschbaum Exp $";   *   "$Id: object.c,v 1.112 2005/11/16 08:16:00 mwedel Exp $";
  */   */
   
 /*  /*
Line 196
 
Line 196
  (ob1->client_type != ob2->client_type) ||   (ob1->client_type != ob2->client_type) ||
  (ob1->materialname != ob2->materialname) ||   (ob1->materialname != ob2->materialname) ||
  (ob1->lore != ob2->lore) ||   (ob1->lore != ob2->lore) ||
  (ob1->subtype != ob2->subtype)   (ob1->subtype != ob2->subtype) ||
    (ob1->move_type != ob2->move_type) ||
    (ob1->move_block != ob2->move_block) ||
    (ob1->move_on != ob2->move_on) ||
    (ob1->move_off != ob2->move_off) ||
    (ob1->move_slow != ob2->move_slow) ||
    (ob1->move_slow_penalty != ob2->move_slow_penalty)
  )    )
      return 0;       return 0;
   
Line 961
 
Line 967
   
 void update_object(object *op, int action) {  void update_object(object *op, int action) {
     int update_now=0, flags;      int update_now=0, flags;
       MoveType move_on, move_off, move_block, move_slow;
          
     if (op == NULL) {      if (op == NULL) {
         /* this should never happen */          /* this should never happen */
Line 992
 
Line 999
          
     flags = GET_MAP_FLAGS(op->map, op->x, op->y);      flags = GET_MAP_FLAGS(op->map, op->x, op->y);
     SET_MAP_FLAGS(op->map, op->x, op->y, flags | P_NEED_UPDATE);      SET_MAP_FLAGS(op->map, op->x, op->y, flags | P_NEED_UPDATE);
       move_slow = GET_MAP_MOVE_SLOW(op->map, op->x, op->y);
       move_on = GET_MAP_MOVE_ON(op->map, op->x, op->y);
       move_block = GET_MAP_MOVE_BLOCK(op->map, op->x, op->y);
       move_off = GET_MAP_MOVE_OFF(op->map, op->x, op->y);
   
     if (action == UP_OBJ_INSERT) {      if (action == UP_OBJ_INSERT) {
         if (QUERY_FLAG(op, FLAG_BLOCKSVIEW) && !(flags & P_BLOCKSVIEW))          if (QUERY_FLAG(op, FLAG_BLOCKSVIEW) && !(flags & P_BLOCKSVIEW))
Line 1003
 
Line 1014
         if (QUERY_FLAG(op, FLAG_DAMNED) && !(flags & P_NO_CLERIC))          if (QUERY_FLAG(op, FLAG_DAMNED) && !(flags & P_NO_CLERIC))
             update_now=1;              update_now=1;
   
         if (QUERY_FLAG(op, FLAG_NO_PASS) && !(flags & P_NO_PASS))  
             update_now=1;  
   
         if (QUERY_FLAG(op, FLAG_ALIVE) && !(flags & P_IS_ALIVE))          if (QUERY_FLAG(op, FLAG_ALIVE) && !(flags & P_IS_ALIVE))
             update_now=1;              update_now=1;
   
    if ((move_on | op->move_on) != move_on) update_now=1;
    if ((move_off | op->move_off) != move_off) update_now=1;
    if ((move_block | op->move_block) != move_block) update_now=1;
    if ((move_slow | op->move_slow) != move_slow) update_now=1;
     }       }
     /* if the object is being removed, we can't make intelligent      /* if the object is being removed, we can't make intelligent
      * decisions, because remove_ob can't really pass the object       * decisions, because remove_ob can't really pass the object
Line 1070
 
Line 1083
  ob->more=NULL;   ob->more=NULL;
     }      }
     if (ob->inv) {      if (ob->inv) {
    /* Only if the space blocks everything do we not process -
    * if some form of movemnt is allowed, let objects
    * drop on that space.
    */
  if (free_inventory || ob->map==NULL || ob->map->in_memory!=MAP_IN_MEMORY ||   if (free_inventory || ob->map==NULL || ob->map->in_memory!=MAP_IN_MEMORY ||
      (get_map_flags(ob->map, NULL, ob->x, ob->y, NULL, NULL) & P_NO_PASS))       (GET_MAP_MOVE_BLOCK(ob->map, ob->x, ob->y) != MOVE_ALL))
  {   {
      op=ob->inv;       op=ob->inv;
      while(op!=NULL) {       while(op!=NULL) {
Line 1354
 
Line 1371
      }       }
      tmp->contr->socket.update_look=1;       tmp->contr->socket.update_look=1;
  }   }
  if (check_walk_off && (QUERY_FLAG (op, FLAG_FLYING) ?   /* See if player moving off should effect something */
      QUERY_FLAG (tmp, FLAG_FLY_OFF) : QUERY_FLAG (tmp, FLAG_WALK_OFF))) {   if (check_walk_off && ((op->move_type & tmp->move_off) &&
          (op->move_type & ~tmp->move_off & ~tmp->move_block)==0)) {
            
      move_apply(tmp, op, NULL);       move_apply(tmp, op, NULL);
      if (was_destroyed (op, tag)) {       if (was_destroyed (op, tag)) {
Line 1560
 
Line 1578
      while (top != NULL) {       while (top != NULL) {
  if (QUERY_FLAG(top, FLAG_IS_FLOOR) ||   if (QUERY_FLAG(top, FLAG_IS_FLOOR) ||
      QUERY_FLAG(top, FLAG_OVERLAY_FLOOR)) floor = top;       QUERY_FLAG(top, FLAG_OVERLAY_FLOOR)) floor = top;
  if (QUERY_FLAG(top, FLAG_NO_PICK) && QUERY_FLAG(top, FLAG_FLYING)) {   if (QUERY_FLAG(top, FLAG_NO_PICK) &&
      (top->move_type & (MOVE_FLY_LOW |MOVE_FLY_HIGH))) {
      /* We insert above top, so we want this object below this */       /* We insert above top, so we want this object below this */
      top=top->below;       top=top->below;
      break;       break;
Line 1650
 
Line 1669
     /* Don't know if moving this to the end will break anything.  However,      /* Don't know if moving this to the end will break anything.  However,
      * we want to have update_look set above before calling this.       * we want to have update_look set above before calling this.
      *       *
      * check_walk_on() must be after this because code called from       * check_move_on() must be after this because code called from
      * check_walk_on() depends on correct map flags (so functions like       * check_move_on() depends on correct map flags (so functions like
      * blocked() and wall() work properly), and these flags are updated by       * blocked() and wall() work properly), and these flags are updated by
      * update_object().       * update_object().
      */       */
Line 1659
 
Line 1678
     /* if this is not the head or flag has been passed, don't check walk on status */      /* if this is not the head or flag has been passed, don't check walk on status */
   
     if (!(flag & INS_NO_WALK_ON) && !op->head) {      if (!(flag & INS_NO_WALK_ON) && !op->head) {
         if (check_walk_on(op, originator))          if (check_move_on(op, originator))
      return NULL;       return NULL;
   
         /* If we are a multi part object, lets work our way through the check          /* If we are a multi part object, lets work our way through the check
          * walk on's.           * walk on's.
          */           */
         for (tmp=op->more; tmp!=NULL; tmp=tmp->more)          for (tmp=op->more; tmp!=NULL; tmp=tmp->more)
             if (check_walk_on (tmp, originator))              if (check_move_on (tmp, originator))
  return NULL;   return NULL;
     }      }
     return op;      return op;
Line 1937
 
Line 1956
 }  }
   
 /*  /*
  * Checks if any objects which has the WALK_ON() (or FLY_ON() if the   * Checks if any objects has a move_type that matches objects
  * object is flying) flag set, will be auto-applied by the insertion   * that effect this object on this space.  Call apply() to process
  * of the object into the map (applying is instantly done).   * these events.
    *
  * Any speed-modification due to SLOW_MOVE() of other present objects   * Any speed-modification due to SLOW_MOVE() of other present objects
  * will affect the speed_left of the object.   * will affect the speed_left of the object.
  *   *
Line 1956
 
Line 1976
  * on top.   * on top.
  */   */
   
 int check_walk_on (object *op, object *originator)  int check_move_on (object *op, object *originator)
 {  {
     object *tmp;      object *tmp;
     tag_t tag;      tag_t tag;
     mapstruct *m=op->map;      mapstruct *m=op->map;
     int x=op->x, y=op->y;      int x=op->x, y=op->y;
       MoveType move_on, move_slow, move_block;
   
     if(QUERY_FLAG(op,FLAG_NO_APPLY))      if(QUERY_FLAG(op,FLAG_NO_APPLY))
  return 0;   return 0;
   
     tag = op->count;      tag = op->count;
   
       move_on = GET_MAP_MOVE_ON(op->map, op->x, op->y);
       move_slow = GET_MAP_MOVE_SLOW(op->map, op->x, op->y);
       move_block = GET_MAP_MOVE_BLOCK(op->map, op->x, op->y);
   
       /* if nothing on this space will slow op down or be applied,
        * no need to do checking below.    have to make sure move_type
        * is set, as lots of objects don't have it set - we treat that
        * as walking.
        */
       if (op->move_type && !(op->move_type & move_on) && !(op->move_type & move_slow))
    return 0;
   
       /* This is basically inverse logic of that below - basically,
        * if the object can avoid the move on or slow move, they do so,
        * but can't do it if the alternate movement they are using is
        * blocked.  Logic on this seems confusing, but does seem correct.
        */
       if ((op->move_type & ~move_on & ~move_block) != 0 &&
    (op->move_type & ~move_slow & ~move_block) != 0) return 0;
   
     /* The objects have to be checked from top to bottom.      /* The objects have to be checked from top to bottom.
      * Hence, we first go to the top: */       * Hence, we first go to the top:
        */
   
     for (tmp=GET_MAP_OB(op->map, op->x, op->y); tmp!=NULL &&      for (tmp=GET_MAP_OB(op->map, op->x, op->y); tmp!=NULL &&
  tmp->above!=NULL; tmp=tmp->above) {   tmp->above!=NULL; tmp=tmp->above) {
  /* Trim the search when we find the first other spell effect    /* Trim the search when we find the first other spell effect
  * this helps performance so that if a space has 50 spell objects,   * this helps performance so that if a space has 50 spell objects,
  * we don't need to check all of them.   * we don't need to check all of them.
  */   */
  if (QUERY_FLAG(tmp, FLAG_FLYING) && QUERY_FLAG(tmp, FLAG_NO_PICK)) break;   if ((tmp->move_type & MOVE_FLY_LOW) && QUERY_FLAG(tmp, FLAG_NO_PICK)) break;
     }      }
       
     for(;tmp!=NULL; tmp=tmp->below) {      for(;tmp!=NULL; tmp=tmp->below) {
  if (tmp == op) continue;    /* Can't apply yourself */   if (tmp == op) continue;    /* Can't apply yourself */
   
  /* Slow down creatures moving over rough terrain */   /* Check to see if one of the movement types should be slowed down.
  if(QUERY_FLAG(tmp,FLAG_SLOW_MOVE)&&!QUERY_FLAG(op,FLAG_FLYING)) {   * Second check makes sure that the movement types not being slowed
    * (~slow_move) is not blocked on this space - just because the
    * space doesn't slow down swimming (for example), if you can't actually
    * swim on that space, can't use it to avoid the penalty.
    */
    if ((!op->move_type && tmp->move_slow & MOVE_WALK) ||
       ((op->move_type & tmp->move_slow) &&
        (op->move_type & ~tmp->move_slow & ~tmp->move_block)==0)) {
   
      float diff;       float diff;
   
      diff=(SLOW_PENALTY(tmp)*FABS(op->speed));       diff= tmp->move_slow_penalty * FABS(op->speed);
      if (op->type==PLAYER) {       if (op->type==PLAYER) {
  if ((QUERY_FLAG(tmp,FLAG_IS_HILLY) && find_skill_by_number(op,SK_CLIMBING)) ||   if ((QUERY_FLAG(tmp,FLAG_IS_HILLY) && find_skill_by_number(op,SK_CLIMBING)) ||
      (QUERY_FLAG(tmp,FLAG_IS_WOODED) && find_skill_by_number(op,SK_WOODSMAN)))  {       (QUERY_FLAG(tmp,FLAG_IS_WOODED) && find_skill_by_number(op,SK_WOODSMAN)))  {
Line 1995
 
Line 2045
      }       }
      op->speed_left -= diff;       op->speed_left -= diff;
  }   }
  if(QUERY_FLAG(op,FLAG_FLYING)?QUERY_FLAG(tmp,FLAG_FLY_ON):  
     QUERY_FLAG(tmp,FLAG_WALK_ON)) {   /* Basically same logic as above, except now for actual apply. */
    if ((!op->move_type && tmp->move_on & MOVE_WALK) ||
        ((op->move_type & tmp->move_on) &&
        (op->move_type & ~tmp->move_on & ~tmp->move_block)==0)) {
   
      move_apply(tmp, op, originator);       move_apply(tmp, op, originator);
             if (was_destroyed (op, tag))              if (was_destroyed (op, tag))
               return 1;                return 1;
   
      /* what the person/creature stepped onto has moved the object       /* what the person/creature stepped onto has moved the object
       * someplace new.  Don't process any further - if we did,        * someplace new.  Don't process any further - if we did,
       * have a feeling strange problems would result.        * have a feeling strange problems would result.
Line 2134
 
Line 2189
 }  }
   
 /*  /*
  * find_free_spot(archetype, map, x, y, start, stop) will search for   * find_free_spot(object, map, x, y, start, stop) will search for
  * a spot at the given map and coordinates which will be able to contain   * a spot at the given map and coordinates which will be able to contain
  * the given archetype.  start and stop specifies how many squares   * the given object.  start and stop specifies how many squares
  * to search (see the freearr_x/y[] definition).   * to search (see the freearr_x/y[] definition).
  * It returns a random choice among the alternatives found.   * It returns a random choice among the alternatives found.
  * start and stop are where to start relative to the free_arr array (1,9   * start and stop are where to start relative to the free_arr array (1,9
Line 2148
 
Line 2203
  * Note2: This function does correctly handle tiled maps, but does not   * Note2: This function does correctly handle tiled maps, but does not
  * inform the caller.  However, insert_ob_in_map will update as   * inform the caller.  However, insert_ob_in_map will update as
  * necessary, so the caller shouldn't need to do any special work.   * necessary, so the caller shouldn't need to do any special work.
    * Note - updated to take an object instead of archetype - this is necessary
    * because arch_blocked (now ob_blocked) needs to know the movement type
    * to know if the space in question will block the object.  We can't use
    * the archetype because that isn't correct if the monster has been
    * customized, changed states, etc.
  */   */
   
 int find_free_spot(archetype *at, mapstruct *m,int x,int y,int start,int stop) {  int find_free_spot(object *ob, mapstruct *m,int x,int y,int start,int stop) {
     int i,index=0, flag;      int i,index=0, flag;
     static int altern[SIZEOFFREE];      static int altern[SIZEOFFREE];
   
     for(i=start;i<stop;i++) {      for(i=start;i<stop;i++) {
  flag = arch_blocked(at,m,x+freearr_x[i],y+freearr_y[i]);   flag = ob_blocked(ob,m,x+freearr_x[i],y+freearr_y[i]);
  if(!flag)   if(!flag)
      altern[index++]=i;       altern[index++]=i;
   
  /* Basically, if we find a wall on a space, we cut down the search size.   /* Basically, if we find a wall on a space, we cut down the search size.
  * In this way, we won't return spaces that are on another side of a wall.   * In this way, we won't return spaces that are on another side of a wall.
  * This mostly work, but it cuts down the search size in all directions -    * This mostly work, but it cuts down the search size in all directions -
Line 2166
 
Line 2227
  * to only the spaces immediately surrounding the target area, and   * to only the spaces immediately surrounding the target area, and
  * won't look 2 spaces south of the target space.   * won't look 2 spaces south of the target space.
  */   */
  else if ((flag & P_NO_PASS) &&  maxfree[i]<stop)   else if ((flag & AB_NO_PASS) && maxfree[i]<stop)
      stop=maxfree[i];       stop=maxfree[i];
     }      }
     if(!index) return -1;      if(!index) return -1;
Line 2180
 
Line 2241
  * Changed 0.93.2: Have it return -1 if there is no free spot available.   * Changed 0.93.2: Have it return -1 if there is no free spot available.
  */   */
   
 int find_first_free_spot(archetype *at, mapstruct *m,int x,int y) {  int find_first_free_spot(object *ob, mapstruct *m,int x,int y) {
     int i;      int i;
     for(i=0;i<SIZEOFFREE;i++) {      for(i=0;i<SIZEOFFREE;i++) {
  if(!arch_blocked(at,m,x+freearr_x[i],y+freearr_y[i]))   if(!ob_blocked(ob,m,x+freearr_x[i],y+freearr_y[i]))
      return i;       return i;
     }      }
     return -1;      return -1;
Line 2236
 
Line 2297
  * live objects.   * live objects.
  * It returns the direction toward the first/closest live object if finds   * It returns the direction toward the first/closest live object if finds
  * any, otherwise 0.   * any, otherwise 0.
    * Perhaps incorrectly, but I'm making the assumption that exclude
    * is actually want is going to try and move there.  We need this info
    * because we have to know what movement the thing looking to move
    * there is capable of.
  */   */
   
 int find_dir(mapstruct *m, int x, int y, object *exclude) {  int find_dir(mapstruct *m, int x, int y, object *exclude) {
Line 2243
 
Line 2308
     sint16 nx, ny;      sint16 nx, ny;
     object *tmp;      object *tmp;
     mapstruct *mp;      mapstruct *mp;
       MoveType blocked, move_type;
   
     if (exclude && exclude->head)      if (exclude && exclude->head) {
  exclude = exclude->head;   exclude = exclude->head;
    move_type = exclude->move_type;
       } else {
    /* If we don't have anything, presume it can use all movement types. */
    move_type=MOVE_ALL;
       }
   
     for(i=1;i<max;i++) {      for(i=1;i<max;i++) {
  mp = m;   mp = m;
Line 2254
 
Line 2325
   
  mflags = get_map_flags(m, &mp, nx, ny, &nx, &ny);   mflags = get_map_flags(m, &mp, nx, ny, &nx, &ny);
   
  if (mflags & P_WALL)   blocked = GET_MAP_MOVE_BLOCK(mp, nx, ny);
   
    if ((move_type & blocked) == move_type)
      max=maxfree[i];       max=maxfree[i];
  else if (mflags & P_IS_ALIVE) {   else if (mflags & P_IS_ALIVE) {
      for (tmp=GET_MAP_OB(mp,nx,ny); tmp!= NULL; tmp=tmp->above) {       for (tmp=GET_MAP_OB(mp,nx,ny); tmp!= NULL; tmp=tmp->above) {
Line 2419
 
Line 2492
   
     mflags = get_map_flags(m, &m, dx, dy, &dx, &dy);      mflags = get_map_flags(m, &m, dx, dy, &dx, &dy);
   
     if (mflags & (P_OUT_OF_MAP | P_WALL)) return 0;      /* This functional arguably was incorrect before - it was
        * checking for P_WALL - that was basically seeing if
        * we could move to the monster - this is being more
        * literal on if we can see it.  To know if we can actually
        * move to the monster, we'd need the monster passed in or
        * at least its move type.
        */
       if (mflags & (P_OUT_OF_MAP | P_BLOCKSVIEW)) return 0;
   
     /* yes, can see. */      /* yes, can see. */
     if(dir < 9) return 1;      if(dir < 9) return 1;


Legend:
line(s) removed in v.1.111 
line(s) changed
 line(s) added in v.1.112

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