lurf/area/
lurf/build/testing/
lurf/log/
lurf/player/
lurf/player/backup/
#include <glib.h>

#include <sys/types.h>
#include <ctype.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <time.h> 
#include <merc.h> 
#include <recycle.h> 
#include <tables.h>

extern void	fwrite_pet	args( ( CHAR_DATA *ch,  FILE *fp ) ); 
extern void	fwrite_obj	args( ( CHAR_DATA *ch,  OBJ_DATA  *obj,	FILE *fp, int iNest ) ); 
extern void    save_char_obj args(( CHAR_DATA *ch ));

//Local Functions
void init_chardata	args(( CHAR_DATA *ch ));
void reset_chardata	args(( CHAR_DATA *ch ));
void reset_pcdata	args(( PC_DATA *pcdata ));



/* stuff for recyling characters */
CHAR_DATA *char_free;

CHAR_DATA *new_char (void) { 
	//static CHAR_DATA ch_zero; 
	CHAR_DATA *ch;

    if (char_free == NULL){ 
	    ch = g_chunk_new (CHAR_DATA, char_data_mem_chunk);
	    init_chardata(ch);
	    mudsetting->Mobiles_New++;
    }
    else { 
	    ch = char_free; 
	    char_free = char_free->next;
	    mudsetting->Mobiles_Recycle++; 
	    mudsetting->Mobiles_Recycle_Heap--;
    }

    VALIDATE(ch);
	
	reset_chardata(ch);
	ch->logon			= current_time; 
	ch->armor = 100; 
	ch->position		= POS_STANDING; 
	ch->practice = 0; 
	ch->hit				= 250; 
	ch->max_hit = 250; 
	ch->mana			= 250; 
	ch->max_mana = 250; 
	ch->move			= 250; 
	ch->max_move = 250; 
	ch->master			= NULL; 
	ch->leader = NULL; 
	ch->fighting		= NULL; 
	ch->mount = NULL; 
	ch->wizard			= NULL; 
	ch->paradox[0] = 0;
	ch->paradox[1]          = 0;
	ch->paradox[2] = 0;
	ch->damcap[0]			= 500;
	ch->damcap[1]			= 0; 
	return ch; 
}

/*
 * Used to init and reset character data.
 */
void reset_chardata(CHAR_DATA *ch)
{
	int x = 0;
	for (x = 0; x < 11; x++)
		ch->stance[x]		=	0;
	for (x = 0; x < 8; x++)
		ch->cmbt[x]		=	0;
	for (x = 0; x < 5; x++)
		ch->spl[x]		=	0;
	for (x = 0; x < 13; x++)
		ch->wpn[x]		=	0;
	for (x = 0; x < 7; x++)
		ch->loc_hp[x]		=	0;
	for (x = 0; x < 10; x++)
		ch->pet_stats[x]	=	0;
	for (x = 0; x < 2; x++)
		ch->damcap[x]	=	0;
	for (x = 0; x < 3; x++)
		ch->paradox[x]	=	0;
	for (x = 0; x < 4; x++)
		ch->sphere_affected_by[x]	=	0;
	ch->questgiver	=	NULL;
	ch->blood_count	=	0;
	ch->questmob	=	0;
	ch->questobj	=	0;
	ch->countdown	=	0;
	ch->nextquest	=	0;
	ch->rp_status	=	0;
	ch->delay_timer	=	0;
	ch->plane	=	0;
	ch->mob_con	=	0;
	ch->mob_fight	=	0;
	ch->affected_by	=	0;
	ch->extra	=	0;
	ch->act	=	0;
	ch->added	=	0;
	ch->sphere_spaffect	=	0;
	ch->special	=	0;
	ch->dead_time	=	0;
	ch->deaf	=	0;
	ch->wimpy	=	0;
	ch->armor	=	0;
	ch->id	=	0;
	ch->damroll	=	0;
	ch->hitroll	=	0;
	ch->alignment	=	0;
	ch->saving_throw	=	0;
	ch->carry_number	=	0;
	ch->carry_weight	=	0;
	ch->primal_hold	=	0;
	ch->practice	=	0;
	ch->position	=	1;
	ch->exp	=	0;
	ch->gold	=	0;
	ch->max_move	=	0;
	ch->move	=	0;
	ch->max_mana	=	0;
	ch->mana	=	0;
	ch->max_hit	=	0;
	ch->hit	=	0;
	ch->mdeath	=	0;
	ch->mkill	=	0;
	ch->pdeath	=	0;
	ch->arete	=	0;
	ch->pkill	=	0;
	ch->wait	=	0;
	ch->timer	=	0;
	ch->played	=	0;
	ch->trust	=	0;
	ch->invis_level	=	0;
	ch->level	=	0;
	ch->save_time	=	0;
	ch->home	=	0;
	ch->mounted	=	0;
	ch->beast	=	0;
	ch->specpower	=	0;
	ch->spectype	=	0;
	ch->vampgen_a	=	0;
	ch->RPts	=	0;
	ch->form	=	0;
	ch->vamppass_a	=	0;
	ch->itemaffect	=	0;
	ch->vampaff_a	=	0;
	ch->polyaff	=	0;
	ch->immune	=	0;
	ch->bclass	=	0;
	ch->creature=	0;
	ch->race	=	0;
	ch->sex	=	0;
	ch->sight	=	0;
	ch->mprog_delay	=	0;
	ch->pk_sect	=	0;
	ch->attack_timer	=	0;
	ch->pk_timer	=	0;
	ch->silent_time	=	0;
	ch->lines	=	0;
	ch->sect	=	0;
	ch->clan	=	0;
	ch->pet_master	=	NULL;
	ch->pet	=	NULL;
	ch->memory	=	NULL;
	ch->pcdata	=	NULL;
	ch->was_in_room	=	NULL;
	ch->in_room	=	NULL;
	ch->carrying	=	NULL;
	ch->sphere_affected	=	NULL;
	ch->affected	=	NULL;
	ch->desc	=	NULL;
	ch->pIndexData	=	NULL;
	ch->spec_fun	=	NULL;
	ch->on	=	NULL;
	ch->last_attacked	=	NULL;
	ch->pnote	=	NULL;
	ch->killed_by	=	NULL;
	ch->wizard	=	NULL;
	ch->mount	=	NULL;
	ch->reply	=	NULL;
	ch->mprog_target	=	NULL;
	ch->fighting	=	NULL;
	ch->mob_hunting	=	NULL;
	ch->leader	=	NULL;
	ch->master	=	NULL;
	ch->next_in_room	=	NULL;
	ch->next	=	NULL;
	ch->desc	=	NULL;
	ch->carrying	=	NULL;
	ch->wizard	=	NULL;
	ch->in_room	=	NULL;

}

/*
 * Declare new Strings for pcdata
 */
void init_pcdata(PC_DATA *pcdata)
{ 
	int x;

	pcdata->marriage	=	g_string_new("");

	for (x = 0; x < MAX_IGNORE; x++)
		pcdata->ignore[x]	=	g_string_new("");

	for (x = 0; x < MAX_ALIAS; x++)
		pcdata->alias_sub[x]	=	g_string_new("");

	for (x = 0; x < MAX_ALIAS; x++)
		pcdata->alias[x]	=	g_string_new("");

	pcdata->roompose	=	g_string_new("");
	pcdata->anon_desc	=	g_string_new("");
	pcdata->demeanor	=	g_string_new("");
	pcdata->nature	=	g_string_new("");
	pcdata->email	=	g_string_new("");
	pcdata->cparents	=	g_string_new("");
	pcdata->parents	=	g_string_new("");
	pcdata->conception	=	g_string_new("");
	pcdata->title	=	g_string_new("");
	pcdata->bamfin	=	g_string_new("");
	pcdata->pwd		=	g_string_new("");
	pcdata->bamfout	=	g_string_new(""); 
}


/*
 * Init new Strings for Chardata
 */
void init_chardata(CHAR_DATA *ch){ 

	ch->murmur_command	=	g_string_new("");
	ch->murmur_name	=	g_string_new("");
	ch->prefix	=	g_string_new("");
	ch->cprompt	=	g_string_new("");
	ch->prompt	=	g_string_new("");
	ch->powertype	=	g_string_new("");
	ch->poweraction	=	g_string_new("");
	ch->lasthost	=	g_string_new("");
	ch->lasttime	=	g_string_new("");
	ch->createtime	=	g_string_new("");
	ch->morph	=	g_string_new("");
	ch->lord	=	g_string_new("");
	ch->description	=	g_string_new("");
	ch->long_descr	=	g_string_new("");
	ch->short_descr	=	g_string_new("");
	ch->hunting	=	g_string_new("");
	ch->name	=	g_string_new(""); 
	ch->pload	= 	g_string_new(""); 
}

void free_char (CHAR_DATA *ch)
{
	OBJ_DATA *obj;
	OBJ_DATA *obj_next;
	AFFECT_DATA *paf;
	SPHERE_DATA *sp_paf;
	SPHERE_DATA *sp_paf_next;
	AFFECT_DATA *paf_next;

	if (!IS_VALID(ch))
		return;

	if (IS_NPC(ch))
	{
		mudsetting->mobiles_created--;
	}

	for (obj = ch->carrying; obj != NULL; obj = obj_next)
	{
		obj_next = obj->next_content;
		extract_obj(obj);
	}

	for (paf = ch->affected; paf != NULL; paf = paf_next)
	{
		paf_next = paf->next;
		affect_remove(ch,paf);
	}

	for ( sp_paf = ch->sphere_affected; sp_paf != NULL; sp_paf = sp_paf_next )
	{
		sp_paf_next = sp_paf->next;
		sphere_remove( ch, sp_paf );
	}

	if (ch->pcdata != NULL)
		free_pcdata(ch->pcdata);


	ch->next 	= char_free;
	char_free  	= ch;
	mudsetting->Mobiles_Recycle_Heap++;

	INVALIDATE(ch);
	return;
}

PC_DATA *pcdata_free;

PC_DATA *new_pcdata(void)
{

    PC_DATA *pcdata;

    if (pcdata_free == NULL){
		pcdata = g_chunk_new (PC_DATA, pcdata_mem_chunk);
		init_pcdata(pcdata);
    }
	else
    {
		pcdata = pcdata_free;
		pcdata_free = pcdata_free->next;
    }
    reset_pcdata(pcdata);

    VALIDATE(pcdata);
    return pcdata;
}
	
/*
 * Init recycled pcdata back to 0
 */
void reset_pcdata(PC_DATA *pcdata)
{
	int x = 0;
	for (x = 0; x < MAX_BOARD; x++)
		pcdata->last_note[x] = 0;
	for (x = 0; x < 10; x++)
		pcdata->hard_skills[x]	=	0;
	for (x = 0; x < 2; x++)
		pcdata->diab[x]	=	0;
	for (x = 0; x < MAX_DISC; x++)
		pcdata->disc[x]	=	0;
	for (x = 0; x < 6; x++)
		pcdata->absorb[x]	=	0;
	for (x = 0; x < 3; x++)
		pcdata->sgift[x]	=	0;
	for (x = 0; x < 20; x++)
		pcdata->tribes[x]	=	0;
	for (x = 0; x < 5; x++)
		pcdata->auspice[x]	=	0;
	for (x = 0; x < 3; x++)
		pcdata->breed[x]	=	0;
	for (x = 0; x < 3; x++)
		pcdata->Trenown[x]	=	0;
	for (x = 0; x < 3; x++)
		pcdata->renown[x]	=	0;
	for (x = 0; x < 5; x++)
		pcdata->spent[x]	=	0;
	for (x = 0; x < 2; x++)
		pcdata->trait_flaw[x]	=	0;
	for (x = 0; x < 2; x++)
		pcdata->trait_merit[x]	=	0;
	for (x = 0; x < 4; x++)
		pcdata->stat_duration[x]		=	0;
	for (x = 0; x < 4; x++)
		pcdata->stat_amount[x]		=	0;
	for (x = 0; x < 4; x++)
		pcdata->stat_ability[x]		=	0;
	for (x = 0; x < MAX_SKILL; x++)
		pcdata->learned[x]			=	0;
	for (x = 0; x < 3; x++)
		pcdata->condition[x]		=	0;
	for (x = 0; x < 10; x++)
		pcdata->genes[x]	=	0;
	for (x = 0; x < 11; x++)
		pcdata->disc_a[x]	=	0;
	for (x = 0; x < 3; x++)
		pcdata->stage[x]	=	0;
	for (x = 0; x < 2; x++)
		pcdata->language[x]	=	0;
	for (x = 0; x < MAX_DISC; x++)
		pcdata->Ninherited[x]	=	0;
	for (x = 0; x < MAX_DISCIPLINE; x++)
		pcdata->inherited[x]	=	0;
	for (x = 0; x < MAX_DISCIPLINE; x++)
		pcdata->discipline[x]	=	0;
	for (x = 0; x < 12; x++)
		pcdata->stats[x]	=	0;
	for (x = 0; x < 20; x++)
		pcdata->powers[x]	=	0;
	pcdata->ghost_ac	=	0;
	pcdata->ghost_damroll	=	0;
	pcdata->ghost_hitroll	=	0;
	pcdata->ghost_affects	=	0;
	pcdata->exhaustion	=	0;
	pcdata->ghost_move	=	0;
	pcdata->obj_vnum	=	0;
	pcdata->ghost_mana	=	0;
	pcdata->ghost_hit	=	0;
	pcdata->lag_time	=	0;
	pcdata->bodymods	=	0;
	pcdata->obeah	=	0;
	pcdata->wiznet	=	0;
	pcdata->conding	=	0;
	pcdata->comm	=	0;
	pcdata->willpower	=	0;
	pcdata->frenzy_action	=	0;
	pcdata->last_rite	=	0;
	pcdata->wwf_shape	=	0;
	pcdata->gnosis	=	0;
	pcdata->rage_points	=	0;
	pcdata->vote	=	0;
	pcdata->security	=	0;
	pcdata->followers	=	0;
	pcdata->fake_ac	=	0;
	pcdata->fake_move	=	0;
	pcdata->fake_mana	=	0;
	pcdata->fake_hp	=	0;
	pcdata->fake_dam	=	0;
	pcdata->fake_hit	=	0;
	pcdata->fake_stance	=	0;
	pcdata->fake_skill	=	0;
	pcdata->demonic_a	=	0;
	pcdata->rank	=	0;
	pcdata->wolf	=	0;
	pcdata->mod_con	=	0;
	pcdata->mod_con	=	0;
	pcdata->mod_dex	=	0;
	pcdata->mod_wis	=	0;
	pcdata->mod_int	=	0;
	pcdata->mod_str	=	0;
	pcdata->perm_con	=	0;
	pcdata->perm_dex	=	0;
	pcdata->perm_wis	=	0;
	pcdata->perm_int	=	0;
	pcdata->perm_str	=	0;
	pcdata->quest	=	0;
	pcdata->in_progress	=	NULL;
	pcdata->board	=	NULL;
	pcdata->known	=	NULL;
	pcdata->partner	= NULL;
	pcdata->chobj	=	NULL;
	pcdata->propose	=	NULL;
	pcdata->familiar	=	NULL;
	pcdata->next	=	NULL;
	pcdata->charpoints = 0;

	pcdata->marriage	=	g_string_assign(pcdata->marriage,"");

	for (x = 0; x < MAX_IGNORE; x++)
		pcdata->ignore[x]	=	g_string_assign(pcdata->ignore[x],"");

	for (x = 0; x < MAX_ALIAS; x++)
		pcdata->alias_sub[x]	=	g_string_assign(pcdata->alias_sub[x],"");

	for (x = 0; x < MAX_ALIAS; x++)
		pcdata->alias[x]	=	g_string_assign(pcdata->alias[x],"");

	pcdata->roompose	=	g_string_assign(pcdata->roompose,"");
	pcdata->anon_desc	=	g_string_assign(pcdata->anon_desc,"");
	pcdata->demeanor	=	g_string_assign(pcdata->demeanor,"");
	pcdata->nature	=	g_string_assign(pcdata->nature,"");
	pcdata->email	=	g_string_assign(pcdata->email,"");
	pcdata->cparents	=	g_string_assign(pcdata->cparents,"");
	pcdata->parents	=	g_string_assign(pcdata->parents,"");
	pcdata->conception	=	g_string_assign(pcdata->conception,"");
	pcdata->title	=	g_string_assign(pcdata->title,"");
	pcdata->bamfin	=	g_string_assign(pcdata->bamfin,"");
	pcdata->pwd		=	g_string_assign(pcdata->pwd,"");
	pcdata->bamfout	=	g_string_assign(pcdata->bamfout,"");
}

void free_pcdata(PC_DATA *pcdata)
{
    KNOWN_DATA *names;

    if (!IS_VALID(pcdata))
	return;

    /*free_buf(pcdata->buffer); */
    
    for (names = pcdata->known; names; names = names->next)
    {
		free_known(names);
    }

    pcdata->next = pcdata_free;
    pcdata_free = pcdata;
	
	INVALIDATE(pcdata);
    
    return;
}
void cr_imms( CHAR_DATA *ch )
{
    if ( IS_IMMUNE(ch, IMM_SLASH)     ) 
		REMOVE_BIT(ch->immune, IMM_SLASH);
	if ( IS_IMMUNE(ch, IMM_STAB)      ) 
		REMOVE_BIT(ch->immune, IMM_STAB);
	if ( IS_IMMUNE(ch, IMM_SMASH)     ) 
		REMOVE_BIT(ch->immune, IMM_SMASH);
	if ( IS_IMMUNE(ch, IMM_ANIMAL)    ) 
		REMOVE_BIT(ch->immune, IMM_ANIMAL);
	if ( IS_IMMUNE(ch, IMM_MISC)      ) 
		REMOVE_BIT(ch->immune, IMM_MISC);
	if ( IS_IMMUNE(ch, IMM_CHARM)     ) 
		REMOVE_BIT(ch->immune, IMM_CHARM);
	if ( IS_IMMUNE(ch, IMM_HEAT)      ) 
		REMOVE_BIT(ch->immune, IMM_HEAT);
	if ( IS_IMMUNE(ch, IMM_COLD)      ) 
		REMOVE_BIT(ch->immune, IMM_COLD);
	if ( IS_IMMUNE(ch, IMM_LIGHTNING) ) 
		REMOVE_BIT(ch->immune, IMM_LIGHTNING);
	if ( IS_IMMUNE(ch, IMM_ACID)      ) 
		REMOVE_BIT(ch->immune, IMM_ACID);
	if ( IS_IMMUNE(ch, IMM_SLEEP)     ) 
		REMOVE_BIT(ch->immune, IMM_SLEEP);
	if ( IS_IMMUNE(ch, IMM_DRAIN)     ) 
		REMOVE_BIT(ch->immune, IMM_DRAIN);
	if ( IS_IMMUNE(ch, IMM_VOODOO)    ) 
		REMOVE_BIT(ch->immune, IMM_VOODOO);
	if ( IS_IMMUNE(ch, IMM_HURL)      ) 
		REMOVE_BIT(ch->immune, IMM_HURL);
	if ( IS_IMMUNE(ch, IMM_BACKSTAB)  ) 
		REMOVE_BIT(ch->immune, IMM_BACKSTAB);
	if ( IS_IMMUNE(ch, IMM_KICK)      ) 
		REMOVE_BIT(ch->immune, IMM_KICK);
	if ( IS_IMMUNE(ch, IMM_DISARM)    ) 
		REMOVE_BIT(ch->immune, IMM_DISARM);
	if ( IS_IMMUNE(ch, IMM_STEAL)     ) 
		REMOVE_BIT(ch->immune, IMM_STEAL);

	return;
}
int count_imms( CHAR_DATA *ch )
{
	int count = 0;
	
	if ( IS_IMMUNE(ch, IMM_SLASH)     ) count += 1;
	if ( IS_IMMUNE(ch, IMM_STAB)      ) count += 1;
	if ( IS_IMMUNE(ch, IMM_SMASH)     ) count += 1;
	if ( IS_IMMUNE(ch, IMM_ANIMAL)    ) count += 1;
	if ( IS_IMMUNE(ch, IMM_MISC)      ) count += 1;
	if ( IS_IMMUNE(ch, IMM_CHARM)     ) count += 1;
	if ( IS_IMMUNE(ch, IMM_HEAT)      ) count += 1;
	if ( IS_IMMUNE(ch, IMM_COLD)      ) count += 1;
	if ( IS_IMMUNE(ch, IMM_LIGHTNING) ) count += 1;
	if ( IS_IMMUNE(ch, IMM_ACID)      ) count += 1;
	if ( IS_IMMUNE(ch, IMM_SLEEP)     ) count += 1;
	if ( IS_IMMUNE(ch, IMM_DRAIN)     ) count += 1;
	if ( IS_IMMUNE(ch, IMM_VOODOO)    ) count += 1;
	if ( IS_IMMUNE(ch, IMM_HURL)      ) count += 1;
	if ( IS_IMMUNE(ch, IMM_BACKSTAB)  ) count += 1;
	if ( IS_IMMUNE(ch, IMM_KICK)      ) count += 1;
	if ( IS_IMMUNE(ch, IMM_DISARM)    ) count += 1;
	if ( IS_IMMUNE(ch, IMM_STEAL)     ) count += 1;
	return count;
}

void set_name(CHAR_DATA *ch, char *name){
    //Bounds checking before and after
    if (sizeof(name) > sizeof(ch->name)) {
    }
    strcpy(ch->name->str, name);
    return;
}

int char_hitroll( CHAR_DATA *ch )
{
	int hr = GET_HITROLL(ch);
	if (!IS_NPC(ch))
	{
		if (IS_ADDED(ch,ADDED_HARDCORE))
			hr += 300;

		if (IS_SWWF(ch))
		{
			switch ( ch->pcdata->wwf_shape )
			{
				case SHAPE_GLABRO:
					hr += 100;
					break;
				case SHAPE_CRINOS:
					hr += 300;
					break;
				case SHAPE_HISPO:
					hr += 200;
					break;
				case SHAPE_LUPUS:
					hr += 150;
					break;
			}
			if (ch->pcdata->wwf_shape != SHAPE_HOMID)
			{
				hr += ch->pcdata->rage_points / 3;
			}
		}
		if (IS_CLASS(ch,CLASS_VAMPIRE) && ch->pcdata->stats[UNI_RAGE] > 0)
			hr += ch->pcdata->stats[UNI_RAGE];
		else if (IS_SET(ch->special,SPC_WOLFMAN) && ch->pcdata->stats[UNI_RAGE] > 0)
			hr += ch->pcdata->stats[UNI_RAGE];
		else if (IS_CLASS(ch, CLASS_HIGHLANDER) && IS_ITEMAFF(ch, ITEMA_HIGHLANDER))
		{
			int wpn = ch->pcdata->powers[HPOWER_WPNSKILL];
			if (wpn == 1 || wpn == 3)
			{
				if (ch->wpn[wpn] >= 500)
					hr += 500;
				else
					hr += ch->wpn[wpn];
			}
		}
	}
	if (IS_SET(ch->added, ADDED_INSANE))
		hr -= hr * (int).2;
        
        //new sphinx 4 hitroll modifier
        if ( !IS_NPC(ch) && IS_CLASS(ch, CLASS_WEREWOLF) 
        && IS_SET(ch->special, SPC_WOLFMAN) && ch->pcdata->powers[WPOWER_SPHINX] > 3)
                hr += number_range(40,60) * ch->pcdata->powers[WPOWER_SPHINX];
	
	return hr;
}

int char_damroll( CHAR_DATA *ch )
{
	int dr = GET_DAMROLL(ch);
	if (!IS_NPC(ch))
	{
		if (IS_SWWF(ch))
		{
			switch ( ch->pcdata->wwf_shape )
			{
				case SHAPE_GLABRO:
					dr += 100;
					break;
				case SHAPE_CRINOS:
					dr += 300;
					break;
				case SHAPE_HISPO:
					dr += 200;
					break;
				case SHAPE_LUPUS:
					dr += 150;
					break;
			}
            if (ch->pcdata->wwf_shape != SHAPE_HOMID)
            {
                dr += ch->pcdata->rage_points / 3;
            }
		}
		if (IS_CLASS(ch,CLASS_VAMPIRE) && ch->pcdata->stats[UNI_RAGE] > 0)
			dr += ch->pcdata->stats[UNI_RAGE];
		else if (IS_SET(ch->special,SPC_WOLFMAN) && ch->pcdata->stats[UNI_RAGE] > 0)
			dr += ch->pcdata->stats[UNI_RAGE];
		else if (IS_CLASS(ch, CLASS_HIGHLANDER) && IS_ITEMAFF(ch, ITEMA_HIGHLANDER))
		{
			int wpn = ch->pcdata->powers[HPOWER_WPNSKILL];
			{
				if (ch->wpn[wpn] >= 500)
					dr += 500;
				else
					dr += ch->wpn[wpn];
			}
		}
	}
	if (IS_ADDED(ch,ADDED_HARDCORE))
		dr *= 2;

	if (IS_SET(ch->added, ADDED_INSANE))
		dr -= dr * (int).2;
	
	return dr;
}

int char_ac( CHAR_DATA *ch )
{
	int a_c = GET_AC(ch);
	if (!IS_NPC(ch))
	{
		if (IS_ADDED(ch,ADDED_HARDCORE))
			a_c -= 200;

		if (IS_SWWF(ch))
		{
			switch ( ch->pcdata->wwf_shape )
			{
				case SHAPE_GLABRO:
					a_c -= 100;
					break;
				case SHAPE_CRINOS:
					a_c -= 700;
					break;
				case SHAPE_HISPO:
					a_c -= 300;
					break;
				case SHAPE_LUPUS:
					a_c -= 250;
					break;
			}
			if (ch->pcdata->wwf_shape != SHAPE_HOMID)
			{
				a_c -= ch->pcdata->rage_points;
			}
			if (get_tribe(ch,TRIBE_SILENT_STRIDERS) > 1) 
			{
				a_c -= 100;
			}
		}
		if (IS_CLASS(ch, CLASS_HIGHLANDER) && IS_ITEMAFF(ch, ITEMA_HIGHLANDER))
		{
			int wpn = ch->pcdata->powers[HPOWER_WPNSKILL];
			if (wpn == 1 || wpn == 3)
				a_c -= ch->wpn[wpn];
		}
	}
	if (IS_SET(ch->act, PLR_MARBLEFLESH))
		a_c -= 100;
        // spheres give random ac per shield, each time called - rc
	if (IS_SET(ch->sphere_spaffect, AFSPHERE_SPIRIT_SHIELD))
		a_c -= number_range(180,250);
	if (IS_SET(ch->sphere_spaffect, AFSPHERE_MIND_SHIELD))
		a_c -= number_range(180,250);
	if (IS_SET(ch->sphere_spaffect, AFSPHERE_ENTROPY_SHIELD))
		a_c -= number_range(180,250);
	if (IS_SET(ch->sphere_spaffect, AFSPHERE_LIFE_SHIELD))
		a_c -= number_range(180,250);
	if (IS_SET(ch->sphere_spaffect, AFSPHERE_FORCES_SHIELD))
		a_c -= number_range(180,250);
	if (IS_SET(ch->sphere_spaffect, AFSPHERE_PRIME_SHIELD))
		a_c -= number_range(180,250);
	return a_c;
}

sh_int fix_sect( CHAR_DATA *ch, char * sect)
{				  
	sh_int loop_count;				  

	for(loop_count = 0;loop_count != MAX_SECTS;loop_count++)
	{
		if (!str_prefix(sect,sect_table[loop_count].pretty_name))
			return loop_count;
	}
	return 0;
}

sh_int fix_clan( CHAR_DATA *ch, char * sect)
{				  
	sh_int loop_count;				  

	for(loop_count = 0;loop_count != MAX_ICLAN;loop_count++)
	{
		if (!str_prefix(sect,iclan_table[loop_count].pretty_name))
			return loop_count;
	}
	return 0;
}

/*
 * Reset a player's data back to normal
 */
CHAR_DATA  *reset_player( DESCRIPTOR_DATA *d, const char *name )
{
	char *strtime;
	CHAR_DATA *ch;
	
	ch = new_char();

	ch->pcdata 				= new_pcdata();
	d->character				= ch;
	ch->desc				= d;
	ch->name				= g_string_assign(ch->name, name );
	ch->act					= PLR_BLANK | PLR_COMBINE | PLR_PROMPT;
	ch->creature                           	= -1;
	ch->id 					= get_pc_id();
	ch->pcdata->pwd 			= g_string_assign(ch->pcdata->pwd,"");
	ch->pcdata->bamfin 			= g_string_assign(ch->pcdata->bamfin,"");
	ch->pcdata->bamfout			= g_string_assign(ch->pcdata->bamfout,"");
	ch->pcdata->title			= g_string_assign(ch->pcdata->title,"");
	ch->pcdata->conception			= g_string_assign(ch->pcdata->conception,"");
	ch->pcdata->parents			= g_string_assign(ch->pcdata->parents,"");
	ch->pcdata->cparents			= g_string_assign(ch->pcdata->cparents,"");
	ch->pcdata->marriage			= g_string_assign(ch->pcdata->marriage,"");
	ch->pcdata->email			= g_string_assign(ch->pcdata->email,"");
	ch->pcdata->board			= &boards[DEFAULT_BOARD];
	ch->pcdata->nature			= g_string_assign(ch->pcdata->nature,"");
	ch->pcdata->roompose			= g_string_assign(ch->pcdata->roompose,"");
	ch->pcdata->demeanor			= g_string_assign(ch->pcdata->demeanor,"");
	ch->lord				= g_string_assign(ch->lord,"");
	ch->lines		                = 20;
    ch->pk_sect					= 0;
	ch->morph				= g_string_assign(ch->morph,"");
	ch->pload				= g_string_assign(ch->pload,"");
	ch->prompt				= g_string_assign(ch->prompt,"");
	ch->cprompt				= g_string_assign(ch->cprompt,"");
	ch->pcdata->confirm_delete          	= FALSE;
	strtime 				= ctime( &current_time );
	strtime[strlen(strtime)-1] = '\0';
	ch->createtime				= g_string_assign(ch->createtime, strtime );
	ch->lasttime				= g_string_assign(ch->lasttime, "" );
	ch->lasthost				= g_string_assign(ch->lasthost, "" );
	ch->poweraction				= g_string_assign(ch->poweraction, "" );
	ch->powertype				= g_string_assign(ch->powertype, "" );
	ch->murmur_name				= g_string_assign(ch->murmur_name, "" );
	ch->murmur_command			= g_string_assign(ch->murmur_command, "" );
	ch->prefix				= g_string_assign(ch->prefix, "" );
	ch->hunting				= g_string_assign(ch->hunting	, "" );
	ch->arete                       	= 1;
	ch->home				= 3001;
	ch->damcap[0]	          		= 1000;
	ch->plane				= 1;
	ch->vamppass_a				= -1;
	ch->form				= 32767;
	ch->beast				= 15;
	ch->creature				= -1;
	ch->pcdata->perm_str			= 13;
	ch->pcdata->perm_int			= 13; 
	ch->pcdata->perm_wis			= 13;
	ch->pcdata->perm_dex			= 13;
	ch->pcdata->perm_con			= 13;
	ch->pcdata->condition[COND_THIRST]	= 48;
	ch->pcdata->condition[COND_FULL]	= 48;
	return ch;
}

void fread_char( CHAR_DATA *ch, FILE *fp )
{
	char buf[MAX_STRING_LENGTH];
	char log[MAX_STRING_LENGTH];
	char *word;
	bool fMatch;
	int  dummy,i;
	int count = 0;
	int alias_count = 0;
	int sn,cimm;
	
	for ( ; ; )
	{
		Player_Load = TRUE;
		Player_Error = FALSE;
		word   = feof( fp ) ? (char *)"End" : fread_word( fp );
		fMatch = FALSE;
		
		switch ( UPPER(word[0]) )
		{
			case '*':
				fMatch = TRUE;
				fread_to_eol( fp );
				break;
				
			case 'A':
				KEY( "Act",		ch->act,		fread_number( fp ) );
				KEY( "Added",		ch->added,		fread_number( fp ) );
				
		/*Horrible hack to get inivs set, Please tell me there is a better way - Spiral */
				if (IS_SET(ch->act,PLR_WIZINVIS))
					ch->invis_level = ch->level;
				
				KEY( "AffectedBy",	ch->affected_by,	fread_number( fp ) );
				KEY( "Alignment",	ch->alignment,		fread_number( fp ) );
				KEY( "Armor",	ch->armor,		fread_number( fp ) );
				KEY( "Arete",	ch->arete,		fread_number( fp ) );
				KEY( "Abs_Mvnum",	ch->pcdata->absorb[ABS_MOB_VNUM],		fread_number( fp ) );
				KEY( "Abs_MHp",	ch->pcdata->absorb[ABS_MOB_HP],		fread_number( fp ) );
				KEY( "Abs_MMaxHp",	ch->pcdata->absorb[ABS_MOB_MAX_HP],		fread_number( fp ) );
				h_KEY( "ANONDes",	ch->pcdata->anon_desc,		nonfread_string(ch->pcdata->anon_desc, fp ) );
                
				if ( !str_cmp( word, "Auspice" ) )
	   		        {
					ch->pcdata->auspice[0] = fread_number( fp );
					ch->pcdata->auspice[1] = fread_number( fp );
					ch->pcdata->auspice[2] = fread_number( fp );
					ch->pcdata->auspice[3] = fread_number( fp );
					ch->pcdata->auspice[4] = fread_number( fp );
					fMatch = TRUE;
					break;
	    			}
	
				if ( !str_cmp( word, "Alias" ) )
				{
					if (alias_count >= MAX_ALIAS)
					{
						fread_to_eol(fp);
						fMatch = TRUE;
						break;
					}
					ch->pcdata->alias[alias_count] 	= g_string_assign(ch->pcdata->alias[alias_count],fread_word(fp));
					ch->pcdata->alias_sub[alias_count]	= nonfread_string(ch->pcdata->alias_sub[alias_count],fp);
					alias_count++;
					fMatch = TRUE;
					break;
				}
				
				
				if ( !str_cmp( word, "Affect" ) || !str_cmp( word, "AffectData" ) )
				{
					AFFECT_DATA *paf;
					
					paf = new_affect();	
					if ( !str_cmp( word, "Affect" ) )
					{
		    /* Obsolete 2.0 form. */
						paf->type	= fread_number( fp );
					}
					else
					{
						int sn;
						
						sn = skill_lookup( fread_word( fp ) );
						if ( sn < 0 )
							bug( "Fread_char: unknown skill.", 0 );
						else
							paf->type = sn;
					}
					
					paf->duration	= fread_number( fp );
					paf->modifier	= fread_number( fp );
					paf->location	= fread_number( fp );
					paf->bitvector	= fread_number( fp );
					paf->next	= ch->affected;
					ch->affected	= paf;
					fMatch = TRUE;
					break;
				}
				
				if ( !str_cmp( word, "AttrMod"  ) )
				{
					ch->pcdata->mod_str  = fread_number( fp );
					ch->pcdata->mod_int  = fread_number( fp );
					ch->pcdata->mod_wis  = fread_number( fp );
					ch->pcdata->mod_dex  = fread_number( fp );
					ch->pcdata->mod_con  = fread_number( fp );
					fMatch = TRUE;
					break;
				}
				
				if ( !str_cmp( word, "AttrPerm" ) )
				{
					ch->pcdata->perm_str = fread_number( fp );
					ch->pcdata->perm_int = fread_number( fp );
					ch->pcdata->perm_wis = fread_number( fp );
					ch->pcdata->perm_dex = fread_number( fp );
					ch->pcdata->perm_con = fread_number( fp );
					fMatch = TRUE;
					break;
				}
				break;
				
			case 'B':
				h_KEY( "Bamfin",	ch->pcdata->bamfin,	nonfread_string(ch->pcdata->bamfin, fp ) );
				h_KEY( "Bamfout",	ch->pcdata->bamfout,	nonfread_string(ch->pcdata->bamfout, fp ) );
				KEY( "Beast",       ch->beast,		fread_number( fp ) );

				if ( !str_cmp( word, "Breed" ) )
	    			{
					ch->pcdata->breed[0] = fread_number( fp );
					ch->pcdata->breed[1] = fread_number( fp );
					ch->pcdata->breed[2] = fread_number( fp );
					fMatch = TRUE;
					break;
	    			}
	    
	    			/* 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->str, boardname);
						log_string2 (buf);
						fread_number (fp); /* read last_note and skip info */
		    			}
		    			else /* Save it */
					ch->pcdata->last_note[i] = fread_number (fp);
					} /* for */

                			fMatch = TRUE;
	      			} /* Boards */
				break;
				
			case 'C':
				if (!str_cmp(word,"Clan"))
				{	
					ch->clan = fix_clan(ch,fread_string(fp));
					fMatch = TRUE;
					break;
				}
				
				if (!str_cmp(word,"ChrPnts"))
				{	
					if (ch->pcdata->charpoints == 0)
						ch->pcdata->charpoints = fread_number(fp);
					else 
						fread_number(fp);
					fMatch = TRUE;
					break;
				}
				
				KEY( "Class",	ch->creature,       	fread_number( fp ) );
				KEY( "Cing",	ch->pcdata->conding, fread_string( fp ));
				KEY( "Comm",	ch->pcdata->comm,  	fread_number( fp ) );
				
				if ( !str_cmp( word, "Combat" ) )
				{
					ch->cmbt[0]	= fread_number( fp );
					ch->cmbt[1]	= fread_number( fp );
					ch->cmbt[2]	= fread_number( fp );
					ch->cmbt[3]	= fread_number( fp );
					ch->cmbt[4]	= fread_number( fp );
					ch->cmbt[5]	= fread_number( fp );
					ch->cmbt[6]	= fread_number( fp );
					ch->cmbt[7]	= fread_number( fp );
					fMatch = TRUE;
					break;
				}
				
				h_KEY( "Conception",	ch->pcdata->conception,	nonfread_string(ch->pcdata->conception, fp ) );
				
				if ( !str_cmp( word, "Condition" ) )
				{
					ch->pcdata->condition[0] = fread_number( fp );
					ch->pcdata->condition[1] = fread_number( fp );
					ch->pcdata->condition[2] = fread_number( fp );
					fMatch = TRUE;
					break;
				}
				h_KEY( "Cparents",	ch->pcdata->cparents,	nonfread_string(ch->pcdata->cparents, fp ) );
				h_KEY( "Cprompt",	ch->cprompt,		nonfread_string(ch->cprompt, fp ) );
				h_KEY( "Createtime",	ch->createtime,		nonfread_string(ch->createtime, fp ) );
				break;
				
			case 'D':
				KEY( "Damroll",	ch->damroll,		fread_number( fp ) );
				KEY( "Deaf",	ch->deaf,		fread_number( fp ) );
				KEY( "Demonic",     dummy,		fread_number( fp ) );
				h_KEY( "Demeanor",	ch->pcdata->demeanor,	nonfread_string(ch->pcdata->demeanor, fp ) );
				h_KEY( "Description",	ch->description,	nonfread_string(ch->description, fp ) );
				KEY( "Diab",	ch->pcdata->diab[DIAB_EVER],	fread_number( fp ) );
				
				
				if ( !str_cmp( word, "Disc" ) )
				{
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					fMatch = TRUE;
					break;
				}
				if ( !str_cmp( word, "Discipline" ) )
				{
					for ( dummy = 0 ; dummy < MAX_DISCIPLINE ; dummy++ )
					{
						ch->pcdata->discipline[dummy] = fread_number( fp );
					}
					if (IS_CLASS(ch,CLASS_VAMPIRE))
                    {
                    //Conversion TIME!!! :P
                    ch->pcdata->disc[DISC_ANIMALISM] = ch->pcdata->discipline[DIS_ANIMALISM];
                    ch->pcdata->disc[DISC_AUSPEX] = ch->pcdata->discipline[DIS_AUSPEX];
                    ch->pcdata->disc[DISC_CELERITY] = ch->pcdata->discipline[DIS_CELERITY];
                    ch->pcdata->disc[DISC_DEMENTATION] = ch->pcdata->discipline[DIS_DEMENTATION];
                    ch->pcdata->disc[DISC_DOMINATE] = ch->pcdata->discipline[DIS_DOMINATE];
                    ch->pcdata->disc[DISC_FORTITUDE] = ch->pcdata->discipline[DIS_FORTITUDE];
                    ch->pcdata->disc[DISC_OBFUSCATE] = ch->pcdata->discipline[DIS_OBFUSCATE];
                    ch->pcdata->disc[DISC_OBTENEBRATION] = ch->pcdata->discipline[DIS_OBTENEBRATION];
                    ch->pcdata->disc[DISC_POTENCE] = ch->pcdata->discipline[DIS_POTENCE];
                    ch->pcdata->disc[DISC_PRESENCE] = ch->pcdata->discipline[DIS_PRESENCE];
                    ch->pcdata->disc[DISC_PROTEAN] = ch->pcdata->discipline[DIS_PROTEAN];
                    ch->pcdata->disc[DISC_QUIETUS] = ch->pcdata->discipline[DIS_QUIETUS];
                    ch->pcdata->disc[DISC_SERPENTIS] = ch->pcdata->discipline[DIS_SERPENTIS];
                    ch->pcdata->disc[DISC_THAUMATURGY] = ch->pcdata->discipline[DIS_THAUMATURGY];
                    ch->pcdata->disc[DISC_VICISSITUDE] = ch->pcdata->discipline[DIS_VICISSITUDE];
                	}
                    fMatch = TRUE;
				}
				KEY( "Drowaff",	dummy,	fread_number( fp ) ); /* Drow */
				KEY( "Drowpwr",	dummy,	fread_number( fp ) ); /* Drow */
				KEY( "Drowmag",	dummy, 	fread_number( fp ) ); /* Drow */
				break;
				
			case 'E':
				h_KEY( "Email",	ch->pcdata->email,	nonfread_string(ch->pcdata->email, fp ) );
				if ( !str_cmp( word, "End" ) )
					return;
				KEY( "Exhaustion",	ch->pcdata->exhaustion,	fread_number( fp ) );
				KEY( "Exp",		ch->exp,		fread_number( fp ) );
				KEY( "Extra",	ch->extra,		fread_number( fp ) );
				break;
				
			case 'F':
				if ( !str_cmp( word, "FakeCon" ) )
				{
					ch->pcdata->fake_skill	= fread_number( fp );
					ch->pcdata->fake_stance	= fread_number( fp );
					ch->pcdata->fake_hit	= fread_number( fp );
					ch->pcdata->fake_dam	= fread_number( fp );
					ch->pcdata->fake_ac	= fread_number( fp );
					ch->pcdata->fake_hp	= fread_number( fp );
					ch->pcdata->fake_mana	= fread_number( fp );
					ch->pcdata->fake_move	= fread_number( fp );
					fMatch = TRUE;
					break;
				}
				KEY( "Form",        ch->form,		fread_number( fp ) );
				
                if (!str_cmp(word, "Follow"))
                {
                    fread_number(fp);
                    fMatch= TRUE;
                }
                
                //KEY( "Follow",      ch->pcdata->followers,		fread_number( fp ) );
                break;
				
			case 'G':
				if ( !str_cmp( word, "Genes" ) )
				{
					ch->pcdata->genes[0] = fread_number( fp );
					ch->pcdata->genes[1] = fread_number( fp );
					ch->pcdata->genes[2] = fread_number( fp );
					ch->pcdata->genes[3] = fread_number( fp );
					ch->pcdata->genes[4] = fread_number( fp );
					ch->pcdata->genes[5] = fread_number( fp );
					ch->pcdata->genes[6] = fread_number( fp );
					ch->pcdata->genes[7] = fread_number( fp );
					ch->pcdata->genes[8] = fread_number( fp );
					ch->pcdata->genes[9] = fread_number( fp );
					fMatch = TRUE;
					break;
				}
				KEY( "Gnosis",	ch->pcdata->gnosis,		fread_number( fp ) );
				KEY( "Gold",	ch->gold,		fread_number( fp ) );
				break;
				
			case 'H':
				KEY( "Hitroll",	ch->hitroll,		fread_number( fp ) );
				KEY( "Home",        ch->home,		fread_number( fp ) );
				if (!str_cmp(word, "HardSkillz")) {
                    for (i = 0; i < MAX_HARD_SKILLS; i++) {
                        ch->pcdata->hard_skills[i] = fread_number( fp );
                    }
                    fMatch = TRUE;
                    break;
                }
				if ( !str_cmp( 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;
				}
				break;
				
			case 'I':
				KEY( "Id",        ch->id,		fread_number( fp ) );
				if (!str_cmp( word, "Ignore"))
				{
					if (count >= MAX_IGNORE)
					{
						fread_to_eol(fp);
						fMatch = TRUE;
						break;
					}
					
					ch->pcdata->ignore[count]        =      nonfread_string(ch->pcdata->ignore[count],fp);
					count++;
					fMatch = TRUE;
					break;
				}
				
				if ( !str_cmp( word, "Immune" ) )
				{
					ch->immune = fread_number( fp );
					if ((cimm = count_imms(ch)) > 0)
					{
						ch->exp += cimm;
						ch->pcdata->charpoints = 20;
						if (IS_AVATAR(ch))
							ch->pcdata->charpoints = 20;
						
						cr_imms(ch);
					}
					fMatch = TRUE;
					break;
				}

				KEY( "iCla",	ch->clan,		fread_number( fp ) );
				KEY( "iSec",	ch->sect,  					fread_number( fp ) );
				KEY( "Itemaffect",    ch->itemaffect,	fread_number( fp ) );
				if ( !str_cmp( word, "Inherited" ) )
				{
					for ( dummy = 0 ; dummy < MAX_DISCIPLINE ; dummy++ )
					{
						ch->pcdata->inherited[dummy] = fread_number( fp );
					}
                    ch->pcdata->Ninherited[DISC_ANIMALISM] = ch->pcdata->inherited[DIS_ANIMALISM];
                    ch->pcdata->Ninherited[DISC_AUSPEX] = ch->pcdata->inherited[DIS_AUSPEX];
                    ch->pcdata->Ninherited[DISC_CELERITY] = ch->pcdata->inherited[DIS_CELERITY];
                    ch->pcdata->Ninherited[DISC_DEMENTATION] = ch->pcdata->inherited[DIS_DEMENTATION];
                    ch->pcdata->Ninherited[DISC_DOMINATE] = ch->pcdata->inherited[DIS_DOMINATE];
                    ch->pcdata->Ninherited[DISC_FORTITUDE] = ch->pcdata->inherited[DIS_FORTITUDE];
                    ch->pcdata->Ninherited[DISC_OBFUSCATE] = ch->pcdata->inherited[DIS_OBFUSCATE];
                    ch->pcdata->Ninherited[DISC_OBTENEBRATION] = ch->pcdata->inherited[DIS_OBTENEBRATION];
                    ch->pcdata->Ninherited[DISC_POTENCE] = ch->pcdata->inherited[DIS_POTENCE];
                    ch->pcdata->Ninherited[DISC_PRESENCE] = ch->pcdata->inherited[DIS_PRESENCE];
                    ch->pcdata->Ninherited[DISC_PROTEAN] = ch->pcdata->inherited[DIS_PROTEAN];
                    ch->pcdata->Ninherited[DISC_QUIETUS] = ch->pcdata->inherited[DIS_QUIETUS];
                    ch->pcdata->Ninherited[DISC_SERPENTIS] = ch->pcdata->inherited[DIS_SERPENTIS];
                    ch->pcdata->Ninherited[DISC_THAUMATURGY] = ch->pcdata->inherited[DIS_THAUMATURGY];
                    ch->pcdata->Ninherited[DISC_VICISSITUDE] = ch->pcdata->inherited[DIS_VICISSITUDE];
                    fMatch = TRUE;
				}
				break;
			
        		case 'K':
           			if ( !str_cmp(word, "Know"))
           			{
					int value;
					KNOWN_DATA *charname;
	
					value = fread_number( fp );
   					charname = new_known();
   					charname->value = value;
   					charname->next = ch->pcdata->known;
   					ch->pcdata->known = charname;

      			  	      	fMatch = TRUE;
        			      	break;
       	    			}
            			if ( !str_cmp(word, "Known"))
            			{
              			int i;
            			  int size;
            			  int number;
              
     			         size = fread_number(fp);
              			for ( i = 1; i < size+1; i++ )
             			   number = fread_number(fp);             
            
          			    			fread_word(fp); /* read final #0 */
     			         fMatch = TRUE;
       			       break;
        			    }
       			     break;
				
			case 'L':
				KEY( "Lag",	ch->pcdata->lag_time,		fread_number( fp ) );
                if ( !str_cmp( word, "Language" ) )
				{
					ch->pcdata->language[0] = fread_number( fp );
					ch->pcdata->language[1] = fread_number( fp );
					fMatch = TRUE;
					break;
				}
				
				h_KEY( "Lasthost",	ch->lasthost,		nonfread_string(ch->lasthost, fp ) );
				h_KEY( "Lasttime",	ch->lasttime,		nonfread_string(ch->lasttime, fp ) );
				KEY( "Level",	ch->level,		fread_number( fp ) );
				if ( !str_cmp( word, "Locationhp" ) )
				{
					ch->loc_hp[0]	= fread_number( fp );
					ch->loc_hp[1]	= fread_number( fp );
					ch->loc_hp[2]	= fread_number( fp );
					ch->loc_hp[3]	= fread_number( fp );
					ch->loc_hp[4]	= fread_number( fp );
					ch->loc_hp[5]	= fread_number( fp );
					ch->loc_hp[6]	= fread_number( fp );
					fMatch = TRUE;
					break;
				}
				h_KEY( "LongDescr",	ch->long_descr,		nonfread_string(ch->long_descr, fp ) );
				h_KEY( "Lord",	ch->lord,		nonfread_string(ch->lord, fp ) );
				KEY( "LRite",	ch->pcdata->last_rite,		fread_number(fp ) );
				break;
				
			case 'M':
				h_KEY( "Marriage",	ch->pcdata->marriage,	nonfread_string(ch->pcdata->marriage, fp ) );
				h_KEY( "Morph",	ch->morph,		nonfread_string(ch->morph, fp ) );
				h_KEY( "Murmurn",	ch->murmur_name,		nonfread_string(ch->murmur_name, fp ) );
				h_KEY( "Murmurc",	ch->murmur_command,		nonfread_string(ch->murmur_command, fp ) );
				break;
				
			case 'N':
				if ( !str_cmp( word, "Name" ) )
				{
		/*
		 * Name already set externally.
		 */
					fread_to_eol( fp );
					fMatch = TRUE;
					break;
				}
				h_KEY( "Nature",	ch->pcdata->nature,	nonfread_string(ch->pcdata->nature, fp ) );
				if (!str_cmp(word,"Note"))
				{
					fread_number(fp);
					fread_number(fp);
					fread_number(fp);
					fread_number(fp);
					fread_number(fp);
					fMatch = TRUE;
					break;
				}
				
                if ( !str_cmp( word, "NInherited" ) )
				{
					for ( dummy = 0 ; dummy < MAX_DISC ; dummy++ )
					{
						ch->pcdata->Ninherited[dummy] = fread_number( fp );
					}
					fMatch = TRUE;
				}
				
                if ( !str_cmp( word, "NDisc" ) )
				{
					for ( dummy = 0 ; dummy < MAX_DISC ; dummy++ )
					{
						ch->pcdata->disc[dummy] = fread_number( fp );
					}
					fMatch = TRUE;
				}
				break;
				
			case 'O':
				KEY( "Objvnum",     ch->pcdata->obj_vnum,	fread_number( fp ) );
				break;
				
			case 'P':
				if ( !str_cmp( word, "Paradox" ) )
				{
					ch->paradox[0]	= fread_number( fp );
					ch->paradox[1]	= fread_number( fp );
					ch->paradox[2]	= fread_number( fp );
					fMatch = TRUE;
					break;
				}
				
				h_KEY( "Parents",	ch->pcdata->parents,	nonfread_string(ch->pcdata->parents, fp ) );
				h_KEY( "Password",	ch->pcdata->pwd,	nonfread_string(ch->pcdata->pwd, fp ) );
				KEY( "Played",	ch->played,		fread_number( fp ) );
				KEY( "Phold",	ch->primal_hold,	fread_number( fp ) );
                KEY( "Polyaff",     ch->polyaff,		fread_number( fp ) );
				KEY( "Power_Point", dummy,	fread_number( fp ) ); /* drow */
				
				if ( !str_cmp( word, "Power" ) )
				{
					for ( sn = 0; sn < 20 ; sn++ )
						ch->pcdata->powers[sn] = fread_number( fp );
					
				        fMatch = TRUE;
					break;
				}
				KEY( "Plane",	ch->plane,		fread_number( fp ) );
				
				h_KEY( "Poweraction",	ch->poweraction,	nonfread_string(ch->poweraction, fp ) );
				h_KEY( "Powertype",	ch->powertype,		nonfread_string(ch->powertype, fp ) );
				KEY( "Position",	ch->position,		fread_number( fp ) );
				KEY( "Practice",	ch->practice,		fread_number( fp ) );
				if ( !str_cmp( word, "PkPdMkMd" ) )
				{
					ch->pkill	= fread_number( fp );
					ch->pdeath	= fread_number( fp );
					ch->mkill	= fread_number( fp );
					ch->mdeath	= fread_number( fp );
					fMatch = TRUE;
					break;
				}
				h_KEY( "Prompt",	ch->prompt,		nonfread_string(ch->prompt, fp ) );
				break;
				
			case 'Q':
				KEY( "Qtimer",       ch->nextquest,	fread_number( fp ) );
				KEY( "Quest",        ch->pcdata->quest,	fread_number( fp ) );
				break;
				
			case 'R':
				KEY( "Race",        ch->race,		fread_number( fp ) );
				KEY( "Rage_P",      ch->pcdata->rage_points,	fread_number( fp ) );
				KEY( "Rank",        ch->pcdata->rank,	fread_number( fp ) );
				
				if ( !str_cmp( word, "Renown" ))
				{
					ch->pcdata->renown[RENOWN_GLORY] = fread_number( fp );
					ch->pcdata->renown[RENOWN_HONOR] = fread_number( fp );
					ch->pcdata->renown[RENOWN_WISDOM] = fread_number( fp );
					fMatch = TRUE;
					break;
				}

				if ( !str_cmp( word, "Room" ) )
				{
					ch->in_room = get_room_index( fread_number( fp ) );
					if ( ch->in_room == NULL )
						ch->in_room = get_room_index( ROOM_VNUM_LIMBO );
					fMatch = TRUE;
					break;
				}
				
				KEY( "RPts",        ch->RPts,		fread_number( fp ) );
				KEY( "RP_Status",   ch->rp_status,	fread_number( fp ) );

				if ( !str_cmp( word, "Runes" ) )
				{
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					fMatch = TRUE;
					break;
				}
				
				break;
				
			case 'S':
				KEY( "SavingThrow",	ch->saving_throw,	fread_number( fp ) );
				
				if ( !str_cmp( word, "Score" ) )
				{
					fread_number( fp );
					fread_number( fp );
					fread_number( fp );
					fread_number( fp );
					fread_number( fp );
					fread_number( fp );
					fMatch = TRUE;
					break;
				}
				
				KEY( "Sec",	    ch->pcdata->security,		fread_number( fp ) );
				if (!str_cmp(word,"Sect"))
				{	
					ch->sect = fix_sect(ch,fread_string(fp));
					fMatch = TRUE;
					break;
				}
				KEY( "Sex",		ch->sex,					fread_number( fp ) );
				KEY( "Sight",	ch->sight,		fread_number( fp ) );
				KEY( "Shape",	ch->pcdata->wwf_shape,		fread_number( fp ) );
				h_KEY( "ShortDescr",	ch->short_descr,		nonfread_string(ch->short_descr, fp ) );
				
				if ( !str_cmp( word, "Skill" ) )
				{
					int sn;
					int value;
					
					value = fread_number( fp );
					sn    = skill_lookup( fread_word( fp ) );
/*
		if ( sn < 0 )
		    bug( "Fread_char: unknown skill.", 0 );
		else
		    ch->pcdata->learned[sn] = value;
*/
					if ( sn >= 0 )
						ch->pcdata->learned[sn] = value;
					fMatch = TRUE;
				}
				
				KEY( "Specpower",	ch->specpower,	fread_number( fp ) );
				KEY( "Spectype",	ch->spectype,	fread_number( fp ) );
				KEY( "Special",	ch->special,	fread_number( fp ) );
				
				if ( !str_cmp( word, "Spells" ) )
				{
					ch->spl[0]	= fread_number( fp );
					ch->spl[1]	= fread_number( fp );
					ch->spl[2]	= fread_number( fp );
					ch->spl[3]	= fread_number( fp );
					ch->spl[4]	= fread_number( fp );
					fMatch = TRUE;
					break;
				}
				KEY( "Sphere_spaffect",	ch->sphere_spaffect,	fread_number( fp ) );
				
				if (!str_cmp(word, "Sphere_AffectedBy"))
				{
					ch->sphere_affected_by[TYPE_SPHERE_ADDED]    =	fread_number( fp );
					ch->sphere_affected_by[TYPE_SPHERE_AFFECT]   =	fread_number( fp );
					ch->sphere_affected_by[TYPE_SPHERE_ACT]      =	fread_number( fp );
					ch->sphere_affected_by[TYPE_SPHERE_SPAFFECT] =  fread_number( fp );
					fMatch = TRUE;
					break;
				}
				
				if (!str_cmp( word, "Sphere_AffectData" ) )
				{
					SPHERE_DATA *paf;
					
					/* man i'm such a dumb ass for putting in this one
					if ( sphere_free == NULL )
					{
						paf		= alloc_perm( sizeof(*paf) );
					}
					else
					{
						paf		= sphere_free;
						sphere_free	= sphere_free->next;
					}
					*/
				        paf = new_sphere();	
					paf->spell_number = fread_number( fp );
					paf->type         = fread_number( fp );
					paf->duration     = fread_number( fp );
					paf->bitvector	  = fread_number( fp );

					paf->next	  = ch->sphere_affected;
					ch->sphere_affected	= paf;

					fMatch = TRUE;
					break;
				}
				
				if (!str_cmp(word, "Spent"))
				{
					ch->pcdata->spent[SPENT_QP]    =	fread_number( fp );
					ch->pcdata->spent[SPENT_CP]    =	fread_number( fp );
					ch->pcdata->spent[SPENT_P]     =	fread_number( fp );
					ch->pcdata->spent[SPENT_RP]    =	fread_number( fp );
					ch->pcdata->spent[SPENT_T]     =	fread_number( fp );
					fMatch = TRUE;
					break;
				}
				

				if ( !str_cmp( word, "Stage" ) )
				{
					ch->pcdata->stage[0] = fread_number( fp );
					ch->pcdata->stage[1] = fread_number( fp );
					ch->pcdata->stage[2] = fread_number( fp );
					fMatch = TRUE;
					break;
				}
				
				if ( !str_cmp( word, "Sgift" ))
				{
					ch->pcdata->sgift[1] = fread_number( fp );
					ch->pcdata->sgift[2] = fread_number( fp );
					ch->pcdata->sgift[3] = fread_number( fp );
					fMatch = TRUE;
					break;
				}

				if ( !str_cmp( word, "Stance" ) )
				{
					ch->stance[0]	= fread_number( fp );
					ch->stance[1]	= fread_number( fp );
					ch->stance[2]	= fread_number( fp );
					ch->stance[3]	= fread_number( fp );
					ch->stance[4]	= fread_number( fp );
					ch->stance[5]	= fread_number( fp );
					ch->stance[6]	= fread_number( fp );
					ch->stance[7]	= fread_number( fp );
					ch->stance[8]	= fread_number( fp );
					ch->stance[9]	= fread_number( fp );
					ch->stance[10]	= fread_number( fp );
					fMatch = TRUE;
					break;
				}
				
				if ( !str_cmp( word, "StatAbility" ) )
				{
					ch->pcdata->stat_ability[0] = fread_number( fp );
					ch->pcdata->stat_ability[1] = fread_number( fp );
					ch->pcdata->stat_ability[2] = fread_number( fp );
					ch->pcdata->stat_ability[3] = fread_number( fp );
					fMatch = TRUE;
					break;
				}
				
				if ( !str_cmp( word, "StatAmount" ) )
				{
					ch->pcdata->stat_amount[0] = fread_number( fp );
					ch->pcdata->stat_amount[1] = fread_number( fp );
					ch->pcdata->stat_amount[2] = fread_number( fp );
					ch->pcdata->stat_amount[3] = fread_number( fp );
					fMatch = TRUE;
					break;
				}
				
				if ( !str_cmp( word, "StatDuration" ) )
				{
					ch->pcdata->stat_duration[0] = fread_number( fp );
					ch->pcdata->stat_duration[1] = fread_number( fp );
					ch->pcdata->stat_duration[2] = fread_number( fp );
					ch->pcdata->stat_duration[3] = fread_number( fp );
					fMatch = TRUE;
					break;
				}
				
				
				if ( !str_cmp( word, "Stats" ) )
				{
					for ( sn = 0; sn < 12 ; sn++ )
						ch->pcdata->stats[sn] = fread_number( fp );
					fMatch = TRUE;
					break;
				}
				
				break;
				
			case 'T':
				KEY( "TR",	ch->pcdata->trait_merit[REG_MERIT],	fread_number( fp ) );
				KEY( "TF",	ch->pcdata->trait_flaw[REG_FLAW],		fread_number( fp ) );
				KEY( "TRi",	ch->pcdata->trait_merit[IMM_MERIT],	fread_number( fp ) );
				KEY( "TFi",	ch->pcdata->trait_flaw[IMM_FLAW],		fread_number( fp ) );
				KEY( "Trust",	ch->trust,		fread_number( fp ) );

				if ( !str_cmp( word, "TRenown" ))
				{
					ch->pcdata->Trenown[RENOWN_GLORY] = fread_number( fp );
					ch->pcdata->Trenown[RENOWN_HONOR] = fread_number( fp );
					ch->pcdata->Trenown[RENOWN_WISDOM] = fread_number( fp );
					fMatch = TRUE;
					break;
				}


			        if ( !str_cmp( word, "Tribes" ) )
	    			{
					ch->pcdata->tribes[0] = fread_number( fp );
					ch->pcdata->tribes[1] = fread_number( fp );
					ch->pcdata->tribes[2] = fread_number( fp );
					ch->pcdata->tribes[3] = fread_number( fp );
					ch->pcdata->tribes[4] = fread_number( fp );
					ch->pcdata->tribes[5] = fread_number( fp );
					ch->pcdata->tribes[6] = fread_number( fp );
					ch->pcdata->tribes[7] = fread_number( fp );
					ch->pcdata->tribes[8] = fread_number( fp );
					ch->pcdata->tribes[9] = fread_number( fp );
					ch->pcdata->tribes[10] = fread_number( fp );
					ch->pcdata->tribes[11] = fread_number( fp );
					ch->pcdata->tribes[12] = fread_number( fp );
					ch->pcdata->tribes[13] = fread_number( fp );
					ch->pcdata->tribes[14] = fread_number( fp );
					ch->pcdata->tribes[15] = fread_number( fp );
					ch->pcdata->tribes[16] = fread_number( fp );
					ch->pcdata->tribes[17] = fread_number( fp );
					ch->pcdata->tribes[18] = fread_number( fp );
					ch->pcdata->tribes[19] = fread_number( fp );
					fMatch = TRUE;
					break;
	   			 }
	
				if ( !str_cmp( word, "Title" ) )
				{
					ch->pcdata->title = nonfread_string(ch->pcdata->title, fp );
					if ( isalpha(ch->pcdata->title->str[0])
						||   isdigit(ch->pcdata->title->str[0]) )
					{
						sprintf( buf, " %s", ch->pcdata->title->str );
						ch->pcdata->title = g_string_assign(ch->pcdata->title, buf );
					}
					fMatch = TRUE;
					break;
				}
				
				break;
				
			case 'V':
				KEY( "Vampaff",        dummy,		fread_number( fp ) );
				KEY( "Vampgen",        dummy,		fread_number( fp ) );
				KEY( "Vamppass",       dummy,		fread_number( fp ) );
				if ( !str_cmp( word, "Vnum" ) )
				{
					ch->pIndexData = get_mob_index( fread_number( fp ) );
					fMatch = TRUE;
					break;
				}
				break;
				
			case 'W':
				if ( !str_cmp( word, "Weapons" ) )
				{
					ch->wpn[0]	= fread_number( fp );
					ch->wpn[1]	= fread_number( fp );
					ch->wpn[2]	= fread_number( fp );
					ch->wpn[3]	= fread_number( fp );
					ch->wpn[4]	= fread_number( fp );
					ch->wpn[5]	= fread_number( fp );
					ch->wpn[6]	= fread_number( fp );
					ch->wpn[7]	= fread_number( fp );
					ch->wpn[8]	= fread_number( fp );
					ch->wpn[9]	= fread_number( fp );
					ch->wpn[10]	= fread_number( fp );
					ch->wpn[11]	= fread_number( fp );
					ch->wpn[12]	= fread_number( fp );
					fMatch = TRUE;
					break;
				}
				KEY( "WIL", 	ch->pcdata->willpower,	fread_number( fp ) );
				KEY( "Wimpy",	ch->wimpy,		fread_number( fp ) );
				KEY( "Wolf",        dummy,		fread_number( fp ) );
				KEY( "Wiznet",  ch->pcdata->wiznet,	fread_number( fp ) );
				if ( !str_cmp( word, "Wolfform" ) )
				{
					dummy = fread_number( fp );
					dummy = fread_number( fp );
					fMatch = TRUE;
					break;
				}
				break;
		}

		if (Player_Error == TRUE)
		{
			send_to_char("Your Pfile has a problem, please note Spiral or Dominion with another char",ch);
			sprintf(log,"Pfile error in player %s",ch->name->str);	
			log_string2(log);
			logchan(log, NULL, NULL,WIZ_LINK,0, LEVEL_QUESTMAKER);
			close_socket(ch->desc);
		        Player_Load = FALSE;
			return;
		}
		
		if ( !fMatch )
		{
			sprintf(buf, "Fread_charB: no match. WORD: %s", word); 
			bug( buf, 0 );
			sprintf(log,"Pfile error in player %s",ch->name->str);	
			log_string2(log);
			logchan(log, NULL, NULL,WIZ_LINK,0, LEVEL_QUESTMAKER);
			/* Kick them off.. with a nice warning */
			//fread_to_eol( fp );
			send_to_char("Your pFile has a problem, please note Spiral or Dominion with another char",ch);
			close_socket(ch->desc);
		        Player_Load = FALSE;
			return;
		}

	}
	Player_Load = FALSE;
	Player_Error = FALSE;
	return;
}
/*
 * Write the char.
 */
void fwrite_char( CHAR_DATA *ch, FILE *fp )
{
	KNOWN_DATA *names;
	AFFECT_DATA *paf;
	SPHERE_DATA *sp_paf;
	int sn,i;
	int pos;
	if (IS_NPC(ch)) {
        return;
    }
	fprintf( fp, "#%s\n", IS_NPC(ch) ? "MOB" : "PLAYERS"		);
	
	fprintf( fp, "Name         %s~\n",	ch->name->str		);
	fprintf( fp, "ShortDescr   %s~\n",	ch->short_descr->str		);
	fprintf( fp, "LongDescr    %s~\n",	ch->long_descr->str		);
	fprintf( fp, "Description  %s~\n",	ch->description->str	);
    fprintf( fp, "ANONDes      %s~\n",	ch->pcdata->anon_desc->str);
	fprintf( fp, "Lord         %s~\n",	ch->lord->str		);
	fprintf( fp, "Id           %ld\n",	ch->id  		);
	fprintf( fp, "Plane        %ld\n",	ch->plane  		);
	fprintf( fp, "iCla         %d\n",	ch->clan		);
	/*fprintf( fp, "Sect         %s~\n",	ch->sect		); - Taken out, no more strings - Spiral*/
	if (ch->sect > 0 )
    	fprintf( fp, "iSec         %d\n",	ch->sect 		);
	fprintf( fp, "Class        %d\n",	ch->creature		);
	fprintf( fp, "Morph        %s~\n",	ch->morph->str		);
	fprintf( fp, "Createtime   %s~\n",	ch->createtime->str		);
	fprintf( fp, "Lasttime     %s~\n",	ch->lasttime->str		);
	fprintf( fp, "Lasthost     %s~\n",	ch->lasthost->str		);
	fprintf( fp, "Poweraction  %s~\n",	ch->poweraction->str		);
	fprintf( fp, "Powertype    %s~\n",	ch->powertype->str		);
	fprintf( fp, "Prompt       %s~\n",	ch->prompt->str		);
	fprintf( fp, "Cprompt      %s~\n",	ch->cprompt->str		);
	fprintf( fp, "Sex          %d\n",	ch->sex			);
	fprintf( fp, "Race         %d\n",	ch->race		);
	fprintf( fp, "Immune       %d\n",	ch->immune		);
	fprintf( fp, "Polyaff      %d\n",	ch->polyaff		);
	fprintf( fp, "Itemaffect   %d\n",	ch->itemaffect		);
	fprintf( fp, "Form         %d\n",	ch->form		);
	fprintf( fp, "Sight        %ld\n",	ch->sight		);
	fprintf( fp, "Lag          %d\n",	ch->pcdata->lag_time);
    fprintf( fp, "Comm         %d\n",	ch->pcdata->comm	);
	fprintf( fp, "Beast        %d\n",	ch->beast		);
	fprintf( fp, "ChrPnts      %d\n",	ch->pcdata->charpoints	);
	fprintf( fp, "TR           %d\n",	ch->pcdata->trait_merit[REG_MERIT]	);
	fprintf( fp, "TF           %d\n",	ch->pcdata->trait_flaw[REG_FLAW]	);
	fprintf( fp, "TRi          %d\n",	ch->pcdata->trait_merit[IMM_MERIT]	);
	fprintf( fp, "TFi          %d\n",	ch->pcdata->trait_flaw[IMM_FLAW]	);
	fprintf( fp, "Spectype     %d\n",	ch->spectype		);
	fprintf( fp, "Specpower    %d\n",	ch->specpower		);
	fprintf( fp, "Home         %d\n",	ch->home		);
	fprintf( fp, "Level        %d\n",	ch->level		);
	fprintf( fp, "Phold        %ld\n",	ch->primal_hold	);
    fprintf( fp, "Trust        %d\n",	ch->trust		);
	fprintf( fp, "Sec          %d\n",	ch->pcdata->security	);
	fprintf( fp, "Nature       %s~\n",	ch->pcdata->nature->str	);
	fprintf( fp, "Demeanor     %s~\n",	ch->pcdata->demeanor->str	);
	fprintf( fp, "RPts         %d\n",	ch->RPts   		);
	fprintf( fp, "Diab         %d\n",	ch->pcdata->diab[DIAB_EVER]	);
	fprintf( fp, "Follow       %d\n",	ch->pcdata->followers );
    if (ch->pcdata->willpower > 0 )
		fprintf( fp, "WIL          %d\n",	ch->pcdata->willpower 		);


	/*
	 * Spiral Werewolf Save
	 */
	if ( IS_CLASS(ch,CLASS_SWWF))
	{
		fprintf( fp, "Rage_P       %d\n",	ch->pcdata->rage_points	);
		fprintf( fp, "Gnosis       %d\n",	ch->pcdata->gnosis	);
		fprintf( fp, "Shape        %d\n",	ch->pcdata->wwf_shape	);
		fprintf( fp, "Renown       %d %d %d\n",	ch->pcdata->renown[RENOWN_GLORY], ch->pcdata->renown[RENOWN_HONOR], ch->pcdata->renown[RENOWN_WISDOM] );
		fprintf( fp, "TRenown      %d %d %d\n",	ch->pcdata->Trenown[RENOWN_GLORY], ch->pcdata->Trenown[RENOWN_HONOR], ch->pcdata->Trenown[RENOWN_WISDOM] );
		fprintf( fp, "Sgift        %d %d %d\n",	ch->pcdata->sgift[1], ch->pcdata->sgift[2], ch->pcdata->sgift[3] );
		fprintf( fp, "LRite        %d\n",	ch->pcdata->last_rite );
	}

	if ( ch->nextquest > 0 )
		fprintf( fp, "Qtimer       %d\n",	ch->nextquest  		);
	fprintf( fp, "RP_Status    %d\n",	ch->rp_status 		);
	fprintf( fp, "Paradox      %d %d %d\n", ch->paradox[0], ch->paradox[1], 
		ch->paradox[2] ); 
	/* 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");
    fprintf(fp, "HardSkillz   ");
    for (i = 0; i < MAX_HARD_SKILLS; i++) {
        fprintf(fp, "%d ", ch->pcdata->hard_skills[i]);
    }
	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 != NULL )
		? ch->was_in_room->vnum
		: ch->in_room->vnum );
	
	fprintf( fp, "PkPdMkMd     %d %d %d %d\n",
		ch->pkill, ch->pdeath, ch->mkill, ch->mdeath );
	
    fprintf( fp, "Discipline  ");
    for ( sn = 0 ; sn < MAX_DISCIPLINE ; sn++ )
    {
        fprintf( fp, " %d", ch->pcdata->discipline[sn]);
    }
    fprintf( fp, "\n");
    
		fprintf( fp, "NDisc  	  ");
		for ( sn = 0 ; sn < MAX_DISC ; sn++ )
		{
			fprintf( fp, " %d", ch->pcdata->disc[sn]);
		}
		fprintf( fp, "\n");
        
        fprintf( fp, "NInherited   ");
        for ( sn = 0 ; sn < MAX_DISC ; sn++ )
        {
            fprintf( fp, " %d", ch->pcdata->Ninherited[sn]);
        }
        fprintf( fp, "\n");

    	fprintf( fp, "Weapons      %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
		ch->wpn[0], ch->wpn[1], ch->wpn[2], ch->wpn[3], ch->wpn[4], 
		ch->wpn[5], ch->wpn[6], ch->wpn[7], ch->wpn[8], ch->wpn[9], 
		ch->wpn[10], ch->wpn[11], ch->wpn[12] );
	fprintf( fp, "Spells       %d %d %d %d %d\n",
		ch->spl[0], ch->spl[1], ch->spl[2], ch->spl[3], ch->spl[4] );
	fprintf( fp, "Combat       %d %d %d %d %d %d %d %d\n",
		ch->cmbt[0], ch->cmbt[1], ch->cmbt[2], ch->cmbt[3],
		ch->cmbt[4], ch->cmbt[5], ch->cmbt[6], ch->cmbt[7] );
	fprintf( fp, "Stance       %d %d %d %d %d %d %d %d %d %d %d\n",
		ch->stance[0], ch->stance[1], ch->stance[2], ch->stance[3],
		ch->stance[4], ch->stance[5], ch->stance[6], ch->stance[7],
		ch->stance[8], ch->stance[9], ch->stance[10] );
	fprintf( fp, "Locationhp   %d %d %d %d %d %d %d\n",
		ch->loc_hp[0], ch->loc_hp[1], ch->loc_hp[2], ch->loc_hp[3],
		ch->loc_hp[4], ch->loc_hp[5], ch->loc_hp[6] );
	fprintf( fp, "Spent        %d %d %d %d %d\n",
		ch->pcdata->spent[SPENT_QP],ch->pcdata->spent[SPENT_CP],
		ch->pcdata->spent[SPENT_P],ch->pcdata->spent[SPENT_RP],ch->pcdata->spent[SPENT_T]);
	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, "Gold         %d\n",	ch->gold		);
	fprintf( fp, "Exp          %d\n",	ch->exp			);
	fprintf( fp, "Act          %d\n",   ch->act			);
	fprintf( fp, "Arete        %d\n",   ch->arete			);
	fprintf( fp, "Special      %d\n",   ch->special		);
	fprintf( fp, "Extra        %d\n",   ch->extra		);
	fprintf( fp, "Added        %d\n",   ch->added		);
	fprintf( fp, "Wiznet       %d\n",   ch->pcdata->wiznet  );
	fprintf( fp, "AffectedBy   %d\n",	ch->affected_by		);
	fprintf( fp, "Sphere_spaffect  %d\n",	ch->sphere_spaffect		);
	fprintf( fp, "Sphere_AffectedBy   %d %d %d %d\n",ch->sphere_affected_by[TYPE_SPHERE_ADDED],ch->sphere_affected_by[TYPE_SPHERE_AFFECT],ch->sphere_affected_by[TYPE_SPHERE_ACT],ch->sphere_affected_by[TYPE_SPHERE_SPAFFECT]);
    /* Bug fix from Alander */
	fprintf( fp, "Position     %d\n",
		ch->position == POS_FIGHTING ? POS_STANDING : ch->position );
	
	fprintf( fp, "Practice     %d\n",	ch->practice		);
	fprintf( fp, "SavingThrow  %d\n",	ch->saving_throw	);
	fprintf( fp, "Alignment    %d\n",	ch->alignment		);
	fprintf( fp, "Hitroll      %d\n",	ch->hitroll		);
	fprintf( fp, "Damroll      %d\n",	ch->damroll		);
	fprintf( fp, "Armor        %d\n",	ch->armor		);
	fprintf( fp, "Wimpy        %d\n",	ch->wimpy		);
	fprintf( fp, "Deaf         %ld\n",	ch->deaf		);
	fprintf( fp, "Abs_Mvnum    %d\n",	ch->pcdata->absorb[ABS_MOB_VNUM]);
	fprintf( fp, "Abs_MHp 	   %d\n",	ch->pcdata->absorb[ABS_MOB_HP]);
	fprintf( fp, "Abs_MMaxHp   %d\n",	ch->pcdata->absorb[ABS_MOB_MAX_HP]);
	if (str_cmp(ch->murmur_name->str,"") && str_cmp(ch->murmur_command->str,""))
	{
		fprintf( fp, "Murmurn      %s~\n",	ch->murmur_name->str);
		fprintf( fp, "Murmurc      %s~\n",	ch->murmur_command->str);
	}
	
	if (ch->pcdata->conding != NULL)
	{
		fprintf( fp, "Cing         %s~\n",ch->pcdata->conding);
	}
	
	if ( IS_NPC(ch) )
	{
		fprintf( fp, "Vnum         %d\n",	ch->pIndexData->vnum	);
	}
	else
	{
		fprintf( fp, "Password     %s~\n",	ch->pcdata->pwd->str		);
		fprintf( fp, "Bamfin       %s~\n",	ch->pcdata->bamfin->str	);
		fprintf( fp, "Bamfout      %s~\n",	ch->pcdata->bamfout->str	);
		fprintf( fp, "Title        %s~\n",	ch->pcdata->title->str	);
		fprintf( fp, "Conception   %s~\n",	ch->pcdata->conception->str	);
		fprintf( fp, "Parents      %s~\n",	ch->pcdata->parents->str	);
		fprintf( fp, "Cparents     %s~\n",	ch->pcdata->cparents->str	);
		fprintf( fp, "Marriage     %s~\n",	ch->pcdata->marriage->str	);
		fprintf( fp, "Email        %s~\n",	ch->pcdata->email->str	);
		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, "Quest        %d\n", ch->pcdata->quest );
		fprintf( fp, "Wolf         %d\n", ch->pcdata->stats[UNI_RAGE]);
		fprintf( fp, "Rank         %d\n", ch->pcdata->rank );
		fprintf( fp, "Language     %d %d\n",
			ch->pcdata->language[0],
			ch->pcdata->language[1] );
		fprintf( fp, "Stage        %d %d %d\n",
			ch->pcdata->stage[0],
			ch->pcdata->stage[1],
			ch->pcdata->stage[2] );
		fprintf( fp, "Genes        %d %d %d %d %d %d %d %d %d %d\n",
			ch->pcdata->genes[0],
			ch->pcdata->genes[1],
			ch->pcdata->genes[2],
			ch->pcdata->genes[3],
			ch->pcdata->genes[4],
			ch->pcdata->genes[5],
			ch->pcdata->genes[6],
			ch->pcdata->genes[7],
			ch->pcdata->genes[8],
			ch->pcdata->genes[9] );
		
        fprintf( fp, "Power        ");
		for (sn=0; sn < 20; sn++)
		{
			fprintf(fp, "%d ", ch->pcdata->powers[sn]);
		}
		fprintf(fp, "\n");
		
        fprintf( fp, "Stats        ");
		for (sn=0; sn < 12; sn++)
		{
			fprintf(fp, "%d ", ch->pcdata->stats[sn]);
		}
		fprintf(fp, "\n");
		
		fprintf( fp, "FakeCon      %d %d %d %d %d %d %d %d\n",
			ch->pcdata->fake_skill, 
			ch->pcdata->fake_stance, 
			ch->pcdata->fake_hit,
			ch->pcdata->fake_dam,
			ch->pcdata->fake_ac,
			ch->pcdata->fake_hp,
			ch->pcdata->fake_mana,
			ch->pcdata->fake_move);
		
		if (ch->pcdata->obj_vnum != 0)
			fprintf( fp, "Objvnum      %d\n", ch->pcdata->obj_vnum );
		
		fprintf( fp, "Condition    %d %d %d\n",
			ch->pcdata->condition[0],
			ch->pcdata->condition[1],
			ch->pcdata->condition[2] );
		
		fprintf( fp, "StatAbility  %d %d %d %d\n",
			ch->pcdata->stat_ability[0],
			ch->pcdata->stat_ability[1],
			ch->pcdata->stat_ability[2],
			ch->pcdata->stat_ability[3] );
		
		fprintf( fp, "StatAmount   %d %d %d %d\n",
			ch->pcdata->stat_amount[0],
			ch->pcdata->stat_amount[1],
			ch->pcdata->stat_amount[2],
			ch->pcdata->stat_amount[3] );
		
		fprintf( fp, "StatDuration %d %d %d %d\n",
			ch->pcdata->stat_duration[0],
			ch->pcdata->stat_duration[1],
			ch->pcdata->stat_duration[2],
			ch->pcdata->stat_duration[3] );
		
		fprintf( fp, "Exhaustion   %d\n", ch->pcdata->exhaustion );
		for (pos = 0; pos < MAX_IGNORE; pos++)  
		{
			if (ch->pcdata->ignore[pos] == NULL)
				break;
			
			fprintf(fp, "Ignore %s~\n", ch->pcdata->ignore[pos]->str);
		}
		
        /* write alias */
		for (pos = 0; pos < MAX_ALIAS; pos++)
		{
			if (ch->pcdata->alias[pos] == NULL
				||  ch->pcdata->alias_sub[pos] == NULL || !strcmp(ch->pcdata->alias[pos]->str,""))
				break;
			fprintf(fp,"Alias        %s %s~\n",ch->pcdata->alias[pos]->str,ch->pcdata->alias_sub[pos]->str);
		}
		
        	/* Write out 'known people' array. */
        
      		for ( names = ch->pcdata->known; names; names = names->next )
       		{
      		 	fprintf(fp, "Know %ld\n", names->value);
       		}

		for ( sn = 0; sn < MAX_SKILL; sn++ )
		{
			if ( skill_table[sn].name != NULL && ch->pcdata->learned[sn] > 0 )
			{
				fprintf( fp, "Skill        %d '%s'\n",
					ch->pcdata->learned[sn], skill_table[sn].name );
			}
		}
	}
	
	for ( paf = ch->affected; paf != NULL; paf = paf->next )
	{
	/* Thx Alander 
	if ( paf->type < 0 || paf->type >= MAX_SKILL )
	    continue; */
		
		fprintf( fp, "AffectData   '%s' %3d %3d %3d %10d\n",
			skill_table[paf->type].name,
			paf->duration,
			paf->modifier,
			paf->location,
			paf->bitvector
			);
	}
	
	for ( sp_paf = ch->sphere_affected; sp_paf != NULL; sp_paf = sp_paf->next )
	{
	/* Thx Alander 
	if ( paf->type < 0 || paf->type >= MAX_SKILL )
	    continue; */
		
		fprintf( fp, "Sphere_AffectData	%d %d %d %d\n",
			sp_paf->spell_number,
			sp_paf->type,
			sp_paf->duration,
			sp_paf->bitvector
			);
	}

	//Kavir-Spiral Changes to Player File for SWWF

	fprintf( fp, "Breed        %d %d %d\n",
	    ch->pcdata->breed[0],
	    ch->pcdata->breed[1],
	    ch->pcdata->breed[2]);
	fprintf( fp, "Auspice      %d %d %d %d %d\n",
	    ch->pcdata->auspice[0], ch->pcdata->auspice[1],
	    ch->pcdata->auspice[2], ch->pcdata->auspice[3],
	    ch->pcdata->auspice[4]);
	fprintf( fp, "Tribes       %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
	    ch->pcdata->tribes[0], ch->pcdata->tribes[1], ch->pcdata->tribes[2],
	    ch->pcdata->tribes[3], ch->pcdata->tribes[4], ch->pcdata->tribes[5], 
	    ch->pcdata->tribes[6], ch->pcdata->tribes[7], ch->pcdata->tribes[8],
	    ch->pcdata->tribes[9], ch->pcdata->tribes[10],ch->pcdata->tribes[11],
	    ch->pcdata->tribes[12],ch->pcdata->tribes[13],ch->pcdata->tribes[14],
	    ch->pcdata->tribes[15],ch->pcdata->tribes[16],ch->pcdata->tribes[17],
	    ch->pcdata->tribes[18],ch->pcdata->tribes[19]);
	
	
	fprintf( fp, "End\n\n" );
	return;
}

GString *
get_player_class_string(CHAR_DATA *ch)
{
	GString *chclass;
	
	if (ch == NULL || IS_NPC(ch))
		return g_string_new("");
	
	
	switch (ch->creature)
	{
		case CLASS_VAMPIRE:
			chclass = g_string_new("Vampire");
			break;
		case CLASS_MAGE:
			chclass = g_string_new("Mage");
			break;
		case CLASS_SWWF:
			chclass = g_string_new("Werewolf");
			break;
		default:
			chclass = g_string_new("Unclassed Avatar");
			break;
	}
	return chclass;
}
void save_char_obj_finger( CHAR_DATA *ch )
{
	char strsave[MAX_STRING_LENGTH];
	FILE *fp;
	
	/*players Don't save on Chaos Night!*/
    if (IS_SET(mudsetting->mud_setting, MS_CHAOS_NIGHT))
        return;

    if ( IS_NPC(ch) || ch->level < 2 )
		return;
	
	if ( ch->desc != NULL && ch->desc->original != NULL )
		ch = ch->desc->original;
	
	ch->save_time = current_time;
	fclose( fpReserve );
	sprintf( strsave, "%sbackup/%s", PLAYER_DIR, capitalize(ch->name->str) );
	if ( ( fp = fopen( strsave, "w" ) ) == NULL )
	{
		fpReserve = fopen( NULL_FILE, "r" );
		bug( "Save_char_obj: fopen", 0 );
		fclose( fpReserve );
	}
	else
	{
		fprintf( fp, "%s~\n",	ch->name->str		);
		fprintf( fp, "%s~\n",	ch->pcdata->title->str	);
		fprintf( fp, "%d\n",	ch->creature   		);
		fprintf( fp, "%d\n",	ch->clan    		);
		fprintf( fp, "%s~\n",	ch->lasthost->str		);
		fprintf( fp, "%s~\n",	ch->lasttime->str		);
		fprintf( fp, "%d\n",	ch->extra		);
		fprintf( fp, "%d\n",	ch->sex			);
		fprintf( fp, "%s~\n",	ch->pcdata->conception->str	);
		fprintf( fp, "%s~\n",	ch->createtime->str		);
		fprintf( fp, "%d\n",	ch->level		);
		fprintf( fp, "%d\n",	ch->race		);
		fprintf( fp, "%d\n",
			ch->played + (int) (current_time - ch->logon));
		fprintf( fp, "%s~\n",	ch->pcdata->marriage->str	);
		fprintf( fp, "%d\n",	ch->pkill );
		fprintf( fp, "%d\n",	ch->pdeath );
		fprintf( fp, "%d\n",	ch->mkill );
		fprintf( fp, "%d\n",	ch->mdeath );
		fprintf( fp, "%s~\n",	ch->pcdata->email->str	);
	}
	fflush( fp );
	fclose( fp );
	fpReserve = fopen( NULL_FILE, "r" );
	return;
}

/*
 * 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 strsavetmp[MAX_STRING_LENGTH];
	char strsave[MAX_STRING_LENGTH];
	FILE *fp;
	
	/*players Don't save on Chaos Night!*/
    if (IS_SET(mudsetting->mud_setting, MS_CHAOS_NIGHT))
        return;

    if ( IS_NPC(ch) || ch->level < 2 )
		return;
	
	if ( ch->desc != NULL && ch->desc->connected != CON_PLAYING )
		return;
	
	if ( ch->desc != NULL && ch->desc->original != NULL )
		ch = ch->desc->original;
/*
    save_char_obj_backup( ch );
*/
	ch->save_time = current_time;
	fclose( fpReserve );
	sprintf( strsavetmp, "%s%s.tmp", PLAYER_DIR, capitalize( ch->name->str ) );
	sprintf( strsave, "%s%s", PLAYER_DIR, capitalize( ch->name->str ) );
	if ( ( fp = fopen( strsavetmp, "w" ) ) == NULL )
	{
		fpReserve = fopen( NULL_FILE, "r" );
		bug( "Save_char_obj: fopen", 0 );
		fclose( fpReserve );
		return;
	}
	else
	{
		fwrite_char( ch, fp );
		
		if ( ch->carrying != NULL )
			fwrite_obj( ch, ch->carrying, fp, 0 );

		if ( ch->pet != NULL )
			fwrite_pet( ch, fp);

		fprintf( fp, "#END\n" );
	}
	fflush( fp );
	fclose( fp );
	fpReserve = fopen( NULL_FILE, "r" );
	rename( strsavetmp, strsave );
	save_char_obj_finger( ch );
	return;
}

/*
 * Retrieve a character's trusted level for permission checking.
 */
int get_trust( CHAR_DATA *ch )
{
	if ( ch->desc != NULL && ch->desc->original != NULL )
		ch = ch->desc->original;
	
	if ( ch->trust != 0 )
		return ch->trust;
	
	if ( IS_NPC(ch) )
	{	
		if( IS_SET(ch->act, ACT_HOLYLIGHT) )
			return LEVEL_IMMORTAL;
		else
			return LEVEL_HERO -1;
		
	}
	return ch->level;
	
	
}	
/*
 * Retrieve a character's age.
 */
int get_age( CHAR_DATA *ch )
{
	int age;

	age = 17 + ( ch->played + (int) (current_time - ch->logon) ) / 7200;
	
	if (!IS_NPC(ch) && IS_MERIT(ch,MERIT_WISE))
		age += 150;

	if (!IS_NPC(ch) && IS_FLAW(ch,FLAW_FOOLISH))
		age -= 150;

	if (age < 0)
		age =0;
		
   return age;		
}



/*
 * Retrieve character's current strength.
 */
int get_curr_str( CHAR_DATA *ch )
{	
	sh_int max = 25;
	
	if ( IS_NPC(ch) )
		return 13;
	
	return URANGE( 3, ch->pcdata->perm_str + ch->pcdata->mod_str, max );
}

/*
 * Retrieve character's current intelligence.
 */
int get_curr_int( CHAR_DATA *ch )
{
	sh_int max;
	
	if ( IS_NPC(ch) )
		return 13;
	
	max = 25;
	
	return URANGE( 3, ch->pcdata->perm_int + ch->pcdata->mod_int, max );
}



/*
 * Retrieve character's current wisdom.
 */
int get_curr_wis( CHAR_DATA *ch )
{
	sh_int max;
	
	if ( IS_NPC(ch) )
		return 13;
	
	max = 25;
	
	return URANGE( 3, ch->pcdata->perm_wis + ch->pcdata->mod_wis, max );
}



/*
 * Retrieve character's current dexterity.
 */
int get_curr_dex( CHAR_DATA *ch )
{
	sh_int max;
	
	if ( IS_NPC(ch) )
		return 13;
	
	max = 25;
	
	return URANGE( 3, ch->pcdata->perm_dex + ch->pcdata->mod_dex, max );
}



/*
 * Retrieve character's current constitution.
 */
int get_curr_con( CHAR_DATA *ch )
{
	sh_int max;
	
	if ( IS_NPC(ch) )
		return 13;
	
	max = 25;
	
	return URANGE( 3, ch->pcdata->perm_con + ch->pcdata->mod_con, max );
}



/*
 * Retrieve a character's carry capacity.
 */
int can_carry_n( CHAR_DATA *ch )
{
	if ( !IS_NPC(ch) && ch->level >= LEVEL_IMMORTAL )
		return 1000;
	
	if ( IS_NPC(ch) && IS_SET(ch->act, ACT_PET) )
		return 0;
	
	return MAX_WEAR + ( 2 * get_curr_dex( ch ) / 3 ) + ch->race * 2;
}



/*
 * Retrieve a character's carry capacity.
 */
int can_carry_w( CHAR_DATA *ch )
{
	if ( !IS_NPC(ch) && ch->level >= LEVEL_IMMORTAL )
		return 1000000;
	
	if ( IS_NPC(ch) && IS_SET(ch->act, ACT_PET) )
		return 0;
	
	return str_app[get_curr_str(ch)].carry;
}



/*
 *  the old way to See if a string is one of the names of an object.
 *
bool is_name( const char *str, char *namelist )
{
    char name[MAX_INPUT_LENGTH];

    for ( ; ; )
    {
	namelist = one_argument( namelist, name );
	if ( name[0] == '\0' )
	    return FALSE;
	if ( !str_cmp( str, name ) )
	    return TRUE;
    }
}
*/