/****************************************************************************
* [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 )
void add_obj_reset args( ( AREA_DATA * pArea, char cm, OBJ_DATA * obj, int v2, int v3 ) );
void instaroom args( ( AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, bool dodoors ) );
#define RID ROOM_INDEX_DATA
RID *find_room args( ( CHAR_DATA * ch, char *argument, ROOM_INDEX_DATA * pRoom ) );
#undef RID
void edit_reset args( ( CHAR_DATA * ch, char *argument, AREA_DATA * pArea, ROOM_INDEX_DATA * aRoom ) );
#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 ) );
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;
}
/* 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[MAX_INPUT_LENGTH];
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 );
/*
* 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[MAX_INPUT_LENGTH];
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 ) && ++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[MAX_INPUT_LENGTH];
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;
}
void edit_reset( CHAR_DATA * ch, char *argument, AREA_DATA * pArea, ROOM_INDEX_DATA * aRoom )
{
char arg[MAX_INPUT_LENGTH];
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: %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 );
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 ) ) )
{
send_to_char( "Error in reset. Reset not changed.\n\r", ch );
return;
}
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;
}
add_reset( pArea, pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3 );
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;
}
place_reset( pArea, pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3 );
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;
}
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, "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, num, pRoom->vnum );
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 );
/*
* 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 );
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 );
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 );
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 );
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[MAX_INPUT_LENGTH];
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( argument, "obj" );
if( isobj == is_name( argument, "room" ) )
{
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 );
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[MAX_INPUT_LENGTH];
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 );
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 );
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 );
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[MAX_INPUT_LENGTH];
char *parg;
/*
* Can't have NPC's doing this. Bug report sent in by Cronel
* -- Shaddai
*/
if( IS_NPC( ch ) )
return;
parg = one_argument( argument, arg );
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_GOD )
{
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;
static int iNest;
int obj_loop, value_loop;
int reset_count = 0;
bool found;
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 );
return;
}
add_reset( pArea, cm, ( cm == 'P' ? iNest : 1 ), obj->pIndexData->vnum, v2, v3 );
/*
* 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 );
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( cm == 'P' )
iNest--;
return;
}
void instaroom( AREA_DATA * pArea, ROOM_INDEX_DATA * pRoom, bool dodoors )
{
CHAR_DATA *rch;
OBJ_DATA *obj;
int obj_loop, value_loop, reset_count;
bool found;
for( rch = pRoom->first_person; rch; rch = rch->next_in_room )
{
if( !IS_NPC( rch ) )
continue;
add_reset( pArea, 'M', 1, rch->pIndexData->vnum, 1, pRoom->vnum );
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( get_obj_index( obj->pIndexData->vnum ), rch->first_carrying );
put_index = 0;
add_obj_reset( pArea, 'G', obj, reset_count, 0 );
}
else
add_obj_reset( pArea, 'E', obj, 1, 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 );
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 );
}
}
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 do_instaroom( CHAR_DATA * ch, char *argument )
{
AREA_DATA *pArea;
ROOM_INDEX_DATA *pRoom;
bool dodoors;
char arg[MAX_INPUT_LENGTH];
if( IS_NPC( ch ) || get_trust( ch ) < LEVEL_SAVIOR || !ch->pcdata || !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;
pArea = ch->pcdata->area;
if( !( pRoom = find_room( ch, arg, NULL ) ) )
{
send_to_char( "Room doesn't exist.\n\r", ch );
return;
}
if( !can_rmodify( ch, pRoom ) )
return;
if( pRoom->area != pArea && get_trust( ch ) < LEVEL_GREATER )
{
send_to_char( "You cannot reset that room.\n\r", ch );
return;
}
if( pArea->first_reset )
wipe_resets( pArea, pRoom );
instaroom( pArea, pRoom, dodoors );
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_SAVIOR || !ch->pcdata || !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( pArea, pRoom, dodoors );
}
send_to_char( "Area resets installed.\n\r", ch );
return;
}
int generate_itemlevel( AREA_DATA * pArea, OBJ_INDEX_DATA * pObjIndex )
{
int olevel;
/*
int min = UMAX(pArea->low_soft_range, 1);
int max = UMIN(pArea->hi_soft_range, min + 15);
if ( pObjIndex->level > 0 )
olevel = UMIN(pObjIndex->level, MAX_LEVEL);
else
switch ( pObjIndex->item_type )
{
default: olevel = 0; break;
case ITEM_PILL: olevel = number_range( min, max ); break;
case ITEM_POTION: olevel = number_range( min, max ); break;
case ITEM_SCROLL: olevel = pObjIndex->value[0]; break;
case ITEM_WAND: olevel = number_range( min+4, max+1 ); break;
case ITEM_STAFF: olevel = number_range( min+9, max+5 ); break;
case ITEM_ARMOR: olevel = number_range( min+4, max+1 ); break;
case ITEM_WEAPON: olevel = number_range( min+4, max+1 ); break;
}
*/
olevel = pObjIndex->level;
return olevel;
}
void reset_area( AREA_DATA * pArea )
{
RESET_DATA *pReset;
RESET_DATA *pResetNext;
CHAR_DATA *mob;
OBJ_DATA *obj;
OBJ_DATA *lastobj;
ROOM_INDEX_DATA *pRoomIndex = NULL;
MOB_INDEX_DATA *pMobIndex;
OBJ_INDEX_DATA *pObjIndex;
OBJ_INDEX_DATA *pObjToIndex;
EXIT_DATA *pexit;
OBJ_DATA *to_obj;
char buf[MAX_STRING_LENGTH];
int level = 0;
void *plc = NULL;
bool ext_bv = FALSE;
CHAR_DATA *target;
bool exit = FALSE;
char buf2[MAX_STRING_LENGTH];
AREA_DATA *temp;
bool proto = FALSE;
if( !pArea )
{
bug( "reset_area: NULL pArea", 0 );
return;
}
for( temp = first_build; temp; temp = temp->next )
{
if( !str_cmp( temp->filename, pArea->filename ) )
{
proto = TRUE;
break;
}
}
mob = NULL;
obj = NULL;
lastobj = NULL;
if( !pArea->first_reset )
{
bug( "%s: reset_area: no resets", ( int )pArea->filename );
return;
}
level = 0;
for( pReset = pArea->first_reset; pReset; pReset = pReset->next )
{
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( proto == TRUE && !xIS_SET( pMobIndex->act, ACT_PROTOTYPE ) )
{
bug( "Reset tried to invoke non-prototype mobile. Skipping.", 0 );
continue;
}
for( target = first_char; target; target = target->next )
{
if( !IS_NPC( target ) )
continue;
if( target->mob_serial == pReset->reset_serial )
{
mob = target;
exit = TRUE;
break;
}
}
if( exit )
{
exit = FALSE;
break;
}
mob = create_mobile( pMobIndex );
mob->mob_serial = pReset->reset_serial;
{
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( room_is_dark( pRoomIndex ) )
xSET_BIT( mob->affected_by, AFF_INFRARED );
char_to_room( mob, pRoomIndex );
economize_mobgold( mob );
level = URANGE( 0, mob->level - 2, LEVEL_AVATAR );
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( proto == TRUE && !IS_OBJ_STAT( pObjIndex, ITEM_PROTOTYPE ) )
{
bug( "Reset tried to invoke non-prototype object. Skipping.", 0 );
continue;
}
if( !mob )
{
lastobj = NULL;
break;
}
if( count_obj_list( pObjIndex, mob->first_carrying ) >= pReset->arg2 )
{
obj = NULL;
lastobj = NULL;
break;
}
if( mob->pIndexData->pShop )
{
int olevel = generate_itemlevel( pArea, pObjIndex );
sprintf( buf2, "mob%d@room%d(SHOP)", mob->pIndexData->vnum, mob->in_room->vnum );
obj = create_object_new( pObjIndex, olevel, ORIGIN_RESET, buf2 );
xSET_BIT( obj->extra_flags, ITEM_INVENTORY );
/* Inventory problem */
obj->count = 1;
}
else
{
/* Inventory problem */
sprintf( buf2, "mob%d@room%d", mob->pIndexData->vnum, mob->in_room->vnum );
obj = create_object_new( pObjIndex, number_fuzzy( level ), ORIGIN_RESET, buf2 );
obj->count = ( pReset->arg2 - count_obj_list( pObjIndex, mob->first_carrying ) );
}
obj = obj_to_char( obj, mob );
if( pReset->command == 'E' )
{
/* Equip reset fault */
obj->count = 1;
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( proto == TRUE && !IS_OBJ_STAT( pObjIndex, ITEM_PROTOTYPE ) )
{
bug( "Reset tried to invoke non-prototype object. Skipping.", 0 );
continue;
}
if( pArea->nplayer > 0 || ( count_obj_list( pObjIndex, pRoomIndex->first_content ) >= pReset->arg2 ) )
{
obj = NULL;
/* New section */
pResetNext = pReset->next;
if( pResetNext && pResetNext->command == 'P' )
{
lastobj = get_obj_type( pObjIndex ); /* find last object reset */
lastobj->value[1] = lastobj->pIndexData->value[1]; /* reset last object flags */
} /* eg locked,closed etc */
else
lastobj = NULL;
/* New section */
break;
}
sprintf( buf2, "room%d", pRoomIndex->vnum );
obj = create_object_new( pObjIndex, number_fuzzy( generate_itemlevel( pArea, pObjIndex ) ), ORIGIN_RESET, buf2 );
obj->count = ( pReset->arg2 - count_obj_list( pObjIndex, pRoomIndex->first_content ) );
obj_to_room( obj, pRoomIndex );
lastobj = obj;
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( proto == TRUE && !IS_OBJ_STAT( pObjIndex, ITEM_PROTOTYPE ) )
{
bug( "Reset tried to invoke non-prototype object. Skipping.", 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( 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;
/* New Section */
if( pArea->nplayer > 0 || ( count_obj_list( pObjIndex, to_obj->first_content ) >= pReset->arg2 ) )
{
obj = NULL;
break;
}
/* New section */
}
sprintf( buf2, "inside%d@room%d", to_obj->pIndexData->vnum, pRoomIndex->vnum );
obj = create_object( pObjIndex, number_fuzzy( UMAX( generate_itemlevel( pArea, pObjIndex ), to_obj->level ) ) );
obj->count = ( pReset->arg2 - count_obj_list( pObjIndex, to_obj->first_content ) );
/* New section */
if( IS_OBJ_TYPE( obj ) )
obj->value[1] = obj->pIndexData->value[1]; /* reset object flags eg closed/locked */
/* New section */
obj_to_obj( obj, to_obj );
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( proto == TRUE && !IS_OBJ_STAT( pObjToIndex, ITEM_PROTOTYPE ) )
{
bug( "Reset tried to invoke non-prototype object. Skipping.", 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, number_fuzzy( to_obj->level ), 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 );
}
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( proto == TRUE && !IS_OBJ_STAT( pObjToIndex, ITEM_PROTOTYPE ) )
{
bug( "Reset tried to invoke non-prototype object. Skipping.", 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( proto == TRUE && !IS_OBJ_STAT( pObjToIndex, ITEM_PROTOTYPE ) )
{
bug( "Reset tried to invoke non-prototype object. Skipping.", 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;
}
}
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 *pbuf;
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, "%2d) ", num );
pbuf = buf + strlen( buf );
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;
sprintf( pbuf, "%s (%d) -> %s (%d) [%d]", mname, pReset->arg1, rname, pReset->arg3, pReset->arg2 );
if( !room )
mob = NULL;
if( ( room = get_room_index( pReset->arg3 - 1 ) ) && xIS_SET( room->room_flags, ROOM_PET_SHOP ) )
strcat( buf, " (pet)\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;
sprintf( pbuf, "%s (%d) -> %s (%s) [%d]", oname, pReset->arg1, mname,
( pReset->command == 'G' ? "carry" : wear_locs[pReset->arg3] ), pReset->arg2 );
if( mob && mob->pShop )
strcat( buf, " (shop)\n\r" );
else
strcat( buf, "\n\r" );
lastobj = obj;
lo_reset = pReset;
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;
sprintf( pbuf, "(object) %s (%d) -> %s (%d) [%d]\n\r", oname, pReset->arg1, rname, pReset->arg3, 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;
}
sprintf( pbuf, "(Put) %s (%d) -> %s (%d) [%d] {nest %d}\n\r", oname,
pReset->arg1, rname, ( obj2 ? obj2->vnum : pReset->arg3 ), pReset->arg2, pReset->extra );
break;
case 'T':
sprintf( pbuf, "TRAP: %d %d %d %d (%s)\n\r", 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, "Hide %s (%d)\n\r", 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 [%d] the %s%s [%d] door %s (%d)\n\r", 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, "Randomize exits 0 to %d -> %s (%d)\n\r", 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 )
{
RESET_DATA *pReset;
CREATE( pReset, RESET_DATA, 1 );
pReset->command = letter;
pReset->extra = extra;
pReset->arg1 = arg1;
pReset->arg2 = arg2;
pReset->arg3 = arg3;
if( letter == 'M' )
{
top_mob_serial++;
pReset->reset_serial = top_mob_serial;
}
else
pReset->reset_serial = -1;
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 )
{
RESET_DATA *pReset;
if( !tarea )
{
bug( "add_reset: NULL area!", 0 );
return NULL;
}
letter = UPPER( letter );
pReset = make_reset( letter, extra, arg1, arg2, arg3 );
switch ( letter )
{
case 'M':
tarea->last_mob_reset = pReset;
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 )
{
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 );
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;
}