/**************************************************************************
* 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 "olc.h"
#include "recycle.h"
#include "lookup.h"
#include "interp.h"
#include "globals.h"
#include "tables.h"
#include "tablesave.h"
CHAR_DATA xChar;
PC_DATA xPc;
DESCRIPTOR_DATA xDesc;
OBJ_DATA xObj2;
typedef enum
{ SET_CHAR, SET_PC, SET_DESC, SET_OBJ }
set_t;
struct set_comm_type
{
const char *name;
void *argument;
ED_FUN *function;
const void *parameter;
VALIDATE_FUN *validator;
};
const struct set_comm_type char_set_comm_table[] = {
{"name", (void *) &xChar.name, olced_str, NULL, NULL},
{"short", (void *) &xChar.short_descr, olced_str, NULL, NULL},
{"long", (void *) &xChar.long_descr, olced_str, (void *) 1, NULL},
{"description", (void *) &xChar.description, olced_desc, NULL, NULL},
{"id", (void *) &xChar.id, olced_time, NULL, NULL},
{"class", (void *) &xChar.Class, olced_mclass, (void *) MAX_REMORT,
NULL},
{"stance", (void *) &xChar.stance, olced_stance, (void *) MAX_STANCE, NULL},
{"stats", (void *) &xChar.perm_stat, olced_stats, (void *) STAT_MAX, NULL},
{"damage", (void *) &xChar.damage[0], olced_dice, NULL, NULL},
{"damtype", (void *) &xChar.dam_type, olced_poslookup,
(void *) attack_lookup, NULL},
{"startpos", (void *) &xChar.start_pos, olced_flag, (void *) position_flags,
NULL},
{"defpos", (void *) &xChar.default_pos, olced_flag, (void *) position_flags,
NULL},
{"deity", (void *) &xChar.deity, olced_deity, NULL, NULL},
{"master", (void *) &xChar.master, olced_getchar, NULL, NULL},
{"leader", (void *) &xChar.leader, olced_getchar, NULL, NULL},
{"fighting", (void *) &xChar.fighting, olced_getchar, NULL, NULL},
{"reply", (void *) &xChar.reply, olced_getchar, NULL, NULL},
{"pet", (void *) &xChar.pet, olced_getchar, NULL, NULL},
{"hunting", (void *) &xChar.hunting, olced_getchar, NULL, NULL},
{"prompt", (void *) &xChar.prompt, olced_str, NULL, NULL},
{"prefix", (void *) &xChar.prefix, olced_str, NULL, NULL},
{"sex", (void *) &xChar.sex, olced_flag, (void *) sex_flags, NULL},
{"race", (void *) &xChar.race, olced_race, NULL, NULL},
{"level", (void *) &xChar.level, olced_number, NULL, validate_level},
{"trust", (void *) &xChar.trust, olced_number, NULL, validate_level},
{"lines", (void *) &xChar.lines, olced_number, NULL, NULL},
{"idle", (void *) &xChar.timer, olced_number, NULL, NULL},
{"wait", (void *) &xChar.wait, olced_number, NULL, NULL},
{"daze", (void *) &xChar.daze, olced_number, NULL, NULL},
{"hit", (void *) &xChar.hit, olced_number_long, NULL, NULL},
{"maxhit", (void *) &xChar.max_hit, olced_number_long, NULL, NULL},
{"mana", (void *) &xChar.mana, olced_number_long, NULL, NULL},
{"maxmana", (void *) &xChar.max_mana, olced_number_long, NULL, NULL},
{"move", (void *) &xChar.move, olced_number_long, NULL, NULL},
{"maxmove", (void *) &xChar.max_move, olced_number_long, NULL, NULL},
{"gold", (void *) &xChar.gold, olced_number_long, NULL, NULL},
{"silver", (void *) &xChar.silver, olced_number_long, NULL, NULL},
{"exp", (void *) &xChar.exp, olced_number, NULL, NULL},
{"act", (void *) &xChar.act, olced_flag, (void *) act_flags, NULL},
{"comm", (void *) &xChar.comm, olced_flag, (void *) comm_flags, NULL},
{"imm", (void *) &xChar.imm_flags, olced_flag, (void *) imm_flags, NULL},
{"res", (void *) &xChar.res_flags, olced_flag, (void *) res_flags, NULL},
{"vuln", (void *) &xChar.vuln_flags, olced_flag, (void *) vuln_flags, NULL},
{"wizi", (void *) &xChar.invis_level, olced_number, NULL, validate_level},
{"incog", (void *) &xChar.incog_level, olced_number, NULL, validate_level},
{"aff", (void *) &xChar.affected_by, olced_flag, (void *) affect_flags,
NULL},
{"position", (void *) &xChar.position, olced_flag, (void *) position_flags,
NULL},
{"practice", (void *) &xChar.practice, olced_number, NULL, NULL},
{"train", (void *) &xChar.train, olced_number, NULL, NULL},
{"align", (void *) &xChar.alignment, olced_number, NULL, validate_align},
{"wimpy", (void *) &xChar.wimpy, olced_number, NULL, NULL},
{"form", (void *) &xChar.form, olced_flag, (void *) form_flags, NULL},
{"rank", (void *) &xChar.rank, olced_number, NULL, NULL},
{"parts", (void *) &xChar.parts, olced_flag, (void *) part_flags, NULL},
{"size", (void *) &xChar.size, olced_flag, (void *) size_flags, NULL},
{"material", (void *) &xChar.material, olced_str, NULL, NULL},
{"hours", (void *) &xChar.played, olced_number, NULL, NULL},
{"off", (void *) &xChar.off_flags, olced_flag, (void *) off_flags, NULL},
{NULL, NULL, NULL, NULL, NULL}
};
const struct set_comm_type pc_set_comm_table[] = {
{"poofin", (void *) &xPc.bamfin, olced_str, NULL, NULL},
{"poofout", (void *) &xPc.bamfout, olced_str, NULL, NULL},
{"title", (void *) &xPc.title, olced_str, NULL, NULL},
{"whodesc", (void *) &xPc.who_descr, olced_str, NULL, NULL},
{"permhit", (void *) &xPc.perm_hit, olced_number_long, NULL, NULL},
{"permmana", (void *) &xPc.perm_mana, olced_number_long, NULL, NULL},
{"permmove", (void *) &xPc.perm_move, olced_number_long, NULL, NULL},
{"truesex", (void *) &xPc.true_sex, olced_flag, (void *) sex_flags,
NULL},
{"points", (void *) &xPc.points, olced_number, NULL, NULL},
{"questpoints", (void *) &xPc.questpoints, olced_number, NULL, NULL},
{"goldbank", (void *) &xPc.gold_bank, olced_number_long, NULL, NULL},
{"silvbank", (void *) &xPc.silver_bank, olced_number_long, NULL, NULL},
{"shares", (void *) &xPc.shares, olced_number, NULL, NULL},
{"condition", (void *) &xPc.condition, olced_array, (void *) 4, NULL},
{"skill", NULL, olced_docomm, (void *) do_sskill, NULL},
{"timezone", (void *) &xPc.timezone, olced_neglookup, (void *) tzone_lookup,
NULL},
{"home", (void *) &xPc.home, olced_larray, (void *) MAX_HOUSE_ROOMS, NULL},
{"hkey", (void *) &xPc.home_key, olced_number, NULL, NULL},
{"trivia", (void *) &xPc.trivia, olced_number, NULL, NULL},
{"security", (void *) &xPc.security, olced_number, NULL, NULL},
{NULL, NULL, NULL, NULL, NULL}
};
const struct set_comm_type desc_set_comm_table[] = {
{"descflags", (void *) &xDesc.d_flags, olced_flag,
(void *) desc_flags, NULL},
{NULL, NULL, NULL, NULL, NULL}
};
const struct set_comm_type obj2_set_comm_table[] = {
{"owner", (void *) &xObj2.owner, olced_str, NULL, NULL},
{"enchanted", (void *) &xObj2.enchanted, olced_bool, NULL, NULL},
{"name", (void *) &xObj2.name, olced_str, NULL, NULL},
{"short", (void *) &xObj2.short_descr, olced_str, NULL, NULL},
{"description", (void *) &xObj2.description, olced_str, (void *) 1, NULL},
{"type", (void *) &xObj2.item_type, olced_flag, (void *) type_flags, NULL},
{"extra", (void *) &xObj2.extra_flags, olced_flag, (void *) extra_flags,
NULL},
{"wear", (void *) &xObj2.wear_flags, olced_flag, (void *) wear_flags, NULL},
{"wloc", (void *) &xObj2.wear_loc, olced_flag,
(void *) wear_loc_strings, NULL},
{"weight", (void *) &xObj2.weight, olced_number, NULL, NULL},
{"cost", (void *) &xObj2.cost, olced_number_long, NULL, NULL},
{"level", (void *) &xObj2.level, olced_number, NULL, validate_level},
{"condition", (void *) &xObj2.condition, olced_number, NULL, NULL},
{"timer", (void *) &xObj2.timer, olced_number, NULL, NULL},
{"material", (void *) &xObj2.material, olced_str, NULL, NULL},
{"value0", (void *) &xObj2.value[0], olced_number_long, NULL, NULL},
{"value1", (void *) &xObj2.value[1], olced_number_long, NULL, NULL},
{"value2", (void *) &xObj2.value[2], olced_number_long, NULL, NULL},
{"value3", (void *) &xObj2.value[3], olced_number_long, NULL, NULL},
{"value4", (void *) &xObj2.value[4], olced_number_long, NULL, NULL},
{NULL, NULL, NULL, NULL, NULL}
};
const struct set_comm_type *get_set_table(set_t type)
{
switch (type)
{
case SET_CHAR:
return char_set_comm_table;
case SET_PC:
return pc_set_comm_table;
case SET_DESC:
return desc_set_comm_table;
case SET_OBJ:
return obj2_set_comm_table;
default:
return NULL;
}
}
void show_set_commands(CHAR_DATA * ch, set_t type)
{
int i;
const struct set_comm_type *table = get_set_table(type);
init_cols(ch, 5);
for (i = 0; table[i].name != NULL; i++)
{
print_cols(chprint, ch, table[i].name);
if (i + 1 % 5 == 0)
chprintln(ch, "");
}
if (!done_newline)
chprintln(ch, "");
if (type == SET_CHAR)
{
show_set_commands(ch, SET_PC);
show_set_commands(ch, SET_DESC);
}
}
bool perform_set(CHAR_DATA * ch, set_t type, const char *argument, void *data)
{
char arg[MIL];
CHAR_DATA *vict = NULL;
PC_DATA *pc;
DESCRIPTOR_DATA *d;
OBJ_DATA *obj;
int temp;
void *puntero;
bool found = FALSE;
const char *logline = argument;
const struct set_comm_type *table = get_set_table(type);
argument = one_argument(argument, arg);
for (temp = 0; table[temp].name && !found; temp++)
{
if (LOWER(arg[0]) == LOWER(table[temp].name[0])
&& !str_prefix(arg, table[temp].name))
{
switch (type)
{
case SET_CHAR:
vict = (CHAR_DATA *) data;
if (table[temp].argument)
puntero =
(void *) ((int) table[temp].argument - (int) &xChar +
(int) vict);
else
puntero = NULL;
if ((*table[temp].function)
(table[temp].name, ch, argument, puntero,
table[temp].parameter, table[temp].validator))
{
if (!IS_NPC(vict))
save_char_obj(vict);
}
found = TRUE;
break;
case SET_PC:
pc = (PC_DATA *) data;
if (table[temp].argument)
puntero =
(void *) ((int) table[temp].argument - (int) &xPc +
(int) pc);
else
puntero = NULL;
(*table[temp].function)
(table[temp].name, ch, argument, puntero,
table[temp].parameter, table[temp].validator);
found = TRUE;
break;
case SET_DESC:
d = (DESCRIPTOR_DATA *) data;
if (table[temp].argument)
puntero =
(void *) ((int) table[temp].argument - (int) &xDesc +
(int) d);
else
puntero = NULL;
(*table[temp].function)
(table[temp].name, ch, argument, puntero,
table[temp].parameter, table[temp].validator);
found = TRUE;
break;
case SET_OBJ:
obj = (OBJ_DATA *) data;
if (table[temp].argument)
puntero =
(void *) ((int) table[temp].argument - (int) &xObj2 +
(int) obj);
else
puntero = NULL;
if ((*table[temp].function)
(table[temp].name, ch, argument, puntero,
table[temp].parameter, table[temp].validator))
{
if (obj->carried_by && !IS_NPC(obj->carried_by))
save_char_obj(obj->carried_by);
}
found = TRUE;
break;
default:
break;
}
}
}
if (!found && type == SET_CHAR)
{
vict = (CHAR_DATA *) data;
if (vict->pcdata)
{
found = perform_set(ch, SET_PC, logline, vict->pcdata);
}
if (!found && vict->desc)
{
found = perform_set(ch, SET_DESC, logline, vict->desc);
}
}
if (!found)
show_set_commands(ch, type);
return found;
}
CH_CMD(do_set_char)
{
DESCRIPTOR_DATA d;
bool result = FALSE;
char name[MIL];
CHAR_DATA *victim;
argument = first_arg(argument, name, FALSE);
if (IS_NULLSTR(name))
{
show_set_commands(ch, SET_CHAR);
chprintln(ch, "Syntax: set char <name> <args...>");
return;
}
if ((victim = get_char_world(ch, name)) == NULL)
{
result = load_char_obj(&d, name);
if (result)
{
if (get_trust(d.character) > get_trust(ch))
{
chprintln(ch, "Sorry, you can't do that.");
free_char(d.character);
return;
}
victim = d.character;
}
else
{
chprintln(ch, "There is no such character.");
free_char(d.character);
return;
}
}
perform_set(ch, SET_CHAR, argument, victim);
if (result)
free_char(victim);
return;
}
CH_CMD(do_set_pc)
{
DESCRIPTOR_DATA d;
bool result = FALSE;
char name[MIL];
CHAR_DATA *victim;
argument = first_arg(argument, name, FALSE);
if (IS_NULLSTR(name))
{
show_set_commands(ch, SET_PC);
chprintln(ch, "Syntax: set player <name> <args...>");
return;
}
if ((victim = get_char_world(ch, name)) == NULL || IS_NPC(victim))
{
result = load_char_obj(&d, name);
if (result)
{
if (get_trust(d.character) > get_trust(ch))
{
chprintln(ch, "Sorry, you can't do that.");
free_char(d.character);
return;
}
victim = d.character;
}
else
{
chprintln(ch, "There is no such player.");
free_char(d.character);
return;
}
}
if (!victim->pcdata)
{
chprintln(ch, "No such player.");
if (result)
free_char(victim);
return;
}
perform_set(ch, SET_PC, argument, victim->pcdata);
if (result)
free_char(victim);
return;
}
CH_CMD(do_set_desc)
{
char name[MIL];
CHAR_DATA *victim;
DESCRIPTOR_DATA *d = NULL;
argument = first_arg(argument, name, FALSE);
if (IS_NULLSTR(name))
{
show_set_commands(ch, SET_DESC);
chprintln(ch, "Syntax: set descriptor <name> <args...>");
return;
}
if ((victim = get_char_world(ch, name)) == NULL || !victim->desc)
{
if (is_number(name))
{
for (d = descriptor_first; d; d = d->next)
if (atoi(name) == d->descriptor)
break;
}
if (!d)
{
chprintln(ch, "Player has no descriptor.");
return;
}
}
else
d = victim->desc;
perform_set(ch, SET_DESC, argument, d);
return;
}
CH_CMD(do_set_obj)
{
OBJ_DATA *obj;
char name[MIL];
argument = first_arg(argument, name, FALSE);
if (IS_NULLSTR(name))
{
show_set_commands(ch, SET_OBJ);
chprintln(ch, "Syntax: set object <name> <args...>");
return;
}
if ((obj = get_obj_world(ch, name)) == NULL)
{
chprintln(ch, "There is no such object.");
return;
}
perform_set(ch, SET_OBJ, argument, obj);
return;
}
CH_CMD(do_set_help)
{
chprintln(ch, "Syntax: set char <name> <option> <value>\n\r"
" : set obj <name> <option> <value>\n\r"
" : set desc <name> <option> <value>\n\r"
" : set skill <name> <skill|all> <value>");
}
CH_CMD(do_set)
{
vinterpret(ch, argument, "character", do_set_char, "mobile", do_set_char,
"player", do_set_pc, "object", do_set_obj, "descriptor",
do_set_desc, "skill", do_sset, "spell", do_sset, NULL,
do_set_help);
}