/**************************************************************************
* 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-2002 by Ryan Jennings *
* http://1stmud.dlmud.com/ <r-jenn@shaw.ca> *
***************************************************************************/
/***************************************************************************
* 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. *
* *
***************************************************************************/
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "tables.h"
#include "olc.h"
#include "recycle.h"
#include "lookup.h"
#include "interp.h"
#include "magic.h"
#define ALT_FLAGVALUE_SET( _blargh, _table, _arg ) \
{ \
flag_t blah = flag_value( _table, _arg ); \
_blargh = UMAX(0, blah); \
}
#define ALT_FLAGVALUE_TOGGLE( _blargh, _table, _arg ) \
{ \
flag_t blah = flag_value( _table, _arg ); \
TOGGLE_BIT(_blargh, UMAX(0, blah)); \
}
/* Return TRUE if area changed, FALSE if not. */
#define REDIT( fun ) bool fun( CHAR_DATA *ch, const char *argument )
#define OEDIT( fun ) bool fun( CHAR_DATA *ch, const char *argument )
#define MEDIT( fun ) bool fun( CHAR_DATA *ch, const char *argument )
#define AEDIT( fun ) bool fun( CHAR_DATA *ch, const char *argument )
#define CEDIT( fun ) bool fun( CHAR_DATA *ch, const char *argument )
struct olc_help_type
{
char *command;
const void *structure;
char *desc;
};
void unlink_reset(ROOM_INDEX_DATA * pRoom, RESET_DATA * pReset)
{
RESET_DATA *prev, *wReset;
for (wReset = pRoom->reset_first; wReset; wReset = prev)
{
prev = wReset->next;
if (wReset == pReset)
{
UNLINK(pReset, pRoom->reset_first, pRoom->reset_last, next, prev);
}
}
}
void unlink_obj_index(OBJ_INDEX_DATA * pObj)
{
int iHash;
iHash = pObj->vnum % MAX_KEY_HASH;
UNLINK_SINGLE(pObj, next, OBJ_INDEX_DATA, obj_index_hash[iHash]);
}
void unlink_room_index(ROOM_INDEX_DATA * pRoom)
{
int iHash;
iHash = pRoom->vnum % MAX_KEY_HASH;
UNLINK_SINGLE(pRoom, next, ROOM_INDEX_DATA, room_index_hash[iHash]);
}
void unlink_mob_index(MOB_INDEX_DATA * pMob)
{
int iHash;
iHash = pMob->vnum % MAX_KEY_HASH;
UNLINK_SINGLE(pMob, next, MOB_INDEX_DATA, mob_index_hash[iHash]);
}
bool show_version(CHAR_DATA * ch, char *argument)
{
chprintln(ch, OLC_VERSION);
chprintln(ch, OLC_AUTHOR);
chprintln(ch, OLC_DATE);
chprintln(ch, OLC_CREDITS);
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."},
{"container", container_flags, "Container status."},
{"targets", target_flags, "Skill target types."},
/* ROM specific bits: */
{"armor", ac_type, "Ac for different attacks."},
{"apply", apply_flags, "Apply flags"},
{"form", form_flags, "Mobile body form."},
{"part", part_flags, "Mobile body parts."},
{"imm", imm_flags, "Mobile immunity."},
{"res", res_flags, "Mobile resistance."},
{"vuln", vuln_flags, "Mobile vulnerability."},
{"off", off_flags, "Mobile offensive behaviour."},
{"size", size_flags, "Mobile size."},
{"position", position_flags, "Mobile positions."},
{"wclass", weapon_class, "Weapon class."},
{"wtype", weapon_type2, "Special weapon type."},
{"portal", portal_flags, "Portal types."},
{"furniture", furniture_flags, "Furniture types."},
{"liquid", liq_table, "Liquid types."},
{"apptype", apply_types, "Apply types."},
{"weapon", attack_table, "Weapon types."},
{"mprog", mprog_flags, "MobProgram flags."},
{"logflags", log_flags, "Command log types."},
{NULL, NULL, NULL}
};
/*****************************************************************************
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 != NULL; 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");
chprint(ch, buf1);
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 < maxSkill; 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");
chprint(ch, buf1);
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;
chprintln(ch, "Preceed special functions with 'spec_'\n\r");
for (spec = 0; spec_table[spec].function != NULL; spec++)
{
sprintf(buf, "%-19.18s", &spec_table[spec].name[5]);
strcat(buf1, buf);
if (++col % 4 == 0)
strcat(buf1, "\n\r");
}
if (col % 4 != 0)
strcat(buf1, "\n\r");
chprint(ch, buf1);
return;
}
/*****************************************************************************
Name: show_help
Purpose: Displays help for many tables used in OLC.
Called by: olc interpreters.
****************************************************************************/
bool show_help(CHAR_DATA * ch, const char *argument)
{
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')
{
chprintln(ch, "Syntax: ? [command]\n\r");
chprintln(ch, "[command] [description]");
for (cnt = 0; help_table[cnt].command != NULL; cnt++)
{
chprintlnf(ch, "%-10.10s -%s",
capitalize(help_table[cnt].command),
help_table[cnt].desc);
}
return FALSE;
}
/*
* Find the command, show changeable data.
* ---------------------------------------
*/
for (cnt = 0; help_table[cnt].command != NULL; 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 == liq_table)
{
show_liqlist(ch);
return FALSE;
}
else if (help_table[cnt].structure == attack_table)
{
show_damlist(ch);
return FALSE;
}
else if (help_table[cnt].structure == skill_table)
{
if (spell[0] == '\0')
{
chprintln(ch, "Syntax: ? spells "
"[ignore/attack/defend/self/object/all]");
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
chprintln(ch, "Syntax: ? spell "
"[ignore/attack/defend/self/object/all]");
return FALSE;
}
else
{
show_flag_cmds(ch,
(struct flag_type *) help_table[cnt].structure);
return FALSE;
}
}
}
show_help(ch, "");
return FALSE;
}
REDIT(redit_format)
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM(ch, pRoom);
pRoom->description = format_string(pRoom->description);
chprintln(ch, "String formatted.");
return TRUE;
}
REDIT(redit_rlist)
{
ROOM_INDEX_DATA *pRoomIndex;
AREA_DATA *pArea;
char buf[MAX_STRING_LENGTH];
BUFFER *buf1;
char arg[MAX_INPUT_LENGTH];
bool found;
vnum_t vnum;
int col = 0;
one_argument(argument, arg);
pArea = ch->in_room->area;
buf1 = new_buf();
/* buf1[0] = '\0'; */
found = FALSE;
for (vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++)
{
if ((pRoomIndex = get_room_index(vnum)))
{
found = TRUE;
sprintf(buf, "[%5ld] %-17.16s", vnum, capitalize(pRoomIndex->name));
add_buf(buf1, buf);
if (++col % 3 == 0)
add_buf(buf1, "\n\r");
}
}
if (!found)
{
chprintln(ch, "Room(s) not found in this area.");
return FALSE;
}
if (col % 3 != 0)
add_buf(buf1, "\n\r");
page_to_char(buf_string(buf1), ch);
free_buf(buf1);
return FALSE;
}
REDIT(redit_mlist)
{
MOB_INDEX_DATA *pMobIndex;
AREA_DATA *pArea;
char buf[MAX_STRING_LENGTH];
BUFFER *buf1;
char arg[MAX_INPUT_LENGTH];
bool fAll, found;
vnum_t vnum;
int col = 0;
one_argument(argument, arg);
if (arg[0] == '\0')
{
chprintln(ch, "Syntax: mlist <all/name>");
return FALSE;
}
buf1 = new_buf();
pArea = ch->in_room->area;
/* buf1[0] = '\0'; */
fAll = !str_cmp(arg, "all");
found = FALSE;
for (vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++)
{
if ((pMobIndex = get_mob_index(vnum)) != NULL)
{
if (fAll || is_name(arg, pMobIndex->player_name))
{
found = TRUE;
sprintf(buf, "[%5ld] %-17.16s", pMobIndex->vnum,
capitalize(pMobIndex->short_descr));
add_buf(buf1, buf);
if (++col % 3 == 0)
add_buf(buf1, "\n\r");
}
}
}
if (!found)
{
chprintln(ch, "Mobile(s) not found in this area.");
return FALSE;
}
if (col % 3 != 0)
add_buf(buf1, "\n\r");
page_to_char(buf_string(buf1), ch);
free_buf(buf1);
return FALSE;
}
REDIT(redit_delete)
{
ROOM_INDEX_DATA *pRoom, *pRoom2;
RESET_DATA *pReset;
EXIT_DATA *ex;
OBJ_DATA *Obj, *obj_next;
CHAR_DATA *wch, *wnext;
EXTRA_DESCR_DATA *pExtra;
char arg[MIL];
vnum_t pIndex, v;
int i, iHash, rcount, ecount, mcount, ocount, edcount;
if (IS_NULLSTR(argument))
{
if (ch)
chprintln(ch, "Syntax: redit delete [vnum]");
return FALSE;
}
one_argument(argument, arg);
if (is_number(arg))
{
pIndex = atol(arg);
pRoom = get_room_index(pIndex);
}
else
{
if (ch)
chprintln(ch, "That is not a number.");
return FALSE;
}
for (i = 0; vnum_table[i].vnum != -1; i++)
{
if (vnum_table[i].type != VNUM_ROOM)
continue;
if (vnum_table[i].vnum == pIndex)
{
if (ch)
chprintln(ch, "That vnum is reserved.");
return FALSE;
}
}
if (!pRoom)
{
if (ch)
chprintln(ch, "No such room.");
return FALSE;
}
stop_editing(pRoom);
SET_BIT(pRoom->area->area_flags, AREA_CHANGED);
rcount = 0;
for (pReset = pRoom->reset_first; pReset; pReset = pReset->next)
{
rcount++;
}
ocount = 0;
for (Obj = pRoom->first_content; Obj; Obj = obj_next)
{
obj_next = Obj->next_content;
extract_obj(Obj);
ocount++;
}
mcount = 0;
for (wch = pRoom->first_person; wch; wch = wnext)
{
wnext = wch->next_in_room;
if (IS_NPC(wch))
{
extract_char(wch, TRUE);
mcount++;
}
else
{
chprintln(wch,
"This room is being deleted. Moving you somewhere safe.");
if (wch->fighting != NULL)
stop_fighting(wch, TRUE);
char_from_room(wch);
char_to_room(wch, get_room_index(ROOM_VNUM_TEMPLE));
wch->was_in_room = wch->in_room;
}
}
ecount = 0;
for (iHash = 0; iHash < MAX_KEY_HASH; iHash++)
{
for (pRoom2 = room_index_hash[iHash]; pRoom2; pRoom2 = pRoom2->next)
{
for (i = 0; i <= MAX_DIR; i++)
{
if (!(ex = pRoom2->exit[i]))
continue;
if (pRoom2 == pRoom)
{
ecount++;
continue;
}
if (ex->u1.to_room == pRoom)
{
free_exit(pRoom2->exit[i]);
pRoom2->exit[i] = NULL;
SET_BIT(pRoom2->area->area_flags, AREA_CHANGED);
ecount++;
}
}
}
}
edcount = 0;
for (pExtra = pRoom->first_extra_descr; pExtra; pExtra = pExtra->next)
{
edcount++;
}
if (top_vnum_room == pIndex)
for (v = 1; v < pIndex; v++)
if (get_room_index(v))
top_vnum_room = v;
top_room--;
if (!IS_SET(pRoom->room_flags, ROOM_NOEXPLORE))
top_explored--;
unlink_room_index(pRoom);
pRoom->area = NULL;
pRoom->vnum = 0;
free_room_index(pRoom);
if (ch)
{
chprintf(ch,
"Removed room vnum {C%ld{x, %d resets, %d extra "
"descriptions and %d exits.\n\r", pIndex, rcount,
edcount, ecount);
chprintf(ch,
"{C%d{x objects and {C%d{x mobiles were extracted "
"from the room.\n\r", ocount, mcount);
}
return TRUE;
}
REDIT(redit_olist)
{
OBJ_INDEX_DATA *pObjIndex;
AREA_DATA *pArea;
char buf[MAX_STRING_LENGTH];
BUFFER *buf1;
char arg[MAX_INPUT_LENGTH];
bool fAll, found;
vnum_t vnum;
int col = 0;
one_argument(argument, arg);
if (arg[0] == '\0')
{
chprintln(ch, "Syntax: olist <all/name/item_type>");
return FALSE;
}
pArea = ch->in_room->area;
buf1 = new_buf();
/* buf1[0] = '\0'; */
fAll = !str_cmp(arg, "all");
found = FALSE;
for (vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++)
{
if ((pObjIndex = get_obj_index(vnum)))
{
if (fAll || is_name(arg, pObjIndex->name) ||
(int) flag_value(type_flags, arg) == pObjIndex->item_type)
{
found = TRUE;
sprintf(buf, "[%5ld] %-17.16s", pObjIndex->vnum,
capitalize(pObjIndex->short_descr));
add_buf(buf1, buf);
if (++col % 3 == 0)
add_buf(buf1, "\n\r");
}
}
}
if (!found)
{
chprintln(ch, "Object(s) not found in this area.");
return FALSE;
}
if (col % 3 != 0)
add_buf(buf1, "\n\r");
page_to_char(buf_string(buf1), ch);
free_buf(buf1);
return FALSE;
}
REDIT(redit_mshow)
{
MOB_INDEX_DATA *pMob;
vnum_t value;
if (argument[0] == '\0')
{
chprintln(ch, "Syntax: mshow <vnum>");
return FALSE;
}
if (!is_number(argument))
{
chprintln(ch, "REdit: Ingresa un numero.");
return FALSE;
}
if (is_number(argument))
{
value = atol(argument);
if (!(pMob = get_mob_index(value)))
{
chprintln(ch, "REdit: That mobile does not exist.");
return FALSE;
}
ch->desc->pEdit = (void *) pMob;
}
medit_show(ch, argument);
ch->desc->pEdit = (void *) ch->in_room;
return FALSE;
}
REDIT(redit_oshow)
{
OBJ_INDEX_DATA *pObj;
vnum_t value;
if (argument[0] == '\0')
{
chprintln(ch, "Syntax: oshow <vnum>");
return FALSE;
}
if (!is_number(argument))
{
chprintln(ch, "REdit: Ingresa un numero.");
return FALSE;
}
if (is_number(argument))
{
value = atol(argument);
if (!(pObj = get_obj_index(value)))
{
chprintln(ch, "REdit: That object does not exist.");
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(long lower, long upper)
{
AREA_DATA *pArea;
int cnt = 0;
for (pArea = area_first; pArea; pArea = pArea->next)
{
/*
* lower < area < upper
*/
if ((lower <= pArea->min_vnum && pArea->min_vnum <= upper) ||
(lower <= pArea->max_vnum && pArea->max_vnum <= upper))
++cnt;
if (cnt > 1)
return FALSE;
}
return TRUE;
}
AREA_DATA *get_vnum_area(vnum_t vnum)
{
AREA_DATA *pArea;
for (pArea = area_first; pArea; pArea = pArea->next)
{
if (vnum >= pArea->min_vnum && vnum <= pArea->max_vnum)
return pArea;
}
return 0;
}
/*
* Area Editor Functions.
*/
AEDIT(aedit_show)
{
AREA_DATA *pArea;
EDIT_AREA(ch, pArea);
chprintf(ch, "%s\n\r",
stringf(ch, 0, ALIGN_CENTER, "-",
FORMATF("[ %s: %s ]", olc_ed_name(ch), olc_ed_vnum(ch))));
chprintlnf(ch, "Name: [%5d] %s", pArea->vnum, pArea->name);
#if 0 /* ROM OLC */
chprintlnf(ch, "Recall: [%5d] %s", pArea->recall,
get_room_index(pArea->recall) ? get_room_index(pArea->recall)->
name : "none");
#endif /* ROM */
chprintlnf(ch, "File: %s", pArea->file_name);
chprintlnf(ch, "Vnums: [%ld-%ld]", pArea->min_vnum, pArea->max_vnum);
chprintlnf(ch, "Age: [%d]", pArea->age);
chprintlnf(ch, "Players: [%d]", pArea->nplayer);
chprintlnf(ch, "Security: [%d]", pArea->security);
chprintlnf(ch, "Builders: [%s]", pArea->builders);
chprintlnf(ch, "Credits : [%s]", pArea->credits);
chprintlnf(ch, "Flags: [%s]",
flag_string(area_flags, pArea->area_flags));
chprintln(ch, draw_line(ch, NULL, 0));
return FALSE;
}
AEDIT(aedit_reset)
{
AREA_DATA *pArea;
EDIT_AREA(ch, pArea);
reset_area(pArea);
chprintln(ch, "Area reset.");
return FALSE;
}
AEDIT(aedit_create)
{
AREA_DATA *pArea;
pArea = new_area();
add_area(pArea);
top_area++;
edit_start(ch, pArea, ED_AREA);
SET_BIT(pArea->area_flags, AREA_ADDED);
chprintln(ch, "Area Created.");
return FALSE;
}
AEDIT(aedit_file)
{
AREA_DATA *pArea;
char file[MAX_STRING_LENGTH];
int i, length;
EDIT_AREA(ch, pArea);
one_argument(argument, file); /* Forces Lowercase */
if (argument[0] == '\0')
{
chprintln(ch, "Syntax: filename [$file]");
return FALSE;
}
/*
* Simple Syntax Check.
*/
length = strlen(argument);
if (length > 8)
{
chprintln(ch, "No more than eight characters allowed.");
return FALSE;
}
/*
* Allow only letters and numbers.
*/
for (i = 0; i < length; i++)
{
if (!isalnum(file[i]))
{
chprintln(ch, "Only letters and numbers are valid.");
return FALSE;
}
}
free_string(pArea->file_name);
strcat(file, ".are");
pArea->file_name = str_dup(file);
chprintln(ch, "Filename set.");
return TRUE;
}
AEDIT(aedit_builder)
{
AREA_DATA *pArea;
char name[MAX_STRING_LENGTH];
char buf[MAX_STRING_LENGTH];
EDIT_AREA(ch, pArea);
one_argument(argument, name);
if (name[0] == '\0')
{
chprintln(ch, "Syntax: builder [$name] -toggles builder");
chprintln(ch, "Syntax: builder All -allows everyone");
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");
}
chprintln(ch, "Builder removed.");
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));
chprintln(ch, "Builder added.");
chprint(ch, pArea->builders);
return TRUE;
}
return FALSE;
}
AEDIT(aedit_vnum)
{
AREA_DATA *pArea;
char lower[MAX_STRING_LENGTH];
char upper[MAX_STRING_LENGTH];
vnum_t ilower;
vnum_t iupper;
EDIT_AREA(ch, pArea);
argument = one_argument(argument, lower);
one_argument(argument, upper);
if (!is_number(lower) || lower[0] == '\0' || !is_number(upper) ||
upper[0] == '\0')
{
chprintln(ch, "Syntax: vnum [#xlower] [#xupper]");
return FALSE;
}
if ((ilower = atoi(lower)) > (iupper = atoi(upper)))
{
chprintln(ch, "AEdit: Upper must be larger then lower.");
return FALSE;
}
if (!check_range(atol(lower), atol(upper)))
{
chprintln(ch, "AEdit: Range must include only this area.");
return FALSE;
}
if (get_vnum_area(ilower) && get_vnum_area(ilower) != pArea)
{
chprintln(ch, "AEdit: Lower vnum already assigned.");
return FALSE;
}
pArea->min_vnum = ilower;
chprintln(ch, "Lower vnum set.");
if (get_vnum_area(iupper) && get_vnum_area(iupper) != pArea)
{
chprintln(ch, "AEdit: Upper vnum already assigned.");
return TRUE; /* The lower value has been set. */
}
if (iupper > MAX_VNUM)
{
chprintlnf(ch, "Vnum can't be higher than %d.", MAX_VNUM);
return FALSE;
}
pArea->max_vnum = iupper;
chprintln(ch, "Upper vnum set.");
return TRUE;
}
AEDIT(aedit_lvnum)
{
AREA_DATA *pArea;
char lower[MAX_STRING_LENGTH];
vnum_t ilower;
vnum_t iupper;
EDIT_AREA(ch, pArea);
one_argument(argument, lower);
if (!is_number(lower) || lower[0] == '\0')
{
chprintln(ch, "Syntax: min_vnum [#xlower]");
return FALSE;
}
if ((ilower = atol(lower)) > (iupper = pArea->max_vnum))
{
chprintln(ch, "AEdit: Value must be less than the max_vnum.");
return FALSE;
}
if (!check_range(ilower, iupper))
{
chprintln(ch, "AEdit: Range must include only this area.");
return FALSE;
}
if (get_vnum_area(ilower) && get_vnum_area(ilower) != pArea)
{
chprintln(ch, "AEdit: Lower vnum already assigned.");
return FALSE;
}
if (ilower > MAX_VNUM)
{
chprintlnf(ch, "Vnum can't be higher than %d", MAX_VNUM);
return FALSE;
}
pArea->min_vnum = ilower;
chprintln(ch, "Lower vnum set.");
return TRUE;
}
AEDIT(aedit_uvnum)
{
AREA_DATA *pArea;
char upper[MAX_STRING_LENGTH];
vnum_t ilower;
vnum_t iupper;
EDIT_AREA(ch, pArea);
one_argument(argument, upper);
if (!is_number(upper) || upper[0] == '\0')
{
chprintln(ch, "Syntax: max_vnum [#xupper]");
return FALSE;
}
if ((ilower = pArea->min_vnum) > (iupper = atol(upper)))
{
chprintln(ch, "AEdit: Upper must be larger then lower.");
return FALSE;
}
if (!check_range(ilower, iupper))
{
chprintln(ch, "AEdit: Range must include only this area.");
return FALSE;
}
if (get_vnum_area(iupper) && get_vnum_area(iupper) != pArea)
{
chprintln(ch, "AEdit: Upper vnum already assigned.");
return FALSE;
}
pArea->max_vnum = iupper;
chprintln(ch, "Upper vnum set.");
return TRUE;
}
/*
* Room Editor Functions.
*/
REDIT(redit_show)
{
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;
PROG_LIST *list;
EDIT_ROOM(ch, pRoom);
buf1[0] = '\0';
strcat(buf1,
stringf(ch, 0, ALIGN_CENTER, "-",
FORMATF("[ %s: %s ]", olc_ed_name(ch), olc_ed_vnum(ch))));
strcat(buf1, "\n\r");
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: [%5ld]\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->heal_rate != 100 || pRoom->mana_rate != 100)
{
sprintf(buf, "Health rec: [%d]\n\rMana rec : [%d]\n\r",
pRoom->heal_rate, pRoom->mana_rate);
strcat(buf1, buf);
}
if (pRoom->clan != NULL)
{
sprintf(buf, "Clan : %s\n\r", pRoom->clan->name);
strcat(buf1, buf);
}
if (!IS_NULLSTR(pRoom->owner))
{
sprintf(buf, "Owner : [%s]\n\r", pRoom->owner);
strcat(buf1, buf);
}
if (pRoom->first_extra_descr)
{
EXTRA_DESCR_DATA *ed;
strcat(buf1, "Desc Kwds: [");
for (ed = pRoom->first_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->first_person; 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->first_content; 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];
const char *state;
int i, length;
sprintf(buf, "-%-5s to [%5ld] Key: [%5ld] ",
capitalize(dir_name[door]),
pexit->u1.to_room ? pexit->u1.to_room->vnum : 0, /* ROM OLC */
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((char *) 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] = UPPER(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);
}
}
}
strcat(buf1, draw_line(ch, NULL, 0));
chprintln(ch, buf1);
if (pRoom->first_rprog)
{
int cnt;
sprintf(buf, "\n\rROOMPrograms for [%5ld]:", pRoom->vnum);
chprintln(ch, buf);
for (cnt = 0, list = pRoom->first_rprog; list; list = list->next)
{
if (cnt == 0)
{
chprintln(ch, " Number Vnum Trigger Phrase");
chprintln(ch, " ------ ---- ------- ------");
}
chprintlnf(ch, "[%5d] %4ld %7s %s", cnt,
list->vnum, prog_type_to_name(list->trig_type),
list->trig_phrase);
cnt++;
}
}
return FALSE;
}
/* Local function. */
bool change_exit(CHAR_DATA * ch, const char *argument, int door)
{
ROOM_INDEX_DATA *pRoom;
char command[MAX_INPUT_LENGTH];
char arg[MAX_INPUT_LENGTH];
flag_t value;
EDIT_ROOM(ch, pRoom);
/*
* Set the exit flags, needs full argument.
* ----------------------------------------
*/
if ((value = flag_value(exit_flags, argument)) != NO_FLAG)
{
ROOM_INDEX_DATA *pToRoom;
int rev; /* ROM OLC */
if (!pRoom->exit[door])
{
chprintln(ch, "Salida no existe.");
return FALSE;
}
/*
* This room.
*/
TOGGLE_BIT(pRoom->exit[door]->rs_flags, value);
/* Don't toggle exit_info because it can be changed by players. */
pRoom->exit[door]->exit_info = pRoom->exit[door]->rs_flags;
/*
* Connected room.
*/
pToRoom = pRoom->exit[door]->u1.to_room; /* ROM OLC */
rev = rev_dir[door];
if (pToRoom->exit[rev] != NULL)
{
pToRoom->exit[rev]->rs_flags = pRoom->exit[door]->rs_flags;
pToRoom->exit[rev]->exit_info = pRoom->exit[door]->exit_info;
}
chprintln(ch, "Exit flag toggled.");
return TRUE;
}
/*
* Now parse the arguments.
*/
argument = one_argument(argument, command);
one_argument(argument, arg);
if (command[0] == '\0' && argument[0] == '\0') /* Move command. */
{
move_char(ch, door, TRUE); /* ROM OLC */
return FALSE;
}
if (command[0] == '?')
{
do_oldhelp(ch, "EXIT");
return FALSE;
}
if (!str_cmp(command, "delete"))
{
ROOM_INDEX_DATA *pToRoom;
int rev; /* ROM OLC */
if (!pRoom->exit[door])
{
chprintln(ch, "REdit: Cannot delete a null exit.");
return FALSE;
}
/*
* Remove ToRoom Exit.
*/
rev = rev_dir[door];
pToRoom = pRoom->exit[door]->u1.to_room; /* ROM OLC */
if (pToRoom->exit[rev])
{
free_exit(pToRoom->exit[rev]);
pToRoom->exit[rev] = NULL;
}
/*
* Remove this exit.
*/
free_exit(pRoom->exit[door]);
pRoom->exit[door] = NULL;
chprintln(ch, "Exit unlinked.");
return TRUE;
}
if (!str_cmp(command, "link"))
{
EXIT_DATA *pExit;
ROOM_INDEX_DATA *toRoom;
if (arg[0] == '\0' || !is_number(arg))
{
chprintln(ch, "Syntax: [direction] link [vnum]");
return FALSE;
}
value = atol(arg);
if (!(toRoom = get_room_index(value)))
{
chprintln(ch, "REdit: Cannot link to non-existant room.");
return FALSE;
}
if (!IS_BUILDER(ch, toRoom->area))
{
chprintln(ch, "REdit: Cannot link to that area.");
return FALSE;
}
if (toRoom->exit[rev_dir[door]])
{
chprintln(ch, "REdit: Remote side's exit already exists.");
return FALSE;
}
if (!pRoom->exit[door])
pRoom->exit[door] = new_exit();
pRoom->exit[door]->u1.to_room = toRoom;
pRoom->exit[door]->orig_door = door;
door = rev_dir[door];
pExit = new_exit();
pExit->u1.to_room = pRoom;
pExit->orig_door = door;
toRoom->exit[door] = pExit;
chprintln(ch, "Two-way link established.");
return TRUE;
}
if (!str_cmp(command, "dig"))
{
char buf[MAX_STRING_LENGTH];
if (arg[0] == '\0' || !is_number(arg))
{
chprintln(ch, "Syntax: [direction] dig <vnum>");
return FALSE;
}
redit_create(ch, arg);
sprintf(buf, "link %s", arg);
change_exit(ch, buf, door);
return TRUE;
}
if (!str_cmp(command, "room"))
{
ROOM_INDEX_DATA *toRoom;
if (arg[0] == '\0' || !is_number(arg))
{
chprintln(ch, "Syntax: [direction] room [vnum]");
return FALSE;
}
value = atol(arg);
if (!(toRoom = get_room_index(value)))
{
chprintln(ch, "REdit: Cannot link to non-existant room.");
return FALSE;
}
if (!pRoom->exit[door])
pRoom->exit[door] = new_exit();
pRoom->exit[door]->u1.to_room = toRoom; /* ROM OLC */
pRoom->exit[door]->orig_door = door;
chprintln(ch, "One-way link established.");
return TRUE;
}
if (!str_cmp(command, "key"))
{
OBJ_INDEX_DATA *key;
if (arg[0] == '\0' || !is_number(arg))
{
chprintln(ch, "Syntax: [direction] key [vnum]");
return FALSE;
}
if (!pRoom->exit[door])
{
chprintln(ch, "Salida no existe.");
return FALSE;
}
value = atol(arg);
if (!(key = get_obj_index(value)))
{
chprintln(ch, "REdit: Key doesn't exist.");
return FALSE;
}
if (key->item_type != ITEM_KEY)
{
chprintln(ch, "REdit: Objeto no es llave.");
return FALSE;
}
pRoom->exit[door]->key = value;
chprintln(ch, "Exit key set.");
return TRUE;
}
if (!str_cmp(command, "name"))
{
if (arg[0] == '\0')
{
chprintln(ch, "Syntax: [direction] name [string]");
chprintln(ch, " [direction] name none");
return FALSE;
}
if (!pRoom->exit[door])
{
chprintln(ch, "Salida no existe.");
return FALSE;
}
free_string(pRoom->exit[door]->keyword);
if (str_cmp(arg, "none"))
pRoom->exit[door]->keyword = str_dup(arg);
else
pRoom->exit[door]->keyword = str_dup("");
chprintln(ch, "Exit name set.");
return TRUE;
}
if (!str_prefix(command, "description"))
{
if (arg[0] == '\0')
{
if (!pRoom->exit[door])
{
chprintln(ch, "Salida no existe.");
return FALSE;
}
string_append(ch, &pRoom->exit[door]->description);
return TRUE;
}
chprintln(ch, "Syntax: [direction] desc");
return FALSE;
}
return FALSE;
}
REDIT(redit_create)
{
AREA_DATA *pArea;
ROOM_INDEX_DATA *pRoom;
vnum_t value;
int iHash;
EDIT_ROOM(ch, pRoom);
value = atol(argument);
if (argument[0] == '\0' || value <= 0)
{
chprintln(ch, "Syntax: create [vnum > 0]");
return FALSE;
}
pArea = get_vnum_area(value);
if (!pArea)
{
chprintln(ch, "REdit: That vnum is not assigned an area.");
return FALSE;
}
if (!IS_BUILDER(ch, pArea))
{
chprintln(ch, "REdit: Vnum in an area you cannot build in.");
return FALSE;
}
if (get_room_index(value))
{
chprintln(ch, "REdit: Room vnum already exists.");
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;
LINK_SINGLE(pRoom, next, room_index_hash[iHash]);
edit_start(ch, pRoom, ED_ROOM);
chprintln(ch, "Room created.");
return TRUE;
}
REDIT(redit_clan)
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM(ch, pRoom);
pRoom->clan = clan_lookup(argument);
chprintln(ch, "Clan set.");
return TRUE;
}
REDIT(redit_mreset)
{
ROOM_INDEX_DATA *pRoom;
MOB_INDEX_DATA *pMobIndex;
CHAR_DATA *newmob;
char arg[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
RESET_DATA *pReset;
EDIT_ROOM(ch, pRoom);
argument = one_argument(argument, arg);
argument = one_argument(argument, arg2);
if (arg[0] == '\0' || !is_number(arg))
{
chprintln(ch, "Syntax: mreset <vnum> <max #x> <mix #x>");
return FALSE;
}
if (!(pMobIndex = get_mob_index(atol(arg))))
{
chprintln(ch, "REdit: No mobile has that vnum.");
return FALSE;
}
if (pMobIndex->area != pRoom->area)
{
chprintln(ch, "REdit: No such mobile in this area.");
return FALSE;
}
/*
* Create the mobile reset.
*/
pReset = new_reset_data();
pReset->command = 'M';
pReset->arg1 = pMobIndex->vnum;
pReset->arg2 = is_number(arg2) ? atoi(arg2) : MAX_MOB;
pReset->arg3 = pRoom->vnum;
pReset->arg4 = is_number(argument) ? atoi(argument) : 1;
add_reset(pRoom, pReset, 0 /* Last slot */ );
/*
* Create the mobile.
*/
newmob = create_mobile(pMobIndex);
char_to_room(newmob, pRoom);
chprintlnf(ch,
"%s (%ld) has been loaded and added to resets.\n\r"
"There will be a maximum of %d loaded to this room.",
capitalize(pMobIndex->short_descr), pMobIndex->vnum,
pReset->arg2);
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[] = {
{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},
{-2, -2}
};
/*****************************************************************************
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(flag_t bits, int count)
{
int flag;
for (flag = 0; wear_table[flag].wear_bit != -2; flag++)
{
if (IS_SET(bits, wear_table[flag].wear_bit) && --count < 1)
return wear_table[flag].wear_loc;
}
return 0;
}
/*****************************************************************************
Name: wear_bit
Purpose: Converts a wear_loc into a bit.
Called by: redit_oreset(olc_act.c).
****************************************************************************/
flag_t wear_bit(int loc)
{
int flag;
for (flag = 0; wear_table[flag].wear_loc != -2; flag++)
{
if (loc == wear_table[flag].wear_loc)
return wear_table[flag].wear_bit;
}
return 0;
}
REDIT(redit_oreset)
{
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;
EDIT_ROOM(ch, pRoom);
argument = one_argument(argument, arg1);
argument = one_argument(argument, arg2);
if (arg1[0] == '\0' || !is_number(arg1))
{
chprintln(ch, "Syntax: oreset <vnum> <args>");
chprintln(ch, " -no_args = into room");
chprintln(ch, " -<obj_name> = into obj");
chprintln(ch, " -<mob_name> <wear_loc> = into mob");
return FALSE;
}
if (!(pObjIndex = get_obj_index(atol(arg1))))
{
chprintln(ch, "REdit: No object has that vnum.");
return FALSE;
}
if (pObjIndex->area != pRoom->area)
{
chprintln(ch, "REdit: No such object in this area.");
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;
pReset->arg4 = 0;
add_reset(pRoom, pReset, 0 /* Last slot */ );
newobj = create_object(pObjIndex, number_fuzzy(olevel));
obj_to_room(newobj, pRoom);
chprintlnf(ch,
"%s (%ld) has been loaded and added to resets.",
capitalize(pObjIndex->short_descr), pObjIndex->vnum);
}
else
/*
* Load into object's inventory.
*/
if (argument[0] == '\0' &&
((to_obj = get_obj_list(ch, arg2, pRoom->first_content)) != NULL))
{
pReset = new_reset_data();
pReset->command = 'P';
pReset->arg1 = pObjIndex->vnum;
pReset->arg2 = 0;
pReset->arg3 = to_obj->pIndexData->vnum;
pReset->arg4 = 1;
add_reset(pRoom, pReset, 0 /* Last slot */ );
newobj = create_object(pObjIndex, number_fuzzy(olevel));
newobj->cost = 0;
obj_to_obj(newobj, to_obj);
chprintlnf(ch,
"%s (%ld) has been loaded into "
"%s (%ld) and added to resets.",
capitalize(newobj->short_descr),
newobj->pIndexData->vnum, to_obj->short_descr,
to_obj->pIndexData->vnum);
}
else
/*
* Load into mobile's inventory.
*/
if ((to_mob = get_char_room(ch, NULL, arg2)) != NULL)
{
int pwear_loc = -1;
/*
* Make sure the location on mobile is valid.
*/
if ((pwear_loc = flag_value(wear_loc_flags, argument)) == NO_FLAG)
{
chprintln(ch, "REdit: Invalid wear_loc. '? wear-loc'");
return FALSE;
}
/*
* Disallow loading a sword(WEAR_WIELD) into WEAR_HEAD.
*/
if (!IS_SET(pObjIndex->wear_flags, wear_bit(pwear_loc)))
{
chprintlnf(ch, "%s (%ld) has wear flags: [%s]",
capitalize(pObjIndex->short_descr),
pObjIndex->vnum, flag_string(wear_flags,
pObjIndex->wear_flags));
return FALSE;
}
/*
* Can't load into same position.
*/
if (get_eq_char(to_mob, pwear_loc))
{
chprintln(ch, "REdit: Object already equipped.");
return FALSE;
}
pReset = new_reset_data();
pReset->arg1 = pObjIndex->vnum;
pReset->arg2 = pwear_loc;
pReset->arg3 = pwear_loc;
if (pReset->arg2 == WEAR_NONE)
pReset->command = 'G';
else
pReset->command = 'E';
add_reset(pRoom, pReset, 0 /* Last slot */ );
olevel = URANGE(0, to_mob->level - 2, MAX_MORTAL_LEVEL);
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);
chprintlnf(ch,
"%s (%ld) has been loaded "
"%s of %s (%ld) and added to resets.",
capitalize(pObjIndex->short_descr), pObjIndex->vnum,
flag_string(wear_loc_strings, pReset->arg3),
to_mob->short_descr, to_mob->pIndexData->vnum);
}
else /* Display Syntax */
{
chprintln(ch, "REdit: That mobile isn't here.");
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)
{
switch (obj->item_type)
{
default: /* No values. */
break;
case ITEM_LIGHT:
if (obj->value[2] == -1 || obj->value[2] == 999) /* ROM OLC */
chprintln(ch, "[v2] Light: Infinite[-1]");
else
chprintlnf(ch, "[v2] Light: [%ld]", obj->value[2]);
break;
case ITEM_WAND:
case ITEM_STAFF:
chprintlnf(ch,
"[v0] Level: [%ld]\n\r"
"[v1] Charges Total: [%ld]\n\r"
"[v2] Charges Left: [%ld]\n\r"
"[v3] Spell: %s", obj->value[0],
obj->value[1], obj->value[2],
obj->value[3] !=
-1 ? skill_table[obj->value[3]].name : "none");
break;
case ITEM_PORTAL:
chprintlnf(ch,
"[v0] Charges: [%ld]\n\r"
"[v1] Exit Flags: %s\n\r"
"[v2] Portal Flags: %s\n\r"
"[v3] Goes to (vnum): [%ld]", obj->value[0],
flag_string(exit_flags, obj->value[1]),
flag_string(portal_flags, obj->value[2]), obj->value[3]);
break;
case ITEM_FURNITURE:
chprintlnf(ch,
"[v0] Max people: [%ld]\n\r"
"[v1] Max weight: [%ld]\n\r"
"[v2] Furniture Flags: %s\n\r"
"[v3] Heal bonus: [%ld]\n\r"
"[v4] Mana bonus: [%ld]", obj->value[0],
obj->value[1], flag_string(furniture_flags,
obj->value[2]),
obj->value[3], obj->value[4]);
break;
case ITEM_SCROLL:
case ITEM_POTION:
case ITEM_PILL:
chprintlnf(ch,
"[v0] Level: [%ld]\n\r" "[v1] Spell: %s\n\r"
"[v2] Spell: %s\n\r" "[v3] Spell: %s\n\r"
"[v4] Spell: %s", 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");
break;
/* ARMOR for ROM */
case ITEM_ARMOR:
chprintlnf(ch,
"[v0] Ac pierce [%ld]\n\r"
"[v1] Ac bash [%ld]\n\r"
"[v2] Ac slash [%ld]\n\r"
"[v3] Ac exotic [%ld]", obj->value[0],
obj->value[1], obj->value[2], obj->value[3]);
break;
/* WEAPON changed in ROM: */
/* I had to split the output here, I have no idea why, but it helped -- Hugin */
/* It somehow fixed a bug in showing scroll/pill/potions too ?! */
case ITEM_WEAPON:
chprintlnf(ch, "[v0] Weapon class: %s",
flag_string(weapon_class, obj->value[0]));
chprintlnf(ch, "[v1] Number of dice: [%ld]", obj->value[1]);
chprintlnf(ch, "[v2] Type of dice: [%ld]", obj->value[2]);
chprintlnf(ch, "[v3] Type: %s",
attack_table[obj->value[3]].name);
chprintlnf(ch, "[v4] Special type: %s",
flag_string(weapon_type2, obj->value[4]));
break;
case ITEM_CONTAINER:
chprintlnf(ch,
"[v0] Weight: [%ld kg]\n\r"
"[v1] Flags: [%s]\n\r" "[v2] Key: %s [%ld]\n\r"
"[v3] Capacity [%ld]\n\r"
"[v4] Weight Mult [%ld]", 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], obj->value[3], obj->value[4]);
break;
case ITEM_DRINK_CON:
chprintlnf(ch,
"[v0] Liquid Total: [%ld]\n\r"
"[v1] Liquid Left: [%ld]\n\r"
"[v2] Liquid: %s\n\r" "[v3] Poisoned: %s",
obj->value[0], obj->value[1],
liq_table[obj->value[2]].liq_name,
obj->value[3] != 0 ? "Yes" : "No");
break;
case ITEM_FOUNTAIN:
chprintlnf(ch,
"[v0] Liquid Total: [%ld]\n\r"
"[v1] Liquid Left: [%ld]\n\r"
"[v2] Liquid: %s", obj->value[0],
obj->value[1], liq_table[obj->value[2]].liq_name);
break;
case ITEM_FOOD:
chprintlnf(ch,
"[v0] Food hours: [%ld]\n\r"
"[v1] Full hours: [%ld]\n\r" "[v3] Poisoned: %s",
obj->value[0], obj->value[1],
obj->value[3] != 0 ? "Yes" : "No");
break;
case ITEM_MONEY:
chprintlnf(ch, "[v0] Gold: [%ld]", obj->value[0]);
break;
}
return;
}
bool set_obj_values(CHAR_DATA * ch, OBJ_INDEX_DATA * pObj, int value_num,
const char *argument)
{
switch (pObj->item_type)
{
default:
break;
case ITEM_LIGHT:
switch (value_num)
{
default:
do_oldhelp(ch, "ITEM_LIGHT");
return FALSE;
case 2:
chprintln(ch, "HOURS OF LIGHT SET.\n\r");
pObj->value[2] = atol(argument);
break;
}
break;
case ITEM_WAND:
case ITEM_STAFF:
switch (value_num)
{
default:
do_oldhelp(ch, "ITEM_STAFF_WAND");
return FALSE;
case 0:
chprintln(ch, "SPELL LEVEL SET.\n\r");
pObj->value[0] = atol(argument);
break;
case 1:
chprintln(ch, "TOTAL NUMBER OF CHARGES SET.\n\r");
pObj->value[1] = atol(argument);
break;
case 2:
chprintln(ch, "CURRENT NUMBER OF CHARGES SET.\n\r");
pObj->value[2] = atol(argument);
break;
case 3:
chprintln(ch, "SPELL TYPE SET.");
pObj->value[3] = skill_lookup(argument);
break;
}
break;
case ITEM_SCROLL:
case ITEM_POTION:
case ITEM_PILL:
switch (value_num)
{
default:
do_oldhelp(ch, "ITEM_SCROLL_POTION_PILL");
return FALSE;
case 0:
chprintln(ch, "SPELL LEVEL SET.\n\r");
pObj->value[0] = atol(argument);
break;
case 1:
chprintln(ch, "SPELL TYPE 1 SET.\n\r");
pObj->value[1] = skill_lookup(argument);
break;
case 2:
chprintln(ch, "SPELL TYPE 2 SET.\n\r");
pObj->value[2] = skill_lookup(argument);
break;
case 3:
chprintln(ch, "SPELL TYPE 3 SET.\n\r");
pObj->value[3] = skill_lookup(argument);
break;
case 4:
chprintln(ch, "SPELL TYPE 4 SET.\n\r");
pObj->value[4] = skill_lookup(argument);
break;
}
break;
/* ARMOR for ROM: */
case ITEM_ARMOR:
switch (value_num)
{
default:
do_oldhelp(ch, "ITEM_ARMOR");
return FALSE;
case 0:
chprintln(ch, "AC PIERCE SET.\n\r");
pObj->value[0] = atol(argument);
break;
case 1:
chprintln(ch, "AC BASH SET.\n\r");
pObj->value[1] = atol(argument);
break;
case 2:
chprintln(ch, "AC SLASH SET.\n\r");
pObj->value[2] = atol(argument);
break;
case 3:
chprintln(ch, "AC EXOTIC SET.\n\r");
pObj->value[3] = atol(argument);
break;
}
break;
/* WEAPONS changed in ROM */
case ITEM_WEAPON:
switch (value_num)
{
default:
do_oldhelp(ch, "ITEM_WEAPON");
return FALSE;
case 0:
chprintln(ch, "WEAPON CLASS SET.\n\r");
ALT_FLAGVALUE_SET(pObj->value[0], weapon_class, argument);
break;
case 1:
chprintln(ch, "NUMBER OF DICE SET.\n\r");
pObj->value[1] = atol(argument);
break;
case 2:
chprintln(ch, "TYPE OF DICE SET.\n\r");
pObj->value[2] = atol(argument);
break;
case 3:
chprintln(ch, "WEAPON TYPE SET.\n\r");
pObj->value[3] = attack_lookup(argument);
break;
case 4:
chprintln(ch, "SPECIAL WEAPON TYPE TOGGLED.\n\r");
ALT_FLAGVALUE_TOGGLE(pObj->value[4], weapon_type2, argument);
break;
}
break;
case ITEM_PORTAL:
switch (value_num)
{
default:
do_oldhelp(ch, "ITEM_PORTAL");
return FALSE;
case 0:
chprintln(ch, "CHARGES SET.\n\r");
pObj->value[0] = atol(argument);
break;
case 1:
chprintln(ch, "EXIT FLAGS SET.\n\r");
ALT_FLAGVALUE_SET(pObj->value[1], exit_flags, argument);
break;
case 2:
chprintln(ch, "PORTAL FLAGS SET.\n\r");
ALT_FLAGVALUE_SET(pObj->value[2], portal_flags, argument);
break;
case 3:
chprintln(ch, "EXIT vnum_t SET.\n\r");
pObj->value[3] = atol(argument);
break;
}
break;
case ITEM_FURNITURE:
switch (value_num)
{
default:
do_oldhelp(ch, "ITEM_FURNITURE");
return FALSE;
case 0:
chprintln(ch, "NUMBER OF PEOPLE SET.\n\r");
pObj->value[0] = atol(argument);
break;
case 1:
chprintln(ch, "MAX WEIGHT SET.\n\r");
pObj->value[1] = atol(argument);
break;
case 2:
chprintln(ch, "FURNITURE FLAGS TOGGLED.\n\r");
ALT_FLAGVALUE_TOGGLE(pObj->value[2], furniture_flags, argument);
break;
case 3:
chprintln(ch, "HEAL BONUS SET.\n\r");
pObj->value[3] = atol(argument);
break;
case 4:
chprintln(ch, "MANA BONUS SET.\n\r");
pObj->value[4] = atol(argument);
break;
}
break;
case ITEM_CONTAINER:
switch (value_num)
{
flag_t value;
default:
do_oldhelp(ch, "ITEM_CONTAINER");
return FALSE;
case 0:
chprintln(ch, "WEIGHT CAPACITY SET.\n\r");
pObj->value[0] = atol(argument);
break;
case 1:
if ((value = flag_value(container_flags, argument)) != NO_FLAG)
TOGGLE_BIT(pObj->value[1], value);
else
{
do_oldhelp(ch, "ITEM_CONTAINER");
return FALSE;
}
chprintln(ch, "CONTAINER TYPE SET.\n\r");
break;
case 2:
if (atol(argument) != 0)
{
if (!get_obj_index(atol(argument)))
{
chprintln(ch, "THERE IS NO SUCH ITEM.\n\r");
return FALSE;
}
if (get_obj_index(atol(argument))->item_type != ITEM_KEY)
{
chprintln(ch, "THAT ITEM IS NOT A KEY.\n\r");
return FALSE;
}
}
chprintln(ch, "CONTAINER KEY SET.\n\r");
pObj->value[2] = atol(argument);
break;
case 3:
chprintln(ch, "CONTAINER MAX WEIGHT SET.");
pObj->value[3] = atol(argument);
break;
case 4:
chprintln(ch, "WEIGHT MULTIPLIER SET.\n\r");
pObj->value[4] = atol(argument);
break;
}
break;
case ITEM_DRINK_CON:
switch (value_num)
{
default:
do_oldhelp(ch, "ITEM_DRINK");
/* OLC do_oldhelp( ch, "liquids" ); */
return FALSE;
case 0:
chprintln(ch, "MAXIMUM AMOUT OF LIQUID HOURS SET.\n\r");
pObj->value[0] = atol(argument);
break;
case 1:
chprintln(ch, "CURRENT AMOUNT OF LIQUID HOURS SET.\n\r");
pObj->value[1] = atol(argument);
break;
case 2:
chprintln(ch, "LIQUID TYPE SET.\n\r");
pObj->value[2] =
(liq_lookup(argument) != -1 ? liq_lookup(argument) : 0);
break;
case 3:
chprintln(ch, "POISON VALUE TOGGLED.\n\r");
pObj->value[3] = (pObj->value[3] == 0) ? 1 : 0;
break;
}
break;
case ITEM_FOUNTAIN:
switch (value_num)
{
default:
do_oldhelp(ch, "ITEM_FOUNTAIN");
/* OLC do_oldhelp( ch, "liquids" ); */
return FALSE;
case 0:
chprintln(ch, "MAXIMUM AMOUT OF LIQUID HOURS SET.\n\r");
pObj->value[0] = atol(argument);
break;
case 1:
chprintln(ch, "CURRENT AMOUNT OF LIQUID HOURS SET.\n\r");
pObj->value[1] = atol(argument);
break;
case 2:
chprintln(ch, "LIQUID TYPE SET.\n\r");
pObj->value[2] =
(liq_lookup(argument) != -1 ? liq_lookup(argument) : 0);
break;
}
break;
case ITEM_FOOD:
switch (value_num)
{
default:
do_oldhelp(ch, "ITEM_FOOD");
return FALSE;
case 0:
chprintln(ch, "HOURS OF FOOD SET.\n\r");
pObj->value[0] = atol(argument);
break;
case 1:
chprintln(ch, "HOURS OF FULL SET.\n\r");
pObj->value[1] = atol(argument);
break;
case 3:
chprintln(ch, "POISON VALUE TOGGLED.\n\r");
pObj->value[3] = (pObj->value[3] == 0) ? 1 : 0;
break;
}
break;
case ITEM_MONEY:
switch (value_num)
{
default:
do_oldhelp(ch, "ITEM_MONEY");
return FALSE;
case 0:
chprintln(ch, "GOLD AMOUNT SET.\n\r");
pObj->value[0] = atol(argument);
break;
case 1:
chprintln(ch, "SILVER AMOUNT SET.\n\r");
pObj->value[1] = atol(argument);
break;
}
break;
}
show_obj_values(ch, pObj);
return TRUE;
}
OEDIT(oedit_show)
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *paf;
int cnt;
PROG_LIST *list;
EDIT_OBJ(ch, pObj);
chprintf(ch, "%s\n\r",
stringf(ch, 0, ALIGN_CENTER, "-",
FORMATF("[ %s: %s ]", olc_ed_name(ch), olc_ed_vnum(ch))));
chprintlnf(ch, "Name: [%s]\n\rArea: [%5d] %s",
pObj->name, !pObj->area ? -1 : pObj->area->vnum,
!pObj->area ? "No Area" : pObj->area->name);
chprintlnf(ch, "Vnum: [%5ld]\n\rType: [%s]", pObj->vnum,
flag_string(type_flags, pObj->item_type));
chprintlnf(ch, "Level: [%5d]", pObj->level);
chprintlnf(ch, "Wear flags: [%s]",
flag_string(wear_flags, pObj->wear_flags));
chprintlnf(ch, "Extra flags: [%s]",
flag_string(extra_flags, pObj->extra_flags));
chprintlnf(ch, "Material: [%s]", /* ROM */
pObj->material);
chprintlnf(ch, "Condition: [%5d]", /* ROM */
pObj->condition);
chprintlnf(ch, "Weight: [%5d]\n\rCost: [%5d]",
pObj->weight, pObj->cost);
if (pObj->first_extra_descr)
{
EXTRA_DESCR_DATA *ed;
chprint(ch, "Ex desc kwd: ");
for (ed = pObj->first_extra_descr; ed; ed = ed->next)
{
chprint(ch, "[");
chprint(ch, ed->keyword);
chprint(ch, "]");
}
chprintln(ch, "");
}
chprintlnf(ch, "Short desc: %s\n\rLong desc:\n\r %s",
pObj->short_descr, pObj->description);
for (cnt = 0, paf = pObj->first_affect; paf; paf = paf->next)
{
if (cnt == 0)
{
chprintln(ch, "Number Modifier Affects");
chprintln(ch, "------ -------- -------");
}
chprintlnf(ch, "[%4d] %-8d %s", cnt, paf->modifier,
flag_string(apply_flags, paf->location));
cnt++;
}
show_obj_values(ch, pObj);
chprintln(ch, draw_line(ch, NULL, 0));
if (pObj->first_oprog)
{
int cnt;
chprintlnf(ch, "\n\rOBJPrograms for [%5ld]:", pObj->vnum);
for (cnt = 0, list = pObj->first_oprog; list; list = list->next)
{
if (cnt == 0)
{
chprintln(ch, " Number Vnum Trigger Phrase");
chprintln(ch, " ------ ---- ------- ------");
}
chprintlnf(ch, "[%5d] %4ld %7s %s", cnt,
list->vnum, prog_type_to_name(list->trig_type),
list->trig_phrase);
cnt++;
}
}
return FALSE;
}
/*
* Need to issue warning if flag_t isn't valid. -- does so now -- Hugin.
*/
OEDIT(oedit_addaffect)
{
int value;
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
char loc[MAX_STRING_LENGTH];
char mod[MAX_STRING_LENGTH];
EDIT_OBJ(ch, pObj);
argument = one_argument(argument, loc);
one_argument(argument, mod);
if (loc[0] == '\0' || mod[0] == '\0' || !is_number(mod))
{
chprintln(ch, "Syntax: addaffect [location] [#xmod]");
return FALSE;
}
if ((value = flag_value(apply_flags, loc)) == NO_FLAG) /* Hugin */
{
chprintln(ch, "Valid affects are:");
show_help(ch, "apply");
return FALSE;
}
pAf = new_affect();
pAf->location = value;
pAf->modifier = atoi(mod);
pAf->where = TO_OBJECT;
pAf->type = -1;
pAf->duration = -1;
pAf->bitvector = 0;
pAf->level = pObj->level;
LINK(pAf, pObj->first_affect, pObj->last_affect, next, prev);
chprintln(ch, "Affect added.");
return TRUE;
}
OEDIT(oedit_delete)
{
OBJ_DATA *obj, *obj_next;
OBJ_INDEX_DATA *pObj;
RESET_DATA *pReset, *wReset;
ROOM_INDEX_DATA *pRoom;
char arg[MIL];
vnum_t pIndex, i;
int rcount, ocount, iHash;
if (IS_NULLSTR(argument))
{
if (ch)
chprintln(ch, "Syntax: oedit delete [vnum]");
return FALSE;
}
one_argument(argument, arg);
if (is_number(arg))
{
pIndex = atol(arg);
pObj = get_obj_index(pIndex);
}
else
{
if (ch)
chprintln(ch, "That is not a number.");
return FALSE;
}
for (i = 0; vnum_table[i].vnum != -1; i++)
{
if (vnum_table[i].type != VNUM_OBJ)
continue;
if (vnum_table[i].vnum == pIndex)
{
if (ch)
chprintln(ch, "That vnum is reserved.");
return FALSE;
}
}
if (!pObj)
{
if (ch)
chprintln(ch, "No such object.");
return FALSE;
}
stop_editing(pObj);
SET_BIT(pObj->area->area_flags, AREA_CHANGED);
if (top_vnum_obj == pIndex)
for (i = 1; i < pIndex; i++)
if (get_obj_index(i))
top_vnum_obj = i;
top_obj_index--;
ocount = 0;
for (obj = object_first; obj; obj = obj_next)
{
obj_next = obj->next;
if (obj->pIndexData == pObj)
{
extract_obj(obj);
ocount++;
}
}
rcount = 0;
for (iHash = 0; iHash < MAX_KEY_HASH; iHash++)
{
for (pRoom = room_index_hash[iHash]; pRoom; pRoom = pRoom->next)
{
for (pReset = pRoom->reset_first; pReset; pReset = wReset)
{
wReset = pReset->next;
switch (pReset->command)
{
case 'O':
case 'E':
case 'P':
case 'G':
if ((pReset->arg1 == pIndex) ||
((pReset->command == 'P') && (pReset->arg3 == pIndex)))
{
unlink_reset(pRoom, pReset);
free_reset_data(pReset);
rcount++;
SET_BIT(pRoom->area->area_flags, AREA_CHANGED);
}
}
}
}
}
unlink_obj_index(pObj);
pObj->area = NULL;
pObj->vnum = 0;
free_obj_index(pObj);
if (ch)
{
chprintf(ch,
"Removed object vnum {C%ld{x and" " {C%d{x resets.\n\r",
pIndex, rcount);
chprintf(ch,
"{C%d{x occurences of the object"
" were extracted from the mud.\n\r", ocount);
}
return TRUE;
}
OEDIT(oedit_addapply)
{
int value, typ;
flag_t bv;
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
char loc[MAX_STRING_LENGTH];
char mod[MAX_STRING_LENGTH];
char type[MAX_STRING_LENGTH];
char bvector[MAX_STRING_LENGTH];
EDIT_OBJ(ch, pObj);
argument = one_argument(argument, type);
argument = one_argument(argument, loc);
argument = one_argument(argument, mod);
one_argument(argument, bvector);
if (type[0] == '\0' || (typ = flag_value(apply_types, type)) == NO_FLAG)
{
chprintln(ch, "Invalid apply type. Valid apply types are:");
show_help(ch, "apptype");
return FALSE;
}
if (loc[0] == '\0' || (value = flag_value(apply_flags, loc)) == NO_FLAG)
{
chprintln(ch, "Valid applys are:");
show_help(ch, "apply");
return FALSE;
}
if (bvector[0] == '\0' ||
(bv = flag_value(bitvector_type[typ].table, bvector)) == NO_FLAG)
{
chprintln(ch, "Invalid bitvector type.");
chprintln(ch, "Valid bitvector types are:");
show_help(ch, bitvector_type[typ].help);
return FALSE;
}
if (mod[0] == '\0' || !is_number(mod))
{
chprintln(ch,
"Syntax: addapply [type] [location] [#xmod] [bitvector]");
return FALSE;
}
pAf = new_affect();
pAf->location = value;
pAf->modifier = atoi(mod);
pAf->where = apply_types[typ].bit;
pAf->type = -1;
pAf->duration = -1;
pAf->bitvector = bv;
pAf->level = pObj->level;
LINK(pAf, pObj->first_affect, pObj->last_affect, next, prev);
chprintln(ch, "Apply added.");
return TRUE;
}
/*
* My thanks to Hans Hvidsten Birkeland and Noam Krendel(Walker)
* for really teaching me how to manipulate pointers.
*/
OEDIT(oedit_delaffect)
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
char affect[MAX_STRING_LENGTH];
int value;
int cnt = 0;
EDIT_OBJ(ch, pObj);
one_argument(argument, affect);
if (!is_number(affect) || affect[0] == '\0')
{
chprintln(ch, "Syntax: delaffect [#xaffect]");
return FALSE;
}
value = atoi(affect);
if (value < 0)
{
chprintln(ch, "Only non-negative affect-numbers allowed.");
return FALSE;
}
for (pAf = pObj->first_affect; pAf != NULL; pAf = pAf->next)
if (++cnt == value)
break;
if (!pAf)
{
chprintln(ch, "OEdit: Non-existant affect.");
return FALSE;
}
UNLINK(pAf, pObj->first_affect, pObj->last_affect, next, prev);
free_affect(pAf);
chprintln(ch, "Affect removed.");
return TRUE;
}
bool set_value(CHAR_DATA * ch, OBJ_INDEX_DATA * pObj, const char *argument,
int value)
{
if (argument[0] == '\0')
{
set_obj_values(ch, pObj, -1, ""); /* '\0' changed to "" -- Hugin */
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. (now five -- Hugin )
****************************************************************************/
bool oedit_values(CHAR_DATA * ch, const char *argument, int value)
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
if (set_value(ch, pObj, argument, value))
return TRUE;
return FALSE;
}
OEDIT(oedit_create)
{
OBJ_INDEX_DATA *pObj;
AREA_DATA *pArea;
vnum_t value;
int iHash;
value = atol(argument);
if (argument[0] == '\0' || value == 0)
{
chprintln(ch, "Syntax: oedit create [vnum]");
return FALSE;
}
pArea = get_vnum_area(value);
if (!pArea)
{
chprintln(ch, "OEdit: That vnum is not assigned an area.");
return FALSE;
}
if (!IS_BUILDER(ch, pArea))
{
chprintln(ch, "OEdit: Vnum in an area you cannot build in.");
return FALSE;
}
if (get_obj_index(value))
{
chprintln(ch, "OEdit: Object vnum already exists.");
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;
LINK_SINGLE(pObj, next, obj_index_hash[iHash]);
edit_start(ch, pObj, ED_OBJECT);
chprintln(ch, "Object Created.");
return TRUE;
}
/*
* Mobile Editor Functions.
*/
MEDIT(medit_show)
{
MOB_INDEX_DATA *pMob;
PROG_LIST *list;
EDIT_MOB(ch, pMob);
chprintf(ch, "%s\n\r",
stringf(ch, 0, ALIGN_CENTER, "-",
FORMATF("[ %s: %s ]", olc_ed_name(ch), olc_ed_vnum(ch))));
chprintlnf(ch, "Name: [%s]\n\rArea: [%5d] %s",
pMob->player_name, !pMob->area ? -1 : pMob->area->vnum,
!pMob->area ? "No Area" : pMob->area->name);
chprintlnf(ch, "Act: [%s]", flag_string(act_flags, pMob->act));
chprintlnf(ch, "Vnum: [%5ld] Sex: [%s] Race: [%s]",
pMob->vnum,
pMob->sex == SEX_MALE ? "male " : pMob->sex ==
SEX_FEMALE ? "female " : pMob->sex ==
3 ? "random " : "neutral", pMob->race->name);
chprintlnf(ch,
"Level: [%2d] Align: [%4d] Hitroll: [%2d] Dam Type: [%s]",
pMob->level, pMob->alignment, pMob->hitroll,
attack_table[pMob->dam_type].name);
if (pMob->group)
{
chprintlnf(ch, "Group: [%5ld]", pMob->group);
}
chprintf(ch, "Hit dice: [%2dd%-3d+%4d] ", pMob->hit[DICE_NUMBER],
pMob->hit[DICE_TYPE], pMob->hit[DICE_BONUS]);
chprintf(ch, "Damage dice: [%2dd%-3d+%4d] ", pMob->damage[DICE_NUMBER],
pMob->damage[DICE_TYPE], pMob->damage[DICE_BONUS]);
chprintlnf(ch, "Mana dice: [%2dd%-3d+%4d]", pMob->mana[DICE_NUMBER],
pMob->mana[DICE_TYPE], pMob->mana[DICE_BONUS]);
/* ROM values end */
chprintlnf(ch, "Affected by: [%s]",
flag_string(affect_flags, pMob->affected_by));
/* ROM values: */
chprintlnf(ch,
"Armor: [pierce: %d bash: %d slash: %d magic: %d]",
pMob->ac[AC_PIERCE], pMob->ac[AC_BASH], pMob->ac[AC_SLASH],
pMob->ac[AC_EXOTIC]);
chprintlnf(ch, "Form: [%s]", flag_string(form_flags, pMob->form));
chprintlnf(ch, "Parts: [%s]", flag_string(part_flags, pMob->parts));
chprintlnf(ch, "Imm: [%s]",
flag_string(imm_flags, pMob->imm_flags));
chprintlnf(ch, "Res: [%s]",
flag_string(res_flags, pMob->res_flags));
chprintlnf(ch, "Vuln: [%s]",
flag_string(vuln_flags, pMob->vuln_flags));
chprintlnf(ch, "Off: [%s]",
flag_string(off_flags, pMob->off_flags));
chprintlnf(ch, "Size: [%s]", flag_string(size_flags, pMob->size));
chprintlnf(ch, "Material: [%s]", pMob->material);
chprintlnf(ch, "Start pos. [%s]",
flag_string(position_flags, pMob->start_pos));
chprintlnf(ch, "Default pos [%s]",
flag_string(position_flags, pMob->default_pos));
chprintlnf(ch, "Wealth: [%5ld]", pMob->wealth);
/* ROM values end */
if (pMob->spec_fun)
{
chprintlnf(ch, "Spec fun: [%s]", spec_name(pMob->spec_fun));
}
chprintf(ch, "Short descr: %s\n\rLong descr:\n\r%s", pMob->short_descr,
pMob->long_descr);
chprintf(ch, "Description:\n\r%s", pMob->description);
if (pMob->pShop)
{
SHOP_DATA *pShop;
int iTrade;
pShop = pMob->pShop;
chprintlnf(ch,
"Shop data for [%5ld]:\n\r"
" Markup for purchaser: %d%%\n\r"
" Markdown for seller: %d%%", pShop->keeper,
pShop->profit_buy, pShop->profit_sell);
chprintlnf(ch, " Hours: %d to %d.", pShop->open_hour,
pShop->close_hour);
for (iTrade = 0; iTrade < MAX_TRADE; iTrade++)
{
if (pShop->buy_type[iTrade] != 0)
{
if (iTrade == 0)
{
chprintln(ch, " Number Trades Type");
chprintln(ch, " ------ -----------");
}
chprintlnf(ch, " [%4d] %s", iTrade,
flag_string(type_flags, pShop->buy_type[iTrade]));
}
}
}
if (pMob->first_mprog)
{
int cnt;
chprintlnf(ch, "\n\rMOBPrograms for [%5ld]:", pMob->vnum);
for (cnt = 0, list = pMob->first_mprog; list; list = list->next)
{
if (cnt == 0)
{
chprintln(ch, " Number Vnum Trigger Phrase");
chprintln(ch, " ------ ---- ------- ------");
}
chprintlnf(ch, "[%5d] %4ld %7s %s", cnt, list->vnum,
prog_type_to_name(list->trig_type), list->trig_phrase);
cnt++;
}
}
chprintln(ch, draw_line(ch, NULL, 0));
return FALSE;
}
MEDIT(medit_create)
{
MOB_INDEX_DATA *pMob;
AREA_DATA *pArea;
vnum_t value;
int iHash;
value = atol(argument);
if (argument[0] == '\0' || value == 0)
{
chprintln(ch, "Syntax: medit create [vnum]");
return FALSE;
}
pArea = get_vnum_area(value);
if (!pArea)
{
chprintln(ch, "MEdit: That vnum is not assigned an area.");
return FALSE;
}
if (!IS_BUILDER(ch, pArea))
{
chprintln(ch, "MEdit: Vnum in an area you cannot build in.");
return FALSE;
}
if (get_mob_index(value))
{
chprintln(ch, "MEdit: Mobile vnum already exists.");
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;
LINK_SINGLE(pMob, next, mob_index_hash[iHash]);
edit_start(ch, pMob, ED_MOBILE);
chprintln(ch, "Mobile Created.");
return TRUE;
}
MEDIT(medit_delete)
{
CHAR_DATA *wch, *wnext;
MOB_INDEX_DATA *pMob;
RESET_DATA *pReset, *wReset;
ROOM_INDEX_DATA *pRoom;
char arg[MIL];
vnum_t pIndex, i;
int mcount, rcount, iHash;
bool foundmob = FALSE;
bool foundobj = FALSE;
if (IS_NULLSTR(argument))
{
if (ch)
chprintln(ch, "Syntax: medit delete [vnum]");
return FALSE;
}
one_argument(argument, arg);
if (is_number(arg))
{
pIndex = atol(arg);
pMob = get_mob_index(pIndex);
}
else
{
if (ch)
chprintln(ch, "That is not a number.");
return FALSE;
}
for (i = 0; vnum_table[i].vnum != -1; i++)
{
if (vnum_table[i].type != VNUM_MOB)
continue;
if (vnum_table[i].vnum == pIndex)
{
if (ch)
chprintln(ch, "That vnum is reserved.");
return FALSE;
}
}
if (!pMob)
{
if (ch)
chprintln(ch, "No such mobile.");
return FALSE;
}
stop_editing(pMob);
SET_BIT(pMob->area->area_flags, AREA_CHANGED);
if (top_vnum_mob == pIndex)
for (i = 1; i < pIndex; i++)
if (get_mob_index(i))
top_vnum_mob = i;
top_mob_index--;
rcount = 0;
mcount = 0;
for (iHash = 0; iHash < MAX_KEY_HASH; iHash++)
{
for (pRoom = room_index_hash[iHash]; pRoom; pRoom = pRoom->next)
{
for (wch = pRoom->first_person; wch; wch = wnext)
{
wnext = wch->next_in_room;
if (wch->pIndexData == pMob)
{
extract_char(wch, TRUE);
mcount++;
}
}
for (pReset = pRoom->reset_first; pReset; pReset = wReset)
{
wReset = pReset->next;
switch (pReset->command)
{
case 'M':
if (pReset->arg1 == pIndex)
{
foundmob = TRUE;
unlink_reset(pRoom, pReset);
free_reset_data(pReset);
rcount++;
SET_BIT(pRoom->area->area_flags, AREA_CHANGED);
}
else
foundmob = FALSE;
break;
case 'E':
case 'G':
if (foundmob)
{
foundobj = TRUE;
unlink_reset(pRoom, pReset);
free_reset_data(pReset);
rcount++;
SET_BIT(pRoom->area->area_flags, AREA_CHANGED);
}
else
foundobj = FALSE;
break;
case '0':
foundobj = FALSE;
break;
case 'P':
if (foundobj && foundmob)
{
unlink_reset(pRoom, pReset);
free_reset_data(pReset);
rcount++;
SET_BIT(pRoom->area->area_flags, AREA_CHANGED);
}
}
}
}
}
unlink_mob_index(pMob);
pMob->area = NULL;
pMob->vnum = 0;
free_mob_index(pMob);
if (ch)
{
chprintf(ch,
"Removed mobile vnum {C%ld{x and {C%d{x resets.\n\r",
pIndex, rcount);
chprintf(ch,
"{C%d{x mobiles were extracted" " from the mud.\n\r", mcount);
}
return TRUE;
}
void show_liqlist(CHAR_DATA * ch)
{
int liq;
BUFFER *buffer;
char buf[MAX_STRING_LENGTH];
buffer = new_buf();
for (liq = 0; liq_table[liq].liq_name != NULL; liq++)
{
if ((liq % 21) == 0)
add_buf(buffer,
"Name Color Proof Full Thirst Food Ssize\n\r");
sprintf(buf, "%-20s %-14s %5d %4d %6d %4d %5d\n\r",
liq_table[liq].liq_name, liq_table[liq].liq_color,
liq_table[liq].liq_affect[0],
liq_table[liq].liq_affect[1],
liq_table[liq].liq_affect[2],
liq_table[liq].liq_affect[3], liq_table[liq].liq_affect[4]);
add_buf(buffer, buf);
}
page_to_char(buf_string(buffer), ch);
free_buf(buffer);
return;
}
void show_damlist(CHAR_DATA * ch)
{
int att;
BUFFER *buffer;
char buf[MAX_STRING_LENGTH];
buffer = new_buf();
for (att = 0; attack_table[att].name != NULL; att++)
{
if ((att % 21) == 0)
add_buf(buffer, "Name Noun\n\r");
sprintf(buf, "%-20s %-20s\n\r", attack_table[att].name,
attack_table[att].noun);
add_buf(buffer, buf);
}
page_to_char(buf_string(buffer), ch);
free_buf(buffer);
return;
}
MEDIT(medit_group)
{
MOB_INDEX_DATA *pMob;
MOB_INDEX_DATA *pMTemp;
char arg[MAX_STRING_LENGTH];
char buf[MAX_STRING_LENGTH];
int temp;
BUFFER *buffer;
bool found = FALSE;
EDIT_MOB(ch, pMob);
if (argument[0] == '\0')
{
chprintln(ch, "Syntax: group [number]");
chprintln(ch, " group show [number]");
return FALSE;
}
if (is_number(argument))
{
pMob->group = atol(argument);
chprintln(ch, "Group set.");
return TRUE;
}
argument = one_argument(argument, arg);
if (!str_cmp(arg, "show") && is_number(argument))
{
if (atol(argument) == 0)
{
chprintln(ch, "Are you crazy?");
return FALSE;
}
buffer = new_buf();
for (temp = 0; temp < 65536; temp++)
{
pMTemp = get_mob_index(temp);
if (pMTemp && (pMTemp->group == atol(argument)))
{
found = TRUE;
sprintf(buf, "[%5ld] %s\n\r", pMTemp->vnum,
pMTemp->player_name);
add_buf(buffer, buf);
}
}
if (found)
page_to_char(buf_string(buffer), ch);
else
chprintln(ch, "No mobs in that group.");
free_buf(buffer);
return FALSE;
}
return FALSE;
}
MEDIT(medit_addmprog)
{
flag_t value;
MOB_INDEX_DATA *pMob;
PROG_LIST *list;
PROG_CODE *code;
char trigger[MAX_STRING_LENGTH];
char phrase[MAX_STRING_LENGTH];
char num[MAX_STRING_LENGTH];
EDIT_MOB(ch, pMob);
argument = one_argument(argument, num);
argument = one_argument(argument, trigger);
argument = one_argument(argument, phrase);
if (!is_number(num) || trigger[0] == '\0' || phrase[0] == '\0')
{
chprintln(ch, "Syntax: addmprog [vnum] [trigger] [phrase]");
return FALSE;
}
if ((value = flag_value(mprog_flags, trigger)) == NO_FLAG)
{
chprintln(ch, "Valid flags are:");
show_help(ch, "mprog");
return FALSE;
}
if ((code = get_prog_index(atol(num), PRG_MPROG)) == NULL)
{
chprintln(ch, "No such MOBProgram.");
return FALSE;
}
list = new_prog();
list->vnum = atol(num);
list->trig_type = value;
list->trig_phrase = str_dup(phrase);
replace_string(list->code, code->code);
SET_BIT(pMob->mprog_flags, value);
LINK(list, pMob->first_mprog, pMob->last_mprog, next, prev);
chprintln(ch, "Mprog Added.");
return TRUE;
}
MEDIT(medit_delmprog)
{
MOB_INDEX_DATA *pMob;
PROG_LIST *list;
char mprog[MAX_STRING_LENGTH];
int value;
int cnt = 0;
EDIT_MOB(ch, pMob);
one_argument(argument, mprog);
if (!is_number(mprog) || mprog[0] == '\0')
{
chprintln(ch, "Syntax: delmprog [#mprog]");
return FALSE;
}
value = atoi(mprog);
if (value < 0)
{
chprintln(ch, "Only non-negative mprog-numbers allowed.");
return FALSE;
}
for (list = pMob->first_mprog; list != NULL; list = list->next)
if ((++cnt == value))
break;
if (!list)
{
chprintln(ch, "MEdit: Non existant mprog.");
return FALSE;
}
REMOVE_BIT(pMob->mprog_flags, list->trig_type);
UNLINK(list, pMob->first_mprog, pMob->last_mprog, next, prev);
free_prog(list);
chprintln(ch, "Mprog removed.");
return TRUE;
}
OEDIT(oedit_addoprog)
{
flag_t value;
OBJ_INDEX_DATA *pObj;
PROG_LIST *list;
PROG_CODE *code;
char trigger[MSL];
char phrase[MSL];
char num[MSL];
EDIT_OBJ(ch, pObj);
argument = one_argument(argument, num);
argument = one_argument(argument, trigger);
strcpy(phrase, argument);
if (!is_number(num) || IS_NULLSTR(trigger) || IS_NULLSTR(phrase))
{
chprintln(ch, "Syntax: addoprog [vnum] [trigger] [phrase]");
return FALSE;
}
if ((value = flag_value(oprog_flags, trigger)) == NO_FLAG)
{
chprintln(ch, "Valid flags are:");
show_help(ch, "oprog");
return FALSE;
}
if ((code = get_prog_index(atol(num), PRG_OPROG)) == NULL)
{
chprintln(ch, "No such OBJProgram.");
return FALSE;
}
list = new_prog();
list->vnum = atol(num);
list->trig_type = value;
replace_string(list->trig_phrase, phrase);
replace_string(list->code, code->code);
SET_BIT(pObj->oprog_flags, value);
LINK(list, pObj->first_oprog, pObj->last_oprog, next, prev);
chprintln(ch, "Oprog Added.");
return TRUE;
}
OEDIT(oedit_deloprog)
{
OBJ_INDEX_DATA *pObj;
PROG_LIST *list;
char oprog[MSL];
int value;
int cnt = -1;
EDIT_OBJ(ch, pObj);
one_argument(argument, oprog);
if (!is_number(oprog) || IS_NULLSTR(oprog))
{
chprintln(ch, "Syntax: deloprog [#oprog]");
return FALSE;
}
value = atoi(oprog);
if (value < 0)
{
chprintln(ch, "Only non-negative oprog-numbers allowed.");
return FALSE;
}
for (list = pObj->first_oprog; list != NULL; list = list->next)
if (++cnt == value)
break;
if (!list)
{
chprintln(ch, "OEdit: Non existant oprog.");
return FALSE;
}
REMOVE_BIT(pObj->oprog_flags, list->trig_type);
UNLINK(list, pObj->first_oprog, pObj->last_oprog, next, prev);
free_prog(list);
chprintln(ch, "Oprog removed.");
return TRUE;
}
REDIT(redit_addrprog)
{
flag_t value;
ROOM_INDEX_DATA *pRoom;
PROG_LIST *list;
PROG_CODE *code;
char trigger[MSL];
char phrase[MSL];
char num[MSL];
EDIT_ROOM(ch, pRoom);
argument = one_argument(argument, num);
argument = one_argument(argument, trigger);
strcpy(phrase, argument);
if (!is_number(num) || IS_NULLSTR(trigger) || IS_NULLSTR(phrase))
{
chprintln(ch, "Syntax: addrprog [vnum] [trigger] [phrase]");
return FALSE;
}
if ((value = flag_value(rprog_flags, trigger)) == NO_FLAG)
{
chprintln(ch, "Valid flags are:");
show_help(ch, "rprog");
return FALSE;
}
if ((code = get_prog_index(atol(num), PRG_RPROG)) == NULL)
{
chprintln(ch, "No such ROOMProgram.");
return FALSE;
}
list = new_prog();
list->vnum = atol(num);
list->trig_type = value;
replace_string(list->trig_phrase, phrase);
replace_string(list->code, code->code);
SET_BIT(pRoom->rprog_flags, value);
LINK(list, pRoom->first_rprog, pRoom->last_rprog, next, prev);
chprintln(ch, "Rprog Added.");
return TRUE;
}
REDIT(redit_delrprog)
{
ROOM_INDEX_DATA *pRoom;
PROG_LIST *list;
char rprog[MSL];
int value;
int cnt = -1;
EDIT_ROOM(ch, pRoom);
one_argument(argument, rprog);
if (!is_number(rprog) || IS_NULLSTR(rprog))
{
chprintln(ch, "Syntax: delrprog [#rprog]");
return FALSE;
}
value = atoi(rprog);
if (value < 0)
{
chprintln(ch, "Only non-negative rprog-numbers allowed.");
return FALSE;
}
for (list = pRoom->first_rprog; list != NULL; list = list->next)
if ((++cnt == value))
break;
if (!list)
{
chprintln(ch, "REdit: Non existant rprog.");
return FALSE;
}
REMOVE_BIT(pRoom->rprog_flags, list->trig_type);
UNLINK(list, pRoom->first_rprog, pRoom->last_rprog, next, prev);
free_prog(list);
chprintln(ch, "Rprog removed.");
return TRUE;
}
VALIDATE_FUN(validate_level)
{
int num = *(int *) arg;
if (num < 0 || num > MAX_LEVEL)
{
chprintf(ch, "Number must be between 0 and %d.\n\r", MAX_LEVEL);
return FALSE;
}
return TRUE;
}
VALIDATE_FUN(validate_align)
{
int num = *(int *) arg;
if (num < -1000 || num > 1000)
{
chprintln(ch, "Number must be between -1000 and 1000.");
return FALSE;
}
return TRUE;
}
ED_FUN_DEC(olced_str)
{
VALIDATE_FUN *validator;
const char **string = (const char **) arg;
if (IS_NULLSTR(argument))
{
chprintf(ch, "Syntax: %s string\n\r", n_fun);
return FALSE;
}
if ((validator = (VALIDATE_FUN *) par) && !validator(ch, argument))
return FALSE;
replace_string(*string, argument);
chprintln(ch, "Ok.");
return TRUE;
}
ED_FUN_DEC(olced_str_line)
{
VALIDATE_FUN *validator;
const char **string = (const char **) arg;
char buf[MSL];
if (IS_NULLSTR(argument))
{
chprintf(ch, "Syntax: %s string\n\r", n_fun);
return FALSE;
}
if ((validator = (VALIDATE_FUN *) par) && !validator(ch, argument))
return FALSE;
sprintf(buf, "%s\n\r", argument);
replace_string(*string, buf);
chprintln(ch, "Ok.");
return TRUE;
}
ED_FUN_DEC(olced_desc)
{
if (IS_NULLSTR(argument))
{
string_append(ch, (const char **) arg);
return TRUE;
}
chprintln(ch, "Syntax : desc");
return FALSE;
}
ED_FUN_DEC(olced_bool)
{
if (IS_NULLSTR(argument))
{
chprintf(ch, "Syntax : %s [TRUE/FALSE]\n\r\n\r", n_fun);
return FALSE;
}
if (!str_cmp(argument, "TRUE"))
*(bool *) arg = TRUE;
else if (!str_cmp(argument, "FALSE"))
*(bool *) arg = FALSE;
else
{
chprintln(ch, "ERROR : invalid argument.");
return FALSE;
}
chprintln(ch, "Ok.");
return TRUE;
}
ED_FUN_DEC(olced_olded)
{
return (*(OLC_FUN *) par) (ch, argument);
}
ED_FUN_DEC(olced_number)
{
int *value = (int *) arg;
char *endptr;
int temp;
char arg1[MIL];
VALIDATE_FUN *validator;
one_argument(argument, arg1);
temp = strtol(arg1, &endptr, 0);
if (IS_NULLSTR(arg1) || !IS_NULLSTR(endptr))
{
chprintf(ch, "Syntax: %s number\n\r", n_fun);
return FALSE;
}
if ((validator = (VALIDATE_FUN *) par) && !validator(ch, &temp))
return FALSE;
*value = temp;
chprintln(ch, "Ok.");
return TRUE;
}
ED_FUN_DEC(olced_number_long)
{
long *value = (long *) arg;
char *endptr;
long temp;
char arg1[MIL];
VALIDATE_FUN *validator;
one_argument(argument, arg1);
temp = strtol(arg1, &endptr, 0);
if (IS_NULLSTR(arg1) || !IS_NULLSTR(endptr))
{
chprintf(ch, "Syntax: %s number\n\r", n_fun);
return FALSE;
}
if ((validator = (VALIDATE_FUN *) par) && !validator(ch, &temp))
return FALSE;
*value = temp;
chprintln(ch, "Ok.");
return TRUE;
}
ED_FUN_DEC(olced_vnum)
{
vnum_t *value = (vnum_t *) arg;
char *endptr;
vnum_t temp;
char arg1[MIL];
VALIDATE_FUN *validator;
one_argument(argument, arg1);
temp = strtol(arg1, &endptr, 0);
if (IS_NULLSTR(arg1) || !IS_NULLSTR(endptr))
{
chprintf(ch, "Syntax: %s number\n\r", n_fun);
return FALSE;
}
if ((validator = (VALIDATE_FUN *) par) && !validator(ch, &temp))
return FALSE;
*value = temp;
chprintln(ch, "Ok.");
return TRUE;
}
void show_flags_buf(BUFFER * output, const struct flag_type *flag_table)
{
int flag;
char buf[MSL];
int col;
col = 0;
for (flag = 0; flag_table[flag].name != NULL; flag++)
{
if (flag_table[flag].settable)
{
sprintf(buf, "%-19.18s", flag_table[flag].name);
add_buf(output, buf);
if (++col % 4 == 0)
add_buf(output, "\n\r");
}
}
if (col % 4 != 0)
add_buf(output, "\n\r");
}
/*****************************************************************************
Name: show_flags
Purpose: Displays settable flags and stats.
****************************************************************************/
void show_flags(CHAR_DATA * ch, const struct flag_type *flag_table)
{
BUFFER *output;
output = new_buf();
show_flags_buf(output, flag_table);
page_to_char(buf_string(output), ch);
free_buf(output);
}
ED_FUN_DEC(olced_flag)
{
int stat;
const struct flag_type *f;
flag_t marked;
if ((stat = is_stat((const struct flag_type *) par)) < 0)
{
chprintf
(ch,
"%s: Unknown table of values (report it to implementors).", n_fun);
return FALSE;
}
if (IS_NULLSTR(argument))
{
chprintlnf(ch, "Syntax: %s value\n\r\n\r"
"Type '%s ?' for a list of "
"acceptable values.", n_fun, n_fun);
return FALSE;
}
if (!str_cmp(argument, "?"))
{
show_flags(ch, (const struct flag_type *) par);
return FALSE;
}
if (stat)
{
if ((f = flag_lookup(argument, (const struct flag_type *) par)) == NULL)
{
chprintlnf(ch, "Syntax: %s value\n\r\n\r"
"Type '%s ?' for a list of "
"acceptable values.", n_fun, n_fun);
return FALSE;
}
if (!f->settable)
{
chprintf(ch, "%s: '%s': value is not settable.\n\n\r",
n_fun, f->name);
return FALSE;
}
*(int *) arg = f->bit;
chprintf(ch, "%s: '%s': Ok.\n\n\r", n_fun, f->name);
return TRUE;
}
marked = 0;
/*
* Accept multiple flags.
*/
for (;;)
{
char word[MAX_INPUT_LENGTH];
argument = one_argument(argument, word);
if (IS_NULLSTR(word))
break;
if ((f = flag_lookup(word, (const struct flag_type *) par)) == NULL)
{
chprintf(ch, "Syntax: %s flag...\n\r\n\r"
"Type '%s ?' for a list of "
"acceptable flags.", n_fun, n_fun);
return FALSE;
}
if (!f->settable)
{
chprintf(ch, "%s: '%s': flag is not settable.\n\r", n_fun, f->name);
continue;
}
SET_BIT(marked, f->bit);
}
if (marked)
{
TOGGLE_BIT(*(flag_t *) arg, marked);
chprintf(ch, "%s: '%s': flag(s) toggled.\n\r",
n_fun, flag_string((const struct flag_type *) par, marked));
return TRUE;
}
return FALSE;
}
ED_FUN_DEC(olced_shop)
{
MOB_INDEX_DATA *pMob = (MOB_INDEX_DATA *) arg;
char command[MAX_INPUT_LENGTH];
char arg1[MAX_INPUT_LENGTH];
argument = one_argument(argument, command);
argument = one_argument(argument, arg1);
if (IS_NULLSTR(command))
{
chprintln(ch, "Syntax : shop hours [open] [close]");
chprintln(ch, " shop profit [%% buy] [%% sell]");
chprintln(ch, " shop type [0-4] [obj type]");
chprintln(ch, " shop type [0-4] none");
chprintln(ch, " shop assign");
chprintln(ch, " shop remove");
return FALSE;
}
if (!str_cmp(command, "hours"))
{
if (IS_NULLSTR(arg1) || !is_number(arg1)
|| IS_NULLSTR(argument) || !is_number(argument))
{
chprintln(ch, "Syntax : shop hours [open] [close]");
return FALSE;
}
if (!pMob->pShop)
{
chprintln(ch, "ERROR : Debes crear un shop primero (shop assign).");
return FALSE;
}
pMob->pShop->open_hour = atoi(arg1);
pMob->pShop->close_hour = atoi(argument);
chprintln(ch, "Hours set.");
return TRUE;
}
if (!str_cmp(command, "profit"))
{
if (IS_NULLSTR(arg1) || !is_number(arg1)
|| IS_NULLSTR(argument) || !is_number(argument))
{
chprintf(ch, "Syntax : shop profit [%% buy] [%% sell]\n\r");
return FALSE;
}
if (!pMob->pShop)
{
chprintln(ch,
"MEdit: You must create a shop first (shop assign).");
return FALSE;
}
pMob->pShop->profit_buy = atoi(arg1);
pMob->pShop->profit_sell = atoi(argument);
chprintln(ch, "Shop profit set.");
return TRUE;
}
if (!str_cmp(command, "type"))
{
flag_t value = 0;
if (IS_NULLSTR(arg1) || !is_number(arg1) || IS_NULLSTR(argument))
{
chprintln(ch, "Syntax: shop type [#x0-4] [item type]");
return FALSE;
}
if (atoi(arg1) >= MAX_TRADE)
{
chprintf(ch, "MEdit: May sell %d items max.\n\r", MAX_TRADE);
return FALSE;
}
if (!pMob->pShop)
{
chprintln(ch,
"MEdit: You must create a shop first (shop assign).");
return FALSE;
}
if ((value = flag_value(type_flags, argument)) == NO_FLAG)
{
chprintln(ch, "MEdit: That type of item is not known.");
return FALSE;
}
pMob->pShop->buy_type[atoi(arg1)] = value;
chprintln(ch, "Shop type set.");
return TRUE;
}
/* shop assign && shop delete by Phoenix */
if (!str_prefix(command, "assign"))
{
if (pMob->pShop)
{
chprintln(ch, "Mob already has a shop assigned to it.");
return FALSE;
}
pMob->pShop = new_shop();
LINK(pMob->pShop, shop_first, shop_last, next, prev);
pMob->pShop->keeper = pMob->vnum;
chprintln(ch, "New shop assigned to mobile.");
return TRUE;
}
if (!str_prefix(command, "remove"))
{
SHOP_DATA *pShop;
pShop = pMob->pShop;
pMob->pShop = NULL;
UNLINK(pShop, shop_first, shop_last, next, prev);
free_shop(pShop);
chprintln(ch, "Mobile is no longer a shopkeeper.");
return TRUE;
}
olced_shop(n_fun, ch, str_empty, arg, par);
return FALSE;
}
ED_FUN_DEC(olced_spec)
{
SPEC_FUN **spec = (SPEC_FUN **) arg;
if (IS_NULLSTR(argument))
{
chprintf(ch, "Sintaxis : %s [%s]\n\r", n_fun, n_fun);
return FALSE;
}
if (!str_cmp(argument, "none"))
{
*spec = NULL;
chprintln(ch, "Spec removed.");
return TRUE;
}
if (spec_lookup(argument))
{
*spec = spec_lookup(argument);
chprintln(ch, "Spec set.");
return TRUE;
}
else
{
chprintln(ch, "ERROR : Spec inexistente.");
return FALSE;
}
return FALSE;
}
ED_FUN_DEC(olced_race)
{
MOB_INDEX_DATA *pMob = (MOB_INDEX_DATA *) arg;
RACE_DATA *race;
if (!IS_NULLSTR(argument) && (race = race_lookup(argument)) != NULL)
{
pMob->race = race;
pMob->act |= race->act;
pMob->affected_by |= race->aff;
pMob->off_flags |= race->off;
pMob->imm_flags |= race->imm;
pMob->res_flags |= race->res;
pMob->vuln_flags |= race->vuln;
pMob->form |= race->form;
pMob->parts |= race->parts;
chprintln(ch, "Race set.");
return TRUE;
}
if (argument[0] == '?')
{
int i = 0;
chprintln(ch, "Available races are:");
for (race = race_first; race != NULL; race = race->next)
{
if ((i % 3) == 0)
chprintln(ch, "");
chprintf(ch, " %-15s", race->name);
i++;
}
chprintln(ch, "");
return FALSE;
}
chprintln(ch, "Syntax: race [race]\n\r"
"Type 'race ?' for a list of races.");
return FALSE;
}
ED_FUN_DEC(olced_ac)
{
MOB_INDEX_DATA *pMob = (MOB_INDEX_DATA *) arg;
char blarg[MAX_INPUT_LENGTH];
int pierce, bash, slash, exotic;
do /* So that I can use break and send the syntax in one place */
{
if (IS_NULLSTR(argument))
break;
argument = one_argument(argument, blarg);
if (!is_number(blarg))
break;
pierce = atoi(blarg);
argument = one_argument(argument, blarg);
if (!IS_NULLSTR(blarg))
{
if (!is_number(blarg))
break;
bash = atoi(blarg);
argument = one_argument(argument, blarg);
}
else
bash = pMob->ac[AC_BASH];
if (!IS_NULLSTR(blarg))
{
if (!is_number(blarg))
break;
slash = atoi(blarg);
argument = one_argument(argument, blarg);
}
else
slash = pMob->ac[AC_SLASH];
if (!IS_NULLSTR(blarg))
{
if (!is_number(blarg))
break;
exotic = atoi(blarg);
}
else
exotic = pMob->ac[AC_EXOTIC];
pMob->ac[AC_PIERCE] = pierce;
pMob->ac[AC_BASH] = bash;
pMob->ac[AC_SLASH] = slash;
pMob->ac[AC_EXOTIC] = exotic;
chprintln(ch, "Ac set.");
return TRUE;
}
while (FALSE); /* Just do it once.. */
chprintln(ch,
"Syntax: ac [ac-pierce [ac-bash [ac-slash [ac-exotic]]]]\n\r"
"help MOB_AC gives a list of reasonable ac-values.");
return FALSE;
}
ED_FUN_DEC(olced_dice)
{
static char syntax[] = "Syntax: %s <number> d <type> + <bonus>\n\r";
char *numb, *type, *bonus, *cp;
int *arreglo = (int *) arg;
if (IS_NULLSTR(argument))
{
chprintf(ch, syntax, n_fun);
return FALSE;
}
numb = cp = (char *) argument;
while (isdigit(*cp))
++cp;
while (*cp != '\0' && !isdigit(*cp))
*(cp++) = '\0';
type = cp;
while (isdigit(*cp))
++cp;
while (*cp != '\0' && !isdigit(*cp))
*(cp++) = '\0';
bonus = cp;
while (isdigit(*cp))
++cp;
if (*cp != '\0')
*cp = '\0';
if ((!is_number(numb) || atoi(numb) < 1)
|| (!is_number(type) || atoi(type) < 1)
|| (!is_number(bonus) || atoi(bonus) < 0))
{
chprintf(ch, syntax, n_fun);
return FALSE;
}
arreglo[DICE_NUMBER] = atoi(numb);
arreglo[DICE_TYPE] = atoi(type);
arreglo[DICE_BONUS] = atoi(bonus);
chprintf(ch, "%s set.\n\r", n_fun);
return TRUE;
}
ED_FUN_DEC(olced_ed)
{
EXTRA_DESCR_DATA *ed;
EXTRA_DESCR_DATA **pEd = (EXTRA_DESCR_DATA **) arg;
EXTRA_DESCR_DATA **lEd = (EXTRA_DESCR_DATA **) par;
char command[MAX_INPUT_LENGTH];
char keyword[MAX_INPUT_LENGTH];
argument = one_argument(argument, command);
argument = one_argument(argument, keyword);
if (IS_NULLSTR(command))
{
chprintln(ch, "Syntax: ed add [keyword]");
chprintln(ch, " ed delete [keyword]");
chprintln(ch, " ed edit [keyword]");
chprintln(ch, " ed format [keyword]");
chprintln(ch, " ed rename [keyword]");
return FALSE;
}
if (!str_cmp(command, "add"))
{
if (IS_NULLSTR(keyword))
{
chprintln(ch, "Syntax: ed add [keyword]");
return FALSE;
}
ed = new_extra_descr();
replace_string(ed->keyword, keyword);
LINK(ed, *pEd, *lEd, next, prev);
string_append(ch, &ed->description);
return TRUE;
}
if (!str_cmp(command, "edit"))
{
if (IS_NULLSTR(keyword))
{
chprintln(ch, "Syntax: ed edit [keyword]");
return FALSE;
}
for (ed = *pEd; ed; ed = ed->next)
{
if (is_name(keyword, ed->keyword))
break;
}
if (!ed)
{
chprintln(ch, "ERROR : No such extra description.");
return FALSE;
}
string_append(ch, &ed->description);
return TRUE;
}
if (!str_cmp(command, "delete"))
{
EXTRA_DESCR_DATA *ped = NULL;
if (IS_NULLSTR(keyword))
{
chprintln(ch, "Syntax: ed delete [keyword]");
return FALSE;
}
for (ed = *pEd; ed; ed = ed->next)
{
if (is_name(keyword, ed->keyword))
break;
ped = ed;
}
if (!ed)
{
chprintln(ch, "ERROR : No such extra description.");
return FALSE;
}
UNLINK(ed, *pEd, *lEd, next, prev);
free_extra_descr(ed);
chprintln(ch, "Extra description deleted.");
return TRUE;
}
if (!str_cmp(command, "format"))
{
EXTRA_DESCR_DATA *ped = NULL;
if (IS_NULLSTR(keyword))
{
chprintln(ch, "Syntax: ed format [keyword]");
return FALSE;
}
for (ed = *pEd; ed; ed = ed->next)
{
if (is_name(keyword, ed->keyword))
break;
ped = ed;
}
if (!ed)
{
chprintln(ch, "ERROR : No Such Extra Description");
return FALSE;
}
ed->description = format_string(ed->description);
chprintln(ch, "Extra description formatted.");
return TRUE;
}
if (!str_cmp(command, "rename"))
{
EXTRA_DESCR_DATA *ped = NULL;
if (IS_NULLSTR(keyword))
{
chprintln(ch, "Syntax: ed rename [old] [new]");
return FALSE;
}
for (ed = *pEd; ed; ed = ed->next)
{
if (is_name(keyword, ed->keyword))
break;
ped = ed;
}
if (!ed)
{
chprintln(ch, "ERROR : No such extra description");
return FALSE;
}
replace_string(ed->keyword, argument);
chprintln(ch, "Extra description renamed.");
return TRUE;
}
return olced_ed(n_fun, ch, "", arg, par);
}
ED_FUN_DEC(olced_direction)
{
return change_exit(ch, argument, (int) par);
}
ED_FUN_DEC(olced_docomm)
{
(*(DO_FUN *) par) (ch, argument);
return FALSE;
}
ED_FUN_DEC(olced_value)
{
return oedit_values(ch, argument, (int) par);
}
bool templookup(const char *n_fun, CHAR_DATA * ch, const char *argument,
void *arg, const void *par, int temp)
{
int value;
LOOKUP_F *blah = (LOOKUP_F *) par;
if (!emptystring(argument))
{
if ((value = ((*blah) (argument))) > temp)
{
*(int *) arg = value;
chprintf(ch, "%s set.\n\r", n_fun);
return TRUE;
}
else
{
chprintf(ch, "ERROR : %s doesn't exist.\n\r", n_fun);
return FALSE;
}
}
chprintf(ch, "Syntax : %s [%s]\n\r"
"Type '? %s' for a list of arguments.\n\r", n_fun, n_fun, n_fun);
return FALSE;
}
ED_FUN_DEC(olced_poslookup)
{
return templookup(n_fun, ch, argument, arg, par, 0);
}
ED_FUN_DEC(olced_neglookup)
{
return templookup(n_fun, ch, argument, arg, par, -1);
}
CEDIT(cedit_show)
{
CLAN_DATA *pClan;
int r;
EDIT_CLAN(ch, pClan);
chprintf(ch, "Name: %s\n\r", pClan->name);
chprintf(ch, "Who: %s\n\r", pClan->who_name);
chprintf(ch, "Hall: %ld\n\r", pClan->hall);
chprintf(ch, "Independant: %s\n\r", pClan->independent ? "TRUE" : "FALSE");
for (r = 0; r < MAX_RANK; r++)
chprintf(ch, "Rank %d: %s\n\r", r + 1, pClan->rank[r].rankname);
return TRUE;
}
CEDIT(cedit_rank)
{
CLAN_DATA *pClan;
char arg1[MIL];
EDIT_CLAN(ch, pClan);
argument = one_argument(argument, arg1);
if (is_number(arg1) && atoi(arg1) <= MAX_RANK && atoi(arg1) > 0)
{
int value;
value = atoi(arg1) - 1;
if (!IS_NULLSTR(argument))
{
replace_string(pClan->rank[value].rankname, argument);
chprintln(ch, "Rank name changed.");
return TRUE;
}
}
chprintln(ch, "Syntax: rank rank# newname");
return FALSE;
}
CEDIT(cedit_create)
{
CLAN_DATA *pClan;
char buf[MIL];
if (!IS_NULLSTR(argument) && clan_lookup(argument) == NULL)
sprintf(buf, argument);
else
sprintf(buf, "New Clan%d", maxClan + 1);
pClan = new_clan();
replace_string(pClan->name, buf);
replace_string(pClan->who_name, buf);
LINK(pClan, clan_first, clan_last, next, prev);
edit_start(ch, pClan, ED_CLAN);
chprintln(ch, "Clan created.");
return TRUE;
}
CEDIT(cedit_delete)
{
CLAN_DATA *pClan;
EDIT_CLAN(ch, pClan);
if (str_cmp(argument, "confirm"))
{
chprintln(ch,
"Typing 'delete confirm' again will permanetely remove this clan!\n\r"
"-or- 'delete cancel' will cancel the deletion.");
return FALSE;
}
else
{
CHAR_DATA *pch;
int hash;
ROOM_INDEX_DATA *pRoom;
MBR_DATA *pmbr, *next = NULL;
for (pmbr = mbr_first; pmbr != NULL; pmbr = next)
{
next = pmbr->next;
if (pmbr->clan == pClan)
{
UNLINK(pmbr, mbr_first, mbr_last, next, prev);
free_mbr(pmbr);
}
}
for (pch = char_first; pch != NULL; pch = pch->next)
{
if (pch->clan == pClan)
{
pch->clan = NULL;
pch->rank = 0;
}
}
for (hash = 0; hash < MAX_KEY_HASH; hash++)
{
for (pRoom = room_index_hash[hash]; pRoom; pRoom = pRoom->next)
{
if (pRoom->clan == pClan)
{
pRoom->clan = NULL;
SET_BIT(pRoom->area->area_flags, AREA_CHANGED);
}
}
}
UNLINK(pClan, clan_first, clan_last, next, prev);
free_clan(pClan);
pClan = clan_first;
edit_start(ch, pClan, ED_CLAN);
chprintln(ch, "Clan deleted.");
}
return TRUE;
}
OEDIT(oedit_autoweapon)
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
if (pObj->item_type != ITEM_WEAPON)
{
chprintln(ch, " {rAutoweapon only works on weapons...{x");
return FALSE;
}
if (pObj->level < 1)
{
chprintlnf
(ch,
" {cAutoweapon requires a level to be set on the weapon first(vnum %ld).{x",
pObj->vnum);
return FALSE;
}
if (IS_OBJ_STAT(pObj, ITEM_QUEST))
{
chprintln(ch, "This weapon cannot be autoset.");
return FALSE;
}
autoweapon(pObj);
chprintln(ch, "Weapon set to default values., check for accuracy.");
return TRUE;
}
OEDIT(oedit_autoarmor)
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
if (pObj->item_type != ITEM_ARMOR)
{
chprintln(ch, " {rAutoArmor only works on Armor ...{x");
return FALSE;
}
if (pObj->level < 1)
{
chprintlnf
(ch,
" {cAutoArmor requires a level to be set on the armor first.(vnum %ld){x",
pObj->vnum);
return FALSE;
}
if (IS_OBJ_STAT(pObj, ITEM_QUEST))
{
chprintln(ch, "This weapon cannot be autoset.");
return FALSE;
}
autoarmor(pObj);
chprintln(ch, "AutoArmor has set experimental values for AC.{x");
return TRUE;
}
MEDIT(medit_autoset)
{
MOB_INDEX_DATA *pMob;
EDIT_MOB(ch, pMob);
if (pMob->level < 1)
{
chprintlnf(ch, "Set a level on the mob first!!!(vnum %ld)", pMob->vnum);
return FALSE;
}
autoset(pMob);
chprintln(ch, " Values set, check for accuracy.");
return TRUE;
}
MEDIT(medit_autohard)
{
MOB_INDEX_DATA *pMob;
EDIT_MOB(ch, pMob);
if (pMob->level < 1)
{
chprintlnf(ch, "Set a level on the mob first!!!(vnum %ld)", pMob->vnum);
return FALSE;
}
autohard(pMob);
chprintln(ch, " Hard values set, check for accuracy.");
return TRUE;
}
MEDIT(medit_autoeasy)
{
MOB_INDEX_DATA *pMob;
EDIT_MOB(ch, pMob);
if (pMob->level < 1)
{
chprintlnf(ch, "Set a level on the mob first!!!(vnum %ld)", pMob->vnum);
return FALSE;
}
autoeasy(pMob);
chprintln(ch, " Easy values set, check for accuracy.");
return TRUE;
}