Difference for server/player.c from version 1.131 to 1.132


version 1.131 version 1.132
Line 1
 
Line 1
 /*  /*
  * static char *rcsid_player_c =   * static char *rcsid_player_c =
  *   "$Id: player.c,v 1.131 2003/09/04 06:25:32 temitchell Exp $";   *   "$Id: player.c,v 1.132 2003/09/13 05:02:12 mwedel Exp $";
  */   */
   
 /*  /*
Line 167
 
Line 167
     strncpy(p->title,op->arch->clone.name,MAX_NAME);      strncpy(p->title,op->arch->clone.name,MAX_NAME);
     op->race = add_string (op->arch->clone.race);      op->race = add_string (op->arch->clone.race);
   
     /* Would be better of '0' was not a defined spell */  
     for(i=0;i<NROFREALSPELLS;i++)  
  p->known_spells[i]= -1;  
   
     p->chosen_spell = -1;  
     CLEAR_FLAG(op,FLAG_READY_SKILL);       CLEAR_FLAG(op,FLAG_READY_SKILL);
   
     /* we need to clear these to -1 and not zero - otherwise,      /* we need to clear these to -1 and not zero - otherwise,
Line 179
 
Line 174
      * send new values to the client, as things like exp start       * send new values to the client, as things like exp start
      * at zero.       * at zero.
      */       */
     for (i=0; i < MAX_EXP_CAT; i++) {      for (i=0; i < NUM_SKILLS; i++) {
  p->last_skill_exp[i] = -1;   p->last_skill_exp[i] = -1;
  p->last_skill_level[i] = -1;   p->last_skill_ob[i] = NULL;
     }      }
     for (i=0; i < NROFATTACKS; i++) {      for (i=0; i < NROFATTACKS; i++) {
  p->last_resist[i] = -1;   p->last_resist[i] = -1;
     }      }
     p->last_skill_index = -1;  
     p->last_stats.exp = -1;      p->last_stats.exp = -1;
   
     p->socket.update_look=0;      p->socket.update_look=0;
Line 468
 
Line 462
   
 void give_initial_items(object *pl,treasurelist *items) {  void give_initial_items(object *pl,treasurelist *items) {
     object *op,*next=NULL;      object *op,*next=NULL;
     /* Lets at least use the SP_ values here and not just numbers, like 0, 1, ... */  
   
     int start_spells[] = {SP_BULLET, SP_S_FIREBALL, SP_BURNING_HANDS,  
  SP_S_LIGHTNING, SP_M_MISSILE ,SP_ICESTORM, SP_S_SNOWSTORM};  
     int nrof_start_spells = sizeof start_spells / sizeof start_spells[0];  
   
     int start_prayers[] = {SP_TURN_UNDEAD, SP_HOLY_WORD, SP_MINOR_HEAL,  
  SP_CAUSE_LIGHT};  
     int nrof_start_prayers = sizeof start_prayers / sizeof start_prayers[0];  
     int idx;  
   
   
     if(pl->randomitems!=NULL)      if(pl->randomitems!=NULL)
  create_treasure(items,pl,GT_STARTEQUIP | GT_ONLY_GOOD,1,0);   create_treasure(items,pl,GT_STARTEQUIP | GT_ONLY_GOOD,1,0);
Line 487
 
Line 470
  next = op->below;   next = op->below;
    
  /* Forces get applied per default, unless they have the   /* Forces get applied per default, unless they have the
            flag "neutral" set. Sorry but I can't think of a better way */           * flag "neutral" set. Sorry but I can't think of a better way
    */
   if(op->type==FORCE && !QUERY_FLAG(op, FLAG_NEUTRAL))    if(op->type==FORCE && !QUERY_FLAG(op, FLAG_NEUTRAL))
    { SET_FLAG(op,FLAG_APPLIED);};       SET_FLAG(op,FLAG_APPLIED);
    
  /* we never give weapons/armour if these cannot be used   /* we never give weapons/armour if these cannot be used
            by this player due to race restrictions */           * by this player due to race restrictions
    */
  if (pl->type == PLAYER) {   if (pl->type == PLAYER) {
    if ((!QUERY_FLAG(pl, FLAG_USE_ARMOUR) &&     if ((!QUERY_FLAG(pl, FLAG_USE_ARMOUR) &&
        (op->type == ARMOUR || op->type == BOOTS ||         (op->type == ARMOUR || op->type == BOOTS ||
Line 506
 
Line 491
    }     }
  }   }
    
   if(op->type==SPELLBOOK) { /* fix spells for first level spells */   /* This really needs to be better - we should really give
      if (strcmp (op->arch->name, "cleric_book") == 0) {   * a substitute spellbook.  The problem is that we don't really
  if (nrof_start_prayers <= 0) {   * have a good idea what to replace it with (need something like
      remove_ob (op);   * a first level treasurelist for each skill.)
      free_object (op);   * remove duplicate skills also
      continue;   */
  }    if(op->type==SPELLBOOK || op->type == SKILL) {
  idx = RANDOM() % nrof_start_prayers;       object *tmp;
  op->stats.sp = start_prayers[idx];  
  /* This makes sure the character does not get duplicate spells */       for (tmp=op->below; tmp; tmp=tmp->below)
  start_prayers[idx] = start_prayers[nrof_start_prayers - 1];   if (tmp->type == op->type && tmp->name == op->name) break;
  nrof_start_prayers--;  
      } else {       if (tmp) {
  if (nrof_start_spells <= 0) {  
      remove_ob (op);       remove_ob (op);
      free_object (op);       free_object (op);
    LOG(llevError,"give_initial_items: Removing duplicate object %s\n",
        tmp->name);
      continue;       continue;
  }   }
  idx = RANDOM() % nrof_start_spells;       if (op->nrof > 1) op->nrof = 1;
  op->stats.sp = start_spells[idx];  
  start_spells[idx] = start_spells[nrof_start_spells - 1];  
  nrof_start_spells--;  
      }       }
   
    if (op->type == SPELLBOOK && op->inv) {
        CLEAR_FLAG(op->inv, FLAG_STARTEQUIP);
  }   }
   
  /* Give starting characters identified, uncursed, and undamned   /* Give starting characters identified, uncursed, and undamned
  * items.  Just don't identify gold or silver, or it won't be   * items.  Just don't identify gold or silver, or it won't be
  * merged properly.   * merged properly.
Line 539
 
Line 526
      CLEAR_FLAG(op, FLAG_CURSED);       CLEAR_FLAG(op, FLAG_CURSED);
      CLEAR_FLAG(op, FLAG_DAMNED);       CLEAR_FLAG(op, FLAG_DAMNED);
  }   }
  if(op->type==ABILITY)  {   if(op->type==SPELL)  {
      pl->contr->known_spells[pl->contr->nrofknownspells++]=op->stats.sp;  
      remove_ob(op);       remove_ob(op);
      free_object(op);       free_object(op);
             continue;              continue;
  }   }
    if(op->type==SKILL)  {
        SET_FLAG(op, FLAG_CAN_USE_SKILL);
        op->stats.exp = 0;
        op->level = 1;
    }
     } /* for loop of objects in player inv */      } /* for loop of objects in player inv */
   
       /* Need to set up the skill pointers */
       link_player_skills(pl);
 }  }
   
 void get_name(object *op) {  void get_name(object *op) {
Line 892
 
Line 886
 #endif  #endif
  start_info(op);   start_info(op);
  CLEAR_FLAG(op, FLAG_WIZ);   CLEAR_FLAG(op, FLAG_WIZ);
  (void) init_player_exp(op);  
  give_initial_items(op,op->randomitems);   give_initial_items(op,op->randomitems);
  (void) link_player_skills(op);   link_player_skills(op);
  esrv_send_inventory(op, op);   esrv_send_inventory(op, op);
  return 0;   return 0;
     }      }
Line 1376
 
Line 1369
 {  {
     object *tmp = NULL;      object *tmp = NULL;
     mapstruct *m;      mapstruct *m;
     int i, mflags, found, number, dex;      int i, mflags, found, number;
     sint16 x, y;      sint16 x, y;
   
     if (op->map == NULL)      if (op->map == NULL)
  return find_arrow(op, type);   return find_arrow(op, type);
   
     /* do a dex check */      /* do a dex check */
     dex = get_skill_stat1(op) ? get_skill_stat1(op) : 10;  
     number = (die_roll(2, 40, op, PREFER_LOW)-2)/2;      number = (die_roll(2, 40, op, PREFER_LOW)-2)/2;
     if (number > (dex + SK_level(op)))      if (number > (op->stats.Dex + (op->chosen_skill?op->chosen_skill->level:op->level)))
  return find_arrow(op, type);   return find_arrow(op, type);
   
     m = op->map;      m = op->map;
Line 1457
 
Line 1449
      return 0;       return 0;
  }   }
     }      }
     if( !bow->race ) {      if( !bow->race || !bow->skill) {
  new_draw_info_format(NDI_UNIQUE, 0, op, "Your %s is broken.", bow->name);   new_draw_info_format(NDI_UNIQUE, 0, op, "Your %s is broken.", bow->name);
  return 0;   return 0;
     }      }
Line 1504
 
Line 1496
  return 0;   return 0;
     }      }
     set_owner(arrow, op);      set_owner(arrow, op);
       if (arrow->skill) free_string(arrow->skill);
       arrow->skill = add_refcount(bow->skill);
   
     arrow->direction=dir;      arrow->direction=dir;
     arrow->x = sx;      arrow->x = sx;
Line 1542
 
Line 1536
   
   
     if (op->type == PLAYER) {      if (op->type == PLAYER) {
  arrow->stats.wc = 20 - bow->magic - arrow->magic - SK_level(op) -   arrow->stats.wc = 20 - bow->magic - arrow->magic -
        (op->chosen_skill?op->chosen_skill->level:op->level) -
      dex_bonus[op->stats.Dex] - thaco_bonus[op->stats.Str] -       dex_bonus[op->stats.Dex] - thaco_bonus[op->stats.Str] -
      arrow->stats.wc - bow->stats.wc + wc_mod;       arrow->stats.wc - bow->stats.wc + wc_mod;
   
  arrow->level = SK_level (op);   arrow->level = op->chosen_skill?op->chosen_skill->level:op->level;
     } else {      } else {
  arrow->stats.wc= op->stats.wc - bow->magic - arrow->magic -   arrow->stats.wc= op->stats.wc - bow->magic - arrow->magic -
      arrow->stats.wc + wc_mod;       arrow->stats.wc + wc_mod;
Line 1628
 
Line 1623
     }      }
   
     item = op->contr->ranges[range_misc];      item = op->contr->ranges[range_misc];
       if (!item->inv) {
    LOG(llevError,"Object %s lacks a spell\n", item->name);
    return;
       }
     if (item->type == WAND) {      if (item->type == WAND) {
  if(item->stats.food<=0) {   if(item->stats.food<=0) {
      play_sound_player_only(op->contr, SOUND_WAND_POOF,0,0);       play_sound_player_only(op->contr, SOUND_WAND_POOF,0,0);
Line 1635
 
Line 1634
      return;       return;
  }   }
     } else if (item->type == ROD || item->type==HORN) {      } else if (item->type == ROD || item->type==HORN) {
  if(item->stats.hp<spells[item->stats.sp].sp) {   if(item->stats.hp<MAX(item->inv->stats.sp, item->inv->stats.grace)) {
      play_sound_player_only(op->contr, SOUND_WAND_POOF,0,0);       play_sound_player_only(op->contr, SOUND_WAND_POOF,0,0);
      if (item->type== ROD)       if (item->type== ROD)
  new_draw_info_format(NDI_UNIQUE, 0,op,   new_draw_info_format(NDI_UNIQUE, 0,op,
Line 1647
 
Line 1646
  }   }
     }      }
   
     if(cast_spell(op,item,dir,item->stats.sp,0,spellMisc,NULL)) {      if(cast_spell(op,item,dir,item->inv,NULL)) {
  SET_FLAG(op, FLAG_BEEN_APPLIED); /* You now know something about it */   SET_FLAG(op, FLAG_BEEN_APPLIED); /* You now know something about it */
  if (item->type == WAND) {   if (item->type == WAND) {
      if (!(--item->stats.food)) {       if (!(--item->stats.food)) {
Line 1668
 
Line 1667
     }      }
 }  }
   
   /* Received a fire command for the player - go and do it.
    */
 void fire(object *op,int dir) {  void fire(object *op,int dir) {
     int spellcost=0;      int spellcost=0;
   
     /* check for loss of invisiblity/hide */      /* check for loss of invisiblity/hide */
     if (action_makes_visible(op)) make_visible(op);      if (action_makes_visible(op)) make_visible(op);
   
     /* a check for players, make sure things are groovy. This routine  
      * will change the skill of the player as appropriate in order to  
      * fire whatever is requested. In the case of spells (range_magic)  
      * it handles whether cleric or mage spell is requested to be cast.   
      * -b.t.   
      */   
     if(op->type==PLAYER)   
  if(!check_skill_to_fire(op)) return;  
   
     switch(op->contr->shoottype) {      switch(op->contr->shoottype) {
  case range_none:   case range_none:
      return;       return;
Line 1692
 
Line 1684
      return;       return;
   
  case range_magic: /* Casting spells */   case range_magic: /* Casting spells */
      op->contr->shoottype= range_magic;       spellcost=cast_spell(op,op,dir,op->contr->ranges[range_magic],NULL);
      spellcost=cast_spell(op,op,dir,op->contr->chosen_spell,0,spellNormal,NULL);  
   
      if(spells[op->contr->chosen_spell].cleric)  
  op->stats.grace-=spellcost;  
      else  
  op->stats.sp-=spellcost;  
      return;       return;
   
  case range_misc:   case range_misc:
Line 1706
 
Line 1692
      return;       return;
   
  case range_golem: /* Control summoned monsters from scrolls */   case range_golem: /* Control summoned monsters from scrolls */
      if(op->contr->golem==NULL) {       if(op->contr->ranges[range_golem]==NULL ||
           op->contr->golem_count != op->contr->ranges[range_golem]->count) {
    op->contr->ranges[range_golem] = NULL;
  op->contr->shoottype=range_none;   op->contr->shoottype=range_none;
  op->contr->chosen_spell= -1;   op->contr->golem_count = 0;
      }       }
      else        else
  control_golem(op->contr->golem, dir);   control_golem(op->contr->ranges[range_golem], dir);
      return;       return;
   
  case range_skill:   case range_skill:
Line 1720
 
Line 1708
      new_draw_info(NDI_UNIQUE, 0,op,"You have no applicable skill to use.");       new_draw_info(NDI_UNIQUE, 0,op,"You have no applicable skill to use.");
  return;   return;
      }       }
      (void) do_skill(op,op,dir,NULL);       (void) do_skill(op,op,op->chosen_skill,dir,NULL);
      return;       return;
  default:   default:
      new_draw_info(NDI_UNIQUE, 0,op,"Illegal shoot type.");       new_draw_info(NDI_UNIQUE, 0,op,"Illegal shoot type.");
Line 1971
 
Line 1959
   
      op->contr->has_hit = 1; /* The last action was to hit, so use weapon_sp */       op->contr->has_hit = 1; /* The last action was to hit, so use weapon_sp */
   
      skill_attack(mon, op, 0, NULL);       skill_attack(mon, op, 0, NULL, NULL);
      /* If attacking another player, that player gets automatic       /* If attacking another player, that player gets automatic
       * hitback, and doesn't loose luck either.        * hitback, and doesn't loose luck either.
       */        */
      if (mon->type == PLAYER && mon->stats.hp >= 0 && !mon->contr->has_hit) {       if (mon->type == PLAYER && mon->stats.hp >= 0 && !mon->contr->has_hit) {
  short luck = mon->stats.luck;   short luck = mon->stats.luck;
  mon->contr->has_hit = 1;   mon->contr->has_hit = 1;
  skill_attack(op, mon, 0, NULL);   skill_attack(op, mon, 0, NULL, NULL);
  mon->stats.luck = luck;   mon->stats.luck = luck;
      }       }
      if(action_makes_visible(op)) make_visible(op);       if(action_makes_visible(op)) make_visible(op);
Line 2051
 
Line 2039
      * destroys the golem looks correct, and it doesn't always happen, so       * destroys the golem looks correct, and it doesn't always happen, so
      * put this in a a workaround to clean up the golem pointer.       * put this in a a workaround to clean up the golem pointer.
      */       */
     if (op->contr->golem &&       if (op->contr->ranges[range_golem] &&
  ((op->contr->golem_count != op->contr->golem->count) ||    ((op->contr->golem_count != op->contr->ranges[range_golem]->count) ||
  QUERY_FLAG(op->contr->golem, FLAG_REMOVED))) {   QUERY_FLAG(op->contr->ranges[range_golem], FLAG_REMOVED))) {
  op->contr->golem = NULL;   op->contr->ranges[range_golem] = NULL;
  op->contr->golem_count = 0;   op->contr->golem_count = 0;
     }      }
   
Line 2216
 
Line 2204
     }      }
   
     /* Regenerate Spell Points */      /* Regenerate Spell Points */
     if(op->contr->golem==NULL&&--op->last_sp<0) {      if(op->contr->ranges[range_golem]==NULL && --op->last_sp<0) {
       gen_sp = gen_sp * 10 / (op->contr->gen_sp_armour < 10? 10 : op->contr->gen_sp_armour);        gen_sp = gen_sp * 10 / (op->contr->gen_sp_armour < 10? 10 : op->contr->gen_sp_armour);
       if(op->stats.sp<op->stats.maxsp) {        if(op->stats.sp<op->stats.maxsp) {
  op->stats.sp++;   op->stats.sp++;
Line 2345
 
Line 2333
     char buf[MAX_BUF];      char buf[MAX_BUF];
     int x,y,i;      int x,y,i;
     mapstruct *map;  /*  this is for resurrection */      mapstruct *map;  /*  this is for resurrection */
     object *tmp;  
     int z;      int z;
     int num_stats_lose;      int num_stats_lose;
     int lost_a_stat;      int lost_a_stat;
Line 2354
 
Line 2341
     int killed_script_rtn; /* GROS: For script return value */      int killed_script_rtn; /* GROS: For script return value */
     CFParm CFP;      CFParm CFP;
     int evtid;      int evtid;
       archetype *at;
       object *tmp;
     event *evt;      event *evt;
   
     if(save_life(op))      if(save_life(op))
  return;   return;
   
   
     /* If player dies on BATTLEGROUND, no stat/exp loss! For Combat-Arenas      /* If player dies on BATTLEGROUND, no stat/exp loss! For Combat-Arenas
      * in cities ONLY!!! It is very important that this doesn't get abused.       * in cities ONLY!!! It is very important that this doesn't get abused.
      * Look at op_on_battleground() for more info       --AndreasV       * Look at op_on_battleground() for more info       --AndreasV
Line 2369
 
Line 2360
      "Local medics have saved your life...");       "Local medics have saved your life...");
   
       /* restore player */        /* restore player */
       cast_heal(op, 0, SP_CURE_POISON);   at = find_archetype("poisoning");
       cast_heal(op, 0, SP_CURE_CONFUSION);          tmp=present_arch_in_ob(at,op);
    if (tmp) {
        remove_ob(tmp);
        free_object(tmp);
        new_draw_info(NDI_UNIQUE, 0,op, "Your body feels cleansed");
    }
   
    at = find_archetype("confusion");
           tmp=present_arch_in_ob(at,op);
    if (tmp) {
        remove_ob(tmp);
        free_object(tmp);
               new_draw_info(NDI_UNIQUE, 0,tmp, "Your mind feels clearer");
    }
   
       cure_disease(op,0);  /* remove any disease */        cure_disease(op,0);  /* remove any disease */
       op->stats.hp=op->stats.maxhp;        op->stats.hp=op->stats.maxhp;
       if (op->stats.food<=0) op->stats.food=999;        if (op->stats.food<=0) op->stats.food=999;
Line 2593
 
Line 2598
  /**************************************/   /**************************************/
   
  /* remove any poisoning and confusion the character may be suffering.*/   /* remove any poisoning and confusion the character may be suffering.*/
  cast_heal(op, 0, SP_CURE_POISON);   /* restore player */
  cast_heal(op, 0, SP_CURE_CONFUSION);   at = find_archetype("poisoning");
           tmp=present_arch_in_ob(at,op);
    if (tmp) {
        remove_ob(tmp);
        free_object(tmp);
        new_draw_info(NDI_UNIQUE, 0,op, "Your body feels cleansed");
    }
   
    at = find_archetype("confusion");
           tmp=present_arch_in_ob(at,op);
    if (tmp) {
        remove_ob(tmp);
        free_object(tmp);
               new_draw_info(NDI_UNIQUE, 0,tmp, "Your mind feels clearer");
    }
  cure_disease(op,0);  /* remove any disease */   cure_disease(op,0);  /* remove any disease */
    
  /*add_exp(op, (op->stats.exp * -0.20)); */   /*add_exp(op, (op->stats.exp * -0.20)); */
Line 2645
 
Line 2664
      op->contr->own_title[0]='\0';       op->contr->own_title[0]='\0';
  new_draw_info(NDI_UNIQUE|NDI_ALL, 0,NULL, buf);   new_draw_info(NDI_UNIQUE|NDI_ALL, 0,NULL, buf);
  check_score(op);   check_score(op);
  if(op->contr->golem!=NULL) {   if(op->contr->ranges[range_golem]!=NULL) {
      remove_friendly_object(op->contr->golem);       remove_friendly_object(op->contr->ranges[range_golem]);
      remove_ob(op->contr->golem);       remove_ob(op->contr->ranges[range_golem]);
      free_object(op->contr->golem);       free_object(op->contr->ranges[range_golem]);
      op->contr->golem=NULL;       op->contr->ranges[range_golem]=NULL;
        op->contr->golem_count=0;
  }   }
  loot_object(op); /* Remove some of the items for good */   loot_object(op); /* Remove some of the items for good */
  remove_ob(op);   remove_ob(op);
Line 2754
 
Line 2774
 }  }
   
   
 /* cast_dust() - handles op throwing objects of type 'DUST' */  /* cast_dust() - handles op throwing objects of type 'DUST'.
    * This is much simpler in the new spell code - we basically
    * just treat this as any other spell casting object.
    */
    
 void cast_dust (object *op, object *throw_ob, int dir) {  void cast_dust (object *op, object *throw_ob, int dir) {
   archetype *arch = find_archetype(spells[throw_ob->stats.sp].archname);      object *skop, *spob;
   
       skop = find_skill_by_name(op, throw_ob->skill);
    
   /* casting POTION 'dusts' is really a use_magic_item skill */    /* casting POTION 'dusts' is really a use_magic_item skill */
   if(op->type==PLAYER&&throw_ob->type==POTION      if(op->type==PLAYER && throw_ob->type==POTION && !skop) {
  &&!change_skill(op,SK_USE_MAGIC_ITEM)) {  
       LOG(llevError,"Player %s lacks critical skill use_magic_item!\n",        LOG(llevError,"Player %s lacks critical skill use_magic_item!\n",
                 op->name);                  op->name);
       return;        return;
   }    }
       spob = throw_ob->inv;
       if (op->type==PLAYER && spob)
    new_draw_info_format(NDI_UNIQUE, 0,op,"You cast %s.",spob->name);
    
   if(throw_ob->type==POTION&&arch!= NULL)      cast_spell(op, throw_ob, dir, spob, NULL);
     cast_cone(op,throw_ob,dir,10,throw_ob->stats.sp,arch,1);  
   else if((arch=find_archetype("dust_effect"))!=NULL) { /* dust_effect */  
     cast_cone(op,throw_ob,dir,1,0,arch,0);  
   } else /* problem occured! */   
     LOG(llevError,"cast_dust() can't find an archetype to use!\n");  
    
   if (op->type==PLAYER&&arch)  
     new_draw_info_format(NDI_UNIQUE, 0,op,"You cast %s.",query_name(throw_ob));  
   if(!QUERY_FLAG(throw_ob,FLAG_REMOVED)) remove_ob(throw_ob);    if(!QUERY_FLAG(throw_ob,FLAG_REMOVED)) remove_ob(throw_ob);
   free_object(throw_ob);    free_object(throw_ob);
 }  }
Line 2783
 
Line 2803
 void make_visible (object *op) {  void make_visible (object *op) {
     op->hide = 0;      op->hide = 0;
     op->invisible = 0;      op->invisible = 0;
     if(op->type==PLAYER)       if(op->type==PLAYER) {
       op->contr->tmp_invis = 0;        op->contr->tmp_invis = 0;
     CLEAR_FLAG(op, FLAG_INVIS_UNDEAD);   if (op->contr->invis_race) FREE_AND_CLEAR_STR(op->contr->invis_race);
       }
     update_object(op,UP_OBJ_FACE);      update_object(op,UP_OBJ_FACE);
 }  }
   
Line 2843
 
Line 2864
   
 void do_hidden_move (object *op) {  void do_hidden_move (object *op) {
     int hide=0, num=random_roll(0, 19, op, PREFER_LOW);      int hide=0, num=random_roll(0, 19, op, PREFER_LOW);
       object *skop;
          
     if(!op || !op->map) return;      if(!op || !op->map) return;
   
     /* its *extremely* hard to run and sneak/hide at the same time! */      /* its *extremely* hard to run and sneak/hide at the same time! */
     if(op->type==PLAYER && op->contr->run_on) {      if(op->type==PLAYER && op->contr->run_on) {
       if(num >= SK_level(op)) {   skop = find_obj_by_type_subtype(op, SKILL, SK_HIDING);
   
    if(!skop || num >= skop->level) {
         new_draw_info(NDI_UNIQUE,0,op,"You ran too much! You are no longer hidden!");          new_draw_info(NDI_UNIQUE,0,op,"You ran too much! You are no longer hidden!");
         make_visible(op);          make_visible(op);
         return;          return;
Line 2862
 
Line 2886
       if(op->type==PLAYER) new_draw_info(NDI_UNIQUE, 0,op,        if(op->type==PLAYER) new_draw_info(NDI_UNIQUE, 0,op,
           "You moved out of hiding! You are visible!");            "You moved out of hiding! You are visible!");
     }      }
       else if (op->type == PLAYER && skop) {
    change_exp(op, calc_skill_exp(op, NULL, skop), skop->skill, 0);
       }
 }  }
   
 /* determine if who is standing near a hostile creature. */  /* determine if who is standing near a hostile creature. */
Line 2952
 
Line 2979
   if(op->invisible && QUERY_FLAG(op,FLAG_ALIVE)) {    if(op->invisible && QUERY_FLAG(op,FLAG_ALIVE)) {
     if(QUERY_FLAG(op,FLAG_MAKE_INVIS))       if(QUERY_FLAG(op,FLAG_MAKE_INVIS))
       return 0;         return 0;
     else if(op->hide || (op->contr&&op->contr->tmp_invis)) {   
    if (op->contr && op->contr->tmp_invis == 0) return 0;
   
    /* If monsters, they should become visible */
    if(op->hide || !op->contr || (op->contr && op->contr->tmp_invis)) {
       new_draw_info_format(NDI_UNIQUE, 0,op,"You become %s!",op->hide?"unhidden":"visible");        new_draw_info_format(NDI_UNIQUE, 0,op,"You become %s!",op->hide?"unhidden":"visible");
       return 1;         return 1;
     } else if(op->contr && !op->contr->shoottype==range_magic) {   
    /* improved invis is lost EXCEPT for case of casting of magic */  
           new_draw_info(NDI_UNIQUE, 0,op,"Your invisibility spell is broken!");  
           return 1;  
     }      }
   }    }
   
   return 0;    return 0;
 }  }
   
Line 3006
 
Line 3032
 void dragon_ability_gain(object *who, int atnr, int level) {  void dragon_ability_gain(object *who, int atnr, int level) {
   treasurelist *trlist = NULL;   /* treasurelist */    treasurelist *trlist = NULL;   /* treasurelist */
   treasure *tr;                  /* treasure */    treasure *tr;                  /* treasure */
   object *tmp;                   /* tmp. object */      object *tmp,*skop;     /* tmp. object */
   object *item;                  /* treasure object */    object *item;                  /* treasure object */
   char buf[MAX_BUF];             /* tmp. string buffer */    char buf[MAX_BUF];             /* tmp. string buffer */
   int i=0, j=0;    int i=0, j=0;
Line 3037
 
Line 3063
      
   /* grant direct spell */    /* grant direct spell */
   if (item->type == SPELLBOOK) {    if (item->type == SPELLBOOK) {
     int spell = look_up_spell_name (item->slaying);   if (check_spell_known (who, item->inv->name))
     if (spell<0 || check_spell_known (who, spell))  
       return;        return;
     if (item->invisible) {      if (item->invisible) {
       sprintf(buf, "You gained the ability of %s", spells[spell].name);       new_draw_info_format(NDI_UNIQUE|NDI_BLUE, 0, who, "You gained the ability of %s", item->inv->name);
       new_draw_info(NDI_UNIQUE|NDI_BLUE, 0, who, buf);       do_learn_spell (who, item->inv, 0);
       do_learn_spell (who, spell, 0);  
       return;        return;
     }      }
   }    }
   else if (item->type == SKILL) {    else if (item->type == SKILL) {
     if (strcmp(item->title, "clawing") == 0 &&   if (item->subtype == SK_CLAWING && (skop=find_skill_by_name(who, item->skill))!=NULL) {
  change_skill (who, lookup_skill_by_name("clawing"))) {  
       /* adding new attacktypes to the clawing skill */  
       tmp = who->chosen_skill; /* clawing skill object */  
               
       if (tmp->type == SKILL && strcmp(tmp->name, "clawing")==0       /* should this perhaps be (skop->attackyp & item->attacktype)!=item->attacktype ...
    && !(tmp->attacktype & item->attacktype)) {        * in this way, if the player is missing any of the attacktypes, he gets
         * them.  As it is now, if the player has any that match the granted skill,
         * but not all of them, he gets nothing.
         */
        if (!(skop->attacktype & item->attacktype)) {
  /* always add physical if there's none */   /* always add physical if there's none */
  if (tmp->attacktype == 0) tmp->attacktype = AT_PHYSICAL;   if (skop->attacktype == 0) skop->attacktype = AT_PHYSICAL;
    
  /* we add the new attacktype to the clawing ability */   /* we add the new attacktype to the clawing ability */
  tmp->attacktype += item->attacktype;   skop->attacktype |= item->attacktype;
    
  if (item->msg != NULL)   if (item->msg != NULL)
    new_draw_info(NDI_UNIQUE|NDI_BLUE, 0, who, item->msg);     new_draw_info(NDI_UNIQUE|NDI_BLUE, 0, who, item->msg);
Line 3076
 
Line 3101
          
     /* adding new spellpath attunements */      /* adding new spellpath attunements */
     if (item->path_attuned > 0 && !(skin->path_attuned & item->path_attuned)) {      if (item->path_attuned > 0 && !(skin->path_attuned & item->path_attuned)) {
       skin->path_attuned += item->path_attuned; /* add attunement to skin */       skin->path_attuned |= item->path_attuned; /* add attunement to skin */
               
       /* print message */        /* print message */
       sprintf(buf, "You feel attuned to ");        sprintf(buf, "You feel attuned to ");
Line 3108
 
Line 3133
   else {    else {
     /* generate misc. treasure */      /* generate misc. treasure */
     tmp = arch_to_object (tr->item);      tmp = arch_to_object (tr->item);
     sprintf(buf, "You gained %s", query_short_name(tmp));   new_draw_info_format(NDI_UNIQUE|NDI_BLUE, 0, who, "You gained %s", query_short_name(tmp));
     new_draw_info(NDI_UNIQUE|NDI_BLUE, 0, who, buf);  
     tmp = insert_ob_in_ob (tmp, who);      tmp = insert_ob_in_ob (tmp, who);
     if (who->type == PLAYER)      if (who->type == PLAYER)
       esrv_send_item(who, tmp);        esrv_send_item(who, tmp);


Legend:
line(s) removed in v.1.131 
line(s) changed
 line(s) added in v.1.132

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