/****************************************************************************
* [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// *
* -----------------------------------------------------------| (0...0) *
* SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( *
* -----------------------------------------------------------| {o o} *
* SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ *
* Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~*
* Tricops and Fireblade | *
* ------------------------------------------------------------------------ *
* Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* ------------------------------------------------------------------------ *
* Online Reset Editing Module *
****************************************************************************/
/*
* This file relies heavily on the fact that your linked lists are correct,
* and that pArea->reset_first is the first reset in pArea. Likewise,
* pArea->reset_last *MUST* be the last reset in pArea. Weird and
* wonderful things will happen if any of your lists are messed up, none
* of them good. The most important are your pRoom->contents,
* pRoom->people, rch->carrying, obj->contains, and pArea->reset_first ..
* pArea->reset_last. -- Altrag
*/
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "mud.h"
/* Externals */
extern int top_reset;
char *sprint_reset args((CHAR_DATA * ch, RESET_DATA * pReset, sh_int num, bool rlist));
RESET_DATA *parse_reset args((AREA_DATA * tarea, char *argument, CHAR_DATA * ch));
int get_wearloc args((char *type));
int get_trapflag args((char *flag));
int get_exflag args((char *flag));
int get_rflag args((char *flag));
extern char *const wear_locs[];
extern char *const ex_flags[];
#define MAX_OBJ 50
int put_index, obj_index;
int obj_array[MAX_OBJ][2];
int put_array[MAX_OBJ][3];
#define IS_OBJ_TYPE(obj) ( obj->item_type == ITEM_KEYRING \
||obj->item_type == ITEM_QUIVER \
||obj->item_type == ITEM_CONTAINER \
||obj->item_type == ITEM_SHEATH)
#define RD RESET_DATA
RD *find_reset args((AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, int num));
#undef RD
void list_resets args((CHAR_DATA * ch, AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, int start, int end));
#define RID ROOM_INDEX_DATA
RID *find_room args((CHAR_DATA * ch, char *argument, ROOM_INDEX_DATA * pRoom));
#undef RID
RESET_DATA *find_reset(AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, int numb)
{
RESET_DATA *pReset;
int num = 0;
for (pReset = pArea->first_reset; pReset; pReset = pReset->next)
if (is_room_reset(pReset, pRoom, pArea) && ++num >= numb)
return pReset;
return NULL;
}
/* Finds the mobs in the Reset Area and puts their limits on in acending order --Xerves*/
int fmob_count(AREA_DATA * pArea, int vnum)
{
RESET_DATA *pReset;
int count = 1;
for (pReset = pArea->first_reset; pReset; pReset = pReset->next)
{
if (pReset->arg1 == vnum && pReset->command == 'M')
{
pReset->arg2 = count;
count++;
}
}
return count;
}
/* This is one loopy function. Ugh. -- Altrag */
bool is_room_reset(RESET_DATA * pReset, ROOM_INDEX_DATA * aRoom, AREA_DATA * pArea)
{
ROOM_INDEX_DATA *pRoom;
RESET_DATA *reset;
int pr;
if (!aRoom)
return TRUE;
switch (pReset->command)
{
case 'M':
case 'O':
pRoom = get_room_index(pReset->arg3);
if (!pRoom || pRoom != aRoom)
return FALSE;
return TRUE;
case 'P':
case 'T':
case 'H':
if (pReset->command == 'H')
pr = pReset->arg1;
else
pr = pReset->arg3;
for (reset = pReset->prev; reset; reset = reset->prev)
if ((reset->command == 'O' || reset->command == 'P' ||
reset->command == 'G' || reset->command == 'E') && (!pr || pr == reset->arg1) && get_obj_index(reset->arg1))
break;
if (reset && is_room_reset(reset, aRoom, pArea))
return TRUE;
return FALSE;
case 'B':
switch (pReset->arg2 & BIT_RESET_TYPE_MASK)
{
case BIT_RESET_DOOR:
case BIT_RESET_ROOM:
return (aRoom->vnum == pReset->arg1);
case BIT_RESET_MOBILE:
for (reset = pReset->prev; reset; reset = reset->prev)
if (reset->command == 'M' && get_mob_index(reset->arg1))
break;
if (reset && is_room_reset(reset, aRoom, pArea))
return TRUE;
return FALSE;
case BIT_RESET_OBJECT:
for (reset = pReset->prev; reset; reset = reset->prev)
if ((reset->command == 'O' || reset->command == 'P' ||
reset->command == 'G' || reset->command == 'E') &&
(!pReset->arg1 || pReset->arg1 == reset->arg1) && get_obj_index(reset->arg1))
break;
if (reset && is_room_reset(reset, aRoom, pArea))
return TRUE;
return FALSE;
}
return FALSE;
case 'G':
case 'E':
for (reset = pReset->prev; reset; reset = reset->prev)
if (reset->command == 'M' && get_mob_index(reset->arg1))
break;
if (reset && is_room_reset(reset, aRoom, pArea))
return TRUE;
return FALSE;
case 'D':
case 'R':
pRoom = get_room_index(pReset->arg1);
if (!pRoom || pRoom->area != pArea || (aRoom && pRoom != aRoom))
return FALSE;
return TRUE;
default:
return FALSE;
}
return FALSE;
}
ROOM_INDEX_DATA *find_room(CHAR_DATA * ch, char *argument, ROOM_INDEX_DATA * pRoom)
{
char arg[MIL];
if (pRoom)
return pRoom;
one_argument(argument, arg);
if (!is_number(arg) && arg[0] != '\0')
{
send_to_char("Reset to which room?\n\r", ch);
return NULL;
}
if (arg[0] == '\0')
pRoom = ch->in_room;
else
pRoom = get_room_index(atoi(arg));
if (!pRoom)
{
send_to_char("Room does not exist.\n\r", ch);
return NULL;
}
return pRoom;
}
/* Separate function for recursive purposes */
#define DEL_RESET(area, reset, rprev) \
do { \
rprev = reset->prev; \
delete_reset(area, reset); \
reset = rprev; \
continue; \
} while(0)
void delete_reset(AREA_DATA * pArea, RESET_DATA * pReset)
{
RESET_DATA *reset;
RESET_DATA *reset_prev;
if (pReset->command == 'M')
{
for (reset = pReset->next; reset; reset = reset->next)
{
/* Break when a new mob found */
if (reset->command == 'M')
break;
/* Delete anything mob is holding */
if (reset->command == 'G' || reset->command == 'E')
DEL_RESET(pArea, reset, reset_prev);
if (reset->command == 'B' && (reset->arg2 & BIT_RESET_TYPE_MASK) == BIT_RESET_MOBILE && (!reset->arg1 || reset->arg1 == pReset->arg1))
DEL_RESET(pArea, reset, reset_prev);
}
}
else if (pReset->command == 'O' || pReset->command == 'P' || pReset->command == 'G' || pReset->command == 'E')
{
for (reset = pReset->next; reset; reset = reset->next)
{
if (reset->command == 'T' && (!reset->arg3 || reset->arg3 == pReset->arg1))
DEL_RESET(pArea, reset, reset_prev);
if (reset->command == 'H' && (!reset->arg1 || reset->arg1 == pReset->arg1))
DEL_RESET(pArea, reset, reset_prev);
/* Delete nested objects, even if they are the same object. */
if (reset->command == 'P' && (reset->arg3 > 0 ||
pReset->command != 'P' || reset->extra - 1 == pReset->extra) && (!reset->arg3 || reset->arg3 == pReset->arg1))
DEL_RESET(pArea, reset, reset_prev);
if (reset->command == 'B' && (reset->arg2 & BIT_RESET_TYPE_MASK) == BIT_RESET_OBJECT && (!reset->arg1 || reset->arg1 == pReset->arg1))
DEL_RESET(pArea, reset, reset_prev);
if (reset->command == 'A')
DEL_RESET(pArea, reset, reset_prev);
/* Break when a new object of same type is found */
if ((reset->command == 'O' || reset->command == 'P' || reset->command == 'G' || reset->command == 'E') && reset->arg1 == pReset->arg1)
break;
}
}
if (pReset == pArea->last_mob_reset)
pArea->last_mob_reset = NULL;
if (pReset == pArea->last_obj_reset)
pArea->last_obj_reset = NULL;
UNLINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
DISPOSE(pReset);
return;
}
#undef DEL_RESET
RESET_DATA *find_oreset(CHAR_DATA * ch, AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, char *name)
{
RESET_DATA *reset;
if (!*name)
{
for (reset = pArea->last_reset; reset; reset = reset->prev)
{
if (!is_room_reset(reset, pRoom, pArea))
continue;
switch (reset->command)
{
default:
continue;
case 'O':
case 'E':
case 'G':
case 'P':
break;
}
break;
}
if (!reset)
send_to_char("No object resets in list.\n\r", ch);
return reset;
}
else
{
char arg[MIL];
int cnt = 0, num = number_argument(name, arg);
OBJ_INDEX_DATA *pObjTo = NULL;
for (reset = pArea->first_reset; reset; reset = reset->next)
{
if (!is_room_reset(reset, pRoom, pArea))
continue;
switch (reset->command)
{
default:
continue;
case 'O':
case 'E':
case 'G':
case 'P':
break;
}
if ((pObjTo = get_obj_index(reset->arg1)) && (is_name(arg, pObjTo->name) || !str_cmp(arg, pObjTo->name)) && ++cnt == num)
break;
}
if (!pObjTo || !reset)
{
send_to_char("To object not in reset list.\n\r", ch);
return NULL;
}
}
return reset;
}
RESET_DATA *find_mreset(CHAR_DATA * ch, AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, char *name)
{
RESET_DATA *reset;
if (!*name)
{
for (reset = pArea->last_reset; reset; reset = reset->prev)
{
if (!is_room_reset(reset, pRoom, pArea))
continue;
switch (reset->command)
{
default:
continue;
case 'M':
break;
}
break;
}
if (!reset)
send_to_char("No mobile resets in list.\n\r", ch);
return reset;
}
else
{
char arg[MIL];
int cnt = 0, num = number_argument(name, arg);
MOB_INDEX_DATA *pMob = NULL;
for (reset = pArea->first_reset; reset; reset = reset->next)
{
if (!is_room_reset(reset, pRoom, pArea))
continue;
switch (reset->command)
{
default:
continue;
case 'M':
break;
}
if ((pMob = get_mob_index(reset->arg1)) && is_name(arg, pMob->player_name) && ++cnt == num)
break;
}
if (!pMob || !reset)
{
send_to_char("Mobile not in reset list.\n\r", ch);
return NULL;
}
}
return reset;
}
bool can_mapmodify(CHAR_DATA * ch, ROOM_INDEX_DATA * room)
{
sh_int vnum = room->vnum;
AREA_DATA *pArea;
if (IS_NPC(ch))
return FALSE;
if (get_trust(ch) >= sysdata.level_modify_proto)
return TRUE;
if (!xIS_SET(room->room_flags, ROOM_PROTOTYPE))
{
send_to_char("You cannot modify this room.\n\r", ch);
return FALSE;
}
if (!ch->pcdata || !(pArea = ch->pcdata->area))
{
send_to_char("You must have an assigned area to modify this room.\n\r", ch);
return FALSE;
}
if (vnum >= pArea->low_r_vnum && vnum <= pArea->hi_r_vnum)
return TRUE;
send_to_char("That room is not in your allocated range.\n\r", ch);
return FALSE;
}
void edit_reset(CHAR_DATA * ch, char *argument, AREA_DATA * pArea, ROOM_INDEX_DATA * aRoom)
{
char arg[MIL];
RESET_DATA *pReset = NULL;
RESET_DATA *reset = NULL;
MOB_INDEX_DATA *pMob = NULL;
ROOM_INDEX_DATA *pRoom;
OBJ_INDEX_DATA *pObj;
int num = 0;
int vnum;
char *origarg = argument;
argument = one_argument(argument, arg);
if (!*arg || !str_cmp(arg, "?"))
{
char *nm = (ch->substate == SUB_REPEATCMD ? "" : (aRoom ? "rreset " : "reset "));
char *rn = (aRoom ? "" : " [room#]");
ch_printf(ch, "Syntax: %s<list|edit|delete|add|insert|place%s>\n\r", nm, (aRoom ? "" : "|area"));
ch_printf(ch, "Syntax: %sremove <#>\n\r", nm);
ch_printf(ch, "Syntax: %smobile <mob#> [limit]%s\n\r", nm, rn);
ch_printf(ch, "Syntax: %sobject <obj#> [limit [room%s]]\n\r", nm, rn);
ch_printf(ch, "Syntax: %sobject <obj#> give <mob name> [limit]\n\r", nm);
ch_printf(ch, "Syntax: %sobject <obj#> equip <mob name> <location> " "[limit]\n\r", nm);
ch_printf(ch, "Syntax: %sobject <obj#> put <to_obj name> [limit]\n\r", nm);
ch_printf(ch, "Syntax: %stime <#> <time to pop>\n\r", nm);
ch_printf(ch, "Syntax: %shide <obj name>\n\r", nm);
ch_printf(ch, "Syntax: %strap <obj name> <type> <charges> <flags>\n\r", nm);
ch_printf(ch, "Syntax: %strap room <type> <charges> <flags>\n\r", nm);
ch_printf(ch, "Syntax: %sbit <set|toggle|remove> door%s <dir> " "<exit flags>\n\r", nm, rn);
ch_printf(ch, "Syntax: %sbit <set|toggle|remove> object <obj name> " "<extra flags>\n\r", nm);
ch_printf(ch, "Syntax: %sbit <set|toggle|remove> mobile <mob name> " "<affect flags>\n\r", nm);
ch_printf(ch, "Syntax: %sbit <set|toggle|remove> room%s <room flags>" "\n\r", nm, rn);
ch_printf(ch, "Syntax: %srandom <last dir>%s\n\r", nm, rn);
if (!aRoom)
{
send_to_char("\n\r[room#] will default to the room you are in, " "if unspecified.\n\r", ch);
}
return;
}
if (!str_cmp(arg, "on"))
{
ch->substate = SUB_REPEATCMD;
ch->dest_buf = (aRoom ? (void *) aRoom : (void *) pArea);
send_to_char("Reset mode on.\n\r", ch);
return;
}
if (!aRoom && !str_cmp(arg, "area"))
{
if (!pArea->first_reset)
{
send_to_char("You don't have any resets defined.\n\r", ch);
return;
}
num = pArea->nplayer;
pArea->nplayer = 0;
reset_area(pArea, 0);
pArea->nplayer = num;
send_to_char("Done.\n\r", ch);
return;
}
if (!str_cmp(arg, "list"))
{
int start, end;
argument = one_argument(argument, arg);
start = is_number(arg) ? atoi(arg) : -1;
argument = one_argument(argument, arg);
end = is_number(arg) ? atoi(arg) : -1;
list_resets(ch, pArea, aRoom, start, end);
return;
}
if (!str_cmp(arg, "edit"))
{
argument = one_argument(argument, arg);
if (!*arg || !is_number(arg))
{
send_to_char("Usage: reset edit <number> <command>\n\r", ch);
return;
}
num = atoi(arg);
if (!(pReset = find_reset(pArea, aRoom, num)))
{
send_to_char("Reset not found.\n\r", ch);
return;
}
if ((reset = parse_reset(pArea, argument, ch)) == NULL)
{
send_to_char("Error in reset. Reset not changed.\n\r", ch);
return;
}
reset->serial = pReset->serial;
reset->prev = pReset->prev;
reset->next = pReset->next;
if (!pReset->prev)
pArea->first_reset = reset;
else
pReset->prev->next = reset;
if (!pReset->next)
pArea->last_reset = reset;
else
pReset->next->prev = reset;
DISPOSE(pReset);
send_to_char("Done.\n\r", ch);
return;
}
if (!str_cmp(arg, "add"))
{
if ((pReset = parse_reset(pArea, argument, ch)) == NULL)
{
send_to_char("Error in reset. Reset not added.\n\r", ch);
return;
}
reset = add_reset(pArea, pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3, pReset->arg4, pReset->arg5, pReset->arg6, -1, 0, 0);
reset->serial = ++serialmobsloaded;
serial_list[reset->serial] = FALSE;
DISPOSE(pReset);
send_to_char("Done.\n\r", ch);
return;
}
if (!str_cmp(arg, "place"))
{
if ((pReset = parse_reset(pArea, argument, ch)) == NULL)
{
send_to_char("Error in reset. Reset not added.\n\r", ch);
return;
}
pReset->serial = ++serialmobsloaded;
serial_list[pReset->serial] = FALSE;
reset = place_reset(pArea, pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3, pReset->arg4, pReset->arg5, pReset->arg6, -1, 0, 0);
reset->serial = ++serialmobsloaded;
serial_list[reset->serial] = FALSE;
DISPOSE(pReset);
send_to_char("Done.\n\r", ch);
return;
}
if (!str_cmp(arg, "insert"))
{
argument = one_argument(argument, arg);
if (!*arg || !is_number(arg))
{
send_to_char("Usage: reset insert <number> <command>\n\r", ch);
return;
}
num = atoi(arg);
if ((reset = find_reset(pArea, aRoom, num)) == NULL)
{
send_to_char("Reset not found.\n\r", ch);
return;
}
if ((pReset = parse_reset(pArea, argument, ch)) == NULL)
{
send_to_char("Error in reset. Reset not inserted.\n\r", ch);
return;
}
pReset->serial = ++serialmobsloaded;
serial_list[pReset->serial] = FALSE;
INSERT(pReset, reset, pArea->first_reset, next, prev);
send_to_char("Done.\n\r", ch);
return;
}
if (!str_cmp(arg, "delete"))
{
int start, end;
bool found;
if (!*argument)
{
send_to_char("Usage: reset delete <start> [end]\n\r", ch);
return;
}
argument = one_argument(argument, arg);
start = is_number(arg) ? atoi(arg) : -1;
end = is_number(arg) ? atoi(arg) : -1;
num = 0;
found = FALSE;
for (pReset = pArea->first_reset; pReset; pReset = reset)
{
reset = pReset->next;
if (!is_room_reset(pReset, aRoom, pArea))
continue;
if (start > ++num)
continue;
if ((end != -1 && num > end) || (end == -1 && found))
return;
UNLINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
if (pReset == pArea->last_mob_reset)
pArea->last_mob_reset = NULL;
DISPOSE(pReset);
top_reset--;
found = TRUE;
}
if (!found)
send_to_char("Reset not found.\n\r", ch);
else
send_to_char("Done.\n\r", ch);
return;
}
if (!str_cmp(arg, "remove"))
{
int iarg;
argument = one_argument(argument, arg);
if (arg[0] == '\0' || !is_number(arg))
{
send_to_char("Delete which reset?\n\r", ch);
return;
}
iarg = atoi(arg);
for (pReset = pArea->first_reset; pReset; pReset = pReset->next)
{
if (is_room_reset(pReset, aRoom, pArea) && ++num == iarg)
break;
}
if (!pReset)
{
send_to_char("Reset does not exist.\n\r", ch);
return;
}
delete_reset(pArea, pReset);
send_to_char("Reset deleted.\n\r", ch);
return;
}
if (!str_prefix(arg, "time"))
{
int tleft;
int ttime = time(0);
int sec, hour, min, days, rtime;
char time[256];
argument = one_argument(argument, arg);
if (!*arg || (!is_number(arg) && str_cmp(arg, "left") && str_cmp(arg, "forcereset")))
{
send_to_char("Usage: reset time <number> <time to reset>\n\r", ch);
send_to_char("Usage: reset time left <number> --Shows Time Left till Reset\n\r", ch);
send_to_char("Usage: reset time forcereset <number> --Sets the time to reset to now, will reset next reset area tick\n\r", ch);
send_to_char("Time to reset is in seconds. 60 seconds in a minute, 3600 seconds in an hour, 86,400 seconds in a day\n\r", ch);
return;
}
if (!str_cmp(arg, "forcereset"))
{
num = atoi(argument);
if (!(pReset = find_reset(pArea, aRoom, num)))
{
send_to_char("Reset not found.\n\r", ch);
return;
}
if (pReset->resetlast < 1)
{
send_to_char("That reset is not a time based Reset.\n\r", ch);
return;
}
pReset->resetlast = ttime-pReset->resettime;
send_to_char("Done.\n\r", ch);
return;
}
if (!str_cmp(arg, "left"))
{
num = atoi(argument);
if (!(pReset = find_reset(pArea, aRoom, num)))
{
send_to_char("Reset not found.\n\r", ch);
return;
}
if (pReset->resetlast < 1)
{
send_to_char("That reset is not a time based Reset.\n\r", ch);
return;
}
tleft = pReset->resetlast + pReset->resettime - ttime;
if (tleft < 1)
{
send_to_char("The Reset will load next time a Reset Area is issued.\n\r", ch);
return;
}
if (tleft > 86400)
{
days = pReset->resettime / 86400;
rtime = pReset->resettime % 86400;
}
else
{
days = 0;
rtime = tleft;
}
sec = rtime % 60;
hour = rtime / 3600;
if (rtime > 60)
{
min = rtime / 60;
min = min % 60;
}
else
{
min = 0;
}
sprintf(time, "&w&WTime Left: D:%d H:%d M:%d S:%d\n\r", days, hour, min, sec);
send_to_char(time, ch);
return;
}
num = atoi(arg);
if (!(pReset = find_reset(pArea, aRoom, num)))
{
send_to_char("Reset not found.\n\r", ch);
return;
}
num = atoi(argument);
if (num < -1 || num > 300000000)
{
send_to_char("Range is -1 (Resets once), 0 (Resets every tick) to 300mil (resets every 10 years or so)\n\r", ch);
return;
}
pReset->resettime = num;
pReset->resetlast = 0;
ch_printf(ch, "Time of %d added.\n\r", num);
return;
}
if (!str_prefix(arg, "mobile"))
{
argument = one_argument(argument, arg);
if (arg[0] == '\0' || !is_number(arg))
{
send_to_char("Reset which mobile vnum?\n\r", ch);
return;
}
if (!(pMob = get_mob_index(atoi(arg))))
{
send_to_char("Mobile does not exist.\n\r", ch);
return;
}
argument = one_argument(argument, arg);
if (arg[0] == '\0')
num = 1;
else if (!is_number(arg))
{
send_to_char("Reset how many mobiles?\n\r", ch);
return;
}
else
num = atoi(arg);
if (!(pRoom = find_room(ch, argument, aRoom)))
return;
pReset = make_reset('M', 0, pMob->vnum, 0, pRoom->vnum, -1, -1, -1, -1, 0, 0);
pReset->serial = ++serialmobsloaded;
pReset->arg2 = 1;
serial_list[pReset->serial] = FALSE;
LINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
send_to_char("Mobile reset added.\n\r", ch);
return;
}
if (!str_prefix(arg, "object"))
{
argument = one_argument(argument, arg);
if (arg[0] == '\0' || !is_number(arg))
{
send_to_char("Reset which object vnum?\n\r", ch);
return;
}
if (!(pObj = get_obj_index(atoi(arg))))
{
send_to_char("Object does not exist.\n\r", ch);
return;
}
argument = one_argument(argument, arg);
if (arg[0] == '\0')
strcpy(arg, "room");
if (!str_prefix(arg, "put"))
{
argument = one_argument(argument, arg);
if (!(reset = find_oreset(ch, pArea, aRoom, arg)))
return;
pReset = reset;
/* Put in_objects after hide and trap resets */
while (reset->next && (reset->next->command == 'H' ||
reset->next->command == 'T' ||
(reset->next->command == 'B' &&
(reset->next->arg2 & BIT_RESET_TYPE_MASK) == BIT_RESET_OBJECT && (!reset->next->arg1 || reset->next->arg1 == pReset->arg1))))
reset = reset->next;
/* pReset = make_reset('P', 1, pObj->vnum, num, reset->arg1);*/
argument = one_argument(argument, arg);
if ((vnum = atoi(arg)) < 1)
vnum = 1;
pReset = make_reset('P', reset->extra + 1, pObj->vnum, vnum, 0, -1, -1, -1, -1, 0, 0);
/* Grumble.. insert puts pReset before reset, and we need it after,
so we make a hackup and reverse all the list params.. :P.. */
INSERT(pReset, reset, pArea->last_reset, prev, next);
send_to_char("Object reset in object created.\n\r", ch);
return;
}
if (!str_prefix(arg, "give"))
{
argument = one_argument(argument, arg);
if (!(reset = find_mreset(ch, pArea, aRoom, arg)))
return;
pReset = reset;
while (reset->next && reset->next->command == 'B' &&
(reset->next->arg2 & BIT_RESET_TYPE_MASK) == BIT_RESET_OBJECT && (!reset->next->arg1 || reset->next->arg1 == pReset->arg1))
reset = reset->next;
argument = one_argument(argument, arg);
if ((vnum = atoi(arg)) < 1)
vnum = 1;
pReset = make_reset('G', 1, pObj->vnum, vnum, 0, -1, -1, -1, -1, 0, 0);
INSERT(pReset, reset, pArea->last_reset, prev, next);
send_to_char("Object reset to mobile created.\n\r", ch);
return;
}
if (!str_prefix(arg, "equip"))
{
argument = one_argument(argument, arg);
if (!(reset = find_mreset(ch, pArea, aRoom, arg)))
return;
pReset = reset;
while (reset->next && reset->next->command == 'B' &&
(reset->next->arg2 & BIT_RESET_TYPE_MASK) == BIT_RESET_OBJECT && (!reset->next->arg1 || reset->next->arg1 == pReset->arg1))
reset = reset->next;
num = get_wearloc(argument);
if (num < 0)
{
send_to_char("Reset object to which location?\n\r", ch);
return;
}
for (pReset = reset->next; pReset; pReset = pReset->next)
{
if (pReset->command == 'M')
break;
if (pReset->command == 'E' && pReset->arg3 == num)
{
send_to_char("Mobile already has an item equipped there.\n\r", ch);
return;
}
}
argument = one_argument(argument, arg);
if ((vnum = atoi(arg)) < 1)
vnum = 1;
pReset = make_reset('E', 1, pObj->vnum, vnum, num, -1, -1, -1, -1, 0, 0);
INSERT(pReset, reset, pArea->last_reset, prev, next);
send_to_char("Object reset equipped by mobile created.\n\r", ch);
return;
}
if (arg[0] == '\0' || !(num = (int) str_cmp(arg, "room")) || is_number(arg))
{
if (!(bool) num)
argument = one_argument(argument, arg);
if (!(pRoom = find_room(ch, argument, aRoom)))
return;
if (pRoom->area != pArea)
{
send_to_char("Cannot reset objects to other areas.\n\r", ch);
return;
}
if ((vnum = atoi(arg)) < 1)
vnum = 1;
pReset = make_reset('O', 0, pObj->vnum, vnum, pRoom->vnum, -1, -1, -1, -1, 0, 0);
LINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
send_to_char("Object reset added.\n\r", ch);
return;
}
send_to_char("Reset object to where?\n\r", ch);
return;
}
if (!str_cmp(arg, "random"))
{
argument = one_argument(argument, arg);
vnum = get_dir(arg);
if (vnum < 0 || vnum > 9)
{
send_to_char("Reset which random doors?\n\r", ch);
return;
}
if (vnum == 0)
{
send_to_char("There is no point in randomizing one door.\n\r", ch);
return;
}
pRoom = find_room(ch, argument, aRoom);
if (pRoom->area != pArea)
{
send_to_char("Cannot randomize doors in other areas.\n\r", ch);
return;
}
pReset = make_reset('R', 0, pRoom->vnum, vnum, 0, -1, -1, -1, -1, 0, 0);
LINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
send_to_char("Reset random doors created.\n\r", ch);
return;
}
if (!str_cmp(arg, "trap"))
{
char oname[MIL];
int chrg, value, extra = 0;
bool isobj;
argument = one_argument(argument, oname);
argument = one_argument(argument, arg);
num = is_number(arg) ? atoi(arg) : -1;
argument = one_argument(argument, arg);
chrg = is_number(arg) ? atoi(arg) : -1;
isobj = is_name("obj", argument);
if (isobj == is_name("room", argument))
{
send_to_char("Reset: TRAP: Must specify ROOM or OBJECT\n\r", ch);
return;
}
if (!str_cmp(oname, "room") && !isobj)
{
vnum = (aRoom ? aRoom->vnum : ch->in_room->vnum);
extra = TRAP_ROOM;
}
else
{
if (is_number(oname) && !isobj)
{
vnum = atoi(oname);
if (!get_room_index(vnum))
{
send_to_char("Reset: TRAP: no such room\n\r", ch);
return;
}
reset = NULL;
extra = TRAP_ROOM;
}
else
{
if (!(reset = find_oreset(ch, pArea, aRoom, oname)))
return;
/* vnum = reset->arg1;*/
vnum = 0;
extra = TRAP_OBJ;
}
}
if (num < 1 || num > MAX_TRAPTYPE)
{
send_to_char("Reset: TRAP: invalid trap type\n\r", ch);
return;
}
if (chrg < 0 || chrg > 10000)
{
send_to_char("Reset: TRAP: invalid trap charges\n\r", ch);
return;
}
while (*argument)
{
argument = one_argument(argument, arg);
value = get_trapflag(arg);
if (value < 0 || value > 31)
{
send_to_char("Reset: TRAP: bad flag\n\r", ch);
return;
}
SET_BIT(extra, 1 << value);
}
pReset = make_reset('T', extra, num, chrg, vnum, -1, -1, -1, -1, 0, 0);
if (reset)
INSERT(pReset, reset, pArea->last_reset, prev, next);
else
LINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
send_to_char("Trap created.\n\r", ch);
return;
}
if (!str_cmp(arg, "bit"))
{
int (*flfunc) (char *type);
int flags = 0;
char option[MIL];
char *parg;
bool ext_bv = FALSE;
argument = one_argument(argument, option);
if (!*option)
{
send_to_char("You must specify SET, REMOVE, or TOGGLE.\n\r", ch);
return;
}
num = 0;
if (!str_prefix(option, "set"))
SET_BIT(num, BIT_RESET_SET);
else if (!str_prefix(option, "toggle"))
SET_BIT(num, BIT_RESET_TOGGLE);
else if (str_prefix(option, "remove"))
{
send_to_char("You must specify SET, REMOVE, or TOGGLE.\n\r", ch);
return;
}
argument = one_argument(argument, option);
parg = argument;
argument = one_argument(argument, arg);
if (!*option)
{
send_to_char("Must specify OBJECT, MOBILE, ROOM, or DOOR.\n\r", ch);
return;
}
if (!str_prefix(option, "door"))
{
SET_BIT(num, BIT_RESET_DOOR);
if (aRoom)
{
pRoom = aRoom;
argument = parg;
}
else if (!is_number(arg))
{
pRoom = ch->in_room;
argument = parg;
}
else if (!(pRoom = find_room(ch, arg, aRoom)))
return;
argument = one_argument(argument, arg);
if (!*arg)
{
send_to_char("Must specify direction.\n\r", ch);
return;
}
vnum = get_dir(arg);
SET_BIT(num, vnum << BIT_RESET_DOOR_THRESHOLD);
vnum = pRoom->vnum;
flfunc = &get_exflag;
reset = NULL;
}
else if (!str_prefix(option, "object"))
{
SET_BIT(num, BIT_RESET_OBJECT);
vnum = 0;
flfunc = &get_oflag;
if (!(reset = find_oreset(ch, pArea, aRoom, arg)))
return;
ext_bv = TRUE;
}
else if (!str_prefix(option, "mobile"))
{
SET_BIT(num, BIT_RESET_MOBILE);
vnum = 0;
flfunc = &get_aflag;
if (!(reset = find_mreset(ch, pArea, aRoom, arg)))
return;
ext_bv = TRUE;
}
else if (!str_prefix(option, "room"))
{
SET_BIT(num, BIT_RESET_ROOM);
if (aRoom)
{
pRoom = aRoom;
argument = parg;
}
else if (!is_number(arg))
{
pRoom = ch->in_room;
argument = parg;
}
else if (!(pRoom = find_room(ch, arg, aRoom)))
return;
vnum = pRoom->vnum;
flfunc = &get_rflag;
reset = NULL;
}
else
{
send_to_char("Must specify OBJECT, MOBILE, ROOM, or DOOR.\n\r", ch);
return;
}
while (*argument)
{
int value;
argument = one_argument(argument, arg);
value = (*flfunc) (arg);
if (value < 0 || (!ext_bv && value > 31))
{
send_to_char("Reset: BIT: bad flag\n\r", ch);
return;
}
if (ext_bv) /* one per flag for extendeds */
{
pReset = make_reset('B', 1, vnum, num, flags, -1, -1, -1, -1, 0, 0);
if (reset)
{
INSERT(pReset, reset, pArea->last_reset, prev, next);
reset = pReset;
}
else
LINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
}
else
SET_BIT(flags, 1 << value);
}
if (!flags)
{
send_to_char("Set which flags?\n\r", ch);
return;
}
if (!ext_bv)
{
pReset = make_reset('B', 1, vnum, num, flags, -1, -1, -1, -1, 0, 0);
if (reset)
INSERT(pReset, reset, pArea->last_reset, prev, next);
else
LINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
}
send_to_char("Bitvector reset created.\n\r", ch);
return;
}
if (!str_cmp(arg, "hide"))
{
argument = one_argument(argument, arg);
if (!(reset = find_oreset(ch, pArea, aRoom, arg)))
return;
/* pReset = make_reset('H', 1, reset->arg1, 0, 0);*/
pReset = make_reset('H', 1, 0, 0, 0, -1, -1, -1, -1, 0, 0);
INSERT(pReset, reset, pArea->last_reset, prev, next);
send_to_char("Object hide reset created.\n\r", ch);
return;
}
if (ch->substate == SUB_REPEATCMD)
{
ch->substate = SUB_NONE;
interpret(ch, origarg);
ch->substate = SUB_REPEATCMD;
ch->last_cmd = (aRoom ? do_rreset : do_reset);
}
else
edit_reset(ch, "", pArea, aRoom);
return;
}
void do_reset(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea = NULL;
char arg[MIL];
char *parg;
parg = one_argument(argument, arg);
/* Mset/Oset/Redit On Mode check -- Stop most building crashes -- Xerves 8/7/99 */
if ((xIS_SET(ch->act, PLR_MSET)) || (xIS_SET(ch->act, PLR_OSET)) || (xIS_SET(ch->act, PLR_REDIT)))
{
send_to_char("You need to turn mset/oset/redit off\n\r", ch);
return;
}
if (ch->substate == SUB_REPEATCMD)
{
pArea = ch->dest_buf;
if (pArea && pArea != ch->pcdata->area && pArea != ch->in_room->area)
{
AREA_DATA *tmp;
for (tmp = first_build; tmp; tmp = tmp->next)
if (tmp == pArea)
break;
if (!tmp)
for (tmp = first_area; tmp; tmp = tmp->next)
if (tmp == pArea)
break;
if (!tmp)
{
send_to_char("Your area pointer got lost. Reset mode off.\n\r", ch);
bug("do_reset: %s's dest_buf points to invalid area", ch->name); /* why was this cast to an int? */
ch->substate = SUB_NONE;
ch->dest_buf = NULL;
return;
}
}
if (!*arg)
{
ch_printf(ch, "Editing resets for area: %s\n\r", pArea->name);
return;
}
if (!str_cmp(arg, "done") || !str_cmp(arg, "off"))
{
send_to_char("Reset mode off.\n\r", ch);
ch->substate = SUB_NONE;
ch->dest_buf = NULL;
return;
}
}
if (!pArea && get_trust(ch) >= LEVEL_STAFF) /* Tracker1 */
{
char fname[80];
sprintf(fname, "%s.are", capitalize(arg));
for (pArea = first_build; pArea; pArea = pArea->next)
if (!str_cmp(fname, pArea->filename))
{
argument = parg;
break;
}
if (!pArea)
pArea = ch->pcdata->area;
if (!pArea)
pArea = ch->in_room->area;
}
else
pArea = ch->pcdata->area;
if (!pArea)
{
send_to_char("You do not have an assigned area.\n\r", ch);
return;
}
edit_reset(ch, argument, pArea, NULL);
return;
}
void do_rreset(CHAR_DATA * ch, char *argument)
{
ROOM_INDEX_DATA *pRoom;
if (ch->substate == SUB_REPEATCMD)
{
pRoom = ch->dest_buf;
if (!pRoom)
{
send_to_char("Your room pointer got lost. Reset mode off.\n\r", ch);
bug("do_rreset: %s's dest_buf points to invalid room", (int) ch->name);
}
ch->substate = SUB_NONE;
ch->dest_buf = NULL;
return;
}
else
pRoom = ch->in_room;
if (!can_rmodify(ch, pRoom))
return;
edit_reset(ch, argument, pRoom->area, pRoom);
return;
}
void add_obj_reset(AREA_DATA * pArea, char cm, OBJ_DATA * obj, int v2, int v3)
{
OBJ_DATA *inobj;
RESET_DATA *pReset;
static int iNest;
int obj_loop, value_loop;
int reset_count = 0;
bool found;
int v4 = -1;
int v7 = -1;
if (obj->value[6] > 99 && (obj->item_type == ITEM_WEAPON || obj->item_type == ITEM_ARMOR) && xIS_SET(obj->extra_flags, ITEM_FORGEABLE))
{
if (cm == '0')
v7 = obj->value[6];
else if (cm == 'E' || cm == 'P')
v4 = obj->value[6];
else if (cm == 'G')
{
v3 = obj->value[6];
v4 = obj->value[11];
}
}
if ((cm == 'O' || cm == 'P') && obj->pIndexData->vnum == OBJ_VNUM_TRAP)
{
if (cm == 'O')
add_reset(pArea, 'T', obj->value[3], obj->value[1], obj->value[0], v3, v4, -1, -1, v7, 0, 0);
return;
}
if (cm == 'O' && IS_OBJ_STAT(obj, ITEM_ONMAP))
{
add_reset(pArea, cm, 1, obj->pIndexData->vnum, v2, v3, obj->coord->x, obj->coord->y, obj->map, v7, 0, 0);
}
else
{
add_reset(pArea, cm, (cm == 'P' ? iNest : 1), obj->pIndexData->vnum, v2, v3, v4, -1, -1, v7, 0, 0);
}
/* Only add hide for in-room objects that are hidden and cant be moved, as
hide is an update reset, not a load-only reset. */
if (cm == 'O' && IS_OBJ_STAT(obj, ITEM_HIDDEN) && !IS_SET(obj->wear_flags, ITEM_TAKE))
add_reset(pArea, 'H', 1, 0, 0, 0, -1, -1, -1, -1, 0, 0);
if (obj->trap)
{
pReset = make_reset('A', 1, obj->trap->uid, 0, 0, -1, -1, -1, -1, 0, 0);
LINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
}
for (inobj = obj->first_content; inobj; inobj = inobj->next_content)
if (inobj->pIndexData->vnum == OBJ_VNUM_TRAP)
add_obj_reset(pArea, 'O', inobj, 0, 0);
if (cm == 'P')
iNest++;
if (put_index == 0)
for (obj_loop = 0; obj_loop < MAX_OBJ; obj_loop++)
for (value_loop = 0; value_loop < 3; value_loop++)
put_array[obj_loop][value_loop] = 0;
for (inobj = obj->first_content; inobj; inobj = inobj->next_content)
{
if (IS_OBJ_TYPE(inobj))
{
found = FALSE;
for (obj_loop = 0; obj_loop <= obj_index; obj_loop++)
{
if ((put_array[obj_loop][0] == inobj->pIndexData->vnum) && (put_array[obj_loop][2] == iNest))
{
reset_count = inobj->count + put_array[obj_loop][1];
put_array[obj_loop][1] = reset_count;
found = TRUE;
}
}
if (!found)
{
reset_count = inobj->count;
put_array[put_index][0] = inobj->pIndexData->vnum;
put_array[put_index][1] = inobj->count;
put_array[put_index][2] = iNest;
put_index++;
}
}
else
reset_count = count_obj_list(get_obj_index(inobj->pIndexData->vnum), obj->first_content);
add_obj_reset(pArea, 'P', inobj, reset_count, 0);
if (inobj->trap)
{
pReset = make_reset('A', 1, obj->trap->uid, 0, 0, -1, -1, -1, -1, 0, 0);
LINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
}
}
if (cm == 'P')
iNest--;
return;
}
int get_reset_equiped(OBJ_DATA *obj, OBJ_DATA *fobj)
{
int count = 0;
for (; fobj; fobj = fobj->next_content)
if (fobj->pIndexData->vnum == obj->pIndexData->vnum && fobj->wear_loc != WEAR_NONE && obj->wear_loc != WEAR_NONE)
{
count++;
if (fobj->wear_loc == obj->wear_loc)
return count;
}
return 1;
}
int count_obj_list_inv(OBJ_INDEX_DATA * pObjIndex, OBJ_DATA * list)
{
OBJ_DATA *obj;
int nMatch = 0;
for (obj = list; obj; obj = obj->next_content)
{
if (obj->pIndexData == pObjIndex && obj->wear_loc == WEAR_NONE)
{
if (obj->count > 1)
nMatch += obj->count;
else
nMatch++;
}
}
return nMatch;
}
void instaroom(CHAR_DATA * ch, AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, bool dodoors, bool allmap)
{
CHAR_DATA *rch;
OBJ_DATA *obj;
RESET_DATA *reset;
int obj_loop, value_loop, reset_count;
int count;
int x;
bool found;
for (rch = pRoom->first_person; rch; rch = rch->next_in_room)
{
if (!IS_NPC(rch))
continue;
if (pRoom->vnum == OVERLAND_SOLAN)
if (allmap == FALSE)
if ((rch->coord->x != ch->coord->x) || (rch->coord->y != ch->coord->y) || (rch->map != ch->map))
continue;
/* Updates the Mob count according to the current mob list, will Make sure mobs go up in
ascending order..1, 2, 3, 4, 5, etc -- Xerves */
reset_count = fmob_count(pArea, rch->pIndexData->vnum);
reset = add_reset(pArea, 'M', 1, rch->pIndexData->vnum, 1, pRoom->vnum, rch->coord->x, rch->coord->y, rch->map, -1, 0, 0);
reset->serial = rch->serial;
serial_list[reset->serial] = TRUE;
obj_index = 0;
reset_count = 0;
for (obj_loop = 0; obj_loop < MAX_OBJ; obj_loop++)
for (value_loop = 0; value_loop < 2; value_loop++)
obj_array[obj_loop][value_loop] = 0;
for (obj = rch->first_carrying; obj; obj = obj->next_content)
{
if (obj->wear_loc == WEAR_NONE)
{
if (IS_OBJ_TYPE(obj))
{
found = FALSE;
for (obj_loop = 0; obj_loop <= obj_index; obj_loop++)
{
if (obj_array[obj_loop][0] == obj->pIndexData->vnum)
{
reset_count = obj->count + obj_array[obj_loop][1];
obj_array[obj_loop][1] = reset_count;
found = TRUE;
}
}
if (!found)
{
reset_count = obj->count;
obj_array[obj_index][0] = obj->pIndexData->vnum;
obj_array[obj_index][1] = obj->count;
obj_index++;
}
}
else
reset_count = count_obj_list_inv(get_obj_index(obj->pIndexData->vnum), rch->first_carrying);
put_index = 0;
count = obj->count;
for (x = 1; x <= count; x++)
add_obj_reset(pArea, 'G', obj, reset_count, 0);
}
else
{
reset_count = get_reset_equiped(obj, rch->first_carrying);
add_obj_reset(pArea, 'E', obj, reset_count, obj->wear_loc);
}
}
}
obj_index = 0;
reset_count = 0;
for (obj_loop = 0; obj_loop < MAX_OBJ; obj_loop++)
for (value_loop = 0; value_loop < 2; value_loop++)
obj_array[obj_loop][value_loop] = 0;
for (obj = pRoom->first_content; obj; obj = obj->next_content)
{
if (IS_OBJ_TYPE(obj))
{
found = FALSE;
for (obj_loop = 0; obj_loop <= obj_index; obj_loop++)
{
if (obj_array[obj_loop][0] == obj->pIndexData->vnum)
{
reset_count = obj->count + obj_array[obj_loop][1];
obj_array[obj_loop][1] = reset_count;
found = TRUE;
}
}
if (!found)
{
reset_count = obj->count;
obj_array[obj_index][0] = obj->pIndexData->vnum;
obj_array[obj_index][1] = obj->count;
obj_index++;
}
}
else
reset_count = count_obj_list(get_obj_index(obj->pIndexData->vnum), pRoom->first_content);
if (pRoom->vnum == OVERLAND_SOLAN)
if (allmap == FALSE)
if ((obj->coord->x != ch->coord->x) || (obj->coord->y != ch->coord->y) || (obj->map != ch->map))
continue;
put_index = 0;
add_obj_reset(pArea, 'O', obj, reset_count, pRoom->vnum);
}
if (dodoors)
{
EXIT_DATA *pexit;
for (pexit = pRoom->first_exit; pexit; pexit = pexit->next)
{
int state = 0;
if (!IS_SET(pexit->exit_info, EX_ISDOOR))
continue;
if (IS_SET(pexit->exit_info, EX_CLOSED))
{
if (IS_SET(pexit->exit_info, EX_LOCKED))
state = 2;
else
state = 1;
}
add_reset(pArea, 'D', 0, pRoom->vnum, pexit->vdir, state, -1, -1, -1, -1, 0, 0);
}
}
return;
}
void wipe_resets(AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom)
{
RESET_DATA *pReset;
for (pReset = pArea->first_reset; pReset;)
{
if (pReset->command != 'R' && is_room_reset(pReset, pRoom, pArea))
{
/* Resets always go forward, so we can safely use the previous reset,
providing it exists, or first_reset if it doesnt. -- Altrag */
RESET_DATA *prev = pReset->prev;
delete_reset(pArea, pReset);
pReset = (prev ? prev->next : pArea->first_reset);
}
else
pReset = pReset->next;
}
return;
}
void wipe_map_resets(CHAR_DATA * ch, AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, int x, int y, int map)
{
RESET_DATA *pReset;
RESET_DATA *prev;
for (pReset = pArea->first_reset; pReset;)
{
if (pReset->command == 'M' || pReset->command == 'O')
{
if ((pReset->arg4 == ch->coord->x) && (pReset->arg5 == ch->coord->y) && (pReset->arg6 == ch->map))
{
prev = pReset->prev;
delete_reset(pArea, pReset);
pReset = (prev ? prev->next : pArea->first_reset);
}
else
{
pReset = pReset->next;
}
}
else
{
pReset = pReset->next;
}
}
return;
}
void do_instaroom(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea;
ROOM_INDEX_DATA *pRoom;
bool dodoors;
bool allmap = FALSE;
char arg[MIL];
int x, y, map;
if (IS_NPC(ch) || get_trust(ch) < LEVEL_IMM || !ch->pcdata || /* Tracker1 */
!ch->pcdata->area)
{
send_to_char("You don't have an assigned area to create resets for.\n\r", ch);
return;
}
argument = one_argument(argument, arg);
if (!str_cmp(argument, "nodoors"))
dodoors = FALSE;
else
dodoors = TRUE;
if (!str_cmp(argument, "allmap"))
allmap = TRUE;
pArea = ch->pcdata->area;
if (!(pRoom = find_room(ch, arg, NULL)))
{
send_to_char("Room doesn't exist.\n\r", ch);
return;
}
if (!can_mapmodify(ch, pRoom))
return;
if (pRoom->area != pArea && get_trust(ch) < LEVEL_STAFF) /* Tracker1 */
{
send_to_char("You cannot reset that room.\n\r", ch);
return;
}
/* Defaults only to change the coords, will not add an actual reset */
if (pRoom->vnum == OVERLAND_SOLAN)
{
if (allmap == FALSE)
{
x = ch->coord->x;
y = ch->coord->y;
map = ch->map;
wipe_map_resets(ch, pArea, pRoom, x, y, map);
instaroom(ch, pArea, pRoom, FALSE, allmap);
send_to_char("Mob coords changed (instaroom allmap to add resets to Wilderness).\n\r", ch);
return;
}
}
if (pArea->first_reset)
wipe_resets(pArea, pRoom);
instaroom(ch, pArea, pRoom, dodoors, allmap);
send_to_char("Room resets installed.\n\r", ch);
}
void do_instazone(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea;
int vnum;
ROOM_INDEX_DATA *pRoom;
bool dodoors;
if (IS_NPC(ch) || get_trust(ch) < LEVEL_IMM || !ch->pcdata || /* Tracker1 */
!ch->pcdata->area)
{
send_to_char("You don't have an assigned area to create resets for.\n\r", ch);
return;
}
if (!str_cmp(argument, "nodoors"))
dodoors = FALSE;
else
dodoors = TRUE;
pArea = ch->pcdata->area;
if (pArea->first_reset)
wipe_resets(pArea, NULL);
for (vnum = pArea->low_r_vnum; vnum <= pArea->hi_r_vnum; vnum++)
{
if (!(pRoom = get_room_index(vnum)) || pRoom->area != pArea)
continue;
instaroom(ch, pArea, pRoom, dodoors, 1);
}
send_to_char("Area resets installed.\n\r", ch);
return;
}
int generate_itemlevel(AREA_DATA * pArea, OBJ_INDEX_DATA * pObjIndex)
{
return 1;
}
int mob_in_area_count(int mvnum, int count, int vnum)
{
CHAR_DATA *victim;
AREA_DATA *tarea;
int cnt = 0;
for (tarea = first_area; tarea; tarea = tarea->next)
{
if (vnum >= tarea->low_r_vnum && vnum <= tarea->hi_r_vnum)
break;
}
if (!tarea)
{
for (tarea = first_build; tarea; tarea = tarea->next)
{
if (vnum >= tarea->low_r_vnum && vnum <= tarea->hi_r_vnum)
break;
}
}
if (!tarea)
{
bug("mob_in_area_count: Could not find the area for some reason, vnum %d", vnum);
return FALSE;
}
for (victim = first_char; victim; victim = victim->next)
{
if (IS_NPC(victim) && victim->pIndexData->vnum == mvnum)
if (victim->in_room->area == tarea)
{
cnt++;
if (count <= cnt)
break;
}
}
if (count <= cnt)
return FALSE;
else
return TRUE;
}
int count_obj_list_eq(OBJ_INDEX_DATA * pObjIndex, OBJ_DATA * list)
{
OBJ_DATA *obj;
int nMatch = 0;
for (obj = list; obj; obj = obj->next_content)
{
if (obj->pIndexData == pObjIndex && obj->wear_loc != WEAR_NONE)
{
if (obj->count > 1)
nMatch += obj->count;
else
nMatch++;
}
}
return nMatch;
}
/*
* Reset one area.
*/
//ttype 0 - Regular area reset 1 - Time check reset
void reset_area(AREA_DATA * pArea, int ttype)
{
RESET_DATA *pReset;
CHAR_DATA *mob;
OBJ_DATA *obj;
OBJ_DATA *lastobj;
ROOM_INDEX_DATA *pRoomIndex;
MOB_INDEX_DATA *pMobIndex;
OBJ_INDEX_DATA *pObjIndex;
OBJ_INDEX_DATA *pObjToIndex;
SLAB_DATA *slab;
EXIT_DATA *pexit;
OBJ_DATA *to_obj;
int fvnum;
int crace = 0;
char buf[MSL];
int level = 0;
int race;
int currentserial;
int change = 0;
void *plc = NULL;
int timemob = 0;
bool ext_bv = FALSE;
TRAP_DATA *trap;
if (!pArea)
{
bug("reset_area: NULL pArea", 0);
return;
}
mob = NULL;
obj = NULL;
lastobj = NULL;
if (!pArea->first_reset)
{
//bug("%s: reset_area: no resets", pArea->filename);
return;
}
level = 0;
for (pReset = pArea->first_reset; pReset; pReset = pReset->next)
{
if (ttype == 1)
{
if (timemob && pReset->command != 'G' && pReset->command != 'E')
timemob = 0;
if (!timemob && pReset->resettime <= 0 && pReset->resetlast <= 0)
continue;
if (!timemob && pReset->resetlast + pReset->resettime > time(0))
continue;
}
switch (pReset->command)
{
default:
sprintf(buf, "%s Reset_area: bad command %c.", pArea->filename, pReset->command);
bug(buf, 0);
break;
case 'M':
if (!(pMobIndex = get_mob_index(pReset->arg1)))
{
sprintf(buf, "%s Reset_area: 'M': bad mob vnum %d.", pArea->filename, pReset->arg1);
bug(buf, 0);
continue;
}
if (!(pRoomIndex = get_room_index(pReset->arg3)))
{
sprintf(buf, "%s Reset_area: 'M': bad room vnum %d.", pArea->filename, pReset->arg3);
bug(buf, 0);
continue;
}
if (pReset->resettime > 0 && pReset->resetlast > 0)
{
if (pReset->resetlast + pReset->resettime > time(0))
{
mob = NULL;
break;
}
}
if (pReset->serial == 0)
{
mob = create_mobile(pMobIndex);
pReset->serial = serialmobsloaded;
serial_list[pReset->serial] = TRUE;
}
else
{
if (serial_list[pReset->serial] == FALSE)
{
currentserial = serialmobsloaded;
serialmobsloaded = pReset->serial-1;
mob = create_mobile(pMobIndex);
serialmobsloaded = currentserial;
serial_list[pReset->serial] = TRUE;
}
else
{
mob = NULL;
break;
}
}
if (pReset->resettime == -1)
xSET_BIT(mob->act, ACT_NORESET);
if (pReset->resettime > 0)
xSET_BIT(mob->act, ACT_TIMERESET);
/* if (!mob_in_area_count(pMobIndex->vnum, pReset->arg2, pReset->arg3))
{
mob = NULL;
break;
}*/
{
ROOM_INDEX_DATA *pRoomPrev = get_room_index(pReset->arg3 - 1);
if (pRoomPrev && xIS_SET(pRoomPrev->room_flags, ROOM_PET_SHOP))
xSET_BIT(mob->act, ACT_PET);
if (pRoomPrev && xIS_SET(pRoomPrev->room_flags, ROOM_MOUNT_SHOP))
xSET_BIT(mob->act, ACT_MOUNTSAVE);
}
if (room_is_dark(pRoomIndex))
xSET_BIT(mob->affected_by, AFF_INFRARED);
char_to_room(mob, pRoomIndex);
economize_mobgold(mob);
level = 0;
if (pRoomIndex->vnum == OVERLAND_SOLAN)
{
mob->coord->x = pReset->arg4;
mob->coord->y = pReset->arg5;
mob->map = pReset->arg6;
SET_ONMAP_FLAG(mob);
}
if (ttype == 1)
timemob = 1;
break;
case 'G':
case 'E':
if (!(pObjIndex = get_obj_index(pReset->arg1)))
{
sprintf(buf, "%s Reset_area: 'E' or 'G': bad obj vnum %d.", pArea->filename, pReset->arg1);
bug(buf, 0);
continue;
}
if (!mob)
{
lastobj = NULL;
break;
}
if (pReset->resettime > 0 && pReset->resetlast > 0)
{
if (pReset->resetlast + pReset->resettime > time(0))
{
obj = NULL;
lastobj = NULL;
break;
}
}
if ((pReset->command == 'G' && count_obj_list_inv(pObjIndex, mob->first_carrying) >= pReset->arg2)
|| (pReset->command == 'E' && count_obj_list_eq(pObjIndex, mob->first_carrying) >= pReset->arg2))
{
obj = NULL;
lastobj = NULL;
break;
}
if (mob->pIndexData->pShop)
{
int olevel = generate_itemlevel(pArea, pObjIndex);
obj = create_object(pObjIndex, olevel);
if (!xIS_SET(mob->act, ACT_CASTEMOB))
xSET_BIT(obj->extra_flags, ITEM_INVENTORY);
}
else
{
obj = create_object(pObjIndex, 1);
}
if (pReset->resettime == -1)
xSET_BIT(obj->extra_flags, ITEM_NORESET);
if (pReset->resettime > 0)
xSET_BIT(obj->extra_flags, ITEM_TIMERESET);
obj->level = 0;
/* obj->count = (pReset->arg2 - count_obj_list(pObjIndex, mob->first_carrying)); */
obj = obj_to_char(obj, mob);
if (pReset->command == 'E')
fvnum = pReset->arg4;
else
fvnum = pReset->arg3;
if (fvnum > 100)
{
OBJ_DATA *oslab;
for (slab = first_slab; slab; slab = slab->next)
{
if (slab->vnum == fvnum)
break;
}
if (!slab)
{
bug("%s Reset_area: 'G' or 'E': bad slab vnum %d.", pArea->filename, fvnum);
}
else
{
race = mob->race;
if (mob->race < 0 || mob->race >= MAX_RACE)
mob->race = 0; //Needs a valid race
if (pReset->command == 'G' && pReset->arg4 > 0)
{
mob->race = pReset->arg4-1;
crace = pReset->arg4;
}
oslab = create_object(get_obj_index(slab->vnum), 1);
alter_forge_obj(mob, obj, oslab, slab);
extract_obj(oslab);
obj->value[6] = fvnum;
obj->value[11] = crace;
mob->race = race;
}
}
if (pReset->command == 'E')
equip_char(mob, obj, pReset->arg3);
lastobj = obj;
break;
case 'O':
if (!(pObjIndex = get_obj_index(pReset->arg1)))
{
/*
sprintf (buf, "%s Reset_area: 'O': bad obj vnum %d.",
pArea->filename, pReset->arg1 );
bug ( buf, 0 );
*/
continue;
}
if (!(pRoomIndex = get_room_index(pReset->arg3)))
{
/*
sprintf ( buf, "%s Reset_area: 'O': bad room vnum %d.", pArea->filename,
pReset->arg3 );
bug ( buf, 0 );
*/
continue;
}
if (pReset->resettime > 0 && pReset->resetlast > 0)
{
if (pReset->resetlast + pReset->resettime > time(0))
{
obj = NULL;
lastobj = NULL;
break;
}
}
/* With objects it is important to load only the amount alouted the that obj */
if ((count_obj_list(pObjIndex, pRoomIndex->first_content) >= pReset->arg2))
{
obj = NULL;
lastobj = NULL;
break;
}
obj = create_object(pObjIndex, 1);
if (pReset->resettime == -1)
xSET_BIT(obj->extra_flags, ITEM_NORESET);
if (pReset->resettime > 0)
xSET_BIT(obj->extra_flags, ITEM_TIMERESET);
obj->level = 0;
/* obj->count = ( pReset->arg2 - count_obj_list(pObjIndex, pRoomIndex->first_content)); */
if (pRoomIndex->vnum == OVERLAND_SOLAN) // Make sure it doesn't group -- Xerves
{
obj->coord->x = pReset->arg4;
obj->coord->y = pReset->arg5;
obj->map = pReset->arg6;
SET_OBJ_STAT(obj, ITEM_ONMAP);
}
obj_to_room(obj, pRoomIndex, NULL);
if (pRoomIndex->vnum == OVERLAND_SOLAN) // Put the values back in after obj_to_room -- Xerves
{
obj->coord->x = pReset->arg4;
obj->coord->y = pReset->arg5;
obj->map = pReset->arg6;
SET_OBJ_STAT(obj, ITEM_ONMAP);
}
if (pReset->arg7 > 100)
{
for (slab = first_slab; slab; slab = slab->next)
{
if (slab->vnum == pReset->arg7)
break;
}
if (!slab)
{
bug("%s Reset_area: 'G' or 'E': bad slab vnum %d.", pArea->filename, pReset->arg7);
}
else
{
race = mob->race;
if (mob->race < 0 || mob->race >= MAX_RACE)
mob->race = 0; //Needs a valid race
alter_forge_obj(mob, obj, create_object(get_obj_index(slab->vnum), 1), slab);
obj->value[6] = pReset->arg7;
mob->race = race;
}
}
lastobj = obj;
break;
//New Trap format, store only the uid here.
case 'A':
for (trap = first_trap; trap; trap = trap->next)
{
if (trap->uid == pReset->arg1)
break;
}
if (!trap)
{
bug("%s Reset_area: 'A': bad trap uid of %d", pArea->filename, pReset->arg1);
continue;
}
if (trap->resetvalue > 0)
{
trap->charges = trap->maxcharges;
}
if (!lastobj)
continue;
if (lastobj->trap)
continue;
if (trap->obj)
continue;
lastobj->trap = trap;
trap->obj = lastobj;
trap->area = pArea;
trap->charges = trap->maxcharges;
break;
case 'P':
if (!(pObjIndex = get_obj_index(pReset->arg1)))
{
/*
sprintf ( buf, "%s Reset_area: 'P': bad obj vnum %d.", pArea->filename,
pReset->arg1 );
bug ( buf, 0 );
*/
continue;
}
if (pReset->arg3 > 0)
{
if (!(pObjToIndex = get_obj_index(pReset->arg3)))
{
/*
sprintf(buf,"%s Reset_area: 'P': bad objto vnum %d.",pArea->filename,
pReset->arg3 );
bug( buf, 0 );
*/
continue;
}
if (pReset->resettime > 0 && pReset->resetlast > 0)
{
if (pReset->resetlast + pReset->resettime > time(0))
{
obj = NULL;
break;
}
}
if (pArea->nplayer > 0
|| !(to_obj = get_obj_type(pObjToIndex)) || !to_obj->in_room || (count_obj_list(pObjIndex, to_obj->first_content) >= pReset->arg2))
{
obj = NULL;
break;
}
lastobj = to_obj;
}
else
{
int iNest;
if (!lastobj)
break;
to_obj = lastobj;
for (iNest = 0; iNest < pReset->extra; iNest++)
if (!(to_obj = to_obj->last_content))
{
/*
sprintf(buf,"%s Reset_area: 'P': Invalid nesting obj %d."
,pArea->filename, pReset->arg1 );
bug( buf, 0 );
*/
iNest = -1;
break;
}
if (iNest < 0)
continue;
}
obj = create_object(pObjIndex, 1);
if (pReset->resettime == -1)
xSET_BIT(obj->extra_flags, ITEM_NORESET);
if (pReset->resettime > 0)
xSET_BIT(obj->extra_flags, ITEM_TIMERESET);
obj->level = 0;
/* obj->count = ( pReset->arg2 - count_obj_list(pObjIndex, to_obj->first_content)); */
obj_to_obj(obj, to_obj);
if (pReset->arg4 > 100)
{
for (slab = first_slab; slab; slab = slab->next)
{
if (slab->vnum == pReset->arg4)
break;
}
if (!slab)
{
bug("%s Reset_area: 'P': bad slab vnum %d.", pArea->filename, pReset->arg4);
}
else
{
race = mob->race;
if (mob->race < 0 || mob->race >= MAX_RACE)
mob->race = 0; //Needs a valid race
alter_forge_obj(mob, obj, create_object(get_obj_index(slab->vnum), 1), slab);
obj->value[6] = pReset->arg4;
mob->race = race;
}
}
break;
case 'T':
if (IS_SET(pReset->extra, TRAP_OBJ))
{
/* We need to preserve obj for future 'T' and 'H' checks */
OBJ_DATA *pobj;
if (pReset->arg3 > 0)
{
if (!(pObjToIndex = get_obj_index(pReset->arg3)))
{
/*
sprintf (buf,"%s Reset_area: 'T': bad objto vnum %d."
,pArea->filename, pReset->arg3 );
bug ( buf, 0 );
*/
continue;
}
if (pArea->nplayer > 0 ||
!(to_obj = get_obj_type(pObjToIndex)) || (to_obj->carried_by && !IS_NPC(to_obj->carried_by)) || is_trapped(to_obj))
break;
}
else
{
if (!lastobj || !obj)
break;
to_obj = obj;
}
pobj = make_trap(pReset->arg2, pReset->arg1, 1, pReset->extra);
obj_to_obj(pobj, to_obj);
}
else
{
if (!(pRoomIndex = get_room_index(pReset->arg3)))
{
/*
sprintf(buf,"%s Reset_area: 'T': bad room %d.", pArea->filename,
pReset->arg3 );
bug( buf, 0 );
*/
continue;
}
if (pArea->nplayer > 0 || count_obj_list(get_obj_index(OBJ_VNUM_TRAP), pRoomIndex->first_content) > 0)
break;
to_obj = make_trap(pReset->arg1, pReset->arg1, 10, pReset->extra);
obj_to_room(to_obj, pRoomIndex, NULL);
}
break;
case 'H':
if (pReset->arg1 > 0)
{
if (!(pObjToIndex = get_obj_index(pReset->arg1)))
{
/*
sprintf(buf,"%s Reset_area: 'H': bad objto vnum %d.",pArea->filename,
pReset->arg1 );
bug( buf, 0 );
*/
continue;
}
if (pArea->nplayer > 0 ||
!(to_obj = get_obj_type(pObjToIndex)) || !to_obj->in_room || to_obj->in_room->area != pArea || IS_OBJ_STAT(to_obj, ITEM_HIDDEN))
break;
}
else
{
if (!lastobj || !obj)
break;
to_obj = obj;
}
xSET_BIT(to_obj->extra_flags, ITEM_HIDDEN);
break;
case 'B':
switch (pReset->arg2 & BIT_RESET_TYPE_MASK)
{
case BIT_RESET_DOOR:
{
int doornum;
if (!(pRoomIndex = get_room_index(pReset->arg1)))
{
/*
sprintf(buf,"%s Reset_area: 'B': door: bad room vnum %d.",
pArea->filename, pReset->arg1 );
bug( buf, 0 );
*/
continue;
}
doornum = (pReset->arg2 & BIT_RESET_DOOR_MASK) >> BIT_RESET_DOOR_THRESHOLD;
if (!(pexit = get_exit(pRoomIndex, doornum)))
break;
plc = &pexit->exit_info;
}
break;
case BIT_RESET_ROOM:
if (!(pRoomIndex = get_room_index(pReset->arg1)))
{
/*
sprintf(buf,"%s Reset_area: 'B': room: bad room vnum %d.",
pArea->filename, pReset->arg1 );
bug(buf, 0);
*/
continue;
}
plc = &pRoomIndex->room_flags;
break;
case BIT_RESET_OBJECT:
if (pReset->arg1 > 0)
{
if (!(pObjToIndex = get_obj_index(pReset->arg1)))
{
/*
sprintf(buf,"%s Reset_area: 'B': object: bad objto vnum %d.",
pArea->filename, pReset->arg1 );
bug( buf, 0 );
*/
continue;
}
if (!(to_obj = get_obj_type(pObjToIndex)) || !to_obj->in_room || to_obj->in_room->area != pArea)
continue;
}
else
{
if (!lastobj || !obj)
continue;
to_obj = obj;
}
plc = &to_obj->extra_flags;
ext_bv = TRUE;
break;
case BIT_RESET_MOBILE:
if (!mob)
continue;
plc = &mob->affected_by;
ext_bv = TRUE;
break;
default:
/*
sprintf(buf, "%s Reset_area: 'B': bad options %d.",
pArea->filename, pReset->arg2 );
bug( buf, 0 );
*/
continue;
}
if (IS_SET(pReset->arg2, BIT_RESET_SET))
{
if (ext_bv)
xSET_BIT(*(EXT_BV *) plc, pReset->arg3);
else
SET_BIT(*(int *) plc, pReset->arg3);
}
else if (IS_SET(pReset->arg2, BIT_RESET_TOGGLE))
{
if (ext_bv)
xTOGGLE_BIT(*(EXT_BV *) plc, pReset->arg3);
else
TOGGLE_BIT(*(int *) plc, pReset->arg3);
}
else
{
if (ext_bv)
xREMOVE_BIT(*(EXT_BV *) plc, pReset->arg3);
else
REMOVE_BIT(*(int *) plc, pReset->arg3);
}
break;
case 'D':
if (!(pRoomIndex = get_room_index(pReset->arg1)))
{
/*
sprintf(buf, "%s Reset_area: 'D': bad room vnum %d.",
pArea->filename, pReset->arg1 );
bug(buf, 0);
*/
continue;
}
if (!(pexit = get_exit(pRoomIndex, pReset->arg2)))
break;
switch (pReset->arg3)
{
case 0:
REMOVE_BIT(pexit->exit_info, EX_CLOSED);
REMOVE_BIT(pexit->exit_info, EX_LOCKED);
break;
case 1:
SET_BIT(pexit->exit_info, EX_CLOSED);
REMOVE_BIT(pexit->exit_info, EX_LOCKED);
if (IS_SET(pexit->exit_info, EX_xSEARCHABLE))
SET_BIT(pexit->exit_info, EX_SECRET);
break;
case 2:
SET_BIT(pexit->exit_info, EX_CLOSED);
SET_BIT(pexit->exit_info, EX_LOCKED);
if (IS_SET(pexit->exit_info, EX_xSEARCHABLE))
SET_BIT(pexit->exit_info, EX_SECRET);
break;
}
break;
case 'R':
if (!(pRoomIndex = get_room_index(pReset->arg1)))
{
/*
sprintf(buf,"%s Reset_area: 'R': bad room vnum %d.",
pArea->filename, pReset->arg1 );
bug(buf, 0);
*/
continue;
}
randomize_exits(pRoomIndex, pReset->arg2 - 1);
break;
}
}
if (change == 1)
fold_area(pArea, pArea->filename, FALSE, 1);
return;
}
void list_resets(CHAR_DATA * ch, AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, int start, int end)
{
RESET_DATA *pReset;
ROOM_INDEX_DATA *room;
MOB_INDEX_DATA *mob;
OBJ_INDEX_DATA *obj, *obj2;
OBJ_INDEX_DATA *lastobj;
RESET_DATA *lo_reset;
bool found;
int num = 0;
const char *rname = "???", *mname = "???", *oname = "???";
char buf[256];
char time[256];
char *pbuf;
int sec, hour, min, days, rtime;
TRAP_DATA *trap;
if (!ch || !pArea)
return;
room = NULL;
mob = NULL;
obj = NULL;
lastobj = NULL;
lo_reset = NULL;
found = FALSE;
for (pReset = pArea->first_reset; pReset; pReset = pReset->next)
{
if (!is_room_reset(pReset, pRoom, pArea))
continue;
++num;
sprintf(buf, "%s%3d) ", char_color_str(AT_PURPLE, ch), num);
pbuf = buf + strlen(buf);
if (pReset->resettime > 0)
{
if (pReset->resettime > 86400)
{
days = pReset->resettime / 86400;
rtime = pReset->resettime % 86400;
}
else
{
days = 0;
rtime = pReset->resettime;
}
sec = rtime % 60;
hour = rtime / 3600;
if (rtime > 60)
{
min = rtime / 60;
min = min % 60;
}
else
{
min = 0;
}
sprintf(time, "D:%d H:%d M:%d S:%d", days, hour, min, sec);
}
if (pReset->resettime == -1)
sprintf(time, "*****ONE RESET*****");
switch (pReset->command)
{
default:
sprintf(pbuf, "*** BAD RESET: %c %d %d %d %d ***\n\r", pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3);
break;
case 'M':
if (!(mob = get_mob_index(pReset->arg1)))
mname = "Mobile: *BAD VNUM*";
else
mname = mob->player_name;
if (!(room = get_room_index(pReset->arg3)))
rname = "Room: *BAD VNUM*";
else
rname = room->name;
if (pReset->resettime > 0 || pReset->resettime == -1)
sprintf(pbuf, "%s%s (%d) -> %s (%d) (%d %d %d) [%d] &w&W<%s>", char_color_str(AT_GREEN, ch), mname, pReset->arg1, rname,
pReset->arg3, pReset->arg4, pReset->arg5, pReset->arg6, pReset->serial, time);
else
sprintf(pbuf, "%s%s (%d) -> %s (%d) (%d %d %d) [%d]", char_color_str(AT_GREEN, ch), mname, pReset->arg1, rname,
pReset->arg3, pReset->arg4, pReset->arg5, pReset->arg6, pReset->serial);
if (!room)
mob = NULL;
if ((room = get_room_index(pReset->arg3 - 1)) && xIS_SET(room->room_flags, ROOM_PET_SHOP))
strcat(buf, "&w&c (pet)\n\r");
else if ((room = get_room_index(pReset->arg3 - 1)) && xIS_SET(room->room_flags, ROOM_MOUNT_SHOP))
strcat(buf, "&w&C (mount)\n\r");
else
strcat(buf, "\n\r");
break;
case 'G':
case 'E':
if (!mob)
mname = "* ERROR: NO MOBILE! *";
if (!(obj = get_obj_index(pReset->arg1)))
oname = "Object: *BAD VNUM*";
else
oname = obj->name;
if (pReset->resettime > 0 || pReset->resettime == -1)
sprintf(pbuf, "%s%s (%d) -> %s (%s) [%d] &w&W<%s>", pReset->command == 'G' ? char_color_str(AT_ORANGE, ch) : char_color_str(AT_YELLOW, ch),
oname, pReset->arg1, mname, (pReset->command == 'G' ? "carry" : wear_locs[pReset->arg3]), pReset->arg2, time);
else
sprintf(pbuf, "%s%s (%d) -> %s (%s) [%d]", pReset->command == 'G' ? char_color_str(AT_ORANGE, ch) : char_color_str(AT_YELLOW, ch),
oname, pReset->arg1, mname, (pReset->command == 'G' ? "carry" : wear_locs[pReset->arg3]), pReset->arg2);
if (mob && mob->pShop)
strcat(buf, "&w&R (shop)\n\r");
else
strcat(buf, "\n\r");
lastobj = obj;
lo_reset = pReset;
break;
case 'A':
for (trap = first_trap; trap; trap = trap->next)
{
if (trap->uid == pReset->arg1)
break;
}
if (!trap)
sprintf(pbuf, "*INVALID TRAP UID*\n\r");
else
sprintf(pbuf, "%s(TRAP) %d uid %d lowdam %d hidam\n\r", char_color_str(AT_RED, ch), trap->uid, trap->damlow, trap->damhigh);
break;
case 'O':
if (!(obj = get_obj_index(pReset->arg1)))
oname = "Object: *BAD VNUM*";
else
oname = obj->name;
if (!(room = get_room_index(pReset->arg3)))
rname = "Room: *BAD VNUM*";
else
rname = room->name;
if (pReset->resettime > 0 || pReset->resettime == -1)
sprintf(pbuf, "%s(object) %s (%d) -> %s (%d) (%d %d %d) [%d] &w&W<%s>\n\r", char_color_str(AT_PINK, ch), oname,
pReset->arg1, rname, pReset->arg3, pReset->arg4, pReset->arg5, pReset->arg6, pReset->arg2, time);
else
sprintf(pbuf, "%s(object) %s (%d) -> %s (%d) (%d %d %d) [%d]\n\r", char_color_str(AT_PINK, ch), oname,
pReset->arg1, rname, pReset->arg3, pReset->arg4, pReset->arg5, pReset->arg6, pReset->arg2);
if (!room)
obj = NULL;
lastobj = obj;
lo_reset = pReset;
break;
case 'P':
if (!(obj = get_obj_index(pReset->arg1)))
oname = "Object1: *BAD VNUM*";
else
oname = obj->name;
obj2 = NULL;
if (pReset->arg3 > 0)
{
obj2 = get_obj_index(pReset->arg3);
rname = (obj2 ? obj2->name : "Object2: *BAD VNUM*");
lastobj = obj2;
}
else if (!lastobj)
rname = "Object2: *NULL obj*";
else if (pReset->extra == 0)
{
rname = lastobj->name;
obj2 = lastobj;
}
else
{
int iNest;
RESET_DATA *reset;
reset = lo_reset->next;
for (iNest = 0; iNest < pReset->extra; iNest++)
{
for (; reset; reset = reset->next)
if (reset->command == 'O' || reset->command == 'G' ||
reset->command == 'E' || (reset->command == 'P' &&
!reset->arg3 && reset->extra == iNest && (get_obj_index(reset->arg1)->item_type == ITEM_CONTAINER)))
break;
if (!reset || reset->command != 'P')
break;
}
if (!reset)
rname = "Object2: *BAD NESTING*";
else if (!(obj2 = get_obj_index(reset->arg1)))
rname = "Object2: *NESTED BAD VNUM*";
else
rname = obj2->name;
}
if (pReset->resettime > 0 || pReset->resettime == -1)
sprintf(pbuf, "%s(Put) %s (%d) -> %s (%d) [%d] {nest %d} &w&W<%s>\n\r", char_color_str(AT_DGREEN, ch), oname,
pReset->arg1, rname, (obj2 ? obj2->vnum : pReset->arg3), pReset->arg2, pReset->extra, time);
else
sprintf(pbuf, "%s(Put) %s (%d) -> %s (%d) [%d] {nest %d}\n\r", char_color_str(AT_DGREEN, ch), oname,
pReset->arg1, rname, (obj2 ? obj2->vnum : pReset->arg3), pReset->arg2, pReset->extra);
break;
case 'T':
sprintf(pbuf, "%sTRAP: %d %d %d %d (%s)\n\r", char_color_str(AT_BLOOD, ch), pReset->extra, pReset->arg1,
pReset->arg2, pReset->arg3, flag_string(pReset->extra, trap_flags));
break;
case 'H':
if (pReset->arg1 > 0)
if (!(obj2 = get_obj_index(pReset->arg1)))
rname = "Object: *BAD VNUM*";
else
rname = obj2->name;
else if (!obj)
rname = "Object: *NULL obj*";
else
rname = oname;
sprintf(pbuf, "%sHide %s (%d)\n\r", char_color_str(AT_DGREY, ch), rname, (pReset->arg1 > 0 ? pReset->arg1 : obj ? obj->vnum : 0));
break;
case 'B':
{
char *const *flagarray;
bool ext_bv = FALSE;
strcpy(pbuf, "BIT: ");
pbuf += 5;
if (IS_SET(pReset->arg2, BIT_RESET_SET))
{
strcpy(pbuf, "Set: ");
pbuf += 5;
}
else if (IS_SET(pReset->arg2, BIT_RESET_TOGGLE))
{
strcpy(pbuf, "Toggle: ");
pbuf += 8;
}
else
{
strcpy(pbuf, "Remove: ");
pbuf += 8;
}
switch (pReset->arg2 & BIT_RESET_TYPE_MASK)
{
case BIT_RESET_DOOR:
{
int door;
if (!(room = get_room_index(pReset->arg1)))
rname = "Room: *BAD VNUM*";
else
rname = room->name;
door = (pReset->arg2 & BIT_RESET_DOOR_MASK) >> BIT_RESET_DOOR_THRESHOLD;
door = URANGE(0, door, MAX_DIR + 1);
sprintf(pbuf, "Exit %s%s (%d), Room %s (%d)", dir_name[door],
(room && get_exit(room, door) ? "" : " (NO EXIT!)"), door, rname, pReset->arg1);
}
flagarray = ex_flags;
break;
case BIT_RESET_ROOM:
if (!(room = get_room_index(pReset->arg1)))
rname = "Room: *BAD VNUM*";
else
rname = room->name;
sprintf(pbuf, "Room %s (%d)", rname, pReset->arg1);
flagarray = r_flags;
break;
case BIT_RESET_OBJECT:
if (pReset->arg1 > 0)
if (!(obj2 = get_obj_index(pReset->arg1)))
rname = "Object: *BAD VNUM*";
else
rname = obj2->name;
else if (!obj)
rname = "Object: *NULL obj*";
else
rname = oname;
sprintf(pbuf, "Object %s (%d)", rname, (pReset->arg1 > 0 ? pReset->arg1 : obj ? obj->vnum : 0));
flagarray = o_flags;
ext_bv = TRUE;
break;
case BIT_RESET_MOBILE:
if (pReset->arg1 > 0)
{
MOB_INDEX_DATA *mob2;
if (!(mob2 = get_mob_index(pReset->arg1)))
rname = "Mobile: *BAD VNUM*";
else
rname = mob2->player_name;
}
else if (!mob)
rname = "Mobile: *NULL mob*";
else
rname = mname;
sprintf(pbuf, "Mobile %s (%d)", rname, (pReset->arg1 > 0 ? pReset->arg1 : mob ? mob->vnum : 0));
flagarray = a_flags;
ext_bv = TRUE;
break;
default:
sprintf(pbuf, "bad type %d", pReset->arg2 & BIT_RESET_TYPE_MASK);
flagarray = NULL;
break;
}
pbuf += strlen(pbuf);
if (flagarray)
{
if (ext_bv)
{
EXT_BV tmp;
tmp = meb(pReset->arg3);
sprintf(pbuf, "; flags: %s [%d]\n\r", ext_flag_string(&tmp, flagarray), pReset->arg3);
}
else
sprintf(pbuf, "; flags: %s [%d]\n\r", flag_string(pReset->arg3, flagarray), pReset->arg3);
}
else
sprintf(pbuf, "; flags %d\n\r", pReset->arg3);
}
break;
case 'D':
{
char *ef_name;
pReset->arg2 = URANGE(0, pReset->arg2, MAX_DIR + 1);
if (!(room = get_room_index(pReset->arg1)))
rname = "Room: *BAD VNUM*";
else
rname = room->name;
switch (pReset->arg3)
{
default:
ef_name = "(* ERROR *)";
break;
case 0:
ef_name = "Open";
break;
case 1:
ef_name = "Close";
break;
case 2:
ef_name = "Close and lock";
break;
}
sprintf(pbuf, "%s%s [%d] the %s%s [%d] door %s (%d)\n\r", char_color_str(AT_GREY, ch), ef_name,
pReset->arg3, dir_name[pReset->arg2],
(room && get_exit(room, pReset->arg2) ? "" : " (NO EXIT!)"), pReset->arg2, rname, pReset->arg1);
}
break;
case 'R':
if (!(room = get_room_index(pReset->arg1)))
rname = "Room: *BAD VNUM*";
else
rname = room->name;
sprintf(pbuf, "%sRandomize exits 0 to %d -> %s (%d)\n\r", char_color_str(AT_BLUE, ch), pReset->arg2, rname, pReset->arg1);
break;
}
if (start == -1 || num >= start)
send_to_char(buf, ch);
if (end != -1 && num >= end)
break;
}
if (num == 0)
send_to_char("You don't have any resets defined.\n\r", ch);
return;
}
/* Setup put nesting levels, regardless of whether or not the resets will
actually reset, or if they're bugged. */
void renumber_put_resets(AREA_DATA * pArea)
{
RESET_DATA *pReset, *lastobj = NULL;
OBJ_INDEX_DATA *putobj;
for (pReset = pArea->first_reset; pReset; pReset = pReset->next)
{
switch (pReset->command)
{
default:
break;
case 'G':
case 'E':
case 'O':
lastobj = pReset;
break;
case 'P':
if (pReset->arg3 == 0)
{
if (!lastobj)
pReset->extra = 1000000;
else if (lastobj->command != 'P' || lastobj->arg3 > 0)
pReset->extra = 0;
else
{
if ((putobj = get_obj_index(lastobj->arg1)) != NULL)
{
if ((putobj->item_type == ITEM_CONTAINER) || (putobj->item_type == ITEM_FURNITURE) || (putobj->item_type == ITEM_QUIVER))
pReset->extra = lastobj->extra + 1;
else
pReset->extra = UMAX((lastobj->extra - 1), 0);
}
}
lastobj = pReset;
}
}
}
return;
}
/*
* Create a new reset (for online building) -Thoric
*/
RESET_DATA *make_reset(char letter, int extra, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int resetlast, int resettime)
{
RESET_DATA *pReset;
CREATE(pReset, RESET_DATA, 1);
pReset->command = letter;
pReset->extra = extra;
pReset->arg1 = arg1;
pReset->arg2 = arg2;
pReset->arg3 = arg3;
pReset->arg4 = arg4;
pReset->arg5 = arg5;
pReset->arg6 = arg6;
pReset->arg7 = arg7;
pReset->resetlast = resetlast;
pReset->resettime = resettime;
top_reset++;
return pReset;
}
/*
* Add a reset to an area -Thoric
*/
RESET_DATA *add_reset(AREA_DATA * tarea, char letter, int extra, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int resetlast, int resettime)
{
RESET_DATA *pReset;
if (!tarea)
{
bug("add_reset: NULL area!", 0);
return NULL;
}
letter = UPPER(letter);
pReset = make_reset(letter, extra, arg1, arg2, arg3, arg4, arg5, arg6, arg7, resetlast, resettime);
switch (letter)
{
case 'M':
tarea->last_mob_reset = pReset;
pReset->arg2 = 1;
break;
case 'H':
if (arg1 > 0)
break;
case 'E':
case 'G':
case 'P':
case 'O':
tarea->last_obj_reset = pReset;
break;
case 'T':
if (IS_SET(extra, TRAP_OBJ) && arg1 == 0)
tarea->last_obj_reset = pReset;
break;
}
LINK(pReset, tarea->first_reset, tarea->last_reset, next, prev);
return pReset;
}
/*
* Place a reset into an area, insert sorting it -Thoric
*/
RESET_DATA *place_reset(AREA_DATA * tarea, char letter, int extra, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int resetlast, int resettime)
{
RESET_DATA *pReset, *tmp, *tmp2;
if (!tarea)
{
bug("place_reset: NULL area!", 0);
return NULL;
}
letter = UPPER(letter);
pReset = make_reset(letter, extra, arg1, arg2, arg3, arg4, arg5, arg6, arg7, resetlast, resettime);
if (letter == 'M')
tarea->last_mob_reset = pReset;
if (tarea->first_reset)
{
switch (letter)
{
default:
bug("place_reset: Bad reset type %c", letter);
return NULL;
case 'D':
case 'R':
for (tmp = tarea->last_reset; tmp; tmp = tmp->prev)
if (tmp->command == letter)
break;
if (tmp) /* organize by location */
for (; tmp && tmp->command == letter && tmp->arg1 > arg1; tmp = tmp->prev) ;
if (tmp) /* organize by direction */
for (; tmp && tmp->command == letter && tmp->arg1 == tmp->arg1 && tmp->arg2 > arg2; tmp = tmp->prev) ;
if (tmp)
INSERT(pReset, tmp, tarea->first_reset, next, prev);
else
LINK(pReset, tarea->first_reset, tarea->last_reset, next, prev);
return pReset;
case 'M':
case 'O':
/* find last reset of same type */
for (tmp = tarea->last_reset; tmp; tmp = tmp->prev)
if (tmp->command == letter)
break;
tmp2 = tmp ? tmp->next : NULL;
/* organize by location */
for (; tmp; tmp = tmp->prev)
if (tmp->command == letter && tmp->arg3 <= arg3)
{
tmp2 = tmp->next;
/* organize by vnum */
if (tmp->arg3 == arg3)
for (; tmp; tmp = tmp->prev)
if (tmp->command == letter && tmp->arg3 == tmp->arg3 && tmp->arg1 <= arg1)
{
tmp2 = tmp->next;
break;
}
break;
}
/* skip over E or G for that mob */
if (tmp2 && letter == 'M')
{
for (; tmp2; tmp2 = tmp2->next)
if (tmp2->command != 'E' && tmp2->command != 'G')
break;
}
else
/* skip over P, T or H for that obj */
if (tmp2 && letter == 'O')
{
for (; tmp2; tmp2 = tmp2->next)
if (tmp2->command != 'P' && tmp2->command != 'T' && tmp2->command != 'H')
break;
}
if (tmp2)
INSERT(pReset, tmp2, tarea->first_reset, next, prev);
else
LINK(pReset, tarea->first_reset, tarea->last_reset, next, prev);
return pReset;
case 'G':
case 'E':
/* find the last mob */
if ((tmp = tarea->last_mob_reset) != NULL)
{
/*
* See if there are any resets for this mob yet,
* put E before G and organize by vnum
*/
if (tmp->next)
{
tmp = tmp->next;
if (tmp && tmp->command == 'E')
{
if (letter == 'E')
for (; tmp && tmp->command == 'E' && tmp->arg1 < arg1; tmp = tmp->next) ;
else
for (; tmp && tmp->command == 'E'; tmp = tmp->next) ;
}
else if (tmp && tmp->command == 'G' && letter == 'G')
for (; tmp && tmp->command == 'G' && tmp->arg1 < arg1; tmp = tmp->next) ;
if (tmp)
INSERT(pReset, tmp, tarea->first_reset, next, prev);
else
LINK(pReset, tarea->first_reset, tarea->last_reset, next, prev);
}
else
LINK(pReset, tarea->first_reset, tarea->last_reset, next, prev);
return pReset;
}
break;
case 'P':
case 'T':
case 'H':
/* find the object in question */
if (((letter == 'P' && arg3 == 0)
|| (letter == 'T' && IS_SET(extra, TRAP_OBJ) && arg1 == 0)
|| (letter == 'H' && arg1 == 0)) && (tmp = tarea->last_obj_reset) != NULL)
{
if ((tmp = tmp->next) != NULL)
INSERT(pReset, tmp, tarea->first_reset, next, prev);
else
LINK(pReset, tarea->first_reset, tarea->last_reset, next, prev);
return pReset;
}
for (tmp = tarea->last_reset; tmp; tmp = tmp->prev)
if ((tmp->command == 'O' || tmp->command == 'G' || tmp->command == 'E' || tmp->command == 'P') && tmp->arg1 == arg3)
{
/*
* See if there are any resets for this object yet,
* put P before H before T and organize by vnum
*/
if (tmp->next)
{
tmp = tmp->next;
if (tmp && tmp->command == 'P')
{
if (letter == 'P' && tmp->arg3 == arg3)
for (; tmp && tmp->command == 'P' && tmp->arg3 == arg3 && tmp->arg1 < arg1; tmp = tmp->next) ;
else if (letter != 'T')
for (; tmp && tmp->command == 'P' && tmp->arg3 == arg3; tmp = tmp->next) ;
}
else if (tmp && tmp->command == 'H')
{
if (letter == 'H' && tmp->arg3 == arg3)
for (; tmp && tmp->command == 'H' && tmp->arg3 == arg3 && tmp->arg1 < arg1; tmp = tmp->next) ;
else if (letter != 'H')
for (; tmp && tmp->command == 'H' && tmp->arg3 == arg3; tmp = tmp->next) ;
}
else if (tmp && tmp->command == 'T' && letter == 'T')
for (; tmp && tmp->command == 'T' && tmp->arg3 == arg3 && tmp->arg1 < arg1; tmp = tmp->next) ;
if (tmp)
INSERT(pReset, tmp, tarea->first_reset, next, prev);
else
LINK(pReset, tarea->first_reset, tarea->last_reset, next, prev);
}
else
LINK(pReset, tarea->first_reset, tarea->last_reset, next, prev);
return pReset;
}
break;
}
/* likely a bad reset if we get here... add it anyways */
}
LINK(pReset, tarea->first_reset, tarea->last_reset, next, prev);
return pReset;
}
void rsmob(AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom)
{
CHAR_DATA *rch;
OBJ_DATA *obj;
RESET_DATA *reset;
if (pArea->first_reset)
wipe_resets(pArea, pRoom);
for (rch = pRoom->first_person; rch; rch = rch->next_in_room)
{
/* Small note, Xerves screwed up here *grins* -- Xerves self-note */
if (!IS_NPC(rch))
continue;
reset = add_reset(pArea, 'M', 1, rch->pIndexData->vnum, 1, pRoom->vnum, rch->coord->x, rch->coord->y, rch->map, -1, 0, 0);
reset->serial = rch->serial;
serial_list[reset->serial] = TRUE;
for (obj = rch->first_carrying; obj; obj = obj->next_content)
{
if (obj->wear_loc == WEAR_NONE)
{
add_obj_reset(pArea, 'G', obj, 1, 0);
}
else
{
add_obj_reset(pArea, 'E', obj, 1, obj->wear_loc);
}
}
}
return;
}
void kupkeep(AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom)
{
CHAR_DATA *rch;
OBJ_DATA *obj;
RESET_DATA *reset;
if (pArea->first_reset)
wipe_resets(pArea, pRoom);
for (rch = pRoom->first_person; rch; rch = rch->next_in_room)
{
/* Small note, Xerves screwed up here *grins* -- Xerves self-note */
if (!IS_NPC(rch))
continue;
if (!xIS_SET(rch->act, ACT_CASTEMOB))
continue;
reset = add_reset(pArea, 'M', 1, rch->pIndexData->vnum, 1, pRoom->vnum, rch->coord->x, rch->coord->y, rch->map, -1, 0, 0);
reset->serial = rch->serial;
serial_list[reset->serial] = TRUE;
for (obj = rch->first_carrying; obj; obj = obj->next_content)
{
if (obj->wear_loc == WEAR_NONE)
{
add_obj_reset(pArea, 'G', obj, 1, 0);
}
else
{
add_obj_reset(pArea, 'E', obj, 1, obj->wear_loc);
}
}
}
return;
}
void do_resetkeeper(CHAR_DATA * ch, char *argument)
{
AREA_DATA *pArea;
ROOM_INDEX_DATA *pRoom;
char arg[MIL];
if (IS_NPC(ch))
{
send_to_char("Mobs cannot reset other mobs. Sorry :-)\n\r", ch);
return;
}
if (!ch->pcdata || !ch->pcdata->keeper || (ch->pcdata->caste < 7))
{
send_to_char("You need to have a shop keeper to reset him/her.\n\r", ch);
return;
}
argument = one_argument(argument, arg);
if (!(pRoom = find_room(ch, arg, NULL)))
{
send_to_char("Room doesn't exsist.\n\r", ch);
return;
}
pArea = pRoom->area;
if (!can_kmodify(ch, pRoom))
return;
if (pRoom->vnum != ch->pcdata->keeper) /* Tracker1 */
{
send_to_char("You cannot reset that room.\n\r", ch);
return;
}
if (pArea->first_reset)
wipe_resets(pArea, pRoom);
resetkeeper(pArea, pRoom, FALSE);
send_to_char("ShopKeeper is Reset.\n\r", ch);
}
bool can_kmodify(CHAR_DATA * ch, ROOM_INDEX_DATA * room)
{
sh_int vnum = room->vnum;
if (IS_NPC(ch))
return FALSE;
if (!xIS_SET(room->room_flags, ROOM_PROTOTYPE))
{
send_to_char("You cannot modify this room.\n\r", ch);
return FALSE;
}
if (!ch->pcdata || !(ch->pcdata->keeper))
{
send_to_char("You must have an assigned shop keeper to modify him/her.\n\r", ch);
return FALSE;
}
if (vnum == ch->pcdata->keeper)
return TRUE;
send_to_char("What are you trying to modify?\n\r", ch);
return FALSE;
}
void resetkeeper(AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, bool dodoors)
{
CHAR_DATA *rch;
OBJ_DATA *obj;
RESET_DATA *reset;
for (rch = pRoom->first_person; rch; rch = rch->next_in_room)
{
if (!IS_NPC(rch) || !xIS_SET(rch->act, ACT_CASTEMOB))
continue;
reset = add_reset(pArea, 'M', 1, rch->pIndexData->vnum, 1, pRoom->vnum, rch->coord->x, rch->coord->y, rch->map, -1, 0, 0);
reset->serial = rch->serial;
serial_list[reset->serial] = TRUE;
for (obj = rch->first_carrying; obj; obj = obj->next_content)
{
if (obj->wear_loc == WEAR_NONE)
add_obj_reset(pArea, 'G', obj, 1, 0);
else
add_obj_reset(pArea, 'E', obj, 1, obj->wear_loc);
}
}
fdarea(rch, pArea->filename);
return;
}