Difference for server/apply.c from version 1.148 to 1.149


version 1.148 version 1.149
Line 1
 
Line 1
 /*  /*
  * static char *rcsid_apply_c =   * static char *rcsid_apply_c =
  *   "$Id: apply.c,v 1.148 2005/10/28 19:08:53 akirschbaum Exp $";   *   "$Id: apply.c,v 1.149 2005/11/16 08:16:08 mwedel Exp $";
  */   */
 /*  /*
     CrossFire, A Multiplayer game for X-windows      CrossFire, A Multiplayer game for X-windows
Line 969
 
Line 969
  tmp->below = sack->inv;   tmp->below = sack->inv;
  tmp->above = NULL;   tmp->above = NULL;
  sack->inv = tmp;   sack->inv = tmp;
  SET_FLAG (sack, FLAG_WALK_OFF); /* trying force closing it */   sack->move_off = MOVE_ALL; /* trying force closing it */
  SET_FLAG (sack, FLAG_FLY_OFF);  
      } else {       } else {
  CLEAR_FLAG (sack, FLAG_WALK_OFF);   sack->move_off = 0;
  CLEAR_FLAG (sack, FLAG_FLY_OFF);  
  tmp = sack->inv;   tmp = sack->inv;
  if (tmp && tmp->type ==  CLOSE_CON) {   if (tmp && tmp->type ==  CLOSE_CON) {
      remove_ob(tmp);       remove_ob(tmp);
Line 1066
 
Line 1064
   
     if (op->container && QUERY_FLAG(sack, FLAG_APPLIED)) {      if (op->container && QUERY_FLAG(sack, FLAG_APPLIED)) {
  if (op->container->env != op) { /* if container is on the ground */   if (op->container->env != op) { /* if container is on the ground */
      CLEAR_FLAG (op->container, FLAG_WALK_OFF);       op->container->move_off = 0;
      CLEAR_FLAG (op->container, FLAG_FLY_OFF);  
  }   }
         /* Lauwenmark: Handle for plugin close event */          /* Lauwenmark: Handle for plugin close event */
         if (execute_event(tmp, EVENT_CLOSE,op,NULL,NULL,SCRIPT_FIX_ALL)!=0)          if (execute_event(tmp, EVENT_CLOSE,op,NULL,NULL,SCRIPT_FIX_ALL)!=0)
             return 1;              return 1;
   
  new_draw_info_format(NDI_UNIQUE, 0, op, "You close %s.",   new_draw_info_format(NDI_UNIQUE, 0, op, "You close %s.",
        query_name(op->container));         query_name(op->container));
  CLEAR_FLAG(op->container, FLAG_APPLIED);   CLEAR_FLAG(op->container, FLAG_APPLIED);
Line 1117
 
Line 1115
      return 0;       return 0;
  }   }
  /* set these so when the player walks off, we can unapply the sack */   /* set these so when the player walks off, we can unapply the sack */
  SET_FLAG (sack, FLAG_WALK_OFF); /* trying force closing it */   sack->move_off = MOVE_ALL; /* trying force closing it */
  SET_FLAG (sack, FLAG_FLY_OFF);  
   
  CLEAR_FLAG (sack, FLAG_APPLIED);   CLEAR_FLAG (sack, FLAG_APPLIED);
  new_draw_info_format(NDI_UNIQUE, 0, op, "You open %s.", query_name(sack));   new_draw_info_format(NDI_UNIQUE, 0, op, "You open %s.", query_name(sack));
Line 1204
 
Line 1201
  for (tmp=op->inv; tmp; tmp=next) {   for (tmp=op->inv; tmp; tmp=next) {
      next = tmp->below;       next = tmp->below;
      if (QUERY_FLAG(tmp, FLAG_UNPAID)) {       if (QUERY_FLAG(tmp, FLAG_UNPAID)) {
  int i = find_free_spot (tmp->arch, op->map, op->x, op->y, 1, 9);   int i = find_free_spot (tmp, op->map, op->x, op->y, 1, 9);
   
  remove_ob(tmp);   remove_ob(tmp);
  if (i==-1) i=0;   if (i==-1) i=0;
Line 1224
 
Line 1221
  if (QUERY_FLAG(op, FLAG_UNPAID) || !QUERY_FLAG(op, FLAG_ALIVE)) {   if (QUERY_FLAG(op, FLAG_UNPAID) || !QUERY_FLAG(op, FLAG_ALIVE)) {
   
      /* Somebody dropped an unpaid item, just move to an adjacent place. */       /* Somebody dropped an unpaid item, just move to an adjacent place. */
      int i = find_free_spot (op->arch, op->map, op->x, op->y, 1, 9);       int i = find_free_spot (op, op->map, op->x, op->y, 1, 9);
      if (i != -1) {       if (i != -1) {
  rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0,   rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0,
                        shop_mat);                         shop_mat);
Line 1266
 
Line 1263
  * they are not on the mat anymore   * they are not on the mat anymore
  */   */
   
  int i = find_free_spot (op->arch, op->map, op->x, op->y, 1, 9);   int i = find_free_spot (op, op->map, op->x, op->y, 1, 9);
  if(i == -1) {   if(i == -1) {
      LOG (llevError, "Internal shop-mat problem.\n");       LOG (llevError, "Internal shop-mat problem.\n");
  } else {   } else {
Line 1297
 
Line 1294
   
     if (sign->stats.food) {      if (sign->stats.food) {
       if (sign->last_eat >= sign->stats.food) {        if (sign->last_eat >= sign->stats.food) {
         if (!QUERY_FLAG (sign, FLAG_WALK_ON) && !QUERY_FLAG (sign, FLAG_FLY_ON))       if (!sign->move_on)
           new_draw_info (NDI_UNIQUE, 0, op, "You cannot read it anymore.");            new_draw_info (NDI_UNIQUE, 0, op, "You cannot read it anymore.");
         return;          return;
       }        }
Line 1305
 
Line 1302
     }      }
   
     /* Sign or magic mouth?  Do we need to see it, or does it talk to us?      /* Sign or magic mouth?  Do we need to see it, or does it talk to us?
      * No way to know for sure.       * No way to know for sure.  The presumption is basically that if
      *       * move_on is zero, it needs to be manually applied (doesn't talk
      * This check fails for signs with FLAG_WALK_ON/FLAG_FLY_ON.  Checking       * to us). 
      * for FLAG_INVISIBLE instead of FLAG_WALK_ON/FLAG_FLY_ON would fail       */
      * for magic mouths that have been made visible.      if (QUERY_FLAG (op, FLAG_BLIND) && ! QUERY_FLAG (op, FLAG_WIZ) && !sign->move_on) {
      */  
     if (QUERY_FLAG (op, FLAG_BLIND) && ! QUERY_FLAG (op, FLAG_WIZ)  
         && ! QUERY_FLAG (sign, FLAG_WALK_ON)  
         && ! QUERY_FLAG (sign, FLAG_FLY_ON))  
     {  
         new_draw_info (NDI_UNIQUE, 0, op,          new_draw_info (NDI_UNIQUE, 0, op,
                        "You are unable to read while blind.");                         "You are unable to read while blind.");
         return;          return;
Line 1326
 
Line 1318
   
   
 /**  /**
  * 'victim' moves onto 'trap' (trap has FLAG_WALK_ON or FLAG_FLY_ON set) or   * 'victim' moves onto 'trap'
  * 'victim' leaves 'trap' (trap has FLAG_WALK_OFF or FLAG_FLY_OFF) set.   * 'victim' leaves 'trap'
    * effect is determined by move_on/move_off of trap and move_type of victime.
  *   *
  * originator: Player, monster or other object that caused 'victim' to move   * originator: Player, monster or other object that caused 'victim' to move
  * onto 'trap'.  Will receive messages caused by this action.  May be NULL.   * onto 'trap'.  Will receive messages caused by this action.  May be NULL.
Line 1337
 
Line 1330
 {  {
   static int recursion_depth = 0;    static int recursion_depth = 0;
   /* move_apply() is the most likely candidate for causing unwanted and    /* move_apply() is the most likely candidate for causing unwanted and
    * possibly unlimited recursion. */     * possibly unlimited recursion.
      */
   /* The following was changed because it was causing perfeclty correct    /* The following was changed because it was causing perfeclty correct
      maps to fail.  1)  it's not an error to recurse:     * maps to fail.  1)  it's not an error to recurse:
      rune detonates, summoning monster.  monster lands on nearby rune.     * rune detonates, summoning monster.  monster lands on nearby rune.
      nearby rune detonates.  This sort of recursion is expected and     * nearby rune detonates.  This sort of recursion is expected and
      proper.  This code was causing needless crashes. */     * proper.  This code was causing needless crashes.
      */
   if (recursion_depth >= 500) {    if (recursion_depth >= 500) {
     LOG (llevDebug, "WARNING: move_apply(): aborting recursion "      LOG (llevDebug, "WARNING: move_apply(): aborting recursion "
          "[trap arch %s, name %s; victim arch %s, name %s]\n",           "[trap arch %s, name %s; victim arch %s, name %s]\n",
Line 1350
 
Line 1345
     return;      return;
   }    }
   recursion_depth++;    recursion_depth++;
     if (trap->head)      if (trap->head) trap=trap->head;
         trap=trap->head;  
     /* Lauwenmark: Handle for plugin trigger event */      /* Lauwenmark: Handle for plugin trigger event */
     if (execute_event(trap, EVENT_TRIGGER,originator,victim,NULL,SCRIPT_FIX_ALL)!=0)      if (execute_event(trap, EVENT_TRIGGER,originator,victim,NULL,SCRIPT_FIX_ALL)!=0)
         return;          return;
   switch (trap->type)  
   {      switch (trap->type) {
   case PLAYERMOVER:    case PLAYERMOVER:
             if (trap->attacktype && (trap->level || victim->type!=PLAYER) &&              if (trap->attacktype && (trap->level || victim->type!=PLAYER) &&
                 !should_director_abort(trap, victim)) {                  !should_director_abort(trap, victim)) {
  if (!trap->stats.maxsp) trap->stats.maxsp=2.0;   if (!trap->stats.maxsp) trap->stats.maxsp=2.0;
   
  /* Is this correct?  From the docs, it doesn't look like it   /* Is this correct?  From the docs, it doesn't look like it
  * should be divided by trap->speed   * should be divided by trap->speed
  */   */
  victim->speed_left = -FABS(trap->stats.maxsp*victim->speed/trap->speed);   victim->speed_left = -FABS(trap->stats.maxsp*victim->speed/trap->speed);
   
  /* Just put in some sanity check.  I think there is a bug in the   /* Just put in some sanity check.  I think there is a bug in the
  * above with some objects have zero speed, and thus the player   * above with some objects have zero speed, and thus the player
  * getting permanently paralyzed.   * getting permanently paralyzed.
  */   */
  if (victim->speed_left<-50.0) victim->speed_left=-50.0;   if (victim->speed_left<-50.0) victim->speed_left=-50.0;
                 /* LOG(llevDebug, "apply, playermove, player speed_left=%f\n",   /* LOG(llevDebug, "apply, playermove, player speed_left=%f\n", victim->speed_left);*/
                  victim->speed_left);*/  
     }      }
     goto leave;      goto leave;
   
Line 1403
 
Line 1399
     if (trap->inv == NULL)      if (trap->inv == NULL)
       goto leave;        goto leave;
     /* fallthrough */      /* fallthrough */
   
   case ARROW:    case ARROW:
   
       /* bad bug: monster throw a object, make a step forwards, step on object ,        /* bad bug: monster throw a object, make a step forwards, step on object ,
        * trigger this here and get hit by own missile - and will be own enemy.         * trigger this here and get hit by own missile - and will be own enemy.
        * Victim then is his own enemy and will start to kill herself (this is         * Victim then is his own enemy and will start to kill herself (this is
        * removed) but we have not synced victim and his missile. To avoid senseless         * removed) but we have not synced victim and his missile. To avoid senseless
        * action, we avoid hits here */        * action, we avoid hits here
             if ((QUERY_FLAG (victim, FLAG_ALIVE) && trap->speed) &&        */
                  trap->owner != victim)       if ((QUERY_FLAG (victim, FLAG_ALIVE) && trap->speed) && trap->owner != victim)
       hit_with_arrow (trap, victim);        hit_with_arrow (trap, victim);
     goto leave;      goto leave;
   
   
     case SPELL_EFFECT:      case SPELL_EFFECT:
  apply_spell_effect(trap, victim);   apply_spell_effect(trap, victim);
  goto leave;   goto leave;
Line 1422
 
Line 1419
   case TRAPDOOR:    case TRAPDOOR:
     {      {
       int max, sound_was_played;        int max, sound_was_played;
       object *ab;       object *ab, *ab_next;
       if(!trap->value) {        if(!trap->value) {
         int tot;          int tot;
         for(ab=trap->above,tot=0;ab!=NULL;ab=ab->above)          for(ab=trap->above,tot=0;ab!=NULL;ab=ab->above)
           if(!QUERY_FLAG(ab,FLAG_FLYING))       if ((ab->move_type && trap->move_on) || ab->move_type==0)
             tot += (ab->nrof ? ab->nrof : 1) * ab->weight + ab->carrying;              tot += (ab->nrof ? ab->nrof : 1) * ab->weight + ab->carrying;
   
         if(!(trap->value=(tot>trap->weight)?1:0))          if(!(trap->value=(tot>trap->weight)?1:0))
           goto leave;            goto leave;
   
  SET_ANIMATION(trap, trap->value);   SET_ANIMATION(trap, trap->value);
         update_object(trap,UP_OBJ_FACE);          update_object(trap,UP_OBJ_FACE);
       }        }
       for (ab = trap->above, max=100, sound_was_played = 0;  
            --max && ab && ! QUERY_FLAG (ab, FLAG_FLYING); ab=ab->above)       for (ab = trap->above, max=100, sound_was_played = 0; --max && ab; ab=ab_next) {
       {   /* need to set this up, since if we do transfer the object,
    * ab->above would be bogus
    */
    ab_next = ab->above;
   
    if ((ab->move_type && trap->move_on) || ab->move_type==0) {
         if ( ! sound_was_played) {          if ( ! sound_was_played) {
           play_sound_map(trap->map, trap->x, trap->y, SOUND_FALL_HOLE);            play_sound_map(trap->map, trap->x, trap->y, SOUND_FALL_HOLE);
           sound_was_played = 1;            sound_was_played = 1;
Line 1443
 
Line 1447
         new_draw_info(NDI_UNIQUE, 0,ab,"You fall into a trapdoor!");          new_draw_info(NDI_UNIQUE, 0,ab,"You fall into a trapdoor!");
         transfer_ob(ab,(int)EXIT_X(trap),(int)EXIT_Y(trap),0,ab);          transfer_ob(ab,(int)EXIT_X(trap),(int)EXIT_Y(trap),0,ab);
       }        }
        }
       goto leave;        goto leave;
     }      }
   
   
   case CONVERTER:    case CONVERTER:
     if (convert_item (victim, trap) < 0) {      if (convert_item (victim, trap) < 0) {
  object *op;   object *op;
   
                 new_draw_info_format(NDI_UNIQUE, 0, originator,   new_draw_info_format(NDI_UNIQUE, 0, originator, "The %s seems to be broken!", query_name(trap));
                                      "The %s seems to be broken!",  
                                      query_name(trap));  
   
  op = get_archetype("burnout");   op = get_archetype("burnout");
  if (op != NULL) {   if (op != NULL) {
Line 1481
 
Line 1485
     /* Hole not open? */      /* Hole not open? */
     if(trap->stats.wc > 0)      if(trap->stats.wc > 0)
       goto leave;        goto leave;
   
     /* Is this a multipart monster and not the head?  If so, return.      /* Is this a multipart monster and not the head?  If so, return.
      * Processing will happen if the head runs into the pit       * Processing will happen if the head runs into the pit
      */       */
     if (victim->head)      if (victim->head)
       goto leave;        goto leave;
   
     play_sound_map (victim->map, victim->x, victim->y, SOUND_FALL_HOLE);      play_sound_map (victim->map, victim->x, victim->y, SOUND_FALL_HOLE);
     new_draw_info (NDI_UNIQUE, 0, victim, "You fall through the hole!\n");      new_draw_info (NDI_UNIQUE, 0, victim, "You fall through the hole!\n");
     transfer_ob (victim, EXIT_X (trap), EXIT_Y (trap), 1, victim);      transfer_ob (victim, EXIT_X (trap), EXIT_Y (trap), 1, victim);
Line 1496
 
Line 1502
  /* Basically, don't show exits leading to random maps the   /* Basically, don't show exits leading to random maps the
  * players output.   * players output.
  */   */
                 if (trap->msg && strncmp(EXIT_PATH(trap),"/!",2)   if (trap->msg && strncmp(EXIT_PATH(trap),"/!",2) && strncmp(EXIT_PATH(trap), "/random/", 8))
                     && strncmp(EXIT_PATH(trap), "/random/", 8))  
      new_draw_info (NDI_NAVY, 0, victim, trap->msg);       new_draw_info (NDI_NAVY, 0, victim, trap->msg);
       enter_exit (victim, trap);        enter_exit (victim, trap);
     }      }
Line 1519
 
Line 1524
   case SIGN:    case SIGN:
     if (victim->type != PLAYER && trap->stats.food > 0)      if (victim->type != PLAYER && trap->stats.food > 0)
       goto leave; /* monsters musn't apply magic_mouths with counters */        goto leave; /* monsters musn't apply magic_mouths with counters */
   
     apply_sign (victim, trap, 1);      apply_sign (victim, trap, 1);
     goto leave;      goto leave;
   
Line 1531
 
Line 1537
   
   case RUNE:    case RUNE:
   case TRAP:    case TRAP:
     if (trap->level && QUERY_FLAG (victim, FLAG_ALIVE))       if (trap->level && QUERY_FLAG (victim, FLAG_ALIVE)) {
         spring_trap(trap, victim);          spring_trap(trap, victim);
        }
     goto leave;      goto leave;
   
   default:    default:
Line 2546
 
Line 2553
 {  {
     int tmp;      int tmp;
   
     if (op->env == NULL && QUERY_FLAG (pl, FLAG_FLYING))      if (op->env == NULL && (pl->move_type & MOVE_FLYING)) {
     {  
         /* player is flying and applying object not in inventory */          /* player is flying and applying object not in inventory */
         if ( ! QUERY_FLAG (pl, FLAG_WIZ)          if ( ! QUERY_FLAG (pl, FLAG_WIZ) && !(op->move_type & MOVE_FLYING)) {
             && ! QUERY_FLAG (op, FLAG_FLYING)  
             && ! QUERY_FLAG (op, FLAG_FLY_ON))  
         {  
             new_draw_info (NDI_UNIQUE, 0, pl, "But you are floating high "              new_draw_info (NDI_UNIQUE, 0, pl, "But you are floating high "
                            "above the ground!");                             "above the ground!");
             return 0;              return 0;
Line 2614
 
Line 2617
             floors++;              floors++;
         else if (floors > 0)          else if (floors > 0)
             return;   /* process only floor objects after first floor object */              return;   /* process only floor objects after first floor object */
  if ( ! tmp->invisible || QUERY_FLAG (tmp, FLAG_WALK_ON)  
             || QUERY_FLAG (tmp, FLAG_FLY_ON))   /* If it is visible, player can apply it.  If it is applied by
         {   * person moving on it, also activate.  Added code to make it
    * so that at least one of players movement types be that which
    * the item needs.
    */
    if ( ! tmp->invisible || (tmp->move_on & pl->move_type)) {
             if (player_apply (pl, tmp, 0, 1) == 1)              if (player_apply (pl, tmp, 0, 1) == 1)
                 return;                  return;
         }          }


Legend:
line(s) removed in v.1.148 
line(s) changed
 line(s) added in v.1.149

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