/***************************************************************************
* Mud20 1.0 by Todd H. Johnson (Kregor) a derivative of the Open Gaming *
* License by Wizards of the Coast. All comments referring to D20, OGL, *
* and SRD refer to the System Reference Document for the Open Gaming *
* system. Any inclusion of these derivatives must include credit to the *
* Mud20 system, the full and complete Open Gaming LIcense, and credit to *
* the respective authors. See ../doc/srd.txt for more information. *
* *
* Emud 2.2 by Igor van den Hoven, Michiel Lange, and Martin Bethlehem. *
* *
* MrMud 1.4 by David Bills, Dug Michael and Martin Gallwey *
* *
* Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* Original Diku Mud copyright (C) 1990 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeld, Tom Madsen, and Katje Nyboe. *
***************************************************************************/
/***************************************************************************
* save.c: Handles saves to data files *
***************************************************************************/
#include <sys/stat.h>
#include "mud.h"
/*
Array of containers read for proper re-nesting of objects.
*/
#define MAX_NEST 10
static OBJ_DATA * rgObjNest [MAX_NEST];
/*
The object version number is saved in the pfiles, if someone logs
in with a non matching version number all the objects carried by
that person will be purged, if you ever need to use this it would
be smart to also add the version check to the quest bits of players,
so the kids can get some new gear - Scandum
*/
/*
Local functions.
*/
int total_language( CHAR_DATA *);
void save_account args( ( DESCRIPTOR_DATA *d ) );
void fwrite_char args( ( CHAR_DATA *ch, FILE *fp ) );
void fwrite_mobile args( ( CHAR_DATA *mob, FILE *fp ) );
void fwrite_obj args( ( CHAR_DATA *ch, OBJ_DATA *obj, FILE *fp, char iNest ) );
void fread_char args( ( CHAR_DATA *ch, FILE *fp ) );
void fread_account args( ( ACCOUNT_DATA *acct, FILE *fp ) );
CHAR_DATA * fread_mobile args( ( FILE *fp ) );
void fread_obj args( ( CHAR_DATA *ch, FILE *fp ) );
bool is_valid_file args( ( CHAR_DATA *ch, FILE *fp ) );
void fwrite_poison_data( POISON_DATA *, FILE *);
POISON_DATA *fread_poison_data( FILE *);
lg_int encrypt64( char *str )
{
lg_int h;
push_call("encrypt64(%p)",str);
for (h = 0 ; *str != 0 ; str++)
{
h = (h << 7) + *str;
}
pop_call();
return h;
}
void add_pvnum( CHAR_DATA *ch )
{
PVNUM_DATA *pvnum;
push_call("add_pvnum(%p)",ch);
if (ch->pcdata->pvnum && pvnum_index[ch->pcdata->pvnum] == NULL)
{
ALLOCMEM(pvnum, PVNUM_DATA, 1);
pvnum->name = STRALLOC(capitalize_name(ch->name));
pvnum->date = mud->current_time;
SET_BIT(pvnum->flags, PVNUM_AUTH_NAME);
pvnum_index[ch->pcdata->pvnum] = pvnum;
}
pop_call();
return;
}
int find_free_pvnum()
{
int cnt;
push_call("find_free_pvnum()");
for (cnt = 100 ; cnt < MAX_PVNUM / 2 ; cnt++)
{
if (pvnum_index[cnt] == NULL)
{
pop_call();
return cnt;
}
}
log_printf("find_free_pvnum: no free pvnum index found: removing deleted players");
for (cnt = 100 ; cnt < MAX_PVNUM ; cnt++)
{
if (pvnum_index[cnt] == NULL)
{
continue;
}
if (IS_SET(pvnum_index[cnt]->flags, PVNUM_DELETED))
{
STRFREE(pvnum_index[cnt]->name);
FREEMEM(pvnum_index[cnt]);
}
}
for (cnt = 100 ; cnt < MAX_PVNUM ; cnt++)
{
if (pvnum_index[cnt] == NULL)
{
pop_call();
return cnt;
}
}
log_printf("find_free_pvnum: no free pvnum index found");
pop_call();
return 0;
}
/*
Save a character and inventory.
*/
void save_char_obj(CHAR_DATA *ch, int which_type)
{
PET_DATA *pet;
char strsave[MAX_INPUT_LENGTH], strtemp[MAX_INPUT_LENGTH];
char logfile[250];
char cap_name[30];
FILE *fp, *logfp;
ROOM_INDEX_DATA *troom;
bool IS_DESC;
push_call("save_char_obj(%p,%p)",ch,which_type);
if (IS_NPC(ch))
{
pop_call();
return;
}
IS_DESC = is_desc_valid( ch );
if ( IS_DESC && ch->desc->original != NULL )
{
send_to_char( "You can't save out of body!\n\r", ch);
pop_call();
return;
}
troom = ch->in_room;
if (troom == NULL)
{
log_printf("Save_char_obj: char was not in a room");
pop_call();
return;
}
if (IS_SET(troom->room_flags, ROOM_NO_SAVE))
{
char_from_room( ch );
char_to_room( ch, ROOM_VNUM_TEMPLE, FALSE );
}
strcpy( cap_name, capitalize_name( ch->name ) );
if (which_type == NORMAL_SAVE)
{
sprintf(strsave,"%s/%c/%s", PLAYER_DIR, tolower(cap_name[0]), cap_name);
sprintf(strtemp,"%s/%c/temp.%s",PLAYER_DIR, tolower(cap_name[0]), cap_name);
}
else
{
sprintf(strsave, "%s/%c/bak/%s", PLAYER_DIR, tolower(cap_name[0]), cap_name);
sprintf(strtemp, "%s/%c/bak/temp.%s", PLAYER_DIR, tolower(cap_name[0]), cap_name);
}
close_reserve();
/*
Save char to "temp.name" then rename to "name" after all done for safety
*/
sprintf(logfile, "%s/%c/%s.log", PLAYER_DIR, tolower(cap_name[0]), cap_name);
logfp = my_fopen(logfile,"w",FALSE);
if (logfp == NULL)
{
log_printf("Could _NOT_ open logfile to log the saving of %s\n\r.",cap_name);
print_errno(errno);
}
if (remove( strtemp ) != 0)
{
if (errno != ENOENT) /* if there was no temp file there's no prob */
{
log_printf("save_char_obj: could not remove %s.", strtemp);
print_errno(errno);
}
}
fp = my_fopen( strtemp, "w", FALSE ) ;
if ( fp == NULL )
{
log_printf("Save_char_obj: could not my_fopen file.");
perror( strsave );
send_to_char( "Through some wierd game error, your character did not save.\n\r", ch);
open_reserve();
pop_call();
return;
}
if (logfp) /* if the logfile is opened correctly */
{
fprintf(logfp, "Removed old backup and opened a new tempfile successfully.\n");
}
{
fwrite_char( ch, fp );
if (logfp)
{
fprintf(logfp,"Wrote character information successfully. (fwrite_char)\n");
}
if (ch->pcdata->corpse && get_room_index(ch->pcdata->corpse_room))
{
obj_to_char(ch->pcdata->corpse, ch);
}
if (ch->pcdata->cart && get_room_index(ch->pcdata->cart_room))
{
obj_to_char(ch->pcdata->cart, ch);
}
if (ch->first_carrying != NULL)
{
if (logfp)
{
fprintf(logfp,"Starting to write ch->first_carrying (%p) to file.\n",ch->first_carrying);
}
fwrite_obj( ch, ch->first_carrying, fp, 0 );
}
if (ch->pcdata->corpse && get_room_index(ch->pcdata->corpse_room))
{
obj_to_room(ch->pcdata->corpse, ch->pcdata->corpse_room);
}
if (ch->pcdata->cart && get_room_index(ch->pcdata->cart_room))
{
obj_to_room(ch->pcdata->cart, ch->pcdata->cart_room);
}
for (pet = mud->f_pet ; pet ; pet = pet->next)
{
if (pet->ch->master == ch)
{
if (IS_SET(pet->ch->act, ACT_PET))
{
fwrite_mobile( pet->ch, fp );
}
}
}
fprintf( fp, "#END %s\n", ch->name );
if (logfp)
{
fprintf(logfp,"Save successfull\n");
}
}
if (ftell(fp) < (long)100)
{
my_fclose( fp );
send_to_char("Oops, file system full! tell one of the Gods!\n\r",ch);
log_string("File system full!!!\n\r");
}
else
{
my_fclose( fp );
fp = my_fopen( strtemp, "r",FALSE ) ;
if (!is_valid_file(ch, fp))
{
my_fclose( fp );
log_printf("SAVE not valid for %s", ch->name );
log_printf("Filesystem unstable, while saving %s", strtemp);
send_to_char( "The file system has become unstable. Please inform the Gods.\n\r", ch);
remove( strtemp );
}
else
{
my_fclose( fp );
if (remove(strsave) != 0)
{
if (errno != ENOENT)
{
log_printf("save_char_obj: (2nd) could not remove %s.", strsave);
print_errno(errno);
}
}
if (rename( strtemp, strsave ) != 0)
{
log_printf("Could not rename %s to %s.", strtemp, strsave);
print_errno(errno);
}
}
}
if (logfp)
{
fprintf(logfp,"All done right.\n");
fflush(logfp);
my_fclose(logfp);
remove( logfile );
}
open_reserve();
ch->pcdata->last_saved = mud->current_time;
// add account saving - Kregor
if (IS_DESC && ch->desc->account)
save_account(ch->desc);
/* restore char to proper room if in NO_SAVE room */
if (ch->in_room != troom)
{
char_from_room(ch);
char_to_room(ch, troom->vnum, FALSE);
}
pop_call();
return;
}
void fix_object_bits(CHAR_DATA *ch, OBJ_DATA *obj)
{
push_call("fix_object_bits(%p,%p)",ch,obj);
while (obj != NULL)
{
if (obj->first_content != NULL)
{
fix_object_bits(ch, obj->first_content);
}
if (!IS_SET(obj->extra_flags, ITEM_MODIFIED))
{
obj = obj->next_content;
continue;
}
if (IS_SET(obj->pIndexData->extra_flags, ITEM_MAGIC)
&& !IS_SET(obj->extra_flags,ITEM_MAGIC))
{
SET_BIT(obj->extra_flags,ITEM_MAGIC);
}
if (IS_SET(obj->pIndexData->extra_flags, ITEM_EVIL)
&& !IS_SET(obj->extra_flags, ITEM_EVIL))
{
SET_BIT(obj->extra_flags,ITEM_EVIL);
}
if (IS_SET(obj->pIndexData->extra_flags, ITEM_CHAOTIC)
&& !IS_SET(obj->extra_flags, ITEM_CHAOTIC))
{
SET_BIT(obj->extra_flags,ITEM_CHAOTIC);
}
if (IS_SET(obj->pIndexData->extra_flags, ITEM_LAWFUL)
&& !IS_SET(obj->extra_flags, ITEM_LAWFUL))
{
SET_BIT(obj->extra_flags,ITEM_LAWFUL);
}
if (IS_SET(obj->pIndexData->extra_flags, ITEM_UNCONCERNED)
&& !IS_SET(obj->extra_flags, ITEM_UNCONCERNED))
{
SET_BIT(obj->extra_flags,ITEM_UNCONCERNED);
}
if (IS_SET(obj->pIndexData->extra_flags,ITEM_GOOD)
&& !IS_SET(obj->extra_flags,ITEM_GOOD))
{
SET_BIT(obj->extra_flags,ITEM_GOOD);
}
if (IS_SET(obj->pIndexData->extra_flags,ITEM_NEUTRAL)
&& !IS_SET(obj->extra_flags,ITEM_NEUTRAL))
{
SET_BIT(obj->extra_flags, ITEM_NEUTRAL);
}
if (IS_SET(obj->pIndexData->extra_flags, ITEM_INVENTORY)
&& !IS_SET(obj->extra_flags,ITEM_INVENTORY))
{
SET_BIT(obj->extra_flags,ITEM_INVENTORY);
}
obj = obj->next_content;
}
pop_call();
return;
}
void fwrite_char( CHAR_DATA *ch, FILE *fp )
{
AFFECT_DATA *paf;
DISEASE_DATA *dis;
CRIME_DATA *pcr;
bool IS_DESC;
int sn;
int cnt;
push_call("fwrite_char(%p,%p)",ch,fp);
IS_DESC = is_desc_valid( ch );
fprintf( fp, "#PLAYER\n");
fprintf( fp, "Version %d\n", PLAYER_VERSION);
fprintf( fp, "Login %s~\n", ch->pcdata->host);
fprintf( fp, "Player %s~\n", ch->pcdata->account);
fprintf( fp, "S_Descr %s~\n", ch->short_descr);
fprintf( fp, "L_Descr %s~\n", ch->long_descr);
fprintf( fp, "E_Descr %s~\n", fixer(ch->description));
if (ch->pcdata->bio && ch->pcdata->bio[0] != '\0')
{
fprintf( fp, "Bio %s~\n", fixer(ch->pcdata->bio));
}
if (ch->pcdata->adjective && ch->pcdata->adjective[0] != '\0')
{
fprintf( fp, "Adject %s~\n", fixer(ch->pcdata->adjective));
}
if (ch->pcdata->first_record)
{
for (pcr = ch->pcdata->first_record ; pcr ; pcr = pcr->next)
{
fprintf( fp, "Crime_Data\n");
fprintf( fp, "%s~\n", fixer(pcr->crime_record));
fprintf( fp, "%s~\n", pcr->arrester);
fprintf( fp, "%ld\n", pcr->date);
fprintf( fp, "%d\n", pcr->level);
fprintf( fp, "%d\n", pcr->jailtime);
fprintf( fp, "%d\n", pcr->released);
fprintf( fp, "%s~\n", pcr->releaser);
}
}
fprintf( fp, "Level %d\n", ch->level );
fprintf( fp, "LostLevel %d\n", ch->lost_levels );
fprintf( fp, "Sex " );
break_bits( fp, ch->sex, "SEX_", TRUE);
fprintf( fp, "\n" );
fprintf( fp, "Class ");
break_bits( fp, ch->class, "CLASS_", TRUE);
fprintf( fp, "\n" );
fprintf( fp, "Race " );
break_bits( fp, ch->race, "RACE_", TRUE);
fprintf( fp, "\n" );
fprintf( fp, "Size " );
break_bits( fp, ch->size, "SIZE_", TRUE);
fprintf( fp, "\n" );
fprintf( fp, "Height %d\n", ch->height );
fprintf( fp, "Weight %d\n", ch->weight );
if (get_room_index(ch->pcdata->was_in_room) && IS_SET(ch->in_room->room_flags, ROOM_NO_SAVE))
{
fprintf( fp, "Room %u\n", ch->pcdata->was_in_room);
}
else
{
fprintf( fp, "Room %u\n", ch->in_room->vnum);
}
if (ch->pcdata->corpse)
{
fprintf( fp, "C_Room %u\n", ch->pcdata->corpse_room );
}
if (ch->pcdata->cart)
{
fprintf( fp, "CartRoom %u\n", ch->pcdata->cart_room );
}
fprintf( fp, "LastRoom %d\n", ch->pcdata->last_real_room );
fprintf( fp, "Language %d\n", ch->language );
fprintf( fp, "Speak %d\n", ch->speak );
for(cnt = 0 ; cnt < MAX_DOMAIN ; cnt++)
{
if (!ch->pcdata->domain[cnt])
continue;
fprintf (fp, "Domains ");
break_bits( fp, cnt, "DOMAIN_", TRUE);
fprintf( fp, " 1\n" );
}
fprintf( fp, "Created %d\n", ch->pcdata->created );
fprintf( fp, "Played %d\n", ch->pcdata->played );
fprintf( fp, "K_Played %d\n", ch->pcdata->killer_played );
fprintf( fp, "O_Played %d\n", ch->pcdata->outcast_played );
fprintf( fp, "HpMaMv %d %d %d %d %d %d\n", ch->hit, ch->max_hit, 0, 0, ch->move, ch->max_move );
for (cnt = 0 ; cnt < MAX_CLASS ; cnt++)
{
if (ch->mana[cnt] > 0)
{
fprintf( fp, "Mana " );
break_bits( fp, cnt, "CLASS_", TRUE);
fprintf( fp, " %d\n", ch->mana[cnt] );
}
}
for (cnt = 0 ; cnt < MAX_CLASS ; cnt++)
{
if (ch->max_mana[cnt] > 0)
{
fprintf( fp, "MaxMana " );
break_bits( fp, cnt, "CLASS_", TRUE);
fprintf( fp, " %d\n", ch->max_mana[cnt] );
}
}
fprintf( fp, "Gold %d\n", ch->gold );
fprintf( fp, "Nonlethal %d\n", ch->nonlethal );
fprintf( fp, "Bank %d\n", ch->pcdata->bank );
fprintf( fp, "Exp %d\n", ch->pcdata->exp );
fprintf( fp, "Ansi %d\n", ch->pcdata->ansi );
fprintf( fp, "Vt100 %d\n", ch->pcdata->vt100 ? 2 : 0 );
fprintf( fp, "Act %lld\n", ch->act);
fprintf( fp, "Affects1 " );
break_bits( fp, ch->affected_by, "AFF_", FALSE);
fprintf( fp, "\n" );
fprintf( fp, "Affects2 " );
break_bits( fp, ch->affected2_by, "AFF2_", FALSE);
fprintf( fp, "\n" );
fprintf( fp, "Practice %d\n", ch->pcdata->practice );
fprintf( fp, "Statpts %d\n", ch->pcdata->stat_pts );
fprintf( fp, "Featpts %d\n", ch->pcdata->feat_pts );
fprintf( fp, "SpellBns %d\n", ch->pcdata->bonus_spells);
for (cnt = 0 ; cnt < MAX_CLASS ; cnt++)
{
if (ch->pcdata->bonus_feat[cnt] > 0)
{
fprintf( fp, "FeatBonus " );
break_bits( fp, cnt, "CLASS_", TRUE);
fprintf( fp, " %d\n", ch->pcdata->bonus_feat[cnt] );
}
}
fprintf( fp, "Align %d\n", ch->alignment );
fprintf( fp, "Ethos %d\n", ch->ethos );
fprintf( fp, "Function %d\n", ch->pcdata->functions );
fprintf( fp, "Channel %d\n", ch->pcdata->channel );
if (ch->pcdata->clan && ch->pcdata->clan_name[0] != '\0')
{
fprintf( fp, "ClanName %s~\n", ch->pcdata->clan_name );
}
if (ch->pcdata->clan_pledge[0] != '\0')
{
fprintf( fp, "ClanPled %s~\n", ch->pcdata->clan_pledge );
}
if (ch->pcdata->clan_position != 0)
{
fprintf( fp, "ClanPosi %d\n", ch->pcdata->clan_position);
}
if (ch->pcdata->last_connect != mud->current_time)
{
fprintf( fp, "LastTime %d\n", (int) mud->current_time );
}
else
{
fprintf( fp, "LastTime %ld\n", ch->pcdata->last_time );
}
fprintf( fp, "Playtime %ld\n", (int) mud->current_time - ch->pcdata->last_connect);
fprintf( fp, "Jailtime %ld\n", ch->pcdata->jailtime );
fprintf( fp, "Jaildate %d\n", ch->pcdata->jaildate );
fprintf( fp, "MailAddy %s~\n", ch->pcdata->mail_address );
fprintf( fp, "HtmlAddy %s~\n", ch->pcdata->html_address );
if (ch->pcdata->password != 0)
{
fprintf( fp, "Psw %lld\n", ch->pcdata->password);
}
else
{
fprintf( fp, "Password %s~\n", ch->pcdata->pwd );
}
fprintf( fp, "Bamfin %s~\n", ch->pcdata->bamfin );
fprintf( fp, "Bamfout %s~\n", ch->pcdata->bamfout );
fprintf( fp, "Title %s~\n", ch->pcdata->title );
fprintf( fp, "AttrPerm %d %d %d %d %d %d\n", ch->perm_str, ch->perm_int, ch->perm_wis, ch->perm_dex, ch->perm_con, ch->perm_cha);
fprintf( fp, "AttrMod %d %d %d %d %d %d\n", ch->mod_str, ch->mod_int, ch->mod_wis, ch->mod_dex, ch->mod_con, ch->mod_cha );
fprintf( fp, "DrFuThAi %d %d %d %d\n", ch->pcdata->condition[0], ch->pcdata->condition[1], ch->pcdata->condition[2], ch->pcdata->condition[3]);
for (cnt = 0 ; cnt < MAX_CLASS ; cnt++)
{
if (ch->mclass[cnt] > 0)
{
fprintf( fp, "Mclass " );
break_bits( fp, cnt, "CLASS_", TRUE);
fprintf( fp, " %d\n", ch->mclass[cnt] );
}
}
for (cnt = 0 ; cnt < MAX_PVNUM ; cnt++)
{
if (ch->pcdata->greeted[cnt])
fprintf( fp, "Greeted %d %d\n", cnt, ch->pcdata->greeted[cnt] );
}
for (sn = 0 ; *skill_table[sn].name != '\0' ; sn++)
{
if (skill_table[sn].skilltype != FSKILL_NONE && ch->learned[sn] > 0)
{
fprintf( fp, "Skill %d '%s'\n", ch->learned[sn], skill_table[sn].name );
}
}
for (sn = 0 ; *skill_table[sn].name != '\0' ; sn++)
{
if (skill_table[sn].skilltype != FSKILL_NONE && ch->imbued[sn] > 0)
{
fprintf( fp, "Imbued %d '%s'\n", ch->imbued[sn], skill_table[sn].name );
}
}
for (cnt = 0 ; sn < MAX_APPLY ; cnt++)
{
if (ch->absorption[cnt] > 0)
{
fprintf( fp, "Absorb %d", ch->absorption[sn] );
break_bits( fp, cnt, "APPLY_", TRUE);
fprintf( fp, " %d\n", ch->absorption[cnt] );
}
}
for (sn = 0 ; *skill_table[sn].name != '\0' ; sn++)
{
if (skill_table[sn].skilltype != FSKILL_NONE && ch->uses[sn] > 0)
{
fprintf( fp, "Uses %d '%s'\n", ch->uses[sn], skill_table[sn].name );
}
}
for (cnt = 0 ; cnt < RACE_ENEMY_MAX ; cnt++)
{
if (ch->pcdata->race_enemy[cnt] > 0)
{
fprintf( fp, "RaceFoe %d %d\n", cnt, ch->pcdata->race_enemy[cnt] );
}
}
for (cnt = 0 ; cnt < MAX_VNUM ; cnt++)
{
if (ch->pcdata->found_dir[cnt] > 0)
{
fprintf( fp, "FoundDir %d %d\n", cnt, ch->pcdata->found_dir[cnt] );
}
}
for (sn = 0 ; *skill_table[sn].name != '\0' ; sn++)
{
if (skill_table[sn].skilltype != FSKILL_NONE && ch->pcdata->prepared[sn] > 0)
{
fprintf( fp, "Prepd %d '%s'\n", ch->pcdata->prepared[sn], skill_table[sn].name );
}
}
for (sn = 0 ; sn < MAX_AREA ; sn++)
{
if (ch->pcdata->quest[sn])
{
fprintf(fp, "Qstb %d %3d ", MAX_QUEST_BYTES, sn);
for (cnt = 0 ; cnt < MAX_QUEST_BYTES ; cnt++)
{
fprintf(fp, "%d ", ch->pcdata->quest[sn][cnt]);
}
fprintf(fp, "\n");
}
}
for (cnt = 0 ; cnt < MAX_VNUM ; cnt++)
{
if (ch->pcdata->theft_grudge[cnt] > 0)
{
fprintf( fp, "GrudgeTh %d %d\n", cnt, ch->pcdata->theft_grudge[cnt] );
}
}
for (cnt = 0 ; cnt < MAX_VNUM ; cnt++)
{
if (ch->pcdata->murder_grudge[cnt] > 0)
{
fprintf( fp, "GrudgeMd %d %d\n", cnt, ch->pcdata->murder_grudge[cnt] );
}
}
for (cnt = 0 ; cnt <= ch->level ; cnt++)
{
if (ch->pcdata->class_level[cnt] > 0)
{
fprintf( fp, "ClassLvl %d ", cnt );
break_bits( fp, ch->pcdata->class_level[cnt], "CLASS_", TRUE);
fprintf( fp, " \n" );
}
}
for (cnt = 0 ; cnt <= ch->level ; cnt++)
{
if (ch->pcdata->hit_level[cnt] > 0)
{
fprintf( fp, "HPLevel %d %d\n", cnt, ch->pcdata->hit_level[cnt] );
}
}
for (cnt = 0 ; cnt <= ch->level ; cnt++)
{
if (ch->pcdata->move_level[cnt] > 0)
{
fprintf( fp, "MvLevel %d %d\n", cnt, ch->pcdata->move_level[cnt] );
}
}
for (cnt = 0 ; cnt <= ch->level ; cnt++)
{
if (ch->pcdata->pract_level[cnt] > 0)
{
fprintf( fp, "PractLvl %d %d\n", cnt, ch->pcdata->pract_level[cnt] );
}
}
if (!IS_IMMORTAL(ch))
{
for (cnt = 0 ; cnt <= ch->level ; cnt++)
{
for (sn = 0 ; *skill_table[sn].name != '\0' ; sn++)
{
if (skill_table[sn].name != NULL && ch->pcdata->skill_level[cnt][sn] > 0)
{
fprintf( fp, "SkillLvl %d %d '%s'\n", cnt, ch->pcdata->skill_level[cnt][sn], skill_table[sn].name );
}
}
}
}
fprintf( fp, "Speed %d\n", ch->speed);
fprintf( fp, "Prev_hrs %d\n", ch->pcdata->previous_hours);
fprintf( fp, "Tactical %d\n", ch->pcdata->tactical_mode);
fprintf( fp, "Compass %d\n", (int) ch->pcdata->compass_width);
if (IS_IMMORTAL(ch))
{
if (ch->pcdata->a_range_lo && ch->pcdata->a_range_hi)
{
fprintf( fp, "A_Range %d %d\n", ch->pcdata->a_range_lo, ch->pcdata->a_range_hi);
}
}
fprintf( fp, "Pvnum %d\n", ch->pcdata->pvnum);
fprintf( fp, "Vt100_T %d\n", ch->pcdata->vt100_type );
fprintf( fp, "Vt100_F %d\n", ch->pcdata->vt100_flags );
fprintf( fp, "Portsize %d\n", ch->pcdata->port_size );
fprintf( fp, "Prompt %s~\n", ch->pcdata->prompt_layout);
fprintf( fp, "Spam %d\n", ch->pcdata->spam );
fprintf( fp, "Clock %d\n", ch->pcdata->clock);
fprintf( fp, "Recall %d\n", ch->pcdata->recall);
fprintf( fp, "Reputation %d\n", ch->pcdata->reputation);
for (cnt = 0 ; cnt <= MAX_WAYPOINT ; cnt++)
{
if (ch->pcdata->waypoint[cnt])
fprintf( fp, "Waypoint %d %d\n", cnt, ch->pcdata->waypoint[cnt] );
}
fprintf( fp, "Death %d\n", ch->pcdata->death_room);
fprintf( fp, "Whichgod %d\n", ch->god);
fprintf( fp, "Blocking %s~\n", ch->pcdata->block_list);
fprintf( fp, "AutoComm %s~\n", ch->pcdata->auto_command);
fprintf( fp, "AutoMode %d\n", ch->pcdata->auto_flags);
fprintf( fp, "AuthedBy %s~\n", ch->pcdata->authed_by);
fprintf( fp, "LastNote %d\n", ch->pcdata->last_note );
for (cnt = 0 ; cnt < MAX_TOPIC ; cnt++)
{
fprintf( fp, "Topic %d %d\n", cnt, ch->pcdata->topic_stamp[cnt]);
}
for (cnt = 0 ; cnt < COLOR_MAX ; cnt++)
{
fprintf( fp, "Color %2d %2d\n", cnt, ch->pcdata->color[cnt]);
}
for (cnt = 0 ; cnt < MAX_ALIAS ; cnt++)
{
if (ch->pcdata->alias[cnt][0]!='\0')
{
fprintf( fp, "Alias %s~%s~\n", ch->pcdata->alias_c[cnt], ch->pcdata->alias[cnt]);
}
}
for (paf = ch->first_affect ; paf != NULL ; paf = paf->next)
{
if (!valid_skill(paf->type))
{
log_printf("save_char_obj: bad affect type: %d", paf->type);
continue;
}
fprintf(fp, "AffectData '%s' %d %d %d %d %lld %d %s\n", skill_table[paf->type].name, paf->duration, paf->modifier, paf->location, paf->bittype, paf->bitvector, paf->level, paf->caster);
}
for (dis = ch->first_disease ; dis != NULL ; dis = dis->next)
{
if (dis->type < 0 || dis->type >= MAX_DISEASE)
{
log_printf("save_char_obj: bad disease type: %d", dis->type);
continue;
}
fprintf(fp, "DiseaseData %d %d %d %d\n",
dis->type, dis->incubation, dis->dc, dis->saves);
}
fprintf( fp, "Critical %d\n", ch->critical_hit_by );
if (ch->poison != NULL)
{
fwrite_poison_data( ch->poison, fp );
}
fprintf( fp, "PK_ATTACKS %d\n", MAX_PK_ATTACKS );
for (cnt = 0 ; cnt < MAX_PK_ATTACKS ; cnt++)
{
fprintf( fp, "%d %d %s~\n", ch->pcdata->last_pk_attack_time[cnt], ch->pcdata->last_pk_attack_pvnum[cnt], ch->pcdata->last_pk_attack_name[cnt]);
}
fprintf( fp, "End\n\n" );
pop_call();
return;
}
void load_clan_pit( FILE *fp )
{
OBJ_INDEX_DATA *pit;
char letter, loop, *word;
push_call("fread_clanpit(void)");
word = fread_word(fp);
pit = obj_index[atol(word)];
rgObjNest[0] = pit->first_instance;
for (loop = TRUE ; loop ; )
{
letter = fread_letter(fp);
if (letter != '#')
{
log_printf("fread_clan_pit: # not found. Word was '%c%s'", letter, fread_word(fp));
break;
}
word = fread_word(fp);
switch (word[0])
{
case 'O':
fread_obj(NULL, fp);
break;
case 'E':
loop = FALSE;
break;
default:
log_printf("fread_clan_pit: bad section.");
loop = FALSE;
break;
}
}
pop_call();
return;
}
void save_clan_pit(CLAN_DATA *clan, FILE *fp )
{
ROOM_INDEX_DATA *location;
OBJ_DATA *pit;
push_call("save_clan_pits(void)");
if ((location = get_room_index(clan->store)) == NULL)
{
pop_call();
return;
}
for (pit = location->first_content ; pit ; pit = pit->next_content)
{
if (pit->pIndexData->creator_pvnum == clan->founder_pvnum && pit->item_type == ITEM_CONTAINER)
{
break;
}
}
if (pit == NULL)
{
pop_call();
return;
}
fprintf( fp, "#PIT %d\n\n", pit->pIndexData->vnum);
fwrite_obj(NULL, pit->first_content, fp, 1);
fprintf(fp, "#END\n");
pop_call();
return;
}
/*
Write an object and its first_content.
Increased speed, no more naughty recursion, objects in unsaved
containers go to inventory - Scandum april 2002
*/
void fwrite_obj( CHAR_DATA *ch, OBJ_DATA *obj, FILE *fp, char iNest )
{
AFFECT_DATA *paf;
DISEASE_DATA *dis;
int sn;
push_call("fwrite_obj(%p,%p,%p,%p)",ch,obj,fp,iNest);
while (obj)
{
if (obj->reset || IS_SET(obj->extra_flags, ITEM_NOT_VALID))
{
if (obj->first_content != NULL)
{
fwrite_obj(ch, obj->first_content, fp, iNest);
}
obj = obj->next_content;
continue;
}
else
{
fprintf( fp, "#OBJECT\n" );
if (iNest)
{
fprintf(fp, "Nest %d\n", iNest);
}
else if (obj->wear_loc != WEAR_NONE)
{
fprintf(fp, "WearLoc %s\n", broken_bits(obj->wear_loc, "WEAR_", TRUE));
}
if (ch == NULL && iNest == 0)
{
fprintf(fp, "InRoom %d\n", obj->in_room->vnum);
}
/*
if (!IS_SET(obj->extra_flags, ITEM_MODIFIED) && obj->first_content == NULL
&& obj->item_type != ITEM_CONTAINER && obj->item_type != ITEM_SHEATH
&& obj->item_type != ITEM_QUIVER && obj->item_type != ITEM_CART && obj->item_type != ITEM_SPELLPOUCH
&& obj->hit_points == obj->pIndexData->hit_points )
{
fprintf(fp, "BasicVnum %d\n", obj->pIndexData->vnum);
}
else*/
{
/*
Compact, latest mode for non-basic objects
*/
fprintf(fp, "Compact\n");
fprintf(fp, "%d\n", obj->pIndexData->vnum);
break_bits( fp, obj->extra_flags, "FLAG_", FALSE);
fprintf( fp, " %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
obj->wear_flags,
obj->item_type,
obj->weight,
obj->level,
obj->timer,
obj->cost,
obj->owned_by,
obj->value[0],
obj->value[1],
obj->value[2],
obj->value[3],
obj->value[4],
obj->value[5],
obj->value[6],
obj->value[7],
obj->material,
obj->hit_points,
obj->size);
if (obj->obj_quest)
{
int cnt;
fprintf(fp, "%d ", MAX_QUEST_BYTES);
for (cnt = 0 ; cnt < MAX_QUEST_BYTES ; cnt++)
{
fprintf(fp, "%d ", obj->obj_quest[cnt]);
}
fprintf(fp, "\n");
}
else
{
fprintf(fp, "0\n");
}
/*
* End of Compact mode, Emud only checks non basic objects - Scandum
*/
if (obj->name != obj->pIndexData->name)
{
fprintf(fp, "Name %s~\n", obj->name);
}
if (obj->short_descr != obj->pIndexData->short_descr)
{
fprintf(fp, "Short %s~\n", obj->short_descr);
}
if (obj->long_descr != obj->pIndexData->long_descr)
{
fprintf(fp, "Long %s~\n", obj->long_descr);
}
if (obj->description != obj->pIndexData->description)
{
fprintf(fp, "Desc %s~\n", obj->description);
}
if (obj->identified == TRUE)
fprintf( fp, "Identified %d\n", 1);
switch ( obj->item_type )
{
case ITEM_SPELLBOOK:
for (sn = 0 ; *skill_table[sn].name != '\0' ; sn++)
{
if (!is_spell(sn))
continue;
if (obj->scribed[sn] > 0)
fprintf( fp, "Scribed '%s'\n", skill_table[obj->scribed[sn]].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 );
}
break;
case ITEM_PIECE:
if (obj->value[3] > 0)
{
fprintf( fp, "Skill 3 '%s'\n", skill_table[obj->value[3]].name );
}
break;
case ITEM_COMPONENT:
if (obj->value[1] > 0)
{
fprintf( fp, "Uses %d\n", obj->value[0] );
}
if ( obj->value[2] > 0 )
{
fprintf( fp, "Poison %d\n", obj->value[1] );
}
if ( obj->value[3] > 0 )
{
fprintf( fp, "Herb %d\n", obj->value[2] );
}
break;
case ITEM_STAFF:
case ITEM_WAND:
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[3]].name );
}
if ( obj->value[5] > 0 )
{
fprintf( fp, "Spell 5 '%s'\n", skill_table[obj->value[3]].name );
}
if ( obj->value[6] > 0 )
{
fprintf( fp, "Spell 6 '%s'\n", skill_table[obj->value[3]].name );
}
break;
}
for (paf = obj->first_affect ; paf ; paf = paf->next )
{
if (!valid_skill(paf->type))
{
log_printf("fwrite_obj: Bad affect: %d", paf->type);
continue;
}
fprintf( fp, "AffectData '%s' %d %d %d %d %lld %d %s\n", skill_table[paf->type].name, paf->duration, paf->modifier, paf->location, paf->bittype, paf->bitvector, paf->level, paf->caster );
}
for (dis = obj->first_disease ; dis ; dis = dis->next )
{
if (dis->type < 0 || dis->type >= MAX_DISEASE)
{
log_printf("fwrite_obj: Bad disease: %d", dis->type);
continue;
}
fprintf(fp, "DiseaseData %d %d %d %d\n",
dis->type, dis->incubation, dis->dc, dis->saves);
}
if (obj->poison != NULL)
{
fwrite_poison_data( obj->poison, fp );
}
}
fprintf( fp, "RefKey %lld\nEnd\n\n", obj->obj_ref_key);
}
if (obj->first_content != NULL)
{
fwrite_obj( ch, obj->first_content, fp, iNest + 1 );
}
obj = obj->next_content;
}
pop_call();
return;
}
/*
* Borrowed from AFKMud's pet saving code - Kregor 7/13/07
* This will write one mobile structure to file --Shaddai
* Edited by Tarl 5 May 2002 to allow pets to load equipment.
*/
void fwrite_mobile( CHAR_DATA * mob, FILE * fp )
{
AFFECT_DATA *paf;
DISEASE_DATA *dis;
OBJ_DATA *obj;
int cnt, sn;
push_call("fwrite_mobile(%p,%p)",mob,fp);
if( !IS_NPC( mob ) || !fp )
{
pop_call();
return;
}
fprintf( fp, "#MOBILE\n" );
fprintf( fp, "Vnum %d\n", mob->pIndexData->vnum );
fprintf( fp, "Level %d\n", mob->level );
fprintf( fp, "LostLevel %d\n", mob->lost_levels );
fprintf( fp, "Race " );
break_bits( fp, mob->race, "RACE_", TRUE);
fprintf( fp, "\n" );
fprintf( fp, "Sex " );
break_bits( fp, mob->sex, "SEX_", TRUE);
fprintf( fp, "\n" );
if( mob->in_room )
fprintf( fp, "Room %d\n", mob->in_room->vnum );
else
fprintf( fp, "Room %d\n", ROOM_VNUM_TEMPLE );
if( mob->name && mob->pIndexData->player_name && strcasecmp( mob->name, mob->pIndexData->player_name ) )
fprintf( fp, "Name %s~\n", mob->name );
if( mob->short_descr && mob->pIndexData->short_descr && strcasecmp( mob->short_descr, mob->pIndexData->short_descr ) )
fprintf( fp, "Short %s~\n", mob->short_descr );
if( mob->long_descr && mob->pIndexData->long_descr && strcasecmp( mob->long_descr, mob->pIndexData->long_descr ) )
fprintf( fp, "Long %s~\n", mob->long_descr );
if( mob->description && mob->pIndexData->description && strcasecmp( mob->description, mob->pIndexData->description ) )
fprintf( fp, "Description %s~\n", fixer(mob->description) );
fprintf( fp, "Position %d\n", mob->position );
fprintf( fp, "Act " );
break_bits( fp, mob->act, "ACT_", FALSE);
fprintf( fp, "\n" );
fprintf( fp, "AffectedBy " );
break_bits( fp, mob->affected_by, "AFF_", FALSE);
fprintf( fp, "\n" );
fprintf( fp, "Affected2By %lld\n", mob->affected2_by );
fprintf( fp, "Armor %d\n", mob->armor );
fprintf( fp, "NatArmor %d\n", mob->nat_armor );
fprintf( fp, "AttrPerm %d %d %d %d %d %d\n", mob->perm_str, mob->perm_int, mob->perm_wis, mob->perm_dex, mob->perm_con, mob->perm_cha);
fprintf( fp, "AttrMod %d %d %d %d %d %d\n", mob->mod_str, mob->mod_int, mob->mod_wis, mob->mod_dex, mob->mod_con, mob->mod_cha );
fprintf( fp, "HpManaMove %d %d %d %d %d %d\n",
mob->hit, mob->max_hit, 0, 0, mob->move, mob->max_move );
for (cnt = 0 ; cnt < MAX_CLASS ; cnt++)
{
if (mob->mana[cnt] > 0)
{
fprintf( fp, "Mana " );
break_bits( fp, cnt, "CLASS_", TRUE);
fprintf( fp, " %d\n", mob->mana[cnt] );
}
}
for (cnt = 0 ; cnt < MAX_CLASS ; cnt++)
{
if (mob->max_mana[cnt] > 0)
{
fprintf( fp, "MaxMana " );
break_bits( fp, cnt, "CLASS_", TRUE);
fprintf( fp, " %d\n", mob->max_mana[cnt] );
}
}
fprintf( fp, "Nonlethal %d\n", mob->nonlethal );
for (paf = mob->first_affect ; paf != NULL ; paf = paf->next)
{
if (!valid_skill(paf->type))
{
log_printf("fwrite_mobile: bad affect type: %d", paf->type);
continue;
}
fprintf(fp, "AffectData '%s' %d %d %d %d %lld %d %s\n", skill_table[paf->type].name, paf->duration, paf->modifier, paf->location, paf->bittype, paf->bitvector, paf->level, paf->caster);
}
for (dis = mob->first_disease ; dis != NULL ; dis = dis->next)
{
if (dis->type < 0 || dis->type >= MAX_DISEASE)
{
log_printf("fwrite_mobile: bad disease type: %d", dis->type);
continue;
}
fprintf(fp, "DiseaseData %d %d %d %d\n",
dis->type, dis->incubation, dis->dc, dis->saves);
}
for (cnt = 0 ; cnt < MAX_CLASS ; cnt++)
{
if (mob->mclass[cnt] > 0)
{
fprintf( fp, "Mclass " );
break_bits( fp, cnt, "CLASS_", TRUE);
fprintf( fp, " %d\n", mob->mclass[cnt] );
}
}
for (sn = 0 ; skill_table[sn].name != '\0' ; sn++)
{
if (mob->learned[sn] > 0)
{
fprintf( fp, "Skill %d '%s'\n", mob->learned[sn], skill_table[sn].name );
}
}
if( (obj = mob->first_carrying) != NULL )
{
fwrite_obj( mob, mob->first_carrying, fp, 0 );
}
fprintf( fp, "%s", "EndMobile\n\n" );
pop_call();
return;
}
/*
Load a char and inventory into a new ch structure.
*/
bool load_char_obj( DESCRIPTOR_DATA *d, char *name )
{
static PC_DATA pcdata_zero;
char strsave[MAX_INPUT_LENGTH];
OBJ_DATA *obj;
CHAR_DATA *ch, *mob;
AFFECT_DATA *paf;
FILE *fp;
bool found, loop;
sh_int cnt, lvl;
push_call("load_char_obj(%p,%p)",d,name);
if (name == NULL || *name == '\0')
{
pop_call();
return( FALSE );
}
ALLOCMEM(ch, CHAR_DATA, 1 );
clear_char( ch );
ALLOCMEM( ch->pcdata, PC_DATA, 1 );
*ch->pcdata = pcdata_zero;
d->character = ch;
ch->desc = d;
ch->name = STRALLOC(capitalize(name));
ch->short_descr = STRALLOC( "" );
ch->description = STRALLOC( "" );
ch->pcdata->bio = STRALLOC( "" );
ch->long_descr = STRALLOC( "" );
ch->pcdata->adjective = STRALLOC( "" );
ch->pcdata->pose = STRALLOC( "" );
ch->pcdata->disguise = STRALLOC( "" );
ch->pcdata->disguise_descr = STRALLOC( "" );
ch->pcdata->host = STRALLOC( "" );
ch->pcdata->mail_address = STRALLOC( "" );
ch->pcdata->html_address = STRALLOC( "" );
ch->pcdata->clan_name = STRALLOC( "" );
ch->pcdata->block_list = STRALLOC( "" );
ch->pcdata->title = STRALLOC( "" );
ch->pcdata->auto_command = STRALLOC( "" );
ch->pcdata->bamfin = STRALLOC( "" );
ch->pcdata->bamfout = STRALLOC( "" );
ch->pcdata->pwd = STRALLOC( "" );
ch->pcdata->practice = 0;
for (lvl = 0 ; lvl < MAX_LEVEL ; lvl++)
{
ch->pcdata->class_level[lvl] = 0;
ch->pcdata->hit_level[lvl] = 0;
ch->pcdata->move_level[lvl] = 0;
ch->pcdata->pract_level[lvl] = 0;
for (cnt = 0 ; skill_table[cnt].name != '\0' ; cnt++)
ch->pcdata->skill_level[lvl][cnt] = 0;
}
ch->pcdata->compass_width = 6;
if (d->descriptor != -999)
{
ch->act = PLR_AUTOEXIT|PLR_EXP_TO_LEVEL;
ch->pcdata->channel = CHANNEL_CHAT|CHANNEL_QUESTION;
ch->pcdata->condition[COND_THIRST] = 48;
ch->pcdata->condition[COND_FULL] = 48;
ch->pcdata->condition[COND_AIR] = get_curr_con(ch) * 2;
ch->pcdata->reputation = 10;
ch->pcdata->last_time = mud->current_time;
ch->pcdata->spam = SPAM_DICE_ROLLS;
ch->pcdata->tactical_mode = 6;
// add account in at player load - Kregor
if (d->account)
{
ch->pcdata->account = STRALLOC(d->account->player_name);
d->account->ch = ch;
}
ch->pcdata->edit_buf = STRDUPE(str_empty);
ch->pcdata->prompt_layout = STRALLOC( "{078}<$c$h{078}hp $c$m{078}m $c$v{078}mv $c$X{078}xp> <{178}$e{078}> ($c$l{078}) ($c$L{078}) {300}" );
ch->pcdata->subprompt = STRDUPE(str_empty);
ch->pcdata->tracking = NULL;
ch->desc->port_size = 4096;
ch->pcdata->port_size = 4096;
ch->pcdata->death_room = ROOM_VNUM_SCHOOL;
ch->pcdata->clan_pledge = STRDUPE(str_empty);
ch->pcdata->vt100_type = 8024;
ch->pcdata->vt100_flags = VT102_FAST|VT100_HIGHLIGHT|VT100_BOLD|VT100_BEEP|VT100_UNDERLINE|VT100_FLASH|VT100_REVERSE;
ch->pcdata->recall = ROOM_VNUM_SCHOOL;
ch->pcdata->scroll_buf[0] = '\0';
for (cnt = 0 ; cnt < COLOR_MAX ; cnt++)
{
ch->pcdata->color[cnt] = 7 + 8 * 10;
}
for (cnt = 0 ; cnt < MAX_PK_ATTACKS ; cnt++)
{
ch->pcdata->last_pk_attack_name[cnt] = STRDUPE(str_empty);
}
for (cnt = 0 ; cnt < MAX_WEAR ; cnt++)
{
ch->pcdata->tattoo[cnt] = STRDUPE(str_empty);
}
}
ch->pcdata->last_real_room = ROOM_VNUM_TEMPLE;
for (cnt = 0 ; cnt < MAX_ALIAS ; cnt++)
{
ch->pcdata->alias[cnt] = STRDUPE(str_empty);
ch->pcdata->alias_c[cnt] = STRDUPE(str_empty);
}
for (cnt = 0 ; cnt < 26 ; cnt++)
{
ch->pcdata->back_buf[cnt] = STRALLOC("\r");
}
found = FALSE;
close_reserve();
sprintf(strsave, "%s/%c/%s", PLAYER_DIR, tolower(name[0]), capitalize_name(name));
fp = my_fopen(strsave, "r" , TRUE);
if (fp != NULL)
{
int iNest;
for (iNest = 0 ; iNest < MAX_NEST ; iNest++)
{
rgObjNest[iNest] = NULL;
}
if (d->descriptor != -999 && d->descriptor != -998)
{
log_god_printf("Loading character file: %s D%d", name, d->descriptor);
}
if (!is_valid_file(ch, fp))
{
log_printf("Erasing invalid file: %s", name);
delete_player(ch);
pop_call();
return(load_char_obj(d, name));
}
found = TRUE;
loop = TRUE;
while (loop)
{
char letter;
char *word;
letter = fread_letter( fp );
if ( letter == '*' )
{
fread_to_eol( fp );
continue;
}
if ( letter != '#' )
{
log_printf("Load_char_obj: # not found. word was '%c%s'", letter, fread_word( fp ));
loop = FALSE;
}
word = fread_word( fp );
switch (word[0])
{
case 'O':
fread_obj(ch, fp);
break;
case 'P':
fread_char (ch, fp);
if (d->descriptor == -999)
{
loop = FALSE;
}
if (strcasecmp(ch->name, name))
{
log_printf("Incorrect name. #END on %s", name );
loop = FALSE;
}
break;
case 'M':
mob = NULL;
mob = fread_mobile( fp );
if( mob )
{
add_follower( mob, ch );
for (obj = mob->first_carrying ; obj ; obj = obj->next_content)
{
if (IS_WORN(obj))
{
for (paf = obj->first_affect ; paf ; paf = paf->next)
{
switch(paf->location)
{
case APPLY_SEX:
break;
default:
affect_modify(mob, paf, TRUE);
break;
}
}
}
}
for (paf = mob->first_affect ; paf ; paf = paf->next)
{
switch(paf->location)
{
case APPLY_SEX:
break;
default:
affect_modify(mob, paf, TRUE);
break;
}
}
}
break;
case 'E':
loop = FALSE;
break;
default:
log_printf("Load_char_obj: bad section.");
loop = FALSE;
break;
}
}
if (ch->pcdata->corpse_room)
{
for (obj = ch->first_carrying ; obj ; obj = obj->next_content)
{
if (obj->item_type == ITEM_CORPSE_PC)
{
ch->pcdata->corpse = obj;
}
}
}
if (ch->pcdata->cart_room)
{
for (obj = ch->first_carrying ; obj ; obj = obj->next_content)
{
if (obj->item_type == ITEM_CART)
{
ch->pcdata->cart = obj;
}
}
}
if (fp != NULL)
{
my_fclose( fp );
}
}
open_reserve();
/*
Fix up a few flags - Chaos 10/1/95
*/
if (d->descriptor == -999)
{
pop_call();
return found;
}
ch->pcdata->last_saved = mud->current_time;
if (ch->level >= MAX_LEVEL)
{
if (!IS_GOD(ch))
{
SET_BIT(pvnum_index[ch->pcdata->pvnum]->flags, PVNUM_DENIED);
}
else
{
REMOVE_BIT(pvnum_index[ch->pcdata->pvnum]->flags, PVNUM_DENIED);
}
}
if (!is_string(ch->pcdata->account))
{
if (!d->account)
{
log_printf("load_char_obj: character loading outside an account!");
}
else
{
log_printf("load_char_obj: character with no account. Fixing...");
ch->pcdata->account = STRALLOC(d->account->player_name);
}
}
if (ch->size <= 0 || ch->size > 9)
ch->size = race_table[ch->race].size;
if (ch->pcdata->reputation <= 0)
ch->pcdata->reputation = 10;
/*
Check for illegal items, fix bits - Order 7/3/1995
*/
fix_object_bits(ch, ch->first_carrying);
char_reset( ch );
pop_call();
return found;
}
/*
Read in a char.
*/
void fread_char( CHAR_DATA *ch, FILE *fp )
{
char *word;
char *line;
bool fMatch;
sh_int cnt, tst;
int x1, x2, x3, x4, x5, x6;
push_call("fread_char(%p,%p)",ch,fp);
if (ch == NULL)
{
log_printf("Attempt to load a NULL character.");
pop_call();
return;
}
if (ch->pcdata == NULL)
{
log_printf("Attempting to load a player with no pcdata!\n");
pop_call();
return;
}
for ( ; ; )
{
word = feof( fp ) ? "End" : fread_word( fp );
fMatch = FALSE;
switch (UPPER(word[0]))
{
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;
case 'A':
NKEY("Account", ch->pcdata->bank, fread_number(fp));
NKEY("Act", ch->act, fread_number(fp));
SKEY("Adject", ch->pcdata->adjective, fread_string(fp));
NKEY("Ansi", ch->pcdata->ansi, fread_number(fp));
NKEY("Affects1", ch->affected_by, fread_number(fp));
NKEY("Affects2", ch->affected2_by, fread_number(fp));
NKEY("Align", ch->alignment, fread_number(fp));
NKEY("AutoMode", ch->pcdata->auto_flags, fread_number(fp));
SKEY("AutoComm", ch->pcdata->auto_command, fread_string(fp));
SKEY("AuthedBy", ch->pcdata->auto_command, fread_string(fp));
AKEY("Absorb", ch->absorption, fread_number(fp));
/* Here to get rid of an old tag */
if ( !strcasecmp( word, "AddLangs" ) )
{
fread_number( fp );
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "AcMaxMana" ) )
{
fread_number( fp );
fread_number( fp );
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "Actuals" ) )
{
fread_number( fp );
fread_number( fp );
fread_number( fp );
fMatch = TRUE;
break;
}
if (!strcmp(word, "AffectData"))
{
AFFECT_DATA paf;
int sn;
sn = skill_lookup(fread_word(fp));
if (sn < 0)
{
log_string("fread_obj: unknown skill.");
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_word( fp );
}
else
{
paf.type = sn;
paf.duration = fread_number( fp );
paf.modifier = fread_number( fp );
paf.location = fread_number( fp );
paf.bittype = fread_number( fp );
paf.bitvector = fread_number( fp );
paf.level = fread_number( fp );
paf.caster = STRALLOC(fread_word( fp ));
affect_to_char(NULL, ch, &paf);
}
fMatch = TRUE;
break;
}
if (!strcmp(word, "AffectData1"))
{
AFFECT_DATA paf;
int sn;
sn = skill_lookup(fread_word(fp));
if (sn < 0)
{
log_string("fread_obj: unknown skill.");
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_word( fp );
}
else
{
paf.type = sn;
paf.duration = fread_number( fp );
paf.modifier = fread_number( fp );
paf.location = fread_number( fp );
paf.bittype = fread_number( fp );
paf.bitvector = fread_number( fp );
paf.level = fread_number( fp );
paf.caster = STRALLOC(fread_word( fp ));
affect_to_char(NULL, ch, &paf);
}
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "AttrMod" ) )
{
line = fread_line( fp );
x1=x2=x3=x4=x5=x6=0;
sscanf( line, "%d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6 );
ch->mod_str = x1;
ch->mod_int = x2;
ch->mod_wis = x3;
ch->mod_dex = x4;
ch->mod_con = x5;
ch->mod_cha = x6;
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "AttrPerm" ) )
{
line = fread_line( fp );
x1=x2=x3=x4=x5=x6=13;
sscanf( line, "%d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6 );
ch->perm_str = x1;
ch->perm_int = x2;
ch->perm_wis = x3;
ch->perm_dex = x4;
ch->perm_con = x5;
ch->perm_cha = x6;
fMatch = TRUE;
break;
}
if ( !strcmp( word, "Alias" ) )
{
tst=0;
for (cnt = 0 ; cnt < MAX_ALIAS && tst == 0 ; cnt++)
{
if (ch->pcdata->alias[cnt][0]=='\0')
{
tst=1;
STRFREE (ch->pcdata->alias[cnt] );
STRFREE (ch->pcdata->alias_c[cnt] );
ch->pcdata->alias_c[cnt]=fread_string( fp ) ;
ch->pcdata->alias[cnt]=fread_string( fp ) ;
}
}
if (tst==0)
{
char *ptx1;
ptx1 = fread_string( fp );
STRFREE (ptx1 );
ptx1 = fread_string( fp );
STRFREE (ptx1 );
}
fMatch = TRUE;
break;
}
if (!strcmp( word, "A_Range" ) )
{
ch->pcdata->a_range_lo = fread_number(fp);
ch->pcdata->a_range_hi = fread_number(fp);
fMatch = TRUE;
break;
}
break;
case 'B':
if (!strcasecmp(word, "BAB"))
{
fread_number(fp);
fMatch = TRUE;
break;
}
NKEY("Bank", ch->pcdata->bank, fread_number(fp));
SKEY("Bamfin", ch->pcdata->bamfin, fread_string(fp));
SKEY("Bamfout", ch->pcdata->bamfout, fread_string(fp));
SKEY("Blocking", ch->pcdata->block_list, fread_string(fp));
SKEY("Bio", ch->pcdata->bio, fread_string(fp));
break;
case 'C':
AKEY("Color", ch->pcdata->color, fread_number(fp));
AKEY("Colorc", ch->pcdata->color, fread_number(fp));
SKEY("ClanName", ch->pcdata->clan_name, fread_string(fp));
SKEY("ClanPled", ch->pcdata->clan_pledge, fread_string(fp));
NKEY("Channel", ch->pcdata->channel, fread_number(fp));
NKEY("ClanPosi", ch->pcdata->clan_position,fread_number(fp));
NKEY("Class", ch->class, fread_number(fp));
NKEY("Critical", ch->critical_hit_by, fread_number(fp));
NKEY("Clock", ch->pcdata->clock, fread_number(fp));
NKEY("Compass", ch->pcdata->compass_width,fread_number(fp));
NKEY("Created", ch->pcdata->created, fread_number(fp));
AKEY("ClassLvl", ch->pcdata->class_level, fread_number(fp));
NKEY("CartRoom", ch->pcdata->cart_room, fread_number(fp));
NKEY("C_Room", ch->pcdata->corpse_room, fread_number(fp));
if (!strcasecmp(word, "Crime_Data"))
{
CRIME_DATA *pcr;
ALLOCMEM(pcr, CRIME_DATA, 1);
pcr->crime_record = fread_string(fp);
pcr->arrester = fread_string(fp);
pcr->date = fread_number(fp);
pcr->level = fread_number(fp);
pcr->jailtime = fread_number(fp);
pcr->released = fread_number(fp);
pcr->releaser = fread_string(fp);
LINK(pcr, ch->pcdata->first_record, ch->pcdata->last_record, next, prev );
fMatch = TRUE;
break;
}
break;
case 'D':
NKEY("Death", ch->pcdata->death_room, fread_number(fp));
AKEY("Domains", ch->pcdata->domain, fread_number(fp));
SKEY("Domain", ch->desc->host, fread_string(fp));
if ( !strcasecmp( word, "DrFuTh" ) )
{
line = fread_line( fp );
sscanf( line, "%d %d %d", &x1, &x2, &x3 );
ch->pcdata->condition[0] = x1;
ch->pcdata->condition[1] = x2;
ch->pcdata->condition[2] = x3;
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "DrFuThAi" ) )
{
line = fread_line( fp );
sscanf( line, "%d %d %d %d", &x1, &x2, &x3, &x4 );
ch->pcdata->condition[0] = x1;
ch->pcdata->condition[1] = x2;
ch->pcdata->condition[2] = x3;
ch->pcdata->condition[3] = x4;
fMatch = TRUE;
break;
}
if (!strcasecmp(word, "DiseaseData"))
{
DISEASE_DATA *dis;
ALLOCMEM(dis, DISEASE_DATA, 1);
dis->type = fread_number( fp );
dis->incubation = fread_number( fp );
dis->dc = fread_number( fp );
dis->saves = fread_number( fp );
LINK(dis, ch->first_disease, ch->last_disease, next, prev );
fMatch = TRUE;
break;
}
break;
case 'E':
SKEY("E_Descr", ch->description, fread_string(fp));
if ( !strcasecmp( word, "Enemies" ) )
{
fread_number( fp );
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "End" ) )
{
/*
ENDLOAD Chaos 10/11/93
*/
if (ch->pcdata->clan_name[0] != '\0')
{
if (get_clan(ch->pcdata->clan_name) != NULL)
{
ch->pcdata->clan = get_clan(ch->pcdata->clan_name);
}
else
{
RESTRING(ch->pcdata->clan_name, "");
ch->pcdata->clan = NULL;
}
}
if (ch->pcdata->vt100_type / 100 < 80 || ch->pcdata->vt100_type / 100 > MAX_TACTICAL_COL)
{
ch->pcdata->vt100_type = 8024;
}
ch->desc->port_size = ch->pcdata->port_size;
ch->position = POS_STANDING;
for (cnt = 0 ; cnt < MAX_ALIAS ; cnt++)
{
if (ch->pcdata->alias[cnt] == NULL)
{
ch->pcdata->alias[cnt] = STRDUPE(str_empty);
}
if (ch->pcdata->alias_c[cnt] == NULL)
{
ch->pcdata->alias_c[cnt] = STRDUPE(str_empty);
}
}
if (ch->hit < 0)
{
ch->hit = 1;
}
if (ch->level < LEVEL_IMMORTAL)
{
if (IS_SET(ch->act, PLR_WIZINVIS))
{
REMOVE_BIT(ch->act, PLR_WIZINVIS);
}
if (IS_SET(ch->act, PLR_WIZCLOAK))
{
REMOVE_BIT(ch->act, PLR_WIZCLOAK);
}
if (IS_SET(ch->act, PLR_HOLYLIGHT))
{
REMOVE_BIT(ch->act, PLR_HOLYLIGHT);
}
}
if (!IS_GOD(ch) && !PLR_FUNCTION(ch, FUNCTION_BUILDER|FUNCTION_BETA_TESTER))
{
if (IS_SET(ch->act, PLR_BUILDLIGHT))
{
REMOVE_BIT(ch->act, PLR_BUILDLIGHT);
}
}
if (ch->act < 0)
{
ch->act = 0;
}
add_pvnum(ch);
REMOVE_BIT(pvnum_index[ch->pcdata->pvnum]->flags, PVNUM_DELETED);
if (get_room_index(ch->pcdata->recall) == NULL)
{
ch->pcdata->recall = ROOM_VNUM_TEMPLE;
}
if (get_room_index(ch->pcdata->death_room) == NULL)
{
ch->pcdata->death_room = ROOM_VNUM_TEMPLE;
}
if (get_room_index(ch->pcdata->was_in_room) == NULL)
{
ch->pcdata->was_in_room = ROOM_VNUM_TEMPLE;
}
ch->in_room = get_room_index(ch->pcdata->was_in_room);
pop_call();
return;
}
NKEY("Ethos", ch->ethos, fread_number(fp));
NKEY("Exp", ch->pcdata->exp, fread_number(fp));
break;
case 'F':
NKEY("Featpts", ch->pcdata->feat_pts, fread_number(fp));
AKEY("FeatBonus", ch->pcdata->bonus_feat, fread_number(fp));
NKEY("Function", ch->pcdata->functions, fread_number(fp));
if (!strcasecmp(word, "Fort"))
{
fread_number(fp);
fMatch = TRUE;
break;
}
AKEY("FoundDir", ch->pcdata->found_dir, fread_number(fp));
if (!strcasecmp( word, "FaithFoe" ) )
{
fread_number(fp);
fread_number(fp);
fMatch = TRUE;
break;
}
break;
case 'G':
NKEY("Gold", ch->gold, fread_number(fp));
AKEY("Greeted", ch->pcdata->greeted, fread_number(fp));
AKEY("GrudgeTh", ch->pcdata->theft_grudge, fread_number(fp));
AKEY("GrudgeMd", ch->pcdata->murder_grudge,fread_number(fp));
break;
case 'H':
NKEY("Height", ch->height, fread_number(fp));
AKEY("HPLevel", ch->pcdata->hit_level, fread_number(fp));
SKEY("HtmlAddy", ch->pcdata->html_address, fread_string(fp));
if (!strcasecmp( word, "History" ) )
{
fread_number(fp);
fread_number(fp);
fMatch = TRUE;
break;
}
if (!strcasecmp( word, "HpMaMv" ) )
{
ch->hit = fread_number(fp);
ch->max_hit = fread_number(fp);
fread_number(fp);
fread_number(fp);
ch->move = fread_number(fp);
ch->max_move = fread_number(fp);
fMatch = TRUE;
break;
}
break;
case 'I':
if ( !strcasecmp( word, "Imbued" ) )
{
int sn;
int value;
value = fread_number( fp );
value = URANGE(0, value, 99);
sn = skill_lookup( fread_word( fp ) );
if (sn < 0)
{
bug("Fread_char: %s - unknown skill.", ch->name);
}
else
{
ch->imbued[sn] = value;
}
fMatch = TRUE;
}
break;
case 'J':
NKEY("Jaildate", ch->pcdata->jaildate, fread_number( fp ) );
NKEY("Jailtime", ch->pcdata->jailtime, fread_number( fp ) );
break;
case 'K':
NKEY("K_Played", ch->pcdata->killer_played, fread_number(fp));
break;
case 'L':
NKEY("Level", ch->level, fread_number(fp));
NKEY("LostLevel", ch->lost_levels, fread_number(fp));
SKEY("L_Descr", ch->long_descr, fread_string(fp));
NKEY("Language", ch->language, fread_number(fp));
NKEY("LastNote", ch->pcdata->last_note, fread_number(fp));
SKEY("Login", ch->pcdata->host, fread_string(fp));
NKEY("LastTime", ch->pcdata->last_time, fread_number(fp));
NKEY("LastRoom", ch->pcdata->last_real_room, fread_number(fp));
break;
case 'M':
AKEY("Mclass", ch->mclass, fread_number(fp));
SKEY("MailAddy", ch->pcdata->mail_address, fread_string(fp));
AKEY("Mana", ch->mana, fread_number(fp));
AKEY("MaxMana", ch->max_mana, fread_number(fp));
AKEY("MvLevel", ch->pcdata->move_level, fread_number(fp));
break;
case 'N':
NKEY("Nonlethal", ch->nonlethal, fread_number(fp));
break;
case 'O':
NKEY("O_Played", ch->pcdata->outcast_played, fread_number(fp));
break;
case 'P':
NKEY("Psw", ch->pcdata->password, fread_number(fp));
SKEY("Password", ch->pcdata->pwd, fread_string(fp));
NKEY("Played", ch->pcdata->played, fread_number(fp));
SKEY("Player", ch->pcdata->account, fread_string(fp));
NKEY("Practice", ch->pcdata->practice, fread_number(fp));
NKEY("Prev_hrs", ch->pcdata->previous_hours, fread_number(fp));
NKEY("Portsize", ch->pcdata->port_size, fread_number(fp));
SKEY("Prompt", ch->pcdata->prompt_layout, fread_string(fp));
NKEY("Pvnum", ch->pcdata->pvnum, fread_number(fp));
AKEY("PractLvl", ch->pcdata->pract_level, fread_number(fp));
if (!strcmp(word, "PK_ATTACKS"))
{
int cnt2;
cnt = fread_number(fp);
for (cnt2 = 0 ; cnt2 < cnt ; cnt2++)
{
if (cnt2 >= MAX_PK_ATTACKS)
{
fread_number(fp);
fread_number(fp);
fread_string(fp);
}
else
{
ch->pcdata->last_pk_attack_time[cnt2] = fread_number(fp);
ch->pcdata->last_pk_attack_pvnum[cnt2] = fread_number(fp);
STRFREE(ch->pcdata->last_pk_attack_name[cnt2]);
ch->pcdata->last_pk_attack_name[cnt2] = fread_string(fp);
}
}
fMatch = TRUE;
break;
}
if (!strcmp( word, "POISON_DATA" ) )
{
POISON_DATA *pd;
pd = fread_poison_data( fp );
if (pd != NULL && ch->poison != NULL)
{
pd->next = ch->poison;
ch->poison = pd;
}
else if (pd != NULL)
{
ch->poison = pd;
}
fMatch = TRUE;
break;
}
if (!strcmp(word, "Playtime"))
{
ch->pcdata->played += fread_number(fp);
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "Prepd" ) )
{
int sn;
int value;
value = fread_number( fp );
value = URANGE(0, value, 99);
sn = skill_lookup( fread_word( fp ) );
if (sn < 0)
{
bug("Fread_char: %s - unknown skill.", ch->name);
}
else
{
ch->pcdata->prepared[sn] = value;
}
fMatch = TRUE;
}
break;
case 'Q':
if (!strcasecmp(word, "Qstb"))
{
int qn, byt;
byt = fread_number( fp );
qn = fread_number( fp );
ALLOCMEM(ch->pcdata->quest[qn], bool, MAX_QUEST_BYTES);
for (cnt = 0 ; cnt < byt ; cnt++)
{
ch->pcdata->quest[qn][cnt] = fread_number( fp );
}
fMatch = TRUE;
}
break;
case 'R':
NKEY("Race", ch->race, fread_number(fp));
NKEY("Recall", ch->pcdata->recall, fread_number(fp));
NKEY("Reputation", ch->pcdata->reputation, fread_number(fp));
if (!strcasecmp(word, "Reflex"))
{
fread_number(fp);
fMatch = TRUE;
break;
}
NKEY("Room", ch->pcdata->was_in_room, fread_number(fp));
AKEY("RaceFoe", ch->pcdata->race_enemy, fread_number(fp));
break;
case 'S':
NKEY("Sex", ch->sex, fread_number(fp));
NKEY("Size", ch->size, fread_number(fp));
SKEY("S_Descr", ch->short_descr, fread_string(fp));
NKEY("Speed", ch->speed, fread_number(fp));
NKEY("Speak", ch->speak, fread_number(fp));
NKEY("Spam", ch->pcdata->spam, fread_number(fp));
NKEY("Statpts", ch->pcdata->stat_pts, fread_number(fp));
if (!strcasecmp( word, "School" ) )
{
fread_number(fp);
fMatch = TRUE;
break;
}
if (!strcasecmp( word, "StyleMnk" ) )
{
fread_number(fp);
fMatch = TRUE;
break;
}
if (!strcasecmp( word, "StyleRgr" ) )
{
fread_number(fp);
fMatch = TRUE;
break;
}
NKEY("SpellBns", ch->pcdata->bonus_spells, fread_number(fp));
if ( !strcasecmp( word, "Skill" ) )
{
int sn;
int value;
value = fread_number( fp );
sn = skill_lookup( fread_word( fp ) );
if (sn < 0)
{
bug("Fread_char: %s - unknown skill.", ch->name);
}
else
{
ch->learned[sn] = value;
}
fMatch = TRUE;
}
if ( !strcasecmp( word, "SkillLvl" ) )
{
int sn, cnt, value;
cnt = fread_number( fp );
value = fread_number( fp );
sn = skill_lookup( fread_word( fp ) );
if (sn < 0)
{
bug("Fread_char: %s - unknown skill.", ch->name);
}
else
{
ch->pcdata->skill_level[cnt][sn] = value;
}
fMatch = TRUE;
}
break;
case 'T':
if (!strcasecmp( word, "Trust" ) )
{
fread_number(fp);
fMatch = TRUE;
break;
}
AKEY("Topic", ch->pcdata->topic_stamp, fread_number( fp ) );
NKEY("Tactical", ch->pcdata->tactical_mode, fread_number( fp ) );
if (!strcasecmp( word, "TactIndx" ) )
{
fread_string(fp);
fMatch = TRUE;
break;
}
if (!strcasecmp(word, "Title"))
{
STRFREE(ch->pcdata->title);
ch->pcdata->title = fread_string(fp);
set_title(ch, ch->pcdata->title);
fMatch = TRUE;
break;
}
break;
case 'U':
if ( !strcasecmp( word, "Uses" ) )
{
int sn;
int value;
value = fread_number( fp );
value = URANGE(0, value, 99);
sn = skill_lookup( fread_word( fp ) );
if (sn < 0)
{
bug("Fread_char: %s - unknown skill.", ch->name);
}
else
{
ch->uses[sn] = value;
}
fMatch = TRUE;
}
break;
case 'V':
NKEY("Version", ch->pcdata->version, fread_number(fp));
NKEY("Vt100", ch->pcdata->vt100, fread_number(fp));
NKEY("Vt100_T", ch->pcdata->vt100_type, fread_number(fp));
NKEY("Vt100_F", ch->pcdata->vt100_flags, fread_number(fp));
break;
case 'W':
AKEY("Waypoint", ch->pcdata->waypoint, fread_number(fp));
NKEY("Weight", ch->weight, fread_number(fp));
NKEY("Whichgod", ch->god, fread_number(fp));
if (!strcasecmp(word, "Will"))
{
fread_number(fp);
fMatch = TRUE;
break;
}
if (!strcasecmp( word, "Wimpy" ) )
{
fread_number(fp);
fMatch = TRUE;
break;
}
break;
}
if ( !fMatch )
{
bug("fread_char: no match: (word) %s (line) %s", word, fread_line(fp));
}
}
log_printf("do_pload: Got this far!");
pop_call();
return;
}
void fread_obj( CHAR_DATA *ch, FILE *fp )
{
OBJ_DATA *obj;
char *word;
int BasicVnum, WearLoc, InRoom;
bool fMatch, iNest;
push_call("fread_obj(%p,%p)",ch,fp);
BasicVnum = 0;
WearLoc = WEAR_NONE;
iNest = 0;
ALLOCMEM(obj, OBJ_DATA, 1);
obj->pIndexData = obj_index[OBJ_VNUM_MUSHROOM];
for ( ; ; )
{
word = feof( fp ) ? "End" : fread_word( fp );
fMatch = FALSE;
switch ( UPPER(word[0]) )
{
case 'A':
if (!strcmp(word, "AffectData"))
{
AFFECT_DATA paf;
int sn;
sn = skill_lookup(fread_word(fp));
if (sn < 0)
{
log_string("fread_obj: unknown skill.");
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_word( fp );
}
else
{
paf.type = sn;
paf.duration = fread_number( fp );
paf.modifier = fread_number( fp );
paf.location = fread_number( fp );
paf.bittype = fread_number( fp );
paf.bitvector = fread_number( fp );
paf.level = fread_number( fp );
paf.caster = STRALLOC(fread_word( fp ));
affect_to_obj(NULL, obj, &paf);
}
fMatch = TRUE;
break;
}
if (!strcmp(word, "AffectData1"))
{
AFFECT_DATA paf;
int sn;
sn = skill_lookup(fread_word(fp));
if (sn < 0)
{
log_string("fread_obj: unknown skill.");
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_word( fp );
}
else
{
paf.type = sn;
paf.duration = fread_number( fp );
paf.modifier = fread_number( fp );
paf.location = fread_number( fp );
paf.bittype = fread_number( fp );
paf.bitvector = fread_number( fp );
paf.level = fread_number( fp );
paf.caster = STRALLOC(fread_word( fp ));
affect_to_obj(NULL, obj, &paf);
}
fMatch = TRUE;
break;
}
break;
case 'B':
NKEY("BasicVnum", BasicVnum, fread_number( fp ) );
break;
case 'C':
if (!strcmp(word, "Compact"))
{
int byt, cnt, vnum;
fread_to_eol( fp );
vnum = fread_number(fp);
if ((obj->pIndexData = get_obj_index(vnum)) == NULL)
{
if (IS_SET(mud->flags, MUD_EMUD_REALGAME))
{
log_printf("fread_obj: bad vnum %d.", vnum);
}
obj->pIndexData = obj_index[OBJ_VNUM_MUSHROOM];
}
obj->extra_flags = fread_number( fp );
obj->wear_flags = fread_number( fp );
obj->item_type = fread_number( fp );
obj->weight = fread_number( fp );
obj->level = fread_number( fp );
obj->timer = fread_number( fp );
obj->cost = fread_number( fp );
obj->owned_by = fread_number( fp );
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 );
obj->value[5] = fread_number( fp );
obj->value[6] = fread_number( fp );
obj->value[7] = fread_number( fp );
obj->material = fread_number( fp );
obj->hit_points = fread_number( fp );
obj->size = fread_number( fp );
byt = fread_number( fp );
if (byt != 0)
{
ALLOCMEM( obj->obj_quest, unsigned char, MAX_QUEST_BYTES );
for (cnt = 0 ; cnt < byt ; cnt++)
{
obj->obj_quest[cnt] = fread_number( fp );
}
}
fMatch = TRUE;
break;
}
break;
case 'D':
SKEY("Desc", obj->description, fread_string( fp ) );
if (!strcmp(word, "DiseaseData"))
{
DISEASE_DATA *dis;
ALLOCMEM(dis, DISEASE_DATA, 1);
dis->type = fread_number( fp );
dis->incubation = fread_number( fp );
dis->dc = fread_number( fp );
dis->saves = fread_number( fp );
LINK (dis, obj->first_disease, obj->last_disease, next, prev);
fMatch = TRUE;
break;
}
break;
case 'E':
if (!strcmp(word, "End"))
{
if (BasicVnum == 0)
{
if (obj->owned_by == 0
&& obj->first_affect == NULL
&& obj->item_type == obj->pIndexData->item_type
&& obj->extra_flags == obj->pIndexData->extra_flags
&& obj->wear_flags == obj->pIndexData->wear_flags
&& 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]
&& obj->value[5] == obj->pIndexData->value[5]
&& obj->value[6] == obj->pIndexData->value[6]
&& obj->value[7] == obj->pIndexData->value[7]
&& obj->weight == obj->pIndexData->weight
&& obj->material == obj->pIndexData->material
&& obj->hit_points == obj->pIndexData->hit_points
&& obj->size == obj->pIndexData->size
&& obj->timer == 0
&& obj->obj_quest == NULL
&& obj->poison == NULL
&& obj->short_descr == NULL)
{
REMOVE_BIT(obj->extra_flags, ITEM_MODIFIED);
}
else
{
SET_BIT(obj->extra_flags, ITEM_MODIFIED);
}
}
else
{
OBJ_INDEX_DATA *pObjIndex;
if ((pObjIndex = get_obj_index(BasicVnum)) == NULL)
{
if (IS_SET(mud->flags, MUD_EMUD_REALGAME))
{
log_printf("fread_obj: bad vnum %d.", BasicVnum);
}
BasicVnum = OBJ_VNUM_MUSHROOM;
pObjIndex = get_obj_index(BasicVnum);
}
obj->pIndexData = pObjIndex;
obj->level = pObjIndex->level;
obj->name = STRDUPE(pObjIndex->name);
obj->short_descr = STRDUPE(pObjIndex->short_descr);
obj->long_descr = STRDUPE(pObjIndex->long_descr);
obj->description = STRDUPE(pObjIndex->description);
obj->id_name = STRDUPE(pObjIndex->id_name);
obj->id_descr = STRDUPE(pObjIndex->id_descr);
obj->item_type = pObjIndex->item_type;
obj->extra_flags = pObjIndex->extra_flags;
obj->wear_flags = pObjIndex->wear_flags;
obj->value[0] = pObjIndex->value[0];
obj->value[1] = pObjIndex->value[1];
obj->value[2] = pObjIndex->value[2];
obj->value[3] = pObjIndex->value[3];
obj->value[4] = pObjIndex->value[4];
obj->value[5] = pObjIndex->value[5];
obj->value[6] = pObjIndex->value[6];
obj->value[7] = pObjIndex->value[7];
obj->weight = pObjIndex->weight;
obj->cost = pObjIndex->cost;
obj->level = pObjIndex->level;
obj->material = pObjIndex->material;
obj->hit_points = pObjIndex->hit_points;
obj->size = pObjIndex->size;
}
/*
Special chains of the Gods
*/
if (BasicVnum == 0)
{
if (obj->level <= 0 || obj->level < obj->pIndexData->level)
{
obj->level = obj->pIndexData->level;
}
if (obj->name == NULL)
{
STRFREE( obj->name );
obj->name = STRDUPE(obj->pIndexData->name);
}
if (obj->short_descr == NULL)
{
STRFREE( obj->short_descr );
obj->short_descr = STRDUPE(obj->pIndexData->short_descr);
}
if (obj->long_descr == NULL)
{
STRFREE( obj->long_descr );
obj->long_descr = STRDUPE(obj->pIndexData->long_descr);
}
if (obj->description == NULL)
{
STRFREE( obj->description );
obj->description = STRDUPE(obj->pIndexData->description);
}
if (strcasecmp(obj->name, obj->pIndexData->name)
|| strcasecmp(obj->short_descr, obj->pIndexData->short_descr)
|| strcasecmp(obj->long_descr, obj->pIndexData->long_descr)
|| strcasecmp(obj->description, obj->pIndexData->description))
{
SET_BIT(obj->extra_flags, ITEM_MODIFIED);
}
}
obj->wear_loc = WearLoc;
rgObjNest[iNest] = obj;
if (iNest == 0)
{
if (ch != NULL)
obj_to_char(obj, ch);
else
obj_to_room(obj, InRoom);
}
else
{
obj_to_obj(obj, rgObjNest[iNest-1]);
}
LINK(obj, mud->f_obj, mud->l_obj, next, prev);
LINK(obj, obj->pIndexData->first_instance, obj->pIndexData->last_instance, next_instance, prev_instance);
add_obj_ref_hash( obj );
mud->total_obj++;
obj->pIndexData->total_objects++;
pop_call();
return;
}
break;
case 'H':
NKEY("Herb", obj->value[2], fread_number(fp));
break;
case 'I':
NKEY("InRoom", InRoom, fread_number(fp));
NKEY("Identified", obj->identified, fread_number(fp));
break;
case 'L':
SKEY("Long", obj->long_descr, fread_string(fp));
break;
case 'N':
NKEY("Nest", iNest, fread_number(fp));
SKEY("Name", obj->name, fread_string(fp));
break;
case 'P':
NKEY("Poison", obj->value[1], fread_number(fp));
if (!strcmp(word, "POISON_DATA"))
{
POISON_DATA *pd;
pd = fread_poison_data( fp );
if (pd != NULL)
{
if (obj->poison != NULL)
{
pd->next = obj->poison;
obj->poison = pd;
}
else if (pd != NULL)
{
obj->poison = pd;
}
}
fMatch = TRUE;
break;
}
break;
case 'R':
NKEY("RefKey", obj->obj_ref_key, fread_number(fp));
break;
case 'S':
SKEY("Short", obj->short_descr, fread_string(fp));
if (!strcasecmp(word, "Scribed"))
{
int sn;
if ((sn = skill_lookup(fread_word(fp))) == -1)
{
log_string("Fread_obj(Scribed): unknown skill.");
}
else
{
obj->scribed[sn] = 1;
}
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "Spell" ) )
{
int iValue, sn;
iValue = fread_number( fp );
sn = skill_lookup( fread_word( fp ) );
if (iValue < 1 || iValue > 7)
{
log_printf("Fread_obj(Spell): bad iValue %d.", iValue );
}
else if (sn < 0)
{
log_string("Fread_obj: unknown skill.");
}
else
{
obj->value[iValue] = sn;
}
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "Skill" ) )
{
int iValue, sn;
iValue = fread_number( fp );
sn = skill_lookup( fread_word( fp ) );
if (iValue < 1 || iValue > 7)
{
log_printf("Fread_obj(Spell): bad iValue %d.", iValue );
}
else if (sn < 0)
{
log_string("Fread_obj: unknown skill.");
}
else
{
obj->value[iValue] = sn;
}
fMatch = TRUE;
break;
}
break;
case 'U':
NKEY("Uses", obj->value[0], fread_number(fp));
break;
case 'W':
NKEY("WearLoc", WearLoc, fread_number(fp));
break;
}
if (!fMatch)
{
fread_to_eol( fp );
log_printf("Fread_obj: no match: %s", word);
}
}
}
/*
* Borrowed from AFKMud's pet saving code - Kregor 7/13/07
* This will read one mobile structure from file - Shaddai
* Edited by Tarl 5 May 2002 to allow pets to load equipment.
*/
CHAR_DATA *fread_mobile( FILE * fp )
{
CHAR_DATA *mob = NULL;
const char *word;
bool fMatch;
char *line;
int inroom = 0, cnt, x1, x2, x3, x4, x5, x6;
MOB_INDEX_DATA *pMobIndex = NULL;
push_call("fread_mobile(%p)",fp);
word = feof( fp ) ? "EndVendor" : fread_word( fp );
if( !strcasecmp( word, "Vnum" ) )
{
int vnum;
vnum = fread_number( fp );
pMobIndex = get_mob_index( vnum );
if( !pMobIndex )
{
for( ;; )
{
word = feof( fp ) ? "EndVendor" : fread_word( fp );
if( !strcasecmp( word, "EndMobile" ) )
break;
}
bug( "Fread_mobile: No index data for vnum %d", vnum );
pop_call();
return NULL;
}
mob = create_mobile( pMobIndex );
}
else
{
for( ;; )
{
word = feof( fp ) ? "EndVendor" : fread_word( fp );
/*
* So we don't get so many bug messages when something messes up
* * --Shaddai
*/
if( !strcasecmp( word, "EndMobile" ) )
break;
}
extract_char( mob );
bug( "%s: Vnum not found",0 );
pop_call();
return NULL;
}
for( ;; )
{
word = feof( fp ) ? "EndVendor" : fread_word( fp );
fMatch = FALSE;
switch ( UPPER( word[0] ) )
{
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;
case 'A':
if (!strcmp(word, "AffectData"))
{
AFFECT_DATA paf;
int sn;
sn = skill_lookup(fread_word(fp));
if (!valid_skill(sn))
{
log_string("fread_obj: unknown skill.");
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_number( fp );
fread_word( fp );
}
else
{
paf.type = sn;
paf.duration = fread_number( fp );
paf.modifier = fread_number( fp );
paf.location = fread_number( fp );
paf.bittype = fread_number( fp );
paf.bitvector = fread_number( fp );
paf.level = fread_number( fp );
paf.caster = STRALLOC(fread_word( fp ));
affect_to_char(NULL, mob, &paf);
}
fMatch = TRUE;
break;
}
NKEY( "Act", mob->act, fread_number( fp ) );
NKEY( "AffectedBy", mob->affected_by, fread_number( fp ) );
NKEY( "Affected2By", mob->affected2_by, fread_number( fp ) );
NKEY( "Armor", mob->armor, fread_number( fp ) );
if ( !strcasecmp( word, "AttrMod" ) )
{
line = fread_line( fp );
x1=x2=x3=x4=x5=x6=0;
sscanf( line, "%d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6 );
mob->mod_str = x1;
mob->mod_int = x2;
mob->mod_wis = x3;
mob->mod_dex = x4;
mob->mod_con = x5;
mob->mod_cha = x6;
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "AttrPerm" ) )
{
line = fread_line( fp );
x1=x2=x3=x4=x5=x6=13;
sscanf( line, "%d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6 );
mob->perm_str = x1;
mob->perm_int = x2;
mob->perm_wis = x3;
mob->perm_dex = x4;
mob->perm_con = x5;
mob->perm_cha = x6;
fMatch = TRUE;
break;
}
break;
case 'D':
SKEY( "Description", mob->description, fread_string( fp ) );
if (!strcasecmp(word, "DiseaseData"))
{
DISEASE_DATA *dis;
ALLOCMEM(dis, DISEASE_DATA, 1);
dis->type = fread_number( fp );
dis->incubation = fread_number( fp );
dis->dc = fread_number( fp );
dis->saves = fread_number( fp );
LINK(dis, mob->first_disease, mob->last_disease, next, prev );
fMatch = TRUE;
break;
}
break;
case 'E':
if( !strcasecmp( word, "EndMobile" ) )
{
if( inroom == 0 )
inroom = ROOM_VNUM_TEMPLE;
if( room_index[inroom] == NULL )
inroom = ROOM_VNUM_LIMBO;
char_to_room( mob, inroom, TRUE );
act( "$n has entered the game.", mob, NULL, NULL, TO_ROOM);
/*
Check for illegal items, fix bits - Order 7/3/1995
*/
fix_object_bits(mob, mob->first_carrying);
char_reset( mob );
pop_call();
return mob;
}
break;
case 'H':
if( !strcasecmp( word, "HpManaMove" ) )
{
mob->hit = fread_number( fp );
mob->max_hit = fread_number( fp );
fread_number( fp );
fread_number( fp );
mob->move = fread_number( fp );
mob->max_move = fread_number( fp );
fMatch = TRUE;
break;
}
break;
case 'L':
NKEY( "Level", mob->level, fread_number( fp ) );
NKEY( "LostLevel", mob->lost_levels, fread_number( fp ) );
SKEY( "Long", mob->long_descr, fread_string( fp ) );
break;
case 'M':
AKEY( "Mclass", mob->mclass, fread_number( fp ) );
AKEY( "Mana", mob->mana, fread_number(fp));
AKEY( "MaxMana", mob->max_mana, fread_number(fp));
break;
case 'N':
SKEY( "Name", mob->name, fread_string( fp ) );
NKEY("Nonlethal", mob->nonlethal, fread_number(fp));
NKEY( "NatArmor", mob->nat_armor, fread_number( fp ) );
break;
case 'P':
NKEY( "Position", mob->position, fread_number( fp ) );
break;
case 'R':
NKEY( "Room", inroom, fread_number( fp ) );
NKEY( "Race", mob->race, fread_number( fp ) );
break;
case 'S':
NKEY( "Sex", mob->sex, fread_number( fp ) );
SKEY( "Short", mob->short_descr, fread_string( fp ) );
if ( !strcasecmp( word, "Skill" ) )
{
int sn;
int value;
value = fread_number( fp );
sn = skill_lookup( fread_word( fp ) );
if (sn < 0)
{
bug("Fread_char: %s - unknown skill.", mob->name);
}
else
{
mob->learned[sn] = value;
}
fMatch = TRUE;
}
break;
}
if( !strcasecmp( word, "#OBJECT" ) )
{
fread_obj( mob, fp );
fMatch = TRUE;
}
if( !fMatch )
{
bug( "%s: no match: %s", word );
fread_to_eol( fp );
}
}
}
/*
This routine makes sure that files are not cross linked of chopped
Chaos - 5/30/96
*/
bool is_valid_file( CHAR_DATA *ch, FILE *fp )
{
char buf[MAX_INPUT_LENGTH];
sh_int cnt, cf;
push_call("is_valid_File(%p,%p)",ch,fp);
cf = ' ';
cnt = 0;
while (cf != '#' && cnt > -50)
{
cnt--;
fseek(fp, cnt, SEEK_END);
cf = fgetc(fp);
}
if (cnt == -50)
{
log_printf("Didn't find an #END on %s", ch->name);
rewind( fp );
pop_call();
return( FALSE );
}
for (cf = '#', cnt = 0 ; cf != '\n' && cf != EOF ; cnt++)
{
buf[cnt] = cf;
cf = fgetc(fp);
}
buf[cnt] = '\0';
if (str_prefix("#END ", buf))
{
log_printf("Didn't find an #END on %s", ch->name);
rewind( fp );
pop_call();
return( FALSE );
}
if (!strcasecmp(ch->name, &buf[5]))
{
rewind( fp );
pop_call();
return( TRUE );
}
log_printf("Cross linked file %s on %s", buf, ch->name );
rewind( fp );
pop_call();
return( FALSE );
}
int total_language( CHAR_DATA *ch )
{
int total, cnt;
push_call("total_language(%p)",ch);
for (total = 0, cnt = 0 ; cnt < MAX_RACE ; cnt++)
{
if (IS_SET(ch->language, SHIFT(cnt)))
{
total++;
}
}
pop_call();
return( total );
}
/*
Let's save that poison data - Chaos 4/20/99
*/
void fwrite_poison_data( POISON_DATA *pd, FILE *fp )
{
push_call("fwrite_poison_data(%p,%p)",pd,fp);
fprintf( fp, "POISON_DATA 1 %d %d %d %d %d\n",
(int) pd->type,
pd->dc,
pd->constant_duration,
pd->owner,
pd->poisoner );
if (pd->next != NULL)
{
fwrite_poison_data( pd->next, fp );
}
pop_call();
return;
}
POISON_DATA *fread_poison_data( FILE *fp )
{
POISON_DATA *pd;
int ptype;
push_call("fread_poison_data(%p)",fp);
ALLOCMEM( pd, POISON_DATA, 1 );
if ((ptype = fread_number( fp )) == 1)
{
pd->type = (sh_int)fread_number(fp);
pd->dc = fread_number(fp);
pd->constant_duration = fread_number(fp);
pd->owner = fread_number(fp);
pd->poisoner = fread_number(fp);
pd->next = NULL;
pop_call();
return( pd );
}
else
{
fread_to_eol( fp );
}
FREEMEM( pd );
pop_call();
return( NULL );
}
/*
Hypnos 20020326: Check player directories
*/
int check_dirs( void )
{
int i, dir;
char tempbuf[320];
push_call("check_dirs()");
dir = 0;
if (mkdir(PLAYER_DIR, XX_DIRMASK) == -1)
{
if (errno != EEXIST)
{
pop_call();
return -1;
}
}
else
{
dir++;
}
for (i = 0 ; i < 26 ; i++)
{
sprintf(tempbuf, "%s/%c", PLAYER_DIR, 'a' + i);
if (mkdir(tempbuf, XX_DIRMASK) == -1)
{
if (errno != EEXIST)
{
pop_call();
return -1;
}
}
else
{
dir++;
}
sprintf(tempbuf, "%s/%c/dmp", PLAYER_DIR, 'a' + i);
if (mkdir(tempbuf, XX_DIRMASK) == -1)
{
if (errno != EEXIST)
{
pop_call();
return -1;
}
}
else
{
dir++;
}
sprintf(tempbuf, "%s/%c/del", PLAYER_DIR, 'a' + i);
if (mkdir(tempbuf, XX_DIRMASK) == -1)
{
if (errno != EEXIST)
{
pop_call();
return -1;
}
}
else
{
dir++;
}
sprintf(tempbuf, "%s/%c/bak", PLAYER_DIR, 'a' + i);
if (mkdir(tempbuf, XX_DIRMASK) == -1)
{
if (errno != EEXIST)
{
pop_call();
return -1;
}
}
else
{
dir++;
}
}
pop_call();
return dir;
}
/*
* Inspired by Locker Code by Aidan 5/4/2006
* immortal@chaos-ascending.com
* severely modified for existing obj read and write codes.
*/
void save_lockers( )
{
FILE *LockerFile;
ROOM_INDEX_DATA *room;
OBJ_DATA *obj = NULL;
int vnum;
/* Close the reserve file */
fclose(fpReserve);
/* Open the Locker File for saving */
LockerFile = my_fopen(LOCKER_FILE, "w", TRUE);
/* Okay, lets loop through all of the rooms on the game */
for(vnum = 0; vnum < MAX_VNUM; vnum++)
{
if((room = get_room_index(vnum)) != NULL)
{
/* Is this a storeroom? */
if(!IS_SET(room->room_flags, ROOM_CLANSTOREROOM))
continue;
if ((obj = room->first_content) != NULL)
fwrite_obj(NULL,obj,LockerFile,0);
}
}
fprintf(LockerFile,"#END\n");
fclose(LockerFile);
fpReserve = my_fopen(NULL_FILE, "r", FALSE);
return;
}
void load_lockers( )
{
FILE *LockerFile;
char letter;
char *word;
fclose(fpReserve);
if((LockerFile = my_fopen(LOCKER_FILE, "r", FALSE)) == NULL)
{
log_string("No locker file found.");
fclose(LockerFile);
fpReserve = my_fopen(NULL_FILE,"r",FALSE);
return;
}
for( ; ; )
{
letter = fread_letter(LockerFile);
if(letter != '#')
{
bug("Load_Lockers: # not found.",0);
break;
}
word = fread_word(LockerFile);
if(!strcasecmp(word,"OBJECT"))
fread_obj(NULL, LockerFile);
else if(!strcasecmp(word,"END"))
break;
else
{
bug("Load_Lockers: bad section.",0);
break;
}
}
fclose(LockerFile);
fpReserve = my_fopen(NULL_FILE,"r",FALSE);
return;
}
/**************************************************
* start new account stuff - Kregor
*/
/*
* initialize a new account, load in
* saved account info if available bilink
* with player decriptor - Kregor
*/
bool add_account( DESCRIPTOR_DATA *d, char *name )
{
ACCOUNT_DATA *acct;
FILE *fp;
char strload[MAX_INPUT_LENGTH];
bool found = FALSE;
int cnt;
push_call("add_account(%p,%p)",d,name);
ALLOCMEM(acct, ACCOUNT_DATA, 1);
d->account = acct;
acct->desc = d;
acct->player_name = STRALLOC(name);
acct->pwd = STRALLOC("");
acct->rp_points = 0;
acct->last_connect = 0;
acct->last_time = 0;
acct->functions = 0;
for (cnt = 0 ; cnt < MAX_PC ; cnt++)
{
acct->character[cnt] = 0;
}
close_reserve();
sprintf(strload, "%s/%c/%s", ACCOUNT_DIR, tolower(name[0]), capitalize_name(name));
if ((fp = my_fopen(strload, "r" , TRUE)) != NULL)
{
found = TRUE;
fread_account(acct, fp);
my_fclose(fp);
}
open_reserve();
acct->desc = d;
d->account = acct;
mud->total_acct++;
LINK(acct, mud->f_acct, mud->l_acct, next, prev);
pop_call();
return found;
}
/*
* close an open account and free memory - Kregor
*/
void free_account( ACCOUNT_DATA *acct )
{
push_call("free_account(%p)",acct);
acct->desc->account = NULL;
acct->desc = NULL;
acct->ch = NULL;
if ((acct->prev == NULL && acct != mud->f_acct)
|| (acct->next == NULL && acct != mud->l_acct))
{
log_printf("UNLINK ERROR unlinking account %s.", acct->player_name);
}
else
{
UNLINK(acct, mud->f_acct, mud->l_acct, next, prev);
}
mud->total_acct--;
STRFREE(acct->player_name);
FREEMEM(acct);
pop_call();
return;
}
void fread_account( ACCOUNT_DATA *acct, FILE *fp )
{
char *word;
bool fMatch;
sh_int cnt;
push_call("fread_account(%p,%p)",acct,fp);
if (acct == NULL)
{
log_printf("Attempt to load a NULL account.");
pop_call();
return;
}
for ( ; ; )
{
word = feof( fp ) ? "End" : fread_word( fp );
fMatch = FALSE;
switch (UPPER(word[0]))
{
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;
case 'A':
NKEY("Ansi", acct->ansi, fread_number(fp));
break;
case 'C':
AKEY("Chars", acct->character, fread_number(fp));
break;
case 'E':
if ( !strcasecmp( word, "End" ) )
{
pop_call();
return;
}
break;
case 'F':
NKEY("Function", acct->functions, fread_number(fp));
break;
case 'L':
NKEY("LastTime", acct->last_time, fread_number(fp));
break;
case 'N':
SKEY("Name", acct->player_name, fread_string(fp));
case 'P':
NKEY("Psw", acct->password, fread_number(fp));
NKEY("Played", acct->played, fread_number(fp));
if (!strcmp(word, "Playtime"))
{
acct->played += fread_number(fp);
fMatch = TRUE;
break;
}
break;
case 'R':
NKEY("RPPoints", acct->rp_points, fread_number(fp));
break;
case 'V':
NKEY("Vt100", acct->vt100, fread_number(fp));
break;
}
if ( !fMatch )
{
bug("fread_account: no match: (word) %s (line) %s", word, fread_line(fp));
}
}
pop_call();
return;
}
void fwrite_acct( ACCOUNT_DATA *acct, FILE *fp )
{
int cnt;
push_call("fwrite_acct(%p,%p)",acct,fp);
fprintf( fp, "Name %s~\n", acct->player_name);
fprintf( fp, "Function " );
break_bits( fp, acct->functions, "FUNCTION_", TRUE);
fprintf( fp, "\n" );
fprintf( fp, "Psw %lld\n", acct->password);
fprintf( fp, "Played %d\n", acct->played);
fprintf( fp, "Ansi %d\n", acct->ansi);
fprintf( fp, "Vt100 %d\n", acct->vt100 ? 2 : 0);
if (acct->ch && acct->ch->pcdata->last_connect != mud->current_time)
{
fprintf( fp, "LastTime %d\n", (int) mud->current_time );
}
else
{
fprintf( fp, "LastTime %ld\n", acct->last_time );
}
fprintf( fp, "Playtime %ld\n", acct->ch ? (int) mud->current_time - acct->ch->pcdata->last_connect : 0);
fprintf( fp, "RPPoints %d\n", acct->rp_points);
for (cnt = 0 ; cnt < MAX_PC ; cnt++)
{
if (acct->character[cnt] > 0)
{
fprintf( fp, "Chars %d %d\n", cnt, acct->character[cnt] );
}
}
fprintf( fp, "End\n\n" );
pop_call();
return;
}
/*
* Calls the account file to save
* call this function in save_char_obj
* in order to use safeguards - Kregor
*/
void save_account( DESCRIPTOR_DATA *d )
{
char strsave[MAX_INPUT_LENGTH], strtemp[MAX_INPUT_LENGTH];
char logfile[250];
char cap_name[30];
FILE *fp, *logfp;
push_call("save_char_obj(%p)",d);
strcpy( cap_name, capitalize_name( d->account->player_name ) );
sprintf(strsave,"%s/%c/%s", ACCOUNT_DIR, tolower(cap_name[0]), cap_name);
sprintf(strtemp,"%s/%c/temp.%s",ACCOUNT_DIR, tolower(cap_name[0]), cap_name);
close_reserve();
// log_printf("save account, %s.", cap_name);
/*
Save char to "temp.name" then rename to "name" after all done for safety
*/
sprintf(logfile, "%s/%c/%s.log", ACCOUNT_DIR, tolower(cap_name[0]), cap_name);
logfp = my_fopen(logfile,"w",FALSE);
if (logfp == NULL)
{
log_printf("Could _NOT_ open logfile to log the saving of %s\n\r.",cap_name);
print_errno(errno);
}
if (remove( strtemp ) != 0)
{
if (errno != ENOENT) /* if there was no temp file there's no prob */
{
log_printf("save_account: could not remove %s.", strtemp);
print_errno(errno);
}
}
fp = my_fopen( strtemp, "w", FALSE ) ;
if ( fp == NULL )
{
log_printf("Save_account: could not my_fopen file.");
perror( strsave );
write_to_buffer(d, "Through some wierd game error, your account did not save.\n\r", 1000000);
open_reserve();
pop_call();
return;
}
if (logfp) /* if the logfile is opened correctly */
{
fprintf(logfp, "Removed old backup and opened a new tempfile successfully.\n");
}
fwrite_acct( d->account, fp );
if (logfp)
{
fprintf(logfp,"Wrote account information successfully. (fwrite_acct)\n");
}
if (ftell(fp) < (long)100)
{
my_fclose( fp );
write_to_buffer(d, "Oops, file system full! tell an admin!\n\r", 1000000);
log_string("File system full!!!\n\r");
}
else
{
my_fclose( fp );
if (remove(strsave) != 0)
{
if (errno != ENOENT)
{
log_printf("save_account: (2nd) could not remove %s.", strsave);
print_errno(errno);
}
}
if (rename( strtemp, strsave ) != 0)
{
log_printf("Could not rename %s to %s.", strtemp, strsave);
print_errno(errno);
}
}
if (logfp)
{
fprintf(logfp,"All done right.\n");
fflush(logfp);
my_fclose(logfp);
remove( logfile );
}
open_reserve();
d->account->last_saved = mud->current_time;
pop_call();
return;
}