/**************************************************************************/
// save.cpp - save a character etc
/***************************************************************************
* The Dawn of Time v1.69r (c)1997-2004 Michael Garratt *
* >> A number of people have contributed to the Dawn codebase, with the *
* majority of code written by Michael Garratt - www.dawnoftime.org *
* >> To use this source code, you must fully comply with all the licenses *
* in licenses.txt... In particular, you may not remove this copyright *
* notice. *
***************************************************************************
* >> Original Diku Mud copyright (c)1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, & Katja Nyboe. *
* >> Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* >> ROM 2.4 is copyright 1993-1995 Russ Taylor and has been brought to *
* you by the ROM consortium: Russ Taylor(rtaylor@pacinfo.com), *
* Gabrielle Taylor(gtaylor@pacinfo.com) & Brian Moore(rom@rom.efn.org) *
* >> Oblivion 1.2 is copyright 1996 Wes Wagner *
**************************************************************************/
#include "include.h" // dawn standard includes
#include "areas.h"
#include "hreboot.h"
#include "cust_col.h"
#include "channels.h"
#include "pload.h"
extern OBJ_DATA *obj_free;
bool dont_nest=false;
int rename(const char *oldfname, const char *newfname);
int who_format_lookup(char *argument);
const char *who_format_name(int index);
char *fwrite_flag( long flags, char buf[] );
void fwrite_custom_colours(FILE* fp, const char *header, const char custom_colours[]);
char *fread_custom_colours(FILE* fp, bool player);
// Local functions.
void fwrite_char args( ( char_data *ch, FILE *fp ) );
void fwrite_obj args( ( OBJ_DATA *obj, FILE *fp, int iNest, char *heading) );
void fwrite_pet args( ( char_data *pet, FILE *fp) );
void fread_char args( ( char_data *ch, FILE *fp ) );
void fread_pet args( ( char_data *ch, FILE *fp ) );
obj_data * fread_obj ( FILE *fp, const char *filename );
/**************************************************************************/
// return the name including directory was
// a pfile name - lowercase and with the .plr extension
char * pfile_filename(char *name)
{
static int i;
static char rbuf[5][MSL];
char buf[MSL], first_name[MSL];
// rotate buffers
++i= i%5;
strcpy(buf, name);
// make lowercase and first word of the name
one_argument( buf, first_name);
sprintf(rbuf[i], "%s.plr", first_name);
return(rbuf[i]);
}
/**************************************************************************/
// return the name including directory was
// a pfile would be called.
char * pfilename(char *name, PFILE_TYPE pt)
{
static int i;
static char rbuf[5][MSL];
char filename[MSL];
// rotate buffers
++i= i%5;
strcpy(filename, pfile_filename(name));
switch(pt){
case PFILE_LOCKED:
sprintf(rbuf[i], PDIR_LOCKED "%s", filename);
break;
case PFILE_NORMAL:
#if defined(NO_INITIAL_ALPHA_PFILEDIRS) || defined(WIN32)
sprintf(rbuf[i], PLAYER_DIR "%s", filename);
#else
sprintf(rbuf[i], PLAYER_DIR "%c" DIR_SYM "%s", filename[0], filename);
#endif
break;
case PFILE_BUILDER:
sprintf(rbuf[i], PDIR_BUILDER"%s", filename);
break;
case PFILE_TRUSTED:
sprintf(rbuf[i], PDIR_TRUSTED"%s", filename);
break;
case PFILE_IMMORTAL:
sprintf(rbuf[i], PDIR_IMMORTAL"%s", filename);
break;
case PFILE_REMORT_BACKUP:
sprintf(rbuf[i], REMORT_DIR "%s", filename);
break;
default:
sprintf(rbuf[i], "ERROR_PFILENAME_INCORRECT_PTYPE, name = %s,pt=%d",
filename, (int)pt);
bugf("ERROR_PFILENAME_INCORRECT_PTYPE %d - name=%s", (int)pt, filename);
}
return(rbuf[i]);
}
/**************************************************************************/
PFILE_TYPE get_pfiletype(char_data *ch)
{
if(ch->level>=LEVEL_IMMORTAL){
return PFILE_IMMORTAL;
}
if(IS_TRUSTED(ch, LEVEL_IMMORTAL)){
return PFILE_TRUSTED;
}
if(HAS_SECURITY(ch,1)){
return PFILE_BUILDER;
}
if(ch->pcdata &&
!IS_NULLSTR(ch->pcdata->unlock_id)
&& str_len(ch->pcdata->unlock_id)==6){
return PFILE_LOCKED;
}
return PFILE_NORMAL;
}
/**************************************************************************/
// returns the type
PFILE_TYPE find_pfiletype(const char *name)
{
char buf[MIL],first_name[MIL];
int count=0;
PFILE_TYPE result=PFILE_NONE;
strcpy(buf, name);
// make lowercase and first word of the name
one_argument( buf, first_name);
// look in all the locations for the pfile
if(file_exists(PDIR_LOCKED "%s.plr", first_name)){
result=PFILE_LOCKED;
count++;
}
#if defined(NO_INITIAL_ALPHA_PFILEDIRS) || defined(WIN32)
if(file_exists(PLAYER_DIR "%s.plr", first_name)){
#else
if(file_exists(PLAYER_DIR "%c" DIR_SYM "%s.plr", first_name[0], first_name)){
#endif
result=PFILE_NORMAL;
count++;
}
if(file_exists(PDIR_BUILDER"%s.plr", first_name)){
result=PFILE_BUILDER;
count++;
}
if(file_exists(PDIR_TRUSTED"%s.plr", first_name)){
result=PFILE_TRUSTED;
count++;
}
if(file_exists(PDIR_IMMORTAL"%s.plr", first_name)){
result=PFILE_IMMORTAL;
count++;
}
// return the results
if (count==0){
return PFILE_NONE;
}
if (count>1){
bugf("find_pfiletype(): MULTIPLE LOCATIONS FOR %s", first_name);
return PFILE_MULTIPLE;
}
return result;
}
/**************************************************************************/
void save_char_obj_to_filename( char_data *ch, char *filename )
{
char strsave[MIL];
strcpy(strsave,filename);
FILE *fp;
if(GAMESETTING5(GAMESET5_DEDICATED_PKILL_STYLE_MUD))
{
logf( "Character %s not saved cause on dedicated pkill style mud", ch->name);
return;
}
fclose( fpReserve );
if ( ( fp = fopen( TEMP_FILE, "w" ) ) == NULL )
{
bugf("save_char_obj_to_filename(): fopen '%s' for write - error %d (%s)",
TEMP_FILE, errno, strerror( errno));
ch->println("`RNOTICE: YOUR PFILE WASN'T SAVED, AS IT WASN'T POSSIBLE "
"TO A TEMPORARY FILE FOR SAVING!`x");
}
else
{
fwrite_char( ch, fp );
if ( ch->carrying != NULL ){
fwrite_obj( ch->carrying, fp, 0, "O");
}
// save the pets
if (ch->pet && IS_NPC(ch->pet)){
fwrite_pet(ch->pet,fp);
// save what a pet is carrying
if ( ch->pet->carrying != NULL ){
fwrite_obj( ch->pet->carrying, fp, 0, "PO" ); // pet objects
}
}
int bytes_for_end_written=fprintf( fp, "#END\n" );
int fclose_result=fclose( fp );
bool save_error=false;
if(bytes_for_end_written>4 && fclose_result==0){
#ifdef WIN32
unlink(strsave);
#endif
if(rename(TEMP_FILE,strsave)!=0){
logf("Error in rename while saving %s pfile. (Attempted to rename '%s' to '%s')",
ch->name,
TEMP_FILE,
strsave);
bugf("save_char_obj_to_filename(): rename(%s, %s) - error %d (%s)",
TEMP_FILE, strsave, errno, strerror( errno));
save_error=true;
};
}else{
save_error=true;
logf("save_char_obj_to_filename(): bytes_for_end_written=%d, fclose_result=%d",
bytes_for_end_written, fclose_result);
bugf("save_char_obj( ): bytes_for_end_written<5!!!\n%s not saved!!! - probably out of diskspace!!!"
"\nRecommend clearing some diskspace!\n", ch->name);
}
if(save_error){
ch->println("`RYOUR PFILE WAS NOT SAVED CORRECTLY - POSSIBLY DUE TO LACK OF DISKSPACE REASONS\r\n"
"(The Immortals have been notified)");
ch->println("`xThis system has been implemented so your pfile wont be corrupted... your pfile will remain as it was when you logged in earlier.");
{
connection_data *d;
for ( d = connection_list; d != NULL; d = d->next )
{
if ( d->connected_state == CON_PLAYING &&
IS_IMMORTAL(d->character))
{
CH(d)->print("\7\7\7");
CH(d)->println("You are being paged by dawn it self!!!");
CH(d)->print("\a");
CH(d)->printlnf("`R'%s's pfile was not saved to '%s' for some reason!!!"
"possibly cause is lack of diskspace or rename problems - check game logs!`x\r\n", ch->name, strsave);
CH(d)->print("\a");
CH(d)->printlnf("`R'%s's pfile was not saved to '%s' for some reason!!!"
"possibly cause is lack of diskspace or rename problems - check game logs!`x\r\n", ch->name, strsave);
CH(d)->print("\a");
CH(d)->printlnf("`R'%s's pfile was not saved to '%s' for some reason!!!"
"possibly cause is lack of diskspace or rename problems - check game logs!`x\r\n", ch->name, strsave);
CH(d)->print("\a");
CH(d)->println(get_piperesult("df"));
CH(d)->println("Clear some diskspace!!!");
}
}
}
}
}
fpReserve = fopen( NULL_FILE, "r" );
}
/**************************************************************************/
// Save a character and inventory.
// Would be cool to save NPC's too for quest purposes,
// some of the infrastructure is provided.
void save_char_obj( char_data *ch )
{
if ( IS_NPC(ch) )
return;
if(ch->pload && ch->pload->dont_save){
if(ch->pload->loaded_by){
ch->pload->loaded_by->printlnf( "Character %s not autosaved cause it was ploaded.", ch->name);
}
logf( "Character %s not saved cause it was ploaded.", ch->name);
return;
}
if(GAMESETTING5(GAMESET5_DEDICATED_PKILL_STYLE_MUD)){
logf( "Character %s not saved cause on dedicated pkill style mud", ch->name);
return;
}
if ( ch->desc != NULL && ch->desc->original != NULL ){
ch = ch->desc->original;
}
PFILE_TYPE pt=get_pfiletype(ch);
ch->pcdata->pfiletype=pt;
save_char_obj_to_filename(ch, pfilename(ch->name, pt));
return;
}
/**************************************************************************/
// Write the char.
void fwrite_char( char_data *ch, FILE *fp )
{
int sn, gn, pos;
// update the version info
ch->version=9;
ch->subversion =2;
fprintf( fp, "#%s\n", IS_NPC(ch) ? "MOB" : "PLAYER" );
fprintf( fp, "Vers %d\n", ch->version);
fprintf( fp, "SubV %d\n", ch->subversion);
fprintf( fp, "Name %s~\n", fix_string(ch->name));
fprintf( fp, "Level %d\n", ch->level);
fprintf( fp, "Trust %d\n", ch->trust);
{ // ID - created time
char time_buf[50];
sprintf( time_buf,"%s", (char *) ctime((time_t*)&ch->id));
time_buf[str_len(time_buf)-1]='\0';
fprintf( fp, "Id %ld (%s)\n", ch->id, time_buf);
}
{ // Logout time, if the character was ploaded use the loaded time
time_t t;
if(ch->pload){
assertp(ch->pcdata);
t=ch->pcdata->last_logout_time;
}else{
t=current_time;
}
char time_buf[50];
sprintf( time_buf,"%s", (char *) ctime( &t));
time_buf[str_len(time_buf)-1]='\0';
fprintf( fp, "LogO %ld (%s)\n", (long) t, time_buf);
}
if (!IS_NPC(ch))
{
// Logout site
if (ch->desc){
fprintf( fp, "LogOS %s~\n", fix_string(ch->desc->remote_hostname));
}else{
fprintf( fp, "LogOS %s~\n", fix_string(ch->pcdata->last_logout_site));
}
// colour codes used within the pfile
if(ch->pcdata->colour_code){
fprintf( fp, "CC %c\n", ch->pcdata->colour_code);
}
if(ch->colour_prefix && ch->colour_prefix!=COLOURCODE){
fprintf( fp, "CPref %c\n", ch->colour_prefix);
}
}
{ // Time played
int played=ch->played;
if(!ch->pload){ // only add the additional time if they were not ploaded
played+=(int)(current_time - ch->logon);
}
fprintf( fp, "Plyd %-9d (%s)\n", played, short_timediff(0, played));
}
if (!IS_NPC(ch)){
fprintf( fp, "Pass %s~\n", fix_string(ch->pcdata->pwd));
fprintf( fp, "Remrt %d\n", ch->remort);
if(ch->beginning_remort){
fprintf( fp, "beginning_remort %d\n", ch->beginning_remort);
}
}
if(!IS_NULLSTR(ch->pcdata->email)){
fprintf( fp, "Email %s~\n", fix_string(ch->pcdata->email));
}
if(!IS_NULLSTR(ch->pcdata->created_from)){
fprintf( fp, "Created_from %s~\n", fix_string(ch->pcdata->created_from));
}
if(!IS_NULLSTR(ch->pcdata->unlock_id)){
fprintf( fp, "Unlock_id %s~\n", fix_string(ch->pcdata->unlock_id));
}
if(!IS_NPC(ch) && ch->know_index){
fprintf( fp, "Know_index %d\n", ch->know_index);
}
if(!IS_NPC(ch) && !IS_NULLSTR(ch->pcdata->webpass)){
fprintf( fp, "WebPass %s~\n", fix_string(ch->pcdata->webpass));
}
if(!IS_NPC(ch) && ch->pcdata->birthdate){
fprintf( fp, "Bdate %d\n", (int) ch->pcdata->birthdate);
}
if(!IS_NPC(ch) && ch->pcdata->birthyear_modifier){
fprintf( fp, "BYearMod %d\n", (int) ch->pcdata->birthyear_modifier);
}
if (!IS_NULLSTR(ch->short_descr)){
fprintf( fp, "ShD %s~\n", fix_string(ch->short_descr) );
}
if( !IS_NULLSTR(ch->long_descr)){
fprintf( fp, "LnD %s~\n", fix_string(ch->long_descr) );
}
if (!IS_NULLSTR(ch->description)){
fprintf( fp, "Desc %s~\n", fix_string(ch->description));
}
if(ch->pcdata && !IS_NULLSTR(ch->pcdata->history)){
fprintf( fp, "History %s~\n", fix_string(ch->pcdata->history));
}
if (!IS_NULLSTR(ch->gprompt)){
fprintf( fp, "GPro %s~\n", fix_string(ch->gprompt));
}
if (!IS_NULLSTR(ch->prompt) && str_cmp(ch->prompt, game_settings->default_prompt)){
fprintf( fp, "Prom %s~\n", fix_string(ch->prompt));
}
if (!IS_NULLSTR(ch->olcprompt)){
fprintf( fp, "OPrmt %s~\n", fix_string(ch->olcprompt));
}
if (!IS_NPC(ch) && !IS_NULLSTR(ch->pcdata->battlelag)){
fprintf( fp, "BattleLag %s~\n", fix_string(ch->pcdata->battlelag));
}
fprintf( fp, "Cla %s~\n", class_table[ch->clss].name);
fprintf( fp, "Race %s~\n", race_table[ch->race]->name );
// language
fprintf( fp, "Lang %s~\n", ch->language->name);
if (!IS_NPC(ch))
{
if(!IS_NULLSTR(ch->pcdata->immtalk_name)){
fprintf( fp, "ITN %s~\n", fix_string(ch->pcdata->immtalk_name));
}
fprintf( fp, "SLvl %d\n", ch->pcdata->sublevel);
fprintf( fp, "SubP %d\n", ch->pcdata->sublevel_pracs);
fprintf( fp, "SubT %d\n", ch->pcdata->sublevel_trains);
// reduced XP and RPS systems
fprintf( fp, "RXP %d\n", ch->pcdata->reduce_xp_percent);
fprintf( fp, "RRPS %d\n", ch->pcdata->reduce_rps_percent);
fprintf( fp, "Sec %d\n", ch->pcdata->security );
fprintf( fp, "Not %ld %ld %ld %ld %ld\n",
(long) ch->pcdata->last_note, (long) ch->pcdata->last_idea,
(long) ch->pcdata->last_penalty, (long) ch->pcdata->last_news,
(long) ch->pcdata->last_changes );
fprintf( fp, "ANote %ld\n", (long) ch->pcdata->last_anote);
fprintf( fp, "INote %ld\n", (long) ch->pcdata->last_inote);
fprintf( fp, "MiscN %ld\n", (long) ch->pcdata->last_misc);
fprintf( fp, "SNote %ld\n", (long) ch->pcdata->last_snote);
fprintf( fp, "PKNote %ld\n",(long) ch->pcdata->last_pknote);
if(IS_THIEF(ch) && GAMESETTING3(GAMESET3_THIEF_SYSTEM_ENABLED)){
fprintf( fp, "Thief_until %ld\n",(long) ch->pcdata->thief_until);
}
if(IS_KILLER(ch) && GAMESETTING3(GAMESET3_KILLER_SYSTEM_ENABLED)){
fprintf( fp, "Killer_until %ld\n",(long) ch->pcdata->killer_until);
}
// save their note posting times if necessary
if(!IS_TRUSTED(ch, NOTE_POST_RESTRICTIONS_BELOW_LEVEL)){
for(int i=0; i<MAX_NOTE_POST_TIME_INDEX; i++){
if(ch->pcdata->note_post_time[i]>0){
fprintf( fp, "NotePost %ld\n", (long)ch->pcdata->note_post_time[i]);
}
}
}
if(ch->pcdata->preference_msp!=PREF_AUTOSENSE){
fwrite_wordflag( preference_types, ch->pcdata->preference_msp, "PrefMSP ", fp);
}
if(ch->pcdata->preference_mxp!=PREF_AUTOSENSE){
fwrite_wordflag( preference_types, ch->pcdata->preference_mxp, "PrefMXP ", fp);
}
if(ch->pcdata->preference_dawnftp!=PREF_AUTOSENSE){
fwrite_wordflag( preference_types, ch->pcdata->preference_dawnftp, "PrefDAWNFTP ", fp);
}
if(ch->pcdata->preference_colour_in_socials!=PREF_AUTOSENSE){
fwrite_wordflag( preference_types, ch->pcdata->preference_colour_in_socials, "PrefColourInSocials ", fp);
}
}
if(ch->pcdata->charnotes){
fprintf( fp, "Cnotes %s~\n", fix_string(ch->pcdata->charnotes));
}
// clan stuff
if (ch->clan)
{
fprintf( fp, "Clan %s~\n",ch->clan->savename());
fprintf( fp, "Rank %s~\n",ch->clan->clan_rank_title(ch->clanrank));
}
// PKILLS info
if (ch->pkool)
fprintf( fp, "PKool %d\n", ch->pkool );
if (ch->pksafe)
fprintf( fp, "PKsaf %d\n", ch->pksafe );
if (ch->pkkills)
fprintf( fp, "PKill %d\n", ch->pkkills );
if (ch->pkdefeats)
fprintf( fp, "PKDef %d\n", ch->pkdefeats );
// MKILLS info and unsafe due to stealing stuff
if(!IS_NPC(ch))
{
if (ch->pcdata->mkills)
fprintf( fp, "MKil %d\n", ch->pcdata->mkills);
if (ch->pcdata->mdefeats)
fprintf( fp, "MDef %d\n", ch->pcdata->mdefeats);
if (ch->pcdata->unsafe_due_to_stealing_till)
fprintf( fp, "Unsafe_4stealing %d\n", (int)ch->pcdata->unsafe_due_to_stealing_till);
}
if(!IS_NPC(ch))
{
fprintf( fp, "Rps %ld\n", ch->pcdata->rp_points);
if(ch->pcdata->xp_penalty)
fprintf( fp, "Xpen %d\n", ch->pcdata->xp_penalty );
// noble stuff
if(ch->pcdata->diplomacy)
{
fprintf(fp, "Diplo %d\n", ch->pcdata->diplomacy );
if(ch->pcdata->dip_points){
fprintf(fp, "Dptn %d\n", ch->pcdata->dip_points);
}
if(ch->pcdata->autovote){
fprintf(fp, "AVote %d\n", ch->pcdata->autovote);
}
}
// auto afk after
if(ch->pcdata->autoafkafter){
fprintf(fp, "AAA %d\n", ch->pcdata->autoafkafter);
}
if(ch->pcdata->rp_count)
fprintf(fp, "Rpcnt %d\n", ch->pcdata->rp_count);
if(ch->pcdata->merit)
fprintf(fp, "Merit %d\n", ch->pcdata->merit);
// Questpoints system
if(ch->pcdata->qpoints){
fprintf( fp, "Quest %d\n", ch->pcdata->qpoints );
}
// karn system
fprintf( fp, "Karns %d\n", ch->pcdata->karns);
fprintf( fp, "KCntd %d\n", ch->pcdata->next_karn_countdown);
fprintf( fp, "HeroXp %d\n", ch->pcdata->heroxp );
if(ch->pcdata->hero_level_count){
fprintf( fp, "HeroLevelCount %d\n", ch->pcdata->hero_level_count );
}
// reroll counter
fprintf( fp, "RCnt %d\n", ch->pcdata->reroll_counter);
}
fprintf( fp, "RecallRoom %d\n", ch->recall_room );
// Inn recall variables.
fprintf( fp, "RecallInnRoom %d\n", ch->recall_inn_room );
fprintf( fp, "ExpireRecallInn %d\n", ch->expire_recall_inn );
if(ch->bleeding)
fprintf( fp, "Bleed %d\n", ch->bleeding);
if(ch->will_die)
fprintf( fp, "Wdie %d\n", ch->will_die);
if(ch->is_stunned)
fprintf( fp, "Stun %d\n", ch->is_stunned);
// fix up sex before writing it - rare to stomp over something
// generally only if someone has 2 change sex'es on them
if(ch->sex<SEX_NEUTRAL || ch->sex>SEX_FEMALE){
if (IS_NPC(ch)){
ch->sex=SEX_NEUTRAL;
}else{
ch->sex=ch->pcdata->true_sex;
}
};
fprintf( fp, "Sex %s~\n", sex_table[ch->sex].name);
if (!IS_NPC(ch)){
fprintf( fp, "TSex %s~\n", sex_table[ch->pcdata->true_sex].name);
if(ch->host_validated){
fprintf( fp, "HostV %s~\n", fix_string(ch->desc->remote_hostname));
}
}
fprintf( fp, "Pos %s~\n",
ch->position == POS_FIGHTING ? position_table[POS_STANDING ].name:
position_table[ch->position].name);
fprintf( fp, "Scro %d\n",ch->lines);
fprintf( fp, "Room %d\n",
(ch->in_room == get_room_index( ROOM_VNUM_LIMBO )
&& ch->was_in_room != NULL )
? ch->was_in_room->vnum
: ch->in_room == NULL ? ROOM_VNUM_LIMBO: ch->in_room->vnum );
fprintf( fp, "LIcRm %d\n", ch->last_ic_room?
ch->last_ic_room->vnum:0);
if(ch->saycolour!='x'){
fprintf( fp, "Saycol %c\n", ch->saycolour);
}
if ( !IS_NPC( ch )){
if ( !IS_NULLSTR( ch->pcdata->surname )){
fprintf( fp, "Surname %s~\n", fix_string(ch->pcdata->surname) );
}
if ( !IS_NULLSTR( ch->pcdata->crest )){
fprintf( fp, "Crest %s~\n", fix_string(ch->pcdata->crest) );
}
if ( !IS_NULLSTR( ch->pcdata->birthplace )){
fprintf( fp, "Birthplace %s~\n", fix_string(ch->pcdata->birthplace) );
}
}
fprintf( fp, "HMV %d %d %d %d %d %d\n",
ch->hit, ch->max_hit, ch->mana,
ch->max_mana, ch->move, ch->max_move );
if (!IS_NPC(ch)){
fprintf( fp, "HMVP %d %d %d\n", ch->pcdata->perm_hit,
ch->pcdata->perm_mana,
ch->pcdata->perm_move);
fprintf( fp, "Cnd %d %d %d %d\n",
ch->pcdata->condition[0],
ch->pcdata->condition[1],
ch->pcdata->condition[2],
ch->pcdata->condition[3] );
}
// money
fprintf( fp, "Gold %ld\n",ch->gold);
fprintf( fp, "Silv %ld\n",ch->silver);
if(ch->bank){
fprintf( fp, "Bank %ld\n", ch->bank);
}
fprintf( fp, "Exp %d\n",ch->exp);
if ( IS_NPC(ch) )
{
fprintf( fp, "Vnum %d\n", ch->pIndexData->vnum);
}
else
{
if (!IS_NULLSTR(ch->pcdata->bamfin)){
fprintf( fp, "Bin %s~\n", fix_string(ch->pcdata->bamfin));
}
if (!IS_NULLSTR(ch->pcdata->bamfout)){
fprintf( fp, "Bout %s~\n", fix_string(ch->pcdata->bamfout));
}
if (!IS_NULLSTR(ch->pcdata->fadein)){
fprintf( fp, "FadeIN %s~\n", fix_string(ch->pcdata->fadein));
}
if (!IS_NULLSTR(ch->pcdata->fadeout)){
fprintf( fp, "FadeOUT %s~\n", fix_string(ch->pcdata->fadeout));
}
fprintf( fp, "Pnts %d\n", ch->pcdata->points );
fprintf( fp, "LLev %d\n", ch->pcdata->last_level );
}
if (ch->invis_level)
fprintf( fp, "Invi %d\n", ch->invis_level );
if (ch->iwizi)
fprintf( fp, "IWizi %d\n", ch->iwizi);
if (ch->olcwizi)
fprintf( fp, "OlcWizi %d\n", ch->olcwizi );
if (ch->owizi)
fprintf( fp, "OWizi %d\n", ch->owizi );
if(ch->temple)
fprintf(fp,"Temple %d\n", ch->temple);
if (ch->incog_level)
fprintf(fp,"Inco %d\n",ch->incog_level);
if (ch->practice)
fprintf( fp, "Prac %d\n", ch->practice);
if (ch->train)
fprintf( fp, "Trai %d\n", ch->train);
fprintf( fp, "Tired %d\n", ch->pcdata->tired );
fprintf( fp, "Tryin %d\n", ch->is_trying_sleep );
if(ch->saving_throw){
fprintf( fp, "Save %d\n", ch->saving_throw);
}
fprintf( fp, "Alig %d %d\n", ch->tendency, ch->alliance);
if (ch->hitroll)
fprintf( fp, "Hit %d\n", ch->hitroll);
if (ch->damroll)
fprintf( fp, "Dam %d\n", ch->damroll);
fprintf( fp, "ACs %3d %3d %3d %3d\n",
ch->armor[0],ch->armor[1],ch->armor[2],ch->armor[3]);
if (ch->wimpy)
fprintf( fp, "Wimp %d\n", ch->wimpy);
if(!IS_NPC(ch) && ch->pcdata->panic){
fprintf( fp, "Panic %d\n", ch->pcdata->panic);
}
if ( !IS_NPC( ch ))
{
if ( !IS_NULLSTR( ch->pcdata->haircolour )){
fprintf( fp, "HairCol %s~\n", fix_string(ch->pcdata->haircolour) );
}
if ( !IS_NULLSTR( ch->pcdata->eyecolour )){
fprintf( fp, "EyeCol %s~\n", fix_string(ch->pcdata->eyecolour) );
}
fprintf( fp, "Height %d\n", ch->pcdata->height );
fprintf( fp, "Weight %d\n", ch->pcdata->weight );
long nVanish = UMAX(0,(int)(current_time - ch->pcdata->next_vanish));
fprintf ( fp, "NVanish %ld\n", nVanish);
long nWorshipTime = UMIN(1000000,(int)(current_time-ch->pcdata->worship_time));
fprintf ( fp, "NWorshipTime %ld\n", nWorshipTime);
// Addition for Deity
if(ch->deity)
{
fprintf ( fp, "DeityName %s~\n", fix_string(ch->deity->name) );
}
}
// stats
fprintf( fp, "Attr %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d\n",
ch->perm_stats[STAT_ST],
ch->perm_stats[STAT_QU],
ch->perm_stats[STAT_PR],
ch->perm_stats[STAT_EM],
ch->perm_stats[STAT_IN],
ch->perm_stats[STAT_CO],
ch->perm_stats[STAT_AG],
ch->perm_stats[STAT_SD],
ch->perm_stats[STAT_ME],
ch->perm_stats[STAT_RE]);
fprintf (fp, "AMod %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d\n",
ch->modifiers[STAT_ST],
ch->modifiers[STAT_QU],
ch->modifiers[STAT_PR],
ch->modifiers[STAT_EM],
ch->modifiers[STAT_IN],
ch->modifiers[STAT_CO],
ch->modifiers[STAT_AG],
ch->modifiers[STAT_SD],
ch->modifiers[STAT_ME],
ch->modifiers[STAT_RE]);
fprintf (fp, "APot %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d\n",
ch->potential_stats[STAT_ST],
ch->potential_stats[STAT_QU],
ch->potential_stats[STAT_PR],
ch->potential_stats[STAT_EM],
ch->potential_stats[STAT_IN],
ch->potential_stats[STAT_CO],
ch->potential_stats[STAT_AG],
ch->potential_stats[STAT_SD],
ch->potential_stats[STAT_ME],
ch->potential_stats[STAT_RE]);
if (ch->act)
{
if (IS_NPC(ch)){ // this will need changing if mobs are ever saved
fwrite_wordflag( act_flags, ch->act, "MAct", fp);
}else{
fwrite_wordflag( plr_flags, ch->act, "Act",fp);
}
}
// ???? Just in case???
if (ch->act2)
{
if (IS_NPC(ch)){ // this will need changing if mobs are ever saved
fwrite_wordflag( act2_flags, ch->act2, "MAct2", fp);
}else{
fwrite_wordflag( act2_flags, ch->act2, "Act2",fp);
}
}
if (ch->affected_by){
fwrite_wordflag( affect_flags, ch->affected_by, "AfBy", fp);
}
if (ch->affected_by2){
fwrite_wordflag( affect2_flags, ch->affected_by2, "AfBy2", fp);
}
fwrite_wordflag( comm_flags, ch->comm, "Comm", fp);
if (ch->wiznet[0]){
fwrite_wordflag( wiznet_flags, ch->wiznet[0], "Immwiznet", fp);
}
if (ch->wiznet[1]){
fwrite_wordflag( wiznet_flags, ch->wiznet[1], "Wiznet", fp);
}
if (ch->wiznet[2]){
fwrite_wordflag( wiznet_flags, ch->wiznet[2], "Wiznet2", fp);
}
if (ch->wiznet[3]){
fwrite_wordflag( wiznet_flags, ch->wiznet[3], "Wiznet3", fp);
}
for(int tempi=0; tempi<4; tempi++){
if(!IS_NULLSTR(ch->wiznet_colour[tempi])){
fprintf( fp, "Wiznet%dc %s~\n", tempi, fix_string(ch->wiznet_colour[tempi]));
}
}
if (ch->config){
fwrite_wordflag( config_flags, ch->config, "Config", fp);
}
if (ch->config2){
fwrite_wordflag( config2_flags, ch->config2, "Config2", fp);
}
if (ch->pcdata->pconfig){
fwrite_wordflag( pconfig_flags, ch->pcdata->pconfig, "PConfig", fp);
}
if (ch->notenet){
fwrite_wordflag( notenet_flags, ch->notenet, "NoteNet", fp);
}
// save the players custom colours and scheme
if(ch->pcdata){
if(ch->pcdata->custom_colour_scheme){
fprintf(fp, "Colour_scheme %s~\n", fix_string(ch->pcdata->custom_colour_scheme->template_name));
}
if(ch->pcdata->custom_colour){
fwrite_custom_colours(fp, "Custom_colours", ch->pcdata->custom_colour);
}
if(ch->pcdata->flashing_disabled){
fprintf(fp, "flashing_disabled 1~\n");
}
fwrite_wordflag( colourmode_types, ch->pcdata->colourmode,
"Colourmode",fp);
if(ch->pcdata->strip_colour_on_channel){
fprintf(fp, "Strip_channel_colours %s~\n",
channel_convert_bitflags_to_text(ch->pcdata->strip_colour_on_channel));
}
if(ch->pcdata->channeloff){
fprintf(fp, "channeloff %s~\n",
channel_convert_bitflags_to_text(ch->pcdata->channeloff));
}
}
if (!IS_NPC(ch))
{
// write duel stats
fprintf( fp, "Duel_challenged %d\n", ch->duel_challenged);
fprintf( fp, "Duel_decline %d\n", ch->duel_decline);
fprintf( fp, "Duel_accept %d\n", ch->duel_accept);
fprintf( fp, "Duel_ignore %d\n", ch->duel_ignore);
fprintf( fp, "Duel_bypass %d\n", ch->duel_bypass);
fprintf( fp, "Duel_subdues_before_karn_loss %d\n", ch->duel_subdues_before_karn_loss);
// write aliases
for (pos = 0; pos < MAX_ALIAS; pos++)
{
if (IS_NULLSTR(ch->pcdata->alias[pos])
|| IS_NULLSTR(ch->pcdata->alias_sub[pos]))
break;
fprintf(fp,"Alias %s %s~\n", fix_string(ch->pcdata->alias[pos]),
fix_string(ch->pcdata->alias_sub[pos]));
}
// write traits - of someone has them
for (pos=0; pos < 9; pos++ )
{
if (ch->pcdata->trait[pos]){
if(str_cmp(ch->pcdata->trait[pos]," ")){
fprintf( fp, "Trait %d '%s'\n",
pos, fix_string(ch->pcdata->trait[pos]));
}
}
}
// write skills
for ( sn = 0; sn < MAX_SKILL; sn++ )
{
// skill values
if ( skill_table[sn].name != NULL && ch->pcdata->learned[sn] > 0 )
{
fprintf( fp, "Sk %d '%s'\n",
ch->pcdata->learned[sn], skill_table[sn].name );
}
// skill last used
if ( skill_table[sn].name != NULL && ch->pcdata->last_used[sn] > 800000000 )
{
fprintf( fp, "SkLU %d '%s'\n",
(int)ch->pcdata->last_used[sn], skill_table[sn].name );
}
}
// write groups
for ( gn = 0; !IS_NULLSTR(skillgroup_table[gn].name); gn++ )
{
if ( ch->pcdata->skillgroup_known[gn])
{
fprintf( fp, "Gr '%s'\n",skillgroup_table[gn].name);
}
}
if(!IS_NULLSTR(ch->pcdata->imm_role)){
fprintf( fp, "ImmRole %s~\n", fix_string(ch->pcdata->imm_role));
}
// write who related stuff
if(!IS_NULLSTR(ch->pcdata->immtitle)){
fprintf( fp, "ImmTitle %s~\n", fix_string(ch->pcdata->immtitle));
}
if(!IS_NULLSTR(ch->pcdata->title)){
fprintf( fp, "Title %s~\n", fix_string(ch->pcdata->title));
}
if(ch->pcdata->who_format){
fprintf( fp, "WhoFormat %s~\n", who_format_name(ch->pcdata->who_format));
}
}
// affects
fwrite_affect_recursive(ch->affected, fp);
fprintf( fp, "End\n\n" );
return;
}
/**************************************************************************/
// write a pet
void fwrite_pet( char_data *pet, FILE *fp)
{
AFFECT_DATA *paf;
fprintf(fp,"#PET\n");
fprintf(fp,"Vnum %d\n",pet->pIndexData->vnum);
fprintf(fp,"Name %s~\n", pet->name);
fprintf(fp,"LogO %ld\n", (long) current_time);
if (pet->short_descr != pet->pIndexData->short_descr)
fprintf(fp,"ShD %s~\n", fix_string(pet->short_descr));
if (pet->long_descr != pet->pIndexData->long_descr)
fprintf(fp,"LnD %s~\n", fix_string(pet->long_descr));
if (pet->description != pet->pIndexData->description)
fprintf(fp,"Desc %s~\n", fix_string(pet->description));
if (pet->race != pet->pIndexData->race)
fprintf(fp,"Race %s~\n", race_table[pet->race]->name);
if (pet->clan){
fprintf( fp, "Clan %s~\n",pet->clan->savename());
}
fprintf(fp,"Sex %d\n", pet->sex);
if (pet->level != pet->pIndexData->level)
fprintf(fp,"Levl %d\n", pet->level);
fprintf(fp, "HMV %d %d %d %d %d %d\n",
pet->hit, pet->max_hit, pet->mana, pet->max_mana, pet->move, pet->max_move);
if (pet->gold > 0)
fprintf(fp,"Gold %ld\n",pet->gold);
if (pet->silver > 0)
fprintf(fp,"Silv %ld\n",pet->silver);
fprintf( fp, "Room %d\n",
( pet->in_room == get_room_index( ROOM_VNUM_LIMBO )
&& pet->was_in_room != NULL )
? pet->was_in_room->vnum
: pet->in_room == NULL ? ROOM_VNUM_LIMBO : pet->in_room->vnum );
if (pet->exp > 0)
fprintf(fp, "Exp %d\n", pet->exp);
if (pet->act != pet->pIndexData->act){
fwrite_wordflag( act_flags, pet->act, "MAct ", fp);
}
if (pet->affected_by != pet->pIndexData->affected_by){
fwrite_wordflag( affect_flags, pet->affected_by, "AffBy ", fp);
}
if (pet->affected_by2 != pet->pIndexData->affected_by2){
fwrite_wordflag( affect2_flags, pet->affected_by2, "AffBy2 ", fp);
}
if (pet->comm != 0){
fwrite_wordflag( comm_flags, pet->comm, "Com ", fp);
}
fprintf(fp,"Pos %d\n", pet->position = POS_FIGHTING ? POS_STANDING : pet->position);
if (pet->saving_throw != 0)
fprintf(fp, "Save %d\n", pet->saving_throw);
if (pet->alliance != pet->pIndexData->alliance ||
pet->tendency != pet->pIndexData->tendency)
fprintf(fp, "Algn %d %d\n", pet->tendency, pet->alliance);
if (pet->hitroll != pet->pIndexData->hitroll)
fprintf(fp, "Hit %d\n", pet->hitroll);
if (pet->damroll != pet->pIndexData->damage[DICE_BONUS])
fprintf(fp, "Dam %d\n", pet->damroll);
fprintf(fp, "ACs %d %d %d %d\n",
pet->armor[0],pet->armor[1],pet->armor[2],pet->armor[3]);
fprintf(fp, "Attr %d %d %d %d %d %d %d %d %d %d\n",
pet->perm_stats[STAT_ST], pet->perm_stats[STAT_QU],
pet->perm_stats[STAT_PR], pet->perm_stats[STAT_EM],
pet->perm_stats[STAT_IN],pet->perm_stats[STAT_CO],
pet->perm_stats[STAT_AG],
pet->perm_stats[STAT_SD], pet->perm_stats[STAT_ME],
pet->perm_stats[STAT_RE]);
fprintf(fp, "AMod %d %d %d %d %d %d %d %d %d %d\n",
pet->modifiers[STAT_ST], pet->modifiers[STAT_QU],
pet->modifiers[STAT_PR], pet->modifiers[STAT_EM],
pet->modifiers[STAT_IN],
pet->modifiers[STAT_CO], pet->modifiers[STAT_AG],
pet->modifiers[STAT_SD], pet->modifiers[STAT_ME],
pet->modifiers[STAT_RE] );
for ( paf = pet->affected; paf != NULL; paf = paf->next )
{
if (paf->type < 0 || paf->type >= MAX_SKILL)
continue;
fprintf(fp, "Affc '%s' %3d %3d %3d %3d %3d %10d\n",
skill_table[paf->type].name,
paf->where, paf->level, paf->duration, paf->modifier,paf->location,
paf->bitvector);
}
fprintf(fp,"End\n");
return;
}
/**************************************************************************/
// Write an object and its contents
void fwrite_obj( obj_data *obj, FILE *fp, int iNest, char *heading )
{
EXTRA_DESCR_DATA *ed;
// Slick recursion to write lists backwards,
// so loading them will load in forwards order.
if ( obj->next_content ){
fwrite_obj( obj->next_content, fp, iNest, heading );
}
fprintf( fp, "#%s\n", heading );
fprintf( fp, "Vnum %d\n", obj->pIndexData->vnum );
// only save obj->no_affects when the flag wont be ignored
if (!obj->affected && obj->no_affects)
fprintf( fp,"no_affects\n" );
if (obj->chaos)
fprintf( fp, "Chaos\n" );
if (obj->restrung) // more grepable file format
fprintf( fp, "RESTRUNG %d\n", obj->pIndexData->vnum );
fprintf( fp, "Nest %d\n", iNest );
// these data are only used if they do not match the defaults
if ( obj->name != obj->pIndexData->name)
fprintf( fp, "Name %s~\n", fix_string(obj->name));
if ( obj->short_descr != obj->pIndexData->short_descr)
fprintf( fp, "ShD %s~\n", fix_string(obj->short_descr));
if ( obj->description != obj->pIndexData->description)
fprintf( fp, "Desc %s~\n", fix_string(obj->description));
if ( obj->extra_flags != obj->pIndexData->extra_flags)
fprintf( fp, "ExtF %d\n", obj->extra_flags );
if ( obj->extra2_flags != obj->pIndexData->extra2_flags)
fprintf( fp, "ExtF2 %d\n", obj->extra2_flags );
if ( obj->wear_flags != obj->pIndexData->wear_flags)
fprintf( fp, "WeaF %d\n", obj->wear_flags );
if ( obj->item_type != obj->pIndexData->item_type)
fprintf( fp, "Ityp %d\n", obj->item_type );
if ( obj->weight != obj->pIndexData->weight)
fprintf( fp, "Wt %d\n", obj->weight );
if ( obj->condition != obj->pIndexData->condition)
fprintf( fp, "Cond %d\n", obj->condition );
// variable data
fwrite_wordflag(wear_location_types, obj->wear_loc, "WearLoc ", fp);
if (obj->level != obj->pIndexData->level)
fprintf( fp, "Lev %d\n", obj->level );
if (obj->timer != 0)
fprintf( fp, "Time %d\n", obj->timer );
fprintf( fp, "Cost %d\n", obj->cost );
if (obj->value[0] != obj->pIndexData->value[0]
|| obj->value[1] != obj->pIndexData->value[1]
|| obj->value[2] != obj->pIndexData->value[2]
|| obj->value[3] != obj->pIndexData->value[3]
|| obj->value[4] != obj->pIndexData->value[4])
fprintf( fp, "Val %d %d %d %d %d\n",
obj->value[0], obj->value[1], obj->value[2], obj->value[3],
obj->value[4] );
switch ( obj->item_type )
{
case ITEM_COMPONENT:
if ( obj->value[1] > 0 )
{
fprintf( fp, "Spell 1 '%s'\n", skill_table[obj->value[1]].name );
}
break;
case ITEM_POTION:
case ITEM_SCROLL:
case ITEM_PILL:
if ( obj->value[1] >= 0 )
{
fprintf( fp, "Spell 1 '%s'\n",
skill_table[obj->value[1]].name );
}
if ( obj->value[2] >= 0 )
{
fprintf( fp, "Spell 2 '%s'\n",
skill_table[obj->value[2]].name );
}
if ( obj->value[3] >= 0 )
{
fprintf( fp, "Spell 3 '%s'\n",
skill_table[obj->value[3]].name );
}
if ( obj->value[4] >= 0 )
{
fprintf( fp, "Spell 4 '%s'\n",
skill_table[obj->value[4]].name );
}
break;
case ITEM_STAFF:
case ITEM_WAND:
if ( obj->value[3] >= 0 )
{
fprintf( fp, "Spell 3 '%s'\n",
skill_table[obj->value[3]].name );
}
break;
case ITEM_PARCHMENT:
fprintf( fp, "ParchmentLanguage '%s'\n",
language_safe_lookup_by_id(obj->value[3])->name );
break;
}
fwrite_affect_recursive(obj->affected, fp);
// attune stuff
if (( IS_SET( obj->attune_flags, ATTUNE_NEED_TO_USE )) &&
( obj->attune_id != 0
|| obj->attune_modifier != 0
|| obj->attune_next > 0
|| IS_SET( obj->attune_flags, ATTUNE_PREVIOUS )))
{
fprintf( fp, "Attune %ld %ld %d %ld\n",
(long)obj->attune_id,
obj->attune_flags,
obj->attune_modifier,
(long)obj->attune_next
);
}
// write extended descriptions for the object
for ( ed = obj->extra_descr; ed != NULL; ed = ed->next )
{
fprintf( fp, "ExDe %s~ .%s~\n",
fix_string(ed->keyword), fix_string(ed->description) );
}
fprintf( fp, "End\n\n" );
if ( obj->contains ){
fwrite_obj( obj->contains, fp, iNest + 1, heading);
}
return;
}
/**************************************************************************/
void colour_convert_player( char_data *ch);
/**************************************************************************/
// Load a char and inventory into a new ch structure.
// return true if player loaded okay
bool load_char_obj( connection_data *d, char *name )
{
char strsave[MIL];
char_data *ch;
PFILE_TYPE pt;
FILE *fp;
bool found;
int stat;
ch = new_char();
ch->pcdata = new_pcdata();
d->character = ch;
ch->desc = d;
ch->name = str_dup( capitalize(name) );
ch->level =0;
ch->trust =0;
ch->id = get_pc_id();
ch->race = race_lookup("human");
ch->act = PLR_NOSUMMON;
ch->config = CONFIG_NOCHARM;
ch->comm = COMM_COMBINE | COMM_PROMPT;
ch->mounted_on =NULL;
ch->ridden_by =NULL;
ch->tethered =false;
ch->bucking =false;
ch->wildness =100;
ch->will =100;
ch->pcdata->confirm_delete = false;
ch->pcdata->pwd = str_dup( "" );
ch->pcdata->webpass = str_dup( "" );
ch->pcdata->bamfin = str_dup( "" );
ch->pcdata->bamfout = str_dup( "" );
for (stat =0; stat < MAX_STATS; stat++)
ch->perm_stats[stat] = 1;
ch->pcdata->condition[COND_THIRST] = 48;
ch->pcdata->condition[COND_FULL] = 48;
ch->pcdata->condition[COND_HUNGER] = 48;
ch->pcdata->autoafkafter =0;
ch->pcdata->qpoints =0;
ch->pcdata->pconfig =0;
ch->pcdata->thief_until =0;
ch->pcdata->killer_until =0;
// no character name
if (IS_NULLSTR(name)){
return false;
}
// find the pfile - from which directory it is in
found = false;
pt=find_pfiletype(ch->name);
ch->pcdata->pfiletype=pt;
if(pt==PFILE_NONE || pt==PFILE_MULTIPLE){
return false;
}
sprintf( strsave, pfilename(name, pt));
fclose( fpReserve );
if ( ( fp = fopen( strsave, "r" ) ) != NULL )
{
int iNest;
for ( iNest = 0; iNest < MAX_NEST; iNest++ ){
rgObjNest[iNest] = NULL;
}
found = true;
for ( ; ; )
{
char letter;
char *word;
letter = fread_letter( fp );
if ( letter == '*' )
{
fread_to_eol( fp );
continue;
}
if ( letter != '#' )
{
bug("Load_char_obj: # not found.");
break;
}
word = fread_word( fp );
if( !str_cmp( word, "PLAYER" ) ){
fread_char( ch, fp );
}
else if ( !str_cmp(word,"OBJECT") || !str_cmp( word, "O") )
{
OBJ_DATA *o=fread_obj( fp, strsave);
if(o){
obj_to_char(o, ch);
}
}else if ( !str_cmp( word, "PET" ) ){
fread_pet( ch, fp );
}else if ( !str_cmp( word, "PO") ){ // pet objects
OBJ_DATA *o=fread_obj( fp, strsave);
if(o && ch->pet){
obj_to_char(o, ch->pet);
}
}else if ( !str_cmp( word, "END" ) ){
break;
}else{
bugf("Load_char_obj: bad section '%s'.", word);
break;
}
}
fclose( fp );
}
fpReserve = fopen( NULL_FILE, "r" );
// initialize race
if (found)
{
int i;
if(ch->race == -1){
ch->race = race_lookup("human");
}
if(ch->race == -1){
logf("load_char_obj(): unfound race for character '%s', human backup not found either, set race to 0 (whatever that is).",
ch->name);
ch->race=0;
}
ch->size = race_table[ch->race]->size;
ch->dam_type = DAM_HARM; // punch
// add racial skills
for(i = 0; i < MAX_RACIAL_SKILLS; i++){
if(race_table[ch->race]->skills[i]==-1){
break;
}
group_add(ch,skill_table[race_table[ch->race]->skills[i]].name,false, 1);
}
if(IS_AFFECTED(ch, AFF_FLYING)){
ch->affected_by = ch->affected_by|race_table[ch->race]->aff;
}else{ // werent flying when they logged out
ch->affected_by = ch->affected_by|race_table[ch->race]->aff;
REMOVE_BIT(ch->affected_by, AFF_FLYING);
}
affect_fly_update(ch); // set/remove DYN_MAGICAL_FLYING as required
ch->affected_by2= ch->affected_by2| race_table[ch->race]->aff2;
ch->imm_flags = ch->imm_flags | race_table[ch->race]->imm;
ch->res_flags = ch->res_flags | race_table[ch->race]->res;
ch->vuln_flags = ch->vuln_flags | race_table[ch->race]->vuln;
ch->form = race_table[ch->race]->form;
ch->parts = race_table[ch->race]->parts;
}
if(!ch->pcdata->custom_colour){
ch->pcdata->custom_colour=fread_custom_colours(NULL, true);
}
if(!IS_NULLSTR(ch->desc->colour_memory.custom_colour)){
free(ch->desc->colour_memory.custom_colour);
}
ch->desc->colour_memory.custom_colour=ch->pcdata->custom_colour;
ch->desc->colour_mode=ch->pcdata->colourmode;
if(!ch->pcdata->custom_colour_scheme){
ch->pcdata->custom_colour_scheme=default_colour_template;
}
ch->desc->colour_memory.colour_template=ch->pcdata->custom_colour_scheme;
ch->desc->flashing_disabled=ch->pcdata->flashing_disabled;
colour_convert_player( ch);
return found;
}
/**************************************************************************/
// Read in a char.
#if defined(KEY)
#undef KEY
#endif
#define KEY( literal, field, value ) \
if ( !str_cmp( word, literal ) ) \
{ \
field = value; \
fMatch = true; \
break; \
}
void fread_char( char_data *ch, FILE *fp )
{
char *word=NULL;
char *previousword;
bool fMatch;
int count = 0;
time_t lastlogoff = current_time;
int percent;
int note_post_index=0;
logf("Loading %s. (socket %d)", ch->name, ch->desc->connected_socket);
for ( ; ; )
{
previousword=word;
word = feof( fp ) ? (char*)"End" : fread_word( fp );
fMatch = false;
switch ( UPPER(word[0]) )
{
case '*':
fMatch = true;
fread_to_eol( fp );
break;
case 'A':
KEY( "ANote", ch->pcdata->last_anote, fread_number( fp ) );
KEY( "AVote", ch->pcdata->autovote, fread_number( fp ) );
KEY( "AfBy", ch->affected_by, fread_wordflag( affect_flags, fp ));
KEY( "AfBy2", ch->affected_by2, fread_wordflag( affect2_flags, fp ));
KEY( "AAA", ch->pcdata->autoafkafter, fread_number( fp ) );
if ( !str_cmp( word, "Act" )){
if (IS_OLD_CHVER(ch)){
ch->act =fread_flag( fp ) ;
}else{
ch->act =fread_wordflag( plr_flags, fp );
}
fMatch = true;
break;
}
if ( !str_cmp( word, "AffectedBy" )){
if (IS_OLD_CHVER(ch)){
ch->affected_by =fread_flag( fp ) ;
}else{
ch->affected_by =fread_wordflag( affect_flags, fp );
}
fMatch = true;
break;
}
if ((!str_cmp( word, "Alignment")||(!str_cmp( word, "Alig"))))
{
if((!IS_NPC(ch)))
{
ch->tendency=fread_number( fp );
ch->alliance=fread_number( fp );
}
fMatch=true;
}
if (!str_cmp( word, "Alia"))
{
if (count >= MAX_ALIAS)
{
fread_to_eol(fp);
fMatch = true;
break;
}
ch->pcdata->alias[count] = str_dup(fread_word(fp));
ch->pcdata->alias_sub[count] = str_dup(fread_word(fp));
count++;
fMatch = true;
break;
}
if (!str_cmp( word, "Alias"))
{
if (count >= MAX_ALIAS)
{
fread_to_eol(fp);
fMatch = true;
break;
}
ch->pcdata->alias[count] = str_dup(fread_word(fp));
ch->pcdata->alias_sub[count] = fread_string(fp);
count++;
fMatch = true;
break;
}
if (!str_cmp( word, "AC") || !str_cmp(word,"Armor"))
{
fread_to_eol(fp);
fMatch = true;
break;
}
if (!str_cmp(word,"ACs"))
{
int i;
for (i = 0; i < 4; i++)
ch->armor[i] = fread_number(fp);
fMatch = true;
break;
}
if (!str_cmp(word, "Affc")) // old affect format
{
AFFECT_DATA *paf;
int sn;
paf = new_affect();
char *skn=fread_word(fp);
sn = skill_lookup(skn);
if (sn < 0){
bugf("Fread_char: unknown skill '%s'.", skn);
}else{
paf->type = sn;
}
paf->where = fread_number(fp);
paf->level = fread_number( fp );
paf->duration = fread_number( fp );
paf->modifier = fread_number( fp );
paf->location = translate_old_apply_number(fread_number( fp ));
paf->bitvector = fread_number( fp );
paf->next = ch->affected;
ch->affected = paf;
fMatch = true;
break;
}
if (!str_cmp(word, "Affect"))
{
AFFECT_DATA *paf=fread_affect(fp);
paf->next = ch->affected;
ch->affected = paf;
fMatch = true;
break;
}
if ( !str_cmp( word, "AttrMod" ) || !str_cmp(word,"AMod"))
{
int stat;
if(ch->version>8)
{
for (stat = 0; stat < MAX_STATS; stat ++)
ch->modifiers[stat] = fread_number(fp);
}
fMatch = true;
break;
}
if ( !str_cmp( word, "AttrPerm" ) || !str_cmp(word,"Attr"))
{
int stat;
if(ch->version>8)
{
for (stat = 0; stat < MAX_STATS; stat++)
ch->perm_stats[stat] = fread_number(fp);
}
fMatch = true;
break;
}
if( !str_cmp(word,"APot") )
{
int stat;
for(stat=0; stat<MAX_STATS; stat++)
ch->potential_stats[stat] = fread_number(fp);
fMatch = true;
break;
}
break;
case 'B':
KEY( "Bank", ch->bank, fread_number( fp ));
KEY( "Bamfin", ch->pcdata->bamfin, fread_string( fp ));
KEY( "Bamfout", ch->pcdata->bamfout, fread_string( fp ));
KEY( "BattleLag", ch->pcdata->battlelag, fread_string( fp ) );
KEY( "Bin", ch->pcdata->bamfin, fread_string( fp ));
KEY( "Bleed", ch->bleeding, fread_number( fp ));
KEY( "Bout", ch->pcdata->bamfout, fread_string( fp ));
KEY( "Bdate", ch->pcdata->birthdate, fread_number( fp ));
KEY( "BYearMod", ch->pcdata->birthyear_modifier, fread_number( fp ));
KEY( "Birthplace", ch->pcdata->birthplace, fread_string( fp ));
KEY( "beginning_remort", ch->beginning_remort, fread_number( fp ));
break;
case 'C':
KEY( "Clan", ch->clan, clan_slookup(fread_string(fp)));
KEY( "Config", ch->config, fread_wordflag( config_flags, fp ));
KEY( "Config2", ch->config2, fread_wordflag( config2_flags, fp ));
KEY( "Cnotes", ch->pcdata->charnotes, fread_string( fp ));
KEY( "Council", ch->pcdata->council, fread_wordflag( council_flags, fp ));
KEY( "Crest", ch->pcdata->crest, fread_string( fp ));
KEY( "Created_from",ch->pcdata->created_from, fread_string( fp ));
KEY( "Custom_colours", ch->pcdata->custom_colour, fread_custom_colours(fp, true));
KEY( "Colourmode", ch->pcdata->colourmode, (COLOUR_TYPE)fread_wordflag(colourmode_types,fp ));
KEY( "CC", ch->pcdata->colour_code, fread_letter( fp ));
KEY( "CPref", ch->colour_prefix, fread_letter( fp ));
if ( !str_cmp( word, "Channeloff" ) )
{
char *text=fread_string(fp);
ch->pcdata->channeloff=
channel_convert_text_to_bitflags(text);
free_string(text);
fMatch = true;
break;
}
if ( !str_cmp( word, "Colour_scheme" )){
char *scheme=fread_string(fp);
ch->pcdata->custom_colour_scheme=find_colour_template(scheme);
free_string(scheme);
if(!ch->pcdata->custom_colour_scheme){
ch->pcdata->custom_colour_scheme=default_colour_template;
}
fMatch = true;
break;
}
if ( !str_cmp( word, "Conf" )){
if (IS_OLD_CHVER(ch)){
ch->config=fread_flag( fp ) ;
}else{
ch->config=fread_wordflag( config_flags, fp );
}
fMatch = true;
break;
}
if ( !str_cmp( word, "Class" ) || !str_cmp(word,"Cla"))
{
char *clss_buf;
if (IS_OLD_CHVER(ch)){
ch->clss = fread_number(fp);
}else{
clss_buf=fread_string(fp);
ch->clss =class_exact_lookup(clss_buf);
if(ch->clss ==-1)
{
bugf("fread_char: Unfound class '%s' in %s's pfile!",
clss_buf, ch->name);
{
char msgbody[MSL];
sprintf(msgbody,"Unfound class '%s' in %s's pfile!\r\n", clss_buf, ch->name);
autonote(NOTE_SNOTE, "fread_char()", "Unfound class in player pfile!", "code cc: imm",
msgbody, true);
}
ch->clss=0; // badly need class 0 to be the classless class
}
}
fMatch = true;
break;
}
if ( !str_cmp( word, "Condition" ) || !str_cmp(word,"Cond"))
{
ch->pcdata->condition[0] = fread_number( fp );
ch->pcdata->condition[1] = fread_number( fp );
ch->pcdata->condition[2] = fread_number( fp );
fMatch = true;
break;
}
if (!str_cmp(word,"Cnd"))
{
ch->pcdata->condition[0] = fread_number( fp );
ch->pcdata->condition[1] = fread_number( fp );
ch->pcdata->condition[2] = fread_number( fp );
ch->pcdata->condition[3] = fread_number( fp );
fMatch = true;
break;
}
if ( !str_cmp( word, "Comm" )){
if (IS_OLD_CHVER(ch)){
ch->comm =fread_flag( fp ) ;
}else{
ch->comm =fread_wordflag( comm_flags, fp );
}
fMatch = true;
break;
}
break;
case 'D':
KEY( "Damroll", ch->damroll, fread_number( fp ));
KEY( "Dam", ch->damroll, fread_number( fp ));
KEY( "Description", ch->description, fread_string( fp ));
KEY( "Desc", ch->description, fread_string( fp ));
KEY( "Diplo", ch->pcdata->diplomacy, fread_number( fp ));
KEY( "Dptn", ch->pcdata->dip_points, fread_number( fp ));
KEY( "DeityName", ch->deity, deity_lookup( fread_string(fp)) );
// Duel records
KEY( "Duel_challenged", ch->duel_challenged, fread_number( fp ));
KEY( "Duel_decline", ch->duel_decline, fread_number( fp ));
KEY( "Duel_accept", ch->duel_accept, fread_number( fp ));
KEY( "Duel_ignore", ch->duel_ignore, fread_number( fp ));
KEY( "Duel_bypass", ch->duel_bypass, fread_number( fp ));
KEY( "Duel_subdues_before_karn_loss",ch->duel_subdues_before_karn_loss, fread_number( fp ));
break;
case 'E':
KEY( "Email", ch->pcdata->email, fread_string( fp ));
KEY( "EyeCol", ch->pcdata->eyecolour, fread_string( fp ));
if ( !str_cmp( word, "End" ) )
{
// adjust hp mana move up -- here for speed's sake
// fully charge up them in 8 hours
percent =(int) (current_time - lastlogoff) * 25 / ( 2 * 60 * 60);
percent = UMIN(percent,100);
if (percent > 0 && !IS_AFFECTED(ch,AFF_POISON)
&& !IS_AFFECTED(ch,AFF_PLAGUE))
{
ch->hit += (ch->max_hit - ch->hit) * percent / 100;
ch->mana += (ch->max_mana - ch->mana) * percent / 100;
ch->move += (ch->max_move - ch->move)* percent / 100;
// make them sleep at about 3-4 times slower than online sleep
// two hours is about 100% rested
percent = (int)(current_time - lastlogoff) * 100 / (60 * 60);
if (percent> 0)
{
percent = UMIN(percent,200); // Allowed to over sleep
ch->pcdata->tired -= 15 * percent / 100;
if(ch->pcdata->tired<0)
ch->pcdata->tired=0;
}
if (ch->hit>0 && ch->position<POS_SLEEPING)
ch->position=POS_RESTING;
}
if (IS_NULLSTR(ch->pcdata->pwd)){
bugf("Null password for %s! (corrupt pfile?!?) - password set to 'password'", ch->name);
ch->pcdata->pwd=str_dup(dot_crypt("password", ch->name));
}
// rank name changed safety code
if(ch->clanrank<0 || ch->clanrank>MAX_RANK){
logf("invalid clan rank for %s, set to minrank", ch->name);
ch->clanrank=ch->clan->minRank();
}
// update the position systems to the new code
return;
}
KEY( "Exp", ch->exp, fread_number( fp ) );
KEY( "ExpireRecallInn", ch->expire_recall_inn, fread_number( fp ));
break;
case 'F':
KEY( "FadeIN", ch->pcdata->fadein, fread_string( fp ));
KEY( "FadeOUT", ch->pcdata->fadeout, fread_string( fp ));
KEY( "flashing_disabled", ch->pcdata->flashing_disabled, (fread_number( fp )==1?true:false));
break;
case 'G':
KEY( "GPro", ch->gprompt, fread_string( fp ) );
KEY( "GPrompt", ch->gprompt, fread_string( fp ) );
KEY( "Gold", ch->gold, fread_number( fp ) );
if ( !str_cmp( word, "Group" ) || !str_cmp(word,"Gr"))
{
int gn;
char *temp;
temp = fread_word( fp );
if(!str_cmp(temp,"rom basics")){ // convert code
temp="dawn basics";
}
gn = skillgroup_lookup(temp);
if ( gn < 0 )
{
if(ch->version<=6)
{
ch->train+=5;
}
bugf("fread_char(): unknown group '%s'.", temp);
}else{
gn_add(ch,gn);
}
fMatch = true;
}
break;
case 'H':
KEY( "HairCol", ch->pcdata->haircolour, fread_string( fp ));
KEY( "Height", ch->pcdata->height, fread_number( fp ));
KEY( "HeroXp", ch->pcdata->heroxp, fread_number( fp ));
KEY( "HeroLevelCount", ch->pcdata->hero_level_count, fread_number( fp ));
KEY( "History", ch->pcdata->history, fread_string( fp ));
KEY( "Hitroll", ch->hitroll, fread_number( fp ));
KEY( "Hit", ch->hitroll, fread_number( fp ));
if ( !str_cmp( word, "HpManaMove" ) || !str_cmp(word,"HMV"))
{
ch->hit = fread_number( fp );
ch->max_hit = fread_number( fp );
ch->mana = fread_number( fp );
ch->max_mana = fread_number( fp );
ch->move = fread_number( fp );
ch->max_move = fread_number( fp );
fMatch = true;
break;
}
if ( !str_cmp( word, "HpManaMovePerm" ) || !str_cmp(word,"HMVP"))
{
ch->pcdata->perm_hit = fread_number( fp );
ch->pcdata->perm_mana = fread_number( fp );
ch->pcdata->perm_move = fread_number( fp );
fMatch = true;
break;
}
if(!str_cmp( word, "HostV"))
{
fread_string(fp);
fread_to_eol(fp);
ch->host_validated=1;
SET_BIT(ch->dyn,DYN_MOB_SEE_ALL|DYN_IMMLASTON);
fMatch = true;
break;
}
break;
case 'I':
KEY( "InvisLevel", ch->invis_level, fread_number( fp ) );
KEY( "Inco", ch->incog_level, fread_number( fp ) );
KEY( "Invi", ch->invis_level, fread_number( fp ) );
KEY( "INote", ch->pcdata->last_inote, fread_number( fp ) );
KEY( "IWizi", ch->iwizi, fread_number( fp ) );
KEY( "Immwiznet",ch->wiznet[0], fread_wordflag( wiznet_flags, fp ));
KEY( "ImmTitle",ch->pcdata->immtitle, fread_string( fp ) );
KEY( "ImmRole", ch->pcdata->imm_role, fread_string( fp ) );
if ( !str_cmp( word, "ITN" ))
{
ch->pcdata->immtalk_name = fread_string( fp );
if(!str_cmp(ch->pcdata->immtalk_name,"(null)")){
ch->pcdata->immtalk_name=str_dup("");
}
fMatch = true;
}
if ( !str_cmp( word, "Id" ))
{
ch->id = fread_number( fp );
fread_to_eol(fp);
fMatch = true;
}
break;
case 'K':
KEY( "Karns", ch->pcdata->karns, fread_number(fp));
KEY( "KCntd", ch->pcdata->next_karn_countdown, fread_number(fp));
KEY( "Know_index", ch->know_index, fread_number(fp));
KEY( "Know_id", ch->know_index, fread_number(fp));
KEY( "Killer_until",ch->pcdata->killer_until,(time_t)fread_number( fp ));
break;
case 'L':
KEY( "LastLevel", ch->pcdata->last_level, fread_number( fp ) );
KEY( "LLev", ch->pcdata->last_level, fread_number( fp ) );
if ( !str_cmp( word, "Level" ))
{
int new_level=fread_number( fp );
if(ch->level){
logf("Reading in a second level value of %d for pfile %s... ignoring!",
new_level, ch->name);
}else{
ch->level=new_level;
}
fMatch = true;
break;
}
KEY( "LongDescr", ch->long_descr, fread_string( fp ) );
KEY( "LnD", ch->long_descr, fread_string( fp ) );
if ( !str_cmp( word, "Lang" ) )
{
if (IS_OLD_CHVER(ch)){
fread_number(fp); // eat up the number
if(ch->race>0){
ch->language = race_table[ch->race]->language;
}
}else{
char *read_buf=fread_string(fp);
ch->language = language_lookup(read_buf);
if(!ch->language){
bugf("fread_char: Unfound language '%s' in %s's pfile!",
read_buf, ch->name);
}
free_string(read_buf);
}
if(!ch->language){
logf("Language set to unknown for '%s'", ch->name);
ch->language=language_unknown;
}
fMatch = true;
break;
}
if ( !str_cmp( word, "LogO" ))
{
lastlogoff = fread_number( fp );
ch->pcdata->last_logout_time=lastlogoff;
fread_to_eol(fp);
fMatch = true;
}
if ( !str_cmp( word, "LogOS" ))
{
ch->pcdata->last_logout_site = fread_string(fp);
fread_to_eol(fp);
fMatch = true;
}
if ( !str_cmp( word, "Last_ic_room" ) || !str_cmp( word, "LIcRm" ))
{
ch->last_ic_room = get_room_index( fread_number( fp ) );
fMatch = true;
}
break;
case 'M':
KEY( "Merit", ch->pcdata->merit, fread_number(fp));
KEY( "MKil", ch->pcdata->mkills, fread_number( fp ) );
KEY( "MDef", ch->pcdata->mdefeats, fread_number( fp ) );
KEY( "MiscN", ch->pcdata->last_misc, fread_number( fp ));
break;
case 'N':
KEY( "Name", ch->name, fread_string( fp ) );
KEY( "Note", ch->pcdata->last_note, fread_number( fp ) );
// KEY( "NoteNet",ch->notenet, fread_wordflag( notenet_flags, fp ));
if ( !str_cmp( word, "NoteNet" )){
if (IS_OLD_CHVER(ch)){
ch->notenet=fread_flag( fp ) ;
}else{
ch->notenet=fread_wordflag( notenet_flags, fp );
}
fMatch = true;
break;
}
if (!str_cmp(word,"Not"))
{
ch->pcdata->last_note = fread_number(fp);
ch->pcdata->last_idea = fread_number(fp);
ch->pcdata->last_penalty = fread_number(fp);
ch->pcdata->last_news = fread_number(fp);
ch->pcdata->last_changes = fread_number(fp);
fMatch = true;
break;
}
if ( !str_cmp( word, "NotePost" )){
ch->pcdata->note_post_time[note_post_index++]=fread_number(fp);
note_post_index=UMIN(note_post_index,MAX_NOTE_POST_TIME_INDEX-1);
fMatch = true;
break;
}
// Addition Vanish skill
KEY( "NVanish", ch->pcdata->next_vanish, (fread_number( fp ) + current_time) );
KEY( "NWorshipTime", ch->pcdata->worship_time, (current_time - fread_number( fp )) );
break;
case 'O':
KEY( "OLCProm", ch->olcprompt, fread_string( fp ) );
KEY( "OLCPrompt", ch->olcprompt, fread_string( fp ) );
KEY( "OPrmt", ch->olcprompt, fread_string( fp ) );
KEY( "OWizi", ch->owizi, fread_number( fp ) );
KEY( "OlcWizi", ch->olcwizi, fread_number( fp ) );
break;
case 'P':
KEY( "Password", ch->pcdata->pwd, fread_string( fp ) );
KEY( "Pass", ch->pcdata->pwd, fread_string( fp ) );
KEY( "Panic", ch->pcdata->panic, fread_number( fp ) );
KEY( "PConfig", ch->pcdata->pconfig, fread_wordflag( pconfig_flags, fp ));
KEY( "PKool", ch->pkool, fread_number( fp ) );
KEY( "PKsafe", ch->pksafe, fread_number( fp ) );
KEY( "PKsaf", ch->pksafe, fread_number( fp ) );
KEY( "PKills", ch->pkkills, fread_number( fp ) );
KEY( "PKill", ch->pkkills, fread_number( fp ) );
KEY( "PKDef", ch->pkdefeats, fread_number( fp ) );
KEY( "PKNote", ch->pcdata->last_pknote, fread_number( fp ) );
KEY( "Points", ch->pcdata->points, fread_number( fp ) );
KEY( "Pnts", ch->pcdata->points, fread_number( fp ) );
KEY( "Practice", ch->practice, fread_number( fp ) );
KEY( "Prac", ch->practice, fread_number( fp ) );
KEY( "Prompt", ch->prompt, fread_string( fp ) );
KEY( "Prom", ch->prompt, fread_string( fp ) );
KEY( "PrefMSP", ch->pcdata->preference_msp, (PREFERENCE_TYPE)fread_wordflag( preference_types, fp ));
KEY( "PrefMXP", ch->pcdata->preference_mxp, (PREFERENCE_TYPE)fread_wordflag( preference_types, fp ));
KEY( "PrefDAWNFTP", ch->pcdata->preference_dawnftp, (PREFERENCE_TYPE)fread_wordflag( preference_types, fp ));
KEY( "PrefColourInSocials", ch->pcdata->preference_colour_in_socials,(PREFERENCE_TYPE)fread_wordflag( preference_types, fp ));
if ( !str_cmp( word, "Played" ) || !str_cmp( word, "Plyd" ))
{
ch->played= fread_number( fp );
fread_to_eol(fp);
fMatch = true;
break;
}
if ( !str_cmp( word, "Pos" ) || !str_cmp( word, "Position" ) )
{
char *read_buf;
if (IS_OLD_CHVER(ch)){
char *t;
int p;
t=fread_word(fp);
// old format
if(is_number(t)){
p=atoi(t);
if(p>6){
p++; // compenstate for kneel being added at position 7
}
ch->position=p;
}else{
// new format
p=position_lookup(t);
if(p>=0){
ch->position=p;
}else{
ch->position=POS_STANDING;
}
}
fMatch = true;
break;
}else{
read_buf=fread_string(fp);
ch->position= position_lookup(read_buf);
if(ch->position ==-1)
{
bugf("fread_char: Unfound position '%s' in %s's pfile!",
read_buf, ch->name);
ch->position=POS_STANDING;
}
}
fMatch = true;
break;
}
break;
case 'Q':
KEY( "Quest", ch->pcdata->qpoints, fread_number(fp));
break;
case 'R':
KEY( "Rps", ch->pcdata->rp_points, fread_number(fp));
KEY( "Rank", ch->clanrank, ch->clan->rank_lookup(fread_string(fp)));
KEY( "Reroll_cnt", ch->pcdata->reroll_counter, fread_number(fp));
KEY( "RecallRoom", ch->recall_room, fread_number(fp));
KEY( "RecallInnRoom", ch->recall_inn_room, fread_number(fp));
KEY( "RCnt", ch->pcdata->reroll_counter, fread_number(fp));
KEY( "Rpcnt", ch->pcdata->rp_count, fread_number(fp));
KEY( "Remrt", ch->remort, fread_number(fp));
KEY( "Remort", ch->remort, fread_number(fp));
KEY( "RXP", ch->pcdata->reduce_xp_percent, fread_number(fp));
KEY( "RRPS", ch->pcdata->reduce_rps_percent, fread_number(fp));
if ( !str_cmp( word, "Room" ) )
{
int room_vnum=fread_number( fp );
ch->in_room = get_room_index( room_vnum );
if ( !ch->in_room){
logf("fread_char(): character '%s' couldn't be logged into "
"room vnum %d because room no longer exists... putting them in limbo instead (%d)",
ch->name, room_vnum, ROOM_VNUM_LIMBO);
ch->in_room = get_room_index( ROOM_VNUM_LIMBO );
}
fMatch = true;
}
//KEY( "Race", ch->race, race_lookup(fread_string( fp )) );
if ( !str_cmp( word, "Race" ) )
{
ch->race = race_lookup(fread_string( fp ));
if (ch->race == -1)
{
ch->race = race_lookup("human");
bugf("fread_char: ch '%s' has an invalid race!!!",
ch->name);
}
fMatch = true;
}
break;
case 'S':
KEY( "SubV", ch->subversion, fread_number( fp ));
// sublevel system
KEY( "SLvl", ch->pcdata->sublevel, fread_number( fp ));
KEY( "SubP", ch->pcdata->sublevel_pracs, fread_number( fp ));
KEY( "SubT", ch->pcdata->sublevel_trains,fread_number( fp ));
KEY( "SavingThrow", ch->saving_throw, fread_number( fp ));
KEY( "Save", ch->saving_throw, fread_number( fp ));
KEY( "Scro", ch->lines, fread_number( fp ));
KEY( "Sec", ch->pcdata->security, fread_number( fp ));
KEY( "ShortDescr", ch->short_descr, fread_string( fp ));
KEY( "ShD", ch->short_descr, fread_string( fp ));
KEY( "Silv", ch->silver, fread_number( fp ));
KEY( "Stun", ch->is_stunned, fread_number( fp ));
KEY( "Surname", ch->pcdata->surname, fread_string( fp ));
KEY( "SNote", ch->pcdata->last_snote, fread_number( fp ));
if ( !str_cmp( word, "Strip_channel_colours" ) )
{
char *text=fread_string(fp);
ch->pcdata->strip_colour_on_channel=
channel_convert_text_to_bitflags(text);
free_string(text);
fMatch = true;
break;
}
if ( !str_cmp( word, "Saycol" ) )
{
char buf[MSL];
char *scw=fread_word( fp );
ch->saycolour=scw[0];
sprintf(buf, "`%c", ch->saycolour);
if (c_str_len(buf)!=0){
bug("Invalid saycolour in pfile - ignored");
ch->saycolour='x';
}
fMatch = true;
break;
}
if ( !str_cmp( word, "Sex" ) )
{
char *read_buf;
if (IS_OLD_CHVER(ch)){
ch->sex = fread_number(fp);
}else{
read_buf=fread_string(fp);
ch->sex =sex_lookup(read_buf);
if(ch->sex ==-1)
{
bugf("fread_char: Unfound sex '%s' in %s's pfile!",
read_buf, ch->name);
ch->sex=0;
}
}
fMatch = true;
break;
}
if ( !str_cmp( word, "SkLU" ) ) // last time the skill was used
{
int sn;
int value;
char *temp;
value = fread_number( fp );
temp = fread_word( fp ) ;
sn = skill_lookup(temp);
if ( sn < 0 ){
bugf("Fread_char: unknown skill '%s'.", temp);
}else{
if (value>100000){ // reset lastused counters
ch->pcdata->last_used[sn] = (time_t)value;
}else{
ch->pcdata->last_used[sn]=0;
}
}
fMatch = true;
break;
}
if ( !str_cmp( word, "Skill" ) || !str_cmp(word,"Sk"))
{
int sn;
int value;
char *temp;
value = fread_number( fp );
temp = fread_word( fp ) ;
sn = skill_lookup(temp);
if(sn < 0 ){
bugf("fread_char: unknown skill '%s'.", temp);
}else{
if((ch->version<=6)&&(sn>=FIRST_SPELL)&&
(sn<=LAST_SPELL))
{
ch->practice+=value/33+1;
}else{
ch->pcdata->learned[sn] = value;
}
}
fMatch = true;
}
break;
case 'T':
KEY( "Temple", ch->temple, fread_number( fp ));
KEY( "Tired", ch->pcdata->tired, fread_number( fp ));
KEY( "TrueSex", ch->pcdata->true_sex, fread_number( fp ));
KEY( "Trai", ch->train, fread_number( fp ));
KEY( "Title", ch->pcdata->title, fread_string( fp ));
KEY( "Thief_until", ch->pcdata->thief_until, (time_t)fread_number( fp ));
if (!str_cmp( word, "Trait"))
{
char *buf;
buf = fread_word(fp);
if ( is_number( buf ))
{
count = atoi( buf );
ch->pcdata->trait[count] = str_dup(fread_word(fp));
}
fMatch = true;
break;
}
if ( !str_cmp( word, "TSex" ) )
{
char *read_buf;
if (IS_OLD_CHVER(ch)){
ch->pcdata->true_sex = fread_number(fp);
}else{
read_buf=fread_string(fp);
ch->pcdata->true_sex =sex_lookup(read_buf);
if(ch->pcdata->true_sex ==-1)
{
bugf("fread_char: Unfound true_sex '%s' in %s's pfile!",
read_buf, ch->name);
ch->pcdata->true_sex=0;
}
}
fMatch = true;
break;
}
if ( !str_cmp( word, "Trying") || !str_cmp( word, "Tryin"))
{
int t = fread_number( fp );
if (t==0){
ch->is_trying_sleep= false;
}else{
ch->is_trying_sleep= true;
}
fMatch = true;
break;
}
if ( !str_cmp( word, "Trust" ))
{
int new_trust=fread_number( fp );
if(ch->trust){
logf("Reading in a second trust value of %d for pfile %s... ignoring!",
new_trust, ch->name);
}else{
ch->trust=new_trust;
}
fMatch = true;
break;
}
break;
case 'U':
KEY( "Unlock_id", ch->pcdata->unlock_id, fread_string( fp ) );
KEY( "Unsafe_4stealing", ch->pcdata->unsafe_due_to_stealing_till, fread_number( fp ) );
break;
case 'V':
KEY( "Ver_update", ch->subversion, fread_number ( fp )); //old
KEY( "Version", ch->version, fread_number ( fp ));
KEY( "Vers", ch->version, fread_number ( fp ));
if ( !str_cmp( word, "Vnum" ) )
{
ch->pIndexData = get_mob_index( fread_number( fp ) );
fMatch = true;
break;
}
break;
case 'W':
KEY( "Weight", ch->pcdata->weight, fread_number( fp ));
KEY( "WebPass", ch->pcdata->webpass, fread_string( fp ));
KEY( "Wimpy", ch->wimpy, fread_number( fp ));
KEY( "Wimp", ch->wimpy, fread_number( fp ));
KEY( "Wdie", ch->will_die, fread_number( fp ));
KEY( "Wiznet", ch->wiznet[1], fread_wordflag( wiznet_flags, fp ));
KEY( "Wiznet2", ch->wiznet[2], fread_wordflag( wiznet_flags, fp ));
KEY( "Wiznet3", ch->wiznet[3], fread_wordflag( wiznet_flags, fp ));
KEY( "Wiznet0c", ch->wiznet_colour[0], fread_string( fp ));
KEY( "Wiznet1c", ch->wiznet_colour[1], fread_string( fp ));
KEY( "Wiznet2c", ch->wiznet_colour[2], fread_string( fp ));
KEY( "Wiznet3c", ch->wiznet_colour[3], fread_string( fp ));
if ( !str_cmp( word, "Wizn" )){
if (IS_OLD_CHVER(ch)){
ch->wiznet[1]=fread_flag( fp ) ;
}else{
ch->wiznet[1]=fread_wordflag( wiznet_flags, fp );
}
fMatch = true;
break;
}
if ( !str_cmp( word, "WhoFormat" )){
char *wfmt=fread_string(fp);
ch->pcdata->who_format=UMAX(0,who_format_lookup(wfmt));
free_string(wfmt);
fMatch = true;
break;
}
break;
case 'X':
KEY( "Xpen", ch->pcdata->xp_penalty, fread_number( fp ) );
break;
}
if ( !fMatch )
{
bugf( "Fread_char: no match for '%s', word before that = '%s'.",
word, previousword);
fread_to_eol( fp );
}
}
}
/**************************************************************************/
// load a pet from the forgotten reaches
void fread_pet( char_data *ch, FILE *fp )
{
char *word;
char_data *pet;
bool fMatch;
time_t lastlogoff = current_time;
int percent;
bool non_existant_pet=false;
int pet_vnum=0;
// first entry had BETTER be the vnum or we barf
word = feof(fp) ? (char*)"END" : fread_word(fp);
if (!str_cmp(word,"Vnum"))
{
pet_vnum= fread_number(fp);
if (get_mob_index(pet_vnum) == NULL)
{
bugf("Fread_pet: bad vnum %d.",pet_vnum);
non_existant_pet=true;
pet = create_mobile(limbo_mob_index_data, 0);
}else{
pet = create_mobile(get_mob_index(pet_vnum), 0);
}
}
else
{
bug("Fread_pet: no vnum in file.");
pet = create_mobile(limbo_mob_index_data, 0);
}
for ( ; ; )
{
word = feof(fp) ? (char*)"END" : fread_word(fp);
fMatch = false;
switch (UPPER(word[0]))
{
case '*':
fMatch = true;
fread_to_eol(fp);
break;
case 'A':
KEY( "Act", pet->act, fread_flag(fp));
KEY( "AfBy", pet->affected_by, fread_flag(fp));
KEY( "AffBy", pet->affected_by, fread_wordflag(affect_flags, fp));
KEY( "AffBy2", pet->affected_by2, fread_wordflag(affect2_flags,fp));
KEY( "Alig", pet->alliance, 3*fread_number(fp)/1000);
if (!str_cmp(word,"Algn"))
{
pet->tendency=fread_number(fp);
pet->alliance=fread_number(fp);
fMatch = true;
break;
}
if (!str_cmp(word,"ACs"))
{
int i;
for (i = 0; i < 4; i++)
pet->armor[i] = fread_number(fp);
fMatch = true;
break;
}
if (!str_cmp(word,"Affc"))
{
AFFECT_DATA *paf;
int sn;
paf = new_affect();
sn = skill_lookup(fread_word(fp));
if (sn < 0)
bug("Fread_char: unknown skill.");
else
paf->type = sn;
paf->where = fread_number(fp);
paf->level = fread_number(fp);
paf->duration = fread_number(fp);
paf->modifier = fread_number(fp);
paf->location = translate_old_apply_number(fread_number(fp));
paf->bitvector = fread_number(fp);
paf->next = pet->affected;
pet->affected = paf;
fMatch = true;
break;
}
if (!str_cmp(word,"AMod"))
{
int stat;
if(ch->version>8)
{
for (stat = 0; stat < MAX_STATS; stat++)
pet->modifiers[stat] = fread_number(fp);
}
fMatch = true;
break;
}
if (!str_cmp(word,"Attr"))
{
int stat;
if(ch->version>8)
{
for (stat = 0; stat < MAX_STATS; stat++)
pet->perm_stats[stat] = fread_number(fp);
}
fMatch = true;
break;
}
break;
case 'C':
KEY( "Clan", pet->clan, clan_slookup(fread_string(fp)));
KEY( "Comm", pet->comm, fread_flag(fp));
KEY( "Com", pet->comm, fread_wordflag(comm_flags, fp));
break;
case 'D':
KEY( "Dam", pet->damroll, fread_number(fp));
KEY( "Desc", pet->description, fread_string(fp));
break;
case 'E':
if (!str_cmp(word,"End"))
{
if(non_existant_pet){
logf("Removing pet from %s, because the vnum of it couldn't be located.", PERS(ch, NULL));
ch->println("`R********************************************************************************");
ch->printlnf("`R*`W Your pet vnum %5d couldn't be located for loading, contact the admin. `R*", pet_vnum);
ch->println("`R********************************************************************************`x");
}else{
pet->leader = ch;
pet->master = ch;
ch->pet = pet;
/* adjust hp mana move up -- here for speed's sake */
percent = (int)(current_time - lastlogoff) * 25 / ( 2 * 60 * 60);
if (percent > 0 && !IS_AFFECTED(ch,AFF_POISON)
&& !IS_AFFECTED(ch,AFF_PLAGUE))
{
percent = UMIN(percent,100);
pet->hit += (pet->max_hit - pet->hit) * percent / 100;
pet->mana += (pet->max_mana - pet->mana) * percent / 100;
pet->move += (pet->max_move - pet->move)* percent / 100;
}
}
return;
}
KEY( "Exp", pet->exp, fread_number(fp));
break;
case 'G':
KEY( "Gold", pet->gold, fread_number(fp));
break;
case 'H':
KEY( "Hit", pet->hitroll, fread_number(fp));
if (!str_cmp(word,"HMV"))
{
pet->hit = fread_number(fp);
pet->max_hit = fread_number(fp);
pet->mana = fread_number(fp);
pet->max_mana = fread_number(fp);
pet->move = fread_number(fp);
pet->max_move = fread_number(fp);
fMatch = true;
break;
}
break;
case 'L':
KEY( "Levl", pet->level, fread_number(fp));
KEY( "LnD", pet->long_descr, fread_string(fp));
KEY( "LogO", lastlogoff, fread_number(fp));
break;
case 'M':
KEY( "MAct", pet->act, fread_wordflag(act_flags,fp));
break;
case 'N':
KEY( "Name", pet->name, fread_string(fp));
break;
case 'P':
KEY( "Pos", pet->position, fread_number(fp));
case 'R':
// KEY( "Race", pet->race, race_lookup(fread_string(fp)));
if ( !str_cmp( word, "Race" ) )
{
ch->race = race_lookup(fread_string( fp ));
if (ch->race == -1)
{
ch->race = race_lookup("human");
bugf("fread_pet: pet '%s' has an invalid race!!!",
ch->name);
}
fMatch = true;
}
if ( !str_cmp( word, "Room" ) )
{
pet->in_room = get_room_index( fread_number( fp ) );
if ( pet->in_room == NULL )
{
pet->in_room = get_room_index( ROOM_VNUM_LIMBO );
}
fMatch = true;
}
break;
case 'S' :
KEY( "Save", pet->saving_throw, fread_number(fp));
KEY( "Sex", pet->sex, fread_number(fp));
KEY( "ShD", pet->short_descr, fread_string(fp));
KEY( "Silv", pet->silver, fread_number( fp ) );
break;
if ( !fMatch )
{
bug("Fread_pet: no match.");
fread_to_eol(fp);
}
}
}
}
/**************************************************************************/
// return the object/container
obj_data * fread_obj( FILE *fp, const char *filename )
{
obj_data *obj;
char *word;
int iNest;
bool fMatch;
bool fNest;
bool fVnum;
bool first;
char obj_rembuf[MSL];
int vnum=0;
fVnum = false;
obj = NULL;
first = true; // used to counter fp offset
word = feof( fp ) ? (char*)"End" : fread_word( fp );
if (!str_cmp(word,"Vnum" ))
{
first = false; // fp will be in right place
vnum = fread_number( fp );
if ( get_obj_index( vnum ) == NULL )
{
bugf( "Fread_obj: bad vnum %d.", vnum );
dont_nest=true;
}
else
{
obj = create_object(get_obj_index(vnum));
}
}
if(!obj){ // object not found
obj = new_obj();
obj->name = str_dup( "" );
obj->short_descr = str_dup( "" );
obj->description = str_dup( "" );
}
fNest = false;
fVnum = true;
iNest = 0;
for ( ; ; )
{
if (first){
first = false;
}else{
word = feof( fp ) ? (char*)"End" : fread_word( fp );
}
fMatch = false;
switch ( UPPER(word[0]) )
{
case '*':
fMatch = true;
fread_to_eol( fp );
break;
case 'A':
if (!str_cmp(word, "Affect"))
{
AFFECT_DATA *paf=fread_affect(fp);
paf->next = obj->affected;
obj->affected = paf;
fMatch = true;
break;
}
if (!str_cmp(word,"Affc"))
{
AFFECT_DATA *paf;
int sn;
paf = new_affect();
sn = skill_lookup(fread_word(fp));
if (sn < 0){
bug("Fread_obj: unknown skill.");
}else{
paf->type = sn;
}
paf->where = fread_number( fp );
paf->level = fread_number( fp );
paf->duration = fread_number( fp );
paf->modifier = fread_number( fp );
paf->location = translate_old_apply_number(fread_number( fp ));
paf->bitvector = fread_number( fp );
paf->next = obj->affected;
obj->affected = paf;
fMatch = true;
break;
}
if (!str_cmp(word, "Attune" ))
{
obj->attune_id = fread_number( fp );
obj->attune_flags = fread_number( fp );
obj->attune_modifier = fread_number( fp );
obj->attune_next = fread_number( fp );
fMatch = true;
break;
}
break;
case 'C':
KEY( "Cond", obj->condition, fread_number( fp ) );
KEY( "Cost", obj->cost, fread_number( fp ) );
if( !str_cmp( word, "Chaos"))
{
obj->chaos=true;
fMatch=true;
break ;
}
break;
case 'D':
KEY( "Description", obj->description, fread_string( fp ) );
KEY( "Desc", obj->description, fread_string( fp ) );
break;
case 'E':
if ( !str_cmp( word, "Enchanted"))
{
// obj->enchanted = true; // removed - kal
fMatch = true;
break;
}
KEY( "ExtraFlags", obj->extra_flags, fread_number( fp ) );
KEY( "ExtF", obj->extra_flags, fread_number( fp ) );
KEY( "ExtF2", obj->extra2_flags, fread_number( fp ) );
if ( !str_cmp( word, "ExtraDescr" ) || !str_cmp(word,"ExDe"))
{
EXTRA_DESCR_DATA *ed;
ed = new_extra_descr();
ed->keyword = fread_string( fp );
ed->description = fread_string( fp );
// chop off the . if it starts with that
if (ed->description[0]=='.')
{
char *temp_string;
temp_string = str_dup(ed->description);
free_string(ed->description);
ed->description= str_dup(temp_string+1);
free_string(temp_string);
}
ed->next = obj->extra_descr;
obj->extra_descr = ed;
fMatch = true;
}
if ( !str_cmp( word, "End" ) )
{
if ( !fNest || !fVnum || obj->pIndexData == NULL)
{
bug("Fread_obj: incomplete object.");
extract_obj(obj);
sprintf(obj_rembuf, "fread() object %d didn't exist in %s", vnum, filename);
append_datetimestring_to_file(OBJ_REM_FILE, obj_rembuf);
return NULL;
}
else
{
// TOKENS & Quitdeath
if (!hotreboot_in_progress
&& (obj->item_type == ITEM_TOKEN)
&& (IS_SET ( obj->value[0], TOKEN_QUITDEATH )))
{
logf("Not hotreboot - removing token %d marked as quitdeath", vnum);
extract_obj(obj);
return NULL;
}
if (!hotreboot_in_progress && (obj->item_type == ITEM_KEY
|| (obj->item_type == ITEM_MAP && !obj->value[0])))
{
logf("Not hotreboot - removing key/map vnum %d", vnum);
extract_obj(obj);
return NULL;
}
if(obj->pIndexData->vnum==OBJ_VNUM_LIGHT_BALL){
if(obj->value[2]==-1 || obj->value[2]>1000){
// continual light - prevent it going on for ever
obj->value[2]=1000;
}
}
if (hotreboot_in_progress && (obj->item_type == ITEM_KEY
|| (obj->item_type == ITEM_MAP && !obj->value[0])))
{
logf("hotreboot - giving them key/map vnum %d", vnum);
}
// if we haven't found a vnum, dynamically create the object
if ( !fVnum ){
free_string( obj->name );
free_string( obj->description );
free_string( obj->short_descr );
obj->next = obj_free;
obj_free = obj;
obj = create_object( get_obj_index( OBJ_VNUM_DUMMY ));
}
if ( iNest != 0 && rgObjNest[iNest]){
if (rgObjNest[iNest-1]->pIndexData){
obj_to_obj( obj, rgObjNest[iNest-1]);
obj=NULL;
}else{
bugf("Fread_obj: object vnum %d couldn't be loaded into parent container!", vnum);
sprintf(obj_rembuf, "object %d couldn't be loaded into parent container! (%s)",
vnum, filename);
append_timestring_to_file(OBJ_REM_FILE, obj_rembuf);
}
}
return obj;
}
}
break;
case 'I':
KEY( "ItemType", obj->item_type, fread_number( fp ) );
KEY( "Ityp", obj->item_type, fread_number( fp ) );
break;
case 'L':
KEY( "Level", obj->level, fread_number( fp ) );
KEY( "Lev", obj->level, fread_number( fp ) );
break;
case 'N':
KEY( "Name", obj->name, fread_string( fp ) );
if ( !str_cmp( word, "no_affects"))
{
obj->no_affects = true;
fMatch = true;
break;
}
if ( !str_cmp( word, "Nest" ) )
{
iNest = fread_number( fp );
if (( iNest < 0 || iNest >= MAX_NEST )&&(dont_nest==true))
{
bugf( "Fread_obj: bad nest %d.", iNest );
}
else
{
rgObjNest[iNest] = obj;
fNest = true;
}
fMatch = true;
}
break;
case 'P':
if( !str_cmp( word, "ParchmentLanguage"))
{
obj->value[3] = language_safe_lookup(fread_word(fp))->unique_id;
fMatch=true;
break ;
}
break;
case 'R': // restrung objects - Kalahn June 98
if( !str_cmp( word, "RESTRUNG"))
{
obj->restrung=true;
fMatch=true;
fread_to_eol( fp );
break ;
}
break;
case 'S':
KEY( "ShortDescr", obj->short_descr, fread_string( fp ) );
KEY( "ShD", obj->short_descr, fread_string( fp ) );
if ( !str_cmp( word, "Spell" ) )
{
int iValue;
int sn;
iValue = fread_number( fp );
sn = skill_lookup( fread_word( fp ) );
if ( iValue < 0 || iValue > 4 )
{
bugf( "Fread_obj: bad iValue %d on object %d.",
iValue, obj->pIndexData?obj->pIndexData->vnum:0 );
}
else if ( sn < 0 )
{
bug("Fread_obj: unknown skill.");
}
else
{
obj->value[iValue] = sn;
}
fMatch = true;
break;
}
break;
case 'T':
KEY( "Timer", obj->timer, fread_number( fp ) );
KEY( "Time", obj->timer, fread_number( fp ) );
break;
case 'V':
if ( !str_cmp( word, "Values" ) || !str_cmp(word,"Vals"))
{
obj->value[0] = fread_number( fp );
obj->value[1] = fread_number( fp );
obj->value[2] = fread_number( fp );
obj->value[3] = fread_number( fp );
if (obj->item_type == ITEM_WEAPON && obj->value[0] == 0){
obj->value[0] = obj->pIndexData->value[0];
}
if(obj->item_type==ITEM_PARCHMENT){
obj->value[3]=language_lookup("unknown")->unique_id;
}
fMatch = true;
break;
}
if ( !str_cmp( word, "Val" ) )
{
obj->value[0] = fread_number( fp );
obj->value[1] = fread_number( fp );
obj->value[2] = fread_number( fp );
obj->value[3] = fread_number( fp );
obj->value[4] = fread_number( fp );
fMatch = true;
break;
}
if ( !str_cmp( word, "Vnum" ) )
{
int vnum;
vnum = fread_number( fp );
if ( ( obj->pIndexData = get_obj_index( vnum ) ) == NULL ){
bugf( "Fread_obj: bad vnum %d.", vnum );
}else{
fVnum = true;
}
fMatch = true;
break;
}
break;
case 'W':
KEY( "WearFlags", obj->wear_flags, fread_number( fp ) );
KEY( "WeaF", obj->wear_flags, fread_number( fp ) );
KEY( "WearLoc", obj->wear_loc, fread_wordflag(wear_location_types, fp ));
KEY( "Wear", obj->wear_loc, fread_number( fp ) );
KEY( "Weight", obj->weight, fread_number( fp ) );
KEY( "Wt", obj->weight, fread_number( fp ) );
break;
}
if ( !fMatch )
{
bugf("Fread_obj: no match for '%s'.", word);
fread_to_eol( fp );
}
}
}
/**************************************************************************/