/***************************************************************************
* Emud 2.2 by Igor van den Hoven, Michiel Lange, and Martin Bethlehem. *
* *
* MrMud 1.4 by David Bills and Dug Michael. *
* *
* Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* Original Diku Mud copyright (C) 1990 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeld, Tom Madsen, and Katje Nyboe. *
***************************************************************************/
#include <sys/stat.h>
#include "emud.h"
/*
Array of containers read for proper re-nesting of objects.
*/
#define MAX_NEST 10
static OBJ_DATA * rgObjNest [MAX_NEST];
/*
The object version number is saved in the pfiles, if someone logs
in with a non matching version number all the objects carried by
that person will be purged, if you ever need to use this it would
be smart to also add the version check to the quest bits of players,
so the kids can get some new gear - Scandum
*/
/*
Local functions.
*/
int total_language( CHAR_DATA *);
void fwrite_char args( ( CHAR_DATA *ch, FILE *fp ) );
void fwrite_obj args( ( CHAR_DATA *ch, OBJ_DATA *obj, FILE *fp, char iNest ) );
void fread_char args( ( CHAR_DATA *ch, FILE *fp ) );
void fread_obj args( ( CHAR_DATA *ch, FILE *fp ) );
bool is_valid_file args( ( CHAR_DATA *ch, FILE *fp ) );
void fwrite_poison_data( POISON_DATA *, FILE *);
POISON_DATA *fread_poison_data( FILE *);
long long encrypt( char *str )
{
long long h;
push_call("encrypt(%p)",str);
for (h = 0 ; *str != 0 ; str++)
{
h += (4 + (h << 7)) * *str;
}
pop_call();
return h;
}
long long encrypt64( char *str )
{
long long h;
push_call("encrypt64(%p)",str);
for (h = 0 ; *str != 0 ; str++)
{
h = (h << 7) + *str;
}
pop_call();
return h;
}
void add_pvnum( CHAR_DATA *ch )
{
PVNUM_DATA *pvnum;
push_call("add_pvnum(%p)",ch);
if (ch->pcdata->pvnum && pvnum_index[ch->pcdata->pvnum] == NULL)
{
ALLOCMEM(pvnum, PVNUM_DATA, 1);
pvnum->name = STRALLOC(capitalize_name(ch->name));
pvnum->date = mud->current_time;
pvnum_index[ch->pcdata->pvnum] = pvnum;
}
pop_call();
return;
}
int find_free_pvnum()
{
int cnt;
push_call("find_free_pvnum()");
for (cnt = 100 ; cnt < MAX_PVNUM / 2 ; cnt++)
{
if (pvnum_index[cnt] == NULL)
{
pop_call();
return cnt;
}
}
log_printf("find_free_pvnum: no free pvnum index found: removing deleted players");
for (cnt = 100 ; cnt < MAX_PVNUM ; cnt++)
{
if (pvnum_index[cnt] == NULL)
{
continue;
}
if (IS_SET(pvnum_index[cnt]->flags, PVNUM_DELETED))
{
STRFREE(pvnum_index[cnt]->name);
FREEMEM(pvnum_index[cnt]);
}
}
for (cnt = 100 ; cnt < MAX_PVNUM ; cnt++)
{
if (pvnum_index[cnt] == NULL)
{
pop_call();
return cnt;
}
}
log_printf("find_free_pvnum: no free pvnum index found");
pop_call();
return 0;
}
/*
Save a character and inventory.
*/
void save_char_obj(CHAR_DATA *ch, int which_type)
{
char strsave[MAX_INPUT_LENGTH], strtemp[MAX_INPUT_LENGTH];
char logfile[250];
char cap_name[30];
FILE *fp, *logfp;
ROOM_INDEX_DATA *troom;
bool IS_DESC;
push_call("save_char_obj(%p,%p)",ch,which_type);
if (IS_NPC(ch))
{
pop_call();
return;
}
IS_DESC = is_desc_valid( ch );
if ( IS_DESC && ch->desc->original != NULL )
{
send_to_char( "You can't save out of body!\n\r", ch);
pop_call();
return;
}
troom = ch->in_room;
if (troom == NULL)
{
log_printf("Save_char_obj: char was not in a room");
pop_call();
return;
}
if (IS_SET(troom->room_flags, ROOM_NO_SAVE))
{
char_from_room( ch );
char_to_room( ch, ROOM_VNUM_TEMPLE );
}
strcpy( cap_name, capitalize_name( ch->name ) );
if (which_type == NORMAL_SAVE)
{
sprintf(strsave,"%s/%c/%c/%s", PLAYER_DIR, tolower(cap_name[0]), tolower(cap_name[1]), cap_name);
sprintf(strtemp,"%s/%c/%c/temp.%s",PLAYER_DIR, tolower(cap_name[0]), tolower(cap_name[1]), cap_name);
}
else
{
sprintf(strsave, "%s/%c/%c/bak/%s", PLAYER_DIR, tolower(cap_name[0]), tolower(cap_name[1]), cap_name);
sprintf(strtemp, "%s/%c/%c/bak/temp.%s", PLAYER_DIR, tolower(cap_name[0]), tolower(cap_name[1]), cap_name);
}
close_reserve();
/*
Save char to "temp.name" then rename to "name" after all done for safety
*/
sprintf(logfile, "%s/%c/%c/%s.log", PLAYER_DIR, tolower(cap_name[0]), tolower(cap_name[1]), cap_name);
logfp = my_fopen(logfile,"w",FALSE);
if (logfp == NULL)
{
log_printf("Could _NOT_ open logfile to log the saving of %s\n\r.",cap_name);
print_errno(errno);
}
if (remove( strtemp ) != 0)
{
if (errno != ENOENT) /* if there was no temp file there's no prob */
{
log_printf("save_char_obj: could not remove %s.", strtemp);
print_errno(errno);
}
}
fp = my_fopen( strtemp, "w", FALSE ) ;
if ( fp == NULL )
{
log_printf("Save_char_obj: could not my_fopen file.");
perror( strsave );
send_to_char( "Through some wierd game error, your character did not save.\n\r", ch);
open_reserve();
pop_call();
return;
}
if (logfp) /* if the logfile is opened correctly */
{
fprintf(logfp, "Removed old backup and opened a new tempfile successfully.\n");
}
{
fwrite_char( ch, fp );
if (logfp)
{
fprintf(logfp,"Wrote character information successfully. (fwrite_char)\n");
}
if (ch->pcdata->corpse && get_room_index(ch->pcdata->corpse_room))
{
obj_to_char(ch->pcdata->corpse, ch);
}
if (ch->first_carrying != NULL)
{
if (logfp)
{
fprintf(logfp,"Starting to write ch->first_carrying (%p) to file.\n",ch->first_carrying);
}
fwrite_obj( ch, ch->first_carrying, fp, 0 );
}
if (ch->pcdata->corpse && get_room_index(ch->pcdata->corpse_room))
{
obj_to_room(ch->pcdata->corpse, ch->pcdata->corpse_room);
}
fprintf( fp, "#END %s\n", ch->name );
if (logfp)
{
fprintf(logfp,"Save successfull\n");
}
}
if (ftell(fp) < (long)100)
{
my_fclose( fp );
send_to_char("Oops, file system full! tell one of the Gods!\n\r(Hypnos, Discard, Gaia, Demise or Manwe)\n\r",ch);
log_string("File system full!!!\n\r");
}
else
{
my_fclose( fp );
fp = my_fopen( strtemp, "r",FALSE ) ;
if (!is_valid_file(ch, fp))
{
my_fclose( fp );
log_printf("SAVE not valid for %s", ch->name );
log_printf("Filesystem unstable, while saving %s", strtemp);
send_to_char( "The file system has become unstable. Please inform the Gods.\n\r", ch);
remove( strtemp );
}
else
{
my_fclose( fp );
if (remove(strsave) != 0)
{
if (errno != ENOENT)
{
log_printf("save_char_obj: (2nd) could not remove %s.", strsave);
print_errno(errno);
}
}
if (rename( strtemp, strsave ) != 0)
{
log_printf("Could not rename %s to %s.", strtemp, strsave);
print_errno(errno);
}
}
}
if (logfp)
{
fprintf(logfp,"All done right.\n");
fflush(logfp);
my_fclose(logfp);
remove( logfile );
}
open_reserve();
ch->pcdata->last_saved = mud->current_time;
/* restore char to proper room if in NO_SAVE room */
if (ch->in_room != troom)
{
char_from_room(ch);
char_to_room(ch, troom->vnum);
}
pop_call();
return;
}
void fix_object_bits(CHAR_DATA *ch, OBJ_DATA *obj)
{
push_call("fix_object_bits(%p,%p)",ch,obj);
while (obj != NULL)
{
if (obj->first_content != NULL)
{
fix_object_bits(ch, obj->first_content);
}
if (obj->wear_loc != WEAR_NONE && obj->level > reinc_eq_level(ch))
{
unequip_char(ch, obj);
}
if (!IS_SET(obj->extra_flags, ITEM_MODIFIED))
{
obj = obj->next_content;
continue;
}
if (IS_SET(obj->pIndexData->extra_flags, ITEM_MAGIC)
&& !IS_SET(obj->extra_flags,ITEM_MAGIC))
{
SET_BIT(obj->extra_flags,ITEM_MAGIC);
}
if (IS_SET(obj->pIndexData->extra_flags, ITEM_ANTI_GOOD)
&& !IS_SET(obj->extra_flags, ITEM_ANTI_GOOD))
{
SET_BIT(obj->extra_flags,ITEM_ANTI_GOOD);
}
if (IS_SET(obj->pIndexData->extra_flags,ITEM_ANTI_EVIL)
&& !IS_SET(obj->extra_flags,ITEM_ANTI_EVIL))
{
SET_BIT(obj->extra_flags,ITEM_ANTI_EVIL);
}
if (IS_SET(obj->pIndexData->extra_flags,ITEM_ANTI_NEUTRAL)
&& !IS_SET(obj->extra_flags,ITEM_ANTI_NEUTRAL))
{
SET_BIT(obj->extra_flags, ITEM_ANTI_NEUTRAL);
}
if (IS_SET(obj->pIndexData->extra_flags, ITEM_INVENTORY)
&& !IS_SET(obj->extra_flags,ITEM_INVENTORY))
{
SET_BIT(obj->extra_flags,ITEM_INVENTORY);
}
obj = obj->next_content;
}
pop_call();
return;
}
void fwrite_char( CHAR_DATA *ch, FILE *fp )
{
AFFECT_DATA *paf;
CRIME_DATA *pcr;
bool IS_DESC;
int sn;
sh_int cnt;
push_call("fwrite_char(%p,%p)",ch,fp);
IS_DESC = is_desc_valid( ch );
fprintf( fp, "#PLAYER\n");
fprintf( fp, "Version %d\n", PLAYER_VERSION);
fprintf( fp, "Login %s~\n", ch->pcdata->host);
fprintf( fp, "S_Descr %s~\n", ch->short_descr);
fprintf( fp, "L_Descr %s~\n", ch->long_descr);
fprintf( fp, "E_Descr %s~\n", fixer(ch->description));
if (ch->pcdata->first_record)
{
for (pcr = ch->pcdata->first_record ; pcr ; pcr = pcr->next)
{
fprintf( fp, "Crime_Data\n");
fprintf( fp, "%s~\n", fixer(pcr->crime_record));
fprintf( fp, "%s~\n", pcr->arrester);
fprintf( fp, "%d\n", pcr->date);
fprintf( fp, "%d\n", pcr->level);
fprintf( fp, "%d\n", pcr->jailtime);
fprintf( fp, "%d\n", pcr->released);
fprintf( fp, "%s~\n", pcr->releaser);
}
}
fprintf( fp, "Level %d\n", ch->level );
fprintf( fp, "Sex %d\n", ch->sex );
fprintf( fp, "Class %d\n", ch->class );
fprintf( fp, "Race %d\n", ch->race );
if (get_room_index(ch->pcdata->was_in_room) && IS_SET(ch->in_room->room_flags, ROOM_NO_SAVE))
{
fprintf( fp, "Room %u\n", ch->pcdata->was_in_room);
}
else
{
fprintf( fp, "Room %u\n", ch->in_room->vnum);
}
if (ch->pcdata->corpse)
{
fprintf( fp, "C_Room %u\n", ch->pcdata->corpse_room );
}
fprintf( fp, "LastRoom %d\n", ch->pcdata->last_real_room );
fprintf( fp, "Language %d\n", ch->pcdata->language );
fprintf( fp, "Speak %d\n", ch->pcdata->speak );
fprintf( fp, "Played %d\n", ch->pcdata->played );
fprintf( fp, "K_Played %d\n", ch->pcdata->killer_played );
fprintf( fp, "O_Played %d\n", ch->pcdata->outcast_played );
fprintf( fp, "HpMaMv %d %d %d %d %d %d\n", ch->hit, ch->max_hit, ch->mana, ch->max_mana, ch->move, ch->max_move );
fprintf( fp, "Actuals %d %d %d\n", ch->pcdata->actual_max_hit, ch->pcdata->actual_max_mana, ch->pcdata->actual_max_move );
fprintf( fp, "Gold %d\n", ch->gold );
fprintf( fp, "Account %d\n", ch->pcdata->account );
fprintf( fp, "Exp %d\n", ch->pcdata->exp );
fprintf( fp, "Ansi %d\n", IS_SET(ch->pcdata->request, REQUEST_ANSI_SAVE_ON) ? 1 : ch->pcdata->ansi);
fprintf( fp, "Vt100 %d\n", IS_SET(ch->pcdata->request, REQUEST_VT_SAVE_ON) ? 2 : ch->pcdata->vt100 ? 2 : 0);
/* Hypnos 20040730: Do NOT save the player's TAGGED status */
fprintf( fp, "Act %lld\n",ch->act&(~PLR_TAGGED) );
fprintf( fp, "Affects1 %lld\n",ch->affected_by );
fprintf( fp, "Affects2 %lld\n",ch->affected2_by );
fprintf( fp, "Practice %d\n", ch->pcdata->practice );
fprintf( fp, "Align %d\n", ch->alignment );
fprintf( fp, "Function %d\n", ch->pcdata->functions );
fprintf( fp, "Channel %d\n", ch->pcdata->channel );
fprintf( fp, "Morph %d\n", ch->pcdata->morph_points );
fprintf( fp, "Trivia %d\n", ch->pcdata->trivia_points);
fprintf( fp, "Wimpy %d\n", ch->pcdata->wimpy );
if (ch->pcdata->clan && ch->pcdata->clan_name[0] != '\0')
{
fprintf( fp, "ClanName %s~\n", ch->pcdata->clan_name );
}
if (ch->pcdata->clan_pledge[0] != '\0')
{
fprintf( fp, "ClanPled %s~\n", ch->pcdata->clan_pledge );
}
if (ch->pcdata->clan_position != 0)
{
fprintf( fp, "ClanPosi %d\n", ch->pcdata->clan_position);
}
if (ch->pcdata->last_connect != mud->current_time)
{
fprintf( fp, "LastTime %d\n", (int) mud->current_time );
}
else
{
fprintf( fp, "LastTime %d\n", ch->pcdata->last_time );
}
fprintf( fp, "Playtime %d\n", (int) mud->current_time - ch->pcdata->last_connect);
fprintf( fp, "Jailtime %d\n", ch->pcdata->jailtime );
fprintf( fp, "Jaildate %d\n", ch->pcdata->jaildate );
fprintf( fp, "MailAddy %s~\n", ch->pcdata->mail_address );
fprintf( fp, "HtmlAddy %s~\n", ch->pcdata->html_address );
fprintf( fp, "Password %lld\n", ch->pcdata->password );
fprintf( fp, "Bamfin %s~\n", ch->pcdata->bamfin );
fprintf( fp, "Bamfout %s~\n", ch->pcdata->bamfout );
fprintf( fp, "Title %s~\n", ch->pcdata->title );
fprintf( fp, "Prefix %d\n", ch->pcdata->honorific );
fprintf( fp, "AttrPerm %d %d %d %d %d\n", ch->pcdata->perm_str, ch->pcdata->perm_int, ch->pcdata->perm_wis, ch->pcdata->perm_dex, ch->pcdata->perm_con);
fprintf( fp, "AttrMod %d %d %d %d %d\n", ch->pcdata->mod_str, ch->pcdata->mod_int, ch->pcdata->mod_wis, ch->pcdata->mod_dex, ch->pcdata->mod_con );
fprintf( fp, "DrFuThAi %d %d %d %d\n", ch->pcdata->condition[0], ch->pcdata->condition[1], ch->pcdata->condition[2], ch->pcdata->condition[3]);
for (cnt = 0 ; cnt < MAX_CLASS ; cnt++)
{
fprintf( fp, "Mclass %d %d\n", cnt, ch->pcdata->mclass[cnt] );
}
for (sn = 0 ; sn < MAX_SKILL ; sn++)
{
if (skill_table[sn].name != NULL && ch->pcdata->learned[sn] > 0)
{
if (multi(ch, sn) != -1)
{
fprintf( fp, "Skill %d '%s'\n", ch->pcdata->learned[sn], skill_table[sn].name );
}
}
}
for (sn = 0 ; sn < MAX_AREA ; sn++)
{
if (ch->pcdata->quest[sn])
{
fprintf(fp, "Qstb %d %3d ", MAX_QUEST_BYTES, sn);
for (cnt = 0 ; cnt < MAX_QUEST_BYTES ; cnt++)
{
fprintf(fp, "%d ", ch->pcdata->quest[sn][cnt]);
}
fprintf(fp, "\n");
}
}
fprintf( fp, "Speed %d\n", ch->speed);
fprintf( fp, "Reinc %d\n", ch->pcdata->reincarnation);
fprintf( fp, "Prev_hrs %d\n", ch->pcdata->previous_hours);
fprintf( fp, "Tactical %d\n", ch->pcdata->tactical_mode);
fprintf( fp, "TactIndx %s~\n", ch->pcdata->tactical_index);
fprintf( fp, "Compass %d\n", (int) ch->pcdata->compass_width);
if (IS_IMMORTAL(ch))
{
if (ch->pcdata->a_range_lo && ch->pcdata->a_range_hi)
{
fprintf( fp, "A_Range %d %d\n", ch->pcdata->a_range_lo, ch->pcdata->a_range_hi);
}
}
fprintf( fp, "Pvnum %d\n", ch->pcdata->pvnum);
fprintf( fp, "Vt100_T %d\n", ch->pcdata->vt100_type );
fprintf( fp, "Vt100_F %d\n", ch->pcdata->vt100_flags );
fprintf( fp, "Portsize %d\n", ch->pcdata->port_size );
fprintf( fp, "Prompt %s~\n", ch->pcdata->prompt_layout);
fprintf( fp, "Spam %d\n", ch->pcdata->spam );
fprintf( fp, "Clock %d\n", ch->pcdata->clock);
fprintf( fp, "Recall %d\n", ch->pcdata->recall);
fprintf( fp, "Death %d\n", ch->pcdata->death_room);
fprintf( fp, "Whichgod %d\n", ch->pcdata->god);
fprintf( fp, "Blocking %s~\n", ch->pcdata->block_list);
fprintf( fp, "AutoComm %s~\n", ch->pcdata->auto_command);
fprintf( fp, "AutoMode %d\n", ch->pcdata->auto_flags);
for (cnt = 0 ; cnt < 6 ; cnt++)
{
fprintf( fp, "History %d %d\n", cnt, ch->pcdata->history[cnt]);
}
fprintf( fp, "LastNote %d\n", ch->pcdata->last_note );
for (cnt = 0 ; cnt < MAX_TOPIC ; cnt++)
{
fprintf( fp, "Topic %d %d\n", cnt, ch->pcdata->topic_stamp[cnt]);
}
for (cnt = 0 ; cnt < COLOR_MAX ; cnt++)
{
fprintf( fp, "Color %2d %2d\n", cnt, ch->pcdata->color[cnt]);
}
for (cnt = 0 ; cnt < MAX_ALIAS ; cnt++)
{
if (ch->pcdata->alias[cnt][0]!='\0')
{
fprintf( fp, "Alias %s~%s~\n", ch->pcdata->alias_c[cnt], ch->pcdata->alias[cnt]);
}
}
/*
castle stuff
*/
if (ch->pcdata->castle != NULL)
{
fprintf( fp, "Cstl_ent %d\n",ch->pcdata->castle->entrance);
fprintf( fp, "Cstl_dor %d\n",ch->pcdata->castle->door_room);
fprintf( fp, "Cstl_dir %d\n",ch->pcdata->castle->door_dir);
fprintf( fp, "Cstl_has %d\n",ch->pcdata->castle->has_backdoor);
fprintf( fp, "Cstl_cst %d\n",ch->pcdata->castle->cost);
fprintf( fp, "Cstl_nrm %d\n",ch->pcdata->castle->num_rooms);
fprintf( fp, "Cstl_nmo %d\n",ch->pcdata->castle->num_mobiles);
fprintf( fp, "Cstl_nob %d\n",ch->pcdata->castle->num_objects);
}
for (paf = ch->first_affect ; paf != NULL ; paf = paf->next)
{
if (paf->type < 0 || paf->type >= MAX_SKILL)
{
log_printf("save_char_obj: bad affect type: %d", paf->type);
continue;
}
fprintf(fp, "AffectData '%s' %d %d %d %d %lld\n", skill_table[paf->type].name, paf->duration, paf->modifier, paf->location, paf->bittype, paf->bitvector);
}
fprintf( fp, "Critical %d\n", ch->critical_hit_by );
if (ch->poison != NULL)
{
fwrite_poison_data( ch->poison, fp );
}
fprintf( fp, "PK_ATTACKS %d\n", MAX_PK_ATTACKS );
for (cnt = 0 ; cnt < MAX_PK_ATTACKS ; cnt++)
{
fprintf( fp, "%d %d %s~\n", ch->pcdata->last_pk_attack_time[cnt], ch->pcdata->last_pk_attack_pvnum[cnt], ch->pcdata->last_pk_attack_name[cnt]);
}
fprintf( fp, "End\n\n" );
pop_call();
return;
}
void load_clan_pit( FILE *fp )
{
OBJ_INDEX_DATA *pit;
char letter, loop, *word;
push_call("fread_clanpit(void)");
word = fread_word(fp);
pit = obj_index[atol(word)];
rgObjNest[0] = pit->first_instance;
for (loop = TRUE ; loop ; )
{
letter = fread_letter(fp);
if (letter != '#')
{
log_printf("fread_clan_pit: # not found. Word was '%c%s'", letter, fread_word(fp));
break;
}
word = fread_word(fp);
switch (word[0])
{
case 'O':
fread_obj(NULL, fp);
break;
case 'E':
loop = FALSE;
break;
default:
log_printf("fread_clan_pit: bad section.");
loop = FALSE;
break;
}
}
pop_call();
return;
}
void save_clan_pit(CLAN_DATA *clan, FILE *fp )
{
ROOM_INDEX_DATA *location;
OBJ_DATA *pit;
push_call("save_clan_pits(void)");
if ((location = get_room_index(clan->store)) == NULL)
{
pop_call();
return;
}
for (pit = location->first_content ; pit ; pit = pit->next_content)
{
if (pit->pIndexData->creator_pvnum == clan->founder_pvnum && pit->item_type == ITEM_CONTAINER)
{
break;
}
}
if (pit == NULL)
{
pop_call();
return;
}
fprintf( fp, "#PIT %d\n\n", pit->pIndexData->vnum);
fwrite_obj(NULL, pit->first_content, fp, 1);
fprintf(fp, "#END\n");
pop_call();
return;
}
/*
Write an object and its first_content.
Increased speed, no more naughty recursion, objects in unsaved
containers go to inventory - Scandum april 2002
*/
void fwrite_obj( CHAR_DATA *ch, OBJ_DATA *obj, FILE *fp, char iNest )
{
AFFECT_DATA *paf;
push_call("fwrite_obj(%p,%p,%p,%p)",ch,obj,fp,iNest);
while (obj)
{
if ((ch != NULL && obj_eq_level(ch, obj) - 5 > ch->level)
|| obj->item_type == ITEM_KEY
|| IS_SET(obj->extra_flags, ITEM_NOT_VALID))
{
if (obj->first_content != NULL)
{
fwrite_obj(ch, obj->first_content, fp, iNest);
}
obj = obj->next_content;
continue;
}
else
{
fprintf( fp, "#OBJECT\n" );
if (iNest)
{
fprintf(fp, "Nest %d\n", iNest);
}
else if (obj->wear_loc != WEAR_NONE)
{
fprintf(fp, "WearLoc %s\n", broken_bits(obj->wear_loc, "WEAR_", TRUE));
}
if (!IS_SET(obj->extra_flags, ITEM_MODIFIED) && obj->first_content == NULL && obj->item_type != ITEM_CONTAINER)
{
fprintf(fp, "BasicVnum %d\n", obj->pIndexData->vnum);
}
else
{
/*
Compact, latest mode for non-basic objects
*/
fprintf(fp, "Compact\n");
fprintf(fp, "%d\n", obj->pIndexData->vnum);
if (IS_OBJ_STAT(obj, ITEM_FORGERY))
{
REMOVE_BIT(obj->extra_flags,ITEM_FORGERY);
fprintf( fp, "%d ", obj->extra_flags);
SET_BIT(obj->extra_flags,ITEM_FORGERY);
}
else
{
fprintf( fp, "%d ", obj->extra_flags);
}
fprintf( fp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
obj->wear_flags,
obj->item_type,
obj->weight,
obj->level,
obj->timer,
obj->cost,
obj->owned_by,
obj->value[0],
obj->value[1],
obj->value[2],
obj->value[3],
obj->value[4],
obj->value[5],
obj->value[6],
obj->value[7]);
if (obj->obj_quest)
{
int cnt;
fprintf(fp, "%d ", MAX_QUEST_BYTES);
for (cnt = 0 ; cnt < MAX_QUEST_BYTES ; cnt++)
{
fprintf(fp, "%d ", obj->obj_quest[cnt]);
}
fprintf(fp, "\n");
}
else
{
fprintf(fp, "0\n");
}
/*
End of Compact mode, Emud only checks non basic objects - Scandum
*/
if (!IS_SET(obj->extra_flags, ITEM_FORGERY))
{
if (obj->name != obj->pIndexData->name)
{
fprintf(fp, "Name %s~\n", obj->name);
}
if (obj->short_descr != obj->pIndexData->short_descr)
{
fprintf(fp, "Short %s~\n", obj->short_descr);
}
if (obj->long_descr != obj->pIndexData->long_descr)
{
fprintf(fp, "Long %s~\n", obj->long_descr);
}
if (obj->description != obj->pIndexData->description)
{
fprintf(fp, "Desc %s~\n", obj->description);
}
}
switch ( obj->item_type )
{
case ITEM_POTION:
case ITEM_SCROLL:
case ITEM_PILL:
if (obj->value[1] > 0)
{
fprintf( fp, "Spell 1 '%s'\n", skill_table[obj->value[1]].name );
}
if ( obj->value[2] > 0 )
{
fprintf( fp, "Spell 2 '%s'\n", skill_table[obj->value[2]].name );
}
if ( obj->value[3] > 0 )
{
fprintf( fp, "Spell 3 '%s'\n", skill_table[obj->value[3]].name );
}
break;
case ITEM_STAFF:
case ITEM_WAND:
if ( obj->value[3] > 0 )
{
fprintf( fp, "Spell 3 '%s'\n", skill_table[obj->value[3]].name );
}
break;
}
for (paf = obj->first_affect ; paf ; paf = paf->next )
{
if (paf->type < 0 || paf->type >= MAX_SKILL)
{
log_printf("fwrite_obj: Bad affect: %d", paf->type);
continue;
}
fprintf( fp, "AffectData '%s' %d %d %d %d %lld\n", skill_table[paf->type].name, paf->duration, paf->modifier, paf->location, paf->bittype, paf->bitvector );
}
if (obj->poison != NULL)
{
fwrite_poison_data( obj->poison, fp );
}
}
fprintf( fp, "RefKey %lld\nEnd\n\n", obj->obj_ref_key);
}
if (obj->first_content != NULL)
{
fwrite_obj( ch, obj->first_content, fp, iNest + 1 );
}
obj = obj->next_content;
}
pop_call();
return;
}
/*
Load a char and inventory into a new ch structure.
*/
bool load_char_obj( DESCRIPTOR_DATA *d, char *name )
{
static PC_DATA pcdata_zero;
char strsave[MAX_INPUT_LENGTH], buf[200], buf1[200], buf2[200];
OBJ_DATA *obj;
CHAR_DATA *ch;
FILE *fp;
bool found, loop;
sh_int cnt;
push_call("load_char_obj(%p,%p)",d,name);
if (name == NULL || *name == '\0')
{
pop_call();
return( FALSE );
}
ALLOCMEM(ch, CHAR_DATA, 1 );
clear_char( ch );
ALLOCMEM( ch->pcdata, PC_DATA, 1 );
*ch->pcdata = pcdata_zero;
d->character = ch;
ch->desc = d;
ch->name = STRALLOC(capitalize(name));
ch->short_descr = STRALLOC( "" );
ch->description = STRALLOC( "" );
ch->long_descr = STRALLOC( "" );
ch->pcdata->host = STRALLOC( "" );
ch->pcdata->mail_address = STRALLOC( "" );
ch->pcdata->html_address = STRALLOC( "" );
ch->pcdata->clan_name = STRALLOC( "" );
ch->pcdata->block_list = STRALLOC( "" );
ch->pcdata->title = STRALLOC( "" );
ch->pcdata->auto_command = STRALLOC( "" );
ch->pcdata->bamfin = STRALLOC( "" );
ch->pcdata->bamfout = STRALLOC( "" );
ch->pcdata->practice = 21;
ch->pcdata->travel = -1;
ch->pcdata->compass_width = 7;
if (d->descriptor != -999)
{
ch->act = PLR_AUTOEXIT|PLR_AUTOSAC|PLR_AUTO_SPLIT|PLR_EXP_TO_LEVEL;
ch->pcdata->channel = CHANNEL_CHAT|CHANNEL_PLAN|CHANNEL_TALK|CHANNEL_TRIVIA|CHANNEL_MORPH;
ch->pcdata->condition[COND_THIRST] = 48;
ch->pcdata->condition[COND_FULL] = 48;
ch->pcdata->condition[COND_AIR] = 10;
ch->pcdata->last_time = mud->current_time;
ch->pcdata->spam = 1024;
ch->pcdata->tactical_mode = 4;
sprintf(buf, "%c%c", toupper(name[0]), tolower(name[1]));
ch->pcdata->tactical_index = STRALLOC(buf);
ch->pcdata->edit_buf = STRDUPE(str_empty);
ch->pcdata->prompt_layout = STRALLOC( "{078}<$c$h{078}hp $c$m{078}m $c$v{078}mv $c$X{078}xp> <{178}$e{078}> ($c$l{078}) ($c$L{078}) {300}" );
ch->pcdata->subprompt = STRDUPE(str_empty);
ch->pcdata->tracking = STRDUPE(str_empty);
ch->pcdata->ambush = STRDUPE(str_empty);
ch->desc->port_size = 4096;
ch->pcdata->port_size = 4096;
ch->pcdata->death_room = ROOM_VNUM_SCHOOL;
ch->pcdata->clan_pledge = STRDUPE(str_empty);
ch->pcdata->god = -1;
ch->pcdata->vt100_type = 8024;
ch->pcdata->vt100_flags = VT102_FAST|VT100_HIGHLIGHT|VT100_BOLD|VT100_BEEP|VT100_UNDERLINE|VT100_FLASH|VT100_REVERSE;
ch->pcdata->recall = ROOM_VNUM_SCHOOL;
ch->pcdata->scroll_buf[0] = '\0';
for (cnt = 0 ; cnt < COLOR_MAX ; cnt++)
{
ch->pcdata->color[cnt] = 7 + 8 * 10;
}
for (cnt = 0 ; cnt < MAX_PK_ATTACKS ; cnt++)
{
ch->pcdata->last_pk_attack_name[cnt] = STRDUPE(str_empty);
}
}
/*
the following is allocated for file reading purposes, gets
deallocated if the player has no castle, need to load for finger too
*/
ALLOCMEM(ch->pcdata->castle, CASTLE_DATA, 1);
ch->pcdata->castle->door_room = -1;
ch->pcdata->castle->door_dir = -1;
ch->pcdata->last_real_room = ROOM_VNUM_TEMPLE;
for (cnt = 0 ; cnt < MAX_ALIAS ; cnt++)
{
ch->pcdata->alias[cnt] = STRDUPE(str_empty);
ch->pcdata->alias_c[cnt] = STRDUPE(str_empty);
}
for (cnt = 0 ; cnt < 26 ; cnt++)
{
ch->pcdata->back_buf[cnt] = STRALLOC("\r");
}
found = FALSE;
close_reserve();
/*
Move to a/a player dir structure for seek speed - Scandum
*/
sprintf(buf1, "%s/%c/%s", PLAYER_DIR, tolower(name[0]), capitalize_name(name));
sprintf(buf2, "%s/%c/%c/%s", PLAYER_DIR, tolower(name[0]), tolower(name[1]), capitalize_name(name));
if ((fp = my_fopen(buf1, "r", TRUE)) != NULL)
{
rename(buf1, buf2);
my_fclose(fp);
}
sprintf(strsave, "%s/%c/%c/%s", PLAYER_DIR, tolower(name[0]), tolower(name[1]), capitalize_name(name));
fp = my_fopen(strsave, "r" , TRUE);
if (fp != NULL)
{
int iNest;
for (iNest = 0 ; iNest < MAX_NEST ; iNest++)
{
rgObjNest[iNest] = NULL;
}
if (d->descriptor != -999 )
{
log_god_printf("Loading character file: %s D%d", name, d->descriptor);
}
if (!is_valid_file(ch, fp))
{
log_printf("Erasing invalid file: %s", name);
delete_player(ch);
pop_call();
return(load_char_obj(d, name));
}
found = TRUE;
loop = TRUE;
while (loop)
{
char letter;
char *word;
letter = fread_letter( fp );
if ( letter == '*' )
{
fread_to_eol( fp );
continue;
}
if ( letter != '#' )
{
log_printf("Load_char_obj: # not found. word was '%c%s'", letter, fread_word( fp ));
loop = FALSE;
}
word = fread_word( fp );
switch (word[0])
{
case 'O':
fread_obj(ch, fp);
break;
case 'P':
fread_char (ch, fp);
if (d->descriptor == -999)
{
loop = FALSE;
}
if (strcasecmp(ch->name, name))
{
log_printf("Incorrect name. #END on %s", name );
loop = FALSE;
}
break;
case 'E':
loop = FALSE;
break;
default:
log_printf("Load_char_obj: bad section.");
loop = FALSE;
break;
}
}
if (ch->pcdata->corpse_room)
{
for (obj = ch->first_carrying ; obj ; obj = obj->next_content)
{
if (obj->item_type == ITEM_CORPSE_PC)
{
ch->pcdata->corpse = obj;
}
}
}
if (fp != NULL)
{
my_fclose( fp );
}
}
if (ch->pcdata->castle && ch->pcdata->castle->num_rooms == 0)
{
FREEMEM(ch->pcdata->castle);
ch->pcdata->castle = NULL;
}
open_reserve();
/*
Fix up a few flags - Chaos 10/1/95
*/
ch->trust = ch->level;
ch->pcdata->god = ch->pcdata->god % MAX_GOD;
if (d->descriptor == -999)
{
pop_call();
return found;
}
ch->pcdata->last_saved = mud->current_time;
if (strlen(ch->pcdata->tactical_index) < 2)
{
sprintf(buf, "%c%c", toupper(ch->name[0]), tolower(ch->name[1]));
STRFREE(ch->pcdata->tactical_index);
ch->pcdata->tactical_index = STRALLOC(buf);
}
if (ch->level >= MAX_LEVEL)
{
if (!IS_GOD(ch))
{
SET_BIT(pvnum_index[ch->pcdata->pvnum]->flags, PVNUM_DENIED);
}
else
{
REMOVE_BIT(pvnum_index[ch->pcdata->pvnum]->flags, PVNUM_DENIED);
}
}
/*
Deny players with screwed up levels - Chaos 3/7/99
*/
if (ch->level < MAX_LEVEL)
{
int cnt2;
for (cnt = 0, cnt2 = 0 ; cnt < MAX_CLASS ; cnt++)
{
cnt2 += ch->pcdata->mclass[cnt];
}
if (ch->level != cnt2)
{
SET_BIT(pvnum_index[ch->pcdata->pvnum]->flags, PVNUM_DENIED);
}
}
/*
Check for illegal items, fix bits - Order 7/3/1995
*/
fix_object_bits(ch, ch->first_carrying);
char_reset( ch );
ch->pcdata->god = -1;
ch->pcdata->god = which_god(ch);
/*
Add missing languages - chaos 4/17/99
*/
{
int lan;
lan = (ch->level/3) + 3;
if (lan > MAX_RACE)
{
lan = MAX_RACE;
}
lan = lan - total_language(ch);
if (lan < 0)
{
ch->pcdata->language = SHIFT(ch->race);
ch->pcdata->speak = SHIFT(ch->race);
lan = UMIN(MAX_RACE, ch->level / 3 + 3);
lan = lan - total_language( ch );
}
for ( ; lan > 0 ; lan--)
{
add_language( ch );
}
}
if (ch->level >= 90)
{
knight_adjust_hpmnmv( ch );
}
/*
Check for old character - Chaos 10/30/95
*/
if (ch->level > 0 && character_expiration(ch) < 0)
{
delete_player(ch);
log_printf("Erasing old char %s", name);
pop_call();
return( load_char_obj( d, name ) );
}
pop_call();
return found;
}
/*
Read in a char.
*/
void fread_char( CHAR_DATA *ch, FILE *fp )
{
char *word;
char *line;
bool fMatch;
sh_int cnt, tst;
int x1, x2, x3, x4, x5;
push_call("fread_char(%p,%p)",ch,fp);
if (ch == NULL)
{
log_printf("Attempt to load a NULL character.");
pop_call();
return;
}
if (ch->pcdata == NULL)
{
log_printf("Attempting to load a player with no pcdata!\n");
pop_call();
return;
}
for ( ; ; )
{
word = feof( fp ) ? "End" : fread_word( fp );
fMatch = FALSE;
switch (UPPER(word[0]))
{
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;
case 'A':
NKEY("Account", ch->pcdata->account, fread_number(fp));
NKEY("Act", ch->act, fread_number(fp));
NKEY("Ansi", ch->pcdata->ansi, fread_number(fp));
NKEY("Affects1", ch->affected_by, fread_number(fp));
NKEY("Affects2", ch->affected2_by, fread_number(fp));
NKEY("Align", ch->alignment, fread_number(fp));
NKEY("AutoMode", ch->pcdata->auto_flags, fread_number(fp));
SKEY("AutoComm", ch->pcdata->auto_command,fread_string(fp));
if (!strcasecmp(word, "AffectData"))
{
AFFECT_DATA *paf;
int sn;
ALLOCMEM(paf, AFFECT_DATA, 1);
sn = skill_lookup(fread_word(fp));
if (sn < 0 || sn > MAX_SKILL)
{
bug("fread_char: unknown skill.");
}
else
{
paf->type = sn;
}
paf->duration = fread_number( fp );
paf->modifier = fread_number( fp );
paf->location = fread_number( fp );
paf->bittype = fread_number( fp );
paf->bitvector = fread_number( fp );
LINK(paf, ch->first_affect, ch->last_affect, next, prev );
fMatch = TRUE;
break;
}
if (!strcasecmp(word, "AffectData1"))
{
AFFECT_DATA *paf;
int sn;
ALLOCMEM(paf, AFFECT_DATA, 1);
sn = skill_lookup(fread_word(fp));
if (sn < 0 || sn > MAX_SKILL)
{
bug("fread_char: unknown skill.");
}
else
{
paf->type = sn;
}
paf->duration = fread_number( fp );
paf->modifier = fread_number( fp );
paf->location = fread_number( fp );
paf->bittype = fread_number( fp );
paf->bitvector = fread_number( fp );
LINK(paf, ch->first_affect, ch->last_affect, next, prev );
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "AttrMod" ) )
{
line = fread_line( fp );
x1=x2=x3=x4=x5=0;
sscanf( line, "%d %d %d %d %d", &x1, &x2, &x3, &x4, &x5 );
ch->pcdata->mod_str = x1;
ch->pcdata->mod_int = x2;
ch->pcdata->mod_wis = x3;
ch->pcdata->mod_dex = x4;
ch->pcdata->mod_con = x5;
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "AttrPerm" ) )
{
line = fread_line( fp );
x1=x2=x3=x4=x5=13;
sscanf( line, "%d %d %d %d %d", &x1, &x2, &x3, &x4, &x5 );
ch->pcdata->perm_str = x1;
ch->pcdata->perm_int = x2;
ch->pcdata->perm_wis = x3;
ch->pcdata->perm_dex = x4;
ch->pcdata->perm_con = x5;
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "Actuals" ) )
{
ch->pcdata->actual_max_hit = fread_number( fp );
ch->pcdata->actual_max_mana = fread_number( fp );
ch->pcdata->actual_max_move = fread_number( fp );
fMatch = TRUE;
break;
}
if ( !strcmp( word, "Alias" ) )
{
tst=0;
for (cnt = 0 ; cnt < MAX_ALIAS && tst == 0 ; cnt++)
{
if (ch->pcdata->alias[cnt][0]=='\0')
{
tst=1;
STRFREE (ch->pcdata->alias[cnt] );
STRFREE (ch->pcdata->alias_c[cnt] );
ch->pcdata->alias_c[cnt]=fread_string( fp ) ;
ch->pcdata->alias[cnt]=fread_string( fp ) ;
}
}
if (tst==0)
{
char *ptx1;
ptx1 = fread_string( fp );
STRFREE (ptx1 );
ptx1 = fread_string( fp );
STRFREE (ptx1 );
}
fMatch = TRUE;
break;
}
if (!strcmp( word, "A_Range" ) )
{
ch->pcdata->a_range_lo = fread_number(fp);
ch->pcdata->a_range_hi = fread_number(fp);
fMatch = TRUE;
break;
}
break;
case 'B':
SKEY("Bamfin", ch->pcdata->bamfin, fread_string(fp));
SKEY("Bamfout", ch->pcdata->bamfout, fread_string(fp));
SKEY("Blocking", ch->pcdata->block_list, fread_string(fp));
break;
case 'C':
AKEY("Color", ch->pcdata->color, fread_number(fp));
/* Old */ AKEY("Colorc", ch->pcdata->color, fread_number(fp));
SKEY("ClanName", ch->pcdata->clan_name, fread_string(fp));
SKEY("ClanPled", ch->pcdata->clan_pledge, fread_string(fp));
NKEY("Channel", ch->pcdata->channel, fread_number(fp));
NKEY("ClanPosi", ch->pcdata->clan_position, fread_number(fp));
NKEY("Class", ch->class, fread_number(fp));
NKEY("Critical", ch->critical_hit_by, fread_number(fp));
NKEY("Clock", ch->pcdata->clock, fread_number(fp));
NKEY("Compass", ch->pcdata->compass_width, fread_number(fp));
NKEY("C_Room", ch->pcdata->corpse_room, fread_number(fp));
if (ch->pcdata->castle != NULL)
{
NKEY("Cstl_ent", ch->pcdata->castle->entrance, fread_number(fp));
NKEY("Cstl_dor", ch->pcdata->castle->door_room, fread_number(fp));
NKEY("Cstl_dir", ch->pcdata->castle->door_dir, fread_number(fp));
NKEY("Cstl_has", ch->pcdata->castle->has_backdoor, fread_number(fp));
NKEY("Cstl_cst", ch->pcdata->castle->cost, fread_number(fp));
NKEY("Cstl_nrm", ch->pcdata->castle->num_rooms, fread_number(fp));
NKEY("Cstl_nmo", ch->pcdata->castle->num_mobiles, fread_number(fp));
NKEY("Cstl_nob", ch->pcdata->castle->num_objects, fread_number(fp));
}
if (!strcasecmp(word, "Crime_Data"))
{
CRIME_DATA *pcr;
ALLOCMEM(pcr, CRIME_DATA, 1);
pcr->crime_record = fread_string(fp);
pcr->arrester = fread_string(fp);
pcr->date = fread_number(fp);
pcr->level = fread_number(fp);
pcr->jailtime = fread_number(fp);
pcr->released = fread_number(fp);
pcr->releaser = fread_string(fp);
LINK(pcr, ch->pcdata->first_record, ch->pcdata->last_record, next, prev );
fMatch = TRUE;
break;
}
break;
case 'D':
NKEY("Damroll", ch->damroll, fread_number(fp));
NKEY("Death", ch->pcdata->death_room, fread_number(fp));
SKEY("Domain", ch->desc->host, fread_string(fp));
if ( !strcasecmp( word, "DrFuTh" ) )
{
line = fread_line( fp );
sscanf( line, "%d %d %d", &x1, &x2, &x3 );
ch->pcdata->condition[0] = x1;
ch->pcdata->condition[1] = x2;
ch->pcdata->condition[2] = x3;
fMatch = TRUE;
break;
}
if ( !strcasecmp( word, "DrFuThAi" ) )
{
line = fread_line( fp );
sscanf( line, "%d %d %d %d", &x1, &x2, &x3, &x4 );
ch->pcdata->condition[0] = x1;
ch->pcdata->condition[1] = x2;
ch->pcdata->condition[2] = x3;
ch->pcdata->condition[3] = x4;
fMatch = TRUE;
break;
}
break;
case 'E':
SKEY("E_Descr", ch->description, fread_string(fp));
NKEY("EQ_DR", ch->pcdata->eqdamroll, fread_number(fp));
NKEY("EQ_HR", ch->pcdata->eqhitroll, fread_number(fp));
NKEY("EQ_AC", cnt, fread_number(fp));
NKEY("EQ_SP", ch->pcdata->eqsaves, fread_number(fp));
if ( !strcasecmp( word, "End" ) )
{
/*
ENDLOAD Chaos 10/11/93
*/
REMOVE_BIT(ch->act, PLR_TELOPTS|PLR_COMBINE|PLR_TELNET_GA|PLR_SILENCE|PLR_MUTE|PLR_LOG|PLR_DENY|PLR_FREEZE|PLR_CHAT|PLR_PLAN|PLR_BATTLE|PLR_VICTIM_LIST|PLR_FOS|PLR_ARRESTED);
if (ch->pcdata->clan_name[0] != '\0')
{
if (get_clan(ch->pcdata->clan_name) != NULL)
{
ch->pcdata->clan = get_clan(ch->pcdata->clan_name);
}
else
{
RESTRING(ch->pcdata->clan_name, "");
ch->pcdata->clan = NULL;
}
}
if (ch->pcdata->vt100_type / 100 < 80 || ch->pcdata->vt100_type / 100 > MAX_TACTICAL_COL)
{
ch->pcdata->vt100_type = 8024;
}
ch->desc->port_size = ch->pcdata->port_size;
ch->position = POS_STANDING;
for (cnt = 0 ; cnt < MAX_ALIAS ; cnt++)
{
if (ch->pcdata->alias[cnt] == NULL)
{
ch->pcdata->alias[cnt] = STRDUPE(str_empty);
}
if (ch->pcdata->alias_c[cnt] == NULL)
{
ch->pcdata->alias_c[cnt] = STRDUPE(str_empty);
}
}
if (ch->hit < 0)
{
ch->hit = 1;
}
ch->trust = ch->level;
if (ch->level < LEVEL_IMMORTAL)
{
if (IS_SET(ch->act, PLR_WIZINVIS))
{
REMOVE_BIT(ch->act, PLR_WIZINVIS);
}
if (IS_SET(ch->act, PLR_WIZCLOAK))
{
REMOVE_BIT(ch->act, PLR_WIZCLOAK);
}
if (IS_AFFECTED(ch, AFF2_CAMPING))
{
REMOVE_BIT(ch->affected2_by, 0-AFF2_CAMPING);
}
if (IS_SET(ch->act, PLR_HOLYLIGHT))
{
REMOVE_BIT(ch->act, PLR_HOLYLIGHT);
}
if (IS_SET(ch->act, PLR_BUILDLIGHT))
{
REMOVE_BIT(ch->act, PLR_BUILDLIGHT);
}
}
if (ch->pcdata->castle && ch->pcdata->castle->entrance > 0 && ch->pcdata->castle->entrance < ROOM_VNUM_CASTLE)
{
ch->pcdata->castle->entrance += 60000;
ch->pcdata->castle->door_room = -1;
ch->pcdata->castle->door_dir = -1;
}
if (ch->act < 0)
{
ch->act = 0;
}
add_pvnum(ch);
REMOVE_BIT(pvnum_index[ch->pcdata->pvnum]->flags, PVNUM_DELETED);
if (get_room_index(ch->pcdata->recall) == NULL)
{
ch->pcdata->recall = ROOM_VNUM_TEMPLE;
}
if (get_room_index(ch->pcdata->death_room) == NULL)
{
ch->pcdata->death_room = ROOM_VNUM_TEMPLE;
}
if (get_room_index(ch->pcdata->was_in_room) == NULL)
{
ch->pcdata->was_in_room = ROOM_VNUM_TEMPLE;
}
ch->in_room = get_room_index(ch->pcdata->was_in_room);
pop_call();
return;
}
NKEY("Exp", ch->pcdata->exp, fread_number(fp));
break;
case 'F':
NKEY("Function", ch->pcdata->functions, fread_number(fp));
break;
case 'G':
NKEY("Gold", ch->gold, fread_number(fp));
break;
case 'H':
AKEY("History", ch->pcdata->history, fread_number(fp));
SKEY("HtmlAddy", ch->pcdata->html_address, fread_string(fp));
NKEY("Hitroll", ch->hitroll, fread_number(fp));
if (!strcasecmp( word, "HpMaMv" ) )
{
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;
}
break;
case 'J':
NKEY("Jaildate", ch->pcdata->jaildate, fread_number( fp ) );
NKEY("Jailtime", ch->pcdata->jailtime, fread_number( fp ) );
break;
case 'K':
NKEY("K_Played", ch->pcdata->killer_played, fread_number(fp));
break;
case 'L':
NKEY("Level", ch->level, fread_number(fp));
SKEY("L_Descr", ch->long_descr, fread_string(fp));
NKEY("Language", ch->pcdata->language, fread_number(fp));
NKEY("LastNote", ch->pcdata->last_note, fread_number(fp));
SKEY("Login", ch->pcdata->host, fread_string(fp));
NKEY("LastTime", ch->pcdata->last_time, fread_number(fp));
NKEY("LastRoom", ch->pcdata->last_real_room, fread_number(fp));
break;
case 'M':
AKEY("Mclass", ch->pcdata->mclass, fread_number(fp));
SKEY("MailAddy", ch->pcdata->mail_address, fread_string(fp));
NKEY("Morph", ch->pcdata->morph_points, fread_number(fp));
break;
case 'N':
break;
case 'O':
NKEY("ObjVerNr", ch->pcdata->obj_version_number, fread_number(fp));
NKEY("O_Played", ch->pcdata->outcast_played, fread_number(fp));
break;
case 'P':
NKEY("Psw", ch->pcdata->password, fread_number(fp));
NKEY("Password", ch->pcdata->password, fread_number(fp));
NKEY("Played", ch->pcdata->played, fread_number(fp));
NKEY("Practice", ch->pcdata->practice, fread_number(fp));
NKEY("Prefix", ch->pcdata->honorific, fread_number(fp));
NKEY("Prev_hrs", ch->pcdata->previous_hours, fread_number(fp));
NKEY("Portsize", ch->pcdata->port_size, fread_number(fp));
SKEY("Prompt", ch->pcdata->prompt_layout, fread_string(fp));
NKEY("Pvnum", ch->pcdata->pvnum, fread_number(fp));
if (!strcmp(word, "PK_ATTACKS"))
{
int cnt2;
cnt = fread_number(fp);
for (cnt2 = 0 ; cnt2 < cnt ; cnt2++)
{
if (cnt2 >= MAX_PK_ATTACKS)
{
fread_number(fp);
fread_number(fp);
fread_string(fp);
}
else
{
ch->pcdata->last_pk_attack_time[cnt2] = fread_number(fp);
ch->pcdata->last_pk_attack_pvnum[cnt2] = fread_number(fp);
STRFREE(ch->pcdata->last_pk_attack_name[cnt2]);
ch->pcdata->last_pk_attack_name[cnt2] = fread_string(fp);
}
}
fMatch = TRUE;
break;
}
if (!strcmp( word, "POISON_DATA" ) )
{
POISON_DATA *pd;
pd = fread_poison_data( fp );
if (pd != NULL && ch->poison != NULL)
{
pd->next = ch->poison;
ch->poison = pd;
}
else if (pd != NULL)
{
ch->poison = pd;
}
fMatch = TRUE;
break;
}
if (!strcmp(word, "Playtime"))
{
ch->pcdata->played += fread_number(fp);
fMatch = TRUE;
break;
}
break;
case 'Q':
if (!strcasecmp(word, "Qstb"))
{
int qn, byt;
byt = fread_number( fp );
qn = fread_number( fp );
ALLOCMEM(ch->pcdata->quest[qn], bool, MAX_QUEST_BYTES);
for (cnt = 0 ; cnt < byt ; cnt++)
{
ch->pcdata->quest[qn][cnt] = fread_number( fp );
}
fMatch = TRUE;
}
break;
case 'R':
NKEY("Race", ch->race, fread_number(fp));
NKEY("Reinc", ch->pcdata->reincarnation, fread_number(fp));
NKEY("Recall", ch->pcdata->recall, fread_number(fp));
NKEY("Room", ch->pcdata->was_in_room, fread_number(fp));
break;
case 'S':
NKEY("Saves", ch->saving_throw, fread_number(fp));
NKEY("Sex", ch->sex, fread_number(fp));
SKEY("S_Descr", ch->short_descr, fread_string(fp));
NKEY("Speed", ch->speed, fread_number(fp));
NKEY("Speak", ch->pcdata->speak, fread_number(fp));
NKEY("Spam", ch->pcdata->spam, fread_number(fp));
if ( !strcasecmp( word, "Skill" ) )
{
int sn;
int value;
value = fread_number( fp );
value = URANGE(0, value, 99);
sn = skill_lookup( fread_word( fp ) );
if (sn < 0)
{
bug("Fread_char: %s - unknown skill.", ch->name);
}
else
{
cnt = multi_pick(ch, sn);
if (cnt >= 0 && value > class_table[cnt].skill_adept)
{
value = class_table[cnt].skill_adept;
}
ch->pcdata->learned[sn] = value;
}
fMatch = TRUE;
}
break;
case 'T':
AKEY("Topic", ch->pcdata->topic_stamp, fread_number( fp ) );
NKEY("Trust", ch->trust, fread_number( fp ) );
NKEY("Tactical", ch->pcdata->tactical_mode, fread_number( fp ) );
NKEY("Trivia", ch->pcdata->trivia_points, fread_number( fp ) );
SKEY("TactIndx", ch->pcdata->tactical_index, fread_string( fp ) );
if (!strcasecmp(word, "Title"))
{
STRFREE(ch->pcdata->title);
ch->pcdata->title = fread_string(fp);
set_title(ch, ch->pcdata->title);
fMatch = TRUE;
break;
}
break;
case 'V':
NKEY("Version", ch->pcdata->version, fread_number(fp));
NKEY("Vt100", ch->pcdata->vt100, fread_number(fp));
NKEY("Vt100_T", ch->pcdata->vt100_type, fread_number(fp));
NKEY("Vt100_F", ch->pcdata->vt100_flags, fread_number(fp));
break;
case 'W':
NKEY("Whichgod", ch->pcdata->god, fread_number(fp));
NKEY("Wimpy", ch->pcdata->wimpy, fread_number(fp));
break;
}
if ( !fMatch )
{
bug("fread_char: no match: (word) %s (line) %s", word, fread_line(fp));
}
}
pop_call();
return;
}
void fread_obj( CHAR_DATA *ch, FILE *fp )
{
OBJ_DATA *obj;
char *word;
int BasicVnum, WearLoc;
bool fMatch, iNest;
push_call("fread_obj(%p,%p)",ch,fp);
BasicVnum = 0;
WearLoc = WEAR_NONE;
iNest = 0;
ALLOCMEM(obj, OBJ_DATA, 1);
obj->pIndexData = obj_index[OBJ_VNUM_MUSHROOM];
for ( ; ; )
{
word = feof( fp ) ? "End" : fread_word( fp );
fMatch = FALSE;
switch ( UPPER(word[0]) )
{
case 'A':
if (!strcmp(word, "AffectData"))
{
AFFECT_DATA *paf;
int sn;
ALLOCMEM(paf, AFFECT_DATA, 1);
sn = skill_lookup(fread_word(fp));
if (sn < 0)
{
log_string("fread_obj: unknown skill.");
}
else
{
paf->type = sn;
}
paf->duration = fread_number( fp );
paf->modifier = fread_number( fp );
paf->location = fread_number( fp );
paf->bittype = fread_number( fp );
paf->bitvector = fread_number( fp );
LINK (paf, obj->first_affect, obj->last_affect, next, prev);
fMatch = TRUE;
break;
}
if (!strcmp(word, "AffectData1"))
{
AFFECT_DATA *paf;
int sn;
ALLOCMEM(paf, AFFECT_DATA, 1);
sn = skill_lookup(fread_word(fp));
if (sn < 0)
{
log_string("fread_obj: unknown skill.");
}
else
{
paf->type = sn;
}
paf->duration = fread_number( fp );
paf->modifier = fread_number( fp );
paf->location = fread_number( fp );
paf->bittype = fread_number( fp );
paf->bitvector = fread_number( fp );
LINK (paf, obj->first_affect, obj->last_affect, next, prev);
fMatch = TRUE;
break;
}
break;
case 'B':
NKEY("BasicVnum", BasicVnum, fread_number( fp ) );
break;
case 'C':
if (!strcmp(word, "Compact"))
{
int byt, cnt, vnum;
fread_to_eol( fp );
vnum = fread_number(fp);
if ((obj->pIndexData = get_obj_index(vnum)) == NULL)
{
if (IS_SET(mud->flags, MUD_EMUD_REALGAME))
{
log_printf("fread_obj: bad vnum %d.", vnum);
}
obj->pIndexData = obj_index[OBJ_VNUM_MUSHROOM];
}
obj->extra_flags = fread_number( fp );
obj->wear_flags = fread_number( fp );
obj->item_type = fread_number( fp );
obj->weight = fread_number( fp );
obj->level = fread_number( fp );
obj->timer = fread_number( fp );
obj->cost = fread_number( fp );
obj->owned_by = fread_number( fp );
obj->value[0] = fread_number( fp );
obj->value[1] = fread_number( fp );
obj->value[2] = fread_number( fp );
obj->value[3] = fread_number( fp );
obj->value[4] = fread_number( fp );
obj->value[5] = fread_number( fp );
obj->value[6] = fread_number( fp );
obj->value[7] = fread_number( fp );
byt = fread_number( fp );
if (byt != 0)
{
ALLOCMEM( obj->obj_quest, unsigned char, MAX_QUEST_BYTES );
for (cnt = 0 ; cnt < byt ; cnt++)
{
obj->obj_quest[cnt] = fread_number( fp );
}
}
fMatch = TRUE;
break;
}
break;
case 'D':
SKEY("Desc", obj->description, fread_string( fp ) );
break;
case 'E':
if (!strcmp(word, "End"))
{
if (BasicVnum == 0)
{
if (obj->owned_by == 0
&& obj->first_affect == NULL
&& obj->value[0] == obj->pIndexData->value[0]
&& obj->value[1] == obj->pIndexData->value[1]
&& obj->value[2] == obj->pIndexData->value[2]
&& obj->value[3] == obj->pIndexData->value[3]
&& obj->timer == 0
&& obj->obj_quest == NULL
&& obj->poison == NULL
&& obj->short_descr == NULL)
{
REMOVE_BIT(obj->extra_flags, ITEM_MODIFIED);
}
else
{
SET_BIT(obj->extra_flags, ITEM_MODIFIED);
}
}
else
{
OBJ_INDEX_DATA *pObjIndex;
if ((pObjIndex = get_obj_index(BasicVnum)) == NULL)
{
if (IS_SET(mud->flags, MUD_EMUD_REALGAME))
{
log_printf("fread_obj: bad vnum %d.", BasicVnum);
}
BasicVnum = OBJ_VNUM_MUSHROOM;
pObjIndex = get_obj_index(BasicVnum);
}
obj->pIndexData = pObjIndex;
obj->level = pObjIndex->level;
obj->name = STRDUPE(pObjIndex->name);
obj->short_descr = STRDUPE(pObjIndex->short_descr);
obj->long_descr = STRDUPE(pObjIndex->long_descr);
obj->description = STRDUPE(pObjIndex->description);
obj->item_type = pObjIndex->item_type;
obj->extra_flags = pObjIndex->extra_flags;
obj->wear_flags = pObjIndex->wear_flags;
obj->value[0] = pObjIndex->value[0];
obj->value[1] = pObjIndex->value[1];
obj->value[2] = pObjIndex->value[2];
obj->value[3] = pObjIndex->value[3];
obj->weight = pObjIndex->weight;
obj->cost = pObjIndex->cost;
obj->level = pObjIndex->level;
}
/*
Special chains of the Gods
*/
if (BasicVnum == 0)
{
if (obj->level <= 0 || obj->level < obj->pIndexData->level)
{
obj->level = obj->pIndexData->level;
}
if (obj->name == NULL)
{
STRFREE( obj->name );
obj->name = STRDUPE(obj->pIndexData->name);
}
if (obj->short_descr == NULL)
{
STRFREE( obj->short_descr );
obj->short_descr = STRDUPE(obj->pIndexData->short_descr);
}
if (obj->long_descr == NULL)
{
STRFREE( obj->long_descr );
obj->long_descr = STRDUPE(obj->pIndexData->long_descr);
}
if (obj->description == NULL)
{
STRFREE( obj->description );
obj->description = STRDUPE(obj->pIndexData->description);
}
}
obj->wear_loc = WearLoc;
rgObjNest[iNest] = obj;
if (iNest == 0)
{
obj_to_char(obj, ch);
}
else
{
obj_to_obj(obj, rgObjNest[iNest-1]);
}
LINK(obj, mud->f_obj, mud->l_obj, next, prev);
LINK(obj, obj->pIndexData->first_instance, obj->pIndexData->last_instance, next_instance, prev_instance);
add_obj_ref_hash( obj );
mud->total_obj++;
obj->pIndexData->total_objects++;
pop_call();
return;
}
break;
case 'L':
SKEY("Long", obj->long_descr, fread_string(fp));
break;
case 'N':
NKEY("Nest", iNest, fread_number(fp));
SKEY("Name", obj->name, fread_string(fp));
break;
case 'P':
if (!strcmp(word, "POISON_DATA"))
{
POISON_DATA *pd;
pd = fread_poison_data( fp );
if (pd != NULL)
{
if (obj->poison != NULL)
{
pd->next = obj->poison;
obj->poison = pd;
}
else if (pd != NULL)
{
obj->poison = pd;
}
}
fMatch = TRUE;
break;
}
break;
case 'Q':
/*
do not remove this section for backward compatibility
*/
if (!strcasecmp( word, "Quick2"))
{
int byt, cnt;
fread_to_eol( fp );
iNest = fread_number( fp );
WearLoc = fread_number( fp );
obj->name = fread_string( fp );
obj->short_descr = fread_string( fp );
obj->long_descr = fread_string( fp );
obj->description = fread_string( fp );
cnt = fread_number(fp);
if ((obj->pIndexData = get_obj_index(cnt)) == NULL)
{
if (IS_SET(mud->flags, MUD_EMUD_REALGAME))
{
log_printf("fread_obj: bad vnum %d.", cnt);
}
obj->pIndexData = obj_index[OBJ_VNUM_MUSHROOM];
}
obj->extra_flags = fread_number( fp );
obj->wear_flags = fread_number( fp );
obj->item_type = fread_number( fp );
obj->weight = fread_number( fp );
obj->level = fread_number( fp );
obj->timer = fread_number( fp );
obj->cost = fread_number( fp );
obj->owned_by = fread_number( fp );
obj->value[0] = fread_number( fp );
obj->value[1] = fread_number( fp );
obj->value[2] = fread_number( fp );
obj->value[3] = fread_number( fp );
byt = fread_number( fp );
if (byt != 0)
{
ALLOCMEM( obj->obj_quest, unsigned char, MAX_QUEST_BYTES );
for (cnt = 0 ; cnt < byt ; cnt++)
{
obj->obj_quest[cnt] = fread_number( fp );
}
}
fMatch = TRUE;
break;
}
break;
case 'R':
NKEY("RefKey", obj->obj_ref_key, fread_number(fp));
break;
case 'S':
SKEY("Short", obj->short_descr, fread_string(fp));
if ( !strcasecmp( word, "Spell" ) )
{
int iValue, sn;
iValue = fread_number( fp );
sn = skill_lookup( fread_word( fp ) );
if (iValue < 1 || iValue > 3)
{
log_printf("Fread_obj: bad iValue %d.", iValue );
}
else if (sn < 0)
{
log_string("Fread_obj: unknown skill.");
}
else
{
obj->value[iValue] = sn;
}
fMatch = TRUE;
break;
}
break;
case 'W':
NKEY("WearLoc", WearLoc, fread_number(fp));
break;
}
if (!fMatch)
{
fread_to_eol( fp );
log_printf("Fread_obj: no match: %s", word);
}
}
}
void roll_race( CHAR_DATA *ch )
{
int race, cnt;
race = ch->race;
push_call("roll_race(%p)",ch);
/*
set average to 15.0 - Scandum 06/02/02
*/
ch->pcdata->perm_str = 15 + race_table[race].race_mod[0];
ch->pcdata->perm_dex = 15 + race_table[race].race_mod[1];
ch->pcdata->perm_int = 15 + race_table[race].race_mod[2];
ch->pcdata->perm_wis = 15 + race_table[race].race_mod[3];
ch->pcdata->perm_con = 15 + race_table[race].race_mod[4];
/*
each stat raises by one per reinc! - Manwe 4/12/1999
*/
ch->pcdata->perm_str += ch->pcdata->reincarnation;
ch->pcdata->perm_dex += ch->pcdata->reincarnation;
ch->pcdata->perm_int += ch->pcdata->reincarnation;
ch->pcdata->perm_wis += ch->pcdata->reincarnation;
ch->pcdata->perm_con += ch->pcdata->reincarnation;
ch->pcdata->language = SHIFT(race);
ch->pcdata->speak = SHIFT(race);
for (cnt = 0 ; cnt < 2 ; cnt++)
{
add_language(ch);
}
pop_call();
return;
}
void add_language( CHAR_DATA *ch )
{
int cnt, scnt;
push_call("add_language(%p)",ch);
cnt = number_range(0, MAX_RACE-1);
scnt = cnt;
while (IS_SHIFT(ch->pcdata->language, cnt))
{
cnt++;
if (cnt == MAX_RACE)
{
cnt = 0;
}
if (cnt == scnt)
{
pop_call();
return;
}
}
ch->pcdata->language = SET_SHIFT(ch->pcdata->language, cnt);
/*
preventing from showing to new users and reincarnators,
Manwe, 15/10/1999
*/
if (ch->level > 2)
{
ch_printf(ch, "You just learned a new language : %s\n\r", race_table[cnt].race_name);
}
pop_call();
return;
}
/*
This routine makes sure that files are not cross linked of chopped
Chaos - 5/30/96
*/
bool is_valid_file( CHAR_DATA *ch, FILE *fp )
{
char buf[MAX_INPUT_LENGTH];
sh_int cnt, cf;
push_call("is_valid_File(%p,%p)",ch,fp);
cf = ' ';
cnt = 0;
while (cf != '#' && cnt > -50)
{
cnt--;
fseek(fp, cnt, SEEK_END);
cf = fgetc(fp);
}
if (cnt == -50)
{
log_printf("Didn't find an #END on %s", ch->name);
rewind( fp );
pop_call();
return( FALSE );
}
for (cf = '#', cnt = 0 ; cf != '\n' && cf != EOF ; cnt++)
{
buf[cnt] = cf;
cf = fgetc(fp);
}
buf[cnt] = '\0';
if (str_prefix("#END ", buf))
{
log_printf("Didn't find an #END on %s", ch->name);
rewind( fp );
pop_call();
return( FALSE );
}
if (!strcasecmp(ch->name, &buf[5]))
{
rewind( fp );
pop_call();
return( TRUE );
}
log_printf("Cross linked file %s on %s", buf, ch->name );
rewind( fp );
pop_call();
return( FALSE );
}
int total_language( CHAR_DATA *ch )
{
int total, cnt;
push_call("total_language(%p)",ch);
for (total = 0, cnt = 0 ; cnt < MAX_RACE ; cnt++)
{
if (IS_SET(ch->pcdata->language, SHIFT(cnt)))
{
total++;
}
}
pop_call();
return( total );
}
/*
Let's save that poison data - Chaos 4/20/99
*/
void fwrite_poison_data( POISON_DATA *pd, FILE *fp )
{
push_call("fwrite_poison_data(%p,%p)",pd,fp);
fprintf( fp, "POISON_DATA 1 %d %d %d %d %d %d %d %d %d\n",
pd->for_npc?1:0,
(int) pd->poison_type,
pd->instant_damage_low,
pd->instant_damage_high,
pd->constant_duration,
pd->constant_damage_low,
pd->constant_damage_high,
pd->owner,
pd->poisoner );
if (pd->next != NULL)
{
fwrite_poison_data( pd->next, fp );
}
pop_call();
return;
}
POISON_DATA *fread_poison_data( FILE *fp )
{
POISON_DATA *pd;
int ptype;
push_call("fread_poison_data(%p)",fp);
ALLOCMEM( pd, POISON_DATA, 1 );
ptype = fread_number( fp );
if (ptype == 1)
{
ptype = fread_number( fp );
if (ptype == 0)
{
pd->for_npc = FALSE;
}
else
{
pd->for_npc = FALSE;
}
pd->poison_type = (sh_int)fread_number(fp);
pd->instant_damage_low = fread_number(fp);
pd->instant_damage_high = fread_number(fp);
pd->constant_duration = fread_number(fp);
pd->constant_damage_low = fread_number(fp);
pd->constant_damage_high = fread_number(fp);
pd->owner = fread_number(fp);
pd->poisoner = fread_number(fp);
pd->next = NULL;
pop_call();
return( pd );
}
else
{
fread_to_eol( fp );
}
FREEMEM( pd );
pop_call();
return( NULL );
}
/*
Hypnos 20020326: Check player directories
*/
int check_dirs( void )
{
int i, j, dir;
char tempbuf[320];
push_call("check_dirs()");
dir = 0;
if (mkdir(PLAYER_DIR, XX_DIRMASK) == -1)
{
if (errno != EEXIST)
{
pop_call();
return -1;
}
}
else
{
dir++;
}
for (i = 0 ; i < 26 ; i++)
{
sprintf(tempbuf, "%s/%c", PLAYER_DIR, 'a' + i);
if (mkdir(tempbuf, XX_DIRMASK) == -1)
{
if (errno != EEXIST)
{
pop_call();
return -1;
}
}
else
{
dir++;
}
}
for (i = 0 ; i < 26 ; i++)
{
for (j = 0 ; j < 26 ; j++)
{
sprintf(tempbuf, "%s/%c/%c", PLAYER_DIR, 'a' + i, 'a' + j);
if (mkdir(tempbuf, XX_DIRMASK) == -1)
{
if (errno != EEXIST)
{
pop_call();
return -1;
}
}
else
{
dir++;
}
sprintf(tempbuf, "%s/%c/%c/dmp", PLAYER_DIR, 'a' + i, 'a' + j);
if (mkdir(tempbuf, XX_DIRMASK) == -1)
{
if (errno != EEXIST)
{
pop_call();
return -1;
}
}
else
{
dir++;
}
sprintf(tempbuf, "%s/%c/%c/del", PLAYER_DIR, 'a' + i, 'a' + j);
if (mkdir(tempbuf, XX_DIRMASK) == -1)
{
if (errno != EEXIST)
{
pop_call();
return -1;
}
}
else
{
dir++;
}
sprintf(tempbuf, "%s/%c/%c/bak", PLAYER_DIR, 'a' + i, 'a' + j);
if (mkdir(tempbuf, XX_DIRMASK) == -1)
{
if (errno != EEXIST)
{
pop_call();
return -1;
}
}
else
{
dir++;
}
}
}
pop_call();
return dir;
}