1stMUD4.0/bin/
1stMUD4.0/doc/MPDocs/
1stMUD4.0/player/
1stMUD4.0/win32/
1stMUD4.0/win32/rom/
/**************************************************************************
*  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
*  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
*                                                                         *
*  Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael         *
*  Chastain, Michael Quan, and Mitchell Tse.                              *
*                                                                         *
*  In order to use any part of this Merc Diku Mud, you must comply with   *
*  both the original Diku license in 'license.doc' as well the Merc       *
*  license in 'license.txt'.  In particular, you may not remove either of *
*  these copyright notices.                                               *
*                                                                         *
*  Much time and thought has gone into this software and you are          *
*  benefiting.  We hope that you share your changes too.  What goes       *
*  around, comes around.                                                  *
***************************************************************************
*       ROM 2.4 is copyright 1993-1998 Russ Taylor                        *
*       ROM has been brought to you by the ROM consortium                 *
*           Russ Taylor (rtaylor@hypercube.org)                           *
*           Gabrielle Taylor (gtaylor@hypercube.org)                      *
*           Brian Moore (zump@rom.org)                                    *
*       By using this code, you have agreed to follow the terms of the    *
*       ROM license, in the file Rom24/doc/rom.license                    *
***************************************************************************
*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
*            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
***************************************************************************/
#include "merc.h"
#include "globals.h"
#include "tables.h"
#include "lookup.h"
#include "interp.h"
#include "olc.h"
#include "recycle.h"
#include "tablesave.h"

CHAR_DATA sChar;
PC_DATA sPC;
DESCRIPTOR_DATA sDesc;
MOB_INDEX_DATA sMob;
SHOP_DATA sShop;
ROOM_INDEX_DATA sRoom;
EXIT_DATA sExit;
OBJ_DATA sObj;
OBJ_INDEX_DATA spObj;
AREA_DATA sArea;

typedef const char *TS_FUNC(CHAR_DATA *, void *);
#define TS_FUN(fun)	const char *fun(CHAR_DATA *pch, void *temp)
#define DECLARE_TS_FUN(fun)     TS_FUNC fun

TS_FUN(ts_class)
{
	CHAR_DATA *ch = (CHAR_DATA *) temp;

	if (!ch)
		return "";
	else
		return class_long(ch);
}

TS_FUN(ts_stance)
{
	int *st = (int *) temp;

	return get_stance_name(*st);
}

TS_FUN(ts_editor)
{
	DESCRIPTOR_DATA *d = (DESCRIPTOR_DATA *) temp;

	if (d->editor != ED_NONE)
		return FORMATF("%s [%s]", olc_ed_name(d), olc_ed_vnum(d));
	else
		return "";
}

TS_FUN(ts_stats)
{
	CHAR_DATA *ch = (CHAR_DATA *) temp;
	static char buf[MSL];

	buf[0] = NUL;
	sprintf(buf, "Str [%d/%d]", ch->perm_stat[STAT_STR],
			get_curr_stat(ch, STAT_STR));
	sprintf(buf + strlen(buf), ", Int [%d/%d]", ch->perm_stat[STAT_INT],
			get_curr_stat(ch, STAT_INT));
	sprintf(buf + strlen(buf), ", Wis [%d/%d]", ch->perm_stat[STAT_WIS],
			get_curr_stat(ch, STAT_WIS));
	sprintf(buf + strlen(buf), ", Dex [%d/%d]", ch->perm_stat[STAT_DEX],
			get_curr_stat(ch, STAT_DEX));
	sprintf(buf + strlen(buf), ", Con [%d/%d]", ch->perm_stat[STAT_CON],
			get_curr_stat(ch, STAT_CON));
	return (buf);
}

TS_FUN(ts_weather)
{
	AREA_DATA *pArea = (AREA_DATA *) temp;

	return FORMATF("Temp [%s], Precip [%s], Wind [%s]",
				   temp_settings[pArea->weather.climate_temp],
				   precip_settings[pArea->weather.climate_precip],
				   wind_settings[pArea->weather.climate_wind]);
}

TS_FUN(ts_hours)
{
	int *h = (int *) temp;

	return FORMATF("%d", *h / HOUR);
}

const struct savetable_type char_stat_table[] = {
	{"Name", FIELD_STRING, (void *) &sChar.name, NULL, NULL},
	{"Id", FIELD_TIME, (void *) &sChar.id, NULL, NULL},
	{"Short", FIELD_STRING, (void *) &sChar.short_descr, NULL, NULL},
	{"Long", FIELD_STRING, (void *) &sChar.long_descr, NULL, NULL},
	{"Desc", FIELD_STRING, (void *) &sChar.description, NULL, NULL},
	{"Prompt", FIELD_STRING, (void *) &sChar.prompt, NULL, NULL},
	{"Prefix", FIELD_STRING, (void *) &sChar.prefix, NULL, NULL},
	{"Group", FIELD_INT, (void *) &sChar.group, (void *) 0, NULL},
	{"Saves", FIELD_INT, (void *) &sChar.saving_throw, (void *) 0, NULL},
	{"Sex", FIELD_INT_FLAGSTRING, (void *) &sChar.sex, (void *) sex_flags,
	 NULL},
	{"Class(s)", FIELD_FUNCTION, NULL, (void *) ts_class, NULL},
	{"Idle", FIELD_INT, (void *) &sChar.timer, (void *) 0, NULL},
	{"Wait", FIELD_INT, (void *) &sChar.wait, (void *) 0, NULL},
	{"Daze", FIELD_INT, (void *) &sChar.daze, (void *) 0, NULL},
	{"Carry Weight", FIELD_INT, (void *) &sChar.carry_weight, (void *) 0, NULL},
	{"Carry Number", FIELD_INT, (void *) &sChar.carry_number, (void *) 0, NULL},
	{"Damage", FIELD_DICE, (void *) &sChar.damage, (void *) 0, NULL},
	{"DamType", FIELD_INT, (void *) &sChar.dam_type,
	 (void *) 0, NULL},
	{"Race", FIELD_RACE, (void *) &sChar.race, (void *) DATA_NAME, NULL},
	{"Level", FIELD_INT, (void *) &sChar.level, NULL, NULL},
	{"Trust", FIELD_INT, (void *) &sChar.trust, (void *) 0, NULL},
	{"Lines", FIELD_INT, (void *) &sChar.lines, (void *) 0, NULL},
	{"Hit", FIELD_LONG, (void *) &sChar.hit, (void *) 0, NULL},
	{"MaxHit", FIELD_LONG, (void *) &sChar.max_hit, (void *) 0, NULL},
	{"Mana", FIELD_LONG, (void *) &sChar.mana, (void *) 0, NULL},
	{"MaxMana", FIELD_LONG, (void *) &sChar.max_mana, (void *) 0, NULL},
	{"Move", FIELD_LONG, (void *) &sChar.move, (void *) 0, NULL},
	{"MaxMove", FIELD_LONG, (void *) &sChar.max_move, (void *) 0, NULL},
	{"Gold", FIELD_LONG, (void *) &sChar.gold, (void *) 0, NULL},
	{"Reply", FIELD_CHARDATA, (void *) &sChar.reply, (void *) DATA_NAME, NULL},
	{"Pet", FIELD_CHARDATA, (void *) &sChar.pet, (void *) DATA_NAME, NULL},
	{"Mprog Target", FIELD_CHARDATA, (void *) &sChar.mprog_target,
	 (void *) DATA_NAME, NULL},
	{"Mprog Delay", FIELD_INT, (void *) &sChar.mprog_delay, (void *) 0, NULL},
	{"Stance", FIELD_INT_FUNCTION, (void *) &sChar.stance[STANCE_AUTODROP],
	 (void *) ts_stance, NULL},
	{"Info", FIELD_FLAGSTRING, (void *) &sChar.info_settings,
	 (void *) info_flags, (void *) 0},
	{"Act", FIELD_FLAGSTRING, (void *) &sChar.act, (void *) act_flags,
	 (void *) 0},

	{"Comm", FIELD_FLAGSTRING, (void *) &sChar.comm, (void *) comm_flags,
	 (void *) 0},
	{"Immune", FIELD_FLAGSTRING, (void *) &sChar.imm_flags, (void *) imm_flags,
	 (void *) 0},
	{"Resist", FIELD_FLAGSTRING, (void *) &sChar.res_flags, (void *) res_flags,
	 (void *) 0},
	{"Vulnerable", FIELD_FLAGSTRING, (void *) &sChar.vuln_flags,
	 (void *) vuln_flags, (void *) 0},
	{"Wizinvis", FIELD_INT, (void *) &sChar.invis_level, (void *) 0, NULL},
	{"Incog", FIELD_INT, (void *) &sChar.incog_level, (void *) 0, NULL},

	{"Affected by", FIELD_FLAGSTRING, (void *) &sChar.affected_by,
	 (void *) affect_flags, (void *) 0},
	{"Position", FIELD_INT_FLAGSTRING, (void *) &sChar.position,
	 (void *) position_flags, NULL},

	{"Start Pos", FIELD_INT_FLAGSTRING, (void *) &sChar.start_pos,
	 (void *) position_flags, (void *) 0},
	{"Default Pos", FIELD_INT_FLAGSTRING, (void *) &sChar.default_pos,
	 (void *) position_flags, (void *) 0},
	{"Practice", FIELD_INT, (void *) &sChar.practice, (void *) 0, NULL},
	{"Train", FIELD_INT, (void *) &sChar.train, (void *) 0, NULL},
	{"Alignment", FIELD_INT, (void *) &sChar.alignment, NULL, NULL},
	{"Hitroll", FIELD_INT, (void *) &sChar.hitroll, (void *) 0, NULL},
	{"Damroll", FIELD_INT, (void *) &sChar.damroll, (void *) 0, NULL},
	{"Armor", FIELD_INT_ARRAY, (void *) &sChar.armor, (void *) 4, NULL},
	{"Wimpy", FIELD_INT, (void *) &sChar.wimpy, (void *) 0, NULL},
	{"Exp", FIELD_LONG, (void *) &sChar.exp, (void *) 0, NULL},
	{"Clan", FIELD_CLAN, (void *) &sChar.clan, (void *) DATA_NAME, NULL},
	{"Rank", FIELD_INT, (void *) &sChar.rank, (void *) 0, NULL},
	{"Invited to", FIELD_CLAN, (void *) &sChar.invited, (void *) DATA_NAME, NULL},
	{"Logged On", FIELD_TIME, (void *) &sChar.logon, NULL, NULL},

	{"Stats", FIELD_FUNCTION, NULL,
	 (void *) ts_stats, NULL},

	{"Form", FIELD_FLAGSTRING, (void *) &sChar.form, (void *) form_flags,
	 (void *) 0},
	{"Parts", FIELD_FLAGSTRING, (void *) &sChar.parts, (void *) part_flags,
	 (void *) 0},
	{"Size", FIELD_INT_FLAGSTRING, (void *) &sChar.size, (void *) size_flags,
	 NULL},

	{"Material", FIELD_STRING, (void *) &sChar.material, (void *) "unknown",
	 NULL},

	{"Hours", FIELD_INT_FUNCTION, (void *) &sChar.played, NULL,
	 (void *) ts_hours},

	{"Offense", FIELD_FLAGSTRING, (void *) &sChar.off_flags,
	 (void *) off_flags, (void *) 0},
	{"Deity", FIELD_DEITY, (void *) &sChar.deity, (void *) DATA_NAME, NULL},
	{"Master", FIELD_CHARDATA, (void *) &sChar.master, (void *) DATA_NAME, NULL},
	{"Leader", FIELD_CHARDATA, (void *) &sChar.leader, (void *) DATA_NAME, NULL},

	{"Fighting", FIELD_CHARDATA, (void *) &sChar.fighting,
	 (void *) DATA_NAME, NULL},
	{"Pet", FIELD_CHARDATA, (void *) &sChar.pet, (void *) DATA_NAME, NULL},

	{"Hunting", FIELD_CHARDATA, (void *) &sChar.hunting, (void *) DATA_NAME,
	 NULL},

	{"SpecFun", FIELD_SPEC_FUN, (void *) &sChar.spec_fun, NULL, NULL},
	{"Area", FIELD_AREA, (void *) &sChar.zone, (void *) DATA_NAME, NULL},
	{"Room", FIELD_ROOM, (void *) &sChar.in_room, (void *) DATA_NAME, NULL},
	{"Mob", FIELD_MOBINDEX, (void *) &sChar.pIndexData, (void *) DATA_STAT, NULL},
	{"PcData", FIELD_PCDATA, (void *) &sChar.pcdata, (void *) DATA_STAT, NULL},
	{"Desc", FIELD_DESC, (void *) &sChar.desc, (void *) DATA_STAT, NULL},
	{NULL, 0, NULL, NULL, NULL}
};

const struct savetable_type pc_stat_table[] = {
	{"Poofin", FIELD_STRING, (void *) &sPC.bamfin, NULL, NULL},
	{"Poofout", FIELD_STRING, (void *) &sPC.bamfout, NULL, NULL},
	{"Title", FIELD_STRING, (void *) &sPC.title, NULL, NULL},
	{"WhoString", FIELD_STRING, (void *) &sPC.who_descr, NULL, NULL},
	{"AfkMsg", FIELD_STRING, (void *) &sPC.afk_msg, NULL, NULL},
	{"Condition", FIELD_INT_ARRAY, (void *) &sPC.condition, (void *) 4, NULL},
	{"Creation Points", FIELD_INT, (void *) &sPC.points, (void *) 0, NULL},
	{"Home Vnums", FIELD_LONG_ARRAY, (void *) &sPC.home,
	 (void *) MAX_HOUSE_ROOMS, (void *) -1},
	{"Home Key", FIELD_LONG, (void *) &sPC.home_key, (void *) -1, NULL},
	{"QuestPoints", FIELD_INT, (void *) &sPC.questpoints, (void *) 0, NULL},
	{"Bank:Gold", FIELD_LONG, (void *) &sPC.gold_bank, (void *) 0, NULL},
	{"Bank:Silver", FIELD_LONG, (void *) &sPC.silver_bank, (void *) 0, NULL},
	{"Shares", FIELD_INT, (void *) &sPC.shares, (void *) 0, NULL},
	{"Trivia", FIELD_INT, (void *) &sPC.trivia, (void *) 0, NULL},
	{"Security", FIELD_INT, (void *) &sPC.security, (void *) 0, NULL},
	{"Timezone", FIELD_INT, (void *) &sPC.timezone, (void *) -1, NULL},
	{NULL, 0, NULL, NULL, NULL}
};

const struct savetable_type desc_stat_table[] = {
	{"Host", FIELD_STRING, (void *) &sDesc.host, NULL, NULL},
	{"Descriptor", FIELD_INT, (void *) &sDesc.descriptor, NULL, NULL},
	{"Connected", FIELD_INT, (void *) &sDesc.connected, NULL, NULL},
	{"Repeated Cmd", FIELD_INT, (void *) &sDesc.repeat, (void *) 0, NULL},
	{"Editor", FIELD_FUNCTION, NULL, (void *) ts_editor, NULL},
	{"Flags", FIELD_FLAGSTRING, (void *) &sDesc.d_flags,
	 (void *) desc_flags, NULL},
	{"Scr Width", FIELD_INT, (void *) &sDesc.scr_width,
	 (void *) 80, NULL},
	{"Scr Height", FIELD_INT, (void *) &sDesc.scr_height,
	 (void *) 24, NULL},
	{"Terminal", FIELD_STRING_SIZE, (void *) &sDesc.ttype[0], NULL, (void *) 60},
	{"IMP Version", FIELD_DOUBLE, (void *) &sDesc.imp_vers, (void *) 0,
	 (void *) 2},
	{"Pueblo Version", FIELD_DOUBLE, (void *) &sDesc.pueblo_vers, (void *) 0,
	 (void *) 2},
#if !defined(NO_MCCP)
	{"MCCP Version", FIELD_INT, (void *) &sDesc.mccp_version, (void *) 0, NULL},
#endif
	{"MXP Versino", FIELD_FLOAT, (void *) &sDesc.mxp.mxp_ver, (void *) 0,
	 (void *) 2},
	{"Client", FIELD_STRING, (void *) &sDesc.mxp.client, NULL, NULL},

	{"Client Version", FIELD_FLOAT, (void *) &sDesc.mxp.client_ver,
	 (void *) 0, (void *) 2},
	{"Portal Version", FIELD_STRING_SIZE, (void *) &sDesc.portal.version[0], NULL,
	 (void *) 20},
	{"Portal Keycode", FIELD_INT, (void *) &sDesc.portal.keycode, (void *) 0,
	 NULL},
#if !defined(NO_MCCP)
	{"Bytes Compressed", FIELD_LONG, (void *) &sDesc.bytes_compressed,
	 (void *) 0, NULL},
#endif
	{"Bytes Normal", FIELD_LONG, (void *) &sDesc.bytes_normal, (void *) 0, NULL},
	{"Original", FIELD_CHARDATA, (void *) &sDesc.original,
	 (void *) DATA_STAT, NULL},
	{"Character", FIELD_CHARDATA, (void *) &sDesc.character, (void *) DATA_STAT,
	 NULL},
	{NULL, 0, NULL, NULL, NULL}
};

const struct savetable_type mob_stat_table[] = {
	{"Special", FIELD_SPEC_FUN, (void *) &sMob.spec_fun, NULL, NULL},
	{"Shop", FIELD_SHOP, (void *) &sMob.pShop, NULL, NULL},
	{"Programs", FIELD_PROG_LIST, (void *) &sMob.first_mprog,
	 (void *) DATA_LIST, NULL},
	{"Area", FIELD_AREA, (void *) &sMob.area, (void *) DATA_NAME, NULL},
	{"Vnum", FIELD_LONG, (void *) &sMob.vnum, NULL, NULL},
	{"Group", FIELD_LONG, (void *) &sMob.group, (void *) 0, NULL},
	{"Count", FIELD_INT, (void *) &sMob.count, (void *) 0, NULL},
	{"Killed", FIELD_LONG, (void *) &sMob.killed, (void *) 0, NULL},
	{"Name", FIELD_STRING, (void *) &sMob.player_name, NULL, NULL},
	{"Short", FIELD_STRING, (void *) &sMob.short_descr, NULL, NULL},
	{"Long", FIELD_STRING, (void *) &sMob.long_descr, NULL, NULL},
	{"Description", FIELD_STRING, (void *) &sMob.description, NULL, NULL},
	{"Act", FIELD_FLAGSTRING, (void *) &sMob.act, (void *) act_flags, (void *) 0},

	{"Affects", FIELD_FLAGSTRING, (void *) &sMob.affected_by,
	 (void *) affect_flags, (void *) 0},
	{"Alignment", FIELD_INT, (void *) &sMob.alignment, NULL, NULL},
	{"Level", FIELD_INT, (void *) &sMob.level, NULL, NULL},
	{"Hitroll", FIELD_INT, (void *) &sMob.hitroll, NULL, NULL},
	{"HitDice", FIELD_DICE, (void *) &sMob.hit, NULL, NULL},
	{"ManaDice", FIELD_DICE, (void *) &sMob.mana, NULL, NULL},
	{"DamDice", FIELD_DICE, (void *) &sMob.damage, NULL, NULL},
	{"Armor", FIELD_INT_ARRAY, (void *) &sMob.ac, (void *) 4, NULL},

	{"DamType", FIELD_INT, (void *) &sMob.dam_type,
	 (void *) 0, NULL},
	{"Offense", FIELD_FLAGSTRING, (void *) &sMob.off_flags, (void *) off_flags,
	 (void *) 0},
	{"Immune", FIELD_FLAGSTRING, (void *) &sMob.imm_flags, (void *) imm_flags,
	 (void *) 0},
	{"Resistant", FIELD_FLAGSTRING, (void *) &sMob.res_flags,
	 (void *) res_flags, (void *) 0},
	{"Vulnerable", FIELD_FLAGSTRING, (void *) &sMob.vuln_flags,
	 (void *) vuln_flags, (void *) 0},
	{"Start Pos", FIELD_INT_FLAGSTRING, (void *) &sMob.start_pos,
	 (void *) position_flags, (void *) 0},
	{"Default Pos", FIELD_INT_FLAGSTRING, (void *) &sMob.default_pos,
	 (void *) position_flags, (void *) 0},
	{"Sex", FIELD_INT_FLAGSTRING, (void *) &sMob.sex, (void *) sex_flags,
	 (void *) 0},
	{"Race", FIELD_RACE, (void *) &sMob.race, NULL, NULL},
	{"Wealth", FIELD_LONG, (void *) &sMob.wealth, NULL, NULL},

	{"Form", FIELD_FLAGSTRING, (void *) &sMob.form, (void *) form_flags,
	 (void *) 0},
	{"Parts", FIELD_FLAGSTRING, (void *) &sMob.parts, (void *) part_flags,
	 (void *) 0},
	{"Size", FIELD_INT_FLAGSTRING, (void *) &sMob.size, (void *) size_flags,
	 NULL},
	{"Material", FIELD_STRING, (void *) &sMob.material, (void *) "unknown",
	 NULL},
	{"Prog Flags", FIELD_FLAGSTRING, (void *) &sMob.mprog_flags,
	 (void *) mprog_flags, (void *) 0},
	{NULL, 0, NULL, NULL, NULL}
};

const struct savetable_type shop_stat_table[] = {
	{"Keeper", FIELD_LONG, (void *) &sShop.keeper, (void *) 0, NULL},

	{"Item Types", FIELD_INT_ARRAY, (void *) &sShop.buy_type,
	 (void *) MAX_TRADE, NULL},
	{"Profit-Buy", FIELD_INT, (void *) &sShop.profit_buy, NULL, NULL},
	{"Profit-Sell", FIELD_INT, (void *) &sShop.profit_sell, NULL, NULL},
	{"Open Hour", FIELD_INT, (void *) &sShop.open_hour, NULL, NULL},
	{"Close Hour", FIELD_INT, (void *) &sShop.close_hour, NULL, NULL},
	{NULL, 0, NULL, NULL, NULL}
};

const struct savetable_type room_stat_table[] = {
	{"Area", FIELD_AREA, (void *) &sRoom.area, (void *) DATA_NAME, NULL},
	{"Programs", FIELD_PROG_LIST, (void *) &sRoom.first_rprog,
	 (void *) DATA_LIST, NULL},
	{"Prog Target", FIELD_CHARDATA, (void *) &sRoom.rprog_target,
	 (void *) DATA_NAME, NULL},
	{"Prog Flags", FIELD_FLAGSTRING, (void *) &sRoom.rprog_flags,
	 (void *) rprog_flags, (void *) 0},
	{"Name", FIELD_STRING, (void *) &sRoom.name, NULL, NULL},
	{"Description", FIELD_STRING, (void *) &sRoom.description, NULL, NULL},
	{"Owner", FIELD_STRING, (void *) &sRoom.owner, NULL, NULL},
	{"Vnum", FIELD_LONG, (void *) &sRoom.vnum, (void *) 0, NULL},

	{"Flags", FIELD_FLAGSTRING, (void *) &sRoom.room_flags,
	 (void *) room_flags, (void *) 0},
	{"Light", FIELD_INT, (void *) &sRoom.light, (void *) 0, NULL},
	{"Sector", FIELD_INT_FLAGSTRING, (void *) &sRoom.sector_type,
	 (void *) sector_flags, NULL},
	{"HealRate", FIELD_INT, (void *) &sRoom.heal_rate, (void *) 100, NULL},
	{"ManaRate", FIELD_INT, (void *) &sRoom.mana_rate, (void *) 100, NULL},
	{"Clan", FIELD_CLAN, (void *) &sRoom.clan, (void *) DATA_NAME, NULL},
	{"People", FIELD_CHARDATA, (void *) &sRoom.first_person,
	 (void *) DATA_LIST, NULL},
	{"Objects", FIELD_OBJ, (void *) &sRoom.first_content,
	 (void *) DATA_LIST, NULL},
	{"Extra Descriptions", FIELD_EXDESC, (void *) &sRoom.first_extra_descr,
	 (void *) DATA_LIST, NULL},
	{"Resets", FIELD_RESET_DATA, (void *) &sRoom.reset_first,
	 (void *) DATA_LIST, NULL},
	{"Exits", FIELD_EXIT_DATA, (void *) &sRoom.exit, (void *) MAX_DIR, NULL},
	{NULL, 0, NULL, NULL, NULL}
};

const struct savetable_type exit_stat_table[] = {
	{"To Room", FIELD_ROOM, (void *) &sExit.u1.to_room, NULL, NULL},
	{"Exit Flags", FIELD_FLAGSTRING, (void *) &sExit.exit_info,
	 (void *) exit_flags, (void *) 0},
	{"Key", FIELD_LONG, (void *) &sExit.key, (void *) 0, NULL},
	{"Keyword", FIELD_STRING, (void *) &sExit.keyword, NULL, NULL},
	{"Description", FIELD_STRING, (void *) &sExit.description, NULL, NULL},
	{NULL, 0, NULL, NULL, NULL}
};

const struct savetable_type obj_stat_table[] = {
	{"In Object", FIELD_OBJ, (void *) &sObj.in_obj, (void *) DATA_NAME, NULL},
	{"On", FIELD_OBJ, (void *) &sObj.on, (void *) DATA_NAME, NULL},

	{"Carried by", FIELD_CHARDATA, (void *) &sObj.carried_by,
	 (void *) DATA_NAME, NULL},

	{"Extra Descriptions", FIELD_EXDESC,
	 (void *) &sObj.first_extra_descr, (void *) DATA_LIST, NULL},
	{"In Room", FIELD_ROOM, (void *) &sObj.in_room, (void *) DATA_NAME, NULL},

	{"Prog Target", FIELD_CHARDATA, (void *) &sObj.oprog_target,
	 (void *) DATA_NAME, NULL},
	{"Prog Delay", FIELD_INT, (void *) &sObj.oprog_delay, (void *) 0, NULL},
	{"Enchanted", FIELD_BOOL, (void *) &sObj.enchanted, NULL, NULL},
	{"Owner", FIELD_STRING, (void *) &sObj.owner, NULL, NULL},
	{"Name", FIELD_STRING, (void *) &sObj.name, NULL, NULL},
	{"Short", FIELD_STRING, (void *) &sObj.short_descr, NULL, NULL},
	{"Long", FIELD_STRING, (void *) &sObj.description, NULL, NULL},

	{"Type", FIELD_INT_FLAGSTRING, (void *) &sObj.item_type,
	 (void *) type_flags, NULL},
	{"Extra", FIELD_FLAGSTRING, (void *) &sObj.extra_flags,
	 (void *) extra_flags, (void *) 0},
	{"Wear", FIELD_FLAGSTRING, (void *) &sObj.wear_flags, (void *) wear_flags,
	 (void *) 0},
	{"Worn on", FIELD_INT_FLAGSTRING, (void *) &sObj.wear_loc,
	 (void *) wear_loc_flags, (void *) 0},
	{"Weight", FIELD_INT, (void *) &sObj.weight, (void *) 0, NULL},
	{"Cost", FIELD_LONG, (void *) &sObj.cost, (void *) 0, NULL},
	{"Level", FIELD_INT, (void *) &sObj.level, NULL, NULL},
	{"Condition", FIELD_INT, (void *) &sObj.condition, (void *) 100, NULL},
	{"Timer", FIELD_INT, (void *) &sObj.timer, (void *) 0, NULL},
	{"Material", FIELD_STRING, (void *) &sObj.material, (void *) "unknown", NULL},
	{"Values", FIELD_LONG_ARRAY, (void *) &sObj.value, (void *) 5, NULL},

	{"Index Data", FIELD_OBJINDEX, (void *) &sObj.pIndexData, NULL, NULL},
	{NULL, 0, NULL, NULL, NULL}
};

const struct savetable_type pobj_stat_table[] = {

	{"Extra Descriptions", FIELD_EXDESC,
	 (void *) &spObj.first_extra_descr, (void *) DATA_LIST, NULL},
	{"Area", FIELD_AREA, (void *) &spObj.area, NULL, NULL},

	{"Programs", FIELD_PROG_LIST, (void *) &spObj.first_oprog,
	 (void *) DATA_LIST, NULL},
	{"Prog Flags", FIELD_FLAGSTRING, (void *) &spObj.oprog_flags,
	 (void *) oprog_flags, NULL},
	{"Name", FIELD_STRING, (void *) &spObj.name, NULL, NULL},
	{"Short", FIELD_STRING, (void *) &spObj.short_descr, NULL, NULL},
	{"Long", FIELD_STRING, (void *) &spObj.description, NULL, NULL},
	{"Vnum", FIELD_LONG, (void *) &spObj.vnum, NULL, NULL},

	{"Type", FIELD_INT_FLAGSTRING, (void *) &spObj.item_type,
	 (void *) type_flags, NULL},
	{"Extra", FIELD_FLAGSTRING, (void *) &spObj.extra_flags,
	 (void *) extra_flags, (void *) 0},
	{"Wear", FIELD_FLAGSTRING, (void *) &spObj.wear_flags, (void *) wear_flags,
	 (void *) 0},
	{"Level", FIELD_INT, (void *) &spObj.level, NULL, NULL},
	{"Condition", FIELD_INT, (void *) &spObj.condition, (void *) 100, NULL},
	{"Count", FIELD_INT, (void *) &spObj.count, (void *) 0, NULL},
	{"Weight", FIELD_INT, (void *) &spObj.weight, (void *) 0, NULL},
	{"Cost", FIELD_LONG, (void *) &spObj.cost, (void *) 0, NULL},

	{"Material", FIELD_STRING, (void *) &spObj.material, (void *) "unknown",
	 NULL},
	{"Values", FIELD_LONG_ARRAY, (void *) &spObj.value, (void *) 5, NULL},

	{"Affects", FIELD_AFFECT, (void *) &spObj.first_affect,
	 (void *) DATA_LIST, NULL},
	{NULL, 0, NULL, NULL, NULL}
};

const struct savetable_type area_stat_table[] = {
	{"File", FIELD_STRING, (void *) &sArea.file_name, NULL, NULL},
	{"Name", FIELD_STRING, (void *) &sArea.name, NULL, NULL},
	{"Credits", FIELD_STRING, (void *) &sArea.credits, NULL, NULL},
	{"Age", FIELD_INT, (void *) &sArea.age, NULL, NULL},
	{"Players", FIELD_INT, (void *) &sArea.nplayer, (void *) 0, NULL},
	{"Min Vnum", FIELD_LONG, (void *) &sArea.min_vnum, NULL, NULL},
	{"Max Vnum", FIELD_LONG, (void *) &sArea.max_vnum, NULL, NULL},
	{"Empty?", FIELD_BOOL, (void *) &sArea.empty, (void *) FALSE, NULL},
	{"Builders", FIELD_STRING, (void *) &sArea.builders, NULL, NULL},
	{"Vnum", FIELD_INT, (void *) &sArea.vnum, NULL, NULL},

	{"Flags", FIELD_FLAGSTRING, (void *) &sArea.area_flags,
	 (void *) area_flags, (void *) 0},
	{"Security", FIELD_INT, (void *) &sArea.security, NULL, NULL},
	{"Min Level", FIELD_INT, (void *) &sArea.min_level, (void *) 0, NULL},
	{"Max Level", FIELD_INT, (void *) &sArea.max_level, (void *) MAX_LEVEL, NULL},
	{"Lvl Comment", FIELD_STRING, (void *) &sArea.lvl_comment, NULL, NULL},
	{"Version", FIELD_INT, (void *) &sArea.version, (void *) AREA_VERSION, NULL},
	{"Climate", FIELD_FUNCTION, NULL, (void *) ts_weather, NULL},
	{NULL, 0, NULL, NULL, NULL}
};

char *format_field(const char *field, int max)
{
	return FORMATF("%-*s", max, field);
}

void show_stat_table(CHAR_DATA * ch, BUFFER * output, void *typebase,
					 const struct savetable_type *table, void *puntero,
					 int recurse)
{
	const struct savetable_type *temp;
	const char **pstring;
	int *pint;
	long *plong;
	int **array;
	long **larray;
	float *floater;
	double *doubler;
	char *pchar;
	char *pstrsz;
	time_t *ptime;
	RW_FUNC *function;
	CHAR_DATA **chdata;
	SPEC_FUN **spdata;
	MOB_INDEX_DATA **mobindex;
	RACE_DATA **racedata;
	DEITY_DATA **deitydata;
	AREA_DATA **areadata;
	ROOM_INDEX_DATA **roomdata;
	CLAN_DATA **clandata;
	OBJ_DATA **objdata;
	AFFECT_DATA **affdata;
	const char *string;
	flag_t *upentero;
	bool *pbool;
	RANK_DATA *rdata;
	SHOP_DATA **shopdata;
	DESCRIPTOR_DATA **descdata;
	OBJ_INDEX_DATA **objindex;
	EXTRA_DESCR_DATA **eddata, *edlist;
	RESET_DATA **resdata, *r;
	EXIT_DATA ***exdata;
	PROG_LIST **progdata;
	PC_DATA **pcdata;
	const struct flag_type *flagtable;
	TS_FUNC *tsfunc;
	int cnt = 0, i, length = 0;
	char buf[MSL * 3];
	init_cols(ch, 2);

	for (temp = table; !IS_NULLSTR(temp->field); temp++)
	{
		i = strlen_color(temp->field);
		if (i > length)
			length = i;
	}
	for (temp = table; !IS_NULLSTR(temp->field); temp++)
	{
		switch (temp->type_field)
		{
		default:
			bugf("type_field %d invalid, field %s",
				 temp->type_field, temp->field);
			break;

		case FIELD_STRING:
			pstring =
				(const char **) ((int) temp->puntero_field - (int) typebase +
								 (int) puntero);

			if (!IS_NULLSTR(*pstring)
				&& str_cmp((const char *) temp->argument, *pstring))
			{
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   *pstring));
			}
			break;

		case FIELD_STRING_SIZE:
			pstrsz =
				(char *) ((int) temp->puntero_field - (int) typebase +
						  (int) puntero);
			string = &(*pstrsz);
			if (!IS_NULLSTR(string)
				&& str_cmp((const char *) temp->argument, string))
			{
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   string));
			}
			break;

		case FIELD_CHAR:
			pchar =
				(char *) ((int) temp->puntero_field - (int) typebase +
						  (int) puntero);

			if (*pchar != !temp->argument ? '\0' : *(char *) temp->argument)
				print_cols(bprint, output, FORMATF("%s: %c{x",
												   format_field(temp->field,
																length),
												   *pchar));
			break;

		case FIELD_INT:
			pint =
				(int *) ((int) temp->puntero_field - (int) typebase +
						 (int) puntero);
			if (*pint != (int) temp->argument)
				print_cols(bprint, output, FORMATF("%s: %d{x",
												   format_field(temp->field,
																length),
												   *pint));
			break;

		case FIELD_INT_FUNCTION:
			pint =
				(int *) ((int) temp->puntero_field - (int) typebase +
						 (int) puntero);
			tsfunc = (TS_FUNC *) temp->array_arg;

			if (*pint != (int) temp->argument)
			{
				if (tsfunc != NULL)
					string = (*tsfunc) (ch, pint);
				else
					string = FORMATF("%d", *pint);

				if (!IS_NULLSTR(string))
					print_cols(bprint, output, FORMATF("%s: %s{x",
													   format_field(temp->field,
																	length),
													   string));
			}
			break;

		case FIELD_FLOAT:
			floater =
				(float *) ((int) temp->puntero_field - (int) typebase +
						   (int) puntero);
			if (temp->argument && *floater != *(float *) temp->argument)
			{
				if (temp->array_arg != NULL)
					print_cols(bprint, output, FORMATF("%s: %.*f{x",
													   format_field(temp->field,
																	length),
													   (int) temp->array_arg,
													   *floater));
				else
					print_cols(bprint, output,
							   FORMATF("%s: %f{x",
									   format_field(temp->field, length),
									   *floater));
			}
			break;

		case FIELD_DOUBLE:
			doubler = (double *) ((int) temp->puntero_field - (int) typebase +
								  (int) puntero);
			if (temp->argument && *doubler != *(double *) temp->argument)
			{
				if (temp->array_arg != NULL)
					print_cols(bprint, output, FORMATF("%s: %.*f{x",
													   format_field(temp->field,
																	length),
													   (int) temp->array_arg,
													   *doubler));
				else
					print_cols(bprint, output,
							   FORMATF("%s: %f{x",
									   format_field(temp->field, length),
									   *doubler));
			}
			break;

		case FIELD_LONG:
			plong =
				(long *) ((int) temp->puntero_field - (int) typebase +
						  (int) puntero);
			if (temp->argument != NULL || *plong != (long) temp->argument)
				print_cols(bprint, output, FORMATF("%s: %ld{x",
												   format_field(temp->field,
																length),
												   *plong));
			break;

		case FIELD_TIME:
			ptime =
				(time_t *) ((int) temp->puntero_field - (int) typebase +
							(int) puntero);
			if (*ptime != (time_t) temp->array_arg)
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   temp->argument !=
												   NULL ? timestr(*ptime,
																  FALSE) :
												   str_time(*ptime, -1, NULL)));
			break;

		case FIELD_FUNCTION_INT_TO_STR:
			function = (RW_FUNC *) temp->argument;
			pint =
				(int *) ((int) temp->puntero_field - (int) typebase +
						 (int) puntero);
			if ((*function) (action_write, pint, &string) == FALSE)
				bugf("field %s invalid, string %s", temp->field, string);
			if (*pint != (int) temp->array_arg)
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   string));
			break;

		case FIELD_FLAGSTRING:
			flagtable = (const struct flag_type *) temp->argument;
			upentero =
				(flag_t *) ((int) temp->puntero_field - (int) typebase +
							(int) puntero);
			if (flagtable == act_flags && table == char_stat_table
				&& !IS_SET(*upentero, ACT_IS_NPC))
				flagtable = plr_flags;
			if (*upentero !=
				(temp->array_arg == NULL ? 0 : (*(flag_t *) temp->array_arg)))
				print_cols(bprint, output,
						   FORMATF("%s: %s{x",
								   format_field(temp->field, length),
								   flag_string(flagtable, *upentero)));
			break;

		case FIELD_INT_FLAGSTRING:
			flagtable = (const struct flag_type *) temp->argument;
			pint =
				(int *) ((int) temp->puntero_field - (int) typebase +
						 (int) puntero);
			if (*pint != (int) temp->array_arg)
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   flag_string(flagtable,
															   *pint)));
			break;

		case FIELD_FLAGVECTOR:
			upentero =
				(flag_t *) ((int) temp->puntero_field - (int) typebase +
							(int) puntero);
			if (*upentero !=
				(temp->argument == NULL ? 0 : (*(flag_t *) temp->argument)))
				print_cols(bprint, output,
						   FORMATF("%s: %s{x",
								   format_field(temp->field, length),
								   fwrite_flags(*upentero)));
			break;

		case FIELD_BOOL:
			pbool =
				(bool *) ((int) temp->puntero_field - (int) typebase +
						  (int) puntero);
			if (*pbool != (bool) temp->argument)
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   (*pbool ==
													TRUE) ? "TRUE" : "FALSE"));
			break;

		case FIELD_INT_ARRAY:
			pint =
				(int *) ((int) temp->puntero_field - (int) typebase +
						 (int) puntero);
			buf[0] = NUL;
			for (i = 0; i < (int) temp->argument; i++)
				if (pint[i] != (int) temp->array_arg)
					sprintf(buf + strlen(buf), ", %d", pint[i]);
			if (buf[0] != NUL)
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   &buf[2]));
			break;

		case FIELD_INT_FUNC_ARRAY:
			pint =
				(int *) ((int) temp->puntero_field - (int) typebase +
						 (int) puntero);
			tsfunc = (TS_FUNC *) temp->array_arg;
			buf[0] = NUL;
			for (i = 0; i < (int) temp->argument; i++)
			{
				if (tsfunc)
					string = (*tsfunc) (ch, &pint[i]);
				else
					string = FORMATF("%d", pint[i]);
				if (!IS_NULLSTR(string))
					sprintf(buf + strlen(buf), ", %s", string);
			}
			if (buf[0] != NUL)
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   &buf[2]));
			break;

		case FIELD_INT_ALLOC_ARRAY:
			array =
				(int **) ((int) temp->puntero_field - (int) typebase +
						  (int) puntero);
			buf[0] = NUL;
			for (i = 0; i < *(int *) temp->argument; i++)
				if ((*array)[i] != (int) temp->array_arg)
					sprintf(buf + strlen(buf), ", %d", (*array)[i]);
			if (buf[0] != NUL)
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   &buf[2]));
			break;

		case FIELD_LONG_ALLOC_ARRAY:
			larray = (long **) ((int) temp->puntero_field - (int) typebase +
								(int) puntero);
			buf[0] = NUL;
			for (i = 0; i < *(int *) temp->argument; i++)
				if ((*larray)[i] != (long) temp->array_arg)
					sprintf(buf + strlen(buf), ", %ld", (*larray)[i]);
			if (buf[0] != NUL)
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   &buf[2]));
			break;

		case FIELD_LONG_ARRAY:
			plong =
				(long *) ((int) temp->puntero_field - (int) typebase +
						  (int) puntero);
			buf[0] = NUL;
			for (i = 0; i < (int) temp->argument; i++)
				if (plong[i] != (long) temp->array_arg)
					sprintf(buf + strlen(buf), ", %ld", plong[i]);
			if (buf[0] != NUL)
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   &buf[2]));
			break;

		case FIELD_STRING_ARRAY:
		case FIELD_STRING_ARRAY_NULL:
			pstring =
				(const char **) ((int) temp->puntero_field - (int) typebase +
								 (int) puntero);
			buf[0] = NUL;
			for (i = 0; i < (int) temp->argument; i++)
			{
				if (!IS_NULLSTR(pstring[i]))
					sprintf(buf + strlen(buf), "%d) %s\n\r", i + 1, pstring[i]);
			}
			if (buf[0] != NUL)
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length), buf));
			break;

		case FIELD_BOOL_ARRAY:
			pbool =
				(bool *) ((int) temp->puntero_field - (int) typebase +
						  (int) puntero);
			buf[0] = NUL;
			for (i = 0; i < (int) temp->argument; i++)
				sprintf(buf + strlen(buf), ", %s",
						pbool[i] == TRUE ? "TRUE" : "FALSE");
			if (buf[0] != NUL)
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   &buf[2]));
			break;

		case FIELD_DICE:
			pint =
				(int *) ((int) temp->puntero_field - (int) typebase +
						 (int) puntero);
			print_cols(bprint, output, FORMATF("%s: %dd%d+%d{x",
											   format_field(temp->field,
															length),
											   pint[DICE_NUMBER],
											   pint[DICE_TYPE],
											   pint[DICE_BONUS]));
			break;

		case FIELD_RANK_DATA:
			rdata =
				(RANK_DATA *) ((int) temp->puntero_field - (int) typebase +
							   (int) puntero);
			for (i = 0; i < (int) temp->argument; i++)
			{
				print_cols(bprint, output, FORMATF("%s: %d %s{x",
												   format_field(temp->field,
																length), i + 1,
												   rdata[i].rankname));
			}
			break;

		case FIELD_CHARDATA:
			chdata =
				(CHAR_DATA **) ((int) temp->puntero_field - (int) typebase +
								(int) puntero);

			if (chdata && *chdata)
			{
				if ((int) temp->argument == DATA_LIST)
				{
					CHAR_DATA *list;
					buf[0] = NUL;
					for (list = *chdata; list != NULL;
						 list = list->next_in_room)
						sprintf(buf + strlen(buf), ", %s",
								IS_NPC(list) ? list->short_descr : list->name);
					if (buf[0] != NUL)
						print_cols(bprint, output, FORMATF("%s: %s{x",
														   format_field
														   (temp->field,
															length), &buf[2]));
				}
				else if ((int) temp->argument == DATA_STAT && recurse == 0)
				{
					if (!done_newline)
						bprintln(output, "");
					bprintln(output, stringf
							 (ch, 0, ALIGN_CENTER, "-", "[CHAR DATA]"));
					show_stat_table(ch, output, &sChar, char_stat_table,
									*chdata, recurse + 1);
				}
				else
				{
					if (!IS_NPC(*chdata))
						print_cols(bprint, output, FORMATF("%s: %s{x",
														   format_field
														   (temp->field,
															length),
														   IS_NPC(*chdata)
														   ?
														   (*chdata)->short_descr
														   : (*chdata)->name));
					else
						print_cols(bprint, output,
								   FORMATF("%s: %s [%ld]{x",
										   format_field(temp->field, length),
										   IS_NPC((*chdata))
										   ? (*chdata)->short_descr
										   : (*chdata)->name,
										   (*chdata)->pIndexData->vnum));
				}
			}
			break;

		case FIELD_EXDESC:
			eddata =
				(EXTRA_DESCR_DATA **) ((int) temp->puntero_field -
									   (int) typebase + (int) puntero);

			buf[0] = NUL;
			for (edlist = *eddata; edlist != NULL; edlist = edlist->next)
				sprintf(buf + strlen(buf), ", %s", edlist->keyword);
			if (buf[0] != NUL)
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   &buf[2]));
			break;

		case FIELD_FUNCTION:
			if ((tsfunc = (TS_FUNC *) temp->argument) != NULL)
			{
				string = (*tsfunc) (ch, puntero);
				if (!IS_NULLSTR(string))
					print_cols(bprint, output, FORMATF("%s: %s{x",
													   format_field(temp->field,
																	length),
													   string));
			}
			break;

		case FIELD_RESET_DATA:
			resdata =
				(RESET_DATA **) ((int) temp->puntero_field - (int) typebase +
								 (int) puntero);

			buf[0] = NUL;
			for (r = *resdata; r != NULL; r = r->next)
				sprintf(buf + strlen(buf), ", [%c-%ld]", r->command, r->arg1);
			if (buf[0] != NUL)
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   &buf[2]));
			break;

		case FIELD_EXIT_DATA:
			exdata =
				(EXIT_DATA ***) ((int) temp->puntero_field - (int) typebase +
								 (int) puntero);

			if ((int) temp->argument == DATA_STAT || recurse == 0)
			{
				for (i = 0; i < (int) temp->argument; i++)
				{
					if (*exdata && (*exdata)[i] != NULL)
					{
						if (!done_newline)
							bprintln(output, "");
						bprintln(output, stringf
								 (ch, 0, ALIGN_CENTER, "-",
								  FORMATF("[%s]", dir_name[i])));
						show_stat_table(ch, output, &sExit, exit_stat_table,
										*exdata, recurse + 1);
					}
				}
			}
			break;

		case FIELD_AFFECT:
			affdata =
				(AFFECT_DATA **) ((int) temp->puntero_field - (int) typebase +
								  (int) puntero);

			if (affdata && *affdata)
			{
				AFFECT_DATA *aff;
				int cnt;

				for (cnt = 0, aff = *affdata; aff != NULL; aff = aff->next)
				{
					if (cnt == 0)
					{
						if (!done_newline)
							bprintln(output, "");
						bprintln(output,
								 "{cNumber Modifier Affects      Special Type{x");
						bprintln(output,
								 "{c------ -------- -------      ------------{x");
					}
					if (aff->bitvector)
						bprintf(output, "[%4d] %-8d %-12s %-7s %s{x", cnt,
								aff->modifier,
								flag_string(apply_flags,
											aff->location),
								flag_string(apply_types,
											aff->where),
								flag_string(bitvector_type
											[aff->where].table,
											aff->bitvector));
					else
					{
						bprintf(output, "[%4d] %-8d %-12s{x", cnt,
								aff->modifier,
								flag_string(apply_flags, aff->location));
					}
					bprintln(output, "");
					cnt++;
				}
			}
			break;

		case FIELD_PROG_LIST:
			progdata =
				(PROG_LIST **) ((int) temp->puntero_field - (int) typebase +
								(int) puntero);

			if (progdata && *progdata)
			{
				PROG_LIST *list;
				int cnt;

				for (cnt = 0, list = *progdata; list != NULL; list = list->next)
				{
					if (cnt == 0)
					{
						if (!done_newline)
							bprintln(output, "");
						bprintln(output, "{c Number Vnum Trigger Phrase{x");
						bprintln(output, "{c ------ ---- ------- ------{x");
					}

					bprintf(output, "{c[%5d]{y %4ld %7s %s{x", cnt,
							list->vnum,
							prog_type_to_name(list->trig_type),
							list->trig_phrase);
					bprintln(output, "");
					cnt++;
				}
			}

			break;

		case FIELD_DESC:
			descdata =
				(DESCRIPTOR_DATA **) ((int) temp->puntero_field -
									  (int) typebase + (int) puntero);

			if (descdata && *descdata)
			{
				if ((int) temp->argument == DATA_STAT && recurse == 0)
				{
					if (!done_newline)
						bprintln(output, "");
					bprintln(output, stringf
							 (ch, 0, ALIGN_CENTER, "-", "[DESCRIPTOR DATA]"));
					show_stat_table(ch, output, &sDesc, desc_stat_table,
									*descdata, recurse + 1);
				}
				else
				{
					print_cols(bprint, output, FORMATF("%s: %d{x",
													   format_field(temp->field,
																	length),
													   (*descdata)->descriptor));
				}
			}
			break;

		case FIELD_SPEC_FUN:
			spdata = (SPEC_FUN **) ((int) temp->puntero_field - (int) typebase +
									(int) puntero);

			if (spdata && *spdata)
			{
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   spec_name((*spdata))));
			}
			break;

		case FIELD_SHOP:
			shopdata =
				(SHOP_DATA **) ((int) temp->puntero_field - (int) typebase +
								(int) puntero);

			if (shopdata && *shopdata)
			{
				if (recurse == 0)
				{
					if (!done_newline)
						bprintln(output, "");
					bprintln(output, stringf
							 (ch, 0, ALIGN_CENTER, "-", "[SHOP DATA]"));
					show_stat_table(ch, output, &sShop, shop_stat_table,
									*shopdata, recurse + 1);
				}
			}
			break;

		case FIELD_PCDATA:
			pcdata =
				(PC_DATA **) ((int) temp->puntero_field - (int) typebase +
							  (int) puntero);

			if (pcdata && *pcdata)
			{
				if (recurse == 0)
				{
					if (!done_newline)
						bprintln(output, "");
					bprintln(output, stringf
							 (ch, 0, ALIGN_CENTER, "-", "[PLAYER DATA]"));
					show_stat_table(ch, output, &sPC, pc_stat_table, *pcdata,
									recurse + 1);
				}
			}
			break;

		case FIELD_MOBINDEX:
			mobindex =
				(MOB_INDEX_DATA **) ((int) temp->puntero_field -
									 (int) typebase + (int) puntero);

			if (mobindex && *mobindex)
			{
				if (recurse == 0)
				{
					if (!done_newline)
						bprintln(output, "");
					bprintln(output, stringf
							 (ch, 0, ALIGN_CENTER, "-", "[MOBILE DATA]"));
					show_stat_table(ch, output, &sMob, mob_stat_table,
									*mobindex, recurse + 1);
				}
			}
			break;

		case FIELD_OBJINDEX:
			objindex =
				(OBJ_INDEX_DATA **) ((int) temp->puntero_field -
									 (int) typebase + (int) puntero);

			if (objindex && *objindex)
			{
				if (recurse == 0)
				{
					if (!done_newline)
						bprintln(output, "");
					bprintln(output, stringf
							 (ch, 0, ALIGN_CENTER, "-", "[OBJECT INDEX DATA]"));
					show_stat_table(ch, output, &spObj, pobj_stat_table,
									*objindex, recurse + 1);
				}
			}
			break;

		case FIELD_RACE:
			racedata =
				(RACE_DATA **) ((int) temp->puntero_field - (int) typebase +
								(int) puntero);

			if (racedata && *racedata)
			{
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   (*racedata)->name));
			}
			break;

		case FIELD_DEITY:
			deitydata =
				(DEITY_DATA **) ((int) temp->puntero_field - (int) typebase +
								 (int) puntero);

			if (deitydata && *deitydata)
			{
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   (*deitydata)->name));
			}
			break;

		case FIELD_AREA:
			areadata =
				(AREA_DATA **) ((int) temp->puntero_field - (int) typebase +
								(int) puntero);

			if (areadata && *areadata)
			{
				if ((int) temp->argument == DATA_STAT && recurse == 0)
				{
					if (!done_newline)
						bprintln(output, "");
					bprintln(output, stringf
							 (ch, 0, ALIGN_CENTER, "-", "[AREA DATA]"));
					show_stat_table(ch, output, &sArea, area_stat_table,
									*areadata, recurse + 1);
				}
				else
				{
					print_cols(bprint, output, FORMATF("%s: %s{x",
													   format_field(temp->field,
																	length),
													   (*areadata)->name));
				}
			}
			break;
		case FIELD_ROOM:
			roomdata =
				(ROOM_INDEX_DATA **) ((int) temp->puntero_field -
									  (int) typebase + (int) puntero);

			if (roomdata && *roomdata)
			{
				if ((int) temp->argument == DATA_STAT && recurse == 0)
				{
					if (!done_newline)
						bprintln(output, "");
					bprintln(output, stringf
							 (ch, 0, ALIGN_CENTER, "-", "[ROOM DATA]"));
					show_stat_table(ch, output, &sRoom, room_stat_table,
									*roomdata, recurse + 1);
				}
				else
				{
					if ((*roomdata)->clan == NULL)
						print_cols(bprint, output, FORMATF("%s: %s [%ld]{x",
														   format_field
														   (temp->field,
															length),
														   (*roomdata)->name,
														   (*roomdata)->vnum));
					else
						print_cols(bprint, output,
								   FORMATF("%s: %s [%ld] (owned by %s){x",
										   format_field(temp->field, length),
										   (*roomdata)->name, (*roomdata)->vnum,
										   (*roomdata)->clan->name));
				}
			}
			break;

		case FIELD_CLAN:
			clandata =
				(CLAN_DATA **) ((int) temp->puntero_field -
								(int) typebase + (int) puntero);

			if (clandata && *clandata)
			{
				print_cols(bprint, output, FORMATF("%s: %s{x",
												   format_field(temp->field,
																length),
												   (*clandata)->who_name));
			}
			break;

		case FIELD_OBJ:
			objdata =
				(OBJ_DATA **) ((int) temp->puntero_field -
							   (int) typebase + (int) puntero);

			if (objdata && *objdata)
			{
				if ((int) temp->argument == DATA_LIST)
				{
					OBJ_DATA *list;

					buf[0] = NUL;
					for (list = *objdata; list != NULL;
						 list = list->next_content)
						sprintf(buf + strlen(buf), ", %s", list->short_descr);
					if (buf[0] != NUL)
						print_cols(bprint, output, FORMATF("%s: %s{x",
														   format_field
														   (temp->field,
															length), &buf[2]));
				}
				else if ((int) temp->argument == DATA_STAT && recurse == 0)
				{
					if (!done_newline)
						bprintln(output, "");
					bprintln(output, stringf
							 (ch, 0, ALIGN_CENTER, "-", "[OBJ DATA]"));
					show_stat_table(ch, output, &sObj, obj_stat_table, *objdata,
									recurse + 1);
				}
				else
				{
					print_cols(bprint, output, FORMATF("%s: %s [%ld]{x",
													   format_field(temp->field,
																	length),
													   (*objdata)->short_descr,
													   (*objdata)->
													   pIndexData->vnum));
				}
			}
			break;

		case FIELD_INUTIL:
			break;
		}

		cnt++;
	}
	if (!done_newline && !recurse)
		bprintln(output, "");
};

CH_CMD(do_stat_char)
{
	CHAR_DATA *victim;
	BUFFER *output;

	if (IS_NULLSTR(argument))
	{
		chprintln(ch, "Stat who?");
		return;
	}

	if ((victim = get_char_world(ch, argument)) == NULL)
	{
		chprintln(ch, "No such character.");
		return;
	}

	output = new_buf();

	bprintln(output, draw_line(ch, "<>", 0));

	show_stat_table(ch, output, &sChar, char_stat_table, victim, 0);

	bprintln(output, draw_line(ch, "<>", 0));
	sendpage(ch, buf_string(output));
	free_buf(output);
}

CH_CMD(do_stat_obj)
{
	OBJ_DATA *obj;
	BUFFER *output;

	if (IS_NULLSTR(argument))
	{
		chprintln(ch, "Stat what?");
		return;
	}

	if ((obj = get_obj_world(ch, argument)) == NULL
		|| (obj = get_obj_here(ch, NULL, argument)) == NULL)
	{
		chprintln(ch, "No such object.");
		return;
	}

	output = new_buf();

	bprintln(output, draw_line(ch, "<>", 0));

	show_stat_table(ch, output, &sObj, obj_stat_table, obj, 0);

	bprintln(output, draw_line(ch, "<>", 0));
	sendpage(ch, buf_string(output));
	free_buf(output);
}

CH_CMD(do_stat_room)
{
	ROOM_INDEX_DATA *room;
	BUFFER *output;

	if ((room = get_room_index(atol(argument))) == NULL)
	{
		room = ch->in_room;
	}

	output = new_buf();

	bprintln(output, draw_line(ch, "<>", 0));

	show_stat_table(ch, output, &sRoom, room_stat_table, room, 0);

	bprintln(output, draw_line(ch, "<>", 0));
	sendpage(ch, buf_string(output));
	free_buf(output);
}

CH_CMD(do_stat_desc)
{
	DESCRIPTOR_DATA *d;
	CHAR_DATA *victim;
	BUFFER *output;

	if (IS_NULLSTR(argument))
	{
		chprintln(ch, "Stat who?");
		return;
	}

	d = NULL;
	if ((victim = get_char_world(ch, argument)) == NULL || victim->desc == NULL)
	{
		if (is_number(argument))
		{
			for (d = descriptor_first; d; d = d->next)
				if (atoi(argument) == d->descriptor)
					break;
		}
		if (!d)
		{
			chprintln(ch, "No such character.");
			return;
		}
	}
	else
		d = victim->desc;

	output = new_buf();

	bprintln(output, draw_line(ch, "<>", 0));

	show_stat_table(ch, output, &sDesc, desc_stat_table, d, 0);

	bprintln(output, draw_line(ch, "<>", 0));
	sendpage(ch, buf_string(output));
	free_buf(output);
}

CH_CMD(do_stat_area)
{
	AREA_DATA *area;
	BUFFER *output;

	area = ch->in_room->area;

	output = new_buf();

	bprintln(output, draw_line(ch, "<>", 0));

	show_stat_table(ch, output, &sArea, area_stat_table, area, 0);

	bprintln(output, draw_line(ch, "<>", 0));
	sendpage(ch, buf_string(output));
	free_buf(output);
}

CH_CMD(do_stat_help)
{
	chprintln(ch, "Syntax(s): stat char <name>\n\r"
			  "         : stat desc <desc>\n\r"
			  "         : stat room <name>\n\r"
			  "         : stat area <name>\n\r"
			  "         : stat object <name>\n\r" "         : stat old <args>");
}

CH_CMD(do_stat)
{
	vinterpret(ch, argument, "char", do_stat_char, "room",
			   do_stat_room, "descriptor", do_stat_desc,
			   "object", do_stat_obj, "area", do_stat_area,
			   "old", do_old_stat, NULL, do_stat_help);
}