/*
* Renumber Imm command
* Author: Cronel (cronel_kal@hotmail.com)
* of FrozenMUD (empire.digiunix.net 4000)
*
* Permission to use and distribute this code is granted provided
* this header is retained and unaltered, and the distribution
* package contains all the original files unmodified.
* If you modify this code and use/distribute modified versions
* you must give credit to the original author(s).
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "mud.h"
#define NOT_FOUND (-1)
enum
{ REN_ROOM, REN_OBJ, REN_MOB };
struct renumber_data
{
int old_vnum;
int new_vnum;
struct renumber_data *next;
};
typedef struct renumber_data RENUMBER_DATA;
struct renumber_area
{
int low_obj, hi_obj;
RENUMBER_DATA *r_obj;
int low_mob, hi_mob;
RENUMBER_DATA *r_mob;
int low_room, hi_room;
RENUMBER_DATA *r_room;
};
typedef struct renumber_area RENUMBER_AREA;
void renumber_area( CHAR_DATA * ch, AREA_DATA * area, RENUMBER_AREA * r_area, bool area_is_proto, bool verbose );
RENUMBER_AREA *gather_renumber_data( AREA_DATA * area, int new_base, bool fill_gaps );
RENUMBER_DATA *gather_one_list( short type, int low, int high, int new_base, bool fill_gaps, int *max_vnum );
void free_renumber_data( RENUMBER_DATA * r_data );
AREA_DATA *find_area( char *filename, bool * p_is_proto );
bool check_vnums( CHAR_DATA * ch, AREA_DATA * tarea, RENUMBER_AREA * r_area );
int find_translation( int vnum, RENUMBER_DATA * r_data );
void translate_reset( RESET_DATA * reset, RENUMBER_AREA * r_data );
void translate_objvals( CHAR_DATA * ch, AREA_DATA * area, RENUMBER_AREA * r_data, bool verbose );
void translate_exits( CHAR_DATA * ch, AREA_DATA * area, RENUMBER_AREA * r_area, bool verbose );
void warn_progs( CHAR_DATA * ch, int low, int high, AREA_DATA * area, RENUMBER_AREA * r_area );
void warn_in_prog( CHAR_DATA * ch, int low, int high, char *where, int vnum, MPROG_DATA * mprog, RENUMBER_AREA * r_area );
/* from db.c */
extern ROOM_INDEX_DATA *room_index_hash[MAX_KEY_HASH];
extern MOB_INDEX_DATA *mob_index_hash[MAX_KEY_HASH];
extern OBJ_INDEX_DATA *obj_index_hash[MAX_KEY_HASH];
void do_renumber( CHAR_DATA * ch, char *argument )
{
RENUMBER_AREA *r_area;
AREA_DATA *area;
bool is_proto;
char arg1[MAX_INPUT_LENGTH];
int new_base;
bool fill_gaps, verbose;
/*
* parse the first two parameters
*/
/*
* first, area
*/
argument = one_argument( argument, arg1 );
if( arg1[0] == '\0' )
{
ch_printf( ch, "What area do you want to renumber?\n\r" );
return;
}
area = find_area( arg1, &is_proto );
if( area == NULL )
{
ch_printf( ch, "No such area '%s'.\n\r", arg1 );
return;
}
/*
* and new vnum base
*/
argument = one_argument( argument, arg1 );
if( arg1[0] == '\0' )
{
ch_printf( ch, "What will be the new vnum base for this area?\n\r" );
return;
}
if( !is_number( arg1 ) )
{
ch_printf( ch, "Sorry, '%s' is not a valid vnum base number!\n\r", arg1 );
return;
}
new_base = atoi( arg1 );
/*
* parse the flags
*/
fill_gaps = FALSE;
verbose = FALSE;
for( ;; )
{
argument = one_argument( argument, arg1 );
if( arg1[0] == '\0' )
break;
else if( !str_prefix( arg1, "fillgaps" ) )
fill_gaps = TRUE;
else if( !str_prefix( arg1, "verbose" ) )
verbose = TRUE;
else
{
ch_printf( ch, "Invalid flag '%s'.\n\r", arg1 );
return;
}
}
/*
* sanity check
*/
if( new_base == area->low_r_vnum && new_base == area->low_o_vnum && new_base == area->low_m_vnum && !fill_gaps )
{
ch_printf( ch,
"You don't want to change the base vnum and you don't want to fill gaps...\n\rSo what DO you wanna do?\n\r" );
return;
}
/*
* some restrictions
*/
if( IS_NPC( ch ) )
{
ch_printf( ch, "Yeah, right.\n\r" );
return;
}
if( ch->level < LEVEL_SAVIOR )
{
ch_printf( ch, "You don't have enough privileges.\n\r" );
return;
}
if( ch->level == LEVEL_SAVIOR )
{
if( area->low_r_vnum < ch->pcdata->r_range_lo || area->hi_r_vnum > ch->pcdata->r_range_hi ||
area->low_m_vnum < ch->pcdata->m_range_lo || area->hi_m_vnum > ch->pcdata->m_range_hi ||
area->low_o_vnum < ch->pcdata->o_range_lo || area->hi_o_vnum > ch->pcdata->o_range_hi )
{
ch_printf( ch, "You can't renumber that area ('%s').\n\r", area->filename );
return;
}
}
/*
* get the renumber data
*/
r_area = gather_renumber_data( area, new_base, fill_gaps );
/*
* one more restriction
*/
if( ch->level == LEVEL_SAVIOR )
{
if( r_area->low_room < ch->pcdata->r_range_lo || r_area->hi_room > ch->pcdata->r_range_hi ||
r_area->low_obj < ch->pcdata->o_range_lo || r_area->hi_obj > ch->pcdata->o_range_hi ||
r_area->low_mob < ch->pcdata->m_range_lo || r_area->hi_mob > ch->pcdata->m_range_hi )
{
ch_printf( ch, "The renumbered area would be outside your assigned vnum range.\n\r" );
return;
}
}
else if( is_proto )
{
if( r_area->low_room < area->low_r_vnum || r_area->hi_room > area->hi_r_vnum ||
r_area->low_obj < area->low_o_vnum || r_area->hi_obj > area->hi_o_vnum ||
r_area->low_mob < area->low_m_vnum || r_area->hi_mob > area->hi_m_vnum )
{
ch_printf( ch,
"Moving a proto area out of its range would create problems.\n\rWait till the area is finished to move it.\n\r" );
return;
}
}
/*
* no overwriting of dest vnums
*/
if( check_vnums( ch, area, r_area ) )
return;
/*
* another sanity check :)
*/
if( r_area == NULL || ( r_area->r_obj == NULL && r_area->r_mob == NULL && r_area->r_room == NULL ) )
{
ch_printf( ch, "No changes to make.\n\r" );
if( r_area != NULL )
DISPOSE( r_area );
return;
}
/*
* ok, do it!
*/
pager_printf( ch, "Renumbering area '%s' to new base %d, filling gaps: %s\n\r",
area->filename, new_base, fill_gaps ? "yes" : "no" );
renumber_area( ch, area, r_area, is_proto, verbose );
pager_printf( ch, "Done.\n\r" );
/*
* clean up and goodbye
*/
if( r_area->r_room != NULL )
free_renumber_data( r_area->r_room );
if( r_area->r_obj != NULL )
free_renumber_data( r_area->r_obj );
if( r_area->r_mob != NULL )
free_renumber_data( r_area->r_mob );
DISPOSE( r_area );
}
bool check_vnums( CHAR_DATA * ch, AREA_DATA * tarea, RENUMBER_AREA * r_area )
{
int high, low;
AREA_DATA *area;
bool proto;
/*
* this function assumes all the lows are allways gonna be
* lower or equal to all the highs ..
*/
high = UMAX( r_area->hi_room, UMAX( r_area->hi_obj, r_area->hi_mob ) );
low = UMIN( r_area->low_room, UMIN( r_area->low_obj, r_area->low_mob ) );
/*
* in do_check_vnums they use first_bsort, first_asort but.. i dunno..
*/
area = first_area;
proto = FALSE;
while( area )
{
if( tarea == area )
;
else if( !( high < area->low_r_vnum || low > area->hi_r_vnum ) ||
!( high < area->low_o_vnum || low > area->hi_o_vnum ) || !( high < area->low_m_vnum || low > area->hi_m_vnum ) )
{
ch_printf( ch, "This operation would overwrite area %s! Use checkvnums first.\n\r", area->filename );
return TRUE;
}
area = area->next;
if( area == NULL && !proto )
{
area = first_build;
proto = TRUE;
}
}
return FALSE;
}
RENUMBER_AREA *gather_renumber_data( AREA_DATA * area, int new_base, bool fill_gaps )
/* this function actualy gathers all the renumber data for an area */
{
RENUMBER_AREA *r_area;
int max;
CREATE( r_area, RENUMBER_AREA, 1 );
r_area->r_mob = gather_one_list( REN_MOB, area->low_m_vnum, area->hi_m_vnum, new_base, fill_gaps, &max );
r_area->low_mob = new_base;
r_area->hi_mob = max;
r_area->r_obj = gather_one_list( REN_OBJ, area->low_o_vnum, area->hi_o_vnum, new_base, fill_gaps, &max );
r_area->low_obj = new_base;
r_area->hi_obj = max;
r_area->r_room = gather_one_list( REN_ROOM, area->low_r_vnum, area->hi_r_vnum, new_base, fill_gaps, &max );
r_area->low_room = new_base;
r_area->hi_room = max;
return r_area;
}
RENUMBER_DATA *gather_one_list( short type, int low, int high, int new_base, bool fill_gaps, int *max_vnum )
/* this function builds a list of renumber data for a type (obj, room, or mob) */
{
int cur_vnum;
RENUMBER_DATA *r_data, root;
bool found;
ROOM_INDEX_DATA *room;
OBJ_INDEX_DATA *obj;
MOB_INDEX_DATA *mob;
int i;
int highest;
memset( &root, 0, sizeof( RENUMBER_DATA ) );
r_data = &root;
cur_vnum = new_base;
highest = -1;
for( i = low; i <= high; i++ )
{
found = FALSE;
switch ( type )
{
case REN_ROOM:
room = get_room_index( i );
if( room != NULL )
found = TRUE;
break;
case REN_OBJ:
obj = get_obj_index( i );
if( obj != NULL )
found = TRUE;
break;
case REN_MOB:
mob = get_mob_index( i );
if( mob != NULL )
found = TRUE;
break;
}
if( found )
{
if( cur_vnum > highest )
highest = cur_vnum;
if( cur_vnum != i )
{
CREATE( r_data->next, RENUMBER_DATA, 1 );
r_data = r_data->next;
r_data->old_vnum = i;
r_data->new_vnum = cur_vnum;
}
cur_vnum++;
}
else if( !fill_gaps )
cur_vnum++;
}
*max_vnum = highest;
return root.next;
}
void free_renumber_data( RENUMBER_DATA * r_data )
/* disposes of a list of renumber data items */
{
RENUMBER_DATA *r_next;
while( r_data != NULL )
{
r_next = r_data->next;
DISPOSE( r_data );
r_data = r_next;
}
}
void renumber_area( CHAR_DATA * ch, AREA_DATA * area, RENUMBER_AREA * r_area, bool area_is_proto, bool verbose )
/* this is the function that actualy does the renumbering of "area" according
to the renumber data in "r_area". "ch" is to show messages. */
{
RENUMBER_DATA *r_data;
ROOM_INDEX_DATA *room, *room_prev, *room_list, *room_next;
MOB_INDEX_DATA *mob, *mob_prev, *mob_list, *mob_next;
OBJ_INDEX_DATA *obj, *obj_prev, *obj_list, *obj_next;
RESET_DATA *reset;
int iHash;
int low, high;
high = UMAX( area->hi_r_vnum, UMIN( area->hi_o_vnum, area->hi_m_vnum ) );
low = UMIN( area->low_r_vnum, UMIN( area->low_o_vnum, area->low_m_vnum ) );
pager_printf( ch, "(Room) Renumbering...\n\r" );
/*
* what we do here is, for each list (room/obj/mob) first we
* * take each element out of the hash array, change the vnum,
* * and move it to our own list. after everything's moved out
* * we put it in again. this is to avoid problems in situations
* * where where room A is being moved to position B, but theres
* * already a room B wich is also being moved to position C.
* * a straightforward approach would result in us moving A to
* * position B first, and then again to position C, and room
* * B being lost inside the hash array, still there, but not
* * foundable (its "covered" by A because they'd have the same
* * vnum).
*/
room_list = NULL;
for( r_data = r_area->r_room; r_data; r_data = r_data->next )
{
if( verbose )
pager_printf( ch, "(Room) %d -> %d\n\r", r_data->old_vnum, r_data->new_vnum );
room = get_room_index( r_data->old_vnum );
if( !room )
{
bug( "renumber_area: NULL room %d", r_data->old_vnum );
continue;
}
/*
* remove it from the hash list
*/
iHash = r_data->old_vnum % MAX_KEY_HASH;
if( room_index_hash[iHash] == room )
room_index_hash[iHash] = room->next;
else
{
for( room_prev = room_index_hash[iHash]; room_prev && room_prev->next != room; room_prev = room_prev->next )
;
if( room_prev == NULL )
{
bug( "renumber_area: Couldn't find a room in the hash table! Skipping it.\n\r" );
continue;
}
room_prev->next = room->next;
room->next = NULL;
}
/*
* change the vnum
*/
room->vnum = r_data->new_vnum;
/*
* move it to the temporary list
*/
room->next = room_list;
room_list = room;
}
/*
* now move everything back into the hash array
*/
for( room = room_list; room; room = room_next )
{
room_next = room->next;
/*
* add it to the hash list again (new position)
*/
iHash = room->vnum % MAX_KEY_HASH;
room->next = room_index_hash[iHash];
room_index_hash[iHash] = room;
}
/*
* if nothing was moved, or if the area is proto, dont change this
*/
if( r_area->r_room != NULL && !area_is_proto )
{
area->low_r_vnum = r_area->low_room;
area->hi_r_vnum = r_area->hi_room;
}
pager_printf( ch, "(Mobs) Renumbering...\n\r" );
mob_list = NULL;
for( r_data = r_area->r_mob; r_data; r_data = r_data->next )
{
if( verbose )
pager_printf( ch, "(Mobs) %d -> %d\n\r", r_data->old_vnum, r_data->new_vnum );
mob = get_mob_index( r_data->old_vnum );
if( !mob )
{
bug( "renumber_area: NULL mob %d", r_data->old_vnum );
continue;
}
/*
* fix references to this mob from shops while renumbering this mob
*/
if( mob->pShop )
{
if( verbose )
pager_printf( ch, "(Mobs) Fixing shop for mob %d -> %d\n\r", r_data->old_vnum, r_data->new_vnum );
mob->pShop->keeper = r_data->new_vnum;
}
if( mob->rShop )
{
if( verbose )
pager_printf( ch, "(Mobs) Fixing repair shop for mob %d -> %d\n\r", r_data->old_vnum, r_data->new_vnum );
mob->rShop->keeper = r_data->new_vnum;
}
/*
* remove it from the hash list
*/
iHash = r_data->old_vnum % MAX_KEY_HASH;
if( mob_index_hash[iHash] == mob )
mob_index_hash[iHash] = mob->next;
else
{
for( mob_prev = mob_index_hash[iHash]; mob_prev && mob_prev->next != mob; mob_prev = mob_prev->next )
;
if( mob_prev == NULL )
{
bug( "renumber_area: Couldn't find a mob in the hash table! Skipping it.\n\r" );
continue;
}
mob_prev->next = mob->next;
mob->next = NULL;
}
/*
* change the vnum
*/
mob->vnum = r_data->new_vnum;
/*
* move to private list
*/
mob->next = mob_list;
mob_list = mob;
}
for( mob = mob_list; mob; mob = mob_next )
{
mob_next = mob->next;
/*
* add it to the hash list again
*/
iHash = mob->vnum % MAX_KEY_HASH;
mob->next = mob_index_hash[iHash];
mob_index_hash[iHash] = mob;
}
if( r_area->r_mob && !area_is_proto )
{
area->low_m_vnum = r_area->low_mob;
area->hi_m_vnum = r_area->hi_mob;
}
pager_printf( ch, "(Objs) Renumbering...\n\r" );
obj_list = NULL;
for( r_data = r_area->r_obj; r_data; r_data = r_data->next )
{
if( verbose )
pager_printf( ch, "(Objs) %d -> %d\n\r", r_data->old_vnum, r_data->new_vnum );
obj = get_obj_index( r_data->old_vnum );
if( !obj )
{
bug( "renumber_area: NULL obj %d", r_data->old_vnum );
continue;
}
/*
* remove it from the hash list
*/
iHash = r_data->old_vnum % MAX_KEY_HASH;
if( obj_index_hash[iHash] == obj )
obj_index_hash[iHash] = obj->next;
else
{
for( obj_prev = obj_index_hash[iHash]; obj_prev && obj_prev->next != obj; obj_prev = obj_prev->next )
;
if( obj_prev == NULL )
{
bug( "renumber_area: Couldn't find an obj in the hash table! Skipping it.\n\r" );
continue;
}
obj_prev->next = obj->next;
obj->next = NULL;
}
/*
* change the vnum
*/
obj->vnum = r_data->new_vnum;
/*
* to our list
*/
obj->next = obj_list;
obj_list = obj;
}
for( obj = obj_list; obj; obj = obj_next )
{
obj_next = obj->next;
/*
* add it to the hash list again
*/
iHash = obj->vnum % MAX_KEY_HASH;
obj->next = obj_index_hash[iHash];
obj_index_hash[iHash] = obj;
}
if( r_area->r_obj && !area_is_proto )
{
area->low_o_vnum = r_area->low_obj;
area->hi_o_vnum = r_area->hi_obj;
}
pager_printf( ch, "Fixing references...\n\r" );
pager_printf( ch, "... fixing objvals...\n\r" );
translate_objvals( ch, area, r_area, verbose );
pager_printf( ch, "... fixing exits...\n\r" );
translate_exits( ch, area, r_area, verbose );
pager_printf( ch, "... fixing resets...\n\r" );
for( reset = area->first_reset; reset; reset = reset->next )
translate_reset( reset, r_area );
if( verbose )
{
pager_printf( ch, "Searching progs for references to renumbered vnums...\n\r" );
warn_progs( ch, low, high, area, r_area );
}
}
void translate_exits( CHAR_DATA * ch, AREA_DATA * area, RENUMBER_AREA * r_area, bool verbose )
{
int i, new_vnum;
EXIT_DATA *exit, *rev_exit;
ROOM_INDEX_DATA *room;
int old_vnum;
for( i = area->low_r_vnum; i <= area->hi_r_vnum; i++ )
{
room = get_room_index( i );
if( !room )
continue;
for( exit = room->first_exit; exit; exit = exit->next )
{
/*
* translate the exit destination, if it was moved
*/
new_vnum = find_translation( exit->vnum, r_area->r_room );
if( new_vnum != NOT_FOUND )
exit->vnum = new_vnum;
/*
* if this room was moved
*/
if( exit->rvnum != i )
{
old_vnum = exit->rvnum;
exit->rvnum = i;
/*
* all reverse exits in other areas will be wrong
*/
rev_exit = get_exit_to( exit->to_room, rev_dir[exit->vdir], old_vnum );
if( rev_exit && exit->to_room->area != area )
{
if( rev_exit->vnum != i )
{
pager_printf( ch, "... fixing reverse exit in area %s.\n\r", exit->to_room->area->filename );
rev_exit->vnum = i;
}
}
}
/*
* translate the key
*/
if( exit->key != -1 )
{
new_vnum = find_translation( exit->key, r_area->r_obj );
if( new_vnum == NOT_FOUND )
continue;
exit->key = new_vnum;
}
}
}
}
void translate_objvals( CHAR_DATA * ch, AREA_DATA * area, RENUMBER_AREA * r_area, bool verbose )
{
int i, new_vnum;
OBJ_INDEX_DATA *obj;
for( i = area->low_o_vnum; i <= area->hi_o_vnum; i++ )
{
obj = get_obj_index( i );
if( !obj )
continue;
if( obj->item_type == ITEM_CONTAINER )
{
new_vnum = find_translation( obj->value[2], r_area->r_obj );
if( new_vnum != NOT_FOUND )
{
if( verbose )
pager_printf( ch, "... container %d; fixing objval2 (key vnum) %d -> %d\n\r", i, obj->value[2], new_vnum );
obj->value[2] = new_vnum;
}
else if( verbose )
pager_printf( ch, "... container %d; no need to fix.\n\r", i );
}
else if( obj->item_type == ITEM_SWITCH || obj->item_type == ITEM_LEVER ||
obj->item_type == ITEM_PULLCHAIN || obj->item_type == ITEM_BUTTON )
{
/*
* levers might have room vnum references in their objvals
*/
if( IS_SET( obj->value[0], TRIG_TELEPORT )
|| IS_SET( obj->value[0], TRIG_TELEPORTALL )
|| IS_SET( obj->value[0], TRIG_TELEPORTPLUS )
|| IS_SET( obj->value[0], TRIG_RAND4 )
|| IS_SET( obj->value[0], TRIG_RAND6 ) || IS_SET( obj->value[0], TRIG_DOOR ) )
{
new_vnum = find_translation( obj->value[1], r_area->r_room );
if( new_vnum != NOT_FOUND )
{
if( verbose )
pager_printf( ch, "... lever %d: fixing source room (%d -> %d)\n\r", i, obj->value[1], new_vnum );
obj->value[1] = new_vnum;
}
if( IS_SET( obj->value[0], TRIG_DOOR ) && IS_SET( obj->value[0], TRIG_PASSAGE ) )
{
new_vnum = find_translation( obj->value[2], r_area->r_room );
if( new_vnum != NOT_FOUND )
{
if( verbose )
pager_printf( ch, "... lever %d: fixing dest room (passage) (%d -> %d)\n\r", i, obj->value[2], new_vnum );
obj->value[2] = new_vnum;
}
}
}
}
}
}
void warn_progs( CHAR_DATA * ch, int low, int high, AREA_DATA * area, RENUMBER_AREA * r_area )
{
ROOM_INDEX_DATA *room;
OBJ_INDEX_DATA *obj;
MOB_INDEX_DATA *mob;
MPROG_DATA *mprog;
int i;
for( i = area->low_r_vnum; i <= area->hi_r_vnum; i++ )
{
room = get_room_index( i );
if( !room )
continue;
mprog = room->mudprogs;
while( mprog )
{
warn_in_prog( ch, low, high, "room", i, mprog, r_area );
mprog = mprog->next;
}
}
for( i = area->low_o_vnum; i <= area->hi_o_vnum; i++ )
{
obj = get_obj_index( i );
if( !obj )
continue;
mprog = obj->mudprogs;
while( mprog )
{
warn_in_prog( ch, low, high, "obj", i, mprog, r_area );
mprog = mprog->next;
}
}
for( i = area->low_m_vnum; i <= area->hi_m_vnum; i++ )
{
mob = get_mob_index( i );
if( !mob )
continue;
mprog = mob->mudprogs;
while( mprog )
{
warn_in_prog( ch, low, high, "mob", i, mprog, r_area );
mprog = mprog->next;
}
}
}
void warn_in_prog( CHAR_DATA * ch, int low, int high, char *where, int vnum, MPROG_DATA * mprog, RENUMBER_AREA * r_area )
{
char *p, *start_number, cTmp;
int num;
p = mprog->comlist;
while( *p )
{
if( isdigit( *p ) )
{
start_number = p;
while( isdigit( *p ) && *p )
p++;
cTmp = *p;
*p = 0;
num = atoi( start_number );
*p = cTmp;
if( num >= low && num <= high )
{
pager_printf( ch,
"Warning! %s prog in %s vnum %d might contain a reference to %d.\n\r(Translation: Room %d, Obj %d, Mob %d)\n\r",
mprog_type_to_name( mprog->type ), where, vnum, num, find_translation( num, r_area->r_room ),
find_translation( num, r_area->r_obj ), find_translation( num, r_area->r_mob ) );
}
if( *p == '\0' )
break;
}
p++;
}
}
void translate_reset( RESET_DATA * reset, RENUMBER_AREA * r_data )
/* this function translates a reset according to the renumber data in r_data */
{
/*
* a list based approach to fixing the resets. instead
* of having a bunch of several instances of very
* similar code, i just made this array that tells the
* code what to do. it's pretty straightforward
*/
char *action_table[] = { "Mm1r3", "Oo1r3", "Ho1", "Po1o3",
"Go1", "Eo1", "Dr1", "Rr1", NULL
};
char *p;
RENUMBER_DATA *r_table;
int *parg, new_vnum, i;
/*
* T is a special case
*/
if( reset->command == 'T' )
{
if( IS_SET( reset->extra, TRAP_ROOM ) )
r_table = r_data->r_room;
else if( IS_SET( reset->extra, TRAP_OBJ ) )
r_table = r_data->r_obj;
else
{
bug( "translate_reset: Invalid 'T' reset found.\n\r" );
return;
}
new_vnum = find_translation( reset->arg3, r_table );
if( new_vnum != NOT_FOUND )
reset->arg3 = new_vnum;
return;
}
/*
* B is another special case
*/
if( reset->command == 'B' )
{
bug( "translate_reset: B command found." );
if( ( reset->arg2 & BIT_RESET_TYPE_MASK ) == BIT_RESET_DOOR || ( reset->arg2 & BIT_RESET_TYPE_MASK ) == BIT_RESET_ROOM )
{
new_vnum = find_translation( reset->arg1, r_data->r_obj );
if( new_vnum != NOT_FOUND )
reset->arg1 = new_vnum;
}
return;
}
for( i = 0; action_table[i] != NULL; i++ )
{
if( reset->command == action_table[i][0] )
{
p = action_table[i] + 1;
while( *p )
{
if( *p == 'm' )
r_table = r_data->r_mob;
else if( *p == 'o' )
r_table = r_data->r_obj;
else if( *p == 'r' )
r_table = r_data->r_room;
else
{
bug( "translate_reset: Invalid action found in action table.\n\r" );
p += 2;
continue;
}
p++;
if( *p == '1' )
parg = &( reset->arg1 );
else if( *p == '2' )
parg = &( reset->arg2 );
else if( *p == '3' )
parg = &( reset->arg3 );
else
{
bug( "translate_reset: Invalid argument number found in action table.\n\r" );
p++;
continue;
}
p++;
new_vnum = find_translation( *parg, r_table );
if( new_vnum != NOT_FOUND )
*parg = new_vnum;
}
return;
}
}
if( action_table[i] == NULL )
bug( "translate_reset: Invalid reset '%c' found.\n\r", reset->command );
}
int find_translation( int vnum, RENUMBER_DATA * r_data )
/* returns the new vnum for the old vnum "vnum" according to the info in
* r_data
*/
{
RENUMBER_DATA *r_temp;
for( r_temp = r_data; r_temp; r_temp = r_temp->next )
{
if( r_temp->old_vnum == vnum )
return r_temp->new_vnum;
}
return NOT_FOUND;
}
AREA_DATA *find_area( char *filename, bool * p_is_proto )
/* simply returns a pointer to a "filename" or NULL if no such area. stores
TRUE in *p_is_proto if the area is proto */
{
bool found;
AREA_DATA *area;
found = FALSE;
for( area = first_area; area; area = area->next )
{
if( !str_cmp( area->filename, filename ) )
{
found = TRUE;
break;
}
}
if( found )
{
*p_is_proto = FALSE;
return area;
}
for( area = first_build; area; area = area->next )
{
if( !str_cmp( area->filename, filename ) )
{
found = TRUE;
break;
}
}
if( found )
{
*p_is_proto = TRUE;
return area;
}
else
return NULL;
}