#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include "mud.h"
/*
* Increment with every major format change.
*/
#define SAVEVERSION 4
/*
* Array to keep track of equipment temporarily. -Thoric
*/
OBJ_DATA *save_equipment[MAX_WEAR][8];
CHAR_DATA *quitting_char, *loading_char, *saving_char;
int file_ver;
/*
* Externals
*/
void fwrite_comments( CHAR_DATA *ch, FILE *fp );
void fread_comment( CHAR_DATA *ch, FILE *fp );
/*
* Array of containers read for proper re-nesting of objects.
*/
static OBJ_DATA * rgObjNest [MAX_NEST];
/*
* Local functions.
*/
void fwrite_char args( ( CHAR_DATA *ch, FILE *fp ) );
void fread_char args( ( CHAR_DATA *ch, FILE *fp, bool preload) );
void write_corpses args( ( CHAR_DATA *ch, char *name ) );
void save_home( CHAR_DATA *ch )
{
if ( ch->plr_home )
{
FILE *fp;
char filename[256];
sh_int templvl;
OBJ_DATA *contents;
sprintf( filename, "%s%c/%s.home", PLAYER_DIR, tolower(ch->name[0]),
capitalize( ch->name ) );
if ( ( fp = fopen( filename, "w" ) ) == NULL )
{
}
else
{
templvl = ch->top_level;
ch->top_level = LEVEL_HERO; /* make sure EQ doesn't get lost */
contents = ch->plr_home->last_content;
if (contents)
fwrite_obj(ch, contents, fp, 0, OS_CARRY );
fprintf( fp, "#END\n" );
ch->top_level = templvl;
fclose( fp );
}
}
}
/*
* Un-equip character before saving to ensure proper -Thoric
* stats are saved in case of changes to or removal of EQ
*/
void de_equip_char( CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
OBJ_DATA *obj;
int x,y;
for ( x = 0; x < MAX_WEAR; x++ )
for ( y = 0; y < MAX_LAYERS; y++ )
save_equipment[x][y] = NULL;
for ( obj = ch->first_carrying; obj; obj = obj->next_content )
if ( obj->wear_loc > -1 && obj->wear_loc < MAX_WEAR )
{
for ( x = 0; x < MAX_LAYERS; x++ )
if ( !save_equipment[obj->wear_loc][x] )
{
save_equipment[obj->wear_loc][x] = obj;
break;
}
if ( x == MAX_LAYERS )
{
sprintf( buf, "%s had on more than %d layers of clothing in one location (%d): %s",
ch->name, MAX_LAYERS, obj->wear_loc, obj->name );
bug( buf, 0 );
}
unequip_char(ch, obj);
}
}
/*
* Re-equip character -Thoric
*/
void re_equip_char( CHAR_DATA *ch )
{
int x,y;
for ( x = 0; x < MAX_WEAR; x++ )
for ( y = 0; y < MAX_LAYERS; y++ )
if ( save_equipment[x][y] != NULL )
{
if ( quitting_char != ch )
equip_char(ch, save_equipment[x][y], x);
save_equipment[x][y] = NULL;
}
else
break;
}
/*
* 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 )
{
char strsave[MAX_INPUT_LENGTH];
char strback[MAX_INPUT_LENGTH];
FILE *fp;
if ( !ch )
{
bug( "Save_char_obj: null ch!", 0 );
return;
}
if ( IS_NPC(ch) || NOT_AUTHED(ch) )
return;
saving_char = ch;
/* save pc's clan's data while we're at it to keep the data in sync */
if ( !IS_NPC(ch) && ch->pcdata->clan )
save_clan( ch->pcdata->clan );
if ( ch->desc && ch->desc->original )
ch = ch->desc->original;
ch->save_time = current_time;
sprintf( strsave, "%s%c/%s", PLAYER_DIR, tolower(ch->name[0]),
capitalize( ch->name ) );
/*
* Auto-backup pfile (can cause lag with high disk access situtations
*/
if ( IS_SET( sysdata.save_flags, SV_BACKUP ) )
{
sprintf( strback, "%s%c/%s", BACKUP_DIR, tolower(ch->name[0]),
capitalize( ch->name ) );
rename( strsave, strback );
}
de_equip_char( ch );
/*
* Save immortal stats, level & vnums for wizlist -Thoric
* and do_vnums command
*
* Also save the player flags so we the wizlist builder can see
* who is a guest and who is retired.
*/
if ( get_trust(ch) > LEVEL_IMMORTAL - 1 && str_cmp(ch->name, "Eleven") )
{
sprintf( strback, "%s%s", GOD_DIR, capitalize( ch->name ) );
if ( ( fp = fopen( strback, "w" ) ) == NULL )
{
bug( "Save_god_level: fopen", 0 );
perror( strsave );
}
else
{
fprintf( fp, "Level %d\n", ch->top_level );
fprintf( fp, "Pcflags %d\n", ch->pcdata->flags );
if ( ch->pcdata->r_range_lo && ch->pcdata->r_range_hi )
fprintf( fp, "RoomRange %d %d\n", ch->pcdata->r_range_lo,
ch->pcdata->r_range_hi );
if ( ch->pcdata->o_range_lo && ch->pcdata->o_range_hi )
fprintf( fp, "ObjRange %d %d\n", ch->pcdata->o_range_lo,
ch->pcdata->o_range_hi );
if ( ch->pcdata->m_range_lo && ch->pcdata->m_range_hi )
fprintf( fp, "MobRange %d %d\n", ch->pcdata->m_range_lo,
ch->pcdata->m_range_hi );
fclose( fp );
}
}
if ( ( fp = fopen( strsave, "w" ) ) == NULL )
{
bug( "Save_char_obj: fopen", 0 );
perror( strsave );
}
else
{
fwrite_char( ch, fp );
if ( ch->first_carrying )
fwrite_obj( ch, ch->last_carrying, fp, 0, OS_CARRY );
if ( ch->comments ) /* comments */
fwrite_comments( ch, fp ); /* comments */
fprintf( fp, "#END\n" );
fclose( fp );
}
re_equip_char( ch );
write_corpses(ch, NULL);
quitting_char = NULL;
saving_char = NULL;
return;
}
void save_clone( CHAR_DATA *ch )
{
char strsave[MAX_INPUT_LENGTH];
char strback[MAX_INPUT_LENGTH];
FILE *fp;
if ( !ch )
{
bug( "Save_char_obj: null ch!", 0 );
return;
}
if ( IS_NPC(ch) || NOT_AUTHED(ch) )
return;
if ( ch->desc && ch->desc->original )
ch = ch->desc->original;
de_equip_char( ch );
ch->save_time = current_time;
SET_BIT(ch->pcdata->act2, ACT_EXEMPT);
sprintf( strsave, "%s%c/%s.clone", PLAYER_DIR, tolower(ch->name[0]),
capitalize( ch->name ) );
/*
* Auto-backup pfile (can cause lag with high disk access situtations
*/
if ( IS_SET( sysdata.save_flags, SV_BACKUP ) )
{
sprintf( strback, "%s%c/%s", BACKUP_DIR, tolower(ch->name[0]),
capitalize( ch->name ) );
rename( strsave, strback );
}
if ( ( fp = fopen( strsave, "w" ) ) == NULL )
{
bug( "Save_char_obj: fopen", 0 );
perror( strsave );
}
else
{
fwrite_char( ch, fp );
if ( ch->comments ) /* comments */
fwrite_comments( ch, fp ); /* comments */
fprintf( fp, "#END\n" );
fclose( fp );
}
re_equip_char( ch );
write_corpses(ch, NULL);
quitting_char = NULL;
saving_char = NULL;
REMOVE_BIT(ch->pcdata->act2, ACT_EXEMPT);
return;
}
/*
* Write the char.
*/
void fwrite_char( CHAR_DATA *ch, FILE *fp )
{
AFFECT_DATA *paf;
QUEST_DATA *quest;
int sn, track, drug;
BUG_DATA *bug;
SKILLTYPE *skill;
SHIP_DATA *ship;
CONTRACT_DATA *contract;
FELLOW_DATA *fellow;
fprintf( fp, "#%s\n", IS_NPC(ch) ? "MOB" : "PLAYER" );
fprintf( fp, "Version %d\n", SAVEVERSION );
fprintf( fp, "Name %s~\n", ch->name );
fprintf( fp, "Comfreq %s~\n", ch->comfreq );
if ( ch->short_descr && ch->short_descr[0] != '\0' )
fprintf( fp, "ShortDescr %s~\n", ch->short_descr );
if ( ch->long_descr && ch->long_descr[0] != '\0' )
fprintf( fp, "LongDescr %s~\n", ch->long_descr );
if ( ch->description && ch->description[0] != '\0' )
fprintf( fp, "Description %s~\n", ch->description );
fprintf( fp, "Sex %d\n", ch->sex );
fprintf( fp, "Race %d\n", ch->race );
fprintf( fp, "Languages %d %d\n", ch->speaks, ch->speaking );
fprintf( fp, "Toplevel %d\n", ch->top_level );
if ( ch->trust )
fprintf( fp, "Trust %d\n", ch->trust );
fprintf( fp, "Pheight %d\n", ch->pheight );
fprintf( fp, "Build %d\n", ch->build );
fprintf( fp, "Played %d\n",
ch->played + (int) (current_time - ch->logon) );
if (ch->in_room && (ship = ship_from_room (ch->in_room->vnum))) {
fprintf(fp, "Ship %s~\n", ship->name);
/* for ( sRoom = ship->first_room ; sRoom ; sRoom = sRoom->next_in_ship )
if ( ch->in_room == sRoom )*/
fprintf(fp, "ShipNum %d\n", ch->in_room->exvnum);
}
else {
fprintf(fp, "Ship ~\n");
fprintf(fp, "ShipNum 0\n");
}
fprintf( fp, "Room %d\n",
( ch->in_room == get_room_index( ROOM_VNUM_LIMBO )
&& ch->was_in_room )
? ch->was_in_room->vnum
: ch->in_room->vnum );
if ( ch->plr_home != NULL )
fprintf( fp, "PlrHome %d\n", ch->plr_home->vnum );
fprintf( fp, "HpManaMove %d %d 0 0 %d %d\n",
ch->hit, ch->max_hit, ch->move, ch->max_move );
fprintf( fp, "Gold %d\n", ch->gold );
fprintf( fp, "Bank %ld\n", ch->pcdata->bank );
fprintf( fp, "Salary %d\n", ch->pcdata->salary );
fprintf( fp, "Experience %ld\n", ch->experience );
{
int ability;
for ( ability = 0 ; ability < MAX_ABILITY ; ability++ )
fprintf( fp, "Ability %d %d\n", ability , ch->class_level[ability] );
for ( ability =0; ability < MAX_NSKILL; ability++ )
fprintf( fp, "Nskill %d %d %d\n", ability, ch->skill_level[ability], ch->skill_percent[ability] );
for ( ability =0; ability < MAX_FSKILL; ability++ )
fprintf( fp, "Fskill %d %d %d\n", ability, ch->force_level[ability], ch->force_percent[ability] );
}
if ( ch->act )
fprintf( fp, "Act %d\n", ch->act );
if ( ch->pcdata->act2 )
fprintf( fp, "Act2 %d\n", ch->pcdata->act2 );
if ( ch->feats )
fprintf( fp, "Feats %d\n", ch->feats );
if ( ch->feats2 )
fprintf( fp, "Feats2 %d\n", ch->feats2 );
if ( ch->feats3 )
fprintf( fp, "Feats3 %d\n", ch->feats3 );
if ( ch->force_feats )
fprintf( fp, "Force_feats %d\n", ch->force_feats );
if ( ch->droid_feat )
fprintf( fp, "Droid_feat %d\n", ch->droid_feat );
if ( ch->affected_by )
fprintf( fp, "AffectedBy %d\n", ch->affected_by );
fprintf( fp, "Cover %d\n", ch->cover );
fprintf( fp, "Position %d\n",
ch->position == POS_FIGHTING ? POS_STANDING : ch->position );
fprintf( fp, "Cards %d\n", ch->cards );
fprintf( fp, "SavingThrows %d %d %d %d %d\n",
ch->saving_poison_death,
ch->saving_wand,
ch->saving_para_petri,
ch->saving_breath,
ch->saving_spell_staff );
fprintf( fp, "Alignment %d\n", ch->alignment );
fprintf( fp, "Glory %d\n", ch->pcdata->quest_curr );
fprintf( fp, "MGlory %d\n", ch->pcdata->quest_accum );
fprintf( fp, "Hitroll %d\n", ch->hitroll );
fprintf( fp, "Damroll %d\n", ch->damroll );
fprintf( fp, "Armor %d\n", ch->armor );
fprintf( fp, "Reputation %d\n", ch->reputation );
fprintf( fp, "Dodge_bonus %d\n", ch->dodge_bonus );
fprintf( fp, "Skillpoints %d\n", ch->skillpoints );
fprintf( fp, "Forcepoints %d\n", ch->forcepoints );
fprintf( fp, "Darkpoints %d\n", ch->darkpoints );
fprintf( fp, "Willpower %d\n", ch->willpower );
// fprintf( fp, "Homeworld %s~\n", ch->pcdata->home );
fprintf( fp, "Age %d\n", ch->pcdata->age );
fprintf( fp, "Alchemy_mod %d\n", ch->pcdata->alchemy_mod );
fprintf( fp, "Is_rep %d\n", ch->pcdata->reputation );
fprintf( fp, "Force_bonus %d\n", ch->pcdata->force_bonus );
fprintf( fp, "Force_status %d\n", ch->pcdata->force_status);
fprintf( fp, "Resources %d\n", ch->resources );
fprintf( fp, "Resources_t %d\n", ch->resources_temp );
fprintf( fp, "Xflags %d\n", ch->xflags );
fprintf( fp, "Damage_reduc %d\n", ch->damage_reduction );
fprintf( fp, "Trains %d\n", ch->trains );
fprintf( fp, "Implant %d\n", ch->implant );
fprintf( fp, "Has_master %d\n", ch->pcdata->has_master );
fprintf( fp, "Has_trained %d\n", ch->pcdata->has_trained );
fprintf( fp, "Can_invest %d\n", ch->pcdata->can_invest );
fprintf( fp, "Loan %ld\n", ch->pcdata->loan );
fprintf( fp, "Efficiency %d\n", ch->efficiency );
fprintf( fp, "Familiarity %d\n", ch->familiarity );
fprintf( fp, "Inspire_fear %d\n", ch->inspire_fear );
fprintf( fp, "Target %d\n", ch->target );
fprintf( fp, "Sneak_attack %d\n", ch->sneak_attack );
fprintf( fp, "Deflect_att %d\n", ch->deflect_attack );
fprintf( fp, "Deflect_def %d\n", ch->deflect_defense );
fprintf( fp, "Force_weapon %d\n", ch->force_weapon );
fprintf( fp, "Secret %d\n", ch->secret );
fprintf( fp, "Talisman %d\n", ch->talisman );
fprintf( fp, "Specialty %d\n", ch->specialty );
fprintf( fp, "Mastercraft %d\n", ch->mastercraft );
fprintf( fp, "Heart %d %d\n", ch->heart, ch->heart_use );
fprintf( fp, "Has_stance %d\n", ch->has_stance );
fprintf( fp, "Stance %d\n", ch->stance );
fprintf( fp, "Precise %d\n", ch->precise_attack );
fprintf( fp, "Coordinate %d\n", ch->coordinate );
fprintf( fp, "Jury_rig %d\n", ch->jury_rig );
fprintf( fp, "Lightsaber_d %d\n", ch->lightsaber_defense );
fprintf( fp, "Unused_feats %d\n", ch->unused_feats );
fprintf( fp, "Reflexes %d\n", ch->reflexes );
fprintf( fp, "Fortitude %d\n", ch->fortitude );
fprintf( fp, "Droid_type %d\n", ch->droid_type );
if ( ch->rppoints )
fprintf( fp, "Rppoints %d\n", ch->rppoints );
else
fprintf( fp, "Rppoints 0\n" );
if ( ch->wimpy )
fprintf( fp, "Wimpy %d\n", ch->wimpy );
if ( ch->deaf )
fprintf( fp, "Deaf %d\n", ch->deaf );
if ( ch->resistant )
fprintf( fp, "Resistant %d\n", ch->resistant );
if ( ch->immune )
fprintf( fp, "Immune %d\n", ch->immune );
if ( ch->susceptible )
fprintf( fp, "Susceptible %d\n", ch->susceptible );
if ( ch->pcdata && ch->pcdata->outcast_time )
fprintf( fp, "Outcast_time %ld\n",ch->pcdata->outcast_time );
if ( ch->pcdata && ch->pcdata->restore_time )
fprintf( fp, "Restore_time %ld\n",ch->pcdata->restore_time );
if ( ch->mental_state != -10 )
fprintf( fp, "Mentalstate %d\n", ch->mental_state );
if ( IS_NPC(ch) )
{
fprintf( fp, "Vnum %d\n", ch->pIndexData->vnum );
fprintf( fp, "Mobinvis %d\n", ch->mobinvis );
}
else
{
fprintf( fp, "Password %s~\n", ch->pcdata->pwd );
fprintf( fp, "Lastplayed %d\n",
(int)current_time );
if ( ch->pcdata->bamfin && ch->pcdata->bamfin[0] != '\0' )
fprintf( fp, "Bamfin %s~\n", ch->pcdata->bamfin );
if ( ch->pcdata->email && ch->pcdata->email[0] != '\0' )
fprintf( fp, "Email %s~\n", ch->pcdata->email );
if ( ch->pcdata->bamfout && ch->pcdata->bamfout[0] != '\0' )
fprintf( fp, "Bamfout %s~\n", ch->pcdata->bamfout );
if ( ch->rank && ch->rank[0] != '\0' )
fprintf( fp, "Rank %s~\n", ch->rank );
if ( ch->pcdata->fiance && ch->pcdata->fiance[0] != '\0' )
fprintf( fp, "Fiance %s~\n", ch->pcdata->fiance );
/*** Now Defunct. Still loads if seen, does not save.
if ( ch->pcdata->last_name && ch->pcdata->last_name[0] != '\0' )
fprintf( fp, "Lastname %s~\n", ch->pcdata->last_name );
***/
if ( ch->pcdata->spouse && ch->pcdata->spouse[0] != '\0' )
fprintf( fp, "Spouse %s~\n", ch->pcdata->spouse );
if (ch->pcdata->forcerank)
fprintf( fp, "forcerank %d\n", ch->pcdata->forcerank );
if ( ch->pcdata->bestowments && ch->pcdata->bestowments[0] != '\0' )
fprintf( fp, "Bestowments %s~\n", ch->pcdata->bestowments );
fprintf( fp, "Title %s~\n", ch->pcdata->title );
if ( ch->pcdata->disguise && ch->pcdata->disguise[0] != '\0' )
fprintf( fp, "Disguise %s~\n", ch->pcdata->disguise );
if ( ch->pcdata->protector && ch->pcdata->protector[0] != '\0' )
fprintf( fp, "Protector %s~\n", ch->pcdata->protector );
if ( ch->pcdata->protected && ch->pcdata->protected[0] != '\0' )
fprintf( fp, "Protected %s~\n", ch->pcdata->protected );
if ( ch->pcdata->homepage && ch->pcdata->homepage[0] != '\0' )
fprintf( fp, "Homepage %s~\n", ch->pcdata->homepage );
if ( ch->pcdata->screenname && ch->pcdata->screenname[0] != '\0' )
fprintf( fp, "Screenname %s~\n", ch->pcdata->screenname );
if ( ch->pcdata->image && ch->pcdata->image[0] != '\0' )
fprintf( fp, "Image %s~\n", ch->pcdata->image );
if ( ch->pcdata->bio && ch->pcdata->bio[0] != '\0' )
fprintf( fp, "Bio %s~\n", ch->pcdata->bio );
if ( ch->pcdata->authed_by && ch->pcdata->authed_by[0] != '\0' )
fprintf( fp, "AuthedBy %s~\n", ch->pcdata->authed_by );
if ( ch->pcdata->min_snoop )
fprintf( fp, "Minsnoop %d\n", ch->pcdata->min_snoop );
if ( ch->pcdata->prompt && *ch->pcdata->prompt )
fprintf( fp, "Prompt %s~\n", ch->pcdata->prompt );
if ( ch->pcdata->pagerlen != 24 )
fprintf( fp, "Pagerlen %d\n", ch->pcdata->pagerlen );
fprintf( fp, "Addiction ");
for ( drug = 0 ; drug <=9 ; drug++ )
fprintf( fp, " %d", ch->pcdata->addiction[drug] );
fprintf( fp, "\n");
fprintf( fp, "Druglevel ");
for ( drug = 0 ; drug <=9 ; drug++ )
fprintf( fp, " %d", ch->pcdata->drug_level[drug] );
fprintf( fp, "\n");
if ( ch->pcdata->wanted_flags )
fprintf( fp, "Wanted %d\n", ch->pcdata->wanted_flags );
if ( IS_IMMORTAL( ch ) || ch->pcdata->area )
{
fprintf( fp, "WizInvis %d\n", ch->pcdata->wizinvis );
if ( ch->pcdata->r_range_lo && ch->pcdata->r_range_hi )
fprintf( fp, "RoomRange %d %d\n", ch->pcdata->r_range_lo,
ch->pcdata->r_range_hi );
if ( ch->pcdata->o_range_lo && ch->pcdata->o_range_hi )
fprintf( fp, "ObjRange %d %d\n", ch->pcdata->o_range_lo,
ch->pcdata->o_range_hi );
if ( ch->pcdata->m_range_lo && ch->pcdata->m_range_hi )
fprintf( fp, "MobRange %d %d\n", ch->pcdata->m_range_lo,
ch->pcdata->m_range_hi );
}
if ( ch->pcdata->clan_name && ch->pcdata->clan_name[0] != '\0' )
fprintf( fp, "Clan %s~\n", ch->pcdata->clan_name );
if ( ch->pcdata->student && ch->pcdata->student[0] != '\0' )
fprintf( fp, "Student %s~\n", ch->pcdata->student );
if ( ch->pcdata->master && ch->pcdata->master[0] != '\0' )
fprintf( fp, "Master %s~\n", ch->pcdata->master );
fprintf( fp, "Flags %d\n", ch->pcdata->flags );
if ( ch->pcdata->release_date > current_time )
fprintf( fp, "Helled %d %s~\n",
(int)ch->pcdata->release_date, ch->pcdata->helled_by );
if ( ch->pcdata->pkills )
fprintf( fp, "PKills %d\n", ch->pcdata->pkills );
if ( ch->pcdata->pdeaths )
fprintf( fp, "PDeaths %d\n", ch->pcdata->pdeaths );
if ( get_timer( ch , TIMER_PKILLED)
&& ( get_timer( ch , TIMER_PKILLED) > 0 ) )
fprintf( fp, "PTimer %d\n", get_timer(ch, TIMER_PKILLED));
fprintf( fp, "MKills %d\n", ch->pcdata->mkills );
fprintf( fp, "MDeaths %d\n", ch->pcdata->mdeaths );
if ( ch->pcdata->illegal_pk )
fprintf( fp, "IllegalPK %d\n", ch->pcdata->illegal_pk );
fprintf( fp, "AttrPerm %d %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,
ch->perm_lck );
fprintf( fp, "AttrMod %d %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,
ch->mod_lck );
fprintf( fp, "Condition %d %d %d %d\n",
ch->pcdata->condition[0],
ch->pcdata->condition[1],
ch->pcdata->condition[2],
ch->pcdata->condition[3] );
if ( ch->desc && ch->desc->host )
fprintf( fp, "Site %s\n", ch->desc->host );
else
fprintf( fp, "Site (Link-Dead)\n" );
for ( sn = 1; sn < top_sn; sn++ )
{
if ( skill_table[sn]->name && ch->pcdata->learned[sn] > 0 )
switch( skill_table[sn]->type )
{
default:
fprintf( fp, "Skill %d '%s'\n",
ch->pcdata->learned[sn], skill_table[sn]->name );
break;
case SKILL_SPELL:
fprintf( fp, "Spell %d '%s'\n",
ch->pcdata->learned[sn], skill_table[sn]->name );
break;
case SKILL_WEAPON:
fprintf( fp, "Weapon %d '%s'\n",
ch->pcdata->learned[sn], skill_table[sn]->name );
break;
case SKILL_TONGUE:
fprintf( fp, "Tongue %d '%s'\n",
ch->pcdata->learned[sn], skill_table[sn]->name );
break;
}
}
}
for(bug=ch->first_bug;bug;bug=bug->next_in_bug)
fprintf( fp, "Bugged %s~\n", bug->name);
for(contract=ch->first_contract;contract;contract=contract->next_in_contract)
fprintf( fp, "Contract %s %d\n", contract->target, contract->amount);
for(fellow=ch->first_fellow;fellow;fellow=fellow->next)
fprintf( fp, "Fellow %s %s~\n", fellow->victim, fellow->knownas);
for ( quest = ch->first_quest; quest; quest = quest->next )
{
if ( quest->name == '\0' || quest->name == NULL )
continue;
fprintf( fp, "QuestData %s~ %2d\n", quest->name, quest->value );
}
for ( paf = ch->first_affect; paf; paf = paf->next )
{
if ( paf->type >= 0 && (skill=get_skilltype(paf->type)) == NULL )
continue;
if ( paf->type >= 0 && paf->type < TYPE_PERSONAL )
fprintf( fp, "AffectData '%s' %3d %3d %3d %10d\n",
skill->name,
paf->duration,
paf->modifier,
paf->location,
paf->bitvector
);
else
fprintf( fp, "Affect %3d %3d %3d %3d %10d\n",
paf->type,
paf->duration,
paf->modifier,
paf->location,
paf->bitvector
);
}
track = URANGE( 2, ((ch->top_level+3) * MAX_KILLTRACK)/LEVEL_AVATAR, MAX_KILLTRACK );
for ( sn = 0; sn < track; sn++ )
{
if ( ch->pcdata->killed[sn].vnum == 0 )
break;
fprintf( fp, "Killed %d %d\n",
ch->pcdata->killed[sn].vnum,
ch->pcdata->killed[sn].count );
}
fprintf( fp, "Has_passed %d\n", ch->pcdata->trials );
fprintf( fp, "Has_trained %d\n", ch->pcdata->has_trained );
fprintf( fp, "End\n\n" );
return;
}
/*
* Write an object and its contents.
*/
void fwrite_obj( CHAR_DATA *ch, OBJ_DATA *obj, FILE *fp, int iNest,
sh_int os_type )
{
EXTRA_DESCR_DATA *ed;
AFFECT_DATA *paf;
sh_int wear, wear_loc, x;
if ( iNest >= MAX_NEST )
{
bug( "fwrite_obj: iNest hit MAX_NEST %d", iNest );
return;
}
/*
* Slick recursion to write lists backwards,
* so loading them will load in forwards order.
*/
if ( obj->prev_content && os_type != OS_CORPSE )
fwrite_obj( ch, obj->prev_content, fp, iNest, OS_CARRY );
/*
* Catch deleted objects -Thoric
*/
if ( obj_extracted(obj) )
return;
/*
* Do NOT save prototype items! -Thoric
*/
if ( IS_OBJ_STAT( obj, ITEM_PROTOTYPE ) )
return;
/* Corpse saving. -- Altrag */
fprintf( fp, (os_type == OS_CORPSE ? "#CORPSE\n" : "#OBJECT\n") );
if ( iNest )
fprintf( fp, "Nest %d\n", iNest );
if ( obj->count > 1 )
fprintf( fp, "Count %d\n", obj->count );
if ( QUICKMATCH( obj->name, obj->pIndexData->name ) == 0 )
fprintf( fp, "Name %s~\n", obj->name );
if ( QUICKMATCH( obj->short_descr, obj->pIndexData->short_descr ) == 0 )
fprintf( fp, "ShortDescr %s~\n", obj->short_descr );
if ( QUICKMATCH( obj->description, obj->pIndexData->description ) == 0 )
fprintf( fp, "Description %s~\n", obj->description );
if ( QUICKMATCH( obj->action_desc, obj->pIndexData->action_desc ) == 0 )
fprintf( fp, "ActionDesc %s~\n", obj->action_desc );
fprintf( fp, "Vnum %d\n", obj->pIndexData->vnum );
if ( os_type == OS_CORPSE && obj->in_room )
fprintf( fp, "Room %d\n", obj->in_room->vnum );
if ( obj->extra_flags != obj->pIndexData->extra_flags )
fprintf( fp, "ExtraFlags %d\n", obj->extra_flags );
if ( obj->wear_flags != obj->pIndexData->wear_flags )
fprintf( fp, "WearFlags %d\n", obj->wear_flags );
wear_loc = -1;
for ( wear = 0; wear < MAX_WEAR; wear++ )
for ( x = 0; x < MAX_LAYERS; x++ )
if ( obj == save_equipment[wear][x] )
{
wear_loc = wear;
break;
}
else
if ( !save_equipment[wear][x] )
break;
if ( wear_loc != -1 )
fprintf( fp, "WearLoc %d\n", wear_loc );
if ( obj->item_type != obj->pIndexData->item_type )
fprintf( fp, "ItemType %d\n", obj->item_type );
if ( obj->weight != obj->pIndexData->weight )
fprintf( fp, "Weight %d\n", obj->weight );
if ( obj->level )
fprintf( fp, "Level %d\n", obj->level );
if ( obj->timer )
fprintf( fp, "Timer %d\n", obj->timer );
if ( obj->cost != obj->pIndexData->cost )
fprintf( fp, "Cost %d\n", obj->cost );
if ( obj->value[0] || obj->value[1] || obj->value[2]
|| obj->value[3] || obj->value[4] || obj->value[5] )
fprintf( fp, "Values %d %d %d %d %d %d\n",
obj->value[0], obj->value[1], obj->value[2],
obj->value[3], obj->value[4], obj->value[5] );
switch ( obj->item_type )
{
case ITEM_PILL: /* was down there with staff and wand, wrongly - Scryn */
case ITEM_POTION:
if ( IS_VALID_SN(obj->value[1]) )
fprintf( fp, "Spell 1 '%s'\n",
skill_table[obj->value[1]]->name );
if ( IS_VALID_SN(obj->value[2]) )
fprintf( fp, "Spell 2 '%s'\n",
skill_table[obj->value[2]]->name );
if ( IS_VALID_SN(obj->value[3]) )
fprintf( fp, "Spell 3 '%s'\n",
skill_table[obj->value[3]]->name );
break;
case ITEM_DEVICE:
if ( IS_VALID_SN(obj->value[3]) )
fprintf( fp, "Spell 3 '%s'\n",
skill_table[obj->value[3]]->name );
break;
case ITEM_SALVE:
if ( IS_VALID_SN(obj->value[4]) )
fprintf( fp, "Spell 4 '%s'\n",
skill_table[obj->value[4]]->name );
if ( IS_VALID_SN(obj->value[5]) )
fprintf( fp, "Spell 5 '%s'\n",
skill_table[obj->value[5]]->name );
break;
}
for ( paf = obj->first_affect; paf; paf = paf->next )
{
/*
* Save extra object affects -Thoric
*/
if ( paf->type < 0 || paf->type >= top_sn )
{
fprintf( fp, "Affect %d %d %d %d %d\n",
paf->type,
paf->duration,
((paf->location == APPLY_WEAPONSPELL
|| paf->location == APPLY_WEARSPELL
|| paf->location == APPLY_REMOVESPELL
|| paf->location == APPLY_STRIPSN)
&& IS_VALID_SN(paf->modifier))
? skill_table[paf->modifier]->slot : paf->modifier,
paf->location,
paf->bitvector
);
}
else
fprintf( fp, "AffectData '%s' %d %d %d %d\n",
skill_table[paf->type]->name,
paf->duration,
((paf->location == APPLY_WEAPONSPELL
|| paf->location == APPLY_WEARSPELL
|| paf->location == APPLY_REMOVESPELL
|| paf->location == APPLY_STRIPSN)
&& IS_VALID_SN(paf->modifier))
? skill_table[paf->modifier]->slot : paf->modifier,
paf->location,
paf->bitvector
);
}
for ( ed = obj->first_extradesc; ed; ed = ed->next )
fprintf( fp, "ExtraDescr %s~ %s~\n",
ed->keyword, ed->description );
fprintf( fp, "End\n\n" );
if ( obj->first_content )
fwrite_obj( ch, obj->last_content, fp, iNest + 1, OS_CARRY );
return;
}
/*
* Load a char and inventory into a new ch structure.
*/
bool load_char_obj( DESCRIPTOR_DATA *d, char *name, bool preload )
{
char strsave[MAX_INPUT_LENGTH];
CHAR_DATA *ch;
FILE *fp;
bool found;
struct stat fst;
int i, x;
extern FILE *fpArea;
extern char strArea[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
CREATE( ch, CHAR_DATA, 1 );
for ( x = 0; x < MAX_WEAR; x++ )
for ( i = 0; i < MAX_LAYERS; i++ )
save_equipment[x][i] = NULL;
clear_char( ch );
loading_char = ch;
CREATE( ch->pcdata, PC_DATA, 1 );
d->character = ch;
ch->desc = d;
ch->name = STRALLOC( name );
ch->act = PLR_BLANK
| PLR_COMBINE
| PLR_PROMPT;
ch->perm_str = 10;
ch->perm_int = 10;
ch->perm_wis = 10;
ch->perm_dex = 10;
ch->perm_con = 10;
ch->perm_cha = 10;
ch->perm_lck = 10;
ch->pcdata->condition[COND_THIRST] = 48;
ch->pcdata->condition[COND_FULL] = 48;
ch->pcdata->condition[COND_BLOODTHIRST] = 10;
ch->pcdata->wizinvis = 0;
ch->mental_state = -10;
ch->mobinvis = 0;
for(i = 0; i < MAX_SKILL; i++)
ch->pcdata->learned[i] = 0;
ch->pcdata->release_date = 0;
ch->pcdata->helled_by = NULL;
ch->saving_poison_death = 0;
ch->saving_wand = 0;
ch->saving_para_petri = 0;
ch->saving_breath = 0;
ch->saving_spell_staff = 0;
ch->comments = NULL; /* comments */
ch->pcdata->pagerlen = 24;
ch->mob_clan = STRALLOC( "" );
ch->was_sentinel = NULL;
ch->plr_home = NULL;
ch->pheight = 0;
ch->build = 0;
found = FALSE;
sprintf( strsave, "%s%c/%s", PLAYER_DIR, tolower(name[0]),
capitalize( name ) );
if ( stat( strsave, &fst ) != -1 )
{
if ( fst.st_size == 0 )
{
sprintf( strsave, "%s%c/%s", BACKUP_DIR, tolower(name[0]),
capitalize( name ) );
send_to_char( "Restoring your backup player file...", ch );
}
else
{
sprintf( buf, "%s player data for: %s (%dK)",
preload ? "Preloading" : "Loading", ch->name,
(int) fst.st_size/1024 );
//log_string_plus( buf, LOG_COMM, LEVEL_GREATER );
}
}
/* else no player file */
if ( ( fp = fopen( strsave, "r" ) ) != NULL )
{
int iNest;
for ( iNest = 0; iNest < MAX_NEST; iNest++ )
rgObjNest[iNest] = NULL;
found = TRUE;
/* Cheat so that bug will show line #'s -- Altrag */
fpArea = fp;
strcpy(strArea, strsave);
for ( ; ; )
{
char letter;
char *word;
letter = fread_letter( fp );
if ( letter == '*' )
{
fread_to_eol( fp );
continue;
}
if ( letter != '#' )
{
bug( "Load_char_obj: # not found.", 0 );
bug( name, 0 );
break;
}
word = fread_word( fp );
if ( !str_cmp( word, "PLAYER" ) )
{
fread_char ( ch, fp, preload );
if ( preload )
break;
}
else
if ( !str_cmp( word, "OBJECT" ) ) /* Objects */
fread_obj ( ch, fp, OS_CARRY );
else
if ( !str_cmp( word, "COMMENT") )
fread_comment(ch, fp ); /* Comments */
else
if ( !str_cmp( word, "END" ) ) /* Done */
break;
else
{
bug( "Load_char_obj: bad section.", 0 );
bug( name, 0 );
break;
}
}
fclose( fp );
fpArea = NULL;
strcpy(strArea, "$");
}
if ( !found )
{
ch->short_descr = STRALLOC( "" );
ch->long_descr = STRALLOC( "" );
ch->description = STRALLOC( "" );
ch->editor = NULL;
ch->pcdata->clan_name = STRALLOC( "" );
ch->pcdata->clan = NULL;
ch->pcdata->master = NULL;
ch->pcdata->student = NULL;
ch->pcdata->pwd = str_dup( "" );
ch->pcdata->email = str_dup( "" );
ch->pcdata->bamfin = str_dup( "" );
ch->pcdata->bamfout = str_dup( "" );
ch->rank = str_dup( "" );
ch->pcdata->shipname = str_dup( "" );
ch->pcdata->bestowments = str_dup( "" );
ch->pcdata->title = STRALLOC( "" );
ch->pcdata->disguise = STRALLOC( "" );
ch->pcdata->protector = STRALLOC( "" );
ch->pcdata->protected = STRALLOC( "" );
ch->pcdata->homepage = str_dup( "" );
ch->pcdata->screenname = str_dup( "" );
ch->pcdata->image = str_dup( "" );
ch->pcdata->bio = STRALLOC( "" );
ch->pcdata->authed_by = STRALLOC( "" );
ch->pcdata->prompt = STRALLOC( "" );
ch->pcdata->r_range_lo = 0;
ch->pcdata->r_range_hi = 0;
ch->pcdata->m_range_lo = 0;
ch->pcdata->m_range_hi = 0;
ch->pcdata->o_range_lo = 0;
ch->pcdata->o_range_hi = 0;
ch->pcdata->wizinvis = 0;
ch->pcdata->wanted_flags = 0;
}
else
{
if ( !ch->pcdata->clan_name )
{
ch->pcdata->clan_name = STRALLOC( "" );
ch->pcdata->clan = NULL;
}
if ( !ch->pcdata->bio )
ch->pcdata->bio = STRALLOC( "" );
if ( !ch->pcdata->authed_by )
ch->pcdata->authed_by = STRALLOC( "" );
if ( !IS_NPC( ch ) && get_trust( ch ) > LEVEL_AVATAR )
{
if ( ch->pcdata->wizinvis < 2 )
ch->pcdata->wizinvis = ch->top_level;
assign_area( ch );
}
if ( file_ver > 1 ){
for ( i = 0; i < MAX_WEAR; i++ )
for ( x = 0; x < MAX_LAYERS; x++ )
if ( save_equipment[i][x] )
{
equip_char( ch, save_equipment[i][x], i );
save_equipment[i][x] = NULL;
}
else
break;
}
}
loading_char = NULL;
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, bool preload )
{
char buf[MAX_STRING_LENGTH];
char *line;
char *word;
int x1, x2, x3, x4, x5, x6, x7, x8, x9, x0;
sh_int killcnt;
bool fMatch;
time_t lastplayed;
int sn, extra;
file_ver = 0;
killcnt = 0;
for ( ; ; )
{
word = feof( fp ) ? "End" : fread_word( fp );
fMatch = FALSE;
switch ( UPPER(word[0]) )
{
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;
case 'A':
KEY( "Act", ch->act, fread_number( fp ) );
KEY( "Act2", ch->pcdata->act2, fread_number( fp ) );
KEY( "AffectedBy", ch->affected_by, fread_number( fp ) );
KEY( "Age", ch->pcdata->age, fread_number( fp ) );
KEY( "Alchemy_mod", ch->pcdata->alchemy_mod,fread_number( fp ) );
KEY( "Alignment", ch->alignment, fread_number( fp ) );
KEY( "Armor", ch->armor, fread_number( fp ) );
if ( !str_cmp( word, "Addiction" ) )
{
line = fread_line( fp );
x0=x1=x2=x3=x4=x5=x6=x7=x8=x9=0;
sscanf( line, "%d %d %d %d %d %d %d %d %d %d",
&x0, &x1, &x2, &x3, &x4, &x5, &x6, &x7, &x8, &x9 );
ch->pcdata->addiction[0] = x0;
ch->pcdata->addiction[1] = x1;
ch->pcdata->addiction[2] = x2;
ch->pcdata->addiction[3] = x3;
ch->pcdata->addiction[4] = x4;
ch->pcdata->addiction[5] = x5;
ch->pcdata->addiction[6] = x6;
ch->pcdata->addiction[7] = x7;
ch->pcdata->addiction[8] = x8;
ch->pcdata->addiction[9] = x9;
fMatch = TRUE;
break;
}
if ( !str_cmp( word, "Ability" ) )
{
line = fread_line( fp );
x0=x1=0;
sscanf( line, "%d %d",
&x0, &x1 );
if ( x0 >= 0 && x0 < MAX_ABILITY )
ch->class_level[x0] = x1;
fMatch = TRUE;
break;
}
if ( !str_cmp( word, "Affect" ) || !str_cmp( word, "AffectData" ) )
{
AFFECT_DATA *paf;
if ( preload )
{
fMatch = TRUE;
fread_to_eol( fp );
break;
}
CREATE( paf, AFFECT_DATA, 1 );
if ( !str_cmp( word, "Affect" ) )
{
paf->type = fread_number( fp );
}
else
{
int sn;
char *sname = fread_word(fp);
if ( (sn=skill_lookup(sname)) < 0 )
{
if ( (sn=herb_lookup(sname)) < 0 )
bug( "Fread_char: unknown skill.", 0 );
else
sn += TYPE_HERB;
}
paf->type = sn;
}
paf->duration = fread_number( fp );
paf->modifier = fread_number( fp );
paf->location = fread_number( fp );
paf->bitvector = fread_number( fp );
LINK(paf, ch->first_affect, ch->last_affect, next, prev );
fMatch = TRUE;
break;
}
if ( !str_cmp( word, "AttrMod" ) )
{
line = fread_line( fp );
x1=x2=x3=x4=x5=x6=x7=13;
sscanf( line, "%d %d %d %d %d %d %d",
&x1, &x2, &x3, &x4, &x5, &x6, &x7 );
ch->mod_str = x1;
ch->mod_int = x2;
ch->mod_wis = x3;
ch->mod_dex = x4;
ch->mod_con = x5;
ch->mod_cha = x6;
ch->mod_lck = x7;
if (!x7)
ch->mod_lck = 0;
fMatch = TRUE;
break;
}
if ( !str_cmp( word, "AttrPerm" ) )
{
line = fread_line( fp );
x1=x2=x3=x4=x5=x6=x7=0;
sscanf( line, "%d %d %d %d %d %d %d",
&x1, &x2, &x3, &x4, &x5, &x6, &x7 );
ch->perm_str = x1;
ch->perm_int = x2;
ch->perm_wis = x3;
ch->perm_dex = x4;
ch->perm_con = x5;
ch->perm_cha = x6;
ch->perm_lck = x7;
if (!x7 || x7 == 0)
ch->perm_lck = 13;
fMatch = TRUE;
break;
}
KEY( "AuthedBy", ch->pcdata->authed_by, fread_string( fp ) );
break;
case 'B':
if (!str_cmp(word, "Bugged")){
BUG_DATA *bug;
CREATE(bug, BUG_DATA, 1);
bug->name = fread_string( fp );
LINK(bug, ch->first_bug, ch->last_bug, next_in_bug, prev_in_bug);
fMatch = TRUE;
break;
}
KEY( "Bamfin", ch->pcdata->bamfin, fread_string_nohash( fp ) );
KEY( "Bamfout", ch->pcdata->bamfout, fread_string_nohash( fp ) );
KEY( "Bestowments", ch->pcdata->bestowments, fread_string_nohash( fp ) );
KEY( "Bio", ch->pcdata->bio, fread_string( fp ) );
KEY( "Bank", ch->pcdata->bank, fread_number( fp ) );
KEY( "Build", ch->build, fread_number( fp ) );
break;
case 'C':
KEY( "Cards", ch->cards, fread_number( fp ) );
KEY( "Cover", ch->cover, fread_number( fp ) );
KEY( "Can_invest", ch->pcdata->can_invest, fread_number( fp ) );
KEY( "Coordinate", ch->coordinate, fread_number( fp ) );
if ( !str_cmp( word, "Comfreq"))
{
ch->comfreq = fread_string(fp);
fMatch = TRUE;
break;
}
if ( !str_cmp( word, "Clan" ) )
{
ch->pcdata->clan_name = fread_string( fp );
if ( !preload
&& ch->pcdata->clan_name[0] != '\0'
&& ( ch->pcdata->clan = get_clan( ch->pcdata->clan_name )) == NULL )
{
sprintf( buf, "Warning: the organization %s no longer exists, and therefore you no longer\n\rbelong to that organization.\n\r",
ch->pcdata->clan_name );
send_to_char( buf, ch );
STRFREE( ch->pcdata->clan_name );
ch->pcdata->clan_name = STRALLOC( "" );
}
fMatch = TRUE;
break;
}
if ( !str_cmp( word, "Condition" ) )
{
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 (!str_cmp(word, "Contract"))
{
char *s1;
int s2;
CONTRACT_DATA *contract;
s1 = fread_word(fp);
s2 = fread_number(fp);
CREATE(contract, CONTRACT_DATA, 1);
contract->target = str_dup(s1);
contract->amount = s2;
LINK(contract, ch->first_contract, ch->last_contract, next_in_contract, prev_in_contract);
fMatch = TRUE;
break;
}
break;
case 'D':
KEY( "Damage_reduc",ch->damage_reduction, fread_number( fp ) );
KEY( "Deflect_def", ch->deflect_defense, fread_number( fp ) );
KEY( "Deflect_att", ch->deflect_attack, fread_number( fp ) );
KEY( "Damroll", ch->damroll, fread_number( fp ) );
KEY( "Darkpoints", ch->darkpoints, fread_number( fp ) );
KEY( "Deaf", ch->deaf, fread_number( fp ) );
KEY( "Description", ch->description, fread_string( fp ) );
KEY( "Disguise", ch->pcdata->disguise, fread_string( fp ) );
KEY( "Dodge_bonus", ch->dodge_bonus, fread_number( fp ) );
KEY( "Droid_feat", ch->droid_feat, fread_number( fp ) );
KEY( "Droid_type", ch->droid_type, fread_number( fp ) );
if ( !str_cmp( word, "Druglevel" ) )
{
line = fread_line( fp );
x0=x1=x2=x3=x4=x5=x6=x7=x8=x9=0;
sscanf( line, "%d %d %d %d %d %d %d %d %d %d",
&x0, &x1, &x2, &x3, &x4, &x5, &x6, &x7, &x8, &x9 );
ch->pcdata->drug_level[0] = x0;
ch->pcdata->drug_level[1] = x1;
ch->pcdata->drug_level[2] = x2;
ch->pcdata->drug_level[3] = x3;
ch->pcdata->drug_level[4] = x4;
ch->pcdata->drug_level[5] = x5;
ch->pcdata->drug_level[6] = x6;
ch->pcdata->drug_level[7] = x7;
ch->pcdata->drug_level[8] = x8;
ch->pcdata->drug_level[9] = x9;
fMatch = TRUE;
break;
}
break;
/* 'E' was moved to after 'S' */
case 'F':
KEY( "Familiarity", ch->familiarity, fread_number( fp ) );
KEY( "Feats", ch->feats, fread_number( fp ) );
KEY( "Feats2", ch->feats2, fread_number( fp ) );
KEY( "Feats3", ch->feats3, fread_number( fp ) );
KEY( "Fortitude", ch->fortitude, fread_number( fp ) );
KEY( "Flags", ch->pcdata->flags, fread_number( fp ) );
KEY( "Fiance", ch->pcdata->fiance, fread_string( fp ) );
KEY( "Force_bonus", ch->pcdata->force_bonus,fread_number( fp ) );
KEY( "Force_weapon",ch->force_weapon, fread_number( fp ) );
KEY( "Force_feats", ch->force_feats, fread_number( fp ) );
KEY( "Forcepoints", ch->forcepoints, fread_number( fp ) );
KEY( "Force_status",ch->pcdata->force_status,fread_number( fp ) );
if ( !str_cmp( word, "Fskill" ) )
{
line = fread_line( fp );
x0=x1=x2=0;
sscanf( line, "%d %d %d",
&x0, &x1, &x2 );
if ( x0 >= 0 && x0 < MAX_FSKILL )
{
ch->force_level[x0] = x1;
ch->force_percent[x0] = x2;
}
fMatch = TRUE;
break;
}
if (!str_cmp(word, "Fellow"))
{
char *victim;
char *knownas;
FELLOW_DATA *fellow;
victim = fread_word( fp );
knownas = fread_string( fp );
CREATE(fellow, FELLOW_DATA, 1);
fellow->victim = STRALLOC(victim);
fellow->knownas = knownas;
LINK(fellow, ch->first_fellow, ch->last_fellow, next, prev);
fMatch = TRUE;
break;
}
break;
case 'G':
KEY( "Glory", ch->pcdata->quest_curr, fread_number( fp ) );
KEY( "Gold", ch->gold, fread_number( fp ) );
/* temporary measure */
if ( !str_cmp( word, "Guild" ) )
{
ch->pcdata->clan_name = fread_string( fp );
if ( !preload
&& ch->pcdata->clan_name[0] != '\0'
&& ( ch->pcdata->clan = get_clan( ch->pcdata->clan_name )) == NULL )
{
sprintf( buf, "Warning: the organization %s no longer exists, and therefore you no longer\n\rbelong to that organization.\n\r",
ch->pcdata->clan_name );
send_to_char( buf, ch );
STRFREE( ch->pcdata->clan_name );
ch->pcdata->clan_name = STRALLOC( "" );
}
fMatch = TRUE;
break;
}
break;
case 'H':
if ( !str_cmp(word, "Helled") )
{
ch->pcdata->release_date = fread_number(fp);
ch->pcdata->helled_by = fread_string(fp);
if ( ch->pcdata->release_date < current_time )
{
STRFREE(ch->pcdata->helled_by);
ch->pcdata->helled_by = NULL;
ch->pcdata->release_date = 0;
}
fMatch = TRUE;
break;
}
KEY( "Has_master", ch->pcdata->has_master, fread_number( fp ) );
KEY( "Has_trained", ch->pcdata->has_trained,fread_number( fp ) );
KEY( "Has_stance", ch->has_stance, fread_number( fp ) );
KEY( "Hitroll", ch->hitroll, fread_number( fp ) );
KEY( "Homepage", ch->pcdata->homepage, fread_string_nohash( fp ) );
// KEY( "Homeworld", ch->pcdata->home, fread_string_nohash( fp ) );
KEY( "Has_passed", ch->pcdata->trials, fread_number( fp ) );
KEY( "Has_trained", ch->pcdata->has_trained,fread_number( fp ) );
if ( !str_cmp( word, "Heart" ) )
{
line = fread_line( fp );
x1=x2=0;
sscanf( line, "%d %d",
&x1, &x2 );
ch->heart = x1;
ch->heart_use = x2;
fMatch = TRUE;
break;
}
if ( !str_cmp( word, "HpManaMove" ) )
{
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->hit = x1;
ch->max_hit = x2;
ch->move = x5;
ch->max_move = x6;
if ( x4 >= 100 )
{
ch->perm_frc = number_range( 1 , 20 );
ch->max_mana = x4;
ch->mana = x4;
}
else if ( x4 >= 10 )
{
ch->perm_frc = 1;
ch->max_mana = x4;
}
fMatch = TRUE;
break;
}
break;
case 'I':
KEY( "Implant", ch->implant, fread_number( fp ) );
KEY( "Inspire_fear",ch->inspire_fear, fread_number( fp ) );
KEY( "IllegalPK", ch->pcdata->illegal_pk, fread_number( fp ) );
KEY( "Image", ch->pcdata->image, fread_string_nohash( fp ) );
KEY( "Immune", ch->immune, fread_number( fp ) );
KEY( "Is_rep", ch->pcdata->reputation, fread_number( fp ) );
break;
case 'J':
KEY( "Jury_rig", ch->jury_rig, fread_number( fp ) );
break;
case 'K':
if ( !str_cmp( word, "Killed" ) )
{
fMatch = TRUE;
if ( killcnt >= MAX_KILLTRACK )
bug( "fread_char: killcnt (%d) >= MAX_KILLTRACK", killcnt );
else
{
ch->pcdata->killed[killcnt].vnum = fread_number( fp );
ch->pcdata->killed[killcnt++].count = fread_number( fp );
}
}
break;
case 'L':
KEY( "Loan", ch->pcdata->loan, fread_number( fp ) );
KEY( "Lightsaber_d", ch->lightsaber_defense, fread_number( fp ) );
KEY( "Lastname", ch->pcdata->last_name, fread_string( fp ) );
if ( !str_cmp(word, "Lastplayed") )
{
lastplayed = fread_number(fp);
fMatch = TRUE;
break;
}
KEY( "LongDescr", ch->long_descr, fread_string( fp ) );
if ( !str_cmp( word, "Languages" ) )
{
ch->speaks = fread_number( fp );
ch->speaking = fread_number( fp );
fMatch = TRUE;
}
break;
case 'M':
KEY( "Master", ch->pcdata->master, fread_string( fp ) );
KEY( "Mastercraft", ch->mastercraft, fread_number( fp ) );
KEY( "MDeaths", ch->pcdata->mdeaths, fread_number( fp ) );
KEY( "Mentalstate", ch->mental_state, fread_number( fp ) );
KEY( "MGlory", ch->pcdata->quest_accum,fread_number( fp ) );
KEY( "Minsnoop", ch->pcdata->min_snoop, fread_number( fp ) );
KEY( "MKills", ch->pcdata->mkills, fread_number( fp ) );
KEY( "Mobinvis", ch->mobinvis, fread_number( fp ) );
if ( !str_cmp( word, "MobRange" ) )
{
ch->pcdata->m_range_lo = fread_number( fp );
ch->pcdata->m_range_hi = fread_number( fp );
fMatch = TRUE;
}
break;
case 'N':
if ( !str_cmp( word, "Nskill" ) )
{
line = fread_line( fp );
x0=x1=x2=0;
sscanf( line, "%d %d %d",
&x0, &x1, &x2 );
if ( x0 >= 0 && x0 < MAX_NSKILL )
{
ch->skill_level[x0] = x1;
ch->skill_percent[x0] = x2;
}
fMatch = TRUE;
break;
}
if ( !str_cmp( word, "Name" ) )
{
/*
* Name already set externally.
*/
fread_to_eol( fp );
fMatch = TRUE;
break;
}
break;
case 'O':
KEY( "Outcast_time", ch->pcdata->outcast_time, fread_number( fp ) );
if ( !str_cmp( word, "ObjRange" ) )
{
ch->pcdata->o_range_lo = fread_number( fp );
ch->pcdata->o_range_hi = fread_number( fp );
fMatch = TRUE;
}
break;
case 'P':
KEY( "Pagerlen", ch->pcdata->pagerlen, fread_number( fp ) );
KEY( "Password", ch->pcdata->pwd, fread_string_nohash( fp ) );
KEY( "PDeaths", ch->pcdata->pdeaths, fread_number( fp ) );
KEY( "Pheight", ch->pheight, fread_number( fp ) );
KEY( "PKills", ch->pcdata->pkills, fread_number( fp ) );
KEY( "Played", ch->played, fread_number( fp ) );
KEY( "Position", ch->position, fread_number( fp ) );
KEY( "Practice", extra, fread_number( fp ) );
KEY( "Precise", ch->precise_attack, fread_number( fp ) );
KEY( "Prompt", ch->pcdata->prompt, fread_string( fp ) );
KEY( "Protected", ch->pcdata->protected, fread_string( fp ) );
KEY( "Protector", ch->pcdata->protector, fread_string( fp ) );
if (!str_cmp ( word, "PTimer" ) )
{
add_timer( ch , TIMER_PKILLED, fread_number(fp), NULL, 0 );
fMatch = TRUE;
break;
}
if ( !str_cmp( word, "PlrHome" ) )
{
ch->plr_home = get_room_index( fread_number( fp ) );
if ( !ch->plr_home )
ch->plr_home = NULL;
fMatch = TRUE;
break;
}
break;
case 'Q':
if ( !str_cmp( word, "QuestData" ) )
{
QUEST_DATA *quest;
CREATE( quest, QUEST_DATA, 1);
quest->name = fread_string( fp );
quest->value = fread_number( fp );
LINK(quest, ch->first_quest, ch->last_quest, next, prev);
fMatch = TRUE;
break;
}
break;
case 'R':
KEY( "Race", ch->race, fread_number( fp ) );
KEY( "Rank", ch->rank, fread_string_nohash( fp ) );
KEY( "Reflexes", ch->reflexes, fread_number( fp ) );
KEY( "Reputation", ch->reputation, fread_number( fp ) );
KEY( "Resistant", ch->resistant, fread_number( fp ) );
KEY( "Restore_time",ch->pcdata->restore_time, fread_number( fp ) );
KEY( "Resources", ch->resources, fread_number( fp ) );
KEY( "Resources_t", ch->resources_temp, fread_number( fp ) );
KEY( "Rppoints", ch->rppoints, fread_number( fp ) );
if ( !str_cmp( word, "Room" ) )
{
ch->in_room = get_room_index( fread_number( fp ) );
if ( !ch->in_room )
ch->in_room = get_room_index( ROOM_VNUM_LIMBO );
fMatch = TRUE;
break;
}
if ( !str_cmp( word, "RoomRange" ) )
{
ch->pcdata->r_range_lo = fread_number( fp );
ch->pcdata->r_range_hi = fread_number( fp );
fMatch = TRUE;
}
break;
case 'S':
KEY( "Student", ch->pcdata->student, fread_string( fp ) );
KEY( "Sneak_attack",ch->sneak_attack, fread_number( fp ) );
KEY( "Stance", ch->stance, fread_number( fp ) );
KEY( "Secret", ch->secret, fread_number( fp ) );
KEY( "Specialty", ch->specialty, fread_number( fp ) );
KEY( "Salary", ch->pcdata->salary, fread_number( fp ) );
KEY( "Screenname", ch->pcdata->screenname, fread_string_nohash( fp ) );
KEY( "Sex", ch->sex, fread_number( fp ) );
KEY( "ShipNum", ch->pcdata->shipnum, fread_number( fp ) );
KEY( "Ship", ch->pcdata->shipname, fread_string( fp ) );
KEY( "ShortDescr", ch->short_descr, fread_string( fp ) );
KEY( "Skillpoints", ch->skillpoints, fread_number( fp ) );
KEY( "Spouse", ch->pcdata->spouse, fread_string( fp ) );
KEY( "Susceptible", ch->susceptible, fread_number( fp ) );
if ( !str_cmp( word, "SavingThrow" ) )
{
ch->saving_wand = fread_number( fp );
ch->saving_poison_death = ch->saving_wand;
ch->saving_para_petri = ch->saving_wand;
ch->saving_breath = ch->saving_wand;
ch->saving_spell_staff = ch->saving_wand;
fMatch = TRUE;
break;
}
if ( !str_cmp( word, "SavingThrows" ) )
{
ch->saving_poison_death = fread_number( fp );
ch->saving_wand = fread_number( fp );
ch->saving_para_petri = fread_number( fp );
ch->saving_breath = fread_number( fp );
ch->saving_spell_staff = fread_number( fp );
fMatch = TRUE;
break;
}
if ( !str_cmp( word, "Site" ) )
{
if ( !preload )
{
sprintf( buf, "Last connected from: %s\n\r", fread_word( fp ) );
send_to_char( buf, ch );
if( file_ver < 4)
{
send_to_char("&R-=-=-=-=-=&WPLEASE READ&R=-=-=-=-=-\n\r", ch);
send_to_pager("&WIn an effort to boost player interactivity, we at FotE have decided to provide each player with 20,000 credits. This will only be given once, and if you wish the muds economy to be stronger, remember that if the credits are kept with the players, there is a larger chance of you getting credits back when you're selling a product or 'service' for you assassins and bounty hunters. So enjoy, and don't let the money go to your head. :)\n\r", ch);
send_to_pager("&R-=-=-=-=-=&WPLEASE READ&R=-=-=-=-=-\n\r", ch);
ch->gold = ch->gold + 20000;
WAIT_STATE(ch, 20*PULSE_PER_SECOND);
}
}
else
fread_to_eol( fp );
fMatch = TRUE;
if ( preload )
word = "End";
else
break;
}
if ( !str_cmp( word, "Skill" ) )
{
int value;
if ( preload )
word = "End";
else
{
value = fread_number( fp );
if ( file_ver < 3 )
sn = skill_lookup( fread_word( fp ) );
else
sn = bsearch_skill_exact( fread_word( fp ), gsn_first_skill, gsn_first_weapon-1 );
if ( sn < 0 )
bug( "Fread_char: unknown skill.", 0 );
else
{
ch->pcdata->learned[sn] = value;
}
fMatch = TRUE;
break;
}
}
if ( !str_cmp( word, "Spell" ) )
{
int sn;
int value;
if ( preload )
word = "End";
else
{
value = fread_number( fp );
sn = bsearch_skill_exact( fread_word( fp ), gsn_first_spell, gsn_first_skill-1 );
if ( sn < 0 )
bug( "Fread_char: unknown spell.", 0 );
else
{
ch->pcdata->learned[sn] = value;
}
fMatch = TRUE;
break;
}
}
if ( str_cmp( word, "End" ) )
break;
case 'E':
if ( !str_cmp( word, "End" ) )
{
if (!ch->short_descr)
ch->short_descr = STRALLOC( "" );
if (!ch->long_descr)
ch->long_descr = STRALLOC( "" );
if (!ch->description)
ch->description = STRALLOC( "" );
if (!ch->pcdata->pwd)
ch->pcdata->pwd = str_dup( "" );
if (!ch->pcdata->shipname)
ch->pcdata->shipname = str_dup( "" );
if (!ch->pcdata->email)
ch->pcdata->email = str_dup( "" );
if (!ch->pcdata->bamfin)
ch->pcdata->bamfin = str_dup( "" );
if (!ch->pcdata->bamfout)
ch->pcdata->bamfout = str_dup( "" );
if (!ch->pcdata->bio)
ch->pcdata->bio = STRALLOC( "" );
if (!ch->rank)
ch->rank = str_dup( "" );
if (!ch->pcdata->bestowments)
ch->pcdata->bestowments = str_dup( "" );
if (!ch->pcdata->title)
ch->pcdata->title = STRALLOC( "" );
if (!ch->pcdata->disguise)
ch->pcdata->disguise = STRALLOC( "" );
if (!ch->pcdata->homepage)
ch->pcdata->homepage = str_dup( "" );
if (!ch->pcdata->screenname)
ch->pcdata->screenname = str_dup( "" );
if (!ch->pcdata->image)
ch->pcdata->image = str_dup( "" );
if (!ch->pcdata->authed_by)
ch->pcdata->authed_by = STRALLOC( "" );
if (!ch->pcdata->prompt )
ch->pcdata->prompt = STRALLOC( "" );
ch->editor = NULL;
killcnt = URANGE( 2, ((ch->top_level+3) * MAX_KILLTRACK)/LEVEL_AVATAR, MAX_KILLTRACK );
if ( killcnt < MAX_KILLTRACK )
ch->pcdata->killed[killcnt].vnum = 0;
if ( !IS_IMMORTAL( ch ) && !ch->speaking )
/* ch->speaking = LANG_BASIC; */
ch->speaking = race_table[ch->race].language;
if ( IS_IMMORTAL( ch ) )
{
ch->speaks = ~0;
if ( ch->speaking == 0 )
ch->speaking = ~0;
}
if ( !ch->pcdata->prompt )
ch->pcdata->prompt = STRALLOC("");
if ( lastplayed != 0 )
{
int hitgain;
hitgain = ( ( int ) ( current_time - lastplayed ) / 60 );
ch->hit = URANGE( 1 , ch->hit + hitgain , ch->max_hit );
ch->move = URANGE( 1 , ch->move + hitgain , ch->max_move );
better_mental_state( ch , hitgain );
}
for ( sn = 0; sn < top_sn; sn++ )
{
if ( !skill_table[sn]->name )
break;
if ( skill_table[sn]->guild < 0 || skill_table[sn]->guild >= MAX_ABILITY )
continue;
}
return;
}
KEY( "Efficiency", ch->efficiency, fread_number( fp ) );
KEY( "Email", ch->pcdata->email, fread_string_nohash( fp ) );
KEY( "Experience", ch->experience, fread_number( fp ) );
break;
case 'T':
KEY( "Trains", ch->trains, fread_number( fp ) );
KEY( "Target", ch->target, fread_number( fp ) );
KEY( "Talisman", ch->talisman, fread_number( fp ) );
KEY( "Toplevel", ch->top_level, fread_number( fp ) );
if ( !str_cmp( word, "Tongue" ) )
{
int sn;
int value;
if ( preload )
word = "End";
else
{
value = fread_number( fp );
sn = bsearch_skill_exact( fread_word( fp ), gsn_first_tongue, gsn_top_sn-1 );
/* temp fix -Tawnos */
if( sn < 0 )
sn = bsearch_skill_exact("basic", gsn_first_tongue, gsn_top_sn-1 );
if ( sn < 0 )
bug( "Fread_char: unknown tongue.", 0 );
else
{
ch->pcdata->learned[sn] = value;
}
fMatch = TRUE;
}
break;
}
KEY( "Trust", ch->trust, fread_number( fp ) );
/* Let no character be trusted higher than one below maxlevel -- Narn */
ch->trust = UMIN( ch->trust, MAX_LEVEL - 1 );
if ( !str_cmp( word, "Title" ) )
{
ch->pcdata->title = fread_string( fp );
if ( isalpha(ch->pcdata->title[0])
|| isdigit(ch->pcdata->title[0]) )
{
sprintf( buf, " %s", ch->pcdata->title );
if ( ch->pcdata->title )
STRFREE( ch->pcdata->title );
ch->pcdata->title = STRALLOC( buf );
}
fMatch = TRUE;
break;
}
break;
case 'U':
KEY( "Unused_feats", ch->unused_feats, fread_number( fp ) );
break;
case 'V':
if ( !str_cmp( word, "Vnum" ) )
{
ch->pIndexData = get_mob_index( fread_number( fp ) );
fMatch = TRUE;
break;
}
KEY( "Version", file_ver, fread_number( fp ) );
break;
case 'W':
if ( !str_cmp( word, "Weapon" ) )
{
int sn;
int value;
if ( preload )
word = "End";
else
{
value = fread_number( fp );
sn = bsearch_skill_exact( fread_word( fp ), gsn_first_weapon, gsn_first_tongue-1 );
if ( sn < 0 )
bug( "Fread_char: unknown weapon.", 0 );
else
{
ch->pcdata->learned[sn] = value;
}
fMatch = TRUE;
}
break;
}
KEY( "Willpower", ch->willpower, fread_number( fp ) );
KEY( "Wimpy", ch->wimpy, fread_number( fp ) );
KEY( "WizInvis", ch->pcdata->wizinvis, fread_number( fp ) );
KEY( "Wanted", ch->pcdata->wanted_flags, fread_number( fp ) );
break;
case 'X':
KEY( "Xflags", ch->xflags, fread_number( fp ) );
break;
}
if ( !fMatch )
{
sprintf( buf, "Fread_char: no match: %s", word );
bug( buf, 0 );
}
}
}
void fread_obj( CHAR_DATA *ch, FILE *fp, sh_int os_type )
{
OBJ_DATA *obj;
char *word;
int iNest;
bool fMatch;
bool fNest;
bool fVnum;
ROOM_INDEX_DATA *room;
CREATE( obj, OBJ_DATA, 1 );
obj->count = 1;
obj->wear_loc = -1;
obj->weight = 1;
fNest = TRUE; /* Requiring a Nest 0 is a waste */
fVnum = TRUE;
iNest = 0;
for ( ; ; )
{
word = feof( fp ) ? "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" ) || !str_cmp( word, "AffectData" ) )
{
AFFECT_DATA *paf;
int pafmod;
CREATE( paf, AFFECT_DATA, 1 );
if ( !str_cmp( word, "Affect" ) )
{
paf->type = fread_number( fp );
}
else
{
int sn;
sn = skill_lookup( fread_word( fp ) );
if ( sn < 0 )
bug( "Fread_obj: unknown skill.", 0 );
else
paf->type = sn;
}
paf->duration = fread_number( fp );
pafmod = fread_number( fp );
paf->location = fread_number( fp );
paf->bitvector = fread_number( fp );
if ( paf->location == APPLY_WEAPONSPELL
|| paf->location == APPLY_WEARSPELL
|| paf->location == APPLY_REMOVESPELL )
paf->modifier = slot_lookup( pafmod );
else
paf->modifier = pafmod;
LINK(paf, obj->first_affect, obj->last_affect, next, prev );
fMatch = TRUE;
break;
}
KEY( "Actiondesc", obj->action_desc, fread_string( fp ) );
break;
case 'C':
KEY( "Cost", obj->cost, fread_number( fp ) );
KEY( "Count", obj->count, fread_number( fp ) );
break;
case 'D':
KEY( "Description", obj->description, fread_string( fp ) );
break;
case 'E':
KEY( "ExtraFlags", obj->extra_flags, fread_number( fp ) );
if ( !str_cmp( word, "ExtraDescr" ) )
{
EXTRA_DESCR_DATA *ed;
CREATE( ed, EXTRA_DESCR_DATA, 1 );
ed->keyword = fread_string( fp );
ed->description = fread_string( fp );
LINK(ed, obj->first_extradesc, obj->last_extradesc, next, prev );
fMatch = TRUE;
}
if ( !str_cmp( word, "End" ) )
{
if ( !fNest || !fVnum )
{
bug( "Fread_obj: incomplete object.", 0 );
if ( obj->name )
STRFREE( obj->name );
if ( obj->description )
STRFREE( obj->description );
if ( obj->short_descr )
STRFREE( obj->short_descr );
DISPOSE( obj );
return;
}
else
{
sh_int wear_loc = obj->wear_loc;
if ( !obj->name )
obj->name = QUICKLINK( obj->pIndexData->name );
if ( !obj->description )
obj->description = QUICKLINK( obj->pIndexData->description );
if ( !obj->short_descr )
obj->short_descr = QUICKLINK( obj->pIndexData->short_descr );
if ( !obj->action_desc )
obj->action_desc = QUICKLINK( obj->pIndexData->action_desc );
LINK(obj, first_object, last_object, next, prev );
obj->pIndexData->count += obj->count;
if ( !obj->serial )
{
cur_obj_serial = UMAX((cur_obj_serial + 1 ) & (BV30-1), 1);
obj->serial = obj->pIndexData->serial = cur_obj_serial;
}
if ( fNest )
rgObjNest[iNest] = obj;
numobjsloaded += obj->count;
++physicalobjects;
if ( file_ver > 1 || obj->wear_loc < -1
|| obj->wear_loc >= MAX_WEAR )
obj->wear_loc = -1;
/* Corpse saving. -- Altrag */
if ( os_type == OS_CORPSE )
{
if ( !room )
{
bug( "Fread_obj: Corpse without room", 0);
room = get_room_index(ROOM_VNUM_LIMBO);
}
obj = obj_to_room( obj, room );
}
else if ( iNest == 0 || rgObjNest[iNest] == NULL )
{
int slot;
bool reslot = FALSE;
if ( file_ver > 1
&& wear_loc > -1
&& wear_loc < MAX_WEAR )
{
int x;
for ( x = 0; x < MAX_LAYERS; x++ )
if ( !save_equipment[wear_loc][x] )
{
save_equipment[wear_loc][x] = obj;
slot = x;
reslot = TRUE;
break;
}
if ( x == MAX_LAYERS )
bug( "Fread_obj: too many layers %d", wear_loc );
}
obj = obj_to_char( obj, ch );
if ( reslot )
save_equipment[wear_loc][slot] = obj;
}
else
{
if ( rgObjNest[iNest-1] )
{
separate_obj( rgObjNest[iNest-1] );
obj = obj_to_obj( obj, rgObjNest[iNest-1] );
}
else
bug( "Fread_obj: nest layer missing %d", iNest-1 );
}
if ( fNest )
rgObjNest[iNest] = obj;
return;
}
}
break;
case 'I':
KEY( "ItemType", obj->item_type, fread_number( fp ) );
break;
case 'L':
KEY( "Level", obj->level, fread_number( fp ) );
break;
case 'N':
KEY( "Name", obj->name, fread_string( fp ) );
if ( !str_cmp( word, "Nest" ) )
{
iNest = fread_number( fp );
if ( iNest < 0 || iNest >= MAX_NEST )
{
bug( "Fread_obj: bad nest %d.", iNest );
iNest = 0;
fNest = FALSE;
}
fMatch = TRUE;
}
break;
case 'R':
KEY( "Room", room, get_room_index(fread_number(fp)) );
case 'S':
KEY( "ShortDescr", 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 > 5 )
bug( "Fread_obj: bad iValue %d.", iValue );
else if ( sn < 0 )
bug( "Fread_obj: unknown skill.", 0 );
else
obj->value[iValue] = sn;
fMatch = TRUE;
break;
}
break;
case 'T':
KEY( "Timer", obj->timer, fread_number( fp ) );
break;
case 'V':
if ( !str_cmp( word, "Values" ) )
{
int x1,x2,x3,x4,x5,x6;
char *ln = fread_line( fp );
x1=x2=x3=x4=x5=x6=0;
sscanf( ln, "%d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6 );
/* clean up some garbage */
if ( file_ver < 3 )
x5=x6=0;
obj->value[0] = x1;
obj->value[1] = x2;
obj->value[2] = x3;
obj->value[3] = x4;
obj->value[4] = x5;
obj->value[5] = x6;
fMatch = TRUE;
break;
}
if ( !str_cmp( word, "Vnum" ) )
{
int vnum;
vnum = fread_number( fp );
if ( ( obj->pIndexData = get_obj_index( vnum ) ) == NULL )
{
fVnum = FALSE;
bug( "Fread_obj: bad vnum %d.", vnum );
}
else
{
fVnum = TRUE;
obj->cost = obj->pIndexData->cost;
obj->weight = obj->pIndexData->weight;
obj->item_type = obj->pIndexData->item_type;
obj->wear_flags = obj->pIndexData->wear_flags;
obj->extra_flags = obj->pIndexData->extra_flags;
}
fMatch = TRUE;
break;
}
break;
case 'W':
KEY( "WearFlags", obj->wear_flags, fread_number( fp ) );
KEY( "WearLoc", obj->wear_loc, fread_number( fp ) );
KEY( "Weight", obj->weight, fread_number( fp ) );
break;
}
if ( !fMatch )
{
EXTRA_DESCR_DATA *ed;
AFFECT_DATA *paf;
bug( "Fread_obj: no match.", 0 );
bug( word, 0 );
fread_to_eol( fp );
if ( obj->name )
STRFREE( obj->name );
if ( obj->description )
STRFREE( obj->description );
if ( obj->short_descr )
STRFREE( obj->short_descr );
while ( (ed=obj->first_extradesc) != NULL )
{
STRFREE( ed->keyword );
STRFREE( ed->description );
UNLINK( ed, obj->first_extradesc, obj->last_extradesc, next, prev );
DISPOSE( ed );
}
while ( (paf=obj->first_affect) != NULL )
{
UNLINK( paf, obj->first_affect, obj->last_affect, next, prev );
DISPOSE( paf );
}
DISPOSE( obj );
return;
}
}
}
void set_alarm( long seconds )
{
alarm( seconds );
}
/*
* Based on last time modified, show when a player was last on -Thoric
*/
void do_last( CHAR_DATA *ch, char *argument )
{
char buf [MAX_STRING_LENGTH];
char arg [MAX_INPUT_LENGTH];
char name[MAX_INPUT_LENGTH];
struct stat fst;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "Usage: last <playername>\n\r", ch );
return;
}
if(strstr(argument,"."))
{
send_to_char("Nope.\n\r", ch);
return;
}
strcpy( name, capitalize(arg) );
sprintf( buf, "%s%c/%s", PLAYER_DIR, tolower(arg[0]), name );
if ( stat( buf, &fst ) != -1 )
sprintf( buf, "%s was last on: %s\r", name, ctime( &fst.st_mtime ) );
else
sprintf( buf, "%s was not found.\n\r", name );
send_to_char( buf, ch );
}
void write_corpses( CHAR_DATA *ch, char *name )
{
OBJ_DATA *corpse;
FILE *fp = NULL;
/* Name and ch support so that we dont have to have a char to save their
corpses.. (ie: decayed corpses while offline) */
if ( ch && IS_NPC(ch) )
{
bug( "Write_corpses: writing NPC corpse.", 0 );
return;
}
if ( ch )
name = ch->name;
/* Go by vnum, less chance of screwups. -- Altrag */
for ( corpse = first_object; corpse; corpse = corpse->next )
if ( corpse->pIndexData->vnum == OBJ_VNUM_CORPSE_PC &&
corpse->in_room != NULL &&
!str_cmp(corpse->short_descr+14, name) )
{
if ( !fp )
{
char buf[127];
sprintf(buf, "%s%s", CORPSE_DIR, capitalize(name));
if ( !(fp = fopen(buf, "w")) )
{
bug( "Write_corpses: Cannot open file.", 0 );
perror(buf);
return;
}
}
fwrite_obj(ch, corpse, fp, 0, OS_CORPSE);
}
if ( fp )
{
fprintf(fp, "#END\n\n");
fclose(fp);
}
else
{
char buf[127];
sprintf(buf, "%s%s", CORPSE_DIR, capitalize(name));
remove(buf);
}
return;
}
void load_corpses( void )
{
DIR *dp;
struct direct *de;
extern FILE *fpArea;
extern char strArea[MAX_INPUT_LENGTH];
extern int falling;
if ( !(dp = opendir(CORPSE_DIR)) )
{
bug( "Load_corpses: can't open CORPSE_DIR", 0);
perror(CORPSE_DIR);
return;
}
falling = 1; /* Arbitrary, must be >0 though. */
while ( (de = readdir(dp)) != NULL )
{
if ( de->d_name[0] != '.' )
{
sprintf(strArea, "%s%s", CORPSE_DIR, de->d_name );
fprintf(stderr, "Corpse -> %s\n", strArea);
if ( !(fpArea = fopen(strArea, "r")) )
{
perror(strArea);
continue;
}
for ( ; ; )
{
char letter;
char *word;
letter = fread_letter( fpArea );
if ( letter == '*' )
{
fread_to_eol(fpArea);
continue;
}
if ( letter != '#' )
{
bug( "Load_corpses: # not found.", 0 );
break;
}
word = fread_word( fpArea );
if ( !str_cmp(word, "CORPSE" ) )
fread_obj( NULL, fpArea, OS_CORPSE );
else if ( !str_cmp(word, "OBJECT" ) )
fread_obj( NULL, fpArea, OS_CARRY );
else if ( !str_cmp( word, "END" ) )
break;
else
{
bug( "Load_corpses: bad section.", 0 );
break;
}
}
fclose(fpArea);
}
}
fpArea = NULL;
strcpy(strArea, "$");
closedir(dp);
falling = 0;
return;
}
void save_profile( CHAR_DATA *ch )
{
char strprofile[MAX_INPUT_LENGTH];
FILE *fp;
if ( !ch )
{
bug( "save_profile: null ch!", 0 );
return;
}
if ( IS_NPC(ch) || NOT_AUTHED(ch) )
return;
sprintf( strprofile, "%s%s.htm", PROFILE_DIR, capitalize( ch->name ) );
if ( ( fp = fopen( strprofile, "w" ) ) == NULL )
{
bug( "Save_profile: fopen", 0 );
perror( strprofile );
}
else
{
char image[MAX_INPUT_LENGTH];
char sex[MAX_INPUT_LENGTH];
char email[MAX_INPUT_LENGTH];
char homepage[MAX_INPUT_LENGTH];
char aimname[MAX_INPUT_LENGTH];
char desc[MAX_STRING_LENGTH];
char bio[MAX_STRING_LENGTH];
bool pageurl=TRUE;
bool emailurl=TRUE;
bool aimurl=TRUE;
if(ch->pcdata->image && ch->pcdata->image[0] != '\0')
sprintf(image, "%s", show_tilde(ch->pcdata->image));
else
sprintf(image, "../grx/noimage.gif");
if(ch->sex == 1)
sprintf(sex, "Male");
else if(ch->sex == 2)
sprintf(sex, "Female");
else
sprintf(sex, "Neutral");
if(ch->pcdata->email && ch->pcdata->email[0] != '\0')
sprintf(email, "%s", ch->pcdata->email);
else
{
sprintf(email, "Not Specified.");
emailurl = FALSE;
}
if(ch->pcdata->homepage && ch->pcdata->homepage[0] != '\0')
{
sprintf(homepage, "%s", show_tilde(ch->pcdata->homepage));
}
else
{
sprintf(homepage, "Not Specified.");
pageurl = FALSE;
}
if(ch->pcdata->screenname && ch->pcdata->screenname[0] != '\0')
sprintf(aimname, "%s", ch->pcdata->screenname);
else
{
sprintf(aimname, "Not Specified.");
aimurl = FALSE;
}
if(ch->description && ch->description[0] != '\0')
sprintf(desc, "%s", ch->description);
else
sprintf(desc, "Not Specified.");
if(ch->pcdata->bio && ch->pcdata->bio[0] != '\0')
sprintf(bio, "%s", ch->pcdata->bio);
else
sprintf(bio, "None.");
fprintf(fp, "<HTML>\n");
fprintf(fp, "<HEAD>\n");
fprintf(fp, "<title>SW:FotE Player Database</title>");
fprintf(fp, "<style type='text/css'>\n");
fprintf(fp, "body{ font-family: Verdana;}\n");
fprintf(fp, ".maintable{border: 1px solid #990000; font-size: 10pt;}\n");
fprintf(fp, ".middletd{border-bottom: 1px solid #990000;}\n");
fprintf(fp, ".imagetd{border-right: 1px solid #990000; border-bottom: 1px solid #990000;}\n");
fprintf(fp, "a{ color: #FF0000;}\n");
fprintf(fp, "a:hover{ text-decoration: underline }\n");
fprintf(fp, "</style>\n");
fprintf(fp, "</HEAD>\n");
fprintf(fp, "<BODY bgcolor='black' text='white'>\n");
fprintf(fp, "<table class='maintable' width='90%%' cellpadding='5' cellspacing='0'>\n");
fprintf(fp, "<tr>\n");
fprintf(fp, "<td class='imagetd' rowspan='6' width='205'><img src='%s' width='200'></td>\n", image);
fprintf(fp, "<td class='middletd'> Name: %s</td>\n", ch->name);
fprintf(fp, "</tr>\n<tr>\n");
fprintf(fp, "<td class='middletd'> Race: %s </td>\n", race_table[ch->race].race_name);
fprintf(fp, "</tr>\n<tr>\n");
fprintf(fp, "<td class='middletd'> Sex: %s </td>\n", sex);
fprintf(fp, "</tr>\n<tr>\n");
if(emailurl)
fprintf(fp, "<td class='middletd'> Email: <a href='mailto:%s'>%s</a></td>\n", email, email);
else
fprintf(fp, "<td class='middletd'> Email: Not Specified.</td>\n");
fprintf(fp, "</tr>\n<tr>\n");
if(pageurl)
fprintf(fp, "<td class='middletd'> Homepage: <a href='%s' target='new'>%s</a></td>\n", homepage, homepage);
else
fprintf(fp, "<td class='middletd'> Homepage: Not Specified.</td>");
fprintf(fp, "</tr>\n<tr>\n");
if(aimurl)
fprintf(fp, "<td class='middletd'> AIM Screenname: <a href='aim:goim?screenname=%s'>%s</a></td>\n", aimname, aimname);
else
fprintf(fp, "<td class='middletd'> AIM Screenname: Not Specified.</td>\n");
fprintf(fp, "</tr>\n<tr>\n");
fprintf(fp, "<td colspan='2' class='middletd'>\n");
fprintf(fp, "Description: <PRE>%s</PRE>\n", htmlcolor(desc));
fprintf(fp, "</td>\n</tr>\n<tr>\n");
fprintf(fp, "<td colspan='2'>\n");
fprintf(fp, "Biography: <PRE>%s</PRE>\n", htmlcolor(bio));
fprintf(fp, "</td>\n</tr>\n</table>\n");
fprintf(fp, "</BODY></HTML>");
fclose(fp);
}
return;
}