/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// * * -----------------------------------------------------------| (0...0) * * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( * * -----------------------------------------------------------| {o o} * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ * * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~* * Tricops and Fireblade | * * ------------------------------------------------------------------------ * * 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{rfeldt, Tom Madsen, and Katja Nyboe. * * ------------------------------------------------------------------------ * * Character saving and loading module * ****************************************************************************/ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <string.h> #include <time.h> #include <sys/stat.h> #ifndef WIN32 #include <dirent.h> #endif #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 ); bool check_parse_name args( ( char *name, bool newchar ) ); extern char *GfpName; extern bool StopFP; void transStatApply( CHAR_DATA * ch, int strMod, int spdMod, int intMod, int conMod ); /* * 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, OBJ_DATA * objrem ) ); #ifdef WIN32 /* NJG */ UINT timer_code = 0; /* needed to kill the timer */ /* Note: need to include: WINMM.LIB to link to timer functions */ void caught_alarm( ); void CALLBACK alarm_handler( UINT IDEvent, /* identifies timer event */ UINT uReserved, /* not used */ DWORD dwUser, /* application-defined instance data */ DWORD dwReserved1, /* not used */ DWORD dwReserved2 ) /* not used */ { caught_alarm( ); } void kill_timer( ) { if( timer_code ) timeKillEvent( timer_code ); timer_code = 0; } #endif void fixTransStatAffects( CHAR_DATA * ch ) { AFFECT_DATA *tAff; if( !ch->first_affect ) return; for( tAff = ch->first_affect; tAff; tAff = tAff->next ) { if( tAff->affLocator == LOC_TRANS_STAT_APPLY ) { switch ( tAff->location ) { case APPLY_STR: ch->mod_str += tAff->modifier; break; case APPLY_DEX: ch->mod_dex += tAff->modifier; break; case APPLY_INT: ch->mod_int += tAff->modifier; break; case APPLY_CON: ch->mod_con += tAff->modifier; break; } } } return; } /* * 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 ) { if( ch->exp >= obj->level ) { 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 ); } } else { sprintf( buf, "%s had on %s: ch->exp = %.0Lf obj->level = %.0Lf", ch->name, obj->name, ch->exp, obj->level ); 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; if( ch->desc && ch->desc->original ) ch = ch->desc->original; de_equip_char( ch ); ch->save_time = current_time; sprintf( strsave, "%s%c/%s", PLAYER_DIR, tolower( ch->pcdata->filename[0] ), capitalize( ch->pcdata->filename ) ); /* * Auto-backup pfile (can cause lag with high disk access situtations). */ /* * Backup of each pfile on save as above can cause lag in high disk * access situations on big muds like Realms. Quitbackup saves most * of that and keeps an adequate backup -- Blodkai, 10/97 */ if( IS_SET( sysdata.save_flags, SV_BACKUP ) || ( IS_SET( sysdata.save_flags, SV_QUITBACKUP ) && quitting_char == ch ) ) { sprintf( strback, "%s%c/%s", BACKUP_DIR, tolower( ch->pcdata->filename[0] ), capitalize( ch->pcdata->filename ) ); rename( strsave, strback ); } /* * 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( ch->level >= LEVEL_IMMORTAL ) { sprintf( strback, "%s%s", GOD_DIR, capitalize( ch->pcdata->filename ) ); if( ( fp = fopen( strback, "w" ) ) == NULL ) { perror( strsave ); bug( "Save_god_level: fopen", 0 ); } else { fprintf( fp, "Level %d\n", ch->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 ); if( ch->pcdata->email && ch->pcdata->email[0] != '\0' ) fprintf( fp, "Email %s~\n", ch->pcdata->email ); if( ch->pcdata->icq > 0 ) fprintf( fp, "ICQ %d\n", ch->pcdata->icq ); fprintf( fp, "End\n" ); fclose( fp ); } } if( ( fp = fopen( TEMP_FILE, "w" ) ) == NULL ) { perror( strsave ); bug( "Save_char_obj: fopen", 0 ); } else { bool ferr; fwrite_char( ch, fp ); if( ch->morph ) fwrite_morph_data( ch, fp ); if( ch->first_carrying ) fwrite_obj( ch, ch->last_carrying, fp, 0, OS_CARRY ); if( sysdata.save_pets && ch->pcdata->pet ) fwrite_mobile( fp, ch->pcdata->pet ); if( ch->comments ) /* comments */ fwrite_comments( ch, fp ); /* comments */ fprintf( fp, "#END\n" ); ferr = ferror( fp ); fclose( fp ); if( ferr ) { perror( strsave ); bug( "Error writing temp file for %s -- not copying", strsave ); } else rename( TEMP_FILE, strsave ); } re_equip_char( ch ); quitting_char = NULL; saving_char = NULL; return; } /* * Write the char. */ void fwrite_char( CHAR_DATA * ch, FILE * fp ) { AFFECT_DATA *paf; int sn, track, i; sh_int pos; SKILLTYPE *skill = NULL; fprintf( fp, "#PLAYER\n" ); fprintf( fp, "Version %d\n", SAVEVERSION ); fprintf( fp, "Name %s~\n", ch->name ); if( ch->pcdata->last_name && strlen( ch->pcdata->last_name ) >= 3 ) fprintf( fp, "Last_Name %s~\n", ch->pcdata->last_name ); if( ch->pcdata->creation_date == 0 ) fprintf( fp, "Creation_date %d\n", ( int )current_time ); else fprintf( fp, "Creation_date %d\n", ( int )ch->pcdata->creation_date ); fprintf( fp, "C_date_word %s~\n", ctime( &ch->pcdata->creation_date ) ); if( ch->description[0] != '\0' ) fprintf( fp, "Description %s~\n", ch->description ); if( ch->pcdata->description1[0] != '\0' ) fprintf( fp, "Description1 %s~\n", ch->pcdata->description1 ); if( ch->pcdata->description2[0] != '\0' ) fprintf( fp, "Description2 %s~\n", ch->pcdata->description2 ); if( ch->pcdata->description3[0] != '\0' ) fprintf( fp, "Description3 %s~\n", ch->pcdata->description3 ); if( ch->pcdata->description4[0] != '\0' ) fprintf( fp, "Description4 %s~\n", ch->pcdata->description4 ); if( ch->pcdata->description5[0] != '\0' ) fprintf( fp, "Description5 %s~\n", ch->pcdata->description5 ); fprintf( fp, "Sex %d\n", ch->sex ); fprintf( fp, "Class %d\n", ch->class ); fprintf( fp, "Race %d\n", ch->race ); fprintf( fp, "Languages %d %d\n", ch->speaks, ch->speaking ); fprintf( fp, "Level %d\n", ch->level ); fprintf( fp, "UpgradeL %d\n", ch->pcdata->upgradeL ); fprintf( fp, "Played %d\n", ch->played + ( int )( current_time - ch->logon ) ); 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 ); fprintf( fp, "HpManaMove %d %d %d %d %d %d\n", ch->hit, ch->max_hit, ch->mana, ch->max_mana, ch->move, ch->max_move ); fprintf( fp, "Zeni %d\n", ch->gold ); fprintf( fp, "Exp %.0Lf\n", ch->exp ); fprintf( fp, "PL %.0Lf\n", ch->pl ); if( ch->race == 1 ) fprintf( fp, "HeartPL %.0Lf\n", ch->heart_pl ); if( ( ( is_saiyan( ch ) || is_hb( ch ) ) && ch->exp > 8000000 ) || ( is_bio( ch ) && ch->exp > 7500000 ) ) fprintf( fp, "Rage %d\n", ch->rage ); fprintf( fp, "Corespl %0.Lf\n", ch->corespl ); fprintf( fp, "Cores %d %d %d\n", ( ( ch->fm_core ) ? 1 : 0 ), ( ( ch->e_core ) ? 1 : 0 ), ( ( ch->h_core ) ? 1 : 0 ) ); fprintf( fp, "Canmajin %d\n", ( ( ch->canmajin ) ? 1 : 0 ) ); fprintf( fp, "Fusionflags %d\n", ch->fusionflags ); fprintf( fp, "Fusions %d\n", ch->fusions ); fprintf( fp, "Fusiontimer %d\n", ch->fusiontimer ); if( ch->fusions > 0 ) { int b = 0; for( b = 0; b < ch->fusions; b++ ) { fprintf( fp, "Fused %d %s~\n", b, ch->fused[b] ); } fprintf( fp, "Bck_name %s~\n", ch->bck_name ); fprintf( fp, "Bck_pl %0.Lf\n", ch->bck_pl ); fprintf( fp, "Bck_race %d\n", ch->bck_race ); } if( ch->rank > 0 ) fprintf( fp, "Rank %d\n", ch->rank ); fprintf( fp, "Evilmod %d\n", ch->evilmod ); fprintf( fp, "Height %d\n", ch->height ); fprintf( fp, "Weight %d\n", ch->weight ); if( !xIS_EMPTY( ch->act ) ) fprintf( fp, "Act %s\n", print_bitvector( &ch->act ) ); if( ch->pcdata->combatFlags != 0 ) fprintf( fp, "CombatFlags %d\n", ch->pcdata->combatFlags ); if( !xIS_EMPTY( ch->affected_by ) ) fprintf( fp, "AffectedBy %s\n", print_bitvector( &ch->affected_by ) ); if( !xIS_EMPTY( ch->no_affected_by ) ) fprintf( fp, "NoAffectedBy %s\n", print_bitvector( &ch->no_affected_by ) ); /* * Strip off fighting positions & store as * new style (pos>=100 flags new style in character loading) */ pos = ch->position; if( pos == POS_BERSERK || pos == POS_AGGRESSIVE || pos == POS_FIGHTING || pos == POS_DEFENSIVE || pos == POS_EVASIVE ) pos = POS_STANDING; pos += 100; fprintf( fp, "Position %d\n", pos ); fprintf( fp, "Style %d\n", ch->style ); /* fprintf( fp, "Practice %d\n", ch->practice ); fprintf( fp, "MaxPrac %d\n", ch->max_prac ); */ fprintf( fp, "Train %d\n", ch->train ); fprintf( fp, "MaxTrain %d\n", ch->max_train ); fprintf( fp, "XTrain %d\n", ch->pcdata->xTrain ); fprintf( fp, "TotalXTrain %d\n", ch->pcdata->total_xTrain ); fprintf( fp, "MaxEnergy %d\n", ch->max_energy ); fprintf( fp, "Powerup %d\n", ch->powerup ); 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, "Favor %d\n", ch->pcdata->favor ); 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, "NaturalAC %d\n", ch->pcdata->natural_ac_max ); if( ch->wimpy ) fprintf( fp, "Wimpy %d\n", ch->wimpy ); if( !xIS_EMPTY( ch->deaf ) ) fprintf( fp, "Deaf %s\n", print_bitvector( &ch->deaf ) ); if( ch->pcdata->imc_deaf ) fprintf( fp, "IMC %ld\n", ch->pcdata->imc_deaf ); if( ch->pcdata->imc_allow ) fprintf( fp, "IMCAllow %ld\n", ch->pcdata->imc_allow ); if( ch->pcdata->imc_deny ) fprintf( fp, "IMCDeny %ld\n", ch->pcdata->imc_deny ); fprintf( fp, "ICEListen %s~\n", ch->pcdata->ice_listen ); if( ch->resistant ) fprintf( fp, "Resistant %d\n", ch->resistant ); if( ch->no_resistant ) fprintf( fp, "NoResistant %d\n", ch->no_resistant ); if( ch->immune ) fprintf( fp, "Immune %d\n", ch->immune ); if( ch->no_immune ) fprintf( fp, "NoImmune %d\n", ch->no_immune ); if( ch->susceptible ) fprintf( fp, "Susceptible %d\n", ch->susceptible ); if( ch->no_susceptible ) fprintf( fp, "NoSusceptible %d\n", ch->no_susceptible ); if( ch->pcdata && ch->pcdata->outcast_time ) fprintf( fp, "Outcast_time %ld\n", ch->pcdata->outcast_time ); if( ch->pcdata && ch->pcdata->nuisance ) fprintf( fp, "NuisanceNew %ld %ld %d %d\n", ch->pcdata->nuisance->time, ch->pcdata->nuisance->max_time, ch->pcdata->nuisance->flags, ch->pcdata->nuisance->power ); if( ch->mental_state != -10 ) fprintf( fp, "Mentalstate %d\n", ch->mental_state ); fprintf( fp, "Password %s~\n", ch->pcdata->pwd ); if( ch->pcdata->bestowments && ch->pcdata->bestowments[0] != '\0' ) fprintf( fp, "Bestowments %s~\n", ch->pcdata->bestowments ); if( ch->pcdata->pretitle && ch->pcdata->pretitle[0] != '\0' ) fprintf( fp, "Pretitle %s~\n", ch->pcdata->pretitle ); fprintf( fp, "Title %s~\n", ch->pcdata->title ); if( ch->pcdata->homepage && ch->pcdata->homepage[0] != '\0' ) fprintf( fp, "Homepage %s~\n", ch->pcdata->homepage ); if( ch->pcdata->email && ch->pcdata->email[0] != '\0' ) /* Samson 4-19-98 */ fprintf( fp, "Email %s~\n", ch->pcdata->email ); if( ch->pcdata->icq > 0 ) /* Samson 1-4-99 */ fprintf( fp, "ICQ %d\n", ch->pcdata->icq ); 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->fprompt && *ch->pcdata->fprompt ) fprintf( fp, "FPrompt %s~\n", ch->pcdata->fprompt ); if( ch->pcdata->pagerlen != 24 ) fprintf( fp, "Pagerlen %d\n", ch->pcdata->pagerlen ); /* * Save note board status */ /* * Save number of boards in case that number changes */ fprintf( fp, "Boards %d ", MAX_BOARD ); for( i = 0; i < MAX_BOARD; i++ ) fprintf( fp, "%s %ld ", boards[i].short_name, ch->pcdata->last_note[i] ); fprintf( fp, "\n" ); /* * If ch is ignoring players then store those players */ { IGNORE_DATA *temp; for( temp = ch->pcdata->first_ignored; temp; temp = temp->next ) { fprintf( fp, "Ignored %s~\n", temp->name ); } } if( IS_IMMORTAL( ch ) ) { if( ch->pcdata->bamfin && ch->pcdata->bamfin[0] != '\0' ) fprintf( fp, "Bamfin %s~\n", ch->pcdata->bamfin ); if( ch->pcdata->bamfout && ch->pcdata->bamfout[0] != '\0' ) fprintf( fp, "Bamfout %s~\n", ch->pcdata->bamfout ); /* if ( ch->trust ) fprintf( fp, "Trust %d\n", ch->trust );*/ if( ch->pcdata && ch->pcdata->restore_time ) fprintf( fp, "Restore_time %ld\n", ch->pcdata->restore_time ); fprintf( fp, "WizInvis %d\n", ch->pcdata->wizinvis ); fprintf( fp, "Ghost %d\n", ch->pcdata->ghost_level ); fprintf( fp, "Incog %d\n", ch->pcdata->incog_level ); 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->council ) fprintf( fp, "Council %s~\n", ch->pcdata->council_name ); if( ch->pcdata->deity_name && ch->pcdata->deity_name[0] != '\0' ) fprintf( fp, "Deity %s~\n", ch->pcdata->deity_name ); if( ch->pcdata->clan_name && ch->pcdata->clan_name[0] != '\0' ) { fprintf( fp, "Clan %s~\n", ch->pcdata->clan_name ); fprintf( fp, "ClanRank %d\n", ch->pcdata->clanRank ); fprintf( fp, "ClanZeniDon %f\n", ch->pcdata->clanZeniDonated ); fprintf( fp, "ClanZeniTax %f\n", ch->pcdata->clanZeniClanTax ); fprintf( fp, "ClanItemsDon %d\n", ch->pcdata->clanItemsDonated ); } fprintf( fp, "Flags %d\n", ch->pcdata->flags ); if( ch->pcdata->release_date ) fprintf( fp, "Helled %d %s~\n", ( int )ch->pcdata->release_date, ch->pcdata->helled_by ); if( ch->pcdata->gnote_date ) fprintf( fp, "Nognote %d\n", ( int )ch->pcdata->gnote_date ); if( ch->pcdata->nextHBTCDate > 0 ) fprintf( fp, "NextHBTC %d\n", ( int )ch->pcdata->nextHBTCDate ); if( ch->pcdata->nextspartime > 0 ) fprintf( fp, "Nextspar %d\n", ( int )ch->pcdata->nextspartime ); if( ch->pcdata->HBTCTimeLeft > 0 ) fprintf( fp, "HBTCLeft %d\n", ch->pcdata->HBTCTimeLeft ); if( ch->pcdata->lastTaxation > 0 ) fprintf( fp, "LastTax %d\n", ( int )ch->pcdata->lastTaxation ); fprintf( fp, "PKills %d\n", ch->pcdata->pkills ); 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 ); fprintf( fp, "IllegalPK %d\n", ch->pcdata->illegal_pk ); fprintf( fp, "SparWins %d\n", ch->pcdata->spar_wins ); fprintf( fp, "SparLoss %d\n", ch->pcdata->spar_loss ); fprintf( fp, "Sparcount %d\n", ch->pcdata->sparcount ); fprintf( fp, "Bounty %d\n", ch->pcdata->bounty ); fprintf( fp, "Bowed %d\n", ch->pcdata->bowed ); fprintf( fp, "Bkills %d\n", ch->pcdata->bkills ); fprintf( fp, "B_timeleft %d\n", ch->pcdata->b_timeleft ); if( ch->pcdata->bounty_by ) fprintf( fp, "BountyBy %s~\n", ch->pcdata->bounty_by ); if( ch->pcdata->hunting ) fprintf( fp, "Hunting %s~\n", ch->pcdata->hunting ); if( ch->pcdata->gohometimer != 0 ) fprintf( fp, "Gohome %d\n", ch->pcdata->gohometimer ); if( get_true_rank( ch ) >= 11 ) { fprintf( fp, "KaiTimer %d\n", ch->pcdata->eKTimer ); fprintf( fp, "KaiMessage %s~\n", ch->pcdata->kaiRestoreMsg ); } fprintf( fp, "Silence %d\n", ch->pcdata->silence ); if( ch->pcdata->silence != 0 ) fprintf( fp, "Silencedby %s~\n", ch->pcdata->silencedby ); fprintf( fp, "PK_timer %d\n", ch->pcdata->pk_timer ); fprintf( fp, "Age %d\n", ch->pcdata->age ); fprintf( fp, "Build %d\n", ch->pcdata->build ); fprintf( fp, "Haircolor %d\n", ch->pcdata->haircolor ); fprintf( fp, "Orignalhaircolor %d\n", ch->pcdata->orignalhaircolor ); fprintf( fp, "Eyes %d\n", ch->pcdata->eyes ); fprintf( fp, "Orignaleyes %d\n", ch->pcdata->orignaleyes ); fprintf( fp, "AuraPowerUp %d\n", ch->pcdata->auraColorPowerUp ); fprintf( fp, "Complexion %d\n", ch->pcdata->complexion ); fprintf( fp, "Secondarycolor %d\n", ch->pcdata->secondarycolor ); fprintf( fp, "Hairstyle %d\n", ch->pcdata->hairstyle ); fprintf( fp, "Hairlen %d\n", ch->pcdata->hairlen ); fprintf( fp, "Tail %d\n", ch->pcdata->tail ); fprintf( fp, "Suppress %.0Lf\n", ch->pcdata->suppress ); fprintf( fp, "Spouse %s~\n", ch->pcdata->spouse ); fprintf( fp, "Auction_PL %.0Lf\n", ch->pcdata->auction_pl ); fprintf( fp, "NPromptCFG %d\n", ch->pcdata->normalPromptConfig ); fprintf( fp, "BPromptCFG %d\n", ch->pcdata->battlePromptConfig ); fprintf( fp, "AttrPerm %d %d %d %d %d\n", ch->perm_str, ch->perm_int, ch->perm_dex, ch->perm_con, ch->perm_lck ); /* * For the android enhance command, so that the base * stats can be modified without interfering with * transformations. At the time, only str and dex * are needed here. The other stats are added just in * case of any future need for them. I also realise that * this is the sort of thing that AttrMod is for, however * I am creating this seperately to avoid any conflicts with * pre-existing code. -Karma. */ fprintf( fp, "AttrAdd %d %d %d %d %d\n", ch->add_str, ch->add_dex, ch->add_int, ch->add_con, ch->add_lck ); fprintf( fp, "PermTStats %d %d %d %d\n", ch->pcdata->permTstr, ch->pcdata->permTint, ch->pcdata->permTspd, ch->pcdata->permTcon ); fprintf( fp, "AttrTrain %d %d %d %d\n", ch->pcdata->tStr, ch->pcdata->tInt, ch->pcdata->tSpd, ch->pcdata->tCon ); fprintf( fp, "AttrMod 0 0 0 0 0\n" ); /* fprintf( fp, "AttrMod %d %d %d %d %d\n", ch->mod_str - ch->perm_str, ch->mod_int - ch->perm_int, ch->mod_dex - ch->perm_dex, ch->mod_con - ch->perm_con, ch->mod_lck - ch->perm_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->race == 6 ) { fprintf( fp, "Absorb_Race %d %d %d %d %d %d %d\n", ch->pcdata->absorb_race[0], ch->pcdata->absorb_race[1], ch->pcdata->absorb_race[2], ch->pcdata->absorb_race[3], ch->pcdata->absorb_race[4], ch->pcdata->absorb_race[5], ch->pcdata->absorb_race[6] ); fprintf( fp, "Absorb_Pc %d\n", ch->pcdata->absorb_pc ); fprintf( fp, "Absorb_Mob %d\n", ch->pcdata->absorb_mob ); fprintf( fp, "Absorb_Pl_Mod %d\n", ch->pcdata->absorb_pl_mod ); } fprintf( fp, "LastIntrest %d %d\n", ch->pcdata->interestLastMonth, ch->pcdata->interestLastYear ); if( ch->race == 6 || is_android( ch ) ) fprintf( fp, "SD_Charge %d\n", ch->pcdata->sd_charge ); if( is_android( ch ) ) fprintf( fp, "Battery %d\n", ch->battery ); if( ch->desc && ch->desc->host ) fprintf( fp, "Site %s\n", ch->desc->host ); else fprintf( fp, "Site %s\n", ch->pcdata->lasthost ); fprintf( fp, "LastOn %d\n", ( int )current_time ); for( sn = 0; sn < AT_MAXCOLOR; ++sn ) if( ch->pcdata->colorize[sn] != -1 ) fprintf( fp, "Color %s %d\n", at_color_table[sn].name, ch->pcdata->colorize[sn] ); 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 %f '%s'\n", ch->pcdata->learned[sn], skill_table[sn]->name ); break; case SKILL_ABILITY: fprintf( fp, "Ability %f '%s'\n", ch->pcdata->learned[sn], skill_table[sn]->name ); break; case SKILL_SPELL: fprintf( fp, "Spell %.0f '%s'\n", ch->pcdata->learned[sn], skill_table[sn]->name ); break; case SKILL_WEAPON: fprintf( fp, "Weapon %.0f '%s'\n", ch->pcdata->learned[sn], skill_table[sn]->name ); break; case SKILL_TONGUE: fprintf( fp, "Tongue %.0f '%s'\n", ch->pcdata->learned[sn], skill_table[sn]->name ); break; } } 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 %3d %s\n", skill->name, paf->duration, paf->modifier, paf->location, paf->affLocator, print_bitvector( &paf->bitvector ) ); else fprintf( fp, "Affect %3d %3d %3d %3d %3d %s\n", paf->type, paf->duration, paf->modifier, paf->location, paf->affLocator, print_bitvector( &paf->bitvector ) ); } track = URANGE( 2, ( ( ch->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, "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 ); /* * Castrate storage characters. * Catch deleted objects -Thoric * Do NOT save prototype items! -Thoric */ /* if ( (ch && ch->exp < (obj->level * 0.30)) || ( obj->item_type == ITEM_KEY && !IS_OBJ_STAT(obj, ITEM_CLANOBJECT )) || obj_extracted(obj) || IS_OBJ_STAT( obj, ITEM_PROTOTYPE ) ) return; */ /* * Munch magic flagged containers for now - bandaid */ if( obj->item_type == ITEM_CONTAINER && IS_OBJ_STAT( obj, ITEM_MAGIC ) ) xTOGGLE_BIT( obj->extra_flags, ITEM_MAGIC ); /* * 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( !obj->origin ) fprintf( fp, "Origin %d, PRE-ORIGIN~\n", ORIGIN_UNKNOWN ); else fprintf( fp, "Origin %s~\n", obj->origin ); if( os_type == OS_CORPSE && obj->in_room ) fprintf( fp, "Room %d\n", obj->in_room->vnum ); if( !xSAME_BITS( obj->extra_flags, obj->pIndexData->extra_flags ) ) fprintf( fp, "ExtraFlags %s\n", print_bitvector( &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 %.0Lf\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: case ITEM_SCROLL: 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_STAFF: case ITEM_WAND: 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 %s\n", paf->type, paf->duration, ( ( paf->location == APPLY_WEAPONSPELL || paf->location == APPLY_WEARSPELL || paf->location == APPLY_REMOVESPELL || paf->location == APPLY_STRIPSN || paf->location == APPLY_RECURRINGSPELL ) && IS_VALID_SN( paf->modifier ) ) ? skill_table[paf->modifier]->slot : paf->modifier, paf->location, print_bitvector( &paf->bitvector ) ); } else fprintf( fp, "AffectData '%s' %d %d %d %s\n", skill_table[paf->type]->name, paf->duration, ( ( paf->location == APPLY_WEAPONSPELL || paf->location == APPLY_WEARSPELL || paf->location == APPLY_REMOVESPELL || paf->location == APPLY_STRIPSN || paf->location == APPLY_RECURRINGSPELL ) && IS_VALID_SN( paf->modifier ) ) ? skill_table[paf->modifier]->slot : paf->modifier, paf->location, print_bitvector( &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->pcdata->filename = STRALLOC( name ); ch->name = NULL; ch->act = multimeb( PLR_BLANK, PLR_COMBINE, PLR_PROMPT, -1 ); ch->perm_str = 10; ch->perm_int = 10; ch->perm_dex = 10; ch->perm_con = 10; ch->perm_lck = 0; ch->canmajin = FALSE; ch->no_resistant = 0; ch->no_susceptible = 0; ch->no_immune = 0; ch->was_in_room = NULL; xCLEAR_BITS( ch->no_affected_by ); ch->pcdata->condition[COND_THIRST] = 48; ch->pcdata->condition[COND_FULL] = 48; ch->pcdata->nuisance = NULL; ch->pcdata->wizinvis = 0; ch->pcdata->ghost_level = 0; ch->pcdata->incog_level = 0; ch->pcdata->charmies = 0; ch->mental_state = -10; ch->mobinvis = 0; ch->pcdata->admintalk = 0; for( i = 0; i < MAX_SKILL; i++ ) ch->pcdata->learned[i] = 0; ch->pcdata->release_date = 0; ch->pcdata->gnote_date = 0; ch->pcdata->nextHBTCDate = 0; ch->pcdata->nextspartime = 0; ch->pcdata->HBTCTimeLeft = 0; ch->pcdata->HBTCPartner = NULL; ch->pcdata->lastTaxation = 0; ch->pcdata->creation_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->style = STYLE_FIGHTING; ch->comments = NULL; /* comments */ ch->pcdata->pagerlen = 24; ch->pcdata->first_ignored = NULL; /* Ignore list */ ch->pcdata->last_ignored = NULL; ch->pcdata->tell_history = NULL; /* imm only lasttell cmnd */ ch->pcdata->lt_index = 0; /* last tell index */ ch->morph = NULL; ch->pcdata->email = NULL; /* Initialize email address - Samson 1-4-99 */ ch->pcdata->homepage = NULL; /* Initialize homepage - Samson 1-4-99 */ ch->pcdata->icq = 0; /* Initalize icq# - Samson 1-4-99 */ /* * Set up defaults for imc stuff */ ch->pcdata->imc_deaf = 0; ch->pcdata->imc_deny = 0; ch->pcdata->imc_allow = 0; ch->pcdata->ice_listen = NULL; ch->pcdata->bounty_by = str_dup( "" ); ch->pcdata->hunting = str_dup( "" ); ch->pcdata->spouse = str_dup( "" ); ch->pcdata->last_name = str_dup( "" ); ch->charge = 0; ch->skillGsn = 0; for( i = 0; i < AT_MAXCOLOR; ++i ) ch->pcdata->colorize[i] = -1; ch->pcdata->absorb_race[0] = 0; ch->pcdata->absorb_race[1] = 0; ch->pcdata->absorb_race[2] = 0; ch->pcdata->absorb_race[3] = 0; ch->pcdata->absorb_race[4] = 0; ch->pcdata->absorb_race[5] = 0; ch->pcdata->absorb_race[6] = 0; ch->pcdata->absorb_race[7] = 0; ch->pcdata->absorb_race[8] = 0; ch->pcdata->absorb_race[9] = 0; ch->pcdata->absorb_race[10] = 0; ch->pcdata->absorb_pc = 0; ch->pcdata->absorb_mob = 0; ch->pcdata->absorb_pl_mod = 0; ch->pcdata->absorb_pl = 0; ch->pcdata->absorb_sn = 0; ch->pcdata->absorb_learn = 0; ch->pcdata->pIdle[0] = 0; ch->pcdata->pIdle[1] = 0; ch->pcdata->pIdle[2] = 0; ch->pcdata->pIdle[3] = 0; ch->pcdata->pIdle[4] = 0; ch->pcdata->iIdle = 0; ch->pcdata->bot_warn[0] = 0; ch->pcdata->bot_warn[1] = 0; ch->pcdata->bot_warn[2] = 0; ch->pcdata->tStr = 0; ch->pcdata->tInt = 0; ch->pcdata->tSpd = 0; ch->pcdata->tCon = 0; ch->pcdata->permTstr = 0; ch->pcdata->permTint = 0; ch->pcdata->permTspd = 0; ch->pcdata->permTcon = 0; ch->pcdata->upgradeL = 0; ch->pcdata->auraColorPowerUp = -1; ch->pcdata->interestLastMonth = 0; ch->pcdata->interestLastYear = 0; ch->focus = 0; found = FALSE; sprintf( strsave, "%s%c/%s", PLAYER_DIR, tolower( name[0] ), capitalize( name ) ); GfpName = strsave; 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 { if( !str_cmp( ch->pcdata->filename, "normed" ) || !str_cmp( ch->pcdata->filename, "bruno" ) || !str_cmp( ch->pcdata->filename, "karn" ) ) { sprintf( buf, "%s player data for: %s (%dK)", preload ? "Preloading" : "Loading", ch->pcdata->filename, ( int )fst.st_size / 1024 ); log_string_plus( buf, LOG_COMM, LEVEL_SUPREME ); } else { sprintf( buf, "%s player data for: %s (%dK)", preload ? "Preloading" : "Loading", ch->pcdata->filename, ( 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; if( StopFP ) { bug( "Bad Pfile detected. Stoping proccessing of bad Pfile." ); StopFP = FALSE; return found; } 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( !strcmp( word, "PLAYER" ) ) { fread_char( ch, fp, preload ); if( preload ) break; } else if( !strcmp( word, "OBJECT" ) ) /* Objects */ fread_obj( ch, fp, OS_CARRY ); else if( !strcmp( word, "MorphData" ) ) /* Morphs */ fread_morph_data( ch, fp ); else if( !strcmp( word, "COMMENT" ) ) fread_comment( ch, fp ); /* Comments */ else if( !strcmp( word, "MOBILE" ) ) { CHAR_DATA *mob; mob = fread_mobile( fp ); ch->pcdata->pet = mob; mob->master = ch; xSET_BIT( mob->affected_by, AFF_CHARM ); } else if( !strcmp( word, "END" ) ) /* Done */ break; else { bug( "Load_char_obj: bad section.", 0 ); bug( name, 0 ); break; } } fclose( fp ); fpArea = NULL; strcpy( strArea, "$" ); } if( ch->pcdata->ice_listen == NULL ) ch->pcdata->ice_listen = str_dup( "" ); if( !found ) { ch->name = STRALLOC( name ); ch->short_descr = STRALLOC( "" ); ch->long_descr = STRALLOC( "" ); ch->description = STRALLOC( "" ); ch->pcdata->description1 = STRALLOC( "" ); ch->pcdata->description2 = STRALLOC( "" ); ch->pcdata->description3 = STRALLOC( "" ); ch->pcdata->description4 = STRALLOC( "" ); ch->pcdata->description5 = STRALLOC( "" ); ch->editor = NULL; ch->pcdata->clan_name = STRALLOC( "" ); ch->pcdata->clan = NULL; ch->pcdata->council_name = STRALLOC( "" ); ch->pcdata->council = NULL; ch->pcdata->deity_name = STRALLOC( "" ); ch->pcdata->deity = NULL; ch->pcdata->pet = NULL; ch->pcdata->pwd = str_dup( "" ); /* * every characters starts at default board from login.. this board * should be read_level == 0 ! */ ch->pcdata->board = &boards[DEFAULT_BOARD]; ch->pcdata->bamfin = str_dup( "" ); ch->pcdata->bamfout = str_dup( "" ); ch->pcdata->bestowments = str_dup( "" ); ch->pcdata->pretitle = STRALLOC( "" ); ch->pcdata->title = STRALLOC( "" ); ch->pcdata->homepage = str_dup( "" ); ch->pcdata->email = str_dup( "" ); /* Samson 4-19-98 */ ch->pcdata->icq = 0; /* Samson 1-4-99 */ ch->pcdata->bio = STRALLOC( "" ); ch->pcdata->authed_by = STRALLOC( "" ); ch->pcdata->prompt = STRALLOC( "" ); ch->pcdata->fprompt = STRALLOC( "" ); ch->pcdata->kaiRestoreMsg = str_dup( "" ); ch->pcdata->bounty_by = str_dup( "" ); ch->pcdata->hunting = str_dup( "" ); ch->pcdata->spouse = str_dup( "" ); ch->pcdata->last_name = str_dup( "" ); 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->ghost_level = 0; ch->pcdata->incog_level = 0; ch->pcdata->admintalk = 0; ch->pcdata->silence = 0; ch->pcdata->eKTimer = 0; ch->pcdata->pk_timer = 0; ch->pcdata->auction_pl = 0; ch->pcdata->pIdle[0] = 0; ch->pcdata->pIdle[1] = 0; ch->pcdata->pIdle[2] = 0; ch->pcdata->pIdle[3] = 0; ch->pcdata->pIdle[4] = 0; ch->pcdata->iIdle = 0; ch->pcdata->bot_warn[0] = 0; ch->pcdata->bot_warn[1] = 0; ch->pcdata->bot_warn[2] = 0; ch->pcdata->auraColorPowerUp = -1; ch->pcdata->interestLastMonth = 0; ch->pcdata->interestLastYear = 0; } else { if( !ch->name ) ch->name = STRALLOC( name ); if( !ch->pcdata->clan_name ) { ch->pcdata->clan_name = STRALLOC( "" ); ch->pcdata->clan = NULL; } if( !ch->pcdata->council_name ) { ch->pcdata->council_name = STRALLOC( "" ); ch->pcdata->council = NULL; } if( !ch->pcdata->deity_name ) { ch->pcdata->deity_name = STRALLOC( "" ); ch->pcdata->deity = NULL; } if( !ch->pcdata->bio ) ch->pcdata->bio = STRALLOC( "" ); if( !ch->pcdata->authed_by ) ch->pcdata->authed_by = STRALLOC( "" ); if( xIS_SET( ch->act, PLR_FLEE ) ) xREMOVE_BIT( ch->act, PLR_FLEE ); if( IS_IMMORTAL( ch ) ) { if( ch->pcdata->wizinvis < 2 ) ch->pcdata->wizinvis = ch->level; if( ch->pcdata->ghost_level < 2 ) ch->pcdata->ghost_level = ch->level; if( ch->pcdata->incog_level < 2 ) ch->pcdata->incog_level = ch->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; } /* * Must be done *AFTER* eq is worn because of wis/int modifiers */ /* if ( !IS_IMMORTAL(ch) ) REMOVE_BIT(ch->speaks, LANG_COMMON | race_table[ch->race]->language); if ( countlangs(ch->speaks) < (ch->level / 10) && !IS_IMMORTAL(ch) ) { int prct = 5 + (get_curr_int(ch) / 6) + (get_curr_wis(ch) / 7); do { int iLang; int lang = 1; int need = (ch->level / 10) - countlangs(ch->speaks); int prac = 2 - (get_curr_cha(ch) / 17) * (70 / prct) * need; if ( ch->practice >= prac ) break; for ( iLang = 1; lang_array[iLang] != LANG_UNKNOWN; iLang++ ) if ( number_range( 1, iLang ) == 1 ) lang = iLang; if ( (iLang = bsearch_skill_exact( lang_names[lang], gsn_first_tongue, gsn_top_sn-1 )) < 0 ) continue; if ( ch->pcdata->learned[iLang] > 0 ) continue; SET_BIT(ch->speaks, lang_array[lang]); ch->pcdata->learned[iLang] = 70; ch->speaks &= VALID_LANGS; REMOVE_BIT(ch->speaks, LANG_COMMON | race_table[ch->race]->language); } }*/ } /* * Rebuild affected_by and RIS to catch errors - FB */ update_aris( ch ); loading_char = NULL; return found; } /* * Read in a char. */ #if defined(KEY) #undef KEY #endif #define KEY( literal, field, value ) \ if ( !strcmp( 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; sh_int killcnt; bool fMatch; file_ver = 0; killcnt = 0; for( ;; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = FALSE; if( StopFP ) { bug( "Bad Pfile detected. Stoping proccessing of bad Pfile." ); StopFP = FALSE; return; } switch ( UPPER( word[0] ) ) { case '*': fMatch = TRUE; fread_to_eol( fp ); break; case 'A': if( !strcmp( word, "Ability" ) ) { int sn; double value; if( preload ) word = "End"; else { value = fread_number_skill( fp ); if( file_ver < 3 ) sn = skill_lookup( fread_word( fp ) ); else sn = bsearch_skill_exact( fread_word( fp ), gsn_first_ability, gsn_first_weapon - 1 ); if( sn < 0 ) bug( "Fread_char: unknown ability.", 0 ); else { ch->pcdata->learned[sn] = value; /* * Take care of people who have stuff they shouldn't * * * Assumes class and level were loaded before. -- Altrag * * * Assumes practices are loaded first too now. -- Altrag */ if( skill_table[sn]->skill_level[ch->class] <= 0 ) { ch->pcdata->learned[sn] = 0; ch->practice++; } } fMatch = TRUE; break; } } if( !str_cmp( word, "Absorb_Race" ) ) { line = fread_line( fp ); sscanf( line, "%d %d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6, &x7 ); ch->pcdata->absorb_race[0] = x1; ch->pcdata->absorb_race[1] = x2; ch->pcdata->absorb_race[2] = x3; ch->pcdata->absorb_race[3] = x4; ch->pcdata->absorb_race[4] = x5; ch->pcdata->absorb_race[5] = x6; ch->pcdata->absorb_race[6] = x7; fMatch = TRUE; break; } KEY( "Absorb_Pc", ch->pcdata->absorb_pc, fread_number( fp ) ); KEY( "Absorb_Mob", ch->pcdata->absorb_mob, fread_number( fp ) ); KEY( "Absorb_Pl_Mod", ch->pcdata->absorb_pl_mod, fread_number( fp ) ); KEY( "Act", ch->act, fread_bitvector( fp ) ); KEY( "AffectedBy", ch->affected_by, fread_bitvector( fp ) ); KEY( "Alignment", ch->alignment, fread_number( fp ) ); KEY( "Armor", ch->armor, fread_number( fp ) ); KEY( "Age", ch->pcdata->age, fread_number( fp ) ); KEY( "AuraPowerUp", ch->pcdata->auraColorPowerUp, fread_number( fp ) ); if( !strcmp( word, "Affect" ) || !strcmp( word, "AffectData" ) ) { AFFECT_DATA *paf; if( preload ) { fMatch = TRUE; fread_to_eol( fp ); break; } CREATE( paf, AFFECT_DATA, 1 ); if( !strcmp( 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 ); if( paf->location == APPLY_WEAPONSPELL || paf->location == APPLY_WEARSPELL || paf->location == APPLY_REMOVESPELL || paf->location == APPLY_STRIPSN || paf->location == APPLY_RECURRINGSPELL ) paf->modifier = slot_lookup( paf->modifier ); paf->affLocator = fread_number( fp ); paf->bitvector = fread_bitvector( fp ); LINK( paf, ch->first_affect, ch->last_affect, next, prev ); fMatch = TRUE; break; } if( !strcmp( word, "AttrMod" ) ) { line = fread_line( fp ); x1 = x2 = x3 = x4 = x5 = 13; sscanf( line, "%d %d %d %d %d", &x1, &x2, &x3, &x4, &x5 ); ch->mod_str = x1; ch->mod_int = x2; ch->mod_dex = x3; ch->mod_con = x4; ch->mod_lck = x5; if( !x5 ) ch->mod_lck = 0; fMatch = TRUE; break; } if( !strcmp( word, "AttrPerm" ) ) { line = fread_line( fp ); x1 = x2 = x3 = x4 = x5 = 0; sscanf( line, "%d %d %d %d %d", &x1, &x2, &x3, &x4, &x5 ); ch->perm_str = x1; ch->perm_int = x2; ch->perm_dex = x3; ch->perm_con = x4; ch->perm_lck = x5; if( !x5 ) ch->perm_lck = 0; fMatch = TRUE; break; } if( !strcmp( word, "AttrAdd" ) ) { line = fread_line( fp ); x1 = x2 = x3 = x4 = x5 = 0; sscanf( line, "%d %d %d %d %d", &x1, &x2, &x3, &x4, &x5 ); ch->add_str = x1; ch->add_dex = x2; ch->add_int = x3; ch->add_con = x4; ch->add_lck = x5; if( !x5 ) ch->add_lck = 0; fMatch = TRUE; break; } if( !strcmp( word, "AttrTrain" ) ) { line = fread_line( fp ); x1 = x2 = x3 = x4 = 0; sscanf( line, "%d %d %d %d", &x1, &x2, &x3, &x4 ); ch->pcdata->tStr = x1; ch->pcdata->tInt = x2; ch->pcdata->tSpd = x3; ch->pcdata->tCon = x4; fMatch = TRUE; break; } KEY( "Auction_PL", ch->pcdata->auction_pl, fread_number_ld( fp ) ); KEY( "AuthedBy", ch->pcdata->authed_by, fread_string( fp ) ); break; case 'B': KEY( "Bamfin", ch->pcdata->bamfin, fread_string_nohash( fp ) ); KEY( "Bamfout", ch->pcdata->bamfout, fread_string_nohash( fp ) ); /* * Read in board status */ if( !str_cmp( word, "Boards" ) ) { int i, num = fread_number( fp ); /* number of boards saved */ char *boardname; for( ; num; num-- ) /* for each of the board saved */ { boardname = fread_word( fp ); i = board_lookup( boardname ); /* find board number */ if( i == BOARD_NOTFOUND ) /* Does board still exist ? */ { sprintf( buf, "fread_char: %s had unknown board name: %s. Skipped.", ch->name, boardname ); log_string( buf ); fread_number( fp ); /* read last_note and skip info */ } else /* Save it */ ch->pcdata->last_note[i] = fread_number( fp ); } /* for */ if( ch->pcdata->board == NULL ) { for( i = 0; i < MAX_BOARD; i++ ) { ch->pcdata->board = &boards[i]; } ch->pcdata->board = &boards[0]; } fMatch = TRUE; } /* Boards */ KEY( "Battery", ch->battery, fread_number( fp ) ); KEY( "BPromptCFG", ch->pcdata->battlePromptConfig, fread_number( fp ) ); KEY( "Bkills", ch->pcdata->bkills, fread_number( fp ) ); KEY( "Bounty", ch->pcdata->bounty, fread_number( fp ) ); KEY( "B_timeleft", ch->pcdata->b_timeleft, fread_number( fp ) ); KEY( "BountyBy", ch->pcdata->bounty_by, fread_string_nohash( fp ) ); KEY( "Bowed", ch->pcdata->bowed, fread_number( fp ) ); KEY( "Bestowments", ch->pcdata->bestowments, fread_string_nohash( fp ) ); KEY( "Bio", ch->pcdata->bio, fread_string( fp ) ); KEY( "Build", ch->pcdata->build, fread_number( fp ) ); KEY( "Bck_name", ch->bck_name, fread_string( fp ) ); KEY( "Bck_pl", ch->bck_pl, fread_number_ld( fp ) ); KEY( "Bck_race", ch->bck_race, fread_number( fp ) ); break; case 'C': if( !strcmp( 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; } KEY( "ClanRank", ch->pcdata->clanRank, fread_number( fp ) ); KEY( "ClanZeniDon", ch->pcdata->clanZeniDonated, fread_number_skill( fp ) ); KEY( "ClanZeniTax", ch->pcdata->clanZeniClanTax, fread_number_skill( fp ) ); KEY( "ClanItemsDon", ch->pcdata->clanItemsDonated, fread_number( fp ) ); KEY( "Class", ch->class, fread_number( fp ) ); KEY( "CombatFlags", ch->pcdata->combatFlags, fread_number( fp ) ); KEY( "Corespl", ch->corespl, fread_number_ld( fp ) ); if( !str_cmp( word, "Cores" ) ) { int fm_core = fread_number( fp ); int e_core = fread_number( fp ); int h_core = fread_number( fp ); if( fm_core == 1 ) ch->fm_core = TRUE; else ch->fm_core = FALSE; if( e_core == 1 ) ch->e_core = TRUE; else ch->e_core = FALSE; if( h_core == 1 ) ch->h_core = TRUE; else ch->h_core = FALSE; fMatch = TRUE; break; } KEY( "Creation_date", ch->pcdata->creation_date, fread_number( fp ) ); if( !str_cmp( word, "C_date_word" ) ) { fread_string_nohash( fp ); fMatch = TRUE; break; } if( !str_cmp( word, "Canmajin" ) ) { int canmajin = fread_number( fp ); if( canmajin == 1 ) ch->canmajin = TRUE; else ch->canmajin = FALSE; fMatch = TRUE; break; } if( !str_cmp( word, "Color" ) ) { char *cword; int at; cword = fread_word( fp ); for( at = 0; at < AT_MAXCOLOR; ++at ) if( !str_cmp( cword, at_color_table[at].name ) ) break; if( at < AT_MAXCOLOR ) ch->pcdata->colorize[at] = fread_number( fp ); else { bug( "Fread_char: color %s invalid.", cword ); fread_number( fp ); } 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( !strcmp( word, "Council" ) ) { ch->pcdata->council_name = fread_string( fp ); if( !preload && ch->pcdata->council_name[0] != '\0' && ( ch->pcdata->council = get_council( ch->pcdata->council_name ) ) == NULL ) { sprintf( buf, "Warning: the council %s no longer exists, and herefore you no longer\n\rbelong to a council.\n\r", ch->pcdata->council_name ); send_to_char( buf, ch ); STRFREE( ch->pcdata->council_name ); ch->pcdata->council_name = STRALLOC( "" ); } fMatch = TRUE; break; } KEY( "Complexion", ch->pcdata->complexion, fread_number( fp ) ); break; case 'D': KEY( "Damroll", ch->damroll, fread_number( fp ) ); KEY( "Deaf", ch->deaf, fread_bitvector( fp ) ); if( !strcmp( word, "Deity" ) ) { ch->pcdata->deity_name = fread_string( fp ); if( !preload && ch->pcdata->deity_name[0] != '\0' && ( ch->pcdata->deity = get_deity( ch->pcdata->deity_name ) ) == NULL ) { sprintf( buf, "Warning: the deity %s no longer exists.\n\r", ch->pcdata->deity_name ); send_to_char( buf, ch ); STRFREE( ch->pcdata->deity_name ); ch->pcdata->deity_name = STRALLOC( "" ); ch->pcdata->favor = 0; } fMatch = TRUE; break; } KEY( "Demonrank", ch->rank, fread_number( fp ) ); KEY( "Description", ch->description, fread_string( fp ) ); KEY( "Description1", ch->pcdata->description1, fread_string( fp ) ); KEY( "Description2", ch->pcdata->description2, fread_string( fp ) ); KEY( "Description3", ch->pcdata->description3, fread_string( fp ) ); KEY( "Description4", ch->pcdata->description4, fread_string( fp ) ); KEY( "Description5", ch->pcdata->description5, fread_string( fp ) ); break; /* * 'E' was moved to after 'S' */ case 'F': KEY( "Favor", ch->pcdata->favor, fread_number( fp ) ); if( !strcmp( word, "Filename" ) ) { /* * File Name already set externally. */ fread_to_eol( fp ); fMatch = TRUE; break; } KEY( "Flags", ch->pcdata->flags, fread_number( fp ) ); KEY( "FPrompt", ch->pcdata->fprompt, fread_string( fp ) ); KEY( "Fusionflags", ch->fusionflags, fread_number( fp ) ); KEY( "Fusions", ch->fusions, fread_number( fp ) ); KEY( "Fusiontimer", ch->fusiontimer, fread_number( fp ) ); if( !strcmp( word, "Fused" ) ) { fMatch = TRUE; x1 = fread_number( fp ); ch->fused[x1] = fread_string( fp ); break; } break; case 'G': KEY( "Ghost", ch->pcdata->ghost_level, fread_number( fp ) ); KEY( "Glory", ch->pcdata->quest_curr, fread_number( fp ) ); KEY( "Gold", ch->gold, fread_number( fp ) ); KEY( "Gohome", ch->pcdata->gohometimer, fread_number( fp ) ); /* * temporary measure */ if( !strcmp( 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': KEY( "HeartPL", ch->heart_pl, fread_number_ld( fp ) ); KEY( "Height", ch->height, fread_number( fp ) ); KEY( "HBTCLeft", ch->pcdata->HBTCTimeLeft, fread_number( fp ) ); if( !strcmp( word, "Helled" ) ) { ch->pcdata->release_date = fread_number( fp ); ch->pcdata->helled_by = fread_string( fp ); fMatch = TRUE; break; } KEY( "Hitroll", ch->hitroll, fread_number( fp ) ); KEY( "Homepage", ch->pcdata->homepage, fread_string_nohash( fp ) ); if( !strcmp( word, "HpManaMove" ) ) { ch->hit = fread_number( fp ); ch->max_hit = fread_number( fp ); ch->mana = fread_number( fp ); ch->max_mana = fread_number( fp ); ch->move = fread_number( fp ); ch->max_move = fread_number( fp ); fMatch = TRUE; break; } KEY( "Haircolor", ch->pcdata->haircolor, fread_number( fp ) ); KEY( "Hairstyle", ch->pcdata->hairstyle, fread_number( fp ) ); KEY( "Hairlen", ch->pcdata->hairlen, fread_number( fp ) ); KEY( "Hunting", ch->pcdata->hunting, fread_string_nohash( fp ) ); break; case 'I': KEY( "ICQ", ch->pcdata->icq, fread_number( fp ) ); if( !strcmp( word, "Ignored" ) ) { char *temp; char fname[1024]; struct stat fst; int ign; IGNORE_DATA *inode; /* * Get the name */ temp = fread_string( fp ); sprintf( fname, "%s%c/%s", PLAYER_DIR, tolower( temp[0] ), capitalize( temp ) ); /* * If there isn't a pfile for the name */ /* * then don't add it to the list */ if( stat( fname, &fst ) == -1 ) { fMatch = TRUE; break; } /* * Count the number of names already ignored */ for( ign = 0, inode = ch->pcdata->first_ignored; inode; inode = inode->next ) { ign++; } /* * Add the name unless the limit has been reached */ if( ign >= MAX_IGN ) { bug( "fread_char: too many ignored names" ); } else { /* * Add the name to the list */ CREATE( inode, IGNORE_DATA, 1 ); inode->name = STRALLOC( temp ); inode->next = NULL; inode->prev = NULL; LINK( inode, ch->pcdata->first_ignored, ch->pcdata->last_ignored, next, prev ); } fMatch = TRUE; break; } KEY( "IllegalPK", ch->pcdata->illegal_pk, fread_number( fp ) ); KEY( "IMC", ch->pcdata->imc_deaf, fread_number( fp ) ); KEY( "IMCAllow", ch->pcdata->imc_allow, fread_number( fp ) ); KEY( "IMCDeny", ch->pcdata->imc_deny, fread_number( fp ) ); KEY( "ICEListen", ch->pcdata->ice_listen, fread_string_nohash( fp ) ); KEY( "Immune", ch->immune, fread_number( fp ) ); KEY( "Incog", ch->pcdata->incog_level, fread_number( fp ) ); break; case 'K': KEY( "Kairank", ch->rank, fread_number( fp ) ); KEY( "KaiTimer", ch->pcdata->eKTimer, fread_number( fp ) ); KEY( "KaiMessage", ch->pcdata->kaiRestoreMsg, fread_string_nohash( fp ) ); if( !strcmp( 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( "LastOn", ch->pcdata->lastlogon, fread_number( fp ) ); if( !strcmp( word, "LastIntrest" ) ) { line = fread_line( fp ); x1 = x2 = 0; sscanf( line, "%d %d", &x1, &x2 ); ch->pcdata->interestLastMonth = x1; ch->pcdata->interestLastYear = x2; fMatch = TRUE; break; } if( !strcmp( word, "Last_Name" ) ) { ch->pcdata->last_name = fread_string_nohash( fp ); { sprintf( buf, " %s", ch->pcdata->last_name ); if( ch->pcdata->last_name ) { DISPOSE( ch->pcdata->last_name ); ch->pcdata->last_name = str_dup( "" ); } ch->pcdata->last_name = strdup( buf ); } fMatch = TRUE; break; } KEY( "Level", ch->level, fread_number( fp ) ); KEY( "LongDescr", ch->long_descr, fread_string( fp ) ); if( !strcmp( word, "Languages" ) ) { ch->speaks = fread_number( fp ); ch->speaking = fread_number( fp ); fMatch = TRUE; } if( !strcmp( "LastTax", word ) ) { ch->pcdata->lastTaxation = fread_number( fp ); fMatch = TRUE; } break; case 'M': KEY( "MaxEnergy", ch->max_energy, fread_number( fp ) ); KEY( "MaxPrac", ch->max_prac, fread_number( fp ) ); KEY( "MaxTrain", ch->max_train, 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( !strcmp( word, "MobRange" ) ) { ch->pcdata->m_range_lo = fread_number( fp ); ch->pcdata->m_range_hi = fread_number( fp ); fMatch = TRUE; } break; case 'N': KEY( "NPromptCFG", ch->pcdata->normalPromptConfig, fread_number( fp ) ); KEY( "NaturalAC", ch->pcdata->natural_ac_max, fread_number( fp ) ); KEY( "Name", ch->name, fread_string( fp ) ); KEY( "NoAffectedBy", ch->no_affected_by, fread_bitvector( fp ) ); KEY( "Nognote", ch->pcdata->gnote_date, fread_number( fp ) ); KEY( "NoImmune", ch->no_immune, fread_number( fp ) ); KEY( "NoResistant", ch->no_resistant, fread_number( fp ) ); KEY( "NoSusceptible", ch->no_susceptible, fread_number( fp ) ); if( !strcmp( "Nuisance", word ) ) { fMatch = TRUE; CREATE( ch->pcdata->nuisance, NUISANCE_DATA, 1 ); ch->pcdata->nuisance->time = fread_number( fp ); ch->pcdata->nuisance->max_time = fread_number( fp ); ch->pcdata->nuisance->flags = fread_number( fp ); ch->pcdata->nuisance->power = 1; } if( !strcmp( "NuisanceNew", word ) ) { fMatch = TRUE; CREATE( ch->pcdata->nuisance, NUISANCE_DATA, 1 ); ch->pcdata->nuisance->time = fread_number( fp ); ch->pcdata->nuisance->max_time = fread_number( fp ); ch->pcdata->nuisance->flags = fread_number( fp ); ch->pcdata->nuisance->power = fread_number( fp ); } if( !strcmp( "NextHBTC", word ) ) { ch->pcdata->nextHBTCDate = fread_number( fp ); fMatch = TRUE; } if( !strcmp( "Nextspar", word ) ) { ch->pcdata->nextspartime = fread_number( fp ); fMatch = TRUE; } break; case 'O': KEY( "Orignaleyes", ch->pcdata->orignaleyes, fread_number( fp ) ); KEY( "Orignalhaircolor", ch->pcdata->orignalhaircolor, fread_number( fp ) ); KEY( "Outcast_time", ch->pcdata->outcast_time, fread_number( fp ) ); if( !strcmp( 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 ) ); if( !strcmp( word, "PermTStats" ) ) { line = fread_line( fp ); x1 = x2 = x3 = x4 = 0; sscanf( line, "%d %d %d %d", &x1, &x2, &x3, &x4 ); ch->pcdata->permTstr = x1; ch->pcdata->permTint = x2; ch->pcdata->permTspd = x3; ch->pcdata->permTcon = x4; fMatch = TRUE; break; } KEY( "PDeaths", ch->pcdata->pdeaths, fread_number( fp ) ); KEY( "PK_timer", ch->pcdata->pk_timer, fread_number( fp ) ); KEY( "PKills", ch->pcdata->pkills, fread_number( fp ) ); KEY( "PL", ch->pl, fread_number_ld( fp ) ); KEY( "Played", ch->played, fread_number( fp ) ); /* * KEY( "Position", ch->position, fread_number( fp ) ); */ /* * new positions are stored in the file from 100 up * old positions are from 0 up * if reading an old position, some translation is necessary */ if( !strcmp( word, "Position" ) ) { ch->position = fread_number( fp ); if( ch->position < 100 ) { switch ( ch->position ) { default:; case 0:; case 1:; case 2:; case 3:; case 4: break; case 5: ch->position = 6; break; case 6: ch->position = 8; break; case 7: ch->position = 9; break; case 8: ch->position = 12; break; case 9: ch->position = 13; break; case 10: ch->position = 14; break; case 11: ch->position = 15; break; } fMatch = TRUE; } else { ch->position -= 100; fMatch = TRUE; } } KEY( "Practice", ch->practice, fread_number( fp ) ); KEY( "Powerup", ch->powerup, fread_number( fp ) ); KEY( "Pretitle", ch->pcdata->pretitle, fread_string( fp ) ); KEY( "Prompt", ch->pcdata->prompt, fread_string( fp ) ); if( !strcmp( word, "PTimer" ) ) { add_timer( ch, TIMER_PKILLED, fread_number( fp ), NULL, 0 ); fMatch = TRUE; break; } break; case 'R': KEY( "Race", ch->race, fread_number( fp ) ); KEY( "Rage", ch->rage, fread_number( fp ) ); KEY( "Resistant", ch->resistant, fread_number( fp ) ); KEY( "Restore_time", ch->pcdata->restore_time, fread_number( fp ) ); if( !strcmp( 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( !strcmp( word, "RoomRange" ) ) { ch->pcdata->r_range_lo = fread_number( fp ); ch->pcdata->r_range_hi = fread_number( fp ); fMatch = TRUE; } KEY( "Rank", ch->rank, fread_number( fp ) ); break; case 'S': KEY( "Saiyanrank", ch->rank, fread_number( fp ) ); KEY( "SD_Charge", ch->pcdata->sd_charge, fread_number( fp ) ); KEY( "Secondarycolor", ch->pcdata->secondarycolor, fread_number( fp ) ); KEY( "Sex", ch->sex, fread_number( fp ) ); KEY( "Silence", ch->pcdata->silence, fread_number( fp ) ); KEY( "Silencedby", ch->pcdata->silencedby, fread_string( fp ) ); KEY( "ShortDescr", ch->short_descr, fread_string( fp ) ); KEY( "Sparcount", ch->pcdata->sparcount, fread_number( fp ) ); KEY( "Spouse", ch->pcdata->spouse, fread_string_nohash( fp ) ); KEY( "Style", ch->style, fread_number( fp ) ); KEY( "Suppress", ch->pcdata->suppress, fread_number_ld( fp ) ); KEY( "Susceptible", ch->susceptible, fread_number( fp ) ); if( !strcmp( 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( !strcmp( 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( !strcmp( word, "Site" ) ) { if( !preload ) { ch->pcdata->lasthost = STRALLOC( fread_word( fp ) ); sprintf( buf, "Last connected from: %s\n\r", ch->pcdata->lasthost ); send_to_char( buf, ch ); if( ch->desc && ch->desc->host ) ch->pcdata->lasthost = STRALLOC( ch->desc->host ); } else fread_to_eol( fp ); fMatch = TRUE; if( preload ) word = "End"; else break; } if( !strcmp( word, "Skill" ) ) { int sn; double value; if( preload ) word = "End"; else { value = fread_number_skill( fp ); if( file_ver < 3 ) sn = skill_lookup( fread_word( fp ) ); else sn = bsearch_skill_exact( fread_word( fp ), gsn_first_skill, gsn_first_ability - 1 ); if( sn < 0 ) bug( "Fread_char: unknown skill.", 0 ); else { ch->pcdata->learned[sn] = value; /* * Take care of people who have stuff they shouldn't * * * Assumes class and level were loaded before. -- Altrag * * * Assumes practices are loaded first too now. -- Altrag */ if( skill_table[sn]->skill_level[ch->class] <= 0 ) { ch->pcdata->learned[sn] = 0; ch->practice++; } } fMatch = TRUE; break; } } KEY( "SparLoss", ch->pcdata->spar_loss, fread_number( fp ) ); KEY( "SparWins", ch->pcdata->spar_wins, fread_number( fp ) ); if( !strcmp( 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; if( ch->level < LEVEL_IMMORTAL ) if( skill_table[sn]->skill_level[ch->class] >= LEVEL_IMMORTAL ) { ch->pcdata->learned[sn] = 0; ch->practice++; } } fMatch = TRUE; break; } } if( strcmp( word, "End" ) ) break; case 'E': if( !strcmp( word, "End" ) ) { ch->logon_start = ch->exp; 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->description1 ) ch->pcdata->description1 = STRALLOC( "" ); if( !ch->pcdata->description2 ) ch->pcdata->description2 = STRALLOC( "" ); if( !ch->pcdata->description3 ) ch->pcdata->description3 = STRALLOC( "" ); if( !ch->pcdata->description4 ) ch->pcdata->description4 = STRALLOC( "" ); if( !ch->pcdata->description5 ) ch->pcdata->description5 = STRALLOC( "" ); if( !ch->pcdata->pwd ) ch->pcdata->pwd = str_dup( "" ); if( !ch->pcdata->bamfin ) ch->pcdata->bamfin = str_dup( "" ); if( !ch->pcdata->bamfout ) ch->pcdata->bamfout = str_dup( "" ); if( !ch->pcdata->bounty_by ) ch->pcdata->bounty_by = str_dup( "" ); if( !ch->pcdata->hunting ) ch->pcdata->hunting = str_dup( "" ); if( !ch->pcdata->last_name ) ch->pcdata->last_name = str_dup( "" ); if( !ch->pcdata->spouse ) ch->pcdata->spouse = str_dup( "" ); if( !ch->pcdata->bio ) ch->pcdata->bio = STRALLOC( "" ); if( !ch->pcdata->bestowments ) ch->pcdata->bestowments = str_dup( "" ); if( !ch->pcdata->pretitle ) ch->pcdata->pretitle = STRALLOC( "" ); if( !ch->pcdata->title ) ch->pcdata->title = STRALLOC( "" ); if( !ch->pcdata->homepage ) ch->pcdata->homepage = str_dup( "" ); if( !ch->pcdata->email ) ch->pcdata->email = str_dup( "" ); if( !ch->pcdata->authed_by ) ch->pcdata->authed_by = STRALLOC( "" ); if( !ch->pcdata->prompt ) ch->pcdata->prompt = STRALLOC( "" ); if( !ch->pcdata->fprompt ) ch->pcdata->fprompt = STRALLOC( "" ); ch->editor = NULL; killcnt = URANGE( 2, ( ( ch->level + 3 ) * MAX_KILLTRACK ) / LEVEL_AVATAR, MAX_KILLTRACK ); if( killcnt < MAX_KILLTRACK ) ch->pcdata->killed[killcnt].vnum = 0; /* * no good for newbies at all */ if( !IS_IMMORTAL( ch ) && !ch->speaking ) ch->speaking = LANG_COMMON; /* * ch->speaking = race_table[ch->race]->language; */ if( IS_IMMORTAL( ch ) ) { int i; ch->speaks = ~0; if( ch->speaking == 0 ) ch->speaking = ~0; CREATE( ch->pcdata->tell_history, char *, 26 ); for( i = 0; i < 26; i++ ) ch->pcdata->tell_history[i] = NULL; } if( !ch->pcdata->prompt ) ch->pcdata->prompt = STRALLOC( "" ); /* * reapply stat bonuses */ fixTransStatAffects( ch ); return; } KEY( "Email", ch->pcdata->email, fread_string_nohash( fp ) ); KEY( "Evilmod", ch->evilmod, fread_number( fp ) ); KEY( "Exp", ch->exp, fread_number_ld( fp ) ); KEY( "Eyes", ch->pcdata->eyes, fread_number( fp ) ); break; case 'T': KEY( "Tail", ch->pcdata->tail, fread_number( fp ) ); if( !strcmp( 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 ); if( sn < 0 ) bug( "Fread_char: unknown tongue.", 0 ); else { ch->pcdata->learned[sn] = value; if( ch->level < LEVEL_IMMORTAL ) if( skill_table[sn]->skill_level[ch->class] >= LEVEL_IMMORTAL ) { ch->pcdata->learned[sn] = 0; ch->practice++; } } fMatch = TRUE; } break; } KEY( "Train", ch->train, fread_number( fp ) ); // 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 ); KEY( "TotalXTrain", ch->pcdata->total_xTrain, fread_number( fp ) ); if( !strcmp( 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( "UpgradeL", ch->pcdata->upgradeL, fread_number( fp ) ); break; case 'V': if( !strcmp( word, "Vnum" ) ) { ch->pIndexData = get_mob_index( fread_number( fp ) ); fMatch = TRUE; break; } if( !str_cmp( word, "Version" ) ) { file_ver = fread_number( fp ); ch->pcdata->version = file_ver; fMatch = TRUE; break; } break; case 'W': KEY( "Weight", ch->weight, fread_number( fp ) ); if( !strcmp( 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; if( ch->level < LEVEL_IMMORTAL ) if( skill_table[sn]->skill_level[ch->class] >= LEVEL_IMMORTAL ) { ch->pcdata->learned[sn] = 0; ch->practice++; } } fMatch = TRUE; } break; } KEY( "Wimpy", ch->wimpy, fread_number( fp ) ); KEY( "WizInvis", ch->pcdata->wizinvis, fread_number( fp ) ); break; case 'X': KEY( "XTrain", ch->pcdata->xTrain, fread_number( fp ) ); break; case 'Z': KEY( "Zeni", ch->gold, fread_number( fp ) ); } 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; char buf[MAX_STRING_LENGTH]; int iNest; bool fMatch; bool fNest; bool fVnum; ROOM_INDEX_DATA *room = NULL; if( ch ) room = ch->in_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': KEY( "ActionDesc", obj->action_desc, fread_string( fp ) ); if( !strcmp( word, "Affect" ) || !strcmp( word, "AffectData" ) ) { AFFECT_DATA *paf; int pafmod; CREATE( paf, AFFECT_DATA, 1 ); if( !strcmp( 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_bitvector( fp ); if( paf->location == APPLY_WEAPONSPELL || paf->location == APPLY_WEARSPELL || paf->location == APPLY_STRIPSN || paf->location == APPLY_REMOVESPELL || paf->location == APPLY_RECURRINGSPELL ) paf->modifier = slot_lookup( pafmod ); else paf->modifier = pafmod; LINK( paf, obj->first_affect, obj->last_affect, next, prev ); fMatch = TRUE; break; } 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_bitvector( fp ) ); if( !strcmp( 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( !strcmp( word, "End" ) ) { if( !fNest || !fVnum ) { if( obj->name ) sprintf( buf, "Fread_obj: %s incomplete object.", obj->name ); else sprintf( buf, "Fread_obj: incomplete object." ); bug( buf, 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 ); if( ( !IS_OBJ_STAT( obj, ITEM_RARE ) && !IS_OBJ_STAT( obj, ITEM_UNIQUE ) ) || IS_NPC( ch ) ) { 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 ); } /* * Give the corpse a timer if there isn't one */ if( obj->timer < 1 ) obj->timer = 40; if( room->vnum == ROOM_VNUM_HALLOFFALLEN && obj->first_content ) obj->timer = -1; obj = obj_to_room( obj, room ); } else if( iNest == 0 || rgObjNest[iNest] == NULL ) { int slot = -1; 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 && slot != -1 ) 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_ld( fp ) ); break; case 'N': KEY( "Name", obj->name, fread_string( fp ) ); if( !strcmp( 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 'O': KEY( "Origin", obj->origin, fread_string( fp ) ); case 'R': KEY( "Room", room, get_room_index( fread_number( fp ) ) ); case 'S': KEY( "ShortDescr", obj->short_descr, fread_string( fp ) ); if( !strcmp( 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( !strcmp( 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( !strcmp( word, "Vnum" ) ) { int vnum; vnum = fread_number( fp ); /* * bug( "Fread_obj: bad vnum %d.", vnum ); */ if( ( obj->pIndexData = get_obj_index( vnum ) ) == NULL ) // { fVnum = FALSE; // break; // } 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 ) { #ifdef WIN32 kill_timer( ); /* kill old timer */ timer_code = timeSetEvent( seconds * 1000L, 1000, alarm_handler, 0, TIME_PERIODIC ); #else alarm( seconds ); #endif } /* * 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; } strcpy( name, capitalize( arg ) ); sprintf( buf, "%s%c/%s", PLAYER_DIR, tolower( arg[0] ), name ); if( stat( buf, &fst ) != -1 && check_parse_name( capitalize( name ), FALSE ) ) 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 ); } /* * Added support for removeing so we could take out the write_corpses * so we could take it out of the save_char_obj function. --Shaddai */ void write_corpses( CHAR_DATA * ch, char *name, OBJ_DATA * objrem ) { 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 ) && objrem != corpse ) { 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 dirent *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( !strcmp( word, "CORPSE" ) ) fread_obj( NULL, fpArea, OS_CORPSE ); else if( !strcmp( word, "OBJECT" ) ) fread_obj( NULL, fpArea, OS_CARRY ); else if( !strcmp( word, "END" ) ) break; else { bug( "Load_corpses: bad section.", 0 ); break; } } fclose( fpArea ); } } fpArea = NULL; strcpy( strArea, "$" ); closedir( dp ); falling = 0; return; } /* * This will write one mobile structure pointed to be fp --Shaddai */ void fwrite_mobile( FILE * fp, CHAR_DATA * mob ) { if( !IS_NPC( mob ) || !fp ) return; fprintf( fp, "#MOBILE\n" ); fprintf( fp, "Vnum %d\n", mob->pIndexData->vnum ); if( mob->in_room ) fprintf( fp, "Room %d\n", ( mob->in_room == get_room_index( ROOM_VNUM_LIMBO ) && mob->was_in_room ) ? mob->was_in_room->vnum : mob->in_room->vnum ); if( QUICKMATCH( mob->name, mob->pIndexData->player_name ) == 0 ) fprintf( fp, "Name %s~\n", mob->name ); if( QUICKMATCH( mob->short_descr, mob->pIndexData->short_descr ) == 0 ) fprintf( fp, "Short %s~\n", mob->short_descr ); if( QUICKMATCH( mob->long_descr, mob->pIndexData->long_descr ) == 0 ) fprintf( fp, "Long %s~", mob->long_descr ); if( QUICKMATCH( mob->description, mob->pIndexData->description ) == 0 ) fprintf( fp, "Description %s~\n", mob->description ); fprintf( fp, "Position %d\n", mob->position ); fprintf( fp, "Flags %s\n", print_bitvector( &mob->act ) ); /* Might need these later --Shaddai de_equip_char( mob ); re_equip_char( mob ); */ if( mob->first_carrying ) fwrite_obj( mob, mob->last_carrying, fp, 0, OS_CARRY ); fprintf( fp, "EndMobile\n" ); return; } /* * This will read one mobile structure pointer to by fp --Shaddai */ CHAR_DATA *fread_mobile( FILE * fp ) { CHAR_DATA *mob = NULL; char *word; bool fMatch; int inroom = 0; ROOM_INDEX_DATA *pRoomIndex = NULL; word = feof( fp ) ? "EndMobile" : fread_word( fp ); if( !strcmp( word, "Vnum" ) ) { int vnum; vnum = fread_number( fp ); mob = create_mobile( get_mob_index( vnum ) ); if( !mob ) { for( ;; ) { word = feof( fp ) ? "EndMobile" : fread_word( fp ); /* * So we don't get so many bug messages when something messes up * * --Shaddai */ if( !strcmp( word, "EndMobile" ) ) break; } bug( "Fread_mobile: No index data for vnum %d", vnum ); return NULL; } } else { for( ;; ) { word = feof( fp ) ? "EndMobile" : fread_word( fp ); /* * So we don't get so many bug messages when something messes up * * --Shaddai */ if( !strcmp( word, "EndMobile" ) ) break; } extract_char( mob, TRUE ); bug( "Fread_mobile: Vnum not found", 0 ); return NULL; } for( ;; ) { word = feof( fp ) ? "EndMobile" : fread_word( fp ); fMatch = FALSE; switch ( UPPER( word[0] ) ) { case '*': fMatch = TRUE; fread_to_eol( fp ); break; case '#': if( !strcmp( word, "#OBJECT" ) ) fread_obj( mob, fp, OS_CARRY ); case 'D': KEY( "Description", mob->description, fread_string( fp ) ); break; case 'E': if( !strcmp( word, "EndMobile" ) ) { if( inroom == 0 ) inroom = ROOM_VNUM_TEMPLE; pRoomIndex = get_room_index( inroom ); if( !pRoomIndex ) pRoomIndex = get_room_index( ROOM_VNUM_TEMPLE ); char_to_room( mob, pRoomIndex ); return mob; } break; case 'F': KEY( "Flags", mob->act, fread_bitvector( fp ) ); case 'L': KEY( "Long", mob->long_descr, fread_string( fp ) ); break; case 'N': KEY( "Name", mob->name, fread_string( fp ) ); break; case 'P': KEY( "Position", mob->position, fread_number( fp ) ); break; case 'R': KEY( "Room", inroom, fread_number( fp ) ); break; case 'S': KEY( "Short", mob->short_descr, fread_string( fp ) ); break; } if( !fMatch ) { bug( "Fread_mobile: no match.", 0 ); bug( word, 0 ); } } return NULL; } /* * This will write in the saved mobile for a char --Shaddai */ void write_char_mobile( CHAR_DATA * ch, char *argument ) { FILE *fp; CHAR_DATA *mob; char buf[MAX_STRING_LENGTH]; if( IS_NPC( ch ) || !ch->pcdata->pet ) return; fclose( fpReserve ); if( ( fp = fopen( argument, "w" ) ) == NULL ) { sprintf( buf, "Write_char_mobile: couldn't open %s for writing!\n\r", argument ); bug( buf, 0 ); fpReserve = fopen( NULL_FILE, "r" ); return; } mob = ch->pcdata->pet; xSET_BIT( mob->affected_by, AFF_CHARM ); fwrite_mobile( fp, mob ); fclose( fp ); fpReserve = fopen( NULL_FILE, "r" ); return; } /* * This will read in the saved mobile for a char --Shaddai */ void read_char_mobile( char *argument ) { FILE *fp; CHAR_DATA *mob; char buf[MAX_STRING_LENGTH]; fclose( fpReserve ); if( ( fp = fopen( argument, "r" ) ) == NULL ) { sprintf( buf, "Read_char_mobile: couldn't open %s for reading!\n\r", argument ); bug( buf, 0 ); fpReserve = fopen( NULL_FILE, "r" ); return; } mob = fread_mobile( fp ); fclose( fp ); fpReserve = fopen( NULL_FILE, "r" ); return; }