Difference for server/player.c from version 1.84 to 1.85


version 1.84 version 1.85
Line 1
 
Line 1
 /*  /*
  * static char *rcsid_player_c =   * static char *rcsid_player_c =
  *   "$Id: player.c,v 1.84 2002/06/15 07:47:36 mwedel Exp $";   *   "$Id: player.c,v 1.85 2002/07/15 04:57:13 mwedel Exp $";
  */   */
   
 /*  /*
Line 68
 
Line 68
     cp=strchr(buf,'\n');      cp=strchr(buf,'\n');
     if(cp!=NULL)      if(cp!=NULL)
       *cp='\0';        *cp='\0';
     new_draw_info(NDI_UNIQUE, 0,op,buf);      new_draw_info(NDI_UNIQUE | NDI_GREEN, 0,op,buf);
   }    }
   close_and_delete(fp, comp);    close_and_delete(fp, comp);
   new_draw_info(NDI_UNIQUE, 0,op," ");    new_draw_info(NDI_UNIQUE, 0,op," ");
Line 86
 
Line 86
  * all the pointers so the caller doesn't need to do that.   * all the pointers so the caller doesn't need to do that.
  * Caller is responsible for setting the correct map.   * Caller is responsible for setting the correct map.
  */   */
 static void get_player(player *p) {  
   /* Redo this to do both get_player_ob and get_player.
    * Hopefully this will be less bugfree and simpler.
    * Returns the player structure.  If 'p' is null,
    * we create a new one.  Otherwise, we recycle
    * the one that is passed.
    */
   static player* get_player(player *p) {
     object *op=arch_to_object(get_player_archetype(NULL));      object *op=arch_to_object(get_player_archetype(NULL));
     int i;      int i;
   
     p->loading = NULL;      if (!p) {
     p->fire_on=0,p->run_on=0;   player *tmp;
     p->count=0;  
     p->count_left=0;   p = (player *) malloc(sizeof(player));
     p->prev_cmd=' ';   if(p==NULL)
     p->prev_fire_on=0;       fatal(OUT_OF_MEMORY);
     p->mode=0;  
     p->idle=0;   /* This adds the player in the linked list.  There is extra
    * complexity here because we want to add the new player at the
    * end of the list - there is in fact no compelling reason that
    * that needs to be done except for things like output of
    * 'who'.
    */
    tmp=first_player;
    while(tmp!=NULL&&tmp->next!=NULL)
        tmp=tmp->next;
    if(tmp!=NULL)
        tmp->next=p;
    else
        first_player=p;
       }
   
       /* Clears basically the entire player structure except
        * for next and socket.
        */
       memset((void*)((char*)p + offsetof(player, maplevel)), 0,
        sizeof(player) - offsetof(player, maplevel));
   
       /* There are some elements we want initialized to non zero value -
        * we deal with that below this point.
        */
       p->party_number=-1;
       p->outputs_sync=16; /* Every 2 seconds */
       p->outputs_count=1; /* Keeps present behaviour */
       p->unapply = unapply_nochoice;
   #ifdef USE_SWAP_STATS
       p->Swap_First = -1;
   #endif
   
 #ifdef AUTOSAVE  #ifdef AUTOSAVE
     p->last_save_tick = 9999999;      p->last_save_tick = 9999999;
 #endif  #endif
     *p->maplevel=0;  
          
     strcpy(p->savebed_map, first_map_path);  /* Init. respawn position */      strcpy(p->savebed_map, first_map_path);  /* Init. respawn position */
     p->bed_x=0, p->bed_y=0;  
          
     op->contr=p; /* this aren't yet in archetype */      op->contr=p; /* this aren't yet in archetype */
     p->ob = op;      p->ob = op;
Line 117
 
Line 153
     roll_stats(op);      roll_stats(op);
     p->state=ST_ROLL_STAT;      p->state=ST_ROLL_STAT;
     clear_los(op);      clear_los(op);
     p->last_stats.Str=0,  p->last_stats.Dex=0,  
     p->last_stats.Int=0,  p->last_stats.Con=0,  
     p->last_stats.Wis=0,  p->last_stats.Cha=0;  
     p->last_stats.Pow=0,  p->last_stats.Pow=0;  
     p->last_stats.hp=0,   p->last_stats.maxhp=0;  
     p->last_stats.wc=0,   p->last_stats.ac=0;  
     p->last_stats.sp=0,   p->last_stats.maxsp=0;  
     p->last_stats.grace=0, p->last_stats.maxgrace=0;  
     p->last_stats.exp= -1,p->last_stats.food=0;  
     p->digestion=0,p->gen_hp=0,p->gen_sp=0,p->gen_grace=0;  
     p->gen_sp_armour=10;      p->gen_sp_armour=10;
     p->last_spell= -1;  
     p->last_value= -1;  
     p->last_speed= -1;      p->last_speed= -1;
     p->shoottype=range_none;      p->shoottype=range_none;
     p->last_shoot= range_bottom;  
     p->listening=9;      p->listening=9;
     p->golem=NULL;  
     p->last_used=NULL;  
     p->last_used_id=0;  
   
     p->weapon_sp=0;  
     p->last_weapon_sp= -1;      p->last_weapon_sp= -1;
     p->has_hit=0;  
   
     p->peaceful=1; /* default peaceful */      p->peaceful=1; /* default peaceful */
     p->last_tell[0] = '\0'; /* last player that told you something [mids 01/14/2002] */  
     p->do_los=1;      p->do_los=1;
     p->last_weight= -1;  
 #ifdef EXPLORE_MODE  #ifdef EXPLORE_MODE
     p->explore=0;      p->explore=0;
 #endif  #endif
Line 153
 
Line 168
     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++)      for(i=0;i<NROFREALSPELLS;i++)
  p->known_spells[i]= -1;   p->known_spells[i]= -1;
     p->nrofknownspells=0;  
     p->chosen_spell = -1;      p->chosen_spell = -1;
     p->ob->chosen_skill = NULL;  
     if(QUERY_FLAG(op,FLAG_READY_SKILL))  
         CLEAR_FLAG(op,FLAG_READY_SKILL);           CLEAR_FLAG(op,FLAG_READY_SKILL);
   
       /* we need to clear these to -1 and not zero - otherwise,
        * if a player quits and starts a new character, we wont
        * send new values to the client, as things like exp start
        * at zero.
        */
       for (i=0; i < MAX_EXP_CAT; i++) {
    p->last_skill_exp[i] = -1;
    p->last_skill_level[i] = -1;
       }
       for (i=0; i < NROFATTACKS; i++) {
    p->last_resist[i] = -1;
       }
       p->last_skill_index = -1;
       p->last_stats.exp = -1;
   
     p->socket.update_look=0;      p->socket.update_look=0;
     p->socket.look_position=0;      p->socket.look_position=0;
     p->own_title[0]='\0';      return p;
 }  }
   
   
Line 198
 
Line 228
   
     init_beforeplay(); /* Make sure everything is ready */      init_beforeplay(); /* Make sure everything is ready */
   
     p=get_player_ob();      p=get_player(NULL);
     get_player(p);  
     memcpy(&p->socket, ns, sizeof(NewSocket));      memcpy(&p->socket, ns, sizeof(NewSocket));
     /* Needed because the socket we just copied over needs to be cleared.      /* Needed because the socket we just copied over needs to be cleared.
      * Note that this can result in a client reset if there is partial data       * Note that this can result in a client reset if there is partial data
Line 541
 
Line 570
 {  {
     op->contr->state=ST_PLAY_AGAIN;      op->contr->state=ST_PLAY_AGAIN;
     op->chosen_skill = NULL;      op->chosen_skill = NULL;
     unlock_player(op->name);  
     send_query(&op->contr->socket, CS_QUERY_SINGLECHAR, "Do you want to play again (a/q)?");      send_query(&op->contr->socket, CS_QUERY_SINGLECHAR, "Do you want to play again (a/q)?");
     /* a bit of a hack, but there are various places early in th      /* a bit of a hack, but there are various places early in th
      * player creation process that a user can quit (eg, roll       * player creation process that a user can quit (eg, roll
Line 569
 
Line 597
   
  remove_friendly_object(op);   remove_friendly_object(op);
  free_object(op);   free_object(op);
  get_player(pl);   pl = get_player(pl);
  op = pl->ob;   op = pl->ob;
  add_friendly_object(op);   add_friendly_object(op);
  op->contr->password[0]='~';   op->contr->password[0]='~';
Line 907
 
Line 935
     op->stats.hp=op->stats.maxhp;      op->stats.hp=op->stats.maxhp;
     op->stats.sp=op->stats.maxsp;      op->stats.sp=op->stats.maxsp;
     op->stats.grace=0;      op->stats.grace=0;
     op->contr->last_value= -1;  
     if (op->msg)       if (op->msg)
  new_draw_info(NDI_BLUE, 0, op, op->msg);   new_draw_info(NDI_BLUE, 0, op, op->msg);
     send_query(&op->contr->socket,CS_QUERY_SINGLECHAR,"Press any key for the next race.\nPress `d' to play this race.\n");      send_query(&op->contr->socket,CS_QUERY_SINGLECHAR,"Press any key for the next race.\nPress `d' to play this race.\n");
Line 936
 
Line 963
     terminate_all_pets(op);      terminate_all_pets(op);
     leave_map(op);      leave_map(op);
     op->direction=0;      op->direction=0;
     op->contr->count_left=0;  
     new_draw_info_format(NDI_UNIQUE | NDI_ALL, 5, NULL,      new_draw_info_format(NDI_UNIQUE | NDI_ALL, 5, NULL,
  "%s quits the game.",op->name);   "%s quits the game.",op->name);
   
Line 1267
 
Line 1293
 }  }
   
 /*  /*
  *  Player fires a bow. This probably should be combined with   *  Creature fires a bow - op can be monster or player.  Returns
  *  monster_use_bow().   * 1 if bow was actually fired, 0 otherwise.
    * op is the object firing the bow.
    * part is for multipart creatures - the part firing the bow.
    * dir is the direction of fire.
  */   */
 static void fire_bow(object *op, int dir)  int fire_bow(object *op, object *part, int dir)
 {  {
   object *bow, *arrow = NULL, *left;      object *arrow = NULL, *left, *bow;
   tag_t left_tag;      tag_t left_tag, tag;
   
   if (!dir) {    if (!dir) {
     new_draw_info(NDI_UNIQUE, 0,op, "You can't shoot yourself!");      new_draw_info(NDI_UNIQUE, 0,op, "You can't shoot yourself!");
     return;   return 0;
   }    }
           if (op->type == PLAYER)
    bow=op->contr->ranges[range_bow];
       else {
   for(bow=op->inv; bow; bow=bow->below)    for(bow=op->inv; bow; bow=bow->below)
     if(bow->type==BOW && QUERY_FLAG(bow, FLAG_APPLIED))       /* Don't check for applied - monsters don't apply bows - in that way, they
         * don't need to switch back and forth between bows and weapons.
         */
        if(bow->type==BOW)
       break;        break;
 #ifdef MANY_CORES /* there must be applied bow if shoot_type is range_bow */  
   if (!bow) {    if (!bow) {
     LOG (llevError, "Range: bow without activated bow.\n");       LOG (llevError, "Range: bow without activated bow (%s).\n", op->name);
     abort();       return 0;
    }
   }    }
 #endif  
   if( !bow->race ) {    if( !bow->race ) {
     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);
     op->contr->count_left=0;   return 0;
     return;  
   }    }
   if ((arrow=find_arrow(op, bow->race)) == NULL) {    if ((arrow=find_arrow(op, bow->race)) == NULL) {
    if (op->type == PLAYER)
     new_draw_info_format(NDI_UNIQUE, 0,op,"You have no %s left.", bow->race);      new_draw_info_format(NDI_UNIQUE, 0,op,"You have no %s left.", bow->race);
     op->contr->count_left=0;   /* FLAG_READY_BOW will get reset if the monsters picks up some arrows */
     return;   else CLEAR_FLAG(op, FLAG_READY_BOW);
    return 0;
   }    }
   if(wall(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir])) {    if(wall(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir])) {
     new_draw_info(NDI_UNIQUE, 0,op,"Something is in the way.");      new_draw_info(NDI_UNIQUE, 0,op,"Something is in the way.");
     op->contr->count_left=0;   return 0;
     return;  
   }    }
   /* this should not happen, but sometimes does */    /* this should not happen, but sometimes does */
   if (arrow->nrof==0) {    if (arrow->nrof==0) {
  remove_ob(arrow);   remove_ob(arrow);
  free_object(arrow);   free_object(arrow);
  return;   return 0;
   }    }
   left = arrow; /* these are arrows left to the player */    left = arrow; /* these are arrows left to the player */
   left_tag = left->count;    left_tag = left->count;
   arrow = get_split_ob(arrow, 1);    arrow = get_split_ob(arrow, 1);
   set_owner(arrow,op);    set_owner(arrow,op);
   arrow->direction=dir;    arrow->direction=dir;
   arrow->x = op->x;      arrow->x = part->x;
   arrow->y = op->y;      arrow->y = part->y;
   arrow->speed = 1;    arrow->speed = 1;
       if (op->type == PLAYER) {
   op->speed_left = 0.01 - (float) FABS(op->speed) * 100 / bow->stats.sp;    op->speed_left = 0.01 - (float) FABS(op->speed) * 100 / bow->stats.sp;
   fix_player(op);    fix_player(op);
       }
   update_ob_speed(arrow);    update_ob_speed(arrow);
   arrow->speed_left = 0;    arrow->speed_left = 0;
   SET_ANIMATION(arrow,dir);    SET_ANIMATION(arrow,dir);
   arrow->stats.sp = arrow->stats.wc; /* save original wc and dam */    arrow->stats.sp = arrow->stats.wc; /* save original wc and dam */
   arrow->stats.hp = arrow->stats.dam;     arrow->stats.hp = arrow->stats.dam;
       /* Note that this was different for monsters - they got their level
        * added to the damage.  I think the strength bonus is more proper.
        */
       
   arrow->stats.dam += (QUERY_FLAG(bow, FLAG_NO_STRENGTH) ?    arrow->stats.dam += (QUERY_FLAG(bow, FLAG_NO_STRENGTH) ?
        0 : dam_bonus[op->stats.Str]) +         0 : dam_bonus[op->stats.Str]) +
  bow->stats.dam + bow->magic + arrow->magic;   bow->stats.dam + bow->magic + arrow->magic;
       if (op->type == PLAYER) {
   arrow->stats.wc = 20 - bow->magic - arrow->magic - SK_level(op) -    arrow->stats.wc = 20 - bow->magic - arrow->magic - SK_level(op) -
     dex_bonus[op->stats.Dex] - thaco_bonus[op->stats.Str] - arrow->stats.wc -      dex_bonus[op->stats.Dex] - thaco_bonus[op->stats.Str] - arrow->stats.wc -
     bow->stats.wc;      bow->stats.wc;
   arrow->level = SK_level (op);    arrow->level = SK_level (op);
       } else {
    arrow->stats.wc= op->stats.wc - bow->magic - arrow->magic -
        arrow->stats.wc;
    arrow->level = op->level;
       }
   
   arrow->map = op->map;    arrow->map = op->map;
   SET_FLAG(arrow, FLAG_FLYING);    SET_FLAG(arrow, FLAG_FLYING);
   SET_FLAG(arrow, FLAG_FLY_ON);    SET_FLAG(arrow, FLAG_FLY_ON);
   SET_FLAG(arrow, FLAG_WALK_ON);    SET_FLAG(arrow, FLAG_WALK_ON);
   play_sound_map(op->map, op->x, op->y, SOUND_FIRE_ARROW);    play_sound_map(op->map, op->x, op->y, SOUND_FIRE_ARROW);
       tag = arrow->count;
   insert_ob_in_map(arrow,op->map,op,0);    insert_ob_in_map(arrow,op->map,op,0);
   
       if (!was_destroyed(arrow, tag))
   move_arrow(arrow);    move_arrow(arrow);
   
       if (op->type == PLAYER) {
   if (was_destroyed (left, left_tag))    if (was_destroyed (left, left_tag))
       esrv_del_item(op->contr, left_tag);        esrv_del_item(op->contr, left_tag);
   else    else
       esrv_send_item(op, left);        esrv_send_item(op, left);
 }  }
       return 1;
   }
   
   /* Fires a misc (wand/rod/horn) object in 'dir'.
    * Broken apart from 'fire' to keep it more readable.
    */
   void fire_misc_object(object *op, int dir)
   {
       object  *item;
   
       if (!op->contr->ranges[range_misc]) {
    new_draw_info(NDI_UNIQUE, 0,op,"You have range item readied.");
    return;
       }
   
       item = op->contr->ranges[range_misc];
       if (item->type == WAND) {
    if(item->stats.food<=0) {
        play_sound_player_only(op->contr, SOUND_WAND_POOF,0,0);
        new_draw_info_format(NDI_UNIQUE, 0,op,"The %s goes poof.", query_base_name(item, 0));
    }
       } else if (item->type == ROD || item->type==HORN) {
    if(item->stats.hp<spells[item->stats.sp].sp) {
        play_sound_player_only(op->contr, SOUND_WAND_POOF,0,0);
        if (item->type== ROD)
    new_draw_info_format(NDI_UNIQUE, 0,op,
         "The %s whines for a while, but nothing happens.", query_base_name(item,0));
        else
        new_draw_info(NDI_UNIQUE, 0,op,
      "No matter how hard you try you can't get another note out.");
        return;
    }
       }
   
       if(cast_spell(op,item,dir,op->contr->chosen_item_spell,0,spellMisc,NULL)) {
    SET_FLAG(op, FLAG_BEEN_APPLIED); /* You now know something about it */
    if (item->type == WAND) {
        if (!(--item->stats.food)) {
    object *tmp;
    if (item->arch) {
        CLEAR_FLAG(item, FLAG_ANIMATE);
        item->face = item->arch->clone.face;
        item->speed = 0;
        update_ob_speed(item);
    }
    if ((tmp=is_player_inv(item)))
        esrv_update_item(UPD_ANIM, tmp, item);
        }
    }
    else if (item->type == ROD || item->type==HORN) {
        drain_rod_charge(item);
    }
       }
   }
   
 void fire(object *op,int dir) {  void fire(object *op,int dir) {
   object *weap=NULL;  
   int spellcost=0;    int spellcost=0;
   
   /* check for loss of invisiblity/hide */    /* check for loss of invisiblity/hide */
Line 1368
 
Line 1471
     return;      return;
   
   case range_bow:    case range_bow:
     fire_bow(op, dir);       fire_bow(op, op, dir);
     return;      return;
   
   case range_magic: /* Casting spells */    case range_magic: /* Casting spells */
   
     op->contr->shoottype= range_magic;      op->contr->shoottype= range_magic;
   
     spellcost=cast_spell(op,op,dir,op->contr->chosen_spell,0,spellNormal,NULL);      spellcost=cast_spell(op,op,dir,op->contr->chosen_spell,0,spellNormal,NULL);
   
     if(spells[op->contr->chosen_spell].cleric)      if(spells[op->contr->chosen_spell].cleric)
         op->stats.grace-=spellcost;          op->stats.grace-=spellcost;
     else      else
  op->stats.sp-=spellcost;   op->stats.sp-=spellcost;
   
     return;      return;
   
   case range_wand:   case range_misc:
     for(weap=op->inv;weap!=NULL;weap=weap->below)       fire_misc_object(op, dir);
       if(weap->type==WAND&&QUERY_FLAG(weap, FLAG_APPLIED))  
  break;  
     if(weap==NULL) {  
       new_draw_info(NDI_UNIQUE, 0,op,"You have no wand readied.");  
       op->contr->count_left=0;  
       return;  
     }  
     if(weap->stats.food<=0) {  
       play_sound_player_only(op->contr, SOUND_WAND_POOF,0,0);  
       new_draw_info(NDI_UNIQUE, 0,op,"The wand says poof.");  
       return;        return;
     }  
     if(cast_spell(op,weap,dir,op->contr->chosen_item_spell,0,spellWand,NULL)) {   case range_golem: /* Control summoned monsters from scrolls */
       SET_FLAG(op, FLAG_BEEN_APPLIED); /* You now know something about it */  
       if (!(--weap->stats.food))  
       {  
  object *tmp;  
  if (weap->arch) {  
    CLEAR_FLAG(weap, FLAG_ANIMATE);  
    weap->face = weap->arch->clone.face;  
    weap->speed = 0;  
    update_ob_speed(weap);  
  }  
  if ((tmp=is_player_inv(weap)))  
      esrv_update_item(UPD_ANIM, tmp, weap);  
       }  
     }  
     return;  
   case range_rod:  
   case range_horn:  
     for(weap=op->inv;weap!=NULL;weap=weap->below)  
       if(QUERY_FLAG(weap, FLAG_APPLIED)&&  
  weap->type==(op->contr->shoottype==range_rod?ROD:HORN))  
  break;  
     if(weap==NULL) {  
       char buf[MAX_BUF];  
       sprintf(buf, "You have no %s readied.",  
  op->contr->shoottype == range_rod ? "rod" : "horn");  
       new_draw_info(NDI_UNIQUE, 0,op, buf);  
       op->contr->count_left=0;  
       return;  
     }  
     if(weap->stats.hp<spells[weap->stats.sp].sp) {  
 #if 0  
       LOG(llevDebug,"Horn/rod: %d < %d (%d)\n", weap->stats.hp, spells[weap->stats.sp].sp, weap->stats.sp);  
 #endif  
       play_sound_player_only(op->contr, SOUND_WAND_POOF,0,0);  
       if (op->contr->shoottype == range_rod)  
  new_draw_info(NDI_UNIQUE, 0,op,"The rod whines for a while, but nothing happens.");  
       else  
  new_draw_info(NDI_UNIQUE, 0,op,  
            "No matter how hard you try you can't get another note out.");  
       return;  
     }  
     if(cast_spell(op,weap,dir,op->contr->chosen_item_spell,0,  
        op->contr->shoottype == range_rod ? spellRod : spellHorn,NULL)) {  
       SET_FLAG(op, FLAG_BEEN_APPLIED); /* You now know something about it */  
       drain_rod_charge(weap);  
     }  
     return;  
   case range_scroll: /* Control summoned monsters from scrolls */  
     if(op->contr->golem==NULL) {      if(op->contr->golem==NULL) {
       op->contr->shoottype=range_none;        op->contr->shoottype=range_none;
       op->contr->chosen_spell= -1;        op->contr->chosen_spell= -1;
Line 1454
 
Line 1496
     else       else
  control_golem(op->contr->golem, dir);   control_golem(op->contr->golem, dir);
     return;      return;
   
   case range_skill:    case range_skill:
     if(!op->chosen_skill) {       if(!op->chosen_skill) {
  if(op->type==PLAYER)   if(op->type==PLAYER)
Line 1464
 
Line 1507
     return;      return;
   default:    default:
     new_draw_info(NDI_UNIQUE, 0,op,"Illegal shoot type.");      new_draw_info(NDI_UNIQUE, 0,op,"Illegal shoot type.");
     op->contr->count_left=0;  
     return;      return;
   }    }
 }  }
Line 1768
 
Line 1810
     HandleClient(&op->contr->socket, op->contr);      HandleClient(&op->contr->socket, op->contr);
     if (op->speed_left<0) return 0;      if (op->speed_left<0) return 0;
   
     CLEAR_FLAG(op,FLAG_PARALYZED); /* if we are here, we never paralyzed anymore */  
       
     if(op->direction && (op->contr->run_on || op->contr->fire_on)) {      if(op->direction && (op->contr->run_on || op->contr->fire_on)) {
  /* All move commands take 1 tick, at least for now */   /* All move commands take 1 tick, at least for now */
  op->speed_left--;   op->speed_left--;
Line 1838
 
Line 1878
 }  }
   
   
   /*
    * Returns pointer a static string containing gravestone text
    * Moved from apply.c to player.c - player.c is what
    * actually uses this function.  player.c may not be quite the
    * best, a misc file for object actions is probably better,
    * but there isn't one in the server directory.
    */
   char *gravestone_text (object *op)
   {
       static char buf2[MAX_BUF];
       char buf[MAX_BUF];
       time_t now = time (NULL);
   
       strcpy (buf2, "                 R.I.P.\n\n");
       if (op->type == PLAYER)
           sprintf (buf, "%s the %s\n", op->name, op->contr->title);
       else
           sprintf (buf, "%s\n", op->name);
       strncat (buf2, "                    ",  20 - strlen (buf) / 2);
       strcat (buf2, buf);
       if (op->type == PLAYER)
           sprintf (buf, "who was in level %d when killed\n", op->level);
       else
           sprintf (buf, "who was in level %d when died.\n\n", op->level);
       strncat (buf2, "                    ",  20 - strlen (buf) / 2);
       strcat (buf2, buf);
       if (op->type == PLAYER) {
           sprintf (buf, "by %s.\n\n", op->contr->killer);
           strncat (buf2, "                    ",  21 - strlen (buf) / 2);
           strcat (buf2, buf);
       }
       strftime (buf, MAX_BUF, "%b %d %Y\n", localtime (&now));
       strncat (buf2, "                    ",  20 - strlen (buf) / 2);
       strcat (buf2, buf);
       return buf2;
   }
   
   
   
 void do_some_living(object *op) {  void do_some_living(object *op) {
   int last_food=op->stats.food;    int last_food=op->stats.food;
   int gen_hp, gen_sp, gen_grace;    int gen_hp, gen_sp, gen_grace;
Line 2310
 
Line 2389
 #ifdef SET_TITLE  #ifdef SET_TITLE
     op->contr->own_title[0]='\0';      op->contr->own_title[0]='\0';
 #endif /* SET_TITLE */  #endif /* SET_TITLE */
     op->contr->count_left=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->golem!=NULL) {


Legend:
line(s) removed in v.1.84 
line(s) changed
 line(s) added in v.1.85

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