/***************************************************************************
* File: olc_act.c *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
* *
* This code was freely distributed with the The Isles 1.1 source code, *
* and has been used here for OLC - OLC would not be what it is without *
* all the previous coders who released their source code. *
***************************************************************************/
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <limits.h> /*
* OLC 1.1b
*/
#include "merc.h"
#include "olc.h"
#define MPEDIT( fun ) bool fun( CHAR_DATA *ch, char *argument )
struct olc_help_type
{
char *command;
const void *structure;
char *desc;
};
/*
* Added by Zen. Substitutes the C macros they were making a do_switch bug!
* Return pointers to what is being edited.
*/
bool is_builder( CHAR_DATA *ch, AREA_DATA *area )
{
CHAR_DATA * rch;
/* Will always have a pc ch after this */
rch = ( ch->desc->original ? ch->desc->original : ch->desc->character );
if ( ( rch->pcdata->security >= area->security
|| strstr( area->builders, rch->name )
|| strstr( area->builders, "All" ) ) )
return TRUE;
return FALSE;
}
MOB_INDEX_DATA *edit_mob( CHAR_DATA *ch )
{
return (MOB_INDEX_DATA *) ch->desc->pEdit;
}
OBJ_INDEX_DATA *edit_obj( CHAR_DATA *ch )
{
return (OBJ_INDEX_DATA *) ch->desc->pEdit;
}
ROOM_INDEX_DATA *edit_room( CHAR_DATA *ch )
{
return ch->in_room;
}
AREA_DATA *edit_area( CHAR_DATA *ch )
{
return (AREA_DATA *) ch->desc->pEdit;
}
bool show_version(CHAR_DATA * ch, char *argument)
{
send_to_char(VERSION, ch);
send_to_char("\n\r", ch);
send_to_char(AUTHOR, ch);
send_to_char("\n\r", ch);
send_to_char(DATE, ch);
send_to_char("\n\r", ch);
send_to_char(CREDITS, ch);
send_to_char("\n\r", ch);
return FALSE;
}
/*
* This table contains help commands and a brief description of each.
* ------------------------------------------------------------------
*/
const struct olc_help_type help_table[] =
{
{ "area", area_flags, "Area attributes." },
{ "room", room_flags, "Room attributes." },
{ "sector", sector_flags, "Sector types, terrain." },
{ "exit", exit_flags, "Exit types." },
{ "type", type_flags, "Types of objects." },
{ "extra", extra_flags, "Object attributes." },
{ "wear", wear_flags, "Where to wear object." },
{ "spec", spec_table, "Available special programs." },
{ "sex", sex_flags, "Sexes." },
{ "act", act_flags, "Mobile attributes." },
{ "affect", affect_flags, "Mobile affects." },
{ "wear-loc", wear_loc_flags, "Where mobile wears object." },
{ "spells", skill_table, "Names of current spells." },
{ "weapon", weapon_flags, "Type of weapon." },
{ "container", container_flags, "Container status." },
{ "liquid", liquid_flags, "Types of liquids." },
{ "race", race_flags, "Mobile races." },
{ "mobprogs", mprog_type_flags, "Types of Mob Programs." },
{ "", 0, "" }
};
/*
* Name: show_flag_cmds
* Purpose: Displays settable flags and stats.
* Called by: show_help(olc_act.c).
*/
void show_flag_cmds(CHAR_DATA * ch, const struct flag_type *flag_table)
{
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH];
int flag;
int col;
buf1[0] = '\0';
col = 0;
for (flag = 0; *flag_table[flag].name; flag++)
{
if (flag_table[flag].settable)
{
sprintf(buf, "%-19.18s", flag_table[flag].name);
strcat(buf1, buf);
if (++col % 4 == 0)
strcat(buf1, "\n\r");
}
}
if (col % 4 != 0)
strcat(buf1, "\n\r");
send_to_char(buf1, ch);
return;
}
/*
* Name: show_skill_cmds
* Purpose: Displays all skill functions.
* Does remove those damn immortal commands from the list.
* Could be improved by:
* (1) Adding a check for a particular class.
* (2) Adding a check for a level range.
* Called by: show_help(olc_act.c).
*/
void show_skill_cmds(CHAR_DATA * ch, int tar)
{
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH * 2];
int sn;
int col;
buf1[0] = '\0';
col = 0;
for (sn = 0; sn < MAX_SKILL; sn++)
{
if (!skill_table[sn].name)
break;
if (!str_cmp(skill_table[sn].name, "reserved")
|| skill_table[sn].spell_fun == spell_null)
continue;
if (tar == -1 || skill_table[sn].target == tar)
{
sprintf(buf, "%-19.18s", skill_table[sn].name);
strcat(buf1, buf);
if (++col % 4 == 0)
strcat(buf1, "\n\r");
}
}
if (col % 4 != 0)
strcat(buf1, "\n\r");
send_to_char(buf1, ch);
return;
}
/*
* Name: show_spec_cmds
* Purpose: Displays settable special functions.
* Called by: show_help(olc_act.c).
*/
void show_spec_cmds(CHAR_DATA * ch)
{
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH];
int spec;
int col;
buf1[0] = '\0';
col = 0;
send_to_char("Preceed special functions with 'spec_'\n\r\n\r", ch);
for (spec = 0; *spec_table[spec].spec_fun; spec++)
{
sprintf(buf, "%-19.18s", &spec_table[spec].spec_name[5]);
strcat(buf1, buf);
if (++col % 4 == 0)
strcat(buf1, "\n\r");
}
if (col % 4 != 0)
strcat(buf1, "\n\r");
send_to_char(buf1, ch);
return;
}
/*
* Name: show_help
* Purpose: Displays help for many tables used in OLC.
* Called by: olc interpreters.
*/
bool show_help(CHAR_DATA * ch, char *argument)
{
char buf[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
char spell[MAX_INPUT_LENGTH];
int cnt;
argument = one_argument(argument, arg);
one_argument(argument, spell);
/*
* Display syntax.
*/
if (arg[0] == '\0')
{
send_to_char("Syntax: ? [command]\n\r\n\r", ch);
send_to_char("[command] [description]\n\r", ch);
for (cnt = 0; help_table[cnt].command[0] != '\0'; cnt++)
{
sprintf(buf, "%-10.10s -%s\n\r",
capitalize(help_table[cnt].command),
help_table[cnt].desc);
send_to_char(buf, ch);
}
return FALSE;
}
/*
* Find the command, show changeable data.
* ---------------------------------------
*/
for (cnt = 0; *help_table[cnt].command; cnt++)
{
if (arg[0] == help_table[cnt].command[0]
&& !str_prefix(arg, help_table[cnt].command))
{
if (help_table[cnt].structure == spec_table)
{
show_spec_cmds(ch);
return FALSE;
}
else if (help_table[cnt].structure == skill_table)
{
if (spell[0] == '\0')
{
send_to_char("Syntax: ? spells "
"[ignore/attack/defend/self/object/all]\n\r", ch);
return FALSE;
}
if (!str_prefix(spell, "all"))
show_skill_cmds(ch, -1);
else if (!str_prefix(spell, "ignore"))
show_skill_cmds(ch, TAR_IGNORE);
else if (!str_prefix(spell, "attack"))
show_skill_cmds(ch, TAR_CHAR_OFFENSIVE);
else if (!str_prefix(spell, "defend"))
show_skill_cmds(ch, TAR_CHAR_DEFENSIVE);
else if (!str_prefix(spell, "self"))
show_skill_cmds(ch, TAR_CHAR_SELF);
else if (!str_prefix(spell, "object"))
show_skill_cmds(ch, TAR_OBJ_INV);
else
send_to_char("Syntax: ? spell "
"[ignore/attack/defend/self/object/all]\n\r", ch);
return FALSE;
}
else
{
show_flag_cmds(ch, help_table[cnt].structure);
return FALSE;
}
}
}
show_help(ch, "");
return FALSE;
}
bool redit_mlist(CHAR_DATA * ch, char *argument)
{
MOB_INDEX_DATA *pMobIndex;
AREA_DATA *pArea;
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH * 2];
char arg[MAX_INPUT_LENGTH];
bool fAll, found;
int vnum;
int col = 0;
one_argument(argument, arg);
if (arg[0] == '\0')
{
send_to_char("Syntax: mlist <all/name>\n\r", ch);
return FALSE;
}
pArea = ch->in_room->area;
buf1[0] = '\0';
fAll = !str_cmp(arg, "all");
found = FALSE;
for (vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++)
{
if ((pMobIndex = get_mob_index(vnum)))
{
if (fAll || is_name(arg, pMobIndex->player_name))
{
found = TRUE;
sprintf(buf, "[%5d] %-17.16s",
pMobIndex->vnum, capitalize(pMobIndex->short_descr));
strcat(buf1, buf);
if (++col % 3 == 0)
strcat(buf1, "\n\r");
}
}
}
if (!found)
{
send_to_char("Mobile(s) not found in this area.\n\r", ch);
return FALSE;
}
if (col % 3 != 0)
strcat(buf1, "\n\r");
send_to_char(buf1, ch);
return FALSE;
}
bool redit_olist(CHAR_DATA * ch, char *argument)
{
OBJ_INDEX_DATA *pObjIndex;
AREA_DATA *pArea;
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH * 2];
char arg[MAX_INPUT_LENGTH];
bool fAll, found;
int vnum;
int col = 0;
one_argument(argument, arg);
if (arg[0] == '\0')
{
send_to_char("Syntax: olist <all/name/item_type>\n\r", ch);
return FALSE;
}
pArea = ch->in_room->area;
buf1[0] = '\0';
fAll = !str_cmp(arg, "all");
found = FALSE;
for (vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++)
{
if ((pObjIndex = get_obj_index(vnum)))
{
if (fAll || is_name(arg, pObjIndex->name)
|| flag_value(type_flags, arg) == pObjIndex->item_type)
{
found = TRUE;
sprintf(buf, "[%5d] %-17.16s",
pObjIndex->vnum, capitalize(pObjIndex->short_descr));
strcat(buf1, buf);
if (++col % 3 == 0)
strcat(buf1, "\n\r");
}
}
}
if (!found)
{
send_to_char("Object(s) not found in this area.\n\r", ch);
return FALSE;
}
if (col % 3 != 0)
strcat(buf1, "\n\r");
send_to_char(buf1, ch);
return FALSE;
}
bool redit_mshow(CHAR_DATA * ch, char *argument)
{
MOB_INDEX_DATA *pMob;
int value;
if (argument[0] == '\0')
{
send_to_char("Syntax: mshow <vnum>\n\r", ch);
return FALSE;
}
if (is_number(argument))
{
value = atoi(argument);
if (!(pMob = get_mob_index(value)))
{
send_to_char("REdit: That mobile does not exist.\n\r", ch);
return FALSE;
}
ch->desc->pEdit = (void *) pMob;
}
medit_show(ch, argument);
ch->desc->pEdit = (void *) ch->in_room;
return FALSE;
}
bool redit_oshow(CHAR_DATA * ch, char *argument)
{
OBJ_INDEX_DATA *pObj;
int value;
if (argument[0] == '\0')
{
send_to_char("Syntax: oshow <vnum>\n\r", ch);
return FALSE;
}
if (is_number(argument))
{
value = atoi(argument);
if (!(pObj = get_obj_index(value)))
{
send_to_char("REdit: That object does not exist.\n\r", ch);
return FALSE;
}
ch->desc->pEdit = (void *) pObj;
}
oedit_show(ch, argument);
ch->desc->pEdit = (void *) ch->in_room;
return FALSE;
}
/*
* Name: check_range( lower vnum, upper vnum )
* Purpose: Ensures the range spans only one area.
* Called by: aedit_vnum(olc_act.c).
*/
bool check_range(int lower, int upper)
{
AREA_DATA *pArea;
int cnt = 0;
for (pArea = area_first; pArea; pArea = pArea->next)
{
/*
* lower < area < upper
*/
if ((lower <= pArea->lvnum && upper >= pArea->lvnum)
|| (upper >= pArea->uvnum && lower <= pArea->uvnum))
cnt++;
if (cnt > 1)
return FALSE;
}
return TRUE;
}
AREA_DATA *get_vnum_area(int vnum)
{
AREA_DATA *pArea;
for (pArea = area_first; pArea; pArea = pArea->next)
{
if (vnum >= pArea->lvnum
&& vnum <= pArea->uvnum)
return pArea;
}
return 0;
}
/*
* Area Editor Functions.
*/
bool aedit_show(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea = edit_area( ch );
char buf[MAX_STRING_LENGTH];
sprintf(buf, "Name: [%5d] %s\n\r", pArea->vnum, pArea->name);
send_to_char(buf, ch);
sprintf(buf, "Recall: [%5d] %s\n\r", pArea->recall,
get_room_index(pArea->recall)
? get_room_index(pArea->recall)->name : "none");
send_to_char(buf, ch);
sprintf(buf, "File: %s\n\r", pArea->filename);
send_to_char(buf, ch);
sprintf(buf, "Vnums: [%d-%d]\n\r", pArea->lvnum, pArea->uvnum);
send_to_char(buf, ch);
sprintf(buf, "Age: [%d]\n\r", pArea->age);
send_to_char(buf, ch);
sprintf(buf, "Players: [%d]\n\r", pArea->nplayer);
send_to_char(buf, ch);
sprintf(buf, "Security: [%d]\n\r", pArea->security);
send_to_char(buf, ch);
sprintf(buf, "Builders: [%s]\n\r", pArea->builders);
send_to_char(buf, ch);
sprintf(buf, "Flags: [%s]\n\r", flag_string(area_flags, pArea->area_flags));
send_to_char(buf, ch);
return FALSE;
}
bool aedit_reset(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea = edit_area( ch );
reset_area(pArea);
send_to_char("Area reset.\n\r", ch);
return FALSE;
}
bool aedit_create(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea;
if (top_area >= INT_MAX) /*
* OLC 1.1b
*/
{
send_to_char("We're out of vnums for new areas.\n\r", ch);
return FALSE;
}
pArea = new_area();
area_last->next = pArea;
area_last = pArea; /*
* Thanks, Walker.
*/
ch->desc->pEdit = (void *) pArea;
SET_BIT(pArea->area_flags, AREA_ADDED);
send_to_char("Area Created.\n\r", ch);
return TRUE; /*
* OLC 1.1b
*/
}
bool aedit_name(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea = edit_area( ch );
if (argument[0] == '\0')
{
send_to_char("Syntax: name [$name]\n\r", ch);
return FALSE;
}
free_string(pArea->name);
pArea->name = str_dup(argument);
send_to_char("Name set.\n\r", ch);
return TRUE;
}
bool aedit_file(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea = edit_area( ch );
char file[MAX_STRING_LENGTH];
int i, length;
one_argument(argument, file); /*
* Forces Lowercase
*/
if (argument[0] == '\0')
{
send_to_char("Syntax: filename [$file]\n\r", ch);
return FALSE;
}
/*
* Simple Syntax Check.
*/
length = strlen(argument);
if (length > 8)
{
send_to_char("No more than eight characters allowed.\n\r", ch);
return FALSE;
}
/*
* Allow only letters and numbers.
*/
for (i = 0; i < length; i++)
{
if (!isalnum(file[i]))
{
send_to_char("Only letters and numbers are valid.\n\r", ch);
return FALSE;
}
}
free_string(pArea->filename);
strcat(file, ".are");
pArea->filename = str_dup(file);
send_to_char("Filename set.\n\r", ch);
return TRUE;
}
bool aedit_age(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea = edit_area( ch );
char age[MAX_STRING_LENGTH];
one_argument(argument, age);
if (!is_number(age) || age[0] == '\0')
{
send_to_char("Syntax: age [#age]\n\r", ch);
return FALSE;
}
pArea->age = atoi(age);
send_to_char("Age set.\n\r", ch);
return TRUE;
}
bool aedit_recall(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea = edit_area( ch );
char room[MAX_STRING_LENGTH];
int value;
one_argument(argument, room);
if (!is_number(argument) || argument[0] == '\0')
{
send_to_char("Syntax: recall [#rvnum]\n\r", ch);
return FALSE;
}
value = atoi(room);
if (!get_room_index(value))
{
send_to_char("AEdit: Room vnum does not exist.\n\r", ch);
return FALSE;
}
pArea->recall = value;
send_to_char("Recall set.\n\r", ch);
return TRUE;
}
bool aedit_security(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea = edit_area( ch );
char sec[MAX_STRING_LENGTH];
char buf[MAX_STRING_LENGTH];
int value;
one_argument(argument, sec);
if (!is_number(sec) || sec[0] == '\0')
{
send_to_char("Syntax: security [#level]\n\r", ch);
return FALSE;
}
value = atoi(sec);
if (value > ch->pcdata->security || value < 0)
{
if (ch->pcdata->security != 0)
{
sprintf(buf, "Security is 0-%d.\n\r", ch->pcdata->security);
send_to_char(buf, ch);
}
else
send_to_char("Security is 0 only.\n\r", ch);
return FALSE;
}
pArea->security = value;
send_to_char("Security set.\n\r", ch);
return TRUE;
}
bool aedit_builder(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea = edit_area( ch );
char name[MAX_STRING_LENGTH];
char buf[MAX_STRING_LENGTH];
one_argument(argument, name);
if (name[0] == '\0')
{
send_to_char("Syntax: builder [$name] -toggles builder\n\r", ch);
send_to_char("Syntax: builder All -allows everyone\n\r", ch);
return FALSE;
}
name[0] = UPPER(name[0]);
if (strstr(pArea->builders, name) != '\0')
{
pArea->builders = string_replace(pArea->builders, name, "\0");
pArea->builders = string_unpad(pArea->builders);
if (pArea->builders[0] == '\0')
{
free_string(pArea->builders);
pArea->builders = str_dup("None");
}
send_to_char("Builder removed.\n\r", ch);
return TRUE;
}
else
{
buf[0] = '\0';
if (strstr(pArea->builders, "None") != '\0')
{
pArea->builders = string_replace(pArea->builders, "None", "\0");
pArea->builders = string_unpad(pArea->builders);
}
if (pArea->builders[0] != '\0')
{
strcat(buf, pArea->builders);
strcat(buf, " ");
}
strcat(buf, name);
free_string(pArea->builders);
pArea->builders = string_proper(str_dup(buf));
send_to_char("Builder added.\n\r", ch);
return TRUE;
}
return FALSE;
}
bool aedit_vnum(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea = edit_area( ch );
char lower[MAX_STRING_LENGTH];
char upper[MAX_STRING_LENGTH];
int ilower;
int iupper;
argument = one_argument(argument, lower);
one_argument(argument, upper);
if (!is_number(lower) || lower[0] == '\0'
|| !is_number(upper) || upper[0] == '\0')
{
send_to_char("Syntax: vnum [#lower] [#upper]\n\r", ch);
return FALSE;
}
if ((ilower = atoi(lower)) > (iupper = atoi(upper)))
{
send_to_char("AEdit: Upper must be larger then lower.\n\r", ch);
return FALSE;
}
/*
* OLC 1.1b
*/
if (ilower <= 0 || ilower >= INT_MAX || iupper <= 0 || iupper >= INT_MAX)
{
char output[MAX_STRING_LENGTH];
sprintf(output, "AEdit: vnum must be between 0 and %d.\n\r", INT_MAX);
send_to_char(output, ch);
return FALSE;
}
if (!check_range(ilower, iupper))
{
send_to_char("AEdit: Range must include only this area.\n\r", ch);
return FALSE;
}
if (get_vnum_area(ilower)
&& get_vnum_area(ilower) != pArea)
{
send_to_char("AEdit: Lower vnum already assigned.\n\r", ch);
return FALSE;
}
pArea->lvnum = ilower;
send_to_char("Lower vnum set.\n\r", ch);
if (get_vnum_area(iupper)
&& get_vnum_area(iupper) != pArea)
{
send_to_char("AEdit: Upper vnum already assigned.\n\r", ch);
return TRUE; /*
* The lower value has been set.
*/
}
pArea->uvnum = iupper;
send_to_char("Upper vnum set.\n\r", ch);
return TRUE;
}
bool aedit_lvnum(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea = edit_area( ch );
char lower[MAX_STRING_LENGTH];
int ilower;
int iupper;
one_argument(argument, lower);
if (!is_number(lower) || lower[0] == '\0')
{
send_to_char("Syntax: lvnum [#lower]\n\r", ch);
return FALSE;
}
if ((ilower = atoi(lower)) > (iupper = pArea->uvnum))
{
send_to_char("AEdit: Value must be less than the uvnum.\n\r", ch);
return FALSE;
}
/*
* OLC 1.1b
*/
if (ilower <= 0 || ilower >= INT_MAX || iupper <= 0 || iupper >= INT_MAX)
{
char output[MAX_STRING_LENGTH];
sprintf(output, "AEdit: vnum must be between 0 and %d.\n\r", INT_MAX);
send_to_char(output, ch);
return FALSE;
}
if (!check_range(ilower, iupper))
{
send_to_char("AEdit: Range must include only this area.\n\r", ch);
return FALSE;
}
if (get_vnum_area(ilower)
&& get_vnum_area(ilower) != pArea)
{
send_to_char("AEdit: Lower vnum already assigned.\n\r", ch);
return FALSE;
}
pArea->lvnum = ilower;
send_to_char("Lower vnum set.\n\r", ch);
return TRUE;
}
bool aedit_uvnum(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea = edit_area( ch );
char upper[MAX_STRING_LENGTH];
int ilower;
int iupper;
one_argument(argument, upper);
if (!is_number(upper) || upper[0] == '\0')
{
send_to_char("Syntax: uvnum [#upper]\n\r", ch);
return FALSE;
}
if ((ilower = pArea->lvnum) > (iupper = atoi(upper)))
{
send_to_char("AEdit: Upper must be larger then lower.\n\r", ch);
return FALSE;
}
/*
* OLC 1.1b
*/
if (ilower <= 0 || ilower >= INT_MAX || iupper <= 0 || iupper >= INT_MAX)
{
char output[MAX_STRING_LENGTH];
sprintf(output, "AEdit: vnum must be between 0 and %d.\n\r", INT_MAX);
send_to_char(output, ch);
return FALSE;
}
if (!check_range(ilower, iupper))
{
send_to_char("AEdit: Range must include only this area.\n\r", ch);
return FALSE;
}
if (get_vnum_area(iupper)
&& get_vnum_area(iupper) != pArea)
{
send_to_char("AEdit: Upper vnum already assigned.\n\r", ch);
return FALSE;
}
pArea->uvnum = iupper;
send_to_char("Upper vnum set.\n\r", ch);
return TRUE;
}
/*
* Room Editor Functions.
*/
bool redit_show(CHAR_DATA * ch, char *argument)
{
ROOM_INDEX_DATA *pRoom;
char buf[MAX_STRING_LENGTH];
char buf1[2 * MAX_STRING_LENGTH];
OBJ_DATA *obj;
CHAR_DATA *rch;
int door;
bool fcnt;
pRoom = edit_room(ch);
buf1[0] = '\0';
sprintf(buf, "Description:\n\r%s", pRoom->description);
strcat(buf1, buf);
sprintf(buf, "Name: [%s]\n\rArea: [%5d] %s\n\r",
pRoom->name, pRoom->area->vnum, pRoom->area->name);
strcat(buf1, buf);
sprintf(buf, "Vnum: [%5d]\n\rSector: [%s]\n\r",
pRoom->vnum, flag_string(sector_flags, pRoom->sector_type));
strcat(buf1, buf);
sprintf(buf, "Room flags: [%s]\n\r",
flag_string(room_flags, pRoom->room_flags));
strcat(buf1, buf);
if (pRoom->extra_descr)
{
EXTRA_DESCR_DATA *ed;
strcat(buf1, "Desc Kwds: [");
for (ed = pRoom->extra_descr; ed; ed = ed->next)
{
strcat(buf1, ed->keyword);
if (ed->next)
strcat(buf1, " ");
}
strcat(buf1, "]\n\r");
}
strcat(buf1, "Characters: [");
fcnt = FALSE;
for (rch = pRoom->people; rch; rch = rch->next_in_room)
{
one_argument(rch->name, buf);
strcat(buf1, buf);
strcat(buf1, " ");
fcnt = TRUE;
}
if (fcnt)
{
int end;
end = strlen(buf1) - 1;
buf1[end] = ']';
strcat(buf1, "\n\r");
}
else
strcat(buf1, "none]\n\r");
strcat(buf1, "Objects: [");
fcnt = FALSE;
for (obj = pRoom->contents; obj; obj = obj->next_content)
{
one_argument(obj->name, buf);
strcat(buf1, buf);
strcat(buf1, " ");
fcnt = TRUE;
}
if (fcnt)
{
int end;
end = strlen(buf1) - 1;
buf1[end] = ']';
strcat(buf1, "\n\r");
}
else
strcat(buf1, "none]\n\r");
for (door = 0; door < MAX_DIR; door++)
{
EXIT_DATA *pexit;
if ((pexit = pRoom->exit[door]))
{
char word[MAX_INPUT_LENGTH];
char reset_state[MAX_STRING_LENGTH];
char *state;
int i, length;
sprintf(buf, "-%-5s to [%5d] Key: [%5d]",
capitalize(dir_name[door]),
pexit->to_room ? pexit->to_room->vnum : 0,
pexit->key);
strcat(buf1, buf);
/*
* Format up the exit info.
* Capitalize all flags that are not part of the reset info.
*/
strcpy(reset_state, flag_string(exit_flags, pexit->rs_flags));
state = flag_string(exit_flags, pexit->exit_info);
strcat(buf1, " Exit flags: [");
for (;;)
{
state = one_argument(state, word);
if (word[0] == '\0')
{
int end;
end = strlen(buf1) - 1;
buf1[end] = ']';
strcat(buf1, "\n\r");
break;
}
if (str_infix(word, reset_state))
{
length = strlen(word);
for (i = 0; i < length; i++)
word[i] = toupper(word[i]);
}
strcat(buf1, word);
strcat(buf1, " ");
}
if (pexit->keyword && pexit->keyword[0] != '\0')
{
sprintf(buf, "Kwds: [%s]\n\r", pexit->keyword);
strcat(buf1, buf);
}
if (pexit->description && pexit->description[0] != '\0')
{
sprintf(buf, "%s", pexit->description);
strcat(buf1, buf);
}
}
}
send_to_char(buf1, ch);
return FALSE;
}
/*
* OLC 1.1b
*
* Name: change_exit
* Purpose: Command interpreter for changing exits.
* Called by: redit_<dir>. This is a local function.
*/
bool change_exit(CHAR_DATA * ch, char *argument, int door)
{
ROOM_INDEX_DATA *pRoom;
char command[MAX_INPUT_LENGTH];
char arg[MAX_INPUT_LENGTH];
char total_arg[MAX_STRING_LENGTH];
int rev;
int value = 0;
pRoom = edit_room(ch);
/*
* Often used data.
*/
rev = rev_dir[door];
if (argument[0] == '\0')
{
do_help(ch, "EXIT");
return FALSE;
}
/*
* Now parse the arguments.
*/
strcpy(total_arg, argument);
argument = one_argument(argument, command);
one_argument(argument, arg);
if (!str_cmp(command, "delete"))
{
if (!pRoom->exit[door])
{
send_to_char("REdit: Exit does not exist.\n\r", ch);
return FALSE;
}
/*
* Remove To Room Exit.
*/
if (pRoom->exit[door]->to_room->exit[rev])
{
free_exit(pRoom->exit[door]->to_room->exit[rev]);
pRoom->exit[door]->to_room->exit[rev] = NULL;
}
/*
* Remove this exit.
*/
free_exit(pRoom->exit[door]);
pRoom->exit[door] = NULL;
send_to_char("Exit unlinked.\n\r", ch);
return TRUE;
}
/*
* Create a two-way exit.
*/
if (!str_cmp(command, "link"))
{
EXIT_DATA *pExit;
ROOM_INDEX_DATA *pLinkRoom;
if (arg[0] == '\0' || !is_number(arg))
{
send_to_char("Syntax: [direction] link [vnum]\n\r", ch);
return FALSE;
}
if (!(pLinkRoom = get_room_index(atoi(arg))))
{
send_to_char("REdit: Non-existant room.\n\r", ch);
return FALSE;
}
if (!is_builder(ch, pLinkRoom->area))
{
send_to_char("REdit: Cannot link to that area.\n\r", ch);
return FALSE;
}
if (pLinkRoom->exit[rev])
{
send_to_char("REdit: Remote side's exit exists.\n\r", ch);
return FALSE;
}
if (!pRoom->exit[door]) /*
* No exit.
*/
pRoom->exit[door] = new_exit();
pRoom->exit[door]->to_room = pLinkRoom; /*
* Assign data.
*/
pRoom->exit[door]->vnum = value;
pExit = new_exit(); /*
* No remote exit.
*/
pExit->to_room = ch->in_room; /*
* Assign data.
*/
pExit->vnum = ch->in_room->vnum;
pLinkRoom->exit[rev] = pExit; /*
* Link exit to room.
*/
send_to_char("Two-way link established.\n\r", ch);
return TRUE;
}
/*
* Create room and make two-way exit.
*/
if (!str_cmp(command, "dig"))
{
char buf[MAX_INPUT_LENGTH];
if (arg[0] == '\0' || !is_number(arg))
{
send_to_char("Syntax: [direction] dig <vnum>\n\r", ch);
return FALSE;
}
redit_create(ch, arg); /*
* Create the room.
*/
sprintf(buf, "link %s", arg);
change_exit(ch, buf, door); /*
* Create the exits.
*/
return TRUE;
}
/*
* Create one-way exit.
*/
if (!str_cmp(command, "room"))
{
ROOM_INDEX_DATA *pLinkRoom;
if (arg[0] == '\0' || !is_number(arg))
{
send_to_char("Syntax: [direction] room [vnum]\n\r", ch);
return FALSE;
}
if (!(pLinkRoom = get_room_index(atoi(arg))))
{
send_to_char("REdit: Non-existant room.\n\r", ch);
return FALSE;
}
if (!pRoom->exit[door])
pRoom->exit[door] = new_exit();
pRoom->exit[door]->to_room = pLinkRoom;
pRoom->exit[door]->vnum = value;
send_to_char("One-way link established.\n\r", ch);
return TRUE;
}
if (!str_cmp(command, "remove"))
{
if (arg[0] == '\0')
{
send_to_char("Syntax: [direction] remove [key/name/desc]\n\r", ch);
return FALSE;
}
if (!pRoom->exit[door])
{
send_to_char("REdit: Exit does not exist.\n\r", ch);
return FALSE;
}
if (!str_cmp(argument, "key"))
{
pRoom->exit[door]->key = 0;
send_to_char("Exit key removed.\n\r", ch);
return TRUE;
}
if (!str_cmp(argument, "name"))
{
free_string(pRoom->exit[door]->keyword);
pRoom->exit[door]->keyword = &str_empty[0];
send_to_char("Exit name removed.\n\r", ch);
return TRUE;
}
if (argument[0] == 'd' && !str_prefix(argument, "description"))
{
free_string(pRoom->exit[door]->description);
pRoom->exit[door]->description = &str_empty[0];
send_to_char("Exit description removed.\n\r", ch);
return TRUE;
}
send_to_char("Syntax: [direction] remove [key/name/desc]\n\r", ch);
return FALSE;
}
if (!str_cmp(command, "key"))
{
OBJ_INDEX_DATA *pObjIndex;
if (arg[0] == '\0' || !is_number(arg))
{
send_to_char("Syntax: [direction] key [vnum]\n\r", ch);
return FALSE;
}
if (!(pObjIndex = get_obj_index(atoi(arg))))
{
send_to_char("REdit: Item does not exist.\n\r", ch);
return FALSE;
}
if (pObjIndex->item_type != ITEM_KEY)
{
send_to_char("REdit: Item is not a key.\n\r", ch);
return FALSE;
}
if (!pRoom->exit[door])
pRoom->exit[door] = new_exit();
pRoom->exit[door]->key = pObjIndex->vnum;
send_to_char("Exit key set.\n\r", ch);
return TRUE;
}
if (!str_cmp(command, "name"))
{
if (arg[0] == '\0')
{
send_to_char("Syntax: [direction] name [string]\n\r", ch);
return FALSE;
}
if (!pRoom->exit[door])
pRoom->exit[door] = new_exit();
free_string(pRoom->exit[door]->keyword);
pRoom->exit[door]->keyword = str_dup(argument);
send_to_char("Exit name set.\n\r", ch);
return TRUE;
}
if (command[0] == 'd' && !str_prefix(command, "description"))
{
if (arg[0] == '\0')
{
if (!pRoom->exit[door])
pRoom->exit[door] = new_exit();
string_append(ch, &pRoom->exit[door]->description);
return TRUE;
}
send_to_char("Syntax: [direction] desc\n\r", ch);
return FALSE;
}
/*
* Set the exit flags, needs full argument.
* ----------------------------------------
*/
if ((value = flag_value(exit_flags, total_arg)) != NO_FLAG)
{
ROOM_INDEX_DATA *pToRoom;
/*
* Create an exit if none exists.
*/
if (!pRoom->exit[door])
pRoom->exit[door] = new_exit();
/*
* Set door bits for this room.
*/
TOGGLE_BIT(pRoom->exit[door]->rs_flags, value);
pRoom->exit[door]->exit_info = pRoom->exit[door]->rs_flags;
/*
* Set door bits of connected room.
* Skip one-way exits and non-existant rooms.
*/
if ((pToRoom = pRoom->exit[door]->to_room) && pToRoom->exit[rev])
{
TOGGLE_BIT(pToRoom->exit[rev]->rs_flags, value);
pToRoom->exit[rev]->exit_info = pToRoom->exit[rev]->rs_flags;
}
send_to_char("Exit flag toggled.\n\r", ch);
return TRUE;
}
return FALSE;
}
bool redit_north(CHAR_DATA * ch, char *argument)
{
if (change_exit(ch, argument, DIR_NORTH))
return TRUE;
return FALSE;
}
bool redit_south(CHAR_DATA * ch, char *argument)
{
if (change_exit(ch, argument, DIR_SOUTH))
return TRUE;
return FALSE;
}
bool redit_east(CHAR_DATA * ch, char *argument)
{
if (change_exit(ch, argument, DIR_EAST))
return TRUE;
return FALSE;
}
bool redit_west(CHAR_DATA * ch, char *argument)
{
if (change_exit(ch, argument, DIR_WEST))
return TRUE;
return FALSE;
}
bool redit_up(CHAR_DATA * ch, char *argument)
{
if (change_exit(ch, argument, DIR_UP))
return TRUE;
return FALSE;
}
bool redit_down(CHAR_DATA * ch, char *argument)
{
if (change_exit(ch, argument, DIR_DOWN))
return TRUE;
return FALSE;
}
/*
* OLC 1.1b
*/
bool redit_move(CHAR_DATA * ch, char *argument)
{
interpret(ch, argument);
return FALSE;
}
bool redit_ed(CHAR_DATA * ch, char *argument)
{
ROOM_INDEX_DATA *pRoom;
EXTRA_DESCR_DATA *ed;
char command[MAX_INPUT_LENGTH];
char keyword[MAX_INPUT_LENGTH];
pRoom = edit_room(ch);
argument = one_argument(argument, command);
one_argument(argument, keyword);
if (command[0] == '\0' || keyword[0] == '\0')
{
send_to_char("Syntax: ed add [keyword]\n\r", ch);
send_to_char(" ed edit [keyword]\n\r", ch);
send_to_char(" ed delete [keyword]\n\r", ch);
send_to_char(" ed format [keyword]\n\r", ch);
return FALSE;
}
if (!str_cmp(command, "add"))
{
if (keyword[0] == '\0')
{
send_to_char("Syntax: ed add [keyword]\n\r", ch);
return FALSE;
}
ed = new_extra_descr();
ed->keyword = str_dup(keyword);
ed->description = str_dup("");
ed->next = pRoom->extra_descr;
pRoom->extra_descr = ed;
string_append(ch, &ed->description);
return TRUE;
}
if (!str_cmp(command, "edit"))
{
if (keyword[0] == '\0')
{
send_to_char("Syntax: ed edit [keyword]\n\r", ch);
return FALSE;
}
for (ed = pRoom->extra_descr; ed; ed = ed->next)
{
if (is_name(keyword, ed->keyword))
break;
}
if (!ed)
{
send_to_char("REdit: Extra description keyword not found.\n\r", ch);
return FALSE;
}
string_append(ch, &ed->description);
return TRUE;
}
if (!str_cmp(command, "delete"))
{
EXTRA_DESCR_DATA *ped = NULL;
if (keyword[0] == '\0')
{
send_to_char("Syntax: ed delete [keyword]\n\r", ch);
return FALSE;
}
for (ed = pRoom->extra_descr; ed; ed = ed->next)
{
if (is_name(keyword, ed->keyword))
break;
ped = ed;
}
if (!ed)
{
send_to_char("REdit: Extra description keyword not found.\n\r", ch);
return FALSE;
}
if (!ped)
pRoom->extra_descr = ed->next;
else
ped->next = ed->next;
free_extra_descr(ed);
send_to_char("Extra description deleted.\n\r", ch);
return TRUE;
}
if (!str_cmp(command, "format"))
{
if (keyword[0] == '\0')
{
send_to_char("Syntax: ed format [keyword]\n\r", ch);
return FALSE;
}
for (ed = pRoom->extra_descr; ed; ed = ed->next)
{
if (is_name(keyword, ed->keyword))
break;
}
if (!ed)
{
send_to_char("REdit: Extra description keyword not found.\n\r", ch);
return FALSE;
}
/*
* OLC 1.1b
*/
if (strlen(ed->description) >= (MAX_STRING_LENGTH - 4))
{
send_to_char("String too long to be formatted.\n\r", ch);
return FALSE;
}
ed->description = format_string(ed->description);
send_to_char("Extra description formatted.\n\r", ch);
return TRUE;
}
redit_ed(ch, "");
return FALSE;
}
bool redit_create(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea;
ROOM_INDEX_DATA *pRoom;
int value;
int iHash;
pRoom = edit_room(ch);
value = atoi(argument);
/*
* OLC 1.1b
*/
if (argument[0] == '\0' || value <= 0 || value >= INT_MAX)
{
char output[MAX_STRING_LENGTH];
sprintf(output, "Syntax: create [0 < vnum < %d]\n\r", INT_MAX);
send_to_char(output, ch);
return FALSE;
}
if (argument[0] == '\0' || value <= 0)
{
send_to_char("Syntax: create [vnum > 0]\n\r", ch);
return FALSE;
}
pArea = get_vnum_area(value);
if (!pArea)
{
send_to_char("REdit: That vnum is not assigned an area.\n\r", ch);
return FALSE;
}
if (!is_builder(ch, pArea))
{
send_to_char("REdit: Vnum in an area you cannot build in.\n\r", ch);
return FALSE;
}
if (get_room_index(value))
{
send_to_char("REdit: Room vnum already exists.\n\r", ch);
return FALSE;
}
pRoom = new_room_index();
pRoom->area = pArea;
pRoom->vnum = value;
if (value > top_vnum_room)
top_vnum_room = value;
iHash = value % MAX_KEY_HASH;
pRoom->next = room_index_hash[iHash];
room_index_hash[iHash] = pRoom;
ch->desc->pEdit = (void *) pRoom;
send_to_char("Room created.\n\r", ch);
return TRUE;
}
bool redit_name(CHAR_DATA * ch, char *argument)
{
ROOM_INDEX_DATA *pRoom;
pRoom = edit_room(ch);
if (argument[0] == '\0')
{
send_to_char("Syntax: name [name]\n\r", ch);
return FALSE;
}
free_string(pRoom->name);
pRoom->name = str_dup(argument);
send_to_char("Name set.\n\r", ch);
return TRUE;
}
bool redit_desc(CHAR_DATA * ch, char *argument)
{
ROOM_INDEX_DATA *pRoom;
pRoom = edit_room(ch);
if (argument[0] == '\0')
{
string_append(ch, &pRoom->description);
return TRUE;
}
send_to_char("Syntax: desc\n\r", ch);
return FALSE;
}
bool redit_format(CHAR_DATA * ch, char *argument)
{
ROOM_INDEX_DATA *pRoom;
pRoom = edit_room(ch);
/*
* OLC 1.1b
*/
if (strlen(pRoom->description) >= (MAX_STRING_LENGTH - 4))
{
send_to_char("String too long to be formatted.\n\r", ch);
return FALSE;
}
pRoom->description = format_string(pRoom->description);
send_to_char("String formatted.\n\r", ch);
return TRUE;
}
bool redit_mreset(CHAR_DATA * ch, char *argument)
{
ROOM_INDEX_DATA *pRoom;
MOB_INDEX_DATA *pMobIndex;
CHAR_DATA *newmob;
char arg[MAX_INPUT_LENGTH];
RESET_DATA *pReset;
char output[MAX_STRING_LENGTH];
pRoom = edit_room(ch);
argument = one_argument(argument, arg);
if (arg[0] == '\0' || !is_number(arg))
{
send_to_char("Syntax: mreset <vnum> <max #>\n\r", ch);
return FALSE;
}
if (!(pMobIndex = get_mob_index(atoi(arg))))
{
send_to_char("REdit: No mobile has that vnum.\n\r", ch);
return FALSE;
}
if (pMobIndex->area != pRoom->area)
{
send_to_char("REdit: No such mobile in this area.\n\r", ch);
return FALSE;
}
/*
* Create the mobile reset.
*/
pReset = new_reset_data();
pReset->command = 'M';
pReset->arg1 = pMobIndex->vnum;
pReset->arg2 = is_number(argument) ? atoi(argument) : MAX_MOB;
pReset->arg3 = pRoom->vnum;
add_reset(pRoom, pReset, 0 /*
* Last slot
*/ );
/*
* Create the mobile.
*/
newmob = create_mobile(pMobIndex);
char_to_room(newmob, pRoom);
sprintf(output, "%s (%d) has been loaded and added to resets.\n\r"
"There will be a maximum of %d loaded to this room.\n\r",
capitalize(pMobIndex->short_descr),
pMobIndex->vnum,
pReset->arg2);
send_to_char(output, ch);
act("$n has created $N!", ch, NULL, newmob, TO_ROOM);
return TRUE;
}
struct wear_type
{
int wear_loc;
int wear_bit;
};
const struct wear_type wear_table_olc[] =
{
{ WEAR_NONE, ITEM_TAKE },
{ WEAR_LIGHT, ITEM_LIGHT },
{ WEAR_FINGER_L, ITEM_WEAR_FINGER },
{ WEAR_FINGER_R, ITEM_WEAR_FINGER },
{ WEAR_NECK_1, ITEM_WEAR_NECK },
{ WEAR_NECK_2, ITEM_WEAR_NECK },
{ WEAR_BODY, ITEM_WEAR_BODY },
{ WEAR_HEAD, ITEM_WEAR_HEAD },
{ WEAR_LEGS, ITEM_WEAR_LEGS },
{ WEAR_FEET, ITEM_WEAR_FEET },
{ WEAR_HANDS, ITEM_WEAR_HANDS },
{ WEAR_ARMS, ITEM_WEAR_ARMS },
{ WEAR_SHIELD, ITEM_WEAR_SHIELD },
{ WEAR_ABOUT, ITEM_WEAR_ABOUT },
{ WEAR_WAIST, ITEM_WEAR_WAIST },
{ WEAR_WRIST_L, ITEM_WEAR_WRIST },
{ WEAR_WRIST_R, ITEM_WEAR_WRIST },
{ WEAR_WIELD, ITEM_WIELD },
{ WEAR_HOLD, ITEM_HOLD },
{ NO_FLAG, NO_FLAG }
};
/*
* Name: wear_loc
* Purpose: Returns the location of the bit that matches the count.
* 1 = first match, 2 = second match etc.
* Called by: oedit_reset(olc_act.c).
*/
int wear_loc(int bits, int count)
{
int flag;
for (flag = 0; wear_table_olc[flag].wear_bit != NO_FLAG; flag++)
{
if (IS_SET(bits, wear_table_olc[flag].wear_bit) && --count < 1)
return wear_table_olc[flag].wear_loc;
}
return NO_FLAG;
}
/*
* Name: wear_bit
* Purpose: Converts a wear_loc into a bit.
* Called by: redit_oreset(olc_act.c).
*/
int wear_bit(int loc)
{
int flag;
for (flag = 0; wear_table_olc[flag].wear_loc != NO_FLAG; flag++)
{
if (loc == wear_table_olc[flag].wear_loc)
return wear_table_olc[flag].wear_bit;
}
return 0;
}
bool redit_oreset(CHAR_DATA * ch, char *argument)
{
ROOM_INDEX_DATA *pRoom;
OBJ_INDEX_DATA *pObjIndex;
OBJ_DATA *newobj;
OBJ_DATA *to_obj;
CHAR_DATA *to_mob;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
int olevel = 0;
RESET_DATA *pReset;
char output[MAX_STRING_LENGTH];
pRoom = edit_room(ch);
argument = one_argument(argument, arg1);
argument = one_argument(argument, arg2);
if (arg1[0] == '\0' || !is_number(arg1))
{
send_to_char("Syntax: oreset <vnum> <args>\n\r", ch);
send_to_char(" -no_args = into room\n\r", ch);
send_to_char(" -<obj_name> = into obj\n\r", ch);
send_to_char(" -<mob_name> <wear_loc> = into mob\n\r", ch);
return FALSE;
}
if (!(pObjIndex = get_obj_index(atoi(arg1))))
{
send_to_char("REdit: No object has that vnum.\n\r", ch);
return FALSE;
}
if (pObjIndex->area != pRoom->area)
{
send_to_char("REdit: No such object in this area.\n\r", ch);
return FALSE;
}
/*
* Load into room.
*/
if (arg2[0] == '\0')
{
pReset = new_reset_data();
pReset->command = 'O';
pReset->arg1 = pObjIndex->vnum;
pReset->arg2 = 0;
pReset->arg3 = pRoom->vnum;
add_reset(pRoom, pReset, 0 /*
* Last slot
*/ );
newobj = create_object(pObjIndex, number_fuzzy(olevel));
obj_to_room(newobj, pRoom);
sprintf(output, "%s (%d) has been loaded and added to resets.\n\r",
capitalize(pObjIndex->short_descr),
pObjIndex->vnum);
send_to_char(output, ch);
}
else
/*
* Load into object's inventory.
*/
if (argument[0] == '\0'
&& ((to_obj = get_obj_list(ch, arg2, pRoom->contents)) != NULL))
{
pReset = new_reset_data();
pReset->command = 'P';
pReset->arg1 = pObjIndex->vnum;
pReset->arg2 = 0;
pReset->arg3 = to_obj->pIndexData->vnum;
add_reset(pRoom, pReset, 0 /*
* Last slot
*/ );
newobj = create_object(pObjIndex, number_fuzzy(olevel));
newobj->cost = 0;
obj_to_obj(newobj, to_obj);
sprintf(output, "%s (%d) has been loaded into "
"%s (%d) and added to resets.\n\r",
capitalize(newobj->short_descr),
newobj->pIndexData->vnum,
to_obj->short_descr,
to_obj->pIndexData->vnum);
send_to_char(output, ch);
}
else
/*
* Load into mobile's inventory.
*/
if ((to_mob = get_char_room(ch, arg2)) != NULL)
{
int wear_loc;
/*
* Make sure the location on mobile is valid.
*/
if ((wear_loc = flag_value(wear_loc_flags, argument)) == NO_FLAG)
{
send_to_char("REdit: Invalid wear_loc. '? wear-loc'\n\r", ch);
return FALSE;
}
/*
* Disallow loading a sword(WEAR_WIELD) into WEAR_HEAD.
*/
if (!IS_SET(pObjIndex->wear_flags, wear_bit(wear_loc)))
{
sprintf(output,
"%s (%d) has wear flags: [%s]\n\r",
capitalize(pObjIndex->short_descr),
pObjIndex->vnum,
flag_string(wear_flags, pObjIndex->wear_flags));
send_to_char(output, ch);
return FALSE;
}
/*
* Can't load into same position.
*/
if (get_eq_char(to_mob, wear_loc))
{
send_to_char("REdit: Object already equipped.\n\r", ch);
return FALSE;
}
pReset = new_reset_data();
pReset->arg1 = pObjIndex->vnum;
pReset->arg2 = wear_loc;
if (pReset->arg2 == WEAR_NONE)
pReset->command = 'G';
else
pReset->command = 'E';
pReset->arg3 = wear_loc;
add_reset(pRoom, pReset, 0 /*
* Last slot
*/ );
olevel = URANGE(0, to_mob->level - 2, LEVEL_HERO);
newobj = create_object(pObjIndex, number_fuzzy(olevel));
if (to_mob->pIndexData->pShop) /*
* Shop-keeper?
*/
{
switch (pObjIndex->item_type)
{
default:
olevel = 0;
break;
case ITEM_PILL:
olevel = number_range(0, 10);
break;
case ITEM_POTION:
olevel = number_range(0, 10);
break;
case ITEM_SCROLL:
olevel = number_range(5, 15);
break;
case ITEM_WAND:
olevel = number_range(10, 20);
break;
case ITEM_STAFF:
olevel = number_range(15, 25);
break;
case ITEM_ARMOR:
olevel = number_range(5, 15);
break;
case ITEM_WEAPON:
if (pReset->command == 'G')
olevel = number_range(5, 15);
else
olevel = number_fuzzy(olevel);
break;
}
newobj = create_object(pObjIndex, olevel);
if (pReset->arg2 == WEAR_NONE)
SET_BIT(newobj->extra_flags, ITEM_INVENTORY);
}
else
newobj = create_object(pObjIndex, number_fuzzy(olevel));
obj_to_char(newobj, to_mob);
if (pReset->command == 'E')
equip_char(to_mob, newobj, pReset->arg3);
sprintf(output, "%s (%d) has been loaded "
"%s of %s (%d) and added to resets.\n\r",
capitalize(pObjIndex->short_descr),
pObjIndex->vnum,
flag_string(wear_loc_strings, pReset->arg3),
to_mob->short_descr,
to_mob->pIndexData->vnum);
send_to_char(output, ch);
}
else
/*
* Display Syntax
*/
{
send_to_char("REdit: That mobile isn't here.\n\r", ch);
return FALSE;
}
act("$n has created $p!", ch, newobj, NULL, TO_ROOM);
return TRUE;
}
/*
* Object Editor Functions.
*/
void show_obj_values(CHAR_DATA * ch, OBJ_INDEX_DATA * obj)
{
char buf[MAX_STRING_LENGTH];
switch (obj->item_type)
{
default: /*
* No values.
*/
break;
case ITEM_LIGHT:
if (obj->value[2] == -1)
sprintf(buf, "[v2] Light: Infinite[-1]\n\r");
else
sprintf(buf, "[v2] Light: [%d]\n\r", obj->value[2]);
send_to_char(buf, ch);
break;
case ITEM_WAND:
case ITEM_STAFF:
sprintf(buf,
"[v0] Level: [%d]\n\r"
"[v1] Charges Total: [%d]\n\r"
"[v2] Charges Left: [%d]\n\r"
"[v3] Spell: %s\n\r",
obj->value[0],
obj->value[1],
obj->value[2],
obj->value[3] != -1 ? skill_table[obj->value[3]].name
: "none");
send_to_char(buf, ch);
break;
case ITEM_SCROLL:
case ITEM_POTION:
case ITEM_PILL:
sprintf(buf,
"[v0] Level: [%d]\n\r"
"[v1] Spell: %s\n\r"
"[v2] Spell: %s\n\r"
"[v3] Spell: %s\n\r"
"[v4] Spell: %s\n\r",
obj->value[0],
obj->value[1] != -1 ? skill_table[obj->value[1]].name
: "none",
obj->value[2] != -1 ? skill_table[obj->value[2]].name
: "none",
obj->value[3] != -1 ? skill_table[obj->value[3]].name
: "none",
obj->value[4] != -1 ? skill_table[obj->value[4]].name
: "none");
send_to_char(buf, ch);
break;
case ITEM_WEAPON:
sprintf(buf,
"[v1] Damage minimum: [%d]\n\r"
"[v2] Damage maximum: [%d]\n\r"
"[v3] Type: %s\n\r",
obj->value[1],
obj->value[2],
flag_string(weapon_flags, obj->value[3]));
send_to_char(buf, ch);
break;
case ITEM_CONTAINER:
sprintf(buf,
"[v0] Weight: [%d kg]\n\r"
"[v1] Flags: [%s]\n\r"
"[v2] Key: %s [%d]\n\r",
obj->value[0],
flag_string(container_flags, obj->value[1]),
get_obj_index(obj->value[2])
? get_obj_index(obj->value[2])->short_descr
: "none", obj->value[2]);
send_to_char(buf, ch);
break;
case ITEM_DRINK_CON:
sprintf(buf,
"[v0] Liquid Total: [%d]\n\r"
"[v1] Liquid Left: [%d]\n\r"
"[v2] Liquid: %s\n\r"
"[v3] Poisoned: %s\n\r",
obj->value[0],
obj->value[1],
flag_string(liquid_flags, obj->value[2]),
obj->value[3] != 0 ? "Yes" : "No");
send_to_char(buf, ch);
break;
case ITEM_FOOD:
sprintf(buf,
"[v0] Food hours: [%d]\n\r"
"[v3] Poisoned: %s\n\r",
obj->value[0],
obj->value[3] != 0 ? "Yes" : "No");
send_to_char(buf, ch);
break;
case ITEM_MONEY:
sprintf(buf, "[v0] Gold: [%d]\n\r", obj->value[0]);
send_to_char(buf, ch);
break;
case ITEM_PORTAL:
sprintf(buf,
"[v0] Charges: [%d]\n\r"
"[v1] Flags: [%s]\n\r"
"[v2] Key: %s [%d]\n\r"
"[v3] Flags: [%s]\n\r"
"[v4] Destiny: [%d]\n\r",
obj->value[0],
flag_string(portal_door_flags, obj->value[1]),
get_obj_index(obj->value[2])
? get_obj_index(obj->value[2])->short_descr
: "none", obj->value[2],
flag_string(portal_flags, obj->value[3]),
obj->value[4]);
send_to_char(buf, ch);
break;
}
return;
}
bool set_obj_values(CHAR_DATA * ch, OBJ_INDEX_DATA * pObj, int value_num, char *argument)
{
switch (pObj->item_type)
{
default:
break;
case ITEM_LIGHT:
switch (value_num)
{
default:
do_help(ch, "ITEM_LIGHT");
return FALSE;
case 2:
send_to_char("HOURS OF LIGHT SET.\n\r\n\r", ch);
pObj->value[2] = atoi(argument);
break;
}
break;
case ITEM_WAND:
case ITEM_STAFF:
switch (value_num)
{
default:
do_help(ch, "ITEM_STAFF_WAND");
return FALSE;
case 0:
send_to_char("SPELL LEVEL SET.\n\r\n\r", ch);
pObj->value[0] = atoi(argument);
break;
case 1:
send_to_char("TOTAL NUMBER OF CHARGES SET.\n\r\n\r", ch);
pObj->value[1] = atoi(argument);
break;
case 2:
send_to_char("CURRENT NUMBER OF CHARGES SET.\n\r\n\r", ch);
pObj->value[2] = atoi(argument);
break;
case 3:
send_to_char("SPELL TYPE SET.\n\r", ch);
pObj->value[3] = skill_lookup(argument);
break;
}
break;
case ITEM_SCROLL:
case ITEM_POTION:
case ITEM_PILL:
switch (value_num)
{
default:
do_help(ch, "ITEM_SCROLL_POTION_PILL");
return FALSE;
case 0:
send_to_char("SPELL LEVEL SET.\n\r\n\r", ch);
pObj->value[0] = atoi(argument);
break;
case 1:
send_to_char("SPELL TYPE 1 SET.\n\r\n\r", ch);
pObj->value[1] = skill_lookup(argument);
break;
case 2:
send_to_char("SPELL TYPE 2 SET.\n\r\n\r", ch);
pObj->value[2] = skill_lookup(argument);
break;
case 3:
send_to_char("SPELL TYPE 3 SET.\n\r\n\r", ch);
pObj->value[3] = skill_lookup(argument);
break;
case 4:
send_to_char("SPELL TYPE 4 SET.\n\r\n\r", ch);
pObj->value[4] = skill_lookup(argument);
break;
}
break;
case ITEM_WEAPON:
switch (value_num)
{
default:
do_help(ch, "ITEM_WEAPON");
return FALSE;
break;
case 1:
send_to_char("MINIMUM DAMAGE SET.\n\r\n\r", ch);
pObj->value[1] = atoi(argument);
break;
case 2:
send_to_char("MAXIMUM DAMAGE SET.\n\r\n\r", ch);
pObj->value[2] = atoi(argument);
break;
case 3:
send_to_char("WEAPON TYPE SET.\n\r\n\r", ch);
pObj->value[3] = flag_value(weapon_flags, argument);
break;
}
break;
case ITEM_CONTAINER:
switch (value_num)
{
int value;
default:
do_help(ch, "ITEM_CONTAINER");
return FALSE;
case 0:
send_to_char("WEIGHT CAPACITY SET.\n\r\n\r", ch);
pObj->value[0] = atoi(argument);
break;
case 1:
if ((value = flag_value(container_flags, argument))
!= NO_FLAG)
TOGGLE_BIT(pObj->value[1], value);
else
{
do_help(ch, "ITEM_CONTAINER");
return FALSE;
}
send_to_char("CONTAINER TYPE SET.\n\r\n\r", ch);
break;
case 2:
if (atoi(argument) != 0)
{
if (!get_obj_index(atoi(argument)))
{
send_to_char("THERE IS NO SUCH ITEM.\n\r\n\r", ch);
return FALSE;
}
if (get_obj_index(atoi(argument))->item_type != ITEM_KEY)
{
send_to_char("THAT ITEM IS NOT A KEY.\n\r\n\r", ch);
return FALSE;
}
}
send_to_char("CONTAINER KEY SET.\n\r\n\r", ch);
pObj->value[2] = atoi(argument);
break;
}
break;
case ITEM_DRINK_CON:
switch (value_num)
{
default:
do_help(ch, "ITEM_DRINK");
return FALSE;
case 0:
send_to_char("MAXIMUM AMOUT OF LIQUID HOURS SET.\n\r\n\r", ch);
pObj->value[0] = atoi(argument);
break;
case 1:
send_to_char("CURRENT AMOUNT OF LIQUID HOURS SET.\n\r\n\r", ch);
pObj->value[1] = atoi(argument);
break;
case 2:
send_to_char("LIQUID TYPE SET.\n\r\n\r", ch);
pObj->value[2] = flag_value(liquid_flags, argument);
break;
case 3:
send_to_char("POISON VALUE TOGGLED.\n\r\n\r", ch);
pObj->value[3] = (pObj->value[3] == 0) ? 1 : 0;
break;
}
break;
case ITEM_FOOD:
switch (value_num)
{
default:
do_help(ch, "ITEM_FOOD");
return FALSE;
case 0:
send_to_char("HOURS OF FOOD SET.\n\r\n\r", ch);
pObj->value[0] = atoi(argument);
break;
case 3:
send_to_char("POISON VALUE TOGGLED.\n\r\n\r", ch);
pObj->value[3] = (pObj->value[3] == 0) ? 1 : 0;
break;
}
break;
case ITEM_MONEY:
switch (value_num)
{
default:
do_help(ch, "ITEM_MONEY");
return FALSE;
case 0:
send_to_char("GOLD AMOUNT SET.\n\r\n\r", ch);
pObj->value[0] = atoi(argument);
break;
}
break;
case ITEM_PORTAL:
switch (value_num)
{
int value;
default:
do_help(ch, "ITEM_PORTAL");
return FALSE;
case 0:
send_to_char("NUMBER OF CHARGES SET.\n\r\n\r", ch);
pObj->value[0] = atoi(argument);
break;
case 1:
if ((value = flag_value(portal_door_flags, argument))
!= NO_FLAG)
TOGGLE_BIT(pObj->value[1], value);
else
{
do_help(ch, "ITEM_PORTAL");
return FALSE;
}
send_to_char("PORTAL DOOR TYPE SET.\n\r\n\r", ch);
break;
case 2:
if (atoi(argument) != 0)
{
if (!get_obj_index(atoi(argument)))
{
send_to_char("THERE IS NO SUCH ITEM.\n\r\n\r", ch);
return FALSE;
}
if (get_obj_index(atoi(argument))->item_type !=
ITEM_KEY)
{
send_to_char("THAT ITEM IS NOT A KEY.\n\r\n\r", ch);
return FALSE;
}
}
send_to_char("PORTAL KEY SET.\n\r\n\r", ch);
pObj->value[2] = atoi(argument);
break;
case 3:
if ((value = flag_value(portal_flags, argument))
!= NO_FLAG)
TOGGLE_BIT(pObj->value[3], value);
else
{
do_help(ch, "ITEM_PORTAL");
return FALSE;
}
send_to_char("PORTAL TYPE SET.\n\r\n\r", ch);
break;
case 4:
send_to_char("PORTAL DESTINY ROOM VNUM SET.\n\r\n\r", ch);
pObj->value[4] = atoi(argument);
break;
}
break;
}
show_obj_values(ch, pObj);
return TRUE;
}
bool oedit_show(CHAR_DATA * ch, char *argument)
{
OBJ_INDEX_DATA *pObj;
char buf[MAX_STRING_LENGTH];
AFFECT_DATA *paf;
int cnt;
pObj = edit_obj(ch);
sprintf(buf, "Name: [%s]\n\rArea: [%5d] %s\n\r",
pObj->name,
!pObj->area ? -1 : pObj->area->vnum,
!pObj->area ? "No Area" : pObj->area->name);
send_to_char(buf, ch);
sprintf(buf, "Vnum: [%5d]\n\rType: [%s]\n\r",
pObj->vnum,
flag_string(type_flags, pObj->item_type));
send_to_char(buf, ch);
sprintf(buf, "Wear flags: [%s]\n\r",
flag_string(wear_flags, pObj->wear_flags));
send_to_char(buf, ch);
sprintf(buf, "Extra flags: [%s]\n\r",
flag_string(extra_flags, pObj->extra_flags));
send_to_char(buf, ch);
sprintf(buf, "Weight: [%d]\n\rCost: [%d]\n\r",
pObj->weight, pObj->cost);
send_to_char(buf, ch);
if (pObj->extra_descr)
{
EXTRA_DESCR_DATA *ed;
send_to_char("Ex desc kwd: ", ch);
for (ed = pObj->extra_descr; ed; ed = ed->next)
{
send_to_char("[", ch);
send_to_char(ed->keyword, ch);
send_to_char("]", ch);
}
send_to_char("\n\r", ch);
}
sprintf(buf, "Short desc: %s\n\rLong desc:\n\r %s\n\r",
pObj->short_descr, pObj->description);
send_to_char(buf, ch);
for (cnt = 0, paf = pObj->affected; paf; paf = paf->next)
{
if (cnt == 0)
{
send_to_char("Number Modifier Affects\n\r", ch);
send_to_char("------ -------- -------\n\r", ch);
}
sprintf(buf, "[%4d] %-8d %s\n\r", cnt,
paf->modifier,
flag_string(apply_flags, paf->location));
send_to_char(buf, ch);
cnt++;
}
show_obj_values(ch, pObj);
return FALSE;
}
/*
* Need to issue warning if flag isn't valid.
*/
bool oedit_addaffect(CHAR_DATA * ch, char *argument)
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
char loc[MAX_STRING_LENGTH];
char mod[MAX_STRING_LENGTH];
pObj = edit_obj(ch);
argument = one_argument(argument, loc);
one_argument(argument, mod);
if (loc[0] == '\0' || mod[0] == '\0' || !is_number(mod))
{
send_to_char("Syntax: addaffect [location] [#mod]\n\r", ch);
return FALSE;
}
pAf = new_affect();
pAf->location = flag_value(apply_flags, loc);
pAf->modifier = atoi(mod);
pAf->type = -1;
pAf->duration = -1;
pAf->bitvector = 0;
pAf->next = pObj->affected;
pObj->affected = pAf;
send_to_char("Affect added.\n\r", ch);
return TRUE;
}
/*
* My thanks to Hans Hvidsten Birkeland and Noam Krendel(Walker)
* for really teaching me how to manipulate pointers.
*/
bool oedit_delaffect(CHAR_DATA * ch, char *argument)
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
AFFECT_DATA *pAf_next;
char affect[MAX_STRING_LENGTH];
int value;
int cnt = 0;
pObj = edit_obj(ch);
one_argument(argument, affect);
if (!is_number(affect) || affect[0] == '\0')
{
send_to_char("Syntax: delaffect [#affect]\n\r", ch);
return FALSE;
}
value = atoi(affect);
if (value < 0)
{
send_to_char("Only non-negative affect-numbers allowed.\n\r", ch);
return FALSE;
}
if (!(pAf = pObj->affected))
{
send_to_char("OEdit: Non-existant affect.\n\r", ch);
return FALSE;
}
if (value == 0) /*
* First case: Remove first affect
*/
{
pAf = pObj->affected;
pObj->affected = pAf->next;
free_affect(pAf);
}
else
/*
* Affect to remove is not the first
*/
{
while ((pAf_next = pAf->next) && (++cnt < value))
pAf = pAf_next;
if (pAf_next) /*
* See if it's the next affect
*/
{
pAf->next = pAf_next->next;
free_affect(pAf_next);
}
else
/*
* Doesn't exist
*/
{
send_to_char("No such affect.\n\r", ch);
return FALSE;
}
}
send_to_char("Affect removed.\n\r", ch);
return TRUE;
}
bool oedit_name(CHAR_DATA * ch, char *argument)
{
OBJ_INDEX_DATA *pObj;
pObj = edit_obj(ch);
if (argument[0] == '\0')
{
send_to_char("Syntax: name [string]\n\r", ch);
return FALSE;
}
free_string(pObj->name);
pObj->name = str_dup(argument);
send_to_char("Name set.\n\r", ch);
return TRUE;
}
bool oedit_short(CHAR_DATA * ch, char *argument)
{
OBJ_INDEX_DATA *pObj;
pObj = edit_obj(ch);
if (argument[0] == '\0')
{
send_to_char("Syntax: short [string]\n\r", ch);
return FALSE;
}
free_string(pObj->short_descr);
pObj->short_descr = str_dup(argument);
pObj->short_descr[0] = LOWER(pObj->short_descr[0]);
send_to_char("Short description set.\n\r", ch);
return TRUE;
}
bool oedit_long(CHAR_DATA * ch, char *argument)
{
OBJ_INDEX_DATA *pObj;
pObj = edit_obj(ch);
if (argument[0] == '\0')
{
send_to_char("Syntax: long [string]\n\r", ch);
return FALSE;
}
free_string(pObj->description);
pObj->description = str_dup(argument);
pObj->description[0] = UPPER(pObj->description[0]);
send_to_char("Long description set.\n\r", ch);
return TRUE;
}
bool set_value(CHAR_DATA * ch, OBJ_INDEX_DATA * pObj, char *argument, int value)
{
if (argument[0] == '\0')
{
set_obj_values(ch, pObj, -1, '\0');
return FALSE;
}
if (set_obj_values(ch, pObj, value, argument))
return TRUE;
return FALSE;
}
/*
* Name: oedit_values
* Purpose: Finds the object and sets its value.
* Called by: The four valueX functions below.
*/
bool oedit_values(CHAR_DATA * ch, char *argument, int value)
{
OBJ_INDEX_DATA *pObj;
pObj = edit_obj(ch);
if (set_value(ch, pObj, argument, value))
return TRUE;
return FALSE;
}
bool oedit_value0(CHAR_DATA * ch, char *argument)
{
if (oedit_values(ch, argument, 0))
return TRUE;
return FALSE;
}
bool oedit_value1(CHAR_DATA * ch, char *argument)
{
if (oedit_values(ch, argument, 1))
return TRUE;
return FALSE;
}
bool oedit_value2(CHAR_DATA * ch, char *argument)
{
if (oedit_values(ch, argument, 2))
return TRUE;
return FALSE;
}
bool oedit_value3(CHAR_DATA * ch, char *argument)
{
if (oedit_values(ch, argument, 3))
return TRUE;
return FALSE;
}
bool oedit_value4(CHAR_DATA * ch, char *argument)
{
if (oedit_values(ch, argument, 4))
return TRUE;
return FALSE;
}
bool oedit_weight(CHAR_DATA * ch, char *argument)
{
OBJ_INDEX_DATA *pObj;
pObj = edit_obj(ch);
if (argument[0] == '\0' || !is_number(argument))
{
send_to_char("Syntax: weight [number]\n\r", ch);
return FALSE;
}
pObj->weight = atoi(argument);
send_to_char("Weight set.\n\r", ch);
return TRUE;
}
bool oedit_cost(CHAR_DATA * ch, char *argument)
{
OBJ_INDEX_DATA *pObj;
pObj = edit_obj(ch);
if (argument[0] == '\0' || !is_number(argument))
{
send_to_char("Syntax: cost [number]\n\r", ch);
return FALSE;
}
pObj->cost = atoi(argument);
send_to_char("Cost set.\n\r", ch);
return TRUE;
}
bool oedit_create(CHAR_DATA * ch, char *argument)
{
OBJ_INDEX_DATA *pObj;
AREA_DATA *pArea;
int value;
int iHash;
value = atoi(argument);
/*
* OLC 1.1b
*/
if (argument[0] == '\0' || value <= 0 || value >= INT_MAX)
{
char output[MAX_STRING_LENGTH];
sprintf(output, "Syntax: create [0 < vnum < %d]\n\r", INT_MAX);
send_to_char(output, ch);
return FALSE;
}
pArea = get_vnum_area(value);
if (!pArea)
{
send_to_char("OEdit: That vnum is not assigned an area.\n\r", ch);
return FALSE;
}
if (!is_builder(ch, pArea))
{
send_to_char("OEdit: Vnum in an area you cannot build in.\n\r", ch);
return FALSE;
}
if (get_obj_index(value))
{
send_to_char("OEdit: Object vnum already exists.\n\r", ch);
return FALSE;
}
pObj = new_obj_index();
pObj->vnum = value;
pObj->area = pArea;
if (value > top_vnum_obj)
top_vnum_obj = value;
iHash = value % MAX_KEY_HASH;
pObj->next = obj_index_hash[iHash];
obj_index_hash[iHash] = pObj;
ch->desc->pEdit = (void *) pObj;
send_to_char("Object Created.\n\r", ch);
return TRUE;
}
bool oedit_ed(CHAR_DATA * ch, char *argument)
{
OBJ_INDEX_DATA *pObj;
EXTRA_DESCR_DATA *ed;
char command[MAX_INPUT_LENGTH];
char keyword[MAX_INPUT_LENGTH];
pObj = edit_obj(ch);
argument = one_argument(argument, command);
one_argument(argument, keyword);
if (command[0] == '\0')
{
send_to_char("Syntax: ed add [keyword]\n\r", ch);
send_to_char(" ed delete [keyword]\n\r", ch);
send_to_char(" ed edit [keyword]\n\r", ch);
send_to_char(" ed format [keyword]\n\r", ch);
return FALSE;
}
if (!str_cmp(command, "add"))
{
if (keyword[0] == '\0')
{
send_to_char("Syntax: ed add [keyword]\n\r", ch);
return FALSE;
}
ed = new_extra_descr();
ed->keyword = str_dup(keyword);
ed->next = pObj->extra_descr;
pObj->extra_descr = ed;
string_append(ch, &ed->description);
return TRUE;
}
if (!str_cmp(command, "edit"))
{
if (keyword[0] == '\0')
{
send_to_char("Syntax: ed edit [keyword]\n\r", ch);
return FALSE;
}
for (ed = pObj->extra_descr; ed; ed = ed->next)
{
if (is_name(keyword, ed->keyword))
break;
}
if (!ed)
{
send_to_char("OEdit: Extra description keyword not found.\n\r", ch);
return FALSE;
}
string_append(ch, &ed->description);
return TRUE;
}
if (!str_cmp(command, "delete"))
{
EXTRA_DESCR_DATA *ped = NULL;
if (keyword[0] == '\0')
{
send_to_char("Syntax: ed delete [keyword]\n\r", ch);
return FALSE;
}
for (ed = pObj->extra_descr; ed; ed = ed->next)
{
if (is_name(keyword, ed->keyword))
break;
ped = ed;
}
if (!ed)
{
send_to_char("OEdit: Extra description keyword not found.\n\r", ch);
return FALSE;
}
if (!ped)
pObj->extra_descr = ed->next;
else
ped->next = ed->next;
free_extra_descr(ed);
send_to_char("Extra description deleted.\n\r", ch);
return TRUE;
}
if (!str_cmp(command, "format"))
{
EXTRA_DESCR_DATA *ped = NULL;
if (keyword[0] == '\0')
{
send_to_char("Syntax: ed format [keyword]\n\r", ch);
return FALSE;
}
for (ed = pObj->extra_descr; ed; ed = ed->next)
{
if (is_name(keyword, ed->keyword))
break;
ped = ed;
}
if (!ed)
{
send_to_char("OEdit: Extra description keyword not found.\n\r", ch);
return FALSE;
}
/*
* OLC 1.1b
*/
if (strlen(ed->description) >= (MAX_STRING_LENGTH - 4))
{
send_to_char("String too long to be formatted.\n\r", ch);
return FALSE;
}
ed->description = format_string(ed->description);
send_to_char("Extra description formatted.\n\r", ch);
return TRUE;
}
oedit_ed(ch, "");
return FALSE;
}
/*
* Mobile Editor Functions.
*/
bool medit_show(CHAR_DATA * ch, char *argument)
{
MOB_INDEX_DATA *pMob;
char buf[MAX_STRING_LENGTH];
pMob = edit_mob(ch);
sprintf(buf, "Name: [%s]\n\rArea: [%5d] %s\n\r",
pMob->player_name,
!pMob->area ? -1 : pMob->area->vnum,
!pMob->area ? "No Area" : pMob->area->name);
send_to_char(buf, ch);
sprintf(buf, "Act: [%s]\n\r",
flag_string(act_flags, pMob->act));
send_to_char(buf, ch);
sprintf(buf, "Vnum: [%5d]\n\rSex: [%s]\n\r",
pMob->vnum,
pMob->sex == SEX_MALE ? "male" :
pMob->sex == SEX_FEMALE ? "female" : "neutral");
send_to_char(buf, ch);
sprintf(buf, "Race: [%s]\n\r", race_table[pMob->race].name);
send_to_char(buf, ch);
sprintf(buf,
"Level: [%2d]\n\rAlign: [%4d]\n\r",
pMob->level, pMob->alignment);
send_to_char(buf, ch);
sprintf(buf, "Affected by: [%s]\n\r",
flag_string(affect_flags, pMob->affected_by));
send_to_char(buf, ch);
if (pMob->spec_fun)
{
sprintf(buf, "Spec fun: [%s]\n\r", spec_string(pMob->spec_fun));
send_to_char(buf, ch);
}
sprintf(buf, "Short descr: %s\n\rLong descr:\n\r%s",
pMob->short_descr,
pMob->long_descr);
send_to_char(buf, ch);
sprintf(buf, "Description:\n\r%s", pMob->description);
send_to_char(buf, ch);
if (pMob->pShop)
{
SHOP_DATA *pShop;
int iTrade;
pShop = pMob->pShop;
sprintf(buf,
"Shop data for [%5d]:\n\r"
" Markup for purchaser: %d%%\n\r"
" Markdown for seller: %d%%\n\r",
pShop->keeper, pShop->profit_buy, pShop->profit_sell);
send_to_char(buf, ch);
sprintf(buf, " Hours: %d to %d.\n\r",
pShop->open_hour, pShop->close_hour);
send_to_char(buf, ch);
for (iTrade = 0; iTrade < MAX_TRADE; iTrade++)
{
if (pShop->buy_type[iTrade] != 0)
{
if (iTrade == 0)
{
send_to_char(" Number Trades Type\n\r", ch);
send_to_char(" ------ -----------\n\r", ch);
}
sprintf(buf, " [%4d] %s\n\r", iTrade,
flag_string(type_flags, pShop->buy_type[iTrade]));
send_to_char(buf, ch);
}
}
}
return FALSE;
}
bool medit_create(CHAR_DATA * ch, char *argument)
{
MOB_INDEX_DATA *pMob;
AREA_DATA *pArea;
int value;
int iHash;
value = atoi(argument);
/*
* OLC 1.1b
*/
if (argument[0] == '\0' || value <= 0 || value >= INT_MAX)
{
char output[MAX_STRING_LENGTH];
sprintf(output, "Syntax: create [0 < vnum < %d]\n\r", INT_MAX);
send_to_char(output, ch);
return FALSE;
}
pArea = get_vnum_area(value);
if (!pArea)
{
send_to_char("MEdit: That vnum is not assigned an area.\n\r", ch);
return FALSE;
}
if (!is_builder(ch, pArea))
{
send_to_char("MEdit: Vnum in an area you cannot build in.\n\r", ch);
return FALSE;
}
if (get_mob_index(value))
{
send_to_char("MEdit: Mobile vnum already exists.\n\r", ch);
return FALSE;
}
pMob = new_mob_index();
pMob->vnum = value;
pMob->area = pArea;
if (value > top_vnum_mob)
top_vnum_mob = value;
pMob->act = ACT_IS_NPC;
iHash = value % MAX_KEY_HASH;
pMob->next = mob_index_hash[iHash];
mob_index_hash[iHash] = pMob;
ch->desc->pEdit = (void *) pMob;
send_to_char("Mobile Created.\n\r", ch);
return TRUE;
}
bool medit_spec(CHAR_DATA * ch, char *argument)
{
MOB_INDEX_DATA *pMob;
pMob = edit_mob(ch);
if (argument[0] == '\0')
{
send_to_char("Syntax: spec [special function]\n\r", ch);
return FALSE;
}
if (!str_cmp(argument, "none"))
{
pMob->spec_fun = NULL;
send_to_char("Spec removed.\n\r", ch);
return TRUE;
}
if (spec_lookup(argument))
{
pMob->spec_fun = spec_lookup(argument);
send_to_char("Spec set.\n\r", ch);
return TRUE;
}
send_to_char("MEdit: No such special function.\n\r", ch);
return FALSE;
}
bool medit_align(CHAR_DATA * ch, char *argument)
{
MOB_INDEX_DATA *pMob;
pMob = edit_mob(ch);
if (argument[0] == '\0' || !is_number(argument))
{
send_to_char("Syntax: alignment [number]\n\r", ch);
return FALSE;
}
pMob->alignment = atoi(argument);
send_to_char("Alignment set.\n\r", ch);
return TRUE;
}
bool medit_level(CHAR_DATA * ch, char *argument)
{
MOB_INDEX_DATA *pMob;
pMob = edit_mob(ch);
if (argument[0] == '\0' || !is_number(argument))
{
send_to_char("Syntax: level [number]\n\r", ch);
return FALSE;
}
pMob->level = atoi(argument);
send_to_char("Level set.\n\r", ch);
return TRUE;
}
bool medit_desc(CHAR_DATA * ch, char *argument)
{
MOB_INDEX_DATA *pMob;
pMob = edit_mob(ch);
if (argument[0] == '\0')
{
string_append(ch, &pMob->description);
return TRUE;
}
send_to_char("Syntax: desc - line edit\n\r", ch);
return FALSE;
}
bool medit_long(CHAR_DATA * ch, char *argument)
{
MOB_INDEX_DATA *pMob;
pMob = edit_mob(ch);
if (argument[0] == '\0')
{
send_to_char("Syntax: long [string]\n\r", ch);
return FALSE;
}
free_string(pMob->long_descr);
strcat(argument, "\n\r");
pMob->long_descr = str_dup(argument);
pMob->long_descr[0] = UPPER(pMob->long_descr[0]);
send_to_char("Long description set.\n\r", ch);
return TRUE;
}
bool medit_short(CHAR_DATA * ch, char *argument)
{
MOB_INDEX_DATA *pMob;
pMob = edit_mob(ch);
if (argument[0] == '\0')
{
send_to_char("Syntax: short [string]\n\r", ch);
return FALSE;
}
free_string(pMob->short_descr);
pMob->short_descr = str_dup(argument);
send_to_char("Short description set.\n\r", ch);
return TRUE;
}
bool medit_name(CHAR_DATA * ch, char *argument)
{
MOB_INDEX_DATA *pMob;
pMob = edit_mob(ch);
if (argument[0] == '\0')
{
send_to_char("Syntax: name [string]\n\r", ch);
return FALSE;
}
free_string(pMob->player_name);
pMob->player_name = str_dup(argument);
send_to_char("Name set.\n\r", ch);
return TRUE;
}
bool medit_shop(CHAR_DATA * ch, char *argument)
{
MOB_INDEX_DATA *pMob;
char command[MAX_INPUT_LENGTH];
char arg1[MAX_INPUT_LENGTH];
argument = one_argument(argument, command);
argument = one_argument(argument, arg1);
pMob = edit_mob(ch);
if (command[0] == '\0')
{
send_to_char("Syntax: shop hours [#opening] [#closing]\n\r", ch);
send_to_char(" shop profit [#buying%] [#selling%]\n\r", ch);
send_to_char(" shop type [#0-4] [item type]\n\r", ch);
send_to_char(" shop delete [#0-4]\n\r", ch);
return FALSE;
}
if (!str_cmp(command, "hours"))
{
if (arg1[0] == '\0' || !is_number(arg1)
|| argument[0] == '\0' || !is_number(argument))
{
send_to_char("Syntax: shop hours [#opening] [#closing]\n\r", ch);
return FALSE;
}
if (!pMob->pShop)
{
pMob->pShop = new_shop();
pMob->pShop->keeper = pMob->vnum;
shop_last->next = pMob->pShop;
}
pMob->pShop->open_hour = atoi(arg1);
pMob->pShop->close_hour = atoi(argument);
send_to_char("Shop hours set.\n\r", ch);
return TRUE;
}
if (!str_cmp(command, "profit"))
{
if (arg1[0] == '\0' || !is_number(arg1)
|| argument[0] == '\0' || !is_number(argument))
{
send_to_char("Syntax: shop profit [#buying%] [#selling%]\n\r", ch);
return FALSE;
}
if (!pMob->pShop)
{
pMob->pShop = new_shop();
pMob->pShop->keeper = pMob->vnum;
shop_last->next = pMob->pShop;
}
pMob->pShop->profit_buy = atoi(arg1);
pMob->pShop->profit_sell = atoi(argument);
send_to_char("Shop profit set.\n\r", ch);
return TRUE;
}
if (!str_cmp(command, "type"))
{
char buf[MAX_INPUT_LENGTH];
int value;
if (arg1[0] == '\0' || !is_number(arg1)
|| argument[0] == '\0')
{
send_to_char("Syntax: shop type [#0-4] [item type]\n\r", ch);
return FALSE;
}
if (atoi(arg1) >= MAX_TRADE)
{
sprintf(buf, "REdit: May sell %d items max.\n\r", MAX_TRADE);
send_to_char(buf, ch);
return FALSE;
}
if ((value = flag_value(type_flags, argument)) == NO_FLAG)
{
send_to_char("REdit: That type of item is not known.\n\r", ch);
return FALSE;
}
if (!pMob->pShop)
{
pMob->pShop = new_shop();
pMob->pShop->keeper = pMob->vnum;
shop_last->next = pMob->pShop;
}
pMob->pShop->buy_type[atoi(arg1)] = value;
send_to_char("Shop type set.\n\r", ch);
return TRUE;
}
if (!str_cmp(command, "delete"))
{
SHOP_DATA *pShop;
SHOP_DATA *pShop_next;
int value;
int cnt = 0;
if (arg1[0] == '\0' || !is_number(arg1))
{
send_to_char("Syntax: shop delete [#0-4]\n\r", ch);
return FALSE;
}
value = atoi(argument);
if (!pMob->pShop)
{
send_to_char("REdit: Non-existant shop.\n\r", ch);
return FALSE;
}
if (value == 0)
{
pShop = pMob->pShop;
pMob->pShop = pMob->pShop->next;
free_shop(pShop);
}
else
for (pShop = pMob->pShop, cnt = 0; pShop; pShop = pShop_next, cnt++)
{
pShop_next = pShop->next;
if (cnt + 1 == value)
{
pShop->next = pShop_next->next;
free_shop(pShop_next);
break;
}
}
send_to_char("Shop deleted.\n\r", ch);
return TRUE;
}
medit_shop(ch, "");
return FALSE;
}
/*
* MobProg Editor Functions.
*/
MPEDIT(mpedit_show)
{
MOB_INDEX_DATA *pMob;
MPROG_DATA *pMobProg;
char buf[MAX_STRING_LENGTH];
pMob = edit_mob(ch);
pMobProg = edit_mprog(ch, pMob);
if (argument[0] == '\0') /*
* Show current mobprog
*/
show_mprog(ch, pMobProg);
else if (is_number(argument)) /*
* show a specific mobprog
*/
{
MPROG_DATA *mprg;
int prg = atoi(argument);
int cnt = mprog_count(pMob);
if (prg < 1 || prg > cnt)
{
sprintf(buf, "MPEdit: Valid range is 1 to %d.\n\r", cnt);
send_to_char(buf, ch);
return FALSE;
}
for (mprg = pMob->mobprogs; mprg && prg-- > 1; mprg = mprg->next)
;
show_mprog(ch, mprg);
}
else if (!str_cmp(argument, "all"))
{
for (pMobProg = pMob->mobprogs; pMobProg;
pMobProg = pMobProg->next)
show_mprog(ch, pMobProg);
send_to_char("|\n\r", ch);
}
else
send_to_char("Syntax: show [all]\n\r", ch);
return FALSE;
}
MPEDIT(mpedit_create)
{
MOB_INDEX_DATA *pMob;
AREA_DATA *pArea;
MPROG_DATA *mprg;
int value;
value = atoi(argument);
if (argument[0] == '\0' || value == 0)
{
send_to_char("Syntax: mpedit create vnum [svnum]\n\r", ch);
return FALSE;
}
pArea = get_vnum_area(value);
if (!pArea)
{
send_to_char("MPEdit: That vnum is not assigned an area.\n\r", ch);
return FALSE;
}
if (!is_builder(ch, pArea))
{
send_to_char("MPEdit: Vnum in an area you cannot build in.\n\r", ch);
return FALSE;
}
if (!(pMob = get_mob_index(value)))
{
send_to_char("MPEdit: Mobile vnum does not exist!\n\r", ch);
return FALSE;
}
if (pMob->mobprogs)
{
send_to_char("MPEdit: Mobile already has mob programs!\n\r", ch);
return FALSE;
}
pMob->mobprogs = (MPROG_DATA *) alloc_perm(sizeof(MPROG_DATA));
mprg = pMob->mobprogs;
/*
* empty mob-program
*/
mprg->type = 0;
mprg->comlist = str_dup("break\n");
mprg->arglist = str_dup("0");
ch->desc->pEdit = (void *) pMob;
ch->pcdata->mprog_edit = 0;
send_to_char("MOBProg Created.\n\r", ch);
return TRUE;
}
MPEDIT(mpedit_add)
{
MOB_INDEX_DATA *pMob;
MPROG_DATA *mprg, *mprg2;
char buf[MAX_INPUT_LENGTH];
int count;
pMob = edit_mob(ch);
if (!pMob->mobprogs)
{
send_to_char("Mobile doesn't have mobprogs. Use create.\n\r", ch);
return FALSE;
}
count = mprog_count(pMob);
/*
* find last mobprog and add after it
*/
for (mprg = mprg2 = pMob->mobprogs; mprg; mprg2 = mprg, mprg = mprg->next)
;
mprg2->next = (MPROG_DATA *) alloc_perm(sizeof(MPROG_DATA));
mprg = mprg2->next;
mprg->type = 0;
mprg->arglist = str_dup("0");
mprg->comlist = str_dup("break\n");
count++;
ch->pcdata->mprog_edit = count - 1;
sprintf(buf, "MOBProg %d Added.\n\r", count);
send_to_char(buf, ch);
return TRUE;
}
MPEDIT(mpedit_delete)
{
MOB_INDEX_DATA *pMob;
char arg[MAX_INPUT_LENGTH];
int count, pnum;
pMob = edit_mob(ch);
count = mprog_count(pMob);
argument = one_argument(argument, arg);
if (arg[0] == '\0') /*
* No argument - delete current program
*/
{
delete_mprog(ch, ch->pcdata->mprog_edit);
}
else if (is_number(arg))
{
if ((pnum = atoi(arg)) > count)
{
send_to_char("Mobile does not have that many programs.\n\r", ch);
return FALSE;
}
delete_mprog(ch, pnum - 1);
}
else if (!str_cmp(arg, "all"))
{
for (pnum = count - 1; pnum >= 0; pnum--)
delete_mprog(ch, pnum);
}
else
{
send_to_char("Syntax: delete [#pnum/all]\n\r", ch);
return FALSE;
}
count = mprog_count(pMob); /*
* Get new count
*/
if (ch->pcdata->mprog_edit >= count)
{
ch->pcdata->mprog_edit = count - 1;
if (count == 0)
edit_done(ch, "");
}
send_to_char("Ok.\n\r", ch);
return TRUE;
}
MPEDIT(mpedit_copy)
{
MOB_INDEX_DATA *pMob, *cMob;
MPROG_DATA *mprg, *mprg_next, *cprg;
int value;
pMob = edit_mob(ch);
if (argument[0] == '\0' || !is_number(argument))
{
send_to_char("Syntax: copy [vnum]\n\r", ch);
return FALSE;
}
value = atoi(argument);
if (!(cMob = get_mob_index(value)))
{
send_to_char("No such mobile exists.\n\r", ch);
return FALSE;
}
if (cMob == pMob)
{
send_to_char("You can't copy from yourself, sorry.\n\r", ch);
return FALSE;
}
if (!cMob->mobprogs)
{
send_to_char("That mobile doesn't have mobprogs!\n\r", ch);
return FALSE;
}
/*
* free existing mobprog list
*/
for (mprg = pMob->mobprogs; mprg; mprg = mprg_next)
{
mprg_next = mprg->next;
free_string(mprg->arglist);
free_string(mprg->comlist);
free_mem(mprg, sizeof(MPROG_DATA));
}
mprg = pMob->mobprogs = (MPROG_DATA *) alloc_perm(sizeof(MPROG_DATA));
/*
* Start copying
*/
for (cprg = cMob->mobprogs; cprg;
cprg = cprg->next, mprg = mprg->next)
{
mprg->type = cprg->type;
SET_BIT(pMob->progtypes, cprg->type);
mprg->arglist = str_dup(cprg->arglist);
mprg->comlist = str_dup(cprg->comlist);
if (cprg->next)
mprg->next = (MPROG_DATA *) alloc_perm(sizeof(MPROG_DATA));
else
mprg->next = NULL;
}
ch->pcdata->mprog_edit = mprog_count(pMob) - 1;
send_to_char("MOBProg copied.\n\r", ch);
return TRUE;
}
MPEDIT(mpedit_trigger)
{
MOB_INDEX_DATA *pMob;
MPROG_DATA *pMobProg;
if (argument[0] == '\0')
{
send_to_char("Syntax: trigger [trigger value(s)]\n\r", ch);
return FALSE;
}
pMob = edit_mob(ch);
pMobProg = edit_mprog(ch, pMob);
free_string(pMobProg->arglist);
pMobProg->arglist = str_dup(argument);
return TRUE;
}
MPEDIT(mpedit_program)
{
MOB_INDEX_DATA *pMob;
MPROG_DATA *pMobProg;
pMob = edit_mob(ch);
pMobProg = edit_mprog(ch, pMob);
if (argument[0] == '\0')
{
string_append(ch, &pMobProg->comlist);
return TRUE;
}
send_to_char("Syntax: program\n\r", ch);
return FALSE;
}
int mprog_count(MOB_INDEX_DATA * pMob)
{
MPROG_DATA *mprg;
int count;
for (count = 0, mprg = pMob->mobprogs;
mprg;
mprg = mprg->next, count++)
;
return count;
}
MPROG_DATA *edit_mprog(CHAR_DATA * ch, MOB_INDEX_DATA * pMob)
{
MPROG_DATA *mprg;
int mprog_num;
int count = 0;
if (IS_NPC(ch))
return NULL;
mprog_num = ch->pcdata->mprog_edit;
for (mprg = pMob->mobprogs; mprg && count < mprog_num; mprg = mprg->next)
count++;
return mprg;
}
void show_mprog(CHAR_DATA * ch, MPROG_DATA * pMobProg)
{
char buf[MAX_STRING_LENGTH];
sprintf(buf, ">%s %s~\n\r",
mprog_type_to_name(pMobProg->type),
pMobProg->arglist ? pMobProg->arglist : "NULL");
send_to_char(buf, ch);
sprintf(buf, "%s~\n\r", pMobProg->comlist
? pMobProg->comlist
: "NULL\n\r");
send_to_char(buf, ch);
}
void delete_mprog(CHAR_DATA * ch, int pnum)
{
MPROG_DATA *mprg, *mprg_prev;
MOB_INDEX_DATA *pMob;
char buf[MAX_INPUT_LENGTH];
int count;
pMob = edit_mob(ch);
if (pnum < 0) /*
* sanity check
*/
return;
if (pnum == 0)
{
free_string(pMob->mobprogs->arglist);
free_string(pMob->mobprogs->comlist);
mprg = pMob->mobprogs->next;
/*
* Here is where we would recycle the memory of pMob->mobprogs...
* no such mechanism yet so this actually IS a sort of memory leak
* since memory allocated with alloc_perm cannot be freed. Walker
*/
pMob->mobprogs = mprg;
}
else
{
mprg_prev = pMob->mobprogs;
mprg = mprg_prev->next;
for (count = 1; mprg && count < pnum; count++)
{
mprg_prev = mprg;
mprg = mprg->next;
}
if (mprg)
{
free_string(mprg->arglist);
free_string(mprg->comlist);
mprg_prev->next = mprg->next;
/*
* Here is where we would recycle the memory of mprg...
* no such mechanism yet so this actually IS a sort of memory leak
* since memory allocated with alloc_perm cannot be freed. Walker
*/
}
}
sprintf(buf, "MOBProg %d Deleted.\n\r", pnum + 1);
send_to_char(buf, ch);
return;
}