Difference for server/gods.c from version 1.36 to 1.37


version 1.36 version 1.37
Line 1
 
Line 1
 /*  /*
  * static char *rcsid_gods_c =   * static char *rcsid_gods_c =
  *   "$Id: gods.c,v 1.36 2003/06/26 11:27:43 gros Exp $";   *   "$Id: gods.c,v 1.37 2003/09/13 05:02:10 mwedel Exp $";
  */   */
   
 /*  /*
Line 42
 
Line 42
 #include <sproto.h>  #include <sproto.h>
 #endif  #endif
   
 static int god_gives_present (object *op, object *god, treasure *tr);  
 static void follower_remove_similar_item (object *op, object *item);  
   
 int lookup_god_by_name(char *name) {  int lookup_god_by_name(char *name) {
   int godnr=-1,nmlen = strlen(name);    int godnr=-1,nmlen = strlen(name);
    
Line 63
 
Line 60
   
   if(name) {     if(name) {
     godlink *gl;      godlink *gl;
   
     for(gl=first_god;gl;gl=gl->next)      for(gl=first_god;gl;gl=gl->next)
       if(!strcmp(name,gl->name)) break;        if(!strcmp(name,gl->name)) break;
     if(gl) god=pntr_to_god_obj(gl);      if(gl) god=pntr_to_god_obj(gl);
Line 70
 
Line 68
   return god;    return god;
 }  }
   
 void pray_at_altar(object *pl, object *altar) {  /* determine_god() - determines if op worships a god. Returns
    * the godname if they do. In the case of an NPC, if they have
    * no god, we give them a random one. -b.t.
    */
   
   char *determine_god(object *op) {
       int godnr = -1;
   
       /* spells */
       if ((op->type == SPELL || op->type == SPELL_EFFECT) &&
             op->title)
       {
    if (lookup_god_by_name(op->title)>=0) return op->title;
       }
   
       if(op->type!= PLAYER && QUERY_FLAG(op,FLAG_ALIVE)) {
    if(!op->title) {
        godlink *gl=first_god;
   
        godnr = rndm(1, gl->id);
        while(gl) {
    if(gl->id==godnr) break;
    gl=gl->next;
        }
        op->title = add_string(gl->name);
    }
    return op->title;
       }
   
   
       /* The god the player worships is in the praying skill (native skill
        * not skill tool).  Since a player can only have one instance of
        * that skill, once we find it, we can return, either with the
        * title or "none".
        */
       if(op->type==PLAYER) {
    object *tmp;
           for (tmp=op->inv; tmp!=NULL; tmp=tmp->below)
        if (tmp->type == SKILL && tmp->subtype == SK_PRAYING) {
    if (tmp->title) return (tmp->title);
    else return("none");
        }
       }
       return ("none");
   }
   
   static int same_string (const char *s1, const char *s2)
   {
       if (s1 == NULL)
           if (s2 == NULL)
               return 1;
           else
               return 0;
       else
           if (s2 == NULL)
               return 0;
           else
               return strcmp (s1, s2) == 0;
   }
   
   
   /*
    * follower_remove_similar_item - Checks for any occurrence of
    * the given 'item' in the inventory of 'op' (recursively).
    * Any matching items in the inventory are deleted, and a
    * message is displayed to the player.
    */
   static void follower_remove_similar_item (object *op, object *item)
   {
       object *tmp, *next;
      
       if (op && op->type == PLAYER && op->contr) {
           /* search the inventory */
           for (tmp = op->inv; tmp != NULL; tmp = next) {
        next = tmp->below;   /* backup in case we remove tmp */
          
        if (tmp->type == item->type
    && same_string (tmp->name, item->name)
    && same_string (tmp->title, item->title)
    && same_string (tmp->msg, item->msg)
    && same_string (tmp->slaying, item->slaying)) {
           
            /* message */
    if (tmp->nrof > 1)
        new_draw_info_format(NDI_UNIQUE,0,op,
          "The %s crumble to dust!", query_short_name(tmp));
    else
        new_draw_info_format(NDI_UNIQUE,0,op,
          "The %s crumbles to dust!", query_short_name(tmp));
           
            remove_ob(tmp);    /* remove obj from players inv. */
    esrv_del_item(op->contr, tmp->count); /* notify client */
    free_object(tmp);  /* free object */
        }
        if (tmp->inv)
          follower_remove_similar_item(tmp, item);
    }
       }
   }
   
   /*
    * follower_has_similar_item - Checks for any occurrence of
    * the given 'item' in the inventory of 'op' (recursively).
    * Returns 1 if found, else 0.
    */
   static int follower_has_similar_item (object *op, object *item)
   {
       object *tmp;
   
       for (tmp = op->inv; tmp != NULL; tmp = tmp->below) {
           if (tmp->type == item->type
               && same_string (tmp->name, item->name)
               && same_string (tmp->title, item->title)
               && same_string (tmp->msg, item->msg)
               && same_string (tmp->slaying, item->slaying))
               return 1;
           if (tmp->inv && follower_has_similar_item (tmp, item))
               return 1;
       }
       return 0;
   }
   
   static int god_gives_present (object *op, object *god, treasure *tr)
   {
       object *tmp;
   
       if (follower_has_similar_item (op, &tr->item->clone))
           return 0;
   
       tmp = arch_to_object (tr->item);
       new_draw_info_format (NDI_UNIQUE, 0, op,
           "%s lets %s appear in your hands.", god->name, query_short_name (tmp));
       tmp = insert_ob_in_ob (tmp, op);
       if (op->type == PLAYER)
           esrv_send_item (op, tmp);
       return 1;
   }
   
   void pray_at_altar(object *pl, object *altar, object *skill) {
     object *pl_god=find_god(determine_god(pl));      object *pl_god=find_god(determine_god(pl));
     int return_pray_script; /* GROS : This is for return value of script */      int return_pray_script; /* GROS : This is for return value of script */
     event *evt;      event *evt;
Line 113
 
Line 249
  return;   return;
   
     } else if(!strcmp(pl_god->name,altar->other_arch->clone.name)) { /* pray at your gods altar */      } else if(!strcmp(pl_god->name,altar->other_arch->clone.name)) { /* pray at your gods altar */
  int bonus = ((pl->stats.Wis/10)+(SK_level(pl)/10));   int bonus = (pl->stats.Wis+skill->level)/10;
   
  /* we can get neg grace up faster */   /* we can get neg grace up faster */
  if(pl->stats.grace<0) pl->stats.grace+=(bonus>-1*(pl->stats.grace/10) ?   if(pl->stats.grace<0) pl->stats.grace+=(bonus>-1*(pl->stats.grace/10) ?
Line 122
 
Line 258
  if(pl->stats.grace<(2*pl->stats.maxgrace)) {   if(pl->stats.grace<(2*pl->stats.maxgrace)) {
      pl->stats.grace+=bonus/2;       pl->stats.grace+=bonus/2;
  }   }
  /* I think there was a bug here in that this was nested  
  * in the if immediately above  
  */  
  if(pl->stats.grace>(2*pl->stats.maxgrace)) {   if(pl->stats.grace>(2*pl->stats.maxgrace)) {
      pl->stats.grace=(2*pl->stats.maxgrace);       pl->stats.grace=(2*pl->stats.maxgrace);
  }   }
Line 135
 
Line 268
  bonus = MAX(1, bonus + MAX(pl->stats.luck, -3)); /* -- DAMN -- */   bonus = MAX(1, bonus + MAX(pl->stats.luck, -3)); /* -- DAMN -- */
   
  if(((random_roll(0, 399, pl, PREFER_LOW))-bonus)<0)   if(((random_roll(0, 399, pl, PREFER_LOW))-bonus)<0)
    god_intervention(pl,pl_god);     god_intervention(pl,pl_god, skill);
   
     } else { /* praying to another god! */      } else { /* praying to another god! */
  int loss = 0,angry=1;   int loss = 0,angry=1;
Line 149
 
Line 282
  */   */
  if(pl_god->other_arch && (altar->other_arch->name==pl_god->other_arch->name)) {   if(pl_god->other_arch && (altar->other_arch->name==pl_god->other_arch->name)) {
      angry=2;       angry=2;
      if(random_roll(0, SK_level(pl)+2, pl, PREFER_LOW)-5 > 0) {       if(random_roll(0, skill->level+2, pl, PREFER_LOW)-5 > 0) {
    object *tmp;
   
        /* you really screwed up */         /* you really screwed up */
  angry=3;   angry=3;
  new_draw_info_format(NDI_UNIQUE|NDI_NAVY,0,pl,   new_draw_info_format(NDI_UNIQUE|NDI_NAVY,0,pl,
                                 "Foul Priest! %s punishes you!",pl_god->name);                                  "Foul Priest! %s punishes you!",pl_god->name);
  cast_mana_storm(pl,pl_god->level+20);   tmp=get_archetype(LOOSE_MANA);
    cast_magic_storm(pl,tmp, pl_god->level+20);
      }       }
      new_draw_info_format(NDI_UNIQUE|NDI_NAVY,0,pl,       new_draw_info_format(NDI_UNIQUE|NDI_NAVY,0,pl,
                                 "Foolish heretic! %s is livid!",pl_god->name);                                  "Foolish heretic! %s is livid!",pl_god->name);
Line 163
 
Line 299
                                 "Heretic! %s is angered!",pl_god->name);                                  "Heretic! %s is angered!",pl_god->name);
    
  /* whether we will be successfull in defecting or not -   /* whether we will be successfull in defecting or not -
  * we lose experience from the clerical experience obj */   * we lose experience from the clerical experience obj
    */
   
  loss = 0.1 * (float) pl->chosen_skill->exp_obj->stats.exp;   loss = 0.1 * (float) skill->stats.exp;
  if(loss)   if(loss)
    lose_priest_exp(pl, random_roll(0, loss*angry-1, pl, PREFER_LOW));       change_exp(pl, -random_roll(0, loss*angry-1, pl, PREFER_LOW),
       skill?skill->skill:"none", SK_SUBTRACT_SKILL_EXP);
    
  /* May switch Gods, but its random chance based on our current level   /* May switch Gods, but its random chance based on our current level
  * note it gets harder to swap gods the higher we get */   * note it gets harder to swap gods the higher we get
  if((angry==1) &&   */
     !(random_roll(0, pl->chosen_skill->exp_obj->level, pl,   if((angry==1) && !(random_roll(0, skill->level, pl, PREFER_LOW))) {
  PREFER_LOW))) {  
    become_follower(pl,&altar->other_arch->clone);     become_follower(pl,&altar->other_arch->clone);
  } /* If angry... switching gods */   } else {
         else {  /* toss this player off the altar.  He can try again. */       /* toss this player off the altar.  He can try again. */
           new_draw_info_format(NDI_UNIQUE|NDI_NAVY,0,pl,       new_draw_info(NDI_UNIQUE|NDI_NAVY,0,pl,
                                "A divine force pushes you off the altar.");                                 "A divine force pushes you off the altar.");
           move_player(pl,absdir(pl->facing + 4)); /* back him off the way he came. */            move_player(pl,absdir(pl->facing + 4)); /* back him off the way he came. */
         } /* didn't successfully change, so forced off altar. */  
     } /* If prayed at altar to other god */  
 }  }
       }
 static int get_spell_number (object *op)  
 {  
     int spell;  
   
     if (op->slaying && (spell = look_up_spell_name (op->slaying)) >= 0)  
         return spell;  
     else  
         return op->stats.sp;  
 }  }
   
 static void check_special_prayers (object *op, object *god)  static void check_special_prayers (object *op, object *god)
Line 201
 
Line 328
  */   */
     treasure *tr;      treasure *tr;
     object *tmp, *next_tmp;      object *tmp, *next_tmp;
     int spell;      int remove=0;
   
     /* Outer loop iterates over all special prayer marks */      /* Outer loop iterates over all special prayer marks */
     for (tmp = op->inv; tmp; tmp = next_tmp)      for (tmp = op->inv; tmp; tmp = next_tmp) {
     {  
         next_tmp = tmp->below;          next_tmp = tmp->below;
   
         if (tmp->type != FORCE || tmp->slaying == NULL          if (tmp->type != FORCE || tmp->slaying == NULL
             || strcmp (tmp->slaying, "special prayer") != 0)              || strcmp (tmp->slaying, "special prayer") != 0)
             continue;              continue;
         spell = tmp->stats.sp;  
   
         if (god->randomitems == NULL) {          if (god->randomitems == NULL) {
             LOG (llevError, "BUG: check_special_prayers(): %s without "              LOG (llevError, "BUG: check_special_prayers(): god %s without randomitems\n", god->name);
                  "randomitems\n", god->name);              do_forget_spell (op, tmp->name);
             do_forget_spell (op, spell);  
             continue;              continue;
  }   }
   
         /* Inner loop tries to find the special prayer in the god's treasure          /* Inner loop tries to find the special prayer in the god's treasure
          * list. */           * list. We default that the spell should be removed.
    */
    remove=1;
         for (tr = god->randomitems->items; tr; tr = tr->next)          for (tr = god->randomitems->items; tr; tr = tr->next)
         {          {
             object *item;              object *item;
Line 229
 
Line 355
                 continue;                  continue;
             item = &tr->item->clone;              item = &tr->item->clone;
   
             if (item->type == SPELLBOOK && get_spell_number (item) == spell)              if (tr->item->clone.type == SPELL && tr->item->clone.name == tmp->name) {
             {   remove=0;
                 /* Current god allows this special prayer. */  
                 spell = -1;  
                 break;                  break;
             }              }
         }          }
    if (remove)
         if (spell >= 0)              do_forget_spell (op, tmp->name);
             do_forget_spell (op, spell);  
     }      }
 }  }
   
Line 249
 
Line 372
  * items (from the former cult).   * items (from the former cult).
  */   */
 void become_follower (object *op, object *new_god) {  void become_follower (object *op, object *new_god) {
     object *exp_obj = op->chosen_skill->exp_obj; /* obj. containing god data */  
     object *old_god = NULL;                      /* old god */      object *old_god = NULL;                      /* old god */
     treasure *tr;      treasure *tr;
     object *item;      object *item, *skop;
     int i;      int i;
          
     /* get old god */      old_god = find_god(determine_god(op));
     if (exp_obj->title)  
         old_god = find_god(exp_obj->title);  
          
     /* take away any special god-characteristic items. */      /* take away any special god-characteristic items. */
     for(item=op->inv;item!=NULL;item=item->below) {      for(item=op->inv;item!=NULL;item=item->below) {
         if(QUERY_FLAG(item,FLAG_STARTEQUIP) && item->invisible) {          if(QUERY_FLAG(item,FLAG_STARTEQUIP) && item->invisible) {
      /* remove all invisible startequ. items which are       /* remove all invisible startequip items which are
         not skill, exp or force */        *  not skill, exp or force
         */
      if(item->type==SKILL || item->type==EXPERIENCE ||       if(item->type==SKILL || item->type==EXPERIENCE ||
         item->type==FORCE) continue;          item->type==FORCE) continue;
      remove_ob(item);       remove_ob(item);
Line 280
 
Line 401
  }   }
     }      }
          
     /* give the player any special god-characteristic-items. */  
     for(tr=new_god->randomitems->items; tr!=NULL; tr = tr->next) {  
       if(tr->item && tr->item->clone.invisible && tr->item->clone.type != SPELLBOOK &&  
          tr->item->clone.type != BOOK)  
         god_gives_present(op,new_god,tr); }  
   
     if(!op||!new_god) return;      if(!op||!new_god) return;
   
     if(op->race&&new_god->slaying&&strstr(op->race,new_god->slaying)) {       if(op->race&&new_god->slaying&&strstr(op->race,new_god->slaying)) {
  new_draw_info_format(NDI_UNIQUE|NDI_NAVY,0,op,"Fool! %s detests your kind!",   new_draw_info_format(NDI_UNIQUE|NDI_NAVY,0,op,"Fool! %s detests your kind!",
       new_god->name);        new_god->name);
         if(random_roll(0, op->level-1, op, PREFER_LOW)-5>0)           if(random_roll(0, op->level-1, op, PREFER_LOW)-5>0) {
     cast_mana_storm(op,new_god->level+10);       object *tmp = get_archetype(LOOSE_MANA);
        cast_magic_storm(op,tmp, new_god->level+10);
    }
  return;   return;
     }      }
   
   
       /* give the player any special god-characteristic-items. */
       for(tr=new_god->randomitems->items; tr!=NULL; tr = tr->next) {
         if(tr->item && tr->item->clone.invisible && tr->item->clone.type != SPELLBOOK &&
            tr->item->clone.type != BOOK)
           god_gives_present(op,new_god,tr); }
   
   
     new_draw_info_format(NDI_UNIQUE|NDI_NAVY,0,op,      new_draw_info_format(NDI_UNIQUE|NDI_NAVY,0,op,
     "You become a follower of %s!",new_god->name);      "You become a follower of %s!",new_god->name);
   
     if(exp_obj->title) { /* get rid of old god */       for (skop = op->inv; skop != NULL; skop=skop->below)
    if (skop->type == SKILL && skop->subtype == SK_PRAYING) break;
   
       /* Player has no skill - give them the skill */
       if (!skop) {
    /* The arhetype should always be defined - if we crash here because it doesn't,
    * things are really messed up anyways.
    */
    skop = give_skill_by_name(op, get_archetype_by_type_subtype(SKILL, SK_PRAYING)->clone.skill);
       }
   
       if(skop->title) { /* get rid of old god */
        new_draw_info_format(NDI_UNIQUE,0,op,         new_draw_info_format(NDI_UNIQUE,0,op,
         "%s's blessing is withdrawn from you.",exp_obj->title);          "%s's blessing is withdrawn from you.",skop->title);
        CLEAR_FLAG(exp_obj,FLAG_APPLIED);    /* The point of this is to really show what abilities the player just lost */
        (void) change_abil(op,exp_obj);   if (QUERY_FLAG(skop, FLAG_APPLIED)) {
        free_string(exp_obj->title);       CLEAR_FLAG(skop,FLAG_APPLIED);
        (void) change_abil(op,skop);
    }
          free_string(skop->title);
     }      }
   
    /* now change to the new gods attributes to exp_obj */     /* now change to the new gods attributes to exp_obj */
     exp_obj->title = add_string(new_god->name);      skop->title = add_string(new_god->name);
     exp_obj->path_attuned=new_god->path_attuned;      skop->path_attuned=new_god->path_attuned;
     exp_obj->path_repelled=new_god->path_repelled;      skop->path_repelled=new_god->path_repelled;
     exp_obj->path_denied=new_god->path_denied;      skop->path_denied=new_god->path_denied;
     /* copy god's resistances */      /* copy god's resistances */
     memcpy(exp_obj->resist, new_god->resist, sizeof(new_god->resist));      memcpy(skop->resist, new_god->resist, sizeof(new_god->resist));
   
     /* make sure that certain immunities do NOT get passed      /* make sure that certain immunities do NOT get passed
      * to the follower! */       * to the follower!
        */
     for (i=0; i<NROFATTACKS; i++)      for (i=0; i<NROFATTACKS; i++)
       if (exp_obj->resist[i] > 30 && (i==ATNR_FIRE || i==ATNR_COLD ||        if (skop->resist[i] > 30 && (i==ATNR_FIRE || i==ATNR_COLD ||
    i==ATNR_ELECTRICITY || i==ATNR_POISON))     i==ATNR_ELECTRICITY || i==ATNR_POISON))
  exp_obj->resist[i] = 30;   skop->resist[i] = 30;
   
     exp_obj->stats.hp= (sint16) new_god->last_heal;      skop->stats.hp= (sint16) new_god->last_heal;
     exp_obj->stats.sp= (sint16) new_god->last_sp;      skop->stats.sp= (sint16) new_god->last_sp;
     exp_obj->stats.grace= (sint16) new_god->last_grace;      skop->stats.grace= (sint16) new_god->last_grace;
     exp_obj->stats.food= (sint16) new_god->last_eat;      skop->stats.food= (sint16) new_god->last_eat;
     exp_obj->stats.luck= (sint8) new_god->stats.luck;      skop->stats.luck= (sint8) new_god->stats.luck;
     /* gods may pass on certain flag properties */      /* gods may pass on certain flag properties */
     update_priest_flag(new_god,exp_obj,FLAG_SEE_IN_DARK);      update_priest_flag(new_god,skop,FLAG_SEE_IN_DARK);
     update_priest_flag(new_god,exp_obj,FLAG_REFL_SPELL);      update_priest_flag(new_god,skop,FLAG_REFL_SPELL);
     update_priest_flag(new_god,exp_obj,FLAG_REFL_MISSILE);      update_priest_flag(new_god,skop,FLAG_REFL_MISSILE);
     update_priest_flag(new_god,exp_obj,FLAG_STEALTH);      update_priest_flag(new_god,skop,FLAG_STEALTH);
     update_priest_flag(new_god,exp_obj,FLAG_MAKE_INVIS);      update_priest_flag(new_god,skop,FLAG_MAKE_INVIS);
     update_priest_flag(new_god,exp_obj,FLAG_UNDEAD);      update_priest_flag(new_god,skop,FLAG_UNDEAD);
     update_priest_flag(new_god,exp_obj,FLAG_BLIND);      update_priest_flag(new_god,skop,FLAG_BLIND);
     update_priest_flag(new_god,exp_obj,FLAG_XRAYS); /* better have this if blind! */      update_priest_flag(new_god,skop,FLAG_XRAYS); /* better have this if blind! */
   
     new_draw_info_format(NDI_UNIQUE,0,op,      new_draw_info_format(NDI_UNIQUE,0,op,
  "You are bathed in %s's aura.",new_god->name);   "You are bathed in %s's aura.",new_god->name);
Line 343
 
Line 483
     /* Weapon/armour use are special...handle flag toggles here as this can      /* Weapon/armour use are special...handle flag toggles here as this can
      * only happen when gods are worshipped and if the new priest could       * only happen when gods are worshipped and if the new priest could
      * have used armour/weapons in the first place */       * have used armour/weapons in the first place */
     update_priest_flag(new_god,exp_obj,FLAG_USE_WEAPON);      update_priest_flag(new_god,skop,FLAG_USE_WEAPON);
     update_priest_flag(new_god,exp_obj,FLAG_USE_ARMOUR);      update_priest_flag(new_god,skop,FLAG_USE_ARMOUR);
   
     if(worship_forbids_use(op,exp_obj,FLAG_USE_WEAPON,"weapons"))      if(worship_forbids_use(op,skop,FLAG_USE_WEAPON,"weapons"))
  stop_using_item(op,WEAPON,2);   stop_using_item(op,WEAPON,2);
   
     if(worship_forbids_use(op,exp_obj,FLAG_USE_ARMOUR,"armour")) {      if(worship_forbids_use(op,skop,FLAG_USE_ARMOUR,"armour")) {
  stop_using_item(op,ARMOUR,1);   stop_using_item(op,ARMOUR,1);
  stop_using_item(op,HELMET,1);   stop_using_item(op,HELMET,1);
  stop_using_item(op,BOOTS,1);   stop_using_item(op,BOOTS,1);
Line 357
 
Line 497
  stop_using_item(op,SHIELD,1);   stop_using_item(op,SHIELD,1);
     }      }
   
     SET_FLAG(exp_obj,FLAG_APPLIED);      SET_FLAG(skop,FLAG_APPLIED);
     (void) change_abil(op,exp_obj);      (void) change_abil(op,skop);
   
     check_special_prayers (op, new_god);      check_special_prayers (op, new_god);
 }  }
Line 420
 
Line 560
 }  }
   
   
 /* determine_god() - determines if op worships a god. Returns  
  * the godname if they do. In the case of an NPC, if they have  
  * no god, we give them a random one. -b.t.  
  */  
   
 char *determine_god(object *op) {  
     int godnr = -1;  
   
     /* spells */  
     if ((op->type == FBULLET || op->type == CONE || op->type == FBALL  
          || op->type == SWARM_SPELL) && op->title)  
     {  
  if(lookup_god_by_name(op->title)>=0) return op->title;  
     }  
   
     if(op->type!= PLAYER && QUERY_FLAG(op,FLAG_ALIVE)) {  
  if(!op->title) {  
      godlink *gl=first_god;  
   
      godnr = rndm(1, gl->id);  
      while(gl) {  
  if(gl->id==godnr) break;  
  gl=gl->next;  
      }  
      op->title = add_string(gl->name);  
  }  
  return op->title;  
     }  
   
   
     /* If we are player, lets search a bit harder for the god.  This  
      * is a fix for perceive self (before, we just looked at the active  
      * skill.)  
      */  
     if(op->type==PLAYER) {  
  object *tmp;  
         for (tmp=op->inv; tmp!=NULL; tmp=tmp->below)  
         {  
                 if (tmp->type == SKILL) /* GROS: This is for the flower's bug */  
                 {  
                         if (tmp->exp_obj && tmp->exp_obj->title)  
                         return tmp->exp_obj->title;  
                 }  
         }  
   
     }  
   
   return ("none");  
 }  
   
   
 archetype *determine_holy_arch (object *god, const char *type)  archetype *determine_holy_arch (object *god, const char *type)
 {  {
Line 535
 
Line 625
     return (30 + (level - 40) / 4) / difficulty;      return (30 + (level - 40) / 4) / difficulty;
 }  }
   
 static int god_enchants_weapon (object *op, object *god, object *tr)  static int god_enchants_weapon (object *op, object *god, object *tr, object *skill)
 {  {
     char buf[MAX_BUF];      char buf[MAX_BUF];
     object *weapon;      object *weapon;
Line 576
 
Line 666
     }      }
   
     /* Higher magic value */      /* Higher magic value */
     tmp = follower_level_to_enchantments (SK_level (op), tr->level);      tmp = follower_level_to_enchantments (skill->level, tr->level);
     if (weapon->magic < tmp) {      if (weapon->magic < tmp) {
         new_draw_info (NDI_UNIQUE, 0, op,          new_draw_info (NDI_UNIQUE, 0, op,
                 "A phosphorescent glow envelops your weapon!");                  "A phosphorescent glow envelops your weapon!");
Line 589
 
Line 679
     return 0;      return 0;
 }  }
   
 static int same_string (const char *s1, const char *s2)  
 {  
     if (s1 == NULL)  
         if (s2 == NULL)  
             return 1;  
         else  
             return 0;  
     else  
         if (s2 == NULL)  
             return 0;  
         else  
             return strcmp (s1, s2) == 0;  
 }  
   
 /*  
  * follower_has_similar_item - Checks for any occurrence of  
  * the given 'item' in the inventory of 'op' (recursively).  
  * Returns 1 if found, else 0.  
  */  
 static int follower_has_similar_item (object *op, object *item)  
 {  
     object *tmp;  
   
     for (tmp = op->inv; tmp != NULL; tmp = tmp->below) {  
         if (tmp->type == item->type  
             && same_string (tmp->name, item->name)  
             && same_string (tmp->title, item->title)  
             && same_string (tmp->msg, item->msg)  
             && same_string (tmp->slaying, item->slaying))  
             return 1;  
         if (tmp->inv && follower_has_similar_item (tmp, item))  
             return 1;  
     }  
     return 0;  
 }  
   
 /*  
  * follower_remove_similar_item - Checks for any occurrence of  
  * the given 'item' in the inventory of 'op' (recursively).  
  * Any matching items in the inventory are deleted, and a  
  * message is displayed to the player.  
  */  
 static void follower_remove_similar_item (object *op, object *item)  
 {  
     object *tmp, *next;  
       
     if (op && op->type == PLAYER && op->contr) {  
         /* search the inventory */  
         for (tmp = op->inv; tmp != NULL; tmp = next) {  
      next = tmp->below;   /* backup in case we remove tmp */  
           
      if (tmp->type == item->type  
  && same_string (tmp->name, item->name)  
  && same_string (tmp->title, item->title)  
  && same_string (tmp->msg, item->msg)  
  && same_string (tmp->slaying, item->slaying)) {  
            
          /* message */  
  if (tmp->nrof > 1)  
      new_draw_info_format(NDI_UNIQUE,0,op,  
        "The %s crumble to dust!", query_short_name(tmp));  
  else  
      new_draw_info_format(NDI_UNIQUE,0,op,  
        "The %s crumbles to dust!", query_short_name(tmp));  
            
          remove_ob(tmp);    /* remove obj from players inv. */  
  esrv_del_item(op->contr, tmp->count); /* notify client */  
  free_object(tmp);  /* free object */  
      }  
      if (tmp->inv)  
        follower_remove_similar_item(tmp, item);  
  }  
     }  
 }  
   
 static int god_gives_present (object *op, object *god, treasure *tr)  
 {  
     object *tmp;  
   
     if (follower_has_similar_item (op, &tr->item->clone))  
         return 0;  
   
     tmp = arch_to_object (tr->item);  
     new_draw_info_format (NDI_UNIQUE, 0, op,  
         "%s lets %s appear in your hands.", god->name, query_short_name (tmp));  
     tmp = insert_ob_in_ob (tmp, op);  
     if (op->type == PLAYER)  
         esrv_send_item (op, tmp);  
     return 1;  
 }  
   
   
 /* god_intervention() - called from praying() currently. Every  /* god_intervention() - called from praying() currently. Every
  * once in a while the god will intervene to help the worshiper.   * once in a while the god will intervene to help the worshiper.
Line 687
 
Line 686
  * priest. -b.t.    * priest. -b.t.
  */   */
   
 void god_intervention (object *op, object *god)  void god_intervention (object *op, object *god, object *skill)
 {  {
     int level = SK_level (op);  
     treasure *tr;      treasure *tr;
   
     if ( ! god || ! god->randomitems) {      if ( ! god || ! god->randomitems) {
         LOG (llevError, "BUG: god_intervention(): no god or god without "          LOG (llevError,
              "randomitems\n");        "BUG: god_intervention(): no god or god without randomitems\n");
         return;          return;
     }      }
   
Line 717
 
Line 715
             treasurelist *tl = find_treasurelist (tr->name);              treasurelist *tl = find_treasurelist (tr->name);
             if (tl == NULL)              if (tl == NULL)
                 continue;                  continue;
   
             new_draw_info (NDI_UNIQUE, 0, op, "Something appears before your "              new_draw_info (NDI_UNIQUE, 0, op, "Something appears before your "
                     "eyes.  You catch it before it falls to the ground.");                      "eyes.  You catch it before it falls to the ground.");
   
             create_treasure (tl, op, GT_STARTEQUIP | GT_ONLY_GOOD              create_treasure (tl, op, GT_STARTEQUIP | GT_ONLY_GOOD
                                       | GT_UPDATE_INV, level, 0);                                        | GT_UPDATE_INV, skill->level, 0);
             return;              return;
         }          }
   
Line 733
 
Line 733
   
         /* Grace limit */          /* Grace limit */
         if (item->type == BOOK && item->invisible          if (item->type == BOOK && item->invisible
             && strcmp (item->name, "grace limit") == 0)              && strcmp (item->name, "grace limit") == 0) {
         {  
             if (op->stats.grace < item->stats.grace              if (op->stats.grace < item->stats.grace
                 || op->stats.grace < op->stats.maxgrace)                  || op->stats.grace < op->stats.maxgrace) {
             {   object *tmp;
   
                 /* Follower lacks the required grace for the following                  /* Follower lacks the required grace for the following
                  * treasure list items. */                   * treasure list items. */
                 (void) cast_change_attr (op, op, 0, SP_HOLY_POSSESSION);  
    tmp = get_archetype(HOLY_POSSESSION);
                   (void) cast_change_ability(op, op, tmp, 0);
    free_object(tmp);
                 return;                  return;
             }              }
             continue;              continue;
Line 788
 
Line 791
         if (item->type == BOOK && item->invisible          if (item->type == BOOK && item->invisible
             && strcmp (item->name, "heal spell") == 0)              && strcmp (item->name, "heal spell") == 0)
         {          {
             if (cast_heal (op, 0, get_spell_number (item)))       object *tmp;
                 return;       int success;
             else  
                 continue;       tmp = get_archetype_by_object_name(item->slaying);
   
        success = cast_heal (op, op, tmp, 0);
        free_object(tmp);
        if (success) return;
        else continue;
         }          }
   
         /* Remove curse */          /* Remove curse */
Line 863
 
Line 871
         if (item->type == BOOK && item->invisible          if (item->type == BOOK && item->invisible
             && strcmp (item->name, "enchant weapon") == 0)              && strcmp (item->name, "enchant weapon") == 0)
         {          {
             if (god_enchants_weapon (op, god, item))              if (god_enchants_weapon (op, god, item, skill))
                 return;                  return;
             else              else
                 continue;                  continue;
         }          }
   
         /* Spellbooks - works correctly only for prayers */          /* Spellbooks - works correctly only for prayers */
         if (item->type == SPELLBOOK)          if (item->type == SPELL)
         {          {
             int spell = get_spell_number (item);              if (check_spell_known (op, item->name))
             if (check_spell_known (op, spell))  
                 continue;                  continue;
             if (spells[spell].level > level)              if (item->level > skill->level)
                 continue;                  continue;
             if (item->invisible) {  
                 new_draw_info_format(NDI_UNIQUE, 0, op,                  new_draw_info_format(NDI_UNIQUE, 0, op,
                         "%s grants you use of a special prayer!", god->name);                          "%s grants you use of a special prayer!", god->name);
                 do_learn_spell (op, spell, 1);       do_learn_spell (op, item, 1);
                 return;  
             }  
             if ( ! QUERY_FLAG (item, FLAG_STARTEQUIP)) {  
                 LOG (llevError, "BUG: visible spellbook in %s's treasure list "  
                      "lacks FLAG_STARTEQUIP\n", god->name);  
                 continue;  
             }  
             if ( ! item->stats.Wis) {  
                 LOG (llevError, "BUG: visible spellbook in %s's treasure list "  
                      "doesn't contain a special prayer\n", god->name);  
                 continue;  
             }  
             if (god_gives_present (op, god, tr))  
                 return;                  return;
             else  
                 continue;  
         }          }
   
         /* Other gifts */          /* Other gifts */
Line 915
 
Line 908
   
 int god_examines_priest (object *op, object *god) {  int god_examines_priest (object *op, object *god) {
   int reaction=1;    int reaction=1;
   object *item=NULL;      object *item=NULL, *skop;
   
   for(item=op->inv;item;item=item->below) {    for(item=op->inv;item;item=item->below) {
     if(QUERY_FLAG(item,FLAG_APPLIED)) {      if(QUERY_FLAG(item,FLAG_APPLIED)) {
Line 925
 
Line 918
   
   /* well, well. Looks like we screwed up. Time for god's revenge */    /* well, well. Looks like we screwed up. Time for god's revenge */
   if(reaction<0) {     if(reaction<0) {
     char buf[MAX_BUF];  
     int loss = 10000000;      int loss = 10000000;
     int angry = abs(reaction);      int angry = abs(reaction);
     if(op->chosen_skill->exp_obj)  
       loss = 0.05 * (float) op->chosen_skill->exp_obj->stats.exp;  
     lose_priest_exp(op, random_roll(0, loss*angry-1, op, PREFER_LOW));  
     if(random_roll(0, angry, op, PREFER_LOW))  
       cast_mana_storm(op,SK_level(op)+(angry*3));  
     sprintf(buf,"%s becomes angry and punishes you!",god->name);  
     new_draw_info(NDI_UNIQUE|NDI_NAVY,0,op,buf);   
   }  
   
    for (skop = op->inv; skop != NULL; skop=skop->below)
        if (skop->type == SKILL && skop->subtype == SK_PRAYING) break;
   
    if (skop)
        loss = 0.05 * (float) skop->stats.exp;
    change_exp(op, -random_roll(0, loss*angry-1, op, PREFER_LOW),
       skop?skop->skill:"none", SK_SUBTRACT_SKILL_EXP);
    if(random_roll(0, angry, op, PREFER_LOW)) {
        object *tmp = get_archetype(LOOSE_MANA);
        cast_magic_storm(op,tmp,op->level+(angry*3));
    }
    new_draw_info_format(NDI_UNIQUE|NDI_NAVY,0,op,
         "%s becomes angry and punishes you!",god->name);
       }
   return reaction;    return reaction;
 }  }
   
Line 990
 
Line 988
     object *god=find_god(determine_god(caster));      object *god=find_god(determine_god(caster));
     int caster_is_spell=0;       int caster_is_spell=0;
   
     if(caster->type==FBULLET      if (caster->type==SPELL_EFFECT || caster->type == SPELL) caster_is_spell=1;
        ||caster->type==CONE  
        ||caster->type==FBALL  
        ||caster->type==SWARM_SPELL) caster_is_spell=1;  
   
     if ( ! god || (spellop->attacktype & AT_HOLYWORD && ! god->race)) {      if ( ! god || (spellop->attacktype & AT_HOLYWORD && ! god->race)) {
         if ( ! caster_is_spell)          if ( ! caster_is_spell)
Line 1037
 
Line 1032
     return 1;      return 1;
 }  }
   
 void lose_priest_exp(object *pl, int loss) {  
   
   if(!pl||pl->type!=PLAYER||!pl->chosen_skill  
      ||!pl->chosen_skill->exp_obj)   
   {  
     LOG(llevError,"Bad call to lose_priest_exp() \n");  
     return;  
   }  
   if((loss = check_exp_loss(pl->chosen_skill->exp_obj,loss))) {  
     pl->chosen_skill->exp_obj->stats.exp -= loss;  
     pl->stats.exp -= loss;  
     player_lvl_adj(pl, pl->chosen_skill->exp_obj);  
     player_lvl_adj(pl, NULL);  
   }  
 }  


Legend:
line(s) removed in v.1.36 
line(s) changed
 line(s) added in v.1.37

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