Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

save.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
00003  *  Michael Seifert, Hans Henrik Strfeldt, Tom Madsen, and Katja Nyboe.    *
00004  *                                                                         *
00005  *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
00006  *  Chastain, Michael Quan, and Mitchell Tse.                              *
00007  *                                                                         *
00008  *  In order to use any part of this Merc Diku Mud, you must comply with   *
00009  *  both the original Diku license in 'license.doc' as well the Merc       *
00010  *  license in 'license.txt'.  In particular, you may not remove either of *
00011  *  these copyright notices.                                               *
00012  *                                                                         *
00013  *  Much time and thought has gone into this software and you are          *
00014  *  benefitting.  We hope that you share your changes too.  What goes      *
00015  *  around, comes around.                                                  *
00016  ***************************************************************************/
00017 
00018 /***************************************************************************
00019  *  ROM 2.4 is copyright 1993-1998 Russ Taylor                             *
00020  *  ROM has been brought to you by the ROM consortium                      *
00021  *      Russ Taylor (rtaylor@@hypercube.org)                                *
00022  *      Gabrielle Taylor (gtaylor@@hypercube.org)                           *
00023  *      Brian Moore (zump@@rom.org)                                         *
00024  *  By using this code, you have agreed to follow the terms of the         *
00025  *  ROM license, in the file Rom24/doc/rom.license                         *
00026  ***************************************************************************/
00027 
00028 #if defined(macintosh)
00029 #include <types.h>
00030 #else
00031 #include <sys/types.h>
00032 #endif
00033 #include <ctype.h>
00034 #include <stdio.h>
00035 #include <string.h>
00036 #include <time.h>
00037 #include <malloc.h>
00038 #include "merc.h"
00039 #include "recycle.h"
00040 #include "tables.h"
00041 #include "lookup.h"
00042 
00043 #if !defined(macintosh)
00044 extern int _filbuf args ((FILE *));
00045 #endif
00046 
00047 
00048 /* int rename(const char *oldfname, const char *newfname); viene en stdio.h */
00049 
00050 char *print_flags (int flag)
00051 {
00052     int count, pos = 0;
00053     static char buf[52];
00054 
00055 
00056     for (count = 0; count < 32; count++)
00057     {
00058         if (IS_SET (flag, 1 << count))
00059         {
00060             if (count < 26)
00061                 buf[pos] = 'A' + count;
00062             else
00063                 buf[pos] = 'a' + (count - 26);
00064             pos++;
00065         }
00066     }
00067 
00068     if (pos == 0)
00069     {
00070         buf[pos] = '0';
00071         pos++;
00072     }
00073 
00074     buf[pos] = '\0';
00075 
00076     return buf;
00077 }
00078 
00079 
00080 /*
00081  * Array of containers read for proper re-nesting of objects.
00082  */
00083 #define MAX_NEST    100
00084 static OBJ_DATA *rgObjNest[MAX_NEST];
00085 
00086 
00087 
00088 /*
00089  * Local functions.
00090  */
00091 void fwrite_char args ((CHAR_DATA * ch, FILE * fp));
00092 void fwrite_obj args ((CHAR_DATA * ch, OBJ_DATA * obj, FILE * fp, int iNest));
00093 void fwrite_pet args ((CHAR_DATA * pet, FILE * fp));
00094 void fread_char args ((CHAR_DATA * ch, FILE * fp));
00095 void fread_pet args ((CHAR_DATA * ch, FILE * fp));
00096 void fread_obj args ((CHAR_DATA * ch, FILE * fp));
00097 
00098 
00099 
00100 /*
00101  * Save a character and inventory.
00102  * Would be cool to save NPC's too for quest purposes,
00103  *   some of the infrastructure is provided.
00104  */
00105 void save_char_obj (CHAR_DATA * ch)
00106 {
00107     char strsave[MAX_INPUT_LENGTH];
00108     FILE *fp;
00109 
00110     if (IS_NPC (ch))
00111         return;
00112 
00113     /*
00114      * Fix by Edwin. JR -- 10/15/00
00115      *
00116      * Don't save if the character is invalidated.
00117      * This might happen during the auto-logoff of players.
00118      * (or other places not yet found out)
00119      */
00120     if ( !IS_VALID(ch)) {
00121         bug("save_char_obj: Trying to save an invalidated character.\n",0);
00122         return;
00123     }
00124 
00125     if (ch->desc != NULL && ch->desc->original != NULL)
00126         ch = ch->desc->original;
00127 
00128 #if defined(unix)
00129     /* create god log */
00130     if (IS_IMMORTAL (ch) || ch->level >= LEVEL_IMMORTAL)
00131     {
00132         fclose (fpReserve);
00133         sprintf (strsave, "%s%s", GOD_DIR, capitalize (ch->name));
00134         if ((fp = fopen (strsave, "w")) == NULL)
00135         {
00136             bug ("Save_char_obj: fopen", 0);
00137             perror (strsave);
00138         }
00139 
00140         fprintf (fp, "Lev %2d Trust %2d  %s%s\n",
00141                  ch->level, get_trust (ch), ch->name, ch->pcdata->title);
00142         fclose (fp);
00143         fpReserve = fopen (NULL_FILE, "r");
00144     }
00145 #endif
00146 
00147     fclose (fpReserve);
00148     sprintf (strsave, "%s%s", PLAYER_DIR, capitalize (ch->name));
00149     if ((fp = fopen (TEMP_FILE, "w")) == NULL)
00150     {
00151         bug ("Save_char_obj: fopen", 0);
00152         perror (strsave);
00153     }
00154     else
00155     {
00156         fwrite_char (ch, fp);
00157         if (ch->carrying != NULL)
00158             fwrite_obj (ch, ch->carrying, fp, 0);
00159         /* save the pets */
00160         if (ch->pet != NULL && ch->pet->in_room == ch->in_room)
00161             fwrite_pet (ch->pet, fp);
00162         fprintf (fp, "#END\n");
00163     }
00164     fclose (fp);
00165     rename (TEMP_FILE, strsave);
00166     fpReserve = fopen (NULL_FILE, "r");
00167     return;
00168 }
00169 
00170 
00171 
00172 /*
00173  * Write the char.
00174  */
00175     void fwrite_char (CHAR_DATA * ch, FILE * fp)
00176     {
00177         AFFECT_DATA *paf;
00178         int sn, gn, pos, i;
00179 
00180         fprintf (fp, "#%s\n", IS_NPC (ch) ? "MOB" : "PLAYER");
00181 
00182         fprintf (fp, "Name %s~\n", ch->name);
00183         fprintf (fp, "Id   %ld\n", ch->id);
00184         fprintf (fp, "LogO %ld\n", current_time);
00185         fprintf (fp, "Vers %d\n", 5);
00186         if (ch->short_descr[0] != '\0')
00187         fprintf (fp, "ShD  %s~\n", ch->short_descr);
00188         if (ch->long_descr[0] != '\0')
00189         fprintf (fp, "LnD  %s~\n", ch->long_descr);
00190         if (ch->description[0] != '\0')
00191         fprintf (fp, "Desc %s~\n", ch->description);
00192         if (ch->prompt != NULL || !str_cmp (ch->prompt, "<%hhp %mm %vmv> ")
00193         || !str_cmp (ch->prompt, "{c<%hhp %mm %vmv>{x "))
00194         fprintf (fp, "Prom %s~\n", ch->prompt);
00195         fprintf (fp, "Race %s~\n", pc_race_table[ch->race].name);
00196         if (ch->clan)
00197         fprintf (fp, "Clan %s~\n", clan_table[ch->clan].name);
00198         if (ch->king)
00199             fprintf (fp, "King %s~\n", kingdom_table[ch->king].name);
00200         else
00201             fprintf (fp, "King 0~\n");
00202 
00203             
00204         fprintf (fp, "Sex  %d\n", ch->sex);
00205         fprintf (fp, "Cla  %d\n", ch->class);
00206         fprintf (fp, "Levl %d\n", ch->level);
00207         if (ch->trust != 0)
00208         fprintf (fp, "Tru  %d\n", ch->trust);
00209         fprintf (fp, "Sec  %d\n", ch->pcdata->security);    /* OLC */
00210         fprintf (fp, "Plyd %d\n", ch->played + (int) (current_time - ch->logon));
00211         fprintf (fp, "Scro %d\n", ch->lines);
00212         fprintf (fp, "Room %d\n", (ch->in_room == get_room_index (ROOM_VNUM_LIMBO)
00213                        && ch->was_in_room != NULL)
00214              ? ch->was_in_room->vnum
00215              : ch->in_room == NULL ? 3001 : ch->in_room->vnum);
00216 
00217         fprintf (fp, "HMV  %d %d %d %d %d %d\n",
00218              ch->hit, ch->max_hit, ch->mana, ch->max_mana, ch->move,
00219              ch->max_move);
00220         if (ch->gold > 0)
00221         fprintf (fp, "Gold %ld\n", ch->gold);
00222         else
00223         fprintf (fp, "Gold %d\n", 0);
00224         if (ch->silver > 0)
00225         fprintf (fp, "Silv %ld\n", ch->silver);
00226         else
00227         fprintf (fp, "Silv %d\n", 0);
00228         fprintf (fp, "Exp  %d\n", ch->exp);
00229         if (ch->act != 0)
00230         fprintf (fp, "Act  %s\n", print_flags (ch->act));
00231         if (ch->affected_by != 0)
00232         fprintf (fp, "AfBy %s\n", print_flags (ch->affected_by));
00233         fprintf (fp, "Comm %s\n", print_flags (ch->comm));
00234         fprintf (fp, "Chann %s\n", print_flags (ch->chann));
00235         fprintf (fp, "CClan %s\n", print_flags (ch->cclan));
00236         if (ch->pcdata->immortal)
00237             fprintf (fp, "Immort %s\n", print_flags (ch->pcdata->immortal));
00238         if (ch->kking)
00239             fprintf (fp, "KKing %s\n", print_flags (ch->kking));
00240        // if(ch->king)
00241     //      fprintf(fp, "King %s\n", kingdom_table[ch->king].name);
00242         
00243         if (ch->wiznet)
00244         fprintf (fp, "Wizn %s\n", print_flags (ch->wiznet));
00245         if (ch->invis_level)
00246         fprintf (fp, "Invi %d\n", ch->invis_level);
00247         if (ch->incog_level)
00248         fprintf (fp, "Inco %d\n", ch->incog_level);
00249         fprintf (fp, "Pos  %d\n",
00250              ch->position == POS_FIGHTING ? POS_STANDING : ch->position);
00251         if (ch->practice != 0)
00252         fprintf (fp, "Prac %d\n", ch->practice);
00253         if (ch->train != 0)
00254         fprintf (fp, "Trai %d\n", ch->train);
00255         if (ch->saving_throw != 0)
00256         fprintf (fp, "Save  %d\n", ch->saving_throw);
00257         fprintf (fp, "Alig  %d\n", ch->alignment);
00258         if (ch->hitroll != 0)
00259         fprintf (fp, "Hit   %d\n", ch->hitroll);
00260         if (ch->damroll != 0)
00261         fprintf (fp, "Dam   %d\n", ch->damroll);
00262         fprintf (fp, "ACs %d %d %d %d\n",
00263              ch->armor[0], ch->armor[1], ch->armor[2], ch->armor[3]);
00264         if (ch->wimpy != 0)
00265         fprintf (fp, "Wimp  %d\n", ch->wimpy);
00266         fprintf (fp, "Attr %d %d %d %d %d\n",
00267              ch->perm_stat[STAT_STR],
00268              ch->perm_stat[STAT_INT],
00269              ch->perm_stat[STAT_WIS],
00270              ch->perm_stat[STAT_DEX], ch->perm_stat[STAT_CON]);
00271 
00272         fprintf (fp, "AMod %d %d %d %d %d\n",
00273              ch->mod_stat[STAT_STR],
00274              ch->mod_stat[STAT_INT],
00275              ch->mod_stat[STAT_WIS],
00276              ch->mod_stat[STAT_DEX], ch->mod_stat[STAT_CON]);
00277 
00278         if (IS_NPC (ch))
00279         {
00280         fprintf (fp, "Vnum %d\n", ch->pIndexData->vnum);
00281         }
00282         else
00283         {
00284         fprintf (fp, "Pass %s~\n", ch->pcdata->pwd);
00285         if (ch->pcdata->bamfin[0] != '\0')
00286             fprintf (fp, "Bin  %s~\n", ch->pcdata->bamfin);
00287         if (ch->pcdata->bamfout[0] != '\0')
00288             fprintf (fp, "Bout %s~\n", ch->pcdata->bamfout);
00289         fprintf (fp, "Titl %s~\n", ch->pcdata->title);
00290         fprintf (fp, "Pnts %d\n", ch->pcdata->points);
00291         fprintf (fp, "TSex %d\n", ch->pcdata->true_sex);
00292         fprintf (fp, "LLev %d\n", ch->pcdata->last_level);
00293         fprintf (fp, "HMVP %d %d %d\n", ch->pcdata->perm_hit,
00294              ch->pcdata->perm_mana, ch->pcdata->perm_move);
00295         fprintf (fp, "Cnd  %d %d %d %d\n",
00296              ch->pcdata->condition[0],
00297              ch->pcdata->condition[1],
00298              ch->pcdata->condition[2], ch->pcdata->condition[3]);
00299         fprintf(fp, "Lastnote %d\n", ch->pcdata->last_note);
00300         fprintf(fp, "Lastidea %d\n", ch->pcdata->last_idea);
00301         fprintf(fp, "Lastpena %d\n", ch->pcdata->last_penalty);
00302         fprintf(fp, "Lastnews %d\n", ch->pcdata->last_news);
00303         fprintf(fp, "Lastchan %d\n", ch->pcdata->last_changes);
00304         fprintf(fp, "Lasthist %d\n", ch->pcdata->last_history);
00305         fprintf(fp, "Eyecolor %s~\n", ch->pcdata->eyecolor);
00306         fprintf(fp, "Hairtype %s~\n", ch->pcdata->hairtype);
00307         fprintf(fp, "Haircolor %s~\n", ch->pcdata->haircolor);
00308         fprintf(fp, "Bodytype %s~\n", ch->pcdata->bodytype);
00309         fprintf(fp, "Hairlength %s~\n", ch->pcdata->hairlength);
00310         fprintf(fp, "Facialhair %s~\n", ch->pcdata->facialhair);
00311         fprintf(fp, "Immtitle %s~\n", ch->pcdata->imm_title);
00312         fprintf(fp, "Age %d\n", ch->pcdata->plr_age);
00313 
00314     //fprintf (fp, "Password %s~\n", ch->pcdata->pwd);
00315         /*
00316          * Write Colour Config Information.
00317          */
00318     /*        fprintf (fp, "Coloura     %d%d%d %d%d%d %d%d%d %d%d%d %d%d%d\n",
00319              ch->pcdata->text[2],
00320              ch->pcdata->text[0],
00321              ch->pcdata->text[1],
00322              ch->pcdata->auction[2],
00323              ch->pcdata->auction[0],
00324              ch->pcdata->auction[1],
00325              ch->pcdata->gossip[2],
00326              ch->pcdata->gossip[0],
00327              ch->pcdata->gossip[1],
00328              ch->pcdata->music[2],
00329              ch->pcdata->music[0],
00330              ch->pcdata->music[1],
00331              ch->pcdata->question[2],
00332              ch->pcdata->question[0], ch->pcdata->question[1]);
00333         fprintf (fp, "Colourb     %d%d%d %d%d%d %d%d%d %d%d%d %d%d%d\n",
00334              ch->pcdata->answer[2],
00335              ch->pcdata->answer[0],
00336              ch->pcdata->answer[1],
00337              ch->pcdata->quote[2],
00338              ch->pcdata->quote[0],
00339              ch->pcdata->quote[1],
00340              ch->pcdata->quote_text[2],
00341              ch->pcdata->quote_text[0],
00342              ch->pcdata->quote_text[1],
00343              ch->pcdata->immtalk_text[2],
00344              ch->pcdata->immtalk_text[0],
00345              ch->pcdata->immtalk_text[1],
00346              ch->pcdata->immtalk_type[2],
00347              ch->pcdata->immtalk_type[0], ch->pcdata->immtalk_type[1]);
00348         fprintf (fp, "Colourc     %d%d%d %d%d%d %d%d%d %d%d%d %d%d%d\n",
00349              ch->pcdata->info[2],
00350              ch->pcdata->info[0],
00351              ch->pcdata->info[1],
00352              ch->pcdata->tell[2],
00353              ch->pcdata->tell[0],
00354              ch->pcdata->tell[1],
00355              ch->pcdata->reply[2],
00356              ch->pcdata->reply[0],
00357              ch->pcdata->reply[1],
00358              ch->pcdata->gtell_text[2],
00359              ch->pcdata->gtell_text[0],
00360              ch->pcdata->gtell_text[1],
00361              ch->pcdata->gtell_type[2],
00362              ch->pcdata->gtell_type[0], ch->pcdata->gtell_type[1]);
00363         fprintf (fp, "Colourd     %d%d%d %d%d%d %d%d%d %d%d%d %d%d%d\n",
00364              ch->pcdata->room_title[2],
00365              ch->pcdata->room_title[0],
00366              ch->pcdata->room_title[1],
00367              ch->pcdata->room_text[2],
00368              ch->pcdata->room_text[0],
00369              ch->pcdata->room_text[1],
00370              ch->pcdata->room_exits[2],
00371              ch->pcdata->room_exits[0],
00372              ch->pcdata->room_exits[1],
00373              ch->pcdata->room_things[2],
00374              ch->pcdata->room_things[0],
00375              ch->pcdata->room_things[1],
00376              ch->pcdata->prompt[2],
00377              ch->pcdata->prompt[0], ch->pcdata->prompt[1]);
00378         fprintf (fp, "Coloure     %d%d%d %d%d%d %d%d%d %d%d%d %d%d%d\n",
00379              ch->pcdata->fight_death[2],
00380              ch->pcdata->fight_death[0],
00381              ch->pcdata->fight_death[1],
00382              ch->pcdata->fight_yhit[2],
00383              ch->pcdata->fight_yhit[0],
00384              ch->pcdata->fight_yhit[1],
00385              ch->pcdata->fight_ohit[2],
00386              ch->pcdata->fight_ohit[0],
00387              ch->pcdata->fight_ohit[1],
00388              ch->pcdata->fight_thit[2],
00389              ch->pcdata->fight_thit[0],
00390              ch->pcdata->fight_thit[1],
00391              ch->pcdata->fight_skill[2],
00392              ch->pcdata->fight_skill[0], ch->pcdata->fight_skill[1]);
00393         fprintf (fp, "Colourf     %d%d%d %d%d%d %d%d%d %d%d%d %d%d%d\n",
00394              ch->pcdata->wiznet[2],
00395              ch->pcdata->wiznet[0],
00396              ch->pcdata->wiznet[1],
00397              ch->pcdata->say[2],
00398              ch->pcdata->say[0],
00399              ch->pcdata->say[1],
00400              ch->pcdata->say_text[2],
00401              ch->pcdata->say_text[0],
00402              ch->pcdata->say_text[1],
00403              ch->pcdata->tell_text[2],
00404              ch->pcdata->tell_text[0],
00405              ch->pcdata->tell_text[1],
00406              ch->pcdata->reply_text[2],
00407              ch->pcdata->reply_text[0], ch->pcdata->reply_text[1]);
00408         fprintf (fp, "Colourg     %d%d%d %d%d%d %d%d%d %d%d%d %d%d%d\n",
00409              ch->pcdata->auction_text[2],
00410              ch->pcdata->auction_text[0],
00411              ch->pcdata->auction_text[1],
00412              ch->pcdata->gossip_text[2],
00413              ch->pcdata->gossip_text[0],
00414              ch->pcdata->gossip_text[1],
00415              ch->pcdata->music_text[2],
00416              ch->pcdata->music_text[0],
00417              ch->pcdata->music_text[1],
00418              ch->pcdata->question_text[2],
00419              ch->pcdata->question_text[0],
00420              ch->pcdata->question_text[1],
00421              ch->pcdata->answer_text[2],
00422              ch->pcdata->answer_text[0], ch->pcdata->answer_text[1]);*/
00423 
00424         /* write alias */
00425         for (pos = 0; pos < MAX_ALIAS; pos++)
00426         {
00427             if (ch->pcdata->alias[pos] == NULL
00428             || ch->pcdata->alias_sub[pos] == NULL)
00429             break;
00430 
00431             fprintf (fp, "Alias %s %s~\n", ch->pcdata->alias[pos],
00432                  ch->pcdata->alias_sub[pos]);
00433         }
00434 
00435             /* Save note board status */
00436             /* Save number of boards in case that number changes */
00437         //  fprintf (fp, "Boards       %d ", MAX_BOARD);
00438         //  for (i = 0; i < MAX_BOARD; i++)
00439         //      fprintf (fp, "%s %ld ", boards[i].short_name, ch->pcdata->last_note[i]);
00440         //  fprintf (fp, "\n");
00441 
00442         for (sn = 0; sn < MAX_SKILL; sn++)
00443         {
00444             if (skill_table[sn].name != NULL && ch->pcdata->learned[sn] > 0)
00445             {
00446             fprintf (fp, "Sk %d '%s'\n",
00447                  ch->pcdata->learned[sn], skill_table[sn].name);
00448             }
00449         }
00450 
00451         for (gn = 0; gn < MAX_GROUP; gn++)
00452         {
00453             if (group_table[gn].name != NULL && ch->pcdata->group_known[gn])
00454             {
00455             fprintf (fp, "Gr '%s'\n", group_table[gn].name);
00456             }
00457         }
00458         }
00459 
00460         for (paf = ch->affected; paf != NULL; paf = paf->next)
00461         {
00462         if (paf->type < 0 || paf->type >= MAX_SKILL)
00463             continue;
00464 
00465         fprintf (fp, "Affc '%s' %3d %3d %3d %3d %3d %10d\n",
00466              skill_table[paf->type].name,
00467              paf->where,
00468              paf->level,
00469              paf->duration, paf->modifier, paf->location, paf->bitvector);
00470         }
00471 
00472         fprintf (fp, "End\n\n");
00473         return;
00474     }
00475 
00476     /* write a pet */
00477     void fwrite_pet (CHAR_DATA * pet, FILE * fp)
00478     {
00479         AFFECT_DATA *paf;
00480 
00481         fprintf (fp, "#PET\n");
00482 
00483         fprintf (fp, "Vnum %d\n", pet->pIndexData->vnum);
00484 
00485         fprintf (fp, "Name %s~\n", pet->name);
00486         fprintf (fp, "LogO %ld\n", current_time);
00487         if (pet->short_descr != pet->pIndexData->short_descr)
00488         fprintf (fp, "ShD  %s~\n", pet->short_descr);
00489         if (pet->long_descr != pet->pIndexData->long_descr)
00490         fprintf (fp, "LnD  %s~\n", pet->long_descr);
00491         if (pet->description != pet->pIndexData->description)
00492         fprintf (fp, "Desc %s~\n", pet->description);
00493         if (pet->race != pet->pIndexData->race)
00494         fprintf (fp, "Race %s~\n", race_table[pet->race].name);
00495         if (pet->clan)
00496         fprintf (fp, "Clan %s~\n", clan_table[pet->clan].name);
00497         fprintf (fp, "Sex  %d\n", pet->sex);
00498         if (pet->level != pet->pIndexData->level)
00499         fprintf (fp, "Levl %d\n", pet->level);
00500         fprintf (fp, "HMV  %d %d %d %d %d %d\n",
00501              pet->hit, pet->max_hit, pet->mana, pet->max_mana, pet->move,
00502              pet->max_move);
00503         if (pet->gold > 0)
00504         fprintf (fp, "Gold %ld\n", pet->gold);
00505         if (pet->silver > 0)
00506         fprintf (fp, "Silv %ld\n", pet->silver);
00507         if (pet->exp > 0)
00508         fprintf (fp, "Exp  %d\n", pet->exp);
00509         if (pet->act != pet->pIndexData->act)
00510         fprintf (fp, "Act  %s\n", print_flags (pet->act));
00511         if (pet->affected_by != pet->pIndexData->affected_by)
00512         fprintf (fp, "AfBy %s\n", print_flags (pet->affected_by));
00513         if (pet->comm != 0)
00514         fprintf (fp, "Comm %s\n", print_flags (pet->comm));
00515         fprintf (fp, "Pos  %d\n", pet->position =
00516              POS_FIGHTING ? POS_STANDING : pet->position);
00517         if (pet->saving_throw != 0)
00518         fprintf (fp, "Save %d\n", pet->saving_throw);
00519         if (pet->alignment != pet->pIndexData->alignment)
00520         fprintf (fp, "Alig %d\n", pet->alignment);
00521         if (pet->hitroll != pet->pIndexData->hitroll)
00522         fprintf (fp, "Hit  %d\n", pet->hitroll);
00523         if (pet->damroll != pet->pIndexData->damage[DICE_BONUS])
00524         fprintf (fp, "Dam  %d\n", pet->damroll);
00525         fprintf (fp, "ACs  %d %d %d %d\n",
00526              pet->armor[0], pet->armor[1], pet->armor[2], pet->armor[3]);
00527         fprintf (fp, "Attr %d %d %d %d %d\n",
00528              pet->perm_stat[STAT_STR], pet->perm_stat[STAT_INT],
00529              pet->perm_stat[STAT_WIS], pet->perm_stat[STAT_DEX],
00530              pet->perm_stat[STAT_CON]);
00531         fprintf (fp, "AMod %d %d %d %d %d\n",
00532              pet->mod_stat[STAT_STR], pet->mod_stat[STAT_INT],
00533              pet->mod_stat[STAT_WIS], pet->mod_stat[STAT_DEX],
00534              pet->mod_stat[STAT_CON]);
00535 
00536         for (paf = pet->affected; paf != NULL; paf = paf->next)
00537         {
00538         if (paf->type < 0 || paf->type >= MAX_SKILL)
00539             continue;
00540 
00541         fprintf (fp, "Affc '%s' %3d %3d %3d %3d %3d %10d\n",
00542              skill_table[paf->type].name,
00543              paf->where, paf->level, paf->duration, paf->modifier,
00544              paf->location, paf->bitvector);
00545         }
00546 
00547         fprintf (fp, "End\n");
00548         return;
00549     }
00550 
00551     /*
00552      * Write an object and its contents.
00553      */
00554     void fwrite_obj (CHAR_DATA * ch, OBJ_DATA * obj, FILE * fp, int iNest)
00555     {
00556         EXTRA_DESCR_DATA *ed;
00557         AFFECT_DATA *paf;
00558 
00559         /*
00560          * Slick recursion to write lists backwards,
00561          *   so loading them will load in forwards order.
00562          */
00563         if (obj->next_content != NULL)
00564         fwrite_obj (ch, obj->next_content, fp, iNest);
00565 
00566         /*
00567          * Castrate storage characters.
00568          */
00569         if ((ch->level < obj->level - 2 && obj->item_type != ITEM_CONTAINER)
00570         || obj->item_type == ITEM_KEY
00571         || (obj->item_type == ITEM_MAP && !obj->value[0]))
00572         return;
00573 
00574         fprintf (fp, "#O\n");
00575         fprintf (fp, "Vnum %d\n", obj->pIndexData->vnum);
00576         if (!obj->pIndexData->new_format)
00577         fprintf (fp, "Oldstyle\n");
00578         if (obj->enchanted)
00579         fprintf (fp, "Enchanted\n");
00580         fprintf (fp, "Nest %d\n", iNest);
00581 
00582         /* these data are only used if they do not match the defaults */
00583 
00584         if (obj->name != obj->pIndexData->name)
00585         fprintf (fp, "Name %s~\n", obj->name);
00586         if (obj->short_descr != obj->pIndexData->short_descr)
00587         fprintf (fp, "ShD  %s~\n", obj->short_descr);
00588         if (obj->description != obj->pIndexData->description)
00589         fprintf (fp, "Desc %s~\n", obj->description);
00590         if (obj->extra_flags != obj->pIndexData->extra_flags)
00591         fprintf (fp, "ExtF %d\n", obj->extra_flags);
00592         if (obj->wear_flags != obj->pIndexData->wear_flags)
00593         fprintf (fp, "WeaF %d\n", obj->wear_flags);
00594         if (obj->item_type != obj->pIndexData->item_type)
00595         fprintf (fp, "Ityp %d\n", obj->item_type);
00596         if (obj->weight != obj->pIndexData->weight)
00597         fprintf (fp, "Wt   %d\n", obj->weight);
00598         if (obj->condition != obj->pIndexData->condition)
00599         fprintf (fp, "Cond %d\n", obj->condition);
00600 
00601         /* variable data */
00602 
00603         fprintf (fp, "Wear %d\n", obj->wear_loc);
00604         if (obj->level != obj->pIndexData->level)
00605         fprintf (fp, "Lev  %d\n", obj->level);
00606         if (obj->timer != 0)
00607         fprintf (fp, "Time %d\n", obj->timer);
00608         fprintf (fp, "Cost %d\n", obj->cost);
00609         if (obj->value[0] != obj->pIndexData->value[0]
00610         || obj->value[1] != obj->pIndexData->value[1]
00611         || obj->value[2] != obj->pIndexData->value[2]
00612         || obj->value[3] != obj->pIndexData->value[3]
00613         || obj->value[4] != obj->pIndexData->value[4])
00614         fprintf (fp, "Val  %d %d %d %d %d\n",
00615              obj->value[0], obj->value[1], obj->value[2], obj->value[3],
00616              obj->value[4]);
00617 
00618         switch (obj->item_type)
00619         {
00620         case ITEM_POTION:
00621         case ITEM_SCROLL:
00622         case ITEM_PILL:
00623             if (obj->value[1] > 0)
00624             {
00625             fprintf (fp, "Spell 1 '%s'\n",
00626                  skill_table[obj->value[1]].name);
00627             }
00628 
00629             if (obj->value[2] > 0)
00630             {
00631             fprintf (fp, "Spell 2 '%s'\n",
00632                  skill_table[obj->value[2]].name);
00633             }
00634 
00635             if (obj->value[3] > 0)
00636             {
00637             fprintf (fp, "Spell 3 '%s'\n",
00638                  skill_table[obj->value[3]].name);
00639             }
00640 
00641             break;
00642 
00643         case ITEM_STAFF:
00644         case ITEM_WAND:
00645             if (obj->value[3] > 0)
00646             {
00647             fprintf (fp, "Spell 3 '%s'\n",
00648                  skill_table[obj->value[3]].name);
00649             }
00650 
00651             break;
00652         }
00653 
00654         for (paf = obj->affected; paf != NULL; paf = paf->next)
00655         {
00656         if (paf->type < 0 || paf->type >= MAX_SKILL)
00657             continue;
00658         fprintf (fp, "Affc '%s' %3d %3d %3d %3d %3d %10d\n",
00659              skill_table[paf->type].name,
00660              paf->where,
00661              paf->level,
00662              paf->duration, paf->modifier, paf->location, paf->bitvector);
00663         }
00664 
00665         for (ed = obj->extra_descr; ed != NULL; ed = ed->next)
00666         {
00667         fprintf (fp, "ExDe %s~ %s~\n", ed->keyword, ed->description);
00668         }
00669 
00670         fprintf (fp, "End\n\n");
00671 
00672         if (obj->contains != NULL)
00673         fwrite_obj (ch, obj->contains, fp, iNest + 1);
00674 
00675         return;
00676     }
00677 
00678 
00679 
00680     /*
00681      * Load a char and inventory into a new ch structure.
00682      */
00683     bool load_char_obj (DESCRIPTOR_DATA * d, char *name)
00684     {
00685         char strsave[MAX_INPUT_LENGTH];
00686         char buf[100];
00687         CHAR_DATA *ch;
00688         FILE *fp;
00689         bool found;
00690         int stat;
00691 
00692         ch = new_char ();
00693         ch->pcdata = new_pcdata ();
00694 
00695         d->character = ch;
00696         ch->desc = d;
00697         ch->name = str_dup (name);
00698         ch->id = get_pc_id ();
00699         ch->race = race_lookup ("human");
00700         ch->act = PLR_NOSUMMON;
00701         ch->comm = COMM_COMBINE | COMM_PROMPT;
00702         ch->prompt = str_dup ("<%hhp %mm %vmv> ");
00703         ch->pcdata->confirm_delete = FALSE;
00704     //  ch->pcdata->board = &boards[DEFAULT_BOARD];
00705         ch->pcdata->pwd = str_dup ("");
00706         ch->pcdata->bamfin = str_dup ("");
00707         ch->pcdata->bamfout = str_dup ("");
00708         ch->pcdata->title = str_dup ("");
00709         for (stat = 0; stat < MAX_STATS; stat++)
00710         ch->perm_stat[stat] = 13;
00711         ch->pcdata->condition[COND_THIRST] = 48;
00712         ch->pcdata->condition[COND_FULL] = 48;
00713         ch->pcdata->condition[COND_HUNGER] = 48;
00714         ch->pcdata->security = 0;    /* OLC */
00715 
00716         ch->pcdata->text[0] = (NORMAL);
00717         ch->pcdata->text[1] = (WHITE);
00718         ch->pcdata->text[2] = 0;
00719         ch->pcdata->auction[0] = (BRIGHT);
00720         ch->pcdata->auction[1] = (YELLOW);
00721         ch->pcdata->auction[2] = 0;
00722         ch->pcdata->auction_text[0] = (BRIGHT);
00723         ch->pcdata->auction_text[1] = (WHITE);
00724         ch->pcdata->auction_text[2] = 0;
00725         ch->pcdata->gossip[0] = (NORMAL);
00726         ch->pcdata->gossip[1] = (MAGENTA);
00727         ch->pcdata->gossip[2] = 0;
00728         ch->pcdata->gossip_text[0] = (BRIGHT);
00729         ch->pcdata->gossip_text[1] = (MAGENTA);
00730         ch->pcdata->gossip_text[2] = 0;
00731         ch->pcdata->music[0] = (NORMAL);
00732         ch->pcdata->music[1] = (RED);
00733         ch->pcdata->music[2] = 0;
00734         ch->pcdata->music_text[0] = (BRIGHT);
00735         ch->pcdata->music_text[1] = (RED);
00736         ch->pcdata->music_text[2] = 0;
00737         ch->pcdata->question[0] = (BRIGHT);
00738         ch->pcdata->question[1] = (YELLOW);
00739         ch->pcdata->question[2] = 0;
00740         ch->pcdata->question_text[0] = (BRIGHT);
00741         ch->pcdata->question_text[1] = (WHITE);
00742         ch->pcdata->question_text[2] = 0;
00743         ch->pcdata->answer[0] = (BRIGHT);
00744         ch->pcdata->answer[1] = (YELLOW);
00745         ch->pcdata->answer[2] = 0;
00746         ch->pcdata->answer_text[0] = (BRIGHT);
00747         ch->pcdata->answer_text[1] = (WHITE);
00748         ch->pcdata->answer_text[2] = 0;
00749         ch->pcdata->quote[0] = (NORMAL);
00750         ch->pcdata->quote[1] = (YELLOW);
00751         ch->pcdata->quote[2] = 0;
00752         ch->pcdata->quote_text[0] = (NORMAL);
00753         ch->pcdata->quote_text[1] = (GREEN);
00754         ch->pcdata->quote_text[2] = 0;
00755         ch->pcdata->immtalk_text[0] = (NORMAL);
00756         ch->pcdata->immtalk_text[1] = (CYAN);
00757         ch->pcdata->immtalk_text[2] = 0;
00758         ch->pcdata->immtalk_type[0] = (NORMAL);
00759         ch->pcdata->immtalk_type[1] = (YELLOW);
00760         ch->pcdata->immtalk_type[2] = 0;
00761         ch->pcdata->info[0] = (BRIGHT);
00762         ch->pcdata->info[1] = (YELLOW);
00763         ch->pcdata->info[2] = 1;
00764         ch->pcdata->say[0] = (NORMAL);
00765         ch->pcdata->say[1] = (GREEN);
00766         ch->pcdata->say[2] = 0;
00767         ch->pcdata->say_text[0] = (BRIGHT);
00768         ch->pcdata->say_text[1] = (GREEN);
00769         ch->pcdata->say_text[2] = 0;
00770         ch->pcdata->tell[0] = (NORMAL);
00771         ch->pcdata->tell[1] = (GREEN);
00772         ch->pcdata->tell[2] = 0;
00773         ch->pcdata->tell_text[0] = (BRIGHT);
00774         ch->pcdata->tell_text[1] = (GREEN);
00775         ch->pcdata->tell_text[2] = 0;
00776         ch->pcdata->reply[0] = (NORMAL);
00777         ch->pcdata->reply[1] = (GREEN);
00778         ch->pcdata->reply[2] = 0;
00779         ch->pcdata->reply_text[0] = (BRIGHT);
00780         ch->pcdata->reply_text[1] = (GREEN);
00781         ch->pcdata->reply_text[2] = 0;
00782         ch->pcdata->gtell_text[0] = (NORMAL);
00783         ch->pcdata->gtell_text[1] = (GREEN);
00784         ch->pcdata->gtell_text[2] = 0;
00785         ch->pcdata->gtell_type[0] = (NORMAL);
00786         ch->pcdata->gtell_type[1] = (RED);
00787         ch->pcdata->gtell_type[2] = 0;
00788         ch->pcdata->wiznet[0] = (NORMAL);
00789         ch->pcdata->wiznet[1] = (GREEN);
00790         ch->pcdata->wiznet[2] = 0;
00791         ch->pcdata->room_title[0] = (NORMAL);
00792         ch->pcdata->room_title[1] = (CYAN);
00793         ch->pcdata->room_title[2] = 0;
00794         ch->pcdata->room_text[0] = (NORMAL);
00795         ch->pcdata->room_text[1] = (WHITE);
00796         ch->pcdata->room_text[2] = 0;
00797         ch->pcdata->room_exits[0] = (NORMAL);
00798         ch->pcdata->room_exits[1] = (GREEN);
00799         ch->pcdata->room_exits[2] = 0;
00800         ch->pcdata->room_things[0] = (NORMAL);
00801         ch->pcdata->room_things[1] = (CYAN);
00802         ch->pcdata->room_things[2] = 0;
00803         ch->pcdata->prompt[0] = (NORMAL);
00804         ch->pcdata->prompt[1] = (CYAN);
00805         ch->pcdata->prompt[2] = 0;
00806         ch->pcdata->fight_death[0] = (BRIGHT);
00807         ch->pcdata->fight_death[1] = (RED);
00808         ch->pcdata->fight_death[2] = 0;
00809         ch->pcdata->fight_yhit[0] = (NORMAL);
00810         ch->pcdata->fight_yhit[1] = (GREEN);
00811         ch->pcdata->fight_yhit[2] = 0;
00812         ch->pcdata->fight_ohit[0] = (NORMAL);
00813         ch->pcdata->fight_ohit[1] = (YELLOW);
00814         ch->pcdata->fight_ohit[2] = 0;
00815         ch->pcdata->fight_thit[0] = (NORMAL);
00816         ch->pcdata->fight_thit[1] = (RED);
00817         ch->pcdata->fight_thit[2] = 0;
00818         ch->pcdata->fight_skill[0] = (BRIGHT);
00819         ch->pcdata->fight_skill[1] = (WHITE);
00820         ch->pcdata->fight_skill[2] = 0;
00821 
00822         found = FALSE;
00823         fclose (fpReserve);
00824 
00825 #if defined(unix)
00826         /* decompress if .gz file exists */
00827         sprintf (strsave, "%s%s%s", PLAYER_DIR, capitalize (name), ".gz");
00828         if ((fp = fopen (strsave, "r")) != NULL)
00829         {
00830         fclose (fp);
00831         sprintf (buf, "gzip -dfq %s", strsave);
00832         system (buf);
00833         }
00834 #endif
00835 
00836         sprintf (strsave, "%s%s", PLAYER_DIR, capitalize (name));
00837         if ((fp = fopen (strsave, "r")) != NULL)
00838         {
00839         int iNest;
00840 
00841         for (iNest = 0; iNest < MAX_NEST; iNest++)
00842             rgObjNest[iNest] = NULL;
00843 
00844         found = TRUE;
00845         for (;;)
00846         {
00847             char letter;
00848             char *word;
00849 
00850             letter = fread_letter (fp);
00851             if (letter == '*')
00852             {
00853             fread_to_eol (fp);
00854             continue;
00855             }
00856 
00857             if (letter != '#')
00858             {
00859             bug ("Load_char_obj: # not found.", 0);
00860             break;
00861             }
00862 
00863             word = fread_word (fp);
00864             if (!str_cmp (word, "PLAYER"))
00865             fread_char (ch, fp);
00866             else if (!str_cmp (word, "OBJECT"))
00867             fread_obj (ch, fp);
00868             else if (!str_cmp (word, "O"))
00869             fread_obj (ch, fp);
00870             else if (!str_cmp (word, "PET"))
00871             fread_pet (ch, fp);
00872             else if (!str_cmp (word, "END"))
00873             break;
00874             else
00875             {
00876             bug ("Load_char_obj: bad section.", 0);
00877             break;
00878             }
00879         }
00880         fclose (fp);
00881         }
00882 
00883         fpReserve = fopen (NULL_FILE, "r");
00884 
00885 
00886         /* initialize race */
00887         if (found)
00888         {
00889         int i;
00890 
00891         if (ch->race == 0)
00892             ch->race = race_lookup ("human");
00893 
00894         ch->size = pc_race_table[ch->race].size;
00895         ch->dam_type = 17;        /*punch */
00896 
00897         for (i = 0; i < 5; i++)
00898         {
00899             if (pc_race_table[ch->race].skills[i] == NULL)
00900             break;
00901             group_add (ch, pc_race_table[ch->race].skills[i], FALSE);
00902         }
00903         ch->affected_by = ch->affected_by | race_table[ch->race].aff;
00904         ch->imm_flags = ch->imm_flags | race_table[ch->race].imm;
00905         ch->res_flags = ch->res_flags | race_table[ch->race].res;
00906         ch->vuln_flags = ch->vuln_flags | race_table[ch->race].vuln;
00907         ch->form = race_table[ch->race].form;
00908         ch->parts = race_table[ch->race].parts;
00909         }
00910 
00911 
00912         /* RT initialize skills */
00913 
00914         if (found && ch->version < 2)
00915         {                            /* need to add the new skills */
00916         group_add (ch, "rom basics", FALSE);
00917         group_add (ch, class_table[ch->class].base_group, FALSE);
00918         group_add (ch, class_table[ch->class].default_group, TRUE);
00919         ch->pcdata->learned[gsn_recall] = 50;
00920         }
00921 
00922         /* fix levels */
00923         if (found && ch->version < 3 && (ch->level > 35 || ch->trust > 35))
00924         {
00925         switch (ch->level)
00926         {
00927             case (40):
00928             ch->level = 60;
00929             break;            /* imp -> imp */
00930             case (39):
00931             ch->level = 58;
00932             break;            /* god -> supreme */
00933             case (38):
00934             ch->level = 56;
00935             break;            /* deity -> god */
00936             case (37):
00937             ch->level = 53;
00938             break;            /* angel -> demigod */
00939         }
00940 
00941         switch (ch->trust)
00942         {
00943             case (40):
00944             ch->trust = 60;
00945             break;            /* imp -> imp */
00946             case (39):
00947             ch->trust = 58;
00948             break;            /* god -> supreme */
00949             case (38):
00950             ch->trust = 56;
00951             break;            /* deity -> god */
00952             case (37):
00953             ch->trust = 53;
00954             break;            /* angel -> demigod */
00955             case (36):
00956             ch->trust = 51;
00957             break;            /* hero -> hero */
00958         }
00959         }
00960 
00961         /* ream gold */
00962         if (found && ch->version < 4)
00963         {
00964         ch->gold /= 100;
00965         }
00966         return found;
00967     }
00968 
00969 
00970 
00971     /*
00972      * Read in a char.
00973      */
00974 
00975 #if defined(KEY)
00976 #undef KEY
00977 #endif
00978 
00979 #define KEY( literal, field, value )                    \
00980             if ( !str_cmp( word, literal ) )    \
00981             {                    \
00982                 field  = value;            \
00983                 fMatch = TRUE;            \
00984                 break;                \
00985             }
00986 
00987     /* provided to free strings */
00988 #if defined(KEYS)
00989 #undef KEYS
00990 #endif
00991 
00992 #define KEYS( literal, field, value )                    \
00993             if ( !str_cmp( word, literal ) )    \
00994             {                    \
00995                 free_string(field);            \
00996                 field  = value;            \
00997                 fMatch = TRUE;            \
00998                 break;                \
00999             }
01000 
01001 void fread_char (CHAR_DATA * ch, FILE * fp)
01002     {
01003         char buf[MAX_STRING_LENGTH];
01004         char *word;
01005         bool fMatch;
01006         int count = 0;
01007         int lastlogoff = current_time;
01008         int percent;
01009 
01010         sprintf (buf, "Loading %s.", ch->name);
01011         log_string (buf);
01012 
01013         for (;;)
01014         {
01015         word = feof (fp) ? "End" : fread_word (fp);
01016         fMatch = FALSE;
01017 
01018         switch (UPPER (word[0]))
01019         {
01020             case '*':
01021             fMatch = TRUE;
01022             fread_to_eol (fp);
01023             break;
01024 
01025             case 'A':
01026             KEY ("Act", ch->act, fread_flag (fp));
01027             KEY ("AffectedBy", ch->affected_by, fread_flag (fp));
01028             KEY ("AfBy", ch->affected_by, fread_flag (fp));
01029             KEY ("Age", ch->pcdata->plr_age, fread_number (fp));
01030             KEY ("Alignment", ch->alignment, fread_number (fp));
01031             KEY ("Alig", ch->alignment, fread_number (fp));
01032 
01033             if (!str_cmp (word, "Alia"))
01034             {
01035                 if (count >= MAX_ALIAS)
01036                 {
01037                 fread_to_eol (fp);
01038                 fMatch = TRUE;
01039                 break;
01040                 }
01041 
01042                 ch->pcdata->alias[count] = str_dup (fread_word (fp));
01043                 ch->pcdata->alias_sub[count] = str_dup (fread_word (fp));
01044                 count++;
01045                 fMatch = TRUE;
01046                 break;
01047             }
01048 
01049             if (!str_cmp (word, "Alias"))
01050             {
01051                 if (count >= MAX_ALIAS)
01052                 {
01053                 fread_to_eol (fp);
01054                 fMatch = TRUE;
01055                 break;
01056                 }
01057 
01058                 ch->pcdata->alias[count] = str_dup (fread_word (fp));
01059                 ch->pcdata->alias_sub[count] = fread_string (fp);
01060                 count++;
01061                 fMatch = TRUE;
01062                 break;
01063             }
01064 
01065             if (!str_cmp (word, "AC") || !str_cmp (word, "Armor"))
01066             {
01067                 fread_to_eol (fp);
01068                 fMatch = TRUE;
01069                 break;
01070             }
01071 
01072             if (!str_cmp (word, "ACs"))
01073             {
01074                 int i;
01075 
01076                 for (i = 0; i < 4; i++)
01077                 ch->armor[i] = fread_number (fp);
01078                 fMatch = TRUE;
01079                 break;
01080             }
01081 
01082             if (!str_cmp (word, "AffD"))
01083             {
01084                 AFFECT_DATA *paf;
01085                 int sn;
01086 
01087                 paf = new_affect ();
01088 
01089                 sn = skill_lookup (fread_word (fp));
01090                 if (sn < 0)
01091                 bug ("Fread_char: unknown skill.", 0);
01092                 else
01093                 paf->type = sn;
01094 
01095                 paf->level = fread_number (fp);
01096                 paf->duration = fread_number (fp);
01097                 paf->modifier = fread_number (fp);
01098                 paf->location = fread_number (fp);
01099                 paf->bitvector = fread_number (fp);
01100                 paf->next = ch->affected;
01101                 ch->affected = paf;
01102                 fMatch = TRUE;
01103                 break;
01104             }
01105 
01106             if (!str_cmp (word, "Affc"))
01107             {
01108                 AFFECT_DATA *paf;
01109                 int sn;
01110 
01111                 paf = new_affect ();
01112 
01113                 sn = skill_lookup (fread_word (fp));
01114                 if (sn < 0)
01115                 bug ("Fread_char: unknown skill.", 0);
01116                 else
01117                 paf->type = sn;
01118 
01119                 paf->where = fread_number (fp);
01120                 paf->level = fread_number (fp);
01121                 paf->duration = fread_number (fp);
01122                 paf->modifier = fread_number (fp);
01123                 paf->location = fread_number (fp);
01124                 paf->bitvector = fread_number (fp);
01125                 paf->next = ch->affected;
01126                 ch->affected = paf;
01127                 fMatch = TRUE;
01128                 break;
01129             }
01130 
01131             if (!str_cmp (word, "AttrMod") || !str_cmp (word, "AMod"))
01132             {
01133                 int stat;
01134                 for (stat = 0; stat < MAX_STATS; stat++)
01135                 ch->mod_stat[stat] = fread_number (fp);
01136                 fMatch = TRUE;
01137                 break;
01138             }
01139 
01140             if (!str_cmp (word, "AttrPerm") || !str_cmp (word, "Attr"))
01141             {
01142                 int stat;
01143 
01144                 for (stat = 0; stat < MAX_STATS; stat++)
01145                 ch->perm_stat[stat] = fread_number (fp);
01146                 fMatch = TRUE;
01147                 break;
01148             }
01149             break;
01150 
01151             case 'B':
01152             KEY ("Bamfin", ch->pcdata->bamfin, fread_string (fp));
01153             KEY ("Bamfout", ch->pcdata->bamfout, fread_string (fp));
01154             KEY ("Bin", ch->pcdata->bamfin, fread_string (fp));
01155             KEY ("Bout", ch->pcdata->bamfout, fread_string (fp));
01156             KEY ("Bodytype", ch->pcdata->bodytype, fread_string(fp));
01157 
01158             break;
01159 
01160             case 'C':
01161             KEY ("Class", ch->class, fread_number (fp));
01162             KEY ("Cla", ch->class, fread_number (fp));
01163             /*f (ch->class != 0)
01164             {
01165                 if (class_lookup[ch->class] == -1 || (ch->class > MAX_CLASS))
01166                     ch->class = 1;
01167             }*/
01168             KEY ("Clan", ch->clan, clan_lookup (fread_string (fp)));
01169             KEY ("Comm", ch->comm, fread_flag (fp));
01170             KEY ("Chann", ch->chann, fread_flag (fp));
01171             KEY ("CClan", ch->cclan, fread_flag (fp));
01172             if (!str_cmp (word, "Condition") || !str_cmp (word, "Cond"))
01173             {
01174                 ch->pcdata->condition[0] = fread_number (fp);
01175                 ch->pcdata->condition[1] = fread_number (fp);
01176                 ch->pcdata->condition[2] = fread_number (fp);
01177                 fMatch = TRUE;
01178                 break;
01179             }
01180             if (!str_cmp (word, "Cnd"))
01181             {
01182                 ch->pcdata->condition[0] = fread_number (fp);
01183                 ch->pcdata->condition[1] = fread_number (fp);
01184                 ch->pcdata->condition[2] = fread_number (fp);
01185                 ch->pcdata->condition[3] = fread_number (fp);
01186                 fMatch = TRUE;
01187                 break;
01188             }
01189 
01190                /*if (!str_cmp (word, "Coloura"))
01191             {
01192                 LOAD_COLOUR (text)
01193                 LOAD_COLOUR (auction)
01194                 LOAD_COLOUR (gossip)
01195                 LOAD_COLOUR (music)
01196                 LOAD_COLOUR (question) fMatch = TRUE;
01197                 break;
01198             }
01199             if (!str_cmp (word, "Colourb"))
01200             {
01201                 LOAD_COLOUR (answer)
01202                 LOAD_COLOUR (quote)
01203                 LOAD_COLOUR (quote_text)
01204                 LOAD_COLOUR (immtalk_text)
01205                 LOAD_COLOUR (immtalk_type) fMatch = TRUE;
01206                 break;
01207             }
01208             if (!str_cmp (word, "Colourc"))
01209             {
01210                 LOAD_COLOUR (info)
01211                 LOAD_COLOUR (tell)
01212                 LOAD_COLOUR (reply)
01213                 LOAD_COLOUR (gtell_text)
01214                 LOAD_COLOUR (gtell_type) fMatch = TRUE;
01215                 break;
01216             }
01217             if (!str_cmp (word, "Colourd"))
01218             {
01219                 LOAD_COLOUR (room_title)
01220                 LOAD_COLOUR (room_text)
01221                 LOAD_COLOUR (room_exits)
01222                 LOAD_COLOUR (room_things)
01223                 LOAD_COLOUR (prompt) fMatch = TRUE;
01224                 break;
01225             }
01226             if (!str_cmp (word, "Coloure"))
01227             {
01228                 LOAD_COLOUR (fight_death)
01229                 LOAD_COLOUR (fight_yhit)
01230                 LOAD_COLOUR (fight_ohit)
01231                 LOAD_COLOUR (fight_thit)
01232                 LOAD_COLOUR (fight_skill) fMatch = TRUE;
01233                 break;
01234             }
01235             if (!str_cmp (word, "Colourf"))
01236             {
01237                 LOAD_COLOUR (wiznet)
01238                 LOAD_COLOUR (say)
01239                 LOAD_COLOUR (say_text)
01240                 LOAD_COLOUR (tell_text)
01241                 LOAD_COLOUR (reply_text) fMatch = TRUE;
01242                 break;
01243             }
01244             if (!str_cmp (word, "Colourg"))
01245             {
01246                 LOAD_COLOUR (auction_text)
01247                 LOAD_COLOUR (gossip_text)
01248                             LOAD_COLOUR (music_text)
01249                 LOAD_COLOUR (question_text)
01250                 LOAD_COLOUR (answer_text) fMatch = TRUE;
01251                 break;
01252             }*/
01253 
01254             break;
01255 
01256             case 'D':
01257             KEY ("Damroll", ch->damroll, fread_number (fp));
01258             KEY ("Dam", ch->damroll, fread_number (fp));
01259             KEY ("Description", ch->description, fread_string (fp));
01260             KEY ("Desc", ch->description, fread_string (fp));
01261             break;
01262 
01263             case 'E':
01264             if (!str_cmp (word, "End"))
01265             {
01266                 /* adjust hp mana move up  -- here for speed's sake */
01267                 percent =
01268                 (current_time - lastlogoff) * 25 / (2 * 60 * 60);
01269 
01270                 percent = UMIN (percent, 100);
01271 
01272                 if (percent > 0 && !IS_AFFECTED (ch, AFF_POISON)
01273                 && !IS_AFFECTED (ch, AFF_PLAGUE))
01274                 {
01275                 ch->hit += (ch->max_hit - ch->hit) * percent / 100;
01276                 ch->mana += (ch->max_mana - ch->mana) * percent / 100;
01277                 ch->move += (ch->max_move - ch->move) * percent / 100;
01278                 }
01279                 if (ch->class > MAX_CLASS)
01280                 {
01281                     ch->class = 1;
01282                     bug ("Fread_char: Class bigger then MAX_CLASS.",0);
01283                 }
01284                 return;
01285             }
01286             KEY ("Eyecolor", ch->pcdata->eyecolor, fread_string(fp));
01287             KEY ("Exp", ch->exp, fread_number (fp));
01288             break;
01289             case 'F':
01290             KEY ("Facialhair", ch->pcdata->facialhair, fread_string(fp));
01291             break;
01292 
01293             case 'G':
01294             KEY ("Gold", ch->gold, fread_number (fp));
01295             if (!str_cmp (word, "Group") || !str_cmp (word, "Gr"))
01296             {
01297                 int gn;
01298                 char *temp;
01299 
01300                 temp = fread_word (fp);
01301                 gn = group_lookup (temp);
01302                 /* gn    = group_lookup( fread_word( fp ) ); */
01303                 if (gn < 0)
01304                 {
01305                 fprintf (stderr, "%s", temp);
01306                 bug ("Fread_char: unknown group. ", 0);
01307                 }
01308                 else
01309                 gn_add (ch, gn);
01310                 fMatch = TRUE;
01311             }
01312             break;
01313 
01314             case 'H':
01315             KEY ("Hairtype", ch->pcdata->hairtype, fread_string(fp));
01316             KEY ("Haircolor", ch->pcdata->haircolor, fread_string(fp));
01317             KEY ("Hairlength", ch->pcdata->hairlength, fread_string(fp));
01318             KEY ("Hitroll", ch->hitroll, fread_number (fp));
01319             KEY ("Hit", ch->hitroll, fread_number (fp));
01320 
01321             if (!str_cmp (word, "HpManaMove") || !str_cmp (word, "HMV"))
01322             {
01323                 ch->hit = fread_number (fp);
01324                 ch->max_hit = fread_number (fp);
01325                 ch->mana = fread_number (fp);
01326                 ch->max_mana = fread_number (fp);
01327                 ch->move = fread_number (fp);
01328                 ch->max_move = fread_number (fp);
01329                 fMatch = TRUE;
01330                 break;
01331             }
01332 
01333             if (!str_cmp (word, "HpManaMovePerm")
01334                 || !str_cmp (word, "HMVP"))
01335             {
01336                 ch->pcdata->perm_hit = fread_number (fp);
01337                 ch->pcdata->perm_mana = fread_number (fp);
01338                 ch->pcdata->perm_move = fread_number (fp);
01339                 fMatch = TRUE;
01340                 break;
01341             }
01342 
01343             break;
01344 
01345             case 'I':
01346             KEY ("Id", ch->id, fread_number (fp));
01347             KEY ("InvisLevel", ch->invis_level, fread_number (fp));
01348             KEY ("Inco", ch->incog_level, fread_number (fp));
01349             KEY ("Invi", ch->invis_level, fread_number (fp));
01350             KEY ("Immtitle", ch->pcdata->imm_title, fread_string(fp));
01351             KEY ("Immort", ch->pcdata->immortal, fread_flag(fp));
01352             break;
01353 
01354             case 'K':
01355             KEY ("King", ch->king, kingdom_lookup (fread_string (fp)));
01356             KEY ("KKing", ch->kking, fread_flag (fp));
01357             break;
01358 
01359             case 'L':
01360             KEY ("LastL