Difference for common/button.c from version 1.2 to 1.3


version 1.2 version 1.3
Line 1
 
Line 1
 /*  /*
  * static char *rcsid_button_c =   * static char *rcsid_button_c =
  *   "$Id: button.c,v 1.2 1999/07/13 06:02:41 cvs Exp $";   *   "$Id: button.c,v 1.3 2000/05/26 09:50:45 jec Exp $";
  */   */
   
 /*  /*
Line 123
 
Line 123
  */   */
   
 void update_button(object *op) {  void update_button(object *op) {
     object *ab,*tmp;      object *ab,*tmp,*head;
     int tot,any_down=0, old_value=op->value;      int tot,any_down=0, old_value=op->value;
     objectlink *ol;      objectlink *ol;
   
Line 144
 
Line 144
  } else if (tmp->type == PEDESTAL) {   } else if (tmp->type == PEDESTAL) {
      tmp->value = 0;       tmp->value = 0;
      for(ab=tmp->above; ab!=NULL; ab=ab->above) {       for(ab=tmp->above; ab!=NULL; ab=ab->above) {
  if(ab->head!=NULL)   head = ab->head ? ab->head : ab;
      ab=ab->head;   if ( (!QUERY_FLAG(head,FLAG_FLYING) ||
  if ( (!QUERY_FLAG(ab,FLAG_FLYING) ||   
        QUERY_FLAG(tmp,FLAG_FLY_ON)) &&         QUERY_FLAG(tmp,FLAG_FLY_ON)) &&
       (ab->race==tmp->slaying ||        (head->race==tmp->slaying ||
        ((ab->type==SPECIAL_KEY) && (ab->slaying==tmp->slaying)) ||          ((head->type==SPECIAL_KEY) && (head->slaying==tmp->slaying)) ||
        (!strcmp (tmp->slaying, "player") &&          (!strcmp (tmp->slaying, "player") &&
         ab->type == PLAYER)))          head->type == PLAYER)))
      tmp->value = 1;       tmp->value = 1;
      }       }
      if(tmp->value)       if(tmp->value)
Line 220
 
Line 219
 #define ARCH_SACRIFICE(xyz) ((xyz)->slaying)  #define ARCH_SACRIFICE(xyz) ((xyz)->slaying)
 #define NROF_SACRIFICE(xyz) ((xyz)->stats.food)  #define NROF_SACRIFICE(xyz) ((xyz)->stats.food)
   
 /* Returns that object if it meets the sacrifice needs of the altar.  /* Returns true if the sacrifice meets the needs of the altar.
  * If no object meets the needs, return NULL.   *
  * Function put in (0.92.1) so that identify altars won't grab money   * Function put in (0.92.1) so that identify altars won't grab money
  * unnecessarily - we can see if there is sufficient money, see if something   * unnecessarily - we can see if there is sufficient money, see if something
  * needs to be identified, and then remove money if needed. (via check_altar)   * needs to be identified, and then remove money if needed.
  * Check_altar uses this function also.   *
  * 0.93.4: Linked objects (ie, objects that are connected) can not be   * 0.93.4: Linked objects (ie, objects that are connected) can not be
  * sacrificed.  This fixes a bug of trying to put multiple altars/related   * sacrificed.  This fixes a bug of trying to put multiple altars/related
  * objects on the same space that take the same sacrifice.   * objects on the same space that take the same sacrifice.
  */   */
    
 object *check_altar_sacrifice(object *altar)  int check_altar_sacrifice (object *altar, object *sacrifice)
 {  {
   object *op;    if ( ! QUERY_FLAG (sacrifice, FLAG_ALIVE)
         && ! QUERY_FLAG (sacrifice, FLAG_IS_LINKED)
   for (op=altar->above; op; op=op->above)        && sacrifice->type != PLAYER)
     if (!QUERY_FLAG(op,FLAG_ALIVE) && !QUERY_FLAG(op,FLAG_IS_LINKED) &&    {
  op->type != PLAYER) {        if ((ARCH_SACRIFICE(altar) == sacrifice->arch->name ||
       if ((ARCH_SACRIFICE(altar) == op->arch->name  ||            ARCH_SACRIFICE(altar) == sacrifice->name ||
           ARCH_SACRIFICE(altar) == op->name ||     ARCH_SACRIFICE(altar) == sacrifice->slaying)
    ARCH_SACRIFICE(altar) == op->slaying)      && NROF_SACRIFICE(altar) <= (sacrifice->nrof?sacrifice->nrof:1))
    && NROF_SACRIFICE(altar) <= (op->nrof?op->nrof:1))   return 1;
  return op;        if (strcmp (ARCH_SACRIFICE(altar), "money") == 0
       if (!strcmp(ARCH_SACRIFICE(altar), "money") &&            && sacrifice->type == MONEY
    op->type==MONEY && op->nrof*op->value>=NROF_SACRIFICE(altar))            && sacrifice->nrof * sacrifice->value >= NROF_SACRIFICE(altar))
  return op;   return 1;
     }      }
     return NULL;    return 0;
 }  }
   
   
 /*  /*
  * check_altar checks if sacrifice was accepted and removes sacrificed   * operate_altar checks if sacrifice was accepted and removes sacrificed
  * objects. If sacrifice was succeed return 1 else 0  Might be better to   * objects.  If sacrifice was succeed return 1 else 0.  Might be better to
  * call check_altar_sacrifice (above) than depend on the return value,   * call check_altar_sacrifice (above) than depend on the return value,
  * since check_altar will remove the sacrifice also.   * since operate_altar will remove the sacrifice also.
  *   *
  * Don't really like the name of this functin, operate_altar might be better -   * If this function returns 1, '*sacrifice' is modified to point to the
  * we aren't really checking it, since it will remove the sacrifice   * remaining sacrifice, or is set to NULL if the sacrifice was used up.
  */   */
   
 int check_altar (object *altar)  int operate_altar (object *altar, object **sacrifice)
 {  {
   object *op;    object *op;
   
     if ( ! altar->map) {
       LOG (llevError, "BUG: operate_altar(): altar has no map\n");
       return 0;
     }
   
   if (!altar->slaying || altar->value)    if (!altar->slaying || altar->value)
     return 0;      return 0;
   
   op=check_altar_sacrifice(altar);    if ( ! check_altar_sacrifice (altar, *sacrifice))
   if (!op)  
     return 0;      return 0;
   
   /* get_altar_sacrifice should have already verified that enough money    /* check_altar_sacrifice should have already verified that enough money
    * has been dropped.     * has been dropped.
    */     */
   if (!strcmp(ARCH_SACRIFICE(altar), "money")) {    if (!strcmp(ARCH_SACRIFICE(altar), "money")) {
  int number=NROF_SACRIFICE(altar)/op->value;   int number=NROF_SACRIFICE(altar) / (*sacrifice)->value;
   
  /* Round up any sacrifices.  Altars don't make change either */   /* Round up any sacrifices.  Altars don't make change either */
  if (NROF_SACRIFICE(altar)%op->value) number++;   if (NROF_SACRIFICE(altar) % (*sacrifice)->value) number++;
  decrease_ob_nr (op, number);   *sacrifice = decrease_ob_nr (*sacrifice, number);
   }    }
   else    else
     decrease_ob_nr (op, NROF_SACRIFICE(altar));      *sacrifice = decrease_ob_nr (*sacrifice, NROF_SACRIFICE(altar));
    
   for (op = get_map_ob(altar->map,altar->x,altar->y);    if (altar->msg)
        op && op->type != PLAYER; op=op->above);      (*info_map_func) (NDI_BLACK, altar->map, altar->msg);
   if (op && altar->msg)  
     (*info_map_func) (NDI_BLACK, op->map, altar->msg);  
   return 1;    return 1;
 }  }
   
 void trigger_move (object *op, int state) /* 1 down and 0 up */  void trigger_move (object *op, int state) /* 1 down and 0 up */
 {  {
     op->stats.wc = state;      op->stats.wc = state;
     SET_ANIMATION(op,op->stats.wc);  
     update_object(op);  
     if (state) {      if (state) {
   
  /* Push button now does it all. */  
  use_trigger(op);   use_trigger(op);
    op->speed = 1.0 / op->arch->clone.stats.exp;
  op->speed =  op->arch->clone.speed;  
  update_ob_speed(op);   update_ob_speed(op);
  op->speed_left = -1;   op->speed_left = -1;
     } else {      } else {
           use_trigger(op);
  op->speed = 0;   op->speed = 0;
  update_ob_speed(op);   update_ob_speed(op);
     }      }
 }  }
   
 void check_trigger (object *op) {  
   /*
    * cause != NULL: something has moved on top of op
    *
    * cause == NULL: nothing has moved, we have been called from
    * animate_trigger().
    *
    * TRIGGER_ALTAR: Returns 1 if 'cause' was destroyed, 0 if not.
    *
    * TRIGGER: Returns 1 if handle could be moved, 0 if not.
    *
    * TRIGGER_BUTTON, TRIGGER_PEDESTAL: Returns 0.
    */
   int check_trigger (object *op, object *cause)
   {
   object *tmp;    object *tmp;
   int push = 0, tot = 0;    int push = 0, tot = 0;
     int in_movement = op->stats.wc || op->speed;
   
   switch (op->type) {    switch (op->type) {
     case TRIGGER_BUTTON:      case TRIGGER_BUTTON:
     if (op->weight > 0) {      if (op->weight > 0) {
           if (cause) {
         for(tmp=op->above; tmp; tmp=tmp->above)          for(tmp=op->above; tmp; tmp=tmp->above)
           if(!QUERY_FLAG(tmp,FLAG_FLYING))            if(!QUERY_FLAG(tmp,FLAG_FLYING))
      tot += tmp->weight * (tmp->nrof ? tmp->nrof : 1) + tmp->carrying;         tot += tmp->weight * (tmp->nrof ? tmp->nrof : 1)
                        + tmp->carrying;
           if (tot >= op->weight)            if (tot >= op->weight)
             push = 1;              push = 1;
           if (!push || op->stats.wc == 0)            if (op->stats.ac == push)
               return 0;
             op->stats.ac = push;
             SET_ANIMATION (op, push);
             update_object (op);
             if (in_movement || ! push)
               return 0;
           }
      trigger_move (op, push);       trigger_move (op, push);
     }      }
     return;      return 0;
   
     case TRIGGER_PEDESTAL:      case TRIGGER_PEDESTAL:
           if (cause) {
         for(tmp=op->above; tmp; tmp=tmp->above) {          for(tmp=op->above; tmp; tmp=tmp->above) {
           if(tmp->head!=NULL)              object *head = tmp->head ? tmp->head : tmp;
             tmp=tmp->head;              if ((!QUERY_FLAG(head,FLAG_FLYING) || QUERY_FLAG(op,FLAG_FLY_ON))
           if ( (!QUERY_FLAG(tmp,FLAG_FLYING) || QUERY_FLAG(op,FLAG_FLY_ON))           && (head->race==op->slaying ||
       && (tmp->race==op->slaying ||                  (!strcmp (op->slaying, "player") && head->type == PLAYER)))
              (!strcmp (op->slaying, "player") && tmp->type == PLAYER)))                {
                 push = 1;                  push = 1;
                   break;
                 }
      }
             if (op->stats.ac == push)
               return 0;
             op->stats.ac = push;
             SET_ANIMATION (op, push);
             update_object(op);
             if (in_movement || ! push)
               return 0;
  }   }
         if (!push || op->stats.wc == 0)  
           trigger_move(op, push);            trigger_move(op, push);
         return;          return 0;
   
     case TRIGGER_ALTAR:      case TRIGGER_ALTAR:
         if (op->stats.wc  == 0)          if (cause) {
           trigger_move (op,  op->speed == 0 ? check_altar(op) : 0);            if (in_movement)
    return;              return 0;
             if (operate_altar (op, &cause)) {
               SET_ANIMATION (op, 1);
               update_object(op);
               trigger_move (op, 1);
               return cause == NULL;
             } else {
               return 0;
             }
           } else {
             SET_ANIMATION (op, 0);
             update_object(op);
             trigger_move (op, 0);
           }
           return 0;
   
     case TRIGGER:      case TRIGGER:
         if (op->stats.wc == 0)   /* handle-trigger */          if (cause) {
             trigger_move (op, op->speed == 0 ? 1 : 0);            if (in_movement)
  return;              return 0;
             push = 1;
           }
           SET_ANIMATION (op, push);
           update_object(op);
           trigger_move (op, push);
    return 1;
   
     default:      default:
  LOG(llevDebug, "Unknown trigger type: %s (%d)\n", op->name, op->type);   LOG(llevDebug, "Unknown trigger type: %s (%d)\n", op->name, op->type);
            return 0;
   }    }
 }  }
   


Legend:
line(s) removed in v.1.2 
line(s) changed
 line(s) added in v.1.3

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