/*___________________________________________________________________________*
)()( DalekenMUD 1.12 (C) 2000 )()(
`][' by Martin Thomson, Lee Brooks, `]['
|| Ken Herbert and David Jacques ||
|| ----------------------------------------------------------------- ||
|| Envy Diku Mud improvements copyright (C) 1994 by Michael Quan, ||
|| David Love, Guilherme 'Willie' Arnold, and Mitchell Tse. ||
|| Merc 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. ||
|| ----------------------------------------------------------------- ||
|| Any use of this software must follow the licenses of the ||
|| creators. Much time and thought has gone into this software and ||
|| you are benefitting. We hope that you share your changes too. ||
|| What goes around, comes around. ||
|| ----------------------------------------------------------------- ||
|| olc_act.c ||
|| Code for editing areas, rooms and mobile and object indexes. ||
*_/<>\_________________________________________________________________/<>\_*/
#include <limits.h> /* OLC 1.1b */
#include "mud.h"
#include "olc.h"
#include "event.h"
#if defined( unix )
#include <unistd.h>
#endif
#ifndef INT_MAX
#define INT_MAX 65536
#endif
extern const int rev_dir[];
void junk_old_religion args( ( AREA_DATA *pArea ) );
int edit_mpadd args( ( CHAR_DATA *ch, MPROG_DATA **top,
const char *argument, int *allowed ) );
bool edit_mpdelete args( ( CHAR_DATA *ch, MPROG_DATA **top,
const char *argument ) );
bool edit_mpedit args( ( CHAR_DATA *ch, MPROG_DATA *mprg,
const char *argument ) );
void edit_mpshow args( ( CHAR_DATA *ch, MPROG_DATA *mprg,
const char *argument ) );
void edit_mpshow( CHAR_DATA *ch, MPROG_DATA *mprg, const char *argument )
{
BUFFER *buf = buffer_new( MAX_STRING_LENGTH );
int num = 0;
int argnum = -1;
bool sh = FALSE;
if( argument[0] != '\0' )
{
if( is_number( argument ) )
{
argnum = atoi( argument );
}
else if( !str_cmp( argument, "short" ) )
{
sh = TRUE;
}
else
{
send_to_char( "Syntax: mpshow [number/'short']\n\r", ch );
return;
}
}
if( !mprg )
{
send_to_char( "Edit: There are no MudProgs here.\n\r", ch );
return;
}
for( ; mprg; mprg = mprg->next, num++ )
{
if( argnum >= 0 && num != argnum )
continue;
bprintf( buf, "&c<%3d> &y%-20s", num,
flag_string( mud_prog_flags, &mprg->type ) );
bprintf( buf, "&garg-&b[&y%s&b]&n\n\r", mprg->arglist );
if( sh )
continue;
bprintf( buf, "&w%s&n\n\r", mprg->comlist );
if( argnum >= 0 )
break;
}
if( argnum >= 0 && !mprg )
send_to_char( "Edit: MudProg not found.\n\r", ch );
else
send_to_char( buf->data, ch );
buffer_free( buf );
return;
}
int edit_mpadd( CHAR_DATA *ch, MPROG_DATA **top, const char *argument,
int *allowed )
{
MPROG_DATA *mprg, *mprg2;
MPROG_GLOBAL *glob;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
int num;
int type, realtype;
int i;
if( !ch->pcdata || ch->pcdata->security < 6 )
{
send_to_char( "You aren't authorised to use mudprogs.\n\r", ch );
return PROG_ERROR;
}
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if( arg1[0] == '\0' || !is_number( arg1 )
|| arg2[0] == '\0' || argument[0] == '\0' )
{
send_to_char( "Syntax: mpadd <#num> <event> <args>.\n\r", ch );
return PROG_ERROR;
}
num = atoi( arg1 );
if( flag_value( &type, mud_prog_flags, arg2 ) == NO_FLAG )
{
send_to_char( "Edit: invalid mudprog event '? MPROG'\n\r", ch );
return PROG_ERROR;
}
/*
* Some extensive checking is required for a global style program.
*/
if( type == GLOBAL_PROG )
{
if( !is_number( argument ) )
{
send_to_char( "For a global prog, please specify a vnum.\n\r",
ch );
return PROG_ERROR;
}
if( !( glob = get_global_mudprog_index( atoi( argument ) ) ) )
{
send_to_char( "That global prog doesn't exist.\n\r",
ch );
return PROG_ERROR;
}
if( !ch->desc )
return PROG_ERROR;
if( !str_cmp( ch->desc->interpreter->name, "OEdit" )
&& !IS_SET( glob->allowed, MPROG_GLOBAL_OBJ ) )
{
send_to_char( "That prog isn't designed for objects.\n\r", ch );
return PROG_ERROR;
}
else if( !str_cmp( ch->desc->interpreter->name, "MEdit" )
&& !IS_SET( glob->allowed, MPROG_GLOBAL_MOB ) )
{
send_to_char( "That prog isn't designed for mobs.\n\r", ch );
return PROG_ERROR;
}
else if( !str_cmp( ch->desc->interpreter->name, "REdit" )
&& !IS_SET( glob->allowed, MPROG_GLOBAL_ROOM ) )
{
send_to_char( "That prog isn't designed for rooms.\n\r", ch );
return PROG_ERROR;
}
realtype = glob->type;
}
else
realtype = type;
/*
* Check that the type of prog is allowed.
*/
for( i = 0; allowed[i] != -1; ++i )
if( allowed[i] == realtype )
break;
if( allowed[i] == -1 )
{
send_to_char( "Edit: that MudProg is used in a different context.\n\r",
ch );
send_to_char( "You can use:", ch );
for( i = 0; allowed[i] != -1; ++i )
charprintf( ch, " %s", flag_string( mud_prog_flags, &allowed[i] ) );
send_to_char( ".\n\r", ch );
return PROG_ERROR;
}
/*
* Create a new prog.
*/
mprg = new_mprog( );
mprg->type = type;
mprg->arglist = str_dup( argument );
if( num <= 0 || !*top )
{
mprg->next = *top;
*top = mprg;
}
else
{
i = 0;
for( mprg2 = *top; mprg2->next; mprg2 = mprg2->next )
{
if( ++i == num )
break;
}
mprg->next = mprg2->next;
mprg2->next = mprg;
}
if( mprg->type == GLOBAL_PROG )
send_to_char( "Global programs don't require any code, but feel\n\r"
"free to add any comments if you want.\n\r", ch );
string_edit( ch, &mprg->comlist );
return realtype;
}
bool edit_mpdelete( CHAR_DATA *ch, MPROG_DATA **top, const char *argument )
{
MPROG_DATA *mprg;
MPROG_DATA *mprg_next;
char mpstr[MAX_STRING_LENGTH];
int value;
int cnt = 0;
one_argument( argument, mpstr );
if( !ch->pcdata || ch->pcdata->security < 6 )
{
send_to_char( "You aren't authorised to use mudprogs.\n\r", ch );
return FALSE;
}
if( !is_number( mpstr ) || mpstr[0] == '\0' )
{
send_to_char( "Syntax: mpdelete [#number]\n\r", ch );
return FALSE;
}
value = atoi( mpstr );
if( value < 0 )
{
send_to_char( "Edit: Only non-negative MudProg-numbers allowed.\n\r",
ch );
return FALSE;
}
if( !( mprg = *top ) )
{
send_to_char( "Edit: Non-existant MudProg.\n\r", ch );
return FALSE;
}
if( value == 0 ) /* First case: Remove first affect */
{
mprg = *top;
*top = mprg->next;
mprg->next = NULL;
free_mprog( mprg );
}
else /* Affect to remove is not the first */
{
while( ( mprg_next = mprg->next ) && ( ++cnt < value ) )
mprg = mprg_next;
if( mprg_next ) /* See if it's the next affect */
{
mprg->next = mprg_next->next;
mprg_next->next = NULL;
free_mprog( mprg_next );
}
else /* Doesn't exist */
{
send_to_char( "Edit: No such MudProg.\n\r", ch );
return FALSE;
}
}
send_to_char( "Edit: MudProg removed.\n\r", ch );
return TRUE;
}
bool edit_mpedit( CHAR_DATA *ch, MPROG_DATA *mprg, const char *argument )
{
char arg[MAX_INPUT_LENGTH];
int num;
if( !ch->pcdata || ch->pcdata->security < 6 )
{
send_to_char( "You aren't authorised to use mudprogs.\n\r", ch );
return FALSE;
}
argument = one_argument( argument, arg );
if( arg[0] == '\0' || !is_number( arg ) )
{
send_to_char( "Syntax: mprog <number> - edit body\n\r", ch );
send_to_char( "Syntax: mprog <number> [arguments] - args\n\r", ch );
return FALSE;
}
num = atoi( arg );
for( ; num && mprg; mprg = mprg->next )
num--;
if( num || !mprg )
{
send_to_char( "That one doesn't exist.\n\r", ch );
return FALSE;
}
if( argument[0] == '\0' )
string_edit( ch, &mprg->comlist );
else
{
free_string( mprg->arglist );
mprg->arglist = str_dup( argument );
send_to_char( "Argument to MudProg changed.\n\r", ch );
}
return TRUE;
}
bool edit_gmplist( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
int mor = MPROG_GLOBAL_MOB|MPROG_GLOBAL_OBJ|MPROG_GLOBAL_ROOM;
int i;
BUFFER *buf = buffer_new( MAX_INPUT_LENGTH );
MPROG_GLOBAL *mprg;
pArea = get_editing_area( ch );
if( argument[0] != '\0' )
mor = flag_value( NULL, mor_type_flags, argument );
for( i = 0; i < MPROG_GLOBAL_HASH; ++i )
for( mprg = global_progs[i]; mprg; mprg = mprg->next )
{
if( mprg->area == pArea && IS_SET( mprg->allowed, mor ) )
{
bprintf( buf, "&b[&r%5d&b]&g %s: %s\n\r", mprg->vnum,
flag_string( mud_prog_flags, &mprg->allowed ),
mprg->arglist );
}
}
send_to_char( buf->data, ch );
buffer_free( buf );
return FALSE;
}
bool redit_mlist( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMobIndex;
AREA_DATA *pArea;
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH * 2];
char arg[MAX_INPUT_LENGTH];
bool fAll, found;
int vnum;
int col = 0;
one_argument( argument, arg );
if( arg[0] == '\0' )
{
send_to_char( "Syntax: mlist <[all]/name>\n\r", ch );
return FALSE;
}
pArea = ch->in_room->area;
buf1[0] = '\0';
fAll = !str_cmp( arg, "all" );
found = FALSE;
for( vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++ )
{
if( ( pMobIndex = get_mob_index( vnum ) )
&& pMobIndex->area == pArea )
{
if( fAll || is_name( arg, pMobIndex->name ) )
{
char tmp[MAX_INPUT_LENGTH];
found = TRUE;
sprintf( buf, "&b[&r%5d&b] &g%s ",
pMobIndex->vnum,
colour_strpad( tmp, capitalize( pMobIndex->short_descr ), 16 ) );
strcat( buf1, buf );
if( ++col % 3 == 0 )
strcat( buf1, "&n\n\r" );
}
}
}
if( !found )
{
send_to_char( "Mobile(s) not found in this area.\n\r", ch );
return FALSE;
}
if( col % 3 != 0 )
strcat( buf1, "\n\r" );
send_to_char( buf1, ch );
return FALSE;
}
bool redit_olist( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObjIndex;
AREA_DATA *pArea;
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH * 2];
char arg[MAX_INPUT_LENGTH];
bool fAll, found;
int vnum;
int col = 0;
one_argument( argument, arg );
if( arg[0] == '\0' )
{
send_to_char( "Syntax: olist <[all]/name/item_type>\n\r", ch );
return FALSE;
}
pArea = ch->in_room->area;
buf1[0] = '\0';
fAll = !str_cmp( arg, "all" );
found = FALSE;
for( vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++ )
{
if( ( pObjIndex = get_obj_index( vnum ) )
&& pObjIndex->area == pArea )
{
if( fAll || is_name( arg, pObjIndex->name )
|| flag_value( NULL, type_flags, arg ) == pObjIndex->item_type )
{
char tmp[MAX_INPUT_LENGTH];
found = TRUE;
sprintf( buf, "&b[&r%5d&b]&g %s ",
pObjIndex->vnum,
colour_strpad( tmp, capitalize( pObjIndex->short_descr ), 16 ) );
strcat( buf1, buf );
if( ++col % 3 == 0 )
strcat( buf1, "&n\n\r" );
}
}
}
if( !found )
{
send_to_char( "Object(s) not found in this area.\n\r", ch );
return FALSE;
}
if( col % 3 != 0 )
strcat( buf1, "\n\r" );
send_to_char( buf1, ch );
return FALSE;
}
bool redit_mshow( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
int value;
if( argument[0] == '\0' )
{
send_to_char( "Syntax: mshow <vnum>\n\r", ch );
return FALSE;
}
if( !is_number( argument ) )
{
send_to_char( "REdit: Please specify an mobile vnum.\n\r", ch );
return FALSE;
}
value = atoi( argument );
if( !( pMob = get_mob_index( value ) ) )
{
send_to_char( "REdit: That mobile does not exist.\n\r", ch );
return FALSE;
}
ch->desc->pEdit = (void *)pMob;
medit_show( ch, argument );
ch->desc->pEdit = (void *)ch->in_room;
return FALSE;
}
bool redit_oshow( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
int value;
if( argument[0] == '\0' )
{
send_to_char( "Syntax: oshow <vnum>\n\r", ch );
return FALSE;
}
if( !is_number( argument ) )
{
send_to_char( "REdit: Please specify an object vnum.\n\r", ch );
return FALSE;
}
value = atoi( argument );
if( !( pObj = get_obj_index( value ) ) )
{
send_to_char( "REdit: That object does not exist.\n\r", ch );
return FALSE;
}
ch->desc->pEdit = (void *)pObj;
oedit_show( ch, argument );
ch->desc->pEdit = (void *)ch->in_room;
return FALSE;
}
/*****************************************************************************
Name: check_range( lower vnum, upper vnum )
Purpose: Ensures the range spans only one area.
Called by: aedit_vnum( olc_act.c ).
****************************************************************************/
bool check_range( int lower, int upper )
{
AREA_DATA *pArea;
int cnt = 0;
for( pArea = area_first; pArea; pArea = pArea->next )
{
/*
* lower < area < upper
*/
if( ( lower <= pArea->lvnum && upper >= pArea->lvnum )
|| ( upper >= pArea->uvnum && lower <= pArea->uvnum ) )
cnt++;
if( cnt > 1 )
return FALSE;
}
return TRUE;
}
AREA_DATA *get_vnum_area( int vnum )
{
AREA_DATA *pArea;
for( pArea = area_first; pArea; pArea = pArea->next )
{
if( vnum >= pArea->lvnum
&& vnum <= pArea->uvnum )
return pArea;
}
return 0;
}
/*
* Area Editor Functions.
*/
bool aedit_show( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
BUFFER *buf = buffer_new( MAX_STRING_LENGTH );
EDIT_AREA( ch, pArea );
bprintf( buf, "&gDescription:\n\r&w%s", pArea->description );
bprintf( buf, "&b[&r%5d&b]&g Name: &b[&c%s&b]&n\n\r",
pArea->vnum, pArea->name );
bprintf( buf, "&gPlane: &b[&c%s&b]&n\n\r",
pArea->plane ? pArea->plane->name : "none" );
bprintf( buf, "&gFile: &b[&c%s&b]&N\n\r", pArea->filename );
bprintf( buf, "&gVnums: &b[&c%d&b-&c%d&b]&n\n\r",
pArea->lvnum, pArea->uvnum );
bprintf( buf, "&gRecall: &b[&c%5d&b] &y%s&n\n\r", pArea->recall,
get_room_index( pArea->recall )
? get_room_index( pArea->recall )->name : "none" );
bprintf( buf, "&gLevels: &b[&c%d&b-&c%d &b(&c%d&b)]&n\n\r",
pArea->min, pArea->max, pArea->ave );
bprintf( buf, "&gAve Temp: &b[&c%5d&b]"
"&g Age: &b[&c%d&b]&n\n\r",
pArea->ave_temp, pArea->age );
bprintf( buf, "&gPlayers: &b[&c%5d&b]"
"&g Mobiles: &b[&c%d&b]&n\n\r",
pArea->nplayer, pArea->nmobile );
bprintf( buf, "&gSecurity: &b[&c%5d&b]"
"&g Builders: &b[&c%s&b]&n\n\r",
pArea->security, pArea->builders );
bprintf( buf, "&gEconomy: &b[&y%8d gold&b]&n\n\r",
pArea->economy );
if( pArea->order )
{
bprintf( buf, "&gOrder: &b[&c%s&b]&n %s&n\n\r",
pArea->order->name, pArea->order->display_name );
bprintf( buf, "&g Religion: &b[&c%s&b]&n %s&n\n\r",
pArea->order->religion->name,
pArea->order->religion->display_name );
bprintf( buf, "&g Token Room: &b[&c%5d&b] &y%s&n\n\r",
pArea->token_room,
get_room_index( pArea->token_room )
? get_room_index( pArea->token_room )->name : "None" );
}
if( pArea->repop && pArea->repop[0] != '\0' )
bprintf( buf, "&gRepop:&n %s", pArea->repop );
bprintf( buf, "&gFlags: &b[&c%s&b]&n\n\r",
flag_string( area_flags, &pArea->area_flags ) );
send_to_char( buf->data, ch );
buffer_free( buf );
return FALSE;
}
bool aedit_reset( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
int save_player;
EDIT_AREA( ch, pArea );
save_player = pArea->nplayer;
pArea->nplayer = 0;
reset_area( pArea );
pArea->nplayer = save_player;
send_to_char( "Area reset.\n\r", ch );
return FALSE;
}
void clear_room( ROOM_INDEX_DATA * room )
{
OBJ_DATA *obj, *obj_next;
CHAR_DATA *victim, *vnext;
for( victim = room->people; victim; victim = vnext )
{
vnext = victim->next_in_room;
if( victim->deleted )
continue;
if( IS_NPC( victim ) )
extract_char( victim, TRUE );
}
for( obj = room->contents; obj; obj = obj_next )
{
obj_next = obj->next_content;
if( obj->deleted )
continue;
if( obj->item_type != ITEM_CORPSE_PC )
extract_obj( obj );
}
return;
}
bool aedit_clear( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
ROOM_INDEX_DATA *pRoom;
int vnum;
EDIT_AREA( ch, pArea );
for( vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++ )
{
if( ( pRoom = get_room_index( vnum ) ) )
clear_room( pRoom );
}
send_to_char( "Area cleared.\n\r", ch );
return FALSE;
}
bool aedit_create( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
if( !ch->pcdata || ch->pcdata->security < 5 )
{
send_to_char( "You aren't authorised to create areas.\n\r", ch );
return FALSE;
}
if( top_area >= INT_MAX ) /* OLC 1.1b */
{
send_to_char( "We're out of vnums for new areas.\n\r", ch );
return FALSE;
}
if( IS_NPC( ch ) || ch->pcdata->security < 3 )
{
send_to_char( "You aren't allowed to create new areas, we don't trust you :p\n\r", ch );
return FALSE;
}
pArea = new_area( );
area_last->next = pArea;
area_last = pArea; /* Thanks, Walker. */
ch->desc->pEdit = (void *)pArea;
wiznetf( ch, WIZ_CREATE, get_trust( ch ), "%s has just created a new area!",
ch->name );
SET_BIT( pArea->area_flags, AREA_ADDED );
send_to_char( "Area Created.\n\r", ch );
return TRUE; /* OLC 1.1b */
}
bool aedit_name( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
EDIT_AREA( ch, pArea );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: name <$name>\n\r", ch );
return FALSE;
}
free_string( pArea->name );
pArea->name = str_dup( argument );
send_to_char( "Name set.\n\r", ch );
return TRUE;
}
bool aedit_plane( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
EDIT_AREA( ch, pArea );
if( ch->pcdata->security <= 5 )
{
send_to_char( "You have insufficient security.\n\r", ch );
return FALSE;
}
if( argument[0] == '\0' )
{
send_to_char( "Syntax: plane <$plane>\n\r", ch );
return FALSE;
}
if( !plane_lookup( argument ) )
{
send_to_char( "AEdit: No such plane.\n\r", ch );
return FALSE;
}
pArea->plane = plane_lookup( argument );
send_to_char( "Plane set.\n\r", ch );
return TRUE;
}
bool aedit_file( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
char file[MAX_STRING_LENGTH];
int i, length;
FILE *fp;
EDIT_AREA( ch, pArea );
first_arg( argument, file, TRUE ); /* Forces Lowercase */
if( argument[0] == '\0' )
{
send_to_char( "Syntax: filename <$file>\n\r", ch );
return FALSE;
}
/*
* Simple Syntax Check.
*/
length = strlen( argument );
if( length > 8 )
{
send_to_char( "No more than eight characters allowed.\n\r", ch );
return FALSE;
}
/*
* Allow only letters and numbers.
*/
for( i = 0; i < length; i++ )
{
if( !isalnum( file[i] ) )
{
send_to_char( "Only letters and numbers are valid.\n\r", ch );
return FALSE;
}
}
strcat( file, ".are" );
if( !( fp = open_file( file, "a+", TRUE ) ) )
{
send_to_char( "Sorry, that file cannot exist.\n\r", ch );
return FALSE;
}
close_file( fp );
log_string( "%s changing file name from %s to %s.",
ch->name, pArea->filename, file );
#if defined( unix )
wiznetf( ch, WIZ_DEBUG, L_MAS, "Unlinking file %s.", pArea->filename );
unlink( pArea->filename );
#else
wiznetf( ch, WIZ_DEBUG, L_MAS, "Please delete old file (%s).",
pArea->filename );
#endif
free_string( pArea->filename );
pArea->filename = str_dup( file );
save_area( pArea );
send_to_char( "Filename set.\n\r", ch );
return TRUE;
}
void junk_old_religion( AREA_DATA *pArea )
{
RELIGION_DATA *pReligion;
OBJ_INDEX_DATA *pObj;
OBJ_DATA *obj;
ROOM_INDEX_DATA *pRoom;
if( !( pReligion = pArea->order->religion ) )
return;
pRoom = get_room_index( pArea->token_room );
pObj = get_obj_index( pReligion->token );
if( pRoom && pObj )
for( obj = pRoom->contents; obj; obj = obj->next_content )
if( !obj->deleted && obj->pIndexData == pObj )
extract_obj( obj );
pArea->order = NULL;
pArea->token_room = -1;
return;
}
/*
* Nifty little formatting function.
*/
void show_range( CHAR_DATA *ch, int low, int high, int *pos )
{
char buf[MAX_INPUT_LENGTH];
char buf1[MAX_INPUT_LENGTH];
buf1[0] = '\0';
if( high > low )
sprintf( buf, "%d-%d", low, high );
else
sprintf( buf, "%d", low );
if( *pos < 0 ) /* initial position */
{
*pos = strlen( buf ) + 4;
}
else if( *pos + strlen( buf ) > 73 ) /* end of line */
{
strcat( buf1, ",&n\n\r &y" );
*pos = strlen( buf ) + 4;
}
else /* normal increment */
{
strcat( buf1, ", " );
*pos += strlen( buf ) + 2;
}
strcat( buf1, buf );
send_to_char( buf1, ch );
}
bool aedit_count( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
ROOM_INDEX_DATA *pRoom;
OBJ_INDEX_DATA *pObj;
MOB_INDEX_DATA *pMob;
bool unused = FALSE;
int start, i, pos;
EDIT_AREA( ch, pArea );
if( UPPER( argument[0] ) == 'U' )
unused = TRUE;
charprintf(
ch, "&gVnums %sused so far in this area from &b[&c%d&b-&c%d&b]&n\n\r",
( unused ) ? "un" : "", pArea->lvnum, pArea->uvnum );
send_to_char( "&mRooms:\n\r &y", ch );
start = -1;
pos = -1;
for( i = pArea->lvnum; i <= pArea->uvnum; ++i )
{
pRoom = get_room_index( i );
if( ( unused && !pRoom )
|| ( !unused && pRoom && pRoom->area == pArea ) )
{
if( start < 0 )
start = i;
}
else
{
if( start > 0 )
show_range( ch, start, i - 1, &pos );
start = -1;
}
}
if( start > 0 )
show_range( ch, start, i - 1, &pos );
send_to_char( "&n\n\r&mMobiles:\n\r &y", ch );
start = -1;
pos = -1;
for( i = pArea->lvnum; i <= pArea->uvnum; ++i )
{
pMob = get_mob_index( i );
if( ( unused && !pMob )
|| ( !unused && pMob && pMob->area == pArea ) )
{
if( start < 0 )
start = i;
}
else
{
if( start > 0 )
show_range( ch, start, i - 1, &pos );
start = -1;
}
}
if( start > 0 )
show_range( ch, start, i - 1, &pos );
send_to_char( "&n\n\r&mObjects:\n\r &y", ch );
start = -1;
pos = -1;
for( i = pArea->lvnum; i <= pArea->uvnum; ++i )
{
pObj = get_obj_index( i );
if( ( unused && !pObj )
|| ( !unused && pObj && pObj->area == pArea ) )
{
if( start < 0 )
start = i;
}
else
{
if( start > 0 )
show_range( ch, start, i - 1, &pos );
start = -1;
}
}
if( start > 0 )
show_range( ch, start, i - 1, &pos );
send_to_char( "&n\n\r", ch );
return FALSE;
}
bool aedit_order( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
CLAN_DATA *pClan;
char room[MAX_INPUT_LENGTH];
ROOM_INDEX_DATA *pRoom;
int value;
OBJ_INDEX_DATA *pObj;
OBJ_DATA *obj;
if( get_trust( ch ) < L_MAS )
{
send_to_char( "You aren't allowed to do this.\n\r", ch );
return FALSE;
}
EDIT_AREA( ch, pArea );
if( !str_cmp( argument, "none" ) )
{
junk_old_religion( pArea );
send_to_char( "Ok.\n\r", ch );
return TRUE;
}
argument = one_argument( argument, room );
if( !is_number( room ) || room[0] == '\0' )
{
send_to_char( "Syntax: order <#tokenrm> <$order>\n\r", ch );
send_to_char( "Syntax: order none\n\r", ch );
return FALSE;
}
value = atoi( room );
if( !( pRoom = get_room_index( value ) ) )
{
send_to_char( "AEdit: Room vnum does not exist.\n\r", ch );
return FALSE;
}
if( !( pClan = clan_lookup( argument ) )
|| pClan->clan_type != CLAN_ORDER )
{
send_to_char( "AEdit: Religious order not found.\n\r", ch );
return FALSE;
}
if( !( pObj = get_obj_index( pClan->religion->token ) ) )
{
send_to_char( "AEdit: Their religion has no token.\n\r", ch );
return FALSE;
}
junk_old_religion( pArea );
obj = create_object( pObj, 0 );
obj_to_room( obj, pRoom );
REMOVE_BIT( obj->extra_flags, ITEM_TAKE );
obj->item_type = ITEM_CORPSE_NPC; /* prevent accidental purge */
strip_events( &obj->events, evn_obj_decay );
strip_events( &obj->events, evn_imp_grab );
pArea->order = pClan;
pArea->token_room = value;
send_to_char( "Religion set.\n\r", ch );
return TRUE;
}
bool aedit_age( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
char age[MAX_STRING_LENGTH];
EDIT_AREA( ch, pArea );
one_argument( argument, age );
if( !is_number( age ) || age[0] == '\0' || atoi( age ) < 3 )
{
send_to_char( "Syntax: age <#age>\n\r", ch );
send_to_char( "Note: age must be at least 3 minutes.\n\r", ch );
return FALSE;
}
pArea->age = atoi( age );
send_to_char( "Age set.\n\r", ch );
return TRUE;
}
bool aedit_economy( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
char economy[MAX_STRING_LENGTH];
EDIT_AREA( ch, pArea );
one_argument( argument, economy );
if( !is_number( economy ) || economy[0] == '\0' )
{
send_to_char( "Syntax: economy <#economy>\n\r", ch );
return FALSE;
}
pArea->economy = atoi( economy );
send_to_char( "Economy set.\n\r", ch );
return TRUE;
}
bool aedit_recall( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
char room[MAX_STRING_LENGTH];
int value;
EDIT_AREA( ch, pArea );
one_argument( argument, room );
if( !is_number( argument ) || argument[0] == '\0' )
{
send_to_char( "Syntax: recall <#rvnum>\n\r", ch );
return FALSE;
}
value = atoi( room );
if( !get_room_index( value ) )
{
send_to_char( "AEdit: Room vnum does not exist.\n\r", ch );
return FALSE;
}
pArea->recall = value;
send_to_char( "Recall set.\n\r", ch );
return TRUE;
}
bool aedit_repop( CHAR_DATA *ch, const char *argument )
{
char buf[MAX_STRING_LENGTH];
AREA_DATA *pArea;
EDIT_AREA( ch, pArea );
if( argument[0] == '\0' )
{
free_string( pArea->repop );
pArea->repop = str_dup( "" );
send_to_char( "AEdit: Area repop message cleared.\n\r", ch );
return TRUE;
}
sprintf( buf, "%s&n\n\r", argument );
free_string( pArea->repop );
pArea->repop = str_dup( buf );
pArea->repop[0] = UPPER( pArea->repop[0] );
send_to_char( "AEdit: Area Repop message set.\n\r", ch );
return TRUE;
}
bool aedit_temp( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
char room[MAX_STRING_LENGTH];
int value;
EDIT_AREA( ch, pArea );
one_argument( argument, room );
if( !is_number( argument ) || argument[0] == '\0' )
{
send_to_char( "Syntax: temp <#temperature>\n\r", ch );
return FALSE;
}
value = URANGE( -250, atoi( room ), 250 );
pArea->ave_temp = value;
send_to_char( "Average area temperature set.\n\r", ch );
return TRUE;
}
bool aedit_security( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
char sec[MAX_STRING_LENGTH];
char buf[MAX_STRING_LENGTH];
int value;
EDIT_AREA( ch, pArea );
one_argument( argument, sec );
if( !is_number( sec ) || sec[0] == '\0' )
{
send_to_char( "Syntax: security <#level>\n\r", ch );
return FALSE;
}
value = atoi( sec );
if( value > ch->pcdata->security + 1 || value < 0 )
{
if( ch->pcdata->security != 0 )
{
sprintf( buf, "Security is 0-%d.\n\r", ch->pcdata->security + 1 );
send_to_char( buf, ch );
}
else
send_to_char( "Security is 0 only.\n\r", ch );
return FALSE;
}
pArea->security = value;
send_to_char( "Security set.\n\r", ch );
return TRUE;
}
bool aedit_builder( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
char name[MAX_STRING_LENGTH];
char buf[MAX_STRING_LENGTH];
EDIT_AREA( ch, pArea );
one_argument( argument, name );
if( name[0] == '\0' )
{
send_to_char( "Syntax: builder <$name> -toggles builder\n\r", ch );
send_to_char( "Syntax: builder All -allows everyone\n\r", ch );
return FALSE;
}
name[0] = UPPER( name[0] );
if( str_str( pArea->builders, name ) != '\0' )
{
string_replace( &pArea->builders, name, "\0", FALSE );
pArea->builders = string_unpad( pArea->builders );
if( pArea->builders[0] == '\0' )
{
free_string( pArea->builders );
pArea->builders = str_dup( "None" );
}
send_to_char( "Builder removed.\n\r", ch );
}
else
{
buf[0] = '\0';
if( str_str( pArea->builders, "None" ) != '\0' )
{
string_replace( &pArea->builders, "None", "\0", FALSE );
pArea->builders = string_unpad( pArea->builders );
}
if( pArea->builders[0] != '\0' )
{
strcat( buf, pArea->builders );
strcat( buf, " " );
}
strcat( buf, name );
free_string( pArea->builders );
pArea->builders = string_proper( str_dup( buf ) );
send_to_char( "Builder added.\n\r", ch );
}
return TRUE;
}
bool aedit_desc( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
EDIT_AREA( ch, pArea );
if( argument[0] == '\0' )
{
string_edit( ch, &pArea->description );
return TRUE;
}
send_to_char( "Syntax: desc - string editor\n\r", ch );
return FALSE;
}
bool aedit_vnum( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
char lower[MAX_STRING_LENGTH];
char upper[MAX_STRING_LENGTH];
int ilower;
int iupper;
EDIT_AREA( ch, pArea );
argument = one_argument( argument, lower );
one_argument( argument, upper );
if( !is_number( lower ) || lower[0] == '\0'
|| !is_number( upper ) || upper[0] == '\0' )
{
send_to_char( "Syntax: vnum <#lower> <#upper>\n\r", ch );
return FALSE;
}
if( ( ilower = atoi( lower ) ) > ( iupper = atoi( upper ) ) )
{
send_to_char( "AEdit: Upper must be larger then lower.\n\r", ch );
return FALSE;
}
/* OLC 1.1b */
if( ilower <= 0 || ilower >= INT_MAX || iupper <= 0 || iupper >= INT_MAX )
{
char output[MAX_STRING_LENGTH];
sprintf( output, "AEdit: vnum must be between 0 and %d.\n\r", INT_MAX );
send_to_char( output, ch );
return FALSE;
}
if( !check_range( ilower, iupper ) )
{
send_to_char( "AEdit: Range must include only this area.\n\r", ch );
return FALSE;
}
if( get_vnum_area( ilower )
&& get_vnum_area( ilower ) != pArea )
{
send_to_char( "AEdit: Lower vnum already assigned.\n\r", ch );
return FALSE;
}
pArea->lvnum = ilower;
send_to_char( "Lower vnum set.\n\r", ch );
if( get_vnum_area( iupper )
&& get_vnum_area( iupper ) != pArea )
{
send_to_char( "AEdit: Upper vnum already assigned.\n\r", ch );
return TRUE; /* The lower value has been set. */
}
pArea->uvnum = iupper;
send_to_char( "Upper vnum set.\n\r", ch );
return TRUE;
}
bool aedit_lvnum( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
char lower[MAX_STRING_LENGTH];
int ilower;
int iupper;
EDIT_AREA( ch, pArea );
one_argument( argument, lower );
if( !is_number( lower ) || lower[0] == '\0' )
{
send_to_char( "Syntax: lvnum <#lower>\n\r", ch );
return FALSE;
}
if( ( ilower = atoi( lower ) ) > ( iupper = pArea->uvnum ) )
{
send_to_char( "AEdit: Value must be less than the uvnum.\n\r", ch );
return FALSE;
}
/* OLC 1.1b */
if( ilower <= 0 || ilower >= INT_MAX || iupper <= 0 || iupper >= INT_MAX )
{
char output[MAX_STRING_LENGTH];
sprintf( output, "AEdit: vnum must be between 0 and %d.\n\r", INT_MAX );
send_to_char( output, ch );
return FALSE;
}
if( !check_range( ilower, iupper ) )
{
send_to_char( "AEdit: Range must include only this area.\n\r", ch );
return FALSE;
}
if( get_vnum_area( ilower )
&& get_vnum_area( ilower ) != pArea )
{
send_to_char( "AEdit: Lower vnum already assigned.\n\r", ch );
return FALSE;
}
pArea->lvnum = ilower;
send_to_char( "Lower vnum set.\n\r", ch );
return TRUE;
}
bool aedit_uvnum( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
char upper[MAX_STRING_LENGTH];
int ilower;
int iupper;
EDIT_AREA( ch, pArea );
one_argument( argument, upper );
if( !is_number( upper ) || upper[0] == '\0' )
{
send_to_char( "Syntax: uvnum <#upper>\n\r", ch );
return FALSE;
}
if( ( ilower = pArea->lvnum ) > ( iupper = atoi( upper ) ) )
{
send_to_char( "AEdit: Upper must be larger then lower.\n\r", ch );
return FALSE;
}
/* OLC 1.1b */
if( ilower <= 0 || ilower >= INT_MAX || iupper <= 0 || iupper >= INT_MAX )
{
char output[MAX_STRING_LENGTH];
sprintf( output, "AEdit: vnum must be between 0 and %d.\n\r", INT_MAX );
send_to_char( output, ch );
return FALSE;
}
if( !check_range( ilower, iupper ) )
{
send_to_char( "AEdit: Range must include only this area.\n\r", ch );
return FALSE;
}
if( get_vnum_area( iupper )
&& get_vnum_area( iupper ) != pArea )
{
send_to_char( "AEdit: Upper vnum already assigned.\n\r", ch );
return FALSE;
}
pArea->uvnum = iupper;
send_to_char( "Upper vnum set.\n\r", ch );
return TRUE;
}
/*
* Room Editor Functions.
*/
bool redit_show( CHAR_DATA *ch, const char *argument )
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM( ch, pRoom );
show_room( ch, pRoom );
return FALSE;
}
void show_room( CHAR_DATA *ch, ROOM_INDEX_DATA *pRoom )
{
char word[MAX_INPUT_LENGTH];
BUFFER *buf = buffer_new( MAX_STRING_LENGTH );
OBJ_DATA *obj;
CHAR_DATA *rch;
int door;
bool fcnt;
bprintf( buf, "&gDescription:\n\r&w%s", pRoom->description );
bprintf( buf, "&b[&r%5d&b]&g Name: &b[&c%s&b]&n\n\r"
"&gArea: &b[&c%5d&b] &m%s&n\n\r",
pRoom->vnum, pRoom->name,
pRoom->area->vnum, pRoom->area->name );
bprintf( buf, "&gSector: &b[&c%s&b]&n\n\r"
"&gLight: &b[&c%5d&b]&n\n\r",
flag_string( sector_flags, &pRoom->sector_type ),
get_room_light( pRoom ) );
bprintf( buf, "&gRoom flags: &b[&c%s&b]&n\n\r",
flag_string( room_flags, &pRoom->room_flags ) );
if( pRoom->extra_descr )
{
EXTRA_DESCR_DATA *ed;
buffer_strcat( buf, "&gDesc Kwds: &b[&c" );
for( ed = pRoom->extra_descr; ed; ed = ed->next )
{
buffer_strcat( buf, ed->keyword );
if( ed->next )
buffer_strcat( buf, " " );
}
buffer_strcat( buf, "&b]&n\n\r" );
}
buffer_strcat( buf, "&gCharacters: &b[&c" );
fcnt = FALSE;
for( rch = pRoom->people; rch; rch = rch->next_in_room )
{
/*
* Security as from rstat
*/
if( can_see( ch, rch ) )
{
one_argument( rch->name, word );
buffer_strcat( buf, word );
buffer_strcat( buf, " " );
fcnt = TRUE;
}
}
if( fcnt )
{
buf->data[--buf->len] = '\0';
buffer_strcat( buf, "&b]&n\n\r" );
}
else
buffer_strcat( buf, "none&b]&n\n\r" );
buffer_strcat( buf, "&gObjects: &b[&c" );
fcnt = FALSE;
for( obj = pRoom->contents; obj; obj = obj->next_content )
{
one_argument( obj->name, word );
buffer_strcat( buf, word );
buffer_strcat( buf, " " );
fcnt = TRUE;
}
if( fcnt )
{
buf->data[--buf->len] = '\0';
buffer_strcat( buf, "&b]&n\n\r" );
}
else
buffer_strcat( buf, "none&b]&n\n\r" );
for( door = 0; door < MAX_DIR; door++ )
{
EXIT_DATA *pexit;
if( ( pexit = pRoom->exit[door] ) )
{
char reset_state[MAX_STRING_LENGTH];
const char *state;
int i, length;
bprintf( buf, "&b-&w%-5s&g to &b[&r%5d&b]&g Key: &b[&r%5d&b]",
capitalize( dir_name[door] ),
pexit->to_room ? pexit->to_room->vnum : 0,
pexit->key );
/*
* Format up the exit info.
* Capitalize all flags that are not part of the reset info.
*/
strcpy( reset_state, flag_string( exit_flags, &pexit->rs_flags ) );
state = flag_string( exit_flags, &pexit->exit_info );
buffer_strcat( buf, " &gExit flags: &b[&c" );
for( ;; )
{
state = one_argument( state, word );
if( word[0] == '\0' )
{
buf->data[--buf->len] = '\0';
buffer_strcat( buf, "&b]&n\n\r" );
break;
}
if( str_infix( word, reset_state ) )
{
length = strlen( word );
for( i = 0; i < length; i++ )
word[i] = toupper( word[i] );
}
buffer_strcat( buf, word );
buffer_strcat( buf, " " );
}
if( pexit->keyword && pexit->keyword[0] != '\0' )
bprintf( buf, "&gKwds: &b[&c%s&b]&n\n\r", pexit->keyword );
if( pexit->description && pexit->description[0] != '\0' )
bprintf( buf, "&w%s&n", pexit->description );
}
}
send_to_char( buf->data, ch );
buffer_free( buf );
return;
}
/* OLC 1.1b */
/*****************************************************************************
Name: change_exit
Purpose: Command interpreter for changing exits.
Called by: redit_<dir>. This is a local function.
****************************************************************************/
bool change_exit( CHAR_DATA *ch, const char *argument, int door )
{
ROOM_INDEX_DATA *pRoom;
ROOM_INDEX_DATA *pToRoom;
char command[MAX_INPUT_LENGTH];
char arg[MAX_INPUT_LENGTH];
char total_arg[MAX_STRING_LENGTH];
int rev;
int value = 0;
EDIT_ROOM( ch, pRoom );
/* Often used data. */
rev = rev_dir[door];
if( argument[0] == '\0' )
{
do_help( ch, "OLCEXIT" );
return FALSE;
}
/*
* Now parse the arguments.
*/
strcpy( total_arg, argument );
argument = one_argument( argument, command );
if( str_cmp( command, "name" ) && strcmp( command, "namerev" ) )
argument = one_argument( argument, arg );
if( !str_cmp( command, "delete" ) )
{
if( !pRoom->exit[door] )
{
send_to_char( "REdit: Exit does not exist.\n\r", ch );
return FALSE;
}
/*
* Remove To Room Exit.
*/
if( pRoom->exit[door]->to_room && pRoom->exit[door]->to_room->exit[rev]
&& pRoom->exit[door]->to_room->exit[rev]->to_room == pRoom )
{
free_exit( pRoom->exit[door]->to_room->exit[rev] );
pRoom->exit[door]->to_room->exit[rev] = NULL;
}
/*
* Remove this exit.
*/
free_exit( pRoom->exit[door] );
pRoom->exit[door] = NULL;
send_to_char( "Exit unlinked.\n\r", ch );
return TRUE;
}
/*
* Create a two-way exit.
*/
if( !str_cmp( command, "link" ) )
{
EXIT_DATA *pExit;
ROOM_INDEX_DATA *pLinkRoom;
if( arg[0] == '\0' || !is_number( arg ) )
{
send_to_char( "Syntax: <direction> link <vnum>\n\r", ch );
return FALSE;
}
if( !( pLinkRoom = get_room_index( atoi( arg ) ) ) )
{
send_to_char( "REdit: Non-existant room.\n\r", ch );
return FALSE;
}
if( !IS_BUILDER( ch, pLinkRoom->area ) )
{
send_to_char( "REdit: Cannot link to that area.\n\r", ch );
return FALSE;
}
if( pLinkRoom->exit[rev] )
{
send_to_char( "REdit: Remote side's exit exists.\n\r", ch );
return FALSE;
}
if( !pRoom->exit[door] ) /* No exit. */
{
pRoom->exit[door] = new_exit( );
pRoom->exit[door]->in_room = pRoom;
}
pRoom->exit[door]->to_room = pLinkRoom; /* Assign data. */
pExit = new_exit( ); /* No remote exit. */
pExit->in_room = pLinkRoom;
pExit->to_room = ch->in_room; /* Assign data. */
pLinkRoom->exit[rev] = pExit; /* Link exit to room. */
send_to_char( "Two-way link established.\n\r", ch );
return TRUE;
}
/*
* Create room and make two-way exit.
*/
if( !str_cmp( command, "dig" ) )
{
char buf[MAX_INPUT_LENGTH];
if( arg[0] == '\0' || !is_number( arg ) )
{
send_to_char( "Syntax: <direction> dig <vnum>\n\r", ch );
return FALSE;
}
redit_create( ch, arg ); /* Create the room. */
sprintf( buf, "link %s", arg );
change_exit( ch, buf, door ); /* Create the exits. */
return TRUE;
}
/*
* Create one-way exit.
*/
if( !str_cmp( command, "room" ) )
{
ROOM_INDEX_DATA *pLinkRoom;
if( arg[0] == '\0' || !is_number( arg ) )
{
send_to_char( "Syntax: <direction> room <vnum>\n\r", ch );
return FALSE;
}
if( !( pLinkRoom = get_room_index( atoi( arg ) ) ) )
{
send_to_char( "REdit: Non-existant room.\n\r", ch );
return FALSE;
}
if( !pRoom->exit[door] )
{
pRoom->exit[door] = new_exit( );
pRoom->exit[door]->in_room = pRoom;
}
pRoom->exit[door]->to_room = pLinkRoom;
send_to_char( "One-way link established.\n\r", ch );
return TRUE;
}
if( !str_cmp( command, "remove" ) )
{
if( arg[0] == '\0' )
{
send_to_char(
"Syntax: <direction> remove <key/name/desc>\n\r", ch );
return FALSE;
}
if( !pRoom->exit[door] )
{
send_to_char( "REdit: Exit does not exist.\n\r", ch );
return FALSE;
}
if( !str_cmp( arg, "key" ) )
{
pRoom->exit[door]->key = -1;
send_to_char( "Exit key removed.\n\r", ch );
return TRUE;
}
if( !str_cmp( arg, "name" ) )
{
free_string( pRoom->exit[door]->keyword );
pRoom->exit[door]->keyword = &str_empty[0];
send_to_char( "Exit name removed.\n\r", ch );
return TRUE;
}
if( arg[0] == 'd' && !str_prefix( argument, "description" ) )
{
free_string( pRoom->exit[door]->description );
pRoom->exit[door]->description = &str_empty[0];
send_to_char( "Exit description removed.\n\r", ch );
return TRUE;
}
send_to_char( "Syntax: <direction> remove <key/name/desc>\n\r", ch );
return FALSE;
}
if( !str_cmp( command, "key" ) || !str_cmp( command, "keyrev" ) )
{
OBJ_INDEX_DATA *pObjIndex;
if( arg[0] == '\0' || !is_number( arg ) )
{
send_to_char( "Syntax: <direction> key <vnum>\n\r", ch );
return FALSE;
}
if( !( pObjIndex = get_obj_index( atoi( arg ) ) ) )
{
send_to_char( "REdit: Item does not exist.\n\r", ch );
return FALSE;
}
if( pObjIndex->item_type != ITEM_KEY )
{
send_to_char( "REdit: Item is not a key.\n\r", ch );
return FALSE;
}
if( !pRoom->exit[door] )
{
pRoom->exit[door] = new_exit( );
pRoom->exit[door]->in_room = pRoom;
}
pRoom->exit[door]->key = pObjIndex->vnum;
/*
* Set key of connected room.
* Skip one-way exits and non-existant rooms.
*/
if( !str_cmp( command, "keyrev" ) &&
( pToRoom = pRoom->exit[door]->to_room ) && pToRoom->exit[rev] )
{
pToRoom->exit[rev]->key = pObjIndex->vnum;
}
send_to_char( "Exit key set.\n\r", ch );
return TRUE;
}
if( !str_cmp( command, "name" ) || !str_cmp( command, "namerev" ) )
{
if( argument[0] == '\0' )
{
send_to_char( "Syntax: <direction> name <string>\n\r", ch );
return FALSE;
}
if( !pRoom->exit[door] )
{
pRoom->exit[door] = new_exit( );
pRoom->exit[door]->in_room = pRoom;
}
free_string( pRoom->exit[door]->keyword );
pRoom->exit[door]->keyword = str_dup( argument );
/*
* Set name of connected room.
* Skip one-way exits and non-existant rooms.
*/
if( !str_cmp( command, "namerev" ) &&
( pToRoom = pRoom->exit[door]->to_room ) && pToRoom->exit[rev] )
{
free_string( pToRoom->exit[rev]->keyword );
pToRoom->exit[rev]->keyword = str_dup( argument );
}
send_to_char( "Exit name set.\n\r", ch );
return TRUE;
}
if( command[0] == 'd' && !str_prefix( command, "description" ) )
{
if( arg[0] == '\0' )
{
if( !pRoom->exit[door] )
{
pRoom->exit[door] = new_exit( );
pRoom->exit[door]->in_room = pRoom;
}
string_edit( ch, &pRoom->exit[door]->description );
return TRUE;
}
send_to_char( "Syntax: <direction> desc\n\r", ch );
return FALSE;
}
/*
* Set the exit flags, needs full argument.
* ----------------------------------------
*/
if( flag_value( &value, exit_flags, total_arg ) != NO_FLAG )
{
/*
* Create an exit if none exists.
*/
if( !pRoom->exit[door] )
{
pRoom->exit[door] = new_exit( );
pRoom->exit[door]->in_room = pRoom;
}
/*
* Set door bits for this room.
*/
TOGGLE_BIT( pRoom->exit[door]->rs_flags, value );
pRoom->exit[door]->exit_info = pRoom->exit[door]->rs_flags;
/*
* Set door bits of connected room.
* Skip one-way exits and non-existant rooms.
*/
if( ( pToRoom = pRoom->exit[door]->to_room ) && pToRoom->exit[rev] )
{
TOGGLE_BIT( pToRoom->exit[rev]->rs_flags, value );
pToRoom->exit[rev]->exit_info = pToRoom->exit[rev]->rs_flags;
}
send_to_char( "Exit flag toggled.\n\r", ch );
return TRUE;
}
return FALSE;
}
bool redit_north( CHAR_DATA *ch, const char *argument )
{
if( change_exit( ch, argument, DIR_NORTH ) )
return TRUE;
return FALSE;
}
bool redit_south( CHAR_DATA *ch, const char *argument )
{
if( change_exit( ch, argument, DIR_SOUTH ) )
return TRUE;
return FALSE;
}
bool redit_east( CHAR_DATA *ch, const char *argument )
{
if( change_exit( ch, argument, DIR_EAST ) )
return TRUE;
return FALSE;
}
bool redit_west( CHAR_DATA *ch, const char *argument )
{
if( change_exit( ch, argument, DIR_WEST ) )
return TRUE;
return FALSE;
}
bool redit_up( CHAR_DATA *ch, const char *argument )
{
if( change_exit( ch, argument, DIR_UP ) )
return TRUE;
return FALSE;
}
bool redit_down( CHAR_DATA *ch, const char *argument )
{
if( change_exit( ch, argument, DIR_DOWN ) )
return TRUE;
return FALSE;
}
/* OLC 1.1b */
bool redit_move( CHAR_DATA *ch, const char *argument )
{
interpret( ch, argument );
return FALSE;
}
bool redit_mpadd( CHAR_DATA *ch, const char *argument )
{
ROOM_INDEX_DATA *pRoom;
int type;
int allowed[] = { GLOBAL_PROG, ACT_PROG, SPEECH_PROG, RAND_PROG,
GREET_PROG, ALL_GREET_PROG, LEAVE_PROG, TIME_PROG,
REPOP_PROG, COMMAND_PROG, LOOK_PROG, SLEEP_PROG,
REST_PROG, DROP_PROG, -1 };
EDIT_ROOM( ch, pRoom );
if( ( type = edit_mpadd( ch, &pRoom->mudprogs, argument, allowed ) ) == PROG_ERROR )
return FALSE;
xSET_BIT( pRoom->progtypes, type );
return TRUE;
}
bool redit_mpdelete( CHAR_DATA *ch, const char *argument )
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM( ch, pRoom );
return edit_mpdelete( ch, &pRoom->mudprogs, argument );
}
bool redit_mpedit( CHAR_DATA *ch, const char *argument )
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM( ch, pRoom );
return edit_mpedit( ch, pRoom->mudprogs, argument );
}
bool redit_mpshow( CHAR_DATA *ch, const char *argument )
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM( ch, pRoom );
edit_mpshow( ch, pRoom->mudprogs, argument );
return FALSE;
}
bool redit_ed( CHAR_DATA *ch, const char *argument )
{
ROOM_INDEX_DATA *pRoom;
EXTRA_DESCR_DATA *ed;
char command[MAX_INPUT_LENGTH];
EDIT_ROOM( ch, pRoom );
argument = one_argument( argument, command );
if( command[0] == '\0' || argument[0] == '\0' )
{
send_to_char( "Syntax: ed add <keyword>\n\r", ch );
send_to_char( " ed edit <keyword>\n\r", ch );
send_to_char( " ed delete <keyword>\n\r", ch );
send_to_char( " ed format <keyword>\n\r", ch );
return FALSE;
}
if( !str_cmp( command, "add" ) )
{
if( argument[0] == '\0' )
{
send_to_char( "Syntax: ed add <keyword>\n\r", ch );
return FALSE;
}
ed = new_extra_descr( );
ed->keyword = str_dup( argument );
ed->description = str_dup( "" );
ed->next = pRoom->extra_descr;
pRoom->extra_descr = ed;
string_edit( ch, &ed->description );
return TRUE;
}
if( !str_cmp( command, "edit" ) )
{
if( argument[0] == '\0' )
{
send_to_char( "Syntax: ed edit <keyword>\n\r", ch );
return FALSE;
}
for( ed = pRoom->extra_descr; ed; ed = ed->next )
{
if( is_name( argument, ed->keyword ) )
break;
}
if( !ed )
{
send_to_char( "REdit: Extra description keyword not found.\n\r", ch );
return FALSE;
}
string_edit( ch, &ed->description );
return TRUE;
}
if( !str_cmp( command, "delete" ) )
{
EXTRA_DESCR_DATA *ped = NULL;
if( argument[0] == '\0' )
{
send_to_char( "Syntax: ed delete <keyword>\n\r", ch );
return FALSE;
}
for( ed = pRoom->extra_descr; ed; ed = ed->next )
{
if( is_name( argument, ed->keyword ) )
break;
ped = ed;
}
if( !ed )
{
send_to_char( "REdit: Extra description keyword not found.\n\r", ch );
return FALSE;
}
if( !ped )
pRoom->extra_descr = ed->next;
else
ped->next = ed->next;
free_extra_descr( ed );
send_to_char( "Extra description deleted.\n\r", ch );
return TRUE;
}
if( !str_cmp( command, "format" ) )
{
if( argument[0] == '\0' )
{
send_to_char( "Syntax: ed format <keyword>\n\r", ch );
return FALSE;
}
for( ed = pRoom->extra_descr; ed; ed = ed->next )
{
if( is_name( argument, ed->keyword ) )
break;
}
if( !ed )
{
send_to_char( "REdit: Extra description keyword not found.\n\r", ch );
return FALSE;
}
/* OLC 1.1b */
if( strlen( ed->description ) >= ( MAX_STRING_LENGTH - 4 ) )
{
send_to_char( "String too long to be formatted.\n\r", ch );
return FALSE;
}
ed->description = format_string( ed->description );
send_to_char( "Extra description formatted.\n\r", ch );
return TRUE;
}
redit_ed( ch, "" );
return FALSE;
}
bool redit_create( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
ROOM_INDEX_DATA *pRoom;
int value;
int iHash;
value = atoi( argument );
/* OLC 1.1b */
if( argument[0] == '\0' || value <= 0 || value >= INT_MAX )
{
char output[MAX_STRING_LENGTH];
sprintf( output, "Syntax: create <0 < #vnum < %d>\n\r", INT_MAX );
send_to_char( output, ch );
return FALSE;
}
if( argument[0] == '\0' || value <= 0 )
{
send_to_char( "Syntax: create <#vnum > 0>\n\r", ch );
return FALSE;
}
pArea = get_vnum_area( value );
if( !pArea )
{
send_to_char( "REdit: That vnum is not assigned an area.\n\r", ch );
return FALSE;
}
if( !IS_BUILDER( ch, pArea ) )
{
send_to_char( "REdit: Vnum in an area you cannot build in.\n\r", ch );
return FALSE;
}
if( get_room_index( value ) )
{
send_to_char( "REdit: Room vnum already exists.\n\r", ch );
return FALSE;
}
pRoom = new_room_index( );
pRoom->area = pArea;
pRoom->vnum = value;
pRoom->name = str_dup( "A Room" );
pRoom->description = str_dup( "" );
if( value > top_vnum_room )
top_vnum_room = value;
iHash = value % MAX_KEY_HASH;
pRoom->next = room_index_hash[iHash];
room_index_hash[iHash] = pRoom;
ch->desc->pEdit = (void *)pRoom;
wiznetf( ch, WIZ_CREATE, get_trust( ch ), "%s has created a new room %d.",
ch->name, value );
send_to_char( "Room created.\n\r", ch );
return TRUE;
}
bool redit_clone( CHAR_DATA *ch, const char *argument )
{
AREA_DATA *pArea;
ROOM_INDEX_DATA *curr;
ROOM_INDEX_DATA *pRoom;
int value;
int iHash;
EDIT_ROOM( ch, curr );
value = atoi( argument );
/* OLC 1.1b */
if( argument[0] == '\0' || value <= 0 || value >= INT_MAX )
{
char output[MAX_STRING_LENGTH];
sprintf( output, "Syntax: create <0 < #vnum < %d>\n\r", INT_MAX );
send_to_char( output, ch );
return FALSE;
}
if( argument[0] == '\0' || value <= 0 )
{
send_to_char( "Syntax: create <vnum > 0>\n\r", ch );
return FALSE;
}
pArea = get_vnum_area( value );
if( !pArea )
{
send_to_char( "REdit: That vnum is not assigned an area.\n\r", ch );
return FALSE;
}
if( !IS_BUILDER( ch, pArea ) )
{
send_to_char( "REdit: Vnum in an area you cannot build in.\n\r", ch );
return FALSE;
}
if( get_room_index( value ) )
{
send_to_char( "REdit: Room vnum already exists.\n\r", ch );
return FALSE;
}
pRoom = new_room_index( );
pRoom->area = pArea;
pRoom->vnum = value;
pRoom->name = str_dup( curr->name );
pRoom->description = str_dup( curr->description );
pRoom->room_flags = curr->room_flags;
pRoom->sector_type = curr->sector_type;
if( value > top_vnum_room )
top_vnum_room = value;
iHash = value % MAX_KEY_HASH;
pRoom->next = room_index_hash[iHash];
room_index_hash[iHash] = pRoom;
ch->desc->pEdit = (void *)pRoom;
send_to_char( "Room created.\n\r", ch );
return TRUE;
}
bool redit_name( CHAR_DATA *ch, const char *argument )
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM( ch, pRoom );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: name <$name>\n\r", ch );
return FALSE;
}
free_string( pRoom->name );
pRoom->name = str_dup( argument );
send_to_char( "Name set.\n\r", ch );
return TRUE;
}
bool redit_desc( CHAR_DATA *ch, const char *argument )
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM( ch, pRoom );
if( argument[0] == '\0' )
{
string_edit( ch, &pRoom->description );
return TRUE;
}
send_to_char( "Syntax: desc - string editor\n\r", ch );
return FALSE;
}
bool redit_format( CHAR_DATA *ch, const char *argument )
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM( ch, pRoom );
/* OLC 1.1b */
if( strlen( pRoom->description ) >= ( MAX_STRING_LENGTH - 4 ) )
{
send_to_char( "String too long to be formatted.\n\r", ch );
return FALSE;
}
pRoom->description = format_string( pRoom->description );
send_to_char( "String formatted.\n\r", ch );
return TRUE;
}
bool redit_mreset( CHAR_DATA *ch, const char *argument )
{
ROOM_INDEX_DATA *pRoom;
MOB_INDEX_DATA *pMobIndex;
CHAR_DATA *newmob;
char arg[MAX_INPUT_LENGTH];
RESET_DATA *pReset;
char output[MAX_STRING_LENGTH];
EDIT_ROOM( ch, pRoom );
argument = one_argument( argument, arg );
if( arg[0] == '\0' || !is_number( arg ) )
{
send_to_char( "Syntax: mreset <#vnum> <max #>\n\r", ch );
return FALSE;
}
if( !( pMobIndex = get_mob_index( atoi( arg ) ) ) )
{
send_to_char( "REdit: No mobile has that vnum.\n\r", ch );
return FALSE;
}
if( pMobIndex->area != pRoom->area )
{
send_to_char( "REdit: No such mobile in this area.\n\r", ch );
return FALSE;
}
/*
* Create the mobile reset.
*/
pReset = new_reset_data( );
pReset->command = 'M';
pReset->arg1 = pMobIndex->vnum;
pReset->arg2 = is_number( argument ) ? atoi( argument ) : MAX_MOB;
add_reset( pRoom, pReset, 0 /* Last slot */ );
/*
* Create the mobile.
*/
newmob = create_mobile( pMobIndex );
char_to_room( newmob, pRoom );
sprintf(
output, "&g%s &b[&r%d&b]&w has been loaded and added to resets.&n\n\r"
"&wThere will be a maximum of &c%d&w loaded to this room.&n\n\r",
capitalize( pMobIndex->short_descr ),
pMobIndex->vnum, pReset->arg2 );
send_to_char( output, ch );
act( "&g$n has created $N!", ch, NULL, newmob, TO_ROOM );
return TRUE;
}
struct wear_type
{
int wear_loc;
int wear_bit;
};
const struct wear_type wear_table_olc[] =
{
{ WEAR_NONE, ITEM_TAKE },
{ WEAR_HEAD, ITEM_WEAR_HEAD },
{ WEAR_HORNS, ITEM_WEAR_HORNS },
{ WEAR_EAR_L, ITEM_WEAR_EAR },
{ WEAR_EAR_R, ITEM_WEAR_EAR },
{ WEAR_FACE, ITEM_WEAR_FACE },
{ WEAR_NOSE, ITEM_WEAR_NOSE },
{ WEAR_NECK_1, ITEM_WEAR_NECK },
{ WEAR_NECK_2, ITEM_WEAR_NECK },
{ WEAR_SHOULDERS, ITEM_WEAR_SHOULDERS },
{ WEAR_WINGS, ITEM_WEAR_WINGS },
{ WEAR_FLOAT_L, ITEM_FLOAT },
{ WEAR_FLOAT_R, ITEM_FLOAT },
{ WEAR_ARMS, ITEM_WEAR_ARMS },
{ WEAR_WRIST_L, ITEM_WEAR_WRIST },
{ WEAR_WRIST_R, ITEM_WEAR_WRIST },
{ WEAR_HANDS, ITEM_WEAR_HANDS },
{ WEAR_FINGER_L, ITEM_WEAR_FINGER },
{ WEAR_FINGER_R, ITEM_WEAR_FINGER },
{ WEAR_WIELD_R, ITEM_WIELD },
{ WEAR_WIELD_L, ITEM_WIELD },
{ WEAR_WIELD_DOUBLE, ITEM_WIELD_DOUBLE },
{ WEAR_HOLD_L, ITEM_HOLD },
{ WEAR_HOLD_R, ITEM_HOLD },
{ WEAR_SHIELD, ITEM_WEAR_SHIELD },
{ WEAR_BODY, ITEM_WEAR_BODY },
{ WEAR_LEGS, ITEM_WEAR_LEGS },
{ WEAR_WAIST, ITEM_WEAR_WAIST },
{ WEAR_ANKLE_L, ITEM_WEAR_ANKLE },
{ WEAR_ANKLE_R, ITEM_WEAR_ANKLE },
{ WEAR_FEET, ITEM_WEAR_FEET },
{ WEAR_JUGGLED, 0 },
{ NO_FLAG, NO_FLAG }
};
/*****************************************************************************
Name: wear_loc
Purpose: Returns the location of the bit that matches the count.
1 = first match, 2 = second match etc.
Called by: oedit_reset( olc_act.c ).
****************************************************************************/
int wear_loc( int bits, int count )
{
int flag;
for( flag = 0; wear_table_olc[flag].wear_bit != NO_FLAG; flag++ )
{
if( IS_SET( bits, wear_table_olc[flag].wear_bit ) && --count < 1 )
return wear_table_olc[flag].wear_loc;
}
return NO_FLAG;
}
/*****************************************************************************
Name: wear_bit
Purpose: Converts a wear_loc into a bit.
Called by: redit_oreset( olc_act.c ).
****************************************************************************/
int wear_bit( int loc )
{
int flag;
for( flag = 0; wear_table_olc[flag].wear_loc != NO_FLAG; flag++ )
{
if( loc == wear_table_olc[flag].wear_loc )
return wear_table_olc[flag].wear_bit;
}
return 0;
}
bool redit_oreset( CHAR_DATA *ch, const char *argument )
{
ROOM_INDEX_DATA *pRoom;
OBJ_INDEX_DATA *pObjIndex;
OBJ_DATA *newobj;
OBJ_DATA *to_obj;
CHAR_DATA *to_mob;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
RESET_DATA *pReset;
char output[MAX_STRING_LENGTH];
EDIT_ROOM( ch, pRoom );
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if( arg1[0] == '\0' || !is_number( arg1 ) )
{
send_to_char( "Syntax: oreset <#vnum> <args>\n\r", ch );
send_to_char( " -no arg = into room\n\r", ch );
send_to_char( " -<obj_name> = into obj\n\r", ch );
send_to_char( " -<mob_name> <wear_loc> = into mob\n\r", ch );
return FALSE;
}
if( !( pObjIndex = get_obj_index( atoi( arg1 ) ) ) )
{
send_to_char( "REdit: No object has that vnum.\n\r", ch );
return FALSE;
}
if( pObjIndex->area != pRoom->area )
{
send_to_char( "REdit: No such object in this area.\n\r", ch );
return FALSE;
}
/*
* Load into room.
*/
if( arg2[0] == '\0' )
{
pReset = new_reset_data( );
pReset->command = 'O';
pReset->arg1 = pObjIndex->vnum;
pReset->arg2 = 0;
add_reset( pRoom, pReset, 0 /* Last slot */ );
newobj = create_object( pObjIndex, 0 );
obj_to_room( newobj, pRoom );
sprintf(
output, "&g%s&n [%d]&w has been loaded and added to resets.&n\n\r",
capitalize( pObjIndex->short_descr ), pObjIndex->vnum );
send_to_char( output, ch );
}
else
/*
* Load into object's inventory.
*/
if( argument[0] == '\0'
&& ( to_obj = get_obj_list( ch, arg2, pRoom->contents ) ) )
{
pReset = new_reset_data( );
pReset->command = 'P';
pReset->arg1 = pObjIndex->vnum;
pReset->arg2 = to_obj->pIndexData->vnum;
add_reset( pRoom, pReset, 0 /* Last slot */ );
newobj = create_object( pObjIndex, 0 );
newobj->cost = 0;
obj_to_obj( newobj, to_obj );
sprintf( output, "&g%s&n &b[&r%d&b]&w has been loaded into "
"&g%s &b[&r%d&b]&w and added to resets.&n\n\r",
capitalize( newobj->short_descr ),
newobj->pIndexData->vnum,
to_obj->short_descr,
to_obj->pIndexData->vnum );
send_to_char( output, ch );
}
else
/*
* Load into mobile's inventory.
*/
if( ( to_mob = get_char_room( ch, arg2 ) ) != NULL )
{
int wear_loc;
/*
* Make sure the location on mobile is valid.
*/
if( flag_value( &wear_loc, wear_loc_flags, argument ) == NO_FLAG )
{
send_to_char( "REdit: Invalid wear_loc. '? wear-loc'\n\r", ch );
return FALSE;
}
/*
* Disallow loading a sword( WEAR_WIELD ) into WEAR_HEAD.
*/
if( !IS_SET( pObjIndex->wear_flags, wear_bit( wear_loc ) ) )
{
sprintf( output,
"&g%s&n &b[&r%d&b]&w has wear flags: &b[&c%s&b]&n\n\r",
capitalize( pObjIndex->short_descr ),
pObjIndex->vnum,
flag_string( wear_flags, &pObjIndex->wear_flags ) );
send_to_char( output, ch );
return FALSE;
}
/*
* Can't load into same position.
*/
if( wear_loc != WEAR_NONE && get_eq_char( to_mob, wear_loc ) )
{
send_to_char( "REdit: Object already equipped.\n\r", ch );
return FALSE;
}
pReset = new_reset_data( );
pReset->arg1 = pObjIndex->vnum;
pReset->arg2 = wear_loc;
if( pReset->arg2 == WEAR_NONE )
pReset->command = 'G';
else
pReset->command = 'E';
add_reset( pRoom, pReset, 0 /* Last slot */ );
if( to_mob->pIndexData->pShop ) /* Shop-keeper? */
{
newobj = create_object( pObjIndex, 0 );
if( pReset->arg2 == WEAR_NONE )
SET_BIT( newobj->extra_flags, ITEM_INVENTORY );
}
else
newobj = create_object( pObjIndex, to_mob->level - 2 );
obj_to_char( newobj, to_mob );
if( pReset->command == 'E' )
equip_char( to_mob, newobj, pReset->arg2 );
sprintf( output, "&g%s&n &b[&r%d&b]&w has been loaded "
"%s of &g%s&n &b[&r%d&b]&w and added to resets.&n\n\r",
capitalize( pObjIndex->short_descr ),
pObjIndex->vnum,
flag_string( wear_loc_strings, &pReset->arg2 ),
to_mob->short_descr, to_mob->pIndexData->vnum );
send_to_char( output, ch );
}
else
/* Display Syntax */
{
send_to_char( "REdit: That mobile isn't here.\n\r", ch );
return FALSE;
}
act( "&g$n has created $p!", ch, newobj, NULL, TO_ROOM );
return TRUE;
}
/*
* Object Editor Functions.
*/
void show_obj_values( int type, int value[], BUFFER *buf )
{
ROOM_INDEX_DATA *room;
switch( type )
{
default: /* No values. */
break;
case ITEM_CORPSE_PC:
case ITEM_CORPSE_NPC:
bprintf( buf, "&b[&cv0&b]&g Corpse Race: &b[&c%s&b]&n\n\r",
( value[0] < 0 || value[0] >= MAX_RACE ) ? "none"
: race_table[value[0]].name );
break;
case ITEM_ARMOUR:
if( value[1] < 0 )
bprintf( buf, "&b[&cv0&b]&g Armour Class: &b[&c%d&b]&n\n\r"
"&b[&cv1&b]&g Armour Size: &b[&cfits all&b]&n\n\r",
value[0] );
else
bprintf( buf, "&b[&cv0&b]&g Armour Class: &b[&c%d&b]&n\n\r"
"&b[&cv1&b]&g Armour Size: &b[&c%d&b]&n\n\r",
value[0], value[1] );
break;
case ITEM_PORTAL:
room = get_room_index( value[0] );
bprintf( buf, "&b[&cv0&b]&g Destination: &b[&r%d&b]&y %s&n\n\r",
value[0], ( room ) ? room->name : "none" );
break;
case ITEM_EXPLOSIVE:
bprintf( buf, "&b[&cv0&b]&g Explosive Level: &b[&c%d&b]&n\n\r",
value[0] );
break;
case ITEM_LIGHT:
if( value[2] == -1 )
bprintf( buf, "&b[&cv2&b]&g Light: &wInfinite&b[&c-1&b]&n\n\r" );
else
bprintf( buf, "&b[&cv2&b]&g Light: &b[&c%d&b]&n\n\r", value[2] );
break;
case ITEM_WAND:
case ITEM_STAFF:
bprintf( buf,
"&b[&cv0&b]&g Level: &b[&c%d&b]&n\n\r"
"&b[&cv1&b]&g Charges Total: &b[&c%d&b]&n\n\r"
"&b[&cv2&b]&g Charges Left: &b[&c%d&b]&n\n\r"
"&b[&cv3&b]&g Spell: &y%s&n\n\r",
value[0], value[1], value[2],
value[3] != -1 ? skill_table[value[3]].name : "none" );
break;
case ITEM_PLANT:
case ITEM_SCROLL:
case ITEM_POTION:
case ITEM_PILL:
bprintf( buf,
"&b[&cv0&b]&g Level: &b[&c%d&b]&n\n\r"
"&b[&cv1&b]&g Spell: &y%s\n\r"
"&b[&cv2&b]&g Spell: &y%s\n\r"
"&b[&cv3&b]&g Spell: &y%s\n\r",
value[0],
value[1] != -1 ? skill_table[value[1]].name : "none",
value[2] != -1 ? skill_table[value[2]].name : "none",
value[3] != -1 ? skill_table[value[3]].name : "none" );
break;
case ITEM_WEAPON:
bprintf( buf,
"&b[&cv0&b]&g Offensive spell:&y%s&n\n\r"
"&b[&cv1&b]&g Damage minimum: &b[&c%d&b]&n\n\r"
"&b[&cv2&b]&g Damage maximum: &b[&c%d&b]&n\n\r"
"&b[&cv3&b]&g Type: &y%s&n\n\r",
( value[0] >= 0 && value[0] < MAX_SKILL )
? skill_table[value[0]].name : "none",
value[1], value[2],
flag_string( weapon_flags, &value[3] ) );
break;
case ITEM_CONTAINER:
bprintf( buf,
"&b[&cv0&b]&g Weight: &b[&c%d &bkg]&n\n\r"
"&b[&cv1&b]&g Flags: &b[&c%s&b]&n\n\r"
"&b[&cv2&b]&g Key: &y%s &b[&r%d&b]&n\n\r",
value[0],
flag_string( container_flags, &value[1] ),
get_obj_index( value[2] )
? get_obj_index( value[2] )->short_descr
: "none", value[2] );
break;
case ITEM_DRINK_CON:
bprintf( buf,
"&b[&cv0&b]&g Liquid Total: &b[&c%d&b]&n\n\r"
"&b[&cv1&b]&g Liquid Left: &b[&c%d&b]&n\n\r"
"&b[&cv2&b]&g Liquid: &y%s&n\n\r"
"&b[&cv3&b]&g Poisoned: &y%s&n\n\r",
value[0], value[1],
flag_string( liquid_flags, &value[2] ),
value[3] != 0 ? "Yes" : "No" );
break;
case ITEM_FOUNTAIN:
bprintf( buf,
"&b[&cv2&b]&g Liquid: &y%s&n\n\r",
flag_string( liquid_flags, &value[2] ) );
break;
case ITEM_FOOD:
bprintf( buf,
"&b[&cv0&b]&g Food hours: &b[&c%d&b]&n\n\r"
"&b[&cv3&b]&g Poisoned: &y%s&n\n\r",
value[0],
value[3] != 0 ? "Yes" : "No" );
break;
case ITEM_LIMB:
bprintf( buf,
"&b[&cv0&b]&g Limbs: &b[&c%s&b]&n\n\r"
"&b[&cv3&b]&g Poisoned: &y%s&n\n\r",
flag_string( body_part_flags, &value[0] ),
value[3] != 0 ? "Yes" : "No" );
break;
case ITEM_MONEY:
bprintf( buf, "&b[&cv0&b]&g Gold: &b[&c%d&b]&n\n\r", value[0] );
break;
case ITEM_TREASURE:
bprintf( buf, "&b[&cv0&b]&g Value: &b[&c%d&b]&n\n\r", value[0] );
break;
case ITEM_BOOK:
bprintf( buf,
"&b[&cv0&b]&g Spell: &y%s&n\n\r"
"&b[&cv1&b]&g %%age per study &b[&c%d%%&b]&n\n\r"
"&b[&cv2&b]&g Maximum %%age 1 &b[&c%d%%&b]&n\n\r"
"&b[&cv3&b]&g Maximum %%age 2 &b[&c%d%%&b]&n\n\r"
"&c*1 &b- Relative to the characters normal adept level.&n\n\r"
"&c*2 &b- An absolute maximum.&n\n\r",
value[0] > 0 ? skill_table[value[0]].name : "none",
value[1], value[2], value[3] );
break;
case ITEM_GEM:
bprintf( buf,
"&b[&cv0&b]&g Magic Sphere: &b[&c%s&b]&n\n\r"
"&b[&cv1&b]&g Capacity: &b[&c%d&b]&n\n\r"
"&b[&cv2&b]&g Current Amount: &b[&c%d&b]&n\n\r",
flag_string( magic_flags, &value[0] ),
value[1], value[2] );
break;
case ITEM_FURNITURE:
bprintf( buf,
"&b[&cv0&b]&g Flags: &b[&c%s&b]&n\n\r"
"&b[&cv1&b]&g Max People: &b[&c%d&b]&n\n\r"
"&b[&cv2&b]&g Health Bonus: &b[&c%d%%&b]&n\n\r"
"&b[&cv3&b]&g Mana Bonus: &b[&c%d%%&b]&n\n\r",
flag_string( furniture_flags, &value[0] ),
value[1], value[2], value[3] );
break;
}
return;
}
bool set_obj_values( CHAR_DATA *ch, OBJ_INDEX_DATA * pObj, int value_num,
const char *argument )
{
BUFFER *buf = buffer_new( MAX_INPUT_LENGTH );
switch( pObj->item_type )
{
default:
break;
case ITEM_GEM:
switch( value_num )
{
default:
do_help( ch, "ITEM_GEM" );
buffer_free( buf );
return FALSE;
case 0:
buffer_strcat( buf, "Gem type: " );
if( flag_value( NULL, magic_flags, argument ) == NO_FLAG )
{
buffer_strcat( buf, "Bad magic type '? magic'.\n\r" );
send_to_char( buf->data, ch );
buffer_free( buf );
return FALSE;
}
else
{
pObj->value[0] = flag_value( NULL, magic_flags, argument );
buffer_strcat( buf, "Sphere set.\n\r" );
}
break;
case 1: case 2:
pObj->value[value_num] = atoi( argument );
buffer_strcat( buf, "Gem value set.\n\r\n\r" );
break;
}
break;
case ITEM_FURNITURE:
switch( value_num )
{
default:
do_help( ch, "ITEM_FURNITURE" );
buffer_free( buf );
return FALSE;
case 0:
buffer_strcat( buf, "Furniture type: " );
if( flag_value( NULL, furniture_flags, argument ) == NO_FLAG )
{
buffer_strcat( buf, "Bad furniture type '? furniture'.\n\r" );
send_to_char( buf->data, ch );
buffer_free( buf );
return FALSE;
}
else
{
TOGGLE_BIT( pObj->value[0],
flag_value( NULL, furniture_flags, argument ) );
buffer_strcat( buf, "Flags set.\n\r" );
}
break;
case 1: case 2: case 3:
pObj->value[value_num] = atoi( argument );
buffer_strcat( buf, "Furniture value set.\n\r\n\r" );
break;
}
break;
case ITEM_PORTAL:
switch( value_num )
{
default:
do_help( ch, "ITEM_PORTAL" );
buffer_free( buf );
return FALSE;
case 0:
buffer_strcat( buf, "Portal Destination: " );
pObj->value[0] = atoi( argument );
if( !get_room_index( pObj->value[0] ) )
{
pObj->value[0] = ROOM_VNUM_TEMPLE;
send_to_char( "That room couldn't be found.\n\r", ch );
buffer_free( buf );
return FALSE;
}
else
{
buffer_strcat( buf, "Successful change.\n\r\n\r" );
}
break;
}
break;
case ITEM_EXPLOSIVE:
switch( value_num )
{
default:
do_help( ch, "ITEM_EXPLOSIVE" );
buffer_free( buf );
return FALSE;
case 0:
buffer_strcat( buf, "EXPLOSIVE LEVEL SET.\n\r\n\r" );
pObj->value[0] = atoi( argument );
break;
}
break;
case ITEM_LIGHT:
switch( value_num )
{
default:
do_help( ch, "ITEM_LIGHT" );
buffer_free( buf );
return FALSE;
case 2:
buffer_strcat( buf, "HOURS OF LIGHT SET.\n\r\n\r" );
pObj->value[2] = atoi_special( argument );
break;
}
break;
case ITEM_WAND:
case ITEM_STAFF:
switch( value_num )
{
default:
do_help( ch, "ITEM_STAFF" );
buffer_free( buf );
return FALSE;
case 0:
buffer_strcat( buf, "SPELL LEVEL SET.\n\r\n\r" );
pObj->value[0] = atoi( argument );
break;
case 1:
buffer_strcat( buf, "TOTAL NUMBER OF CHARGES SET.\n\r\n\r" );
pObj->value[1] = atoi_special( argument );
break;
case 2:
buffer_strcat( buf, "CURRENT NUMBER OF CHARGES SET.\n\r\n\r" );
pObj->value[2] = atoi_special( argument );
break;
case 3:
buffer_strcat( buf, "SPELL TYPE SET.\n\r" );
pObj->value[3] = skill_lookup( argument );
break;
}
break;
case ITEM_PLANT:
case ITEM_SCROLL:
case ITEM_POTION:
case ITEM_PILL:
switch( value_num )
{
default:
do_help( ch, "ITEM_SCROLL_POTION_PILL" );
buffer_free( buf );
return FALSE;
case 0:
buffer_strcat( buf, "SPELL LEVEL SET.\n\r\n\r" );
pObj->value[0] = atoi( argument );
break;
case 1:
buffer_strcat( buf, "SPELL TYPE 1 SET.\n\r\n\r" );
pObj->value[1] = skill_lookup( argument );
break;
case 2:
buffer_strcat( buf, "SPELL TYPE 2 SET.\n\r\n\r" );
pObj->value[2] = skill_lookup( argument );
break;
case 3:
buffer_strcat( buf, "SPELL TYPE 3 SET.\n\r\n\r" );
pObj->value[3] = skill_lookup( argument );
break;
}
break;
case ITEM_WEAPON:
switch( value_num )
{
default:
do_help( ch, "ITEM_WEAPON" );
buffer_free( buf );
return FALSE;
case 0:
buffer_strcat( buf, "WEAPON SPELL SET.\n\r\n\r" );
pObj->value[0] = skill_lookup( argument );
break;
case 1:
buffer_strcat( buf, "MINIMUM DAMAGE SET.\n\r\n\r" );
pObj->value[1] = atoi( argument );
break;
case 2:
buffer_strcat( buf, "MAXIMUM DAMAGE SET.\n\r\n\r" );
pObj->value[2] = atoi( argument );
break;
case 3:
buffer_strcat( buf, "WEAPON TYPE SET.\n\r\n\r" );
pObj->value[3] = flag_value( NULL, weapon_flags, argument );
break;
}
break;
case ITEM_ARMOUR:
switch( value_num )
{
default:
do_help( ch, "ITEM_ARMOUR" );
buffer_free( buf );
return FALSE;
case 1:
buffer_strcat( buf, "ARMOUR SIZE SET.\n\r\n\r" );
pObj->value[1] = atoi( argument );
break;
}
break;
case ITEM_CORPSE_PC:
case ITEM_CORPSE_NPC:
switch( value_num )
{
default:
do_help( ch, "ITEM_CORPSE" );
buffer_free( buf );
return FALSE;
case 0:
buffer_strcat( buf, "CORPSE RACE SET.\n\r\n\r" );
pObj->value[0] = race_lookup( argument );
break;
}
break;
case ITEM_CONTAINER:
switch( value_num )
{
int value;
default:
do_help( ch, "ITEM_CONTAINER" );
buffer_free( buf );
return FALSE;
case 0:
buffer_strcat( buf, "WEIGHT CAPACITY SET.\n\r\n\r" );
pObj->value[0] = atoi_special( argument );
break;
case 1:
if( flag_value( &value, container_flags, argument ) != NO_FLAG )
TOGGLE_BIT( pObj->value[1], value );
else
{
do_help( ch, "ITEM_CONTAINER" );
buffer_free( buf );
return FALSE;
}
buffer_strcat( buf, "CONTAINER TYPE SET.\n\r\n\r" );
break;
case 2:
if( ( value = atoi( argument ) != 0 ) )
{
if( !get_obj_index( value ) )
{
send_to_char( "THERE IS NO SUCH ITEM.\n\r\n\r", ch );
buffer_free( buf );
return FALSE;
}
if( get_obj_index( value )->item_type != ITEM_KEY )
{
send_to_char( "THAT ITEM IS NOT A KEY.\n\r\n\r", ch );
buffer_free( buf );
return FALSE;
}
}
buffer_strcat( buf, "CONTAINER KEY SET.\n\r\n\r" );
pObj->value[2] = value;
break;
}
break;
case ITEM_DRINK_CON:
switch( value_num )
{
default:
do_help( ch, "ITEM_DRINK" );
buffer_free( buf );
return FALSE;
case 0:
buffer_strcat( buf, "MAXIMUM AMOUNT OF LIQUID HOURS SET.\n\r\n\r" );
pObj->value[0] = atoi_special( argument );
break;
case 1:
buffer_strcat( buf, "CURRENT AMOUNT OF LIQUID HOURS SET.\n\r\n\r" );
pObj->value[1] = atoi_special( argument );
break;
case 2:
buffer_strcat( buf, "LIQUID TYPE SET.\n\r\n\r" );
pObj->value[2] = flag_value( NULL, liquid_flags, argument );
break;
case 3:
buffer_strcat( buf, "POISON VALUE TOGGLED.\n\r\n\r" );
pObj->value[3] = ( pObj->value[3] == 0 ) ? 1 : 0;
break;
}
break;
case ITEM_FOUNTAIN:
switch( value_num )
{
default:
do_help( ch, "ITEM_FOUNTAIN" );
buffer_free( buf );
return FALSE;
case 2:
buffer_strcat( buf, "LIQUID TYPE SET.\n\r\n\r" );
pObj->value[2] = flag_value( NULL, liquid_flags, argument );
break;
}
break;
case ITEM_FOOD:
switch( value_num )
{
default:
do_help( ch, "ITEM_FOOD" );
buffer_free( buf );
return FALSE;
case 0:
buffer_strcat( buf, "HOURS OF FOOD SET.\n\r\n\r" );
pObj->value[0] = atoi_special( argument );
break;
case 3:
buffer_strcat( buf, "POISON VALUE TOGGLED.\n\r\n\r" );
pObj->value[3] = ( pObj->value[3] == 0 ) ? 1 : 0;
break;
}
break;
case ITEM_LIMB:
switch( value_num )
{
default:
do_help( ch, "ITEM_LIMB" );
buffer_free( buf );
return FALSE;
case 0:
if( flag_value( NULL, body_part_flags, argument ) == NO_FLAG )
{
send_to_char( "Invalid Limb.\n\r", ch );
buffer_free( buf );
return FALSE;
}
buffer_strcat( buf, "LIMB VALUE SET.\n\r\n\r" );
TOGGLE_BIT( pObj->value[0],
flag_value( NULL, body_part_flags, argument ) );
break;
case 3:
buffer_strcat( buf, "POISON VALUE TOGGLED.\n\r\n\r" );
pObj->value[3] = ( pObj->value[3] == 0 ) ? 1 : 0;
break;
}
break;
case ITEM_MONEY:
case ITEM_TREASURE:
switch( value_num )
{
default:
do_help( ch, "ITEM_MONEY" );
buffer_free( buf );
return FALSE;
case 0:
buffer_strcat( buf, "GOLD VALUE SET.\n\r\n\r" );
pObj->value[0] = atoi_special( argument );
break;
}
break;
case ITEM_BOOK:
switch( value_num )
{
default:
do_help( ch, "ITEM_BOOK" );
buffer_free( buf );
return FALSE;
case 0:
buffer_strcat( buf, "SPELL/SKILL SET.\n\r" );
pObj->value[0] = skill_lookup( argument );
break;
case 1:
buffer_strcat( buf, "PERCENTAGE GAIN PER STUDY SET.\n\r" );
pObj->value[1] = URANGE( 0, atoi( argument ), 100 );
break;
case 2:
buffer_strcat( buf, "RELATIVE MAXIMUM SKILL LEVEL FROM STUDYING SET.\n\r" );
pObj->value[2] = URANGE( -100, atoi( argument ), 200 );
break;
case 3:
buffer_strcat( buf, "ABSOLUTE MAXIMUM SKILL LEVEL FROM STUDYING SET.\n\r" );
pObj->value[2] = URANGE( 0, atoi( argument ), 200 );
break;
}
break;
}
show_obj_values( pObj->item_type, pObj->value, buf );
send_to_char( buf->data, ch );
buffer_free( buf );
return TRUE;
}
bool oedit_show( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
BUFFER *buf = buffer_new( MAX_STRING_LENGTH );
char *p;
AFFECT_DATA *paf;
int cnt;
EDIT_OBJ( ch, pObj );
bprintf( buf, "&b[&r%5d&b]&g Name: &b[&c%s&b]&n\n\r",
pObj->vnum, pObj->name );
bprintf( buf, "&gArea: &b[&c%5d&b]&m %s&n\n\r",
!pObj->area ? -1 : pObj->area->vnum,
!pObj->area ? "No Area" : pObj->area->name );
bprintf( buf, "&gLevel: &b[&c%5d&b]"
"&g Repop: &b[&c%d&b/&c1000&b]&n\n\r",
pObj->level, pObj->reset_chance );
bprintf( buf, "&gWeight: &b[&c%5d&b]"
"&g Cost: &b[&c%5s&b]&n\n\r",
pObj->weight, int_to_str_special( pObj->cost ) );
bprintf( buf, "&gType: &b[&c%s&b]&n\n\r",
flag_string( type_flags, &pObj->item_type ) );
bprintf( buf, "&gWear flags: &b[&c%s&b]&n\n\r",
flag_string( wear_flags, &pObj->wear_flags ) );
bprintf( buf, "&gExtra flags: &b[&c%s&b]&n\n\r",
flag_string( extra_flags, &pObj->extra_flags ) );
bprintf( buf, "&gRequired: &b[&c%s&b]&n\n\r",
( pObj->required_skill > 0 )
? skill_table[pObj->required_skill].name : "none" );
bprintf( buf, "&gMaterial: &b[&c%s&b]&n\n\r"
"&gCondition: &b[&c%3d.%d%%&b]&n\n\r",
flag_string( material_flags, &pObj->material ),
pObj->condition / 10, pObj->condition % 10 );
if( pObj->extra_descr )
{
EXTRA_DESCR_DATA *ed;
buffer_strcat( buf, "&gEx desc kwd: " );
for( ed = pObj->extra_descr; ed; ed = ed->next )
{
buffer_strcat( buf, "&b[&c" );
buffer_strcat( buf, ed->keyword );
buffer_strcat( buf, "&b]" );
}
buffer_strcat( buf, "&n\n\r" );
}
bprintf( buf, "&gShort desc: &w%s&n\n\r&gLong desc:\n\r &w%s&n\n\r",
pObj->short_descr, pObj->description );
if( pObj->action && pObj->action[0] != '\0' )
bprintf( buf, "&gAction:&n\n\r%s&n", pObj->action );
for( cnt = 0, paf = pObj->affected; paf; paf = paf->next )
{
char temp[MAX_STRING_LENGTH];
if( cnt == 0 )
{
buffer_strcat( buf, "&gNum Name Affects Mod Bits&n\n\r" );
buffer_strcat( buf, "&B----- ------------- ---------- --- --------&n\n\r" );
}
if( paf->type == gsn_delayed_effect
|| paf->type == gsn_continuous_effect )
strcpy( temp, skill_table[paf->location].name );
else
strcpy( temp, flag_string( apply_flags, &paf->location ) );
if( paf->type != gsn_perm_spell )
bprintf( buf, "&b[&r%3d&b]&y %-13.13s %-10.10s &c%3d&y %s&n\n\r",
cnt, paf->type > 0 ? skill_table[paf->type].name : "none",
temp, paf->modifier,
flag_string( affect_flags, paf->bitvector ) );
else
bprintf( buf, "&b[&r%3d&b]&y %-13.13s permanent spell.&n\n\r",
cnt, paf->location > 0
? skill_table[paf->location].name
: "ERROR - delete this!" );
cnt++;
}
show_obj_values( pObj->item_type, pObj->value, buf );
while( ( p = strstr( buf->data, "&x" ) ) )
*( p + 1 ) = 'w';
send_to_char( buf->data, ch );
buffer_free( buf );
return FALSE;
}
/*
* Need to issue warning if flag isn't valid.
*/
bool oedit_addaffect( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
char loc[MAX_STRING_LENGTH];
char mod[MAX_STRING_LENGTH];
int value;
EDIT_OBJ( ch, pObj );
argument = one_argument( argument, loc );
one_argument( argument, mod );
if( loc[0] == '\0' || mod[0] == '\0' || !is_number( mod ) )
{
send_to_char( "Syntax: addaffect <location> <#mod>\n\r", ch );
return FALSE;
}
if( flag_value( &value, apply_flags, loc ) == NO_FLAG )
{
send_to_char( "OEdit: Invalid value. '? apply'\n\r", ch );
return FALSE;
}
pAf = new_affect( );
pAf->location = flag_value( NULL, apply_flags, loc );
pAf->modifier = atoi( mod );
pAf->type = -1;
pAf->duration = -1;
vzero( pAf->bitvector );
pAf->next = pObj->affected;
pObj->affected = pAf;
send_to_char( "Affect added.\n\r", ch );
return TRUE;
}
/*
* Need to issue warning if flag isn't valid.
* Just like addaffect but with extras
*/
bool oedit_addspell( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
char type[MAX_INPUT_LENGTH];
char loc[MAX_INPUT_LENGTH];
char mod[MAX_INPUT_LENGTH];
int value;
int vect[MAX_VECTOR];
EDIT_OBJ( ch, pObj );
argument = one_argument( argument, type );
argument = one_argument( argument, loc );
argument = one_argument( argument, mod );
if( type[0] == '\0' || loc[0] == '\0' || mod[0] == '\0'
|| ( !is_number( mod )
&& flag_value( NULL, body_part_flags, mod ) == NO_FLAG ) )
{
send_to_char(
"Syntax: addspell <type> <location> <#mod> [bits]\n\r", ch );
return FALSE;
}
if( skill_lookup( type ) < 0 )
{
send_to_char( "OEdit: Invalid spell name.\n\r", ch );
return FALSE;
}
if( !is_number( loc ) &&
flag_value( &value, apply_flags, loc ) == NO_FLAG )
{
send_to_char( "OEdit: Invalid value. '? apply'\n\r", ch );
return FALSE;
}
if( argument[0] != '\0' && str_cmp( argument, "none" ) &&
flag_value( vect, affect_flags, argument ) == NO_FLAG )
{
send_to_char( "OEdit: Invalid value. '? affect'\n\r", ch );
return FALSE;
}
pAf = new_affect( );
pAf->location = is_number( loc )
? atoi( loc )
: flag_value( NULL, apply_flags, loc );
pAf->modifier = is_number( mod )
? atoi( mod )
: flag_value( NULL, body_part_flags, mod );
pAf->type = skill_lookup( type );
pAf->duration = -1;
if( !strcmp( argument, "none" ) || argument[0] == '\0' )
vzero( pAf->bitvector );
else
flag_value( pAf->bitvector, affect_flags, argument );
pAf->next = pObj->affected;
pObj->affected = pAf;
send_to_char( "Spell effect added.\n\r", ch );
return TRUE;
}
bool oedit_addperm( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
int sn;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: addperm <type>\n\r", ch );
return FALSE;
}
if( ( sn = skill_lookup( argument ) ) < 0 )
{
send_to_char( "OEdit: Invalid spell name.\n\r", ch );
return FALSE;
}
if( ( skill_table[sn].target != TAR_CHAR_DEFENSIVE
&& skill_table[sn].target != TAR_CHAR_SELF
&& skill_table[sn].target != TAR_CHAR_OFFENSIVE )
|| !skill_table[sn].spell_fun )
{
send_to_char( "OEdit: Please use a character targeted spell.\n\r",
ch );
return FALSE;
}
pAf = new_affect( );
pAf->type = gsn_perm_spell;
pAf->location = skill_lookup( argument );
pAf->modifier = 0;
pAf->duration = -1;
vzero( pAf->bitvector );
pAf->next = pObj->affected;
pObj->affected = pAf;
send_to_char( "Permanent spell effect added.\n\r", ch );
return TRUE;
}
/*
* My thanks to Hans Hvidsten Birkeland and Noam Krendel (Walker)
* for really teaching me how to manipulate pointers.
*/
bool oedit_delaffect( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
AFFECT_DATA *pAf_next;
char affect[MAX_STRING_LENGTH];
int value;
int cnt = 0;
EDIT_OBJ( ch, pObj );
one_argument( argument, affect );
if( !is_number( affect ) || affect[0] == '\0' )
{
send_to_char( "Syntax: delaffect <#affect>\n\r", ch );
return FALSE;
}
value = atoi( affect );
if( value < 0 )
{
send_to_char( "Only non-negative affect-numbers allowed.\n\r", ch );
return FALSE;
}
if( !( pAf = pObj->affected ) )
{
send_to_char( "OEdit: Non-existant affect.\n\r", ch );
return FALSE;
}
if( value == 0 ) /* First case: Remove first affect */
{
pAf = pObj->affected;
pObj->affected = pAf->next;
free_affect( pAf );
}
else
/* Affect to remove is not the first */
{
while( ( pAf_next = pAf->next ) && ( ++cnt < value ) )
pAf = pAf_next;
if( pAf_next ) /* See if it's the next affect */
{
pAf->next = pAf_next->next;
free_affect( pAf_next );
}
else /* Doesn't exist */
{
send_to_char( "No such affect.\n\r", ch );
return FALSE;
}
}
send_to_char( "Affect removed.\n\r", ch );
return TRUE;
}
bool oedit_name( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: name <$name>\n\r", ch );
return FALSE;
}
free_string( pObj->name );
pObj->name = str_dup( argument );
send_to_char( "Name set.\n\r", ch );
return TRUE;
}
bool oedit_short( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: short <$short>\n\r", ch );
return FALSE;
}
free_string( pObj->short_descr );
pObj->short_descr = str_dup( argument );
send_to_char( "Short description set.\n\r", ch );
return TRUE;
}
bool oedit_level( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' || !is_number( argument ) )
{
send_to_char( "Syntax: level <#lvl>\n\r", ch );
return FALSE;
}
pObj->level = atoi( argument );
send_to_char( "Level set.\n\r", ch );
return TRUE;
}
bool oedit_long( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: long <$long>\n\r", ch );
return FALSE;
}
free_string( pObj->description );
pObj->description = str_dup( argument );
pObj->description[0] = UPPER( pObj->description[0] );
send_to_char( "Long description set.\n\r", ch );
return TRUE;
}
bool oedit_action( CHAR_DATA *ch, const char *argument )
{
char buf[MAX_STRING_LENGTH];
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' )
{
free_string( pObj->action );
pObj->action = str_dup( "" );
send_to_char( "Action description cleared.\n\r", ch );
return TRUE;
}
sprintf( buf, "%s&n\n\r", argument );
free_string( pObj->action );
pObj->action = str_dup( buf );
pObj->action[0] = UPPER( pObj->action[0] );
send_to_char( "Action description set.\n\r", ch );
return TRUE;
}
bool set_value( CHAR_DATA *ch, OBJ_INDEX_DATA * pObj, const char *argument,
int value )
{
if( argument[0] == '\0' )
{
set_obj_values( ch, pObj, -1, '\0' );
return FALSE;
}
if( set_obj_values( ch, pObj, value, argument ) )
return TRUE;
return FALSE;
}
/*****************************************************************************
Name: oedit_values
Purpose: Finds the object and sets its value.
Called by: The four valueX functions below.
****************************************************************************/
bool oedit_values( CHAR_DATA *ch, const char *argument, int value )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
if( set_value( ch, pObj, argument, value ) )
return TRUE;
return FALSE;
}
bool oedit_value0( CHAR_DATA *ch, const char *argument )
{
if( oedit_values( ch, argument, 0 ) )
return TRUE;
return FALSE;
}
bool oedit_value1( CHAR_DATA *ch, const char *argument )
{
if( oedit_values( ch, argument, 1 ) )
return TRUE;
return FALSE;
}
bool oedit_value2( CHAR_DATA *ch, const char *argument )
{
if( oedit_values( ch, argument, 2 ) )
return TRUE;
return FALSE;
}
bool oedit_value3( CHAR_DATA *ch, const char *argument )
{
if( oedit_values( ch, argument, 3 ) )
return TRUE;
return FALSE;
}
bool oedit_mpadd( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
int type;
int allowed[] = { GLOBAL_PROG, ACT_PROG, SPEECH_PROG, RAND_PROG,
GREET_PROG, ALL_GREET_PROG, LEAVE_PROG, TIME_PROG,
REPOP_PROG, COMMAND_PROG, WEAR_PROG, REMOVE_PROG,
SAC_PROG, LOOK_PROG, EXAMINE_PROG, USE_PROG, GET_PROG,
DROP_PROG, GIVE_PROG, DAMAGE_PROG, REPAIR_PROG,
OPEN_PROG, CLOSE_PROG, LOOT_PROG, -1 };
EDIT_OBJ( ch, pObj );
if( ( type = edit_mpadd( ch, &pObj->mudprogs, argument, allowed ) ) == PROG_ERROR )
return FALSE;
xSET_BIT( pObj->progtypes, type );
return TRUE;
}
bool oedit_mpdelete( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
return edit_mpdelete( ch, &pObj->mudprogs, argument );
}
bool oedit_mpedit( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
return edit_mpedit( ch, pObj->mudprogs, argument );
}
bool oedit_mpshow( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
edit_mpshow( ch, pObj->mudprogs, argument );
return FALSE;
}
bool oedit_weight( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
int weight;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' || !is_number( argument ) )
{
send_to_char( "Syntax: weight <#weight>\n\r", ch );
return FALSE;
}
weight = atoi_special( argument );
if( weight < 0 )
{
send_to_char( "You may not set negative weight.\n\r", ch );
return FALSE;
}
pObj->weight = weight;
send_to_char( "Weight set.\n\r", ch );
return TRUE;
}
bool oedit_repop( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
int repop;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' || !is_number( argument ) )
{
send_to_char( "Syntax: repop <#repop>\n\r", ch );
return FALSE;
}
repop = atoi_special( argument );
if( repop < 0 || repop > 1000 )
{
send_to_char( "Range is 0 to 1000.\n\r", ch );
return FALSE;
}
pObj->reset_chance = repop;
send_to_char( "Repop chance set.\n\r", ch );
return TRUE;
}
bool oedit_required( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
int sn;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: required <skill>\n\r", ch );
return FALSE;
}
sn = skill_lookup( argument );
if( sn < 0 )
{
send_to_char( "Skill not found.\n\r", ch );
return FALSE;
}
pObj->required_skill = sn;
send_to_char( "Required Skill set.\n\r", ch );
return TRUE;
}
bool oedit_rsfind( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
OBJ_INDEX_DATA *pObjToIndex;
MOB_INDEX_DATA *pMob = NULL;
ROOM_INDEX_DATA *pRoom;
int rvnum;
RESET_DATA *pReset;
BUFFER *buf = buffer_new( MAX_STRING_LENGTH );
char tmp[MAX_INPUT_LENGTH];
EDIT_OBJ( ch, pObj );
for( rvnum = pObj->area->lvnum; rvnum <= pObj->area->uvnum; rvnum++ )
{
if( ( pRoom = get_room_index( rvnum ) ) && pRoom->area == pObj->area )
{
for( pReset = pRoom->reset_first; pReset; pReset = pReset->next )
{
if( pReset->command == 'M' )
{
pMob = get_mob_index( pReset->arg1 );
continue;
}
if( pReset->arg1 != pObj->vnum )
continue;
switch( pReset->command )
{
case 'O':
bprintf( buf, "&m[%5d]&y%s &ginto room.&n\n\r", rvnum,
colour_strpad( tmp, pRoom->name, 20 ) );
break;
case 'P':
if( !( pObjToIndex = get_obj_index( pReset->arg2 ) ) )
{
bprintf( buf, "Put Object - Bad To Object %d.\n\r",
pReset->arg2 );
break;
}
bprintf( buf, "&m[%5d]&y%s ", rvnum,
colour_strpad( tmp, pRoom->name, 20 ) );
bprintf( buf, "&ginside &mO[%5d] &y%s&n\n\r", pReset->arg2,
colour_strpad( tmp, pObjToIndex->short_descr, 20 ) );
break;
case 'E':
case 'G':
if( !pMob )
{
bprintf( buf, "No last mobile - Room %d.\n\r", rvnum );
break;
}
bprintf( buf, "&m[%5d]&y%s ", rvnum,
colour_strpad( tmp, pRoom->name, 20 ) );
bprintf( buf, "&g%-20.20s &mM[%5d] &y%s&n\n\r",
( pReset->command == 'G' ) ?
wear_loc_strings[0].name
: flag_string( wear_loc_strings, &pReset->arg2 ),
pMob->vnum, colour_strpad( tmp, pMob->short_descr, 20 ) );
break;
}
}
}
}
if( buf->data[0] != '\0' )
send_to_char( buf->data, ch );
else
send_to_char( "This object has no resets in this area.\n\r", ch );
buffer_free( buf );
return FALSE;
}
bool oedit_cost( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
int cost;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' || !is_number_special( argument ) )
{
send_to_char( "Syntax: cost <number with k/m/t suffix>\n\r", ch );
return FALSE;
}
cost = atoi_special( argument );
if( cost < 0 )
{
send_to_char( "You may not set negative cost.\n\r", ch );
return FALSE;
}
pObj->cost = cost;
send_to_char( "Cost set.\n\r", ch );
return TRUE;
}
bool oedit_condition( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
int cond;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' || !is_number( argument ) )
{
send_to_char( "Syntax: condition <#condition/100>\n\r", ch );
return FALSE;
}
cond = atoi( argument );
if( cond < 0 )
{
send_to_char( "You may not set negative condition.\n\r", ch );
return FALSE;
}
else if( cond > 100 )
send_to_char( "OEdit: [WARNING] setting condition higher than 100 "
"isn't a good idea.\n\r", ch );
pObj->condition = cond * 10;
send_to_char( "Condition set.\n\r", ch );
return TRUE;
}
bool oedit_create( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
AREA_DATA *pArea;
int value;
int iHash;
value = atoi( argument );
/* OLC 1.1b */
if( argument[0] == '\0' || value <= 0 || value >= INT_MAX )
{
char output[MAX_STRING_LENGTH];
sprintf( output, "Syntax: create <0 < #vnum < %d>\n\r", INT_MAX );
send_to_char( output, ch );
return FALSE;
}
pArea = get_vnum_area( value );
if( !pArea )
{
send_to_char( "OEdit: That vnum is not assigned an area.\n\r", ch );
return FALSE;
}
if( !IS_BUILDER( ch, pArea ) )
{
send_to_char( "OEdit: Vnum in an area you cannot build in.\n\r", ch );
return FALSE;
}
if( get_obj_index( value ) )
{
send_to_char( "OEdit: Object vnum already exists.\n\r", ch );
return FALSE;
}
pObj = new_obj_index( );
pObj->vnum = value;
pObj->area = pArea;
pObj->action = str_dup( "" );
if( value > top_vnum_obj )
top_vnum_obj = value;
iHash = value % MAX_KEY_HASH;
pObj->next = obj_index_hash[iHash];
obj_index_hash[iHash] = pObj;
ch->desc->pEdit = (void *)pObj;
wiznetf( ch, WIZ_CREATE, get_trust( ch ), "%s has created a new object %d.",
ch->name, value );
send_to_char( "Object Created.\n\r", ch );
return TRUE;
}
bool oedit_clone( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
OBJ_INDEX_DATA *curr;
AREA_DATA *pArea;
int value;
int iHash;
EDIT_OBJ( ch, curr );
value = atoi( argument );
/* OLC 1.1b */
if( argument[0] == '\0' || value <= 0 || value >= INT_MAX )
{
char output[MAX_STRING_LENGTH];
sprintf( output, "Syntax: clone <0 < #vnum < %d>\n\r", INT_MAX );
send_to_char( output, ch );
return FALSE;
}
pArea = get_vnum_area( value );
if( !pArea )
{
send_to_char( "OEdit: That vnum is not assigned an area.\n\r", ch );
return FALSE;
}
if( !IS_BUILDER( ch, pArea ) )
{
send_to_char( "OEdit: Vnum in an area you cannot build in.\n\r", ch );
return FALSE;
}
if( get_obj_index( value ) )
{
send_to_char( "OEdit: Object vnum already exists.\n\r", ch );
return FALSE;
}
pObj = new_obj_index( );
pObj->vnum = value;
pObj->area = pArea;
free_string( pObj->name );
pObj->name = str_dup( curr->name );
free_string( pObj->short_descr );
pObj->short_descr = str_dup( curr->short_descr );
free_string( pObj->description );
pObj->description = str_dup( curr->description );
free_string( pObj->action );
pObj->action = str_dup( curr->action );
pObj->level = curr->level;
pObj->value[0] = curr->value[0];
pObj->value[1] = curr->value[1];
pObj->value[2] = curr->value[2];
pObj->value[3] = curr->value[3];
pObj->item_type = curr->item_type;
pObj->extra_flags = curr->extra_flags;
pObj->wear_flags = curr->wear_flags;
pObj->weight = curr->weight;
pObj->required_skill = curr->required_skill;
pObj->material = curr->material;
pObj->cost = curr->cost;
if( value > top_vnum_obj )
top_vnum_obj = value;
iHash = value % MAX_KEY_HASH;
pObj->next = obj_index_hash[iHash];
obj_index_hash[iHash] = pObj;
ch->desc->pEdit = (void *)pObj;
send_to_char( "Object Cloned.\n\r", ch );
return TRUE;
}
bool oedit_ed( CHAR_DATA *ch, const char *argument )
{
OBJ_INDEX_DATA *pObj;
EXTRA_DESCR_DATA *ed;
char command[MAX_INPUT_LENGTH];
EDIT_OBJ( ch, pObj );
argument = one_argument( argument, command );
if( command[0] == '\0' )
{
send_to_char( "Syntax: ed add <keyword\n\r", ch );
send_to_char( " ed delete <keyword>\n\r", ch );
send_to_char( " ed edit <keyword>\n\r", ch );
send_to_char( " ed format <keyword>\n\r", ch );
return FALSE;
}
if( !str_cmp( command, "add" ) )
{
if( argument[0] == '\0' )
{
send_to_char( "Syntax: ed add <keyword>\n\r", ch );
return FALSE;
}
ed = new_extra_descr( );
ed->keyword = str_dup( argument );
ed->next = pObj->extra_descr;
pObj->extra_descr = ed;
string_edit( ch, &ed->description );
return TRUE;
}
if( !str_cmp( command, "edit" ) )
{
if( argument[0] == '\0' )
{
send_to_char( "Syntax: ed edit <keyword>\n\r", ch );
return FALSE;
}
for( ed = pObj->extra_descr; ed; ed = ed->next )
{
if( is_name( argument, ed->keyword ) )
break;
}
if( !ed )
{
send_to_char( "OEdit: Extra description keyword not found.\n\r", ch );
return FALSE;
}
string_edit( ch, &ed->description );
return TRUE;
}
if( !str_cmp( command, "delete" ) )
{
EXTRA_DESCR_DATA *ped = NULL;
if( argument[0] == '\0' )
{
send_to_char( "Syntax: ed delete <keyword>\n\r", ch );
return FALSE;
}
for( ed = pObj->extra_descr; ed; ed = ed->next )
{
if( is_name( argument, ed->keyword ) )
break;
ped = ed;
}
if( !ed )
{
send_to_char( "OEdit: Extra description keyword not found.\n\r", ch );
return FALSE;
}
if( !ped )
pObj->extra_descr = ed->next;
else
ped->next = ed->next;
free_extra_descr( ed );
send_to_char( "Extra description deleted.\n\r", ch );
return TRUE;
}
if( !str_cmp( command, "format" ) )
{
if( argument[0] == '\0' )
{
send_to_char( "Syntax: ed format <keyword>\n\r", ch );
return FALSE;
}
for( ed = pObj->extra_descr; ed; ed = ed->next )
if( is_name( argument, ed->keyword ) )
break;
if( !ed )
{
send_to_char( "OEdit: Extra description keyword not found.\n\r", ch );
return FALSE;
}
/* OLC 1.1b */
if( strlen( ed->description ) >= ( MAX_STRING_LENGTH - 4 ) )
{
send_to_char( "String too long to be formatted.\n\r", ch );
return FALSE;
}
ed->description = format_string( ed->description );
send_to_char( "Extra description formatted.\n\r", ch );
return TRUE;
}
oedit_ed( ch, "" );
return FALSE;
}
/*
* Mobile Editor Functions.
*/
bool medit_show( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
BUFFER *buf = buffer_new( MAX_STRING_LENGTH );
char tmp[MAX_STRING_LENGTH];
char tmp2[MAX_STRING_LENGTH];
char *p;
EDIT_MOB( ch, pMob );
bprintf( buf, "&b[&r%5d&b]&g Name: &b[&c%s&b]&n\n\r"
"&gArea: &b[&c%5d&b]&m %s&n\n\r",
pMob->vnum, pMob->name,
!pMob->area ? -1 : pMob->area->vnum,
!pMob->area ? "No Area" : pMob->area->name );
bprintf( buf, "&gLevel: &b[&c%5d&b]"
"&g Race: &b[&c%s&b]&n\n\r",
pMob->level, race_table[pMob->race].name );
bprintf( buf, "&gRepop: &b[&c%4d&b/&c1000&b]"
"&g Class: &b[&c%s&b]&n\n\r",
pMob->reset_chance,
pMob->class < 0 ? "none" : class_table[pMob->class].name );
bprintf( buf, "&gAlign: &b[&c%5d&b]"
"&g Sex: &b[&c%s&b]&n\n\r",
pMob->alignment,
pMob->sex == SEX_MALE ? "male" :
pMob->sex == SEX_FEMALE ? "female" : "neutral" );
bprintf( buf, "&gAct: &b[&c%s&b]&n\n\r",
flag_string( act_flags, pMob->act ) );
sprintf( tmp, "&gAffected by: &b[&c%s&b]&n\n\r",
flag_string( affect_flags, pMob->affected_by ) );
buffer_strcat( buf, multi_line( tmp2, tmp, 79, 15 ) );
sprintf( tmp, "&gBody Parts: &b[&c%s&b]&n\n\r",
flag_string( body_part_flags, &pMob->body_parts ) );
buffer_strcat( buf, multi_line( tmp2, tmp, 79, 15 ) );
if( pMob->spec_fun )
bprintf( buf, "&gSpec fun: &b[&c%s&b]&n\n\r",
spec_table[pMob->spec_fun].spec_name );
bprintf( buf, "&gShort descr: &w%s\n\r&gLong descr:\n\r&w%s&n",
pMob->short_descr, pMob->long_descr );
buffer_strcat( buf, "&gDescription:\n\r&w" );
buffer_strcat( buf, pMob->description );
buffer_strcat( buf, "&n" );
if( pMob->pShop )
{
SHOP_DATA *pShop;
int iTrade;
pShop = pMob->pShop;
bprintf( buf,
"&gShop data for &b[&r%5d&b]&g:&n\n\r"
"\t&gMarkup for purchaser: &b[&c%d%%&b]&n\n\r"
"\t&gMarkdown for seller: &b[&c%d%%&b]&n\n\r",
pMob->vnum, pShop->profit_buy, pShop->profit_sell );
bprintf( buf, "\t&gHours: &c%d&g to &c%d&g.&n\n\r",
pShop->open_hour, pShop->close_hour );
for( iTrade = 0; iTrade < MAX_TRADE; iTrade++ )
{
if( pShop->buy_type[iTrade] > 0 )
{
if( iTrade == 0 )
{
buffer_strcat( buf, "\t&gNumber Trades Type&n\n\r" );
buffer_strcat( buf, "\t&B------ -----------&n\n\r" );
}
bprintf( buf, "\t&b[&c%4d&b]&n &y%s&n\n\r", iTrade,
flag_string( type_flags, &pShop->buy_type[iTrade] ) );
}
}
}
while( ( p = strstr( buf->data, "&x" ) ) )
*( p + 1 ) = 'w';
send_to_char( buf->data, ch );
buffer_free( buf );
return FALSE;
}
bool medit_create( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
AREA_DATA *pArea;
int value;
int iHash;
value = atoi( argument );
/* OLC 1.1b */
if( argument[0] == '\0' || value <= 0 || value >= INT_MAX )
{
char output[MAX_STRING_LENGTH];
sprintf( output, "Syntax: create <0 < #vnum < %d>\n\r", INT_MAX );
send_to_char( output, ch );
return FALSE;
}
pArea = get_vnum_area( value );
if( !pArea )
{
send_to_char( "MEdit: That vnum is not assigned an area.\n\r", ch );
return FALSE;
}
if( !IS_BUILDER( ch, pArea ) )
{
send_to_char( "MEdit: Vnum in an area you cannot build in.\n\r", ch );
return FALSE;
}
if( get_mob_index( value ) )
{
send_to_char( "MEdit: Mobile vnum already exists.\n\r", ch );
return FALSE;
}
pMob = new_mob_index( );
pMob->vnum = value;
pMob->area = pArea;
pMob->body_parts = race_table[0].body_parts;
pMob->class = CLASS_NONE;
if( value > top_vnum_mob )
top_vnum_mob = value;
vset( pMob->act, ACT_IS_NPC );
iHash = value % MAX_KEY_HASH;
pMob->next = mob_index_hash[iHash];
mob_index_hash[iHash] = pMob;
ch->desc->pEdit = (void *)pMob;
wiznetf( ch, WIZ_CREATE, get_trust( ch ), "%s has created a new mobile (%d).",
ch->name, value );
send_to_char( "Mobile Created.\n\r", ch );
return TRUE;
}
bool medit_clone( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
MOB_INDEX_DATA *curr;
AREA_DATA *pArea;
int value;
int iHash;
EDIT_MOB( ch, curr );
value = atoi( argument );
/* OLC 1.1b */
if( argument[0] == '\0' || value <= 0 || value >= INT_MAX )
{
char output[MAX_STRING_LENGTH];
sprintf( output, "Syntax: create <0 < #vnum < %d>\n\r", INT_MAX );
send_to_char( output, ch );
return FALSE;
}
pArea = get_vnum_area( value );
if( !pArea )
{
send_to_char( "MEdit: That vnum is not assigned an area.\n\r", ch );
return FALSE;
}
if( !IS_BUILDER( ch, pArea ) )
{
send_to_char( "MEdit: Vnum in an area you cannot build in.\n\r", ch );
return FALSE;
}
if( get_mob_index( value ) )
{
send_to_char( "MEdit: Mobile vnum already exists.\n\r", ch );
return FALSE;
}
pMob = new_mob_index( );
pMob->vnum = value;
pMob->area = pArea;
free_string( pMob->name );
pMob->name = str_dup( curr->name );
free_string( pMob->short_descr );
pMob->short_descr = str_dup( curr->short_descr );
free_string( pMob->long_descr );
pMob->long_descr = str_dup( curr->long_descr );
free_string( pMob->description );
pMob->description = str_dup( curr->description );
pMob->spec_fun = curr->spec_fun;
pMob->level = curr->level;
vcopy( pMob->act, curr->act );
vcopy( pMob->affected_by, curr->affected_by );
pMob->race = curr->race;
pMob->sex = curr->sex;
pMob->body_parts = curr->body_parts;
pMob->alignment = curr->alignment;
pMob->class = curr->class;
if( value > top_vnum_mob )
top_vnum_mob = value;
iHash = value % MAX_KEY_HASH;
pMob->next = mob_index_hash[iHash];
mob_index_hash[iHash] = pMob;
ch->desc->pEdit = (void *)pMob;
send_to_char( "Mobile Cloned.\n\r", ch );
return TRUE;
}
bool medit_spec( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB( ch, pMob );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: spec <special function>\n\r", ch );
return FALSE;
}
if( !str_cmp( argument, "none" ) )
{
pMob->spec_fun = 0;
send_to_char( "Spec removed.\n\r", ch );
return TRUE;
}
if( spec_lookup( argument ) >= 0 )
{
pMob->spec_fun = spec_lookup( argument );
send_to_char( "Spec set.\n\r", ch );
return TRUE;
}
send_to_char( "MEdit: No such special function.\n\r", ch );
return FALSE;
}
bool medit_class( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB( ch, pMob );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: class <class name/'none'>\n\r", ch );
return FALSE;
}
if( flag_value( NULL, class_flags, argument ) != NO_FLAG )
{
pMob->class = flag_value( NULL, class_flags, argument );
send_to_char( "Class set.\n\r", ch );
return TRUE;
}
send_to_char( "MEdit: No such class.\n\r", ch );
return FALSE;
}
bool medit_mpadd( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
int type;
int allowed[] = { GLOBAL_PROG, SUB_PROG, ACT_PROG, SPEECH_PROG,
RAND_PROG, GREET_PROG, ALL_GREET_PROG, LEAVE_PROG,
TIME_PROG, REPOP_PROG, COMMAND_PROG, LOOK_PROG,
FIGHT_PROG, DEATH_PROG, HITPRCNT_PROG, ENTRY_PROG,
GIVE_PROG, BRIBE_PROG, ATTACK_PROG, DELAY_PROG,
CAST_PROG, -1 };
EDIT_MOB( ch, pMob );
if( ( type = edit_mpadd( ch, &pMob->mudprogs, argument, allowed ) ) == PROG_ERROR )
return FALSE;
xSET_BIT( pMob->progtypes, type );
return TRUE;
}
bool medit_mpdelete( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB( ch, pMob );
return edit_mpdelete( ch, &pMob->mudprogs, argument );
}
bool medit_mpedit( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB( ch, pMob );
return edit_mpedit( ch, pMob->mudprogs, argument );
}
bool medit_mpshow( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB( ch, pMob );
edit_mpshow( ch, pMob->mudprogs, argument );
return FALSE;
}
bool medit_align( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB( ch, pMob );
if( argument[0] == '\0' || !is_number( argument ) )
{
send_to_char( "Syntax: alignment <#align>\n\r", ch );
return FALSE;
}
pMob->alignment = atoi( argument );
send_to_char( "Alignment set.\n\r", ch );
return TRUE;
}
bool medit_repop( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
int repop;
EDIT_MOB( ch, pMob );
if( argument[0] == '\0' || !is_number( argument ) )
{
send_to_char( "Syntax: repop <#repop>\n\r", ch );
return FALSE;
}
repop = atoi_special( argument );
if( repop < 0 || repop > 1000 )
{
send_to_char( "Range is 0 to 1000.\n\r", ch );
return FALSE;
}
pMob->reset_chance = repop;
send_to_char( "Repop chance set.\n\r", ch );
return TRUE;
}
bool medit_rsfind( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
ROOM_INDEX_DATA *pRoom;
int rvnum, col = 0;
RESET_DATA *pReset;
BUFFER *buf = buffer_new( MAX_STRING_LENGTH );
EDIT_MOB( ch, pMob );
for( rvnum = pMob->area->lvnum; rvnum <= pMob->area->uvnum; rvnum++ )
{
if( ( pRoom = get_room_index( rvnum ) ) && pRoom->area == pMob->area )
{
for( pReset = pRoom->reset_first; pReset; pReset = pReset->next )
{
if( pReset->command == 'M' && pReset->arg1 == pMob->vnum )
{
char tmp[MAX_INPUT_LENGTH];
bprintf( buf, "&m[%5d]&y%s &gnumber: %3d", rvnum,
colour_strpad( tmp, pRoom->name, 19 ), pReset->arg2 );
if( ++col % 2 == 0 )
buffer_strcat( buf, ".&n\n\r" );
else
buffer_strcat( buf, ", " );
}
}
}
}
if( col % 2 != 0 )
buffer_strcat( buf, "&n\n\r" );
if( buf->data[0] != '\0' )
send_to_char( buf->data, ch );
else
send_to_char( "This mobile has no resets in this area.\n\r", ch );
buffer_free( buf );
return FALSE;
}
bool medit_level( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB( ch, pMob );
if( argument[0] == '\0' || !is_number( argument ) )
{
send_to_char( "Syntax: level <#lvl>\n\r", ch );
return FALSE;
}
pMob->level = atoi( argument );
send_to_char( "Level set.\n\r", ch );
return TRUE;
}
bool medit_desc( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB( ch, pMob );
if( argument[0] == '\0' )
{
string_edit( ch, &pMob->description );
return TRUE;
}
send_to_char( "Syntax: desc - line edit\n\r", ch );
return FALSE;
}
bool medit_long( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
char buf[MAX_INPUT_LENGTH];
EDIT_MOB( ch, pMob );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: long <$long>\n\r", ch );
return FALSE;
}
free_string( pMob->long_descr );
sprintf( buf, "%s\n\r", argument );
pMob->long_descr = str_dup( buf );
pMob->long_descr[0] = UPPER( pMob->long_descr[0] );
send_to_char( "Long description set.\n\r", ch );
return TRUE;
}
bool medit_short( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB( ch, pMob );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: short <#short>\n\r", ch );
return FALSE;
}
free_string( pMob->short_descr );
pMob->short_descr = str_dup( argument );
send_to_char( "Short description set.\n\r", ch );
return TRUE;
}
bool medit_name( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB( ch, pMob );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: name <$name>\n\r", ch );
return FALSE;
}
free_string( pMob->name );
pMob->name = str_dup( argument );
send_to_char( "Name set.\n\r", ch );
return TRUE;
}
bool medit_shop( CHAR_DATA *ch, const char *argument )
{
MOB_INDEX_DATA *pMob;
char command[MAX_INPUT_LENGTH];
char arg1[MAX_INPUT_LENGTH];
argument = one_argument( argument, command );
argument = one_argument( argument, arg1 );
EDIT_MOB( ch, pMob );
if( command[0] == '\0' )
{
send_to_char( "Syntax: shop hours <#opening> <#closing>\n\r", ch );
send_to_char( " shop profit <#buying%> <#selling%>\n\r", ch );
send_to_char( " shop type <#0-4> <item type>\n\r", ch );
send_to_char( " shop delete <#0-4>\n\r", ch );
return FALSE;
}
if( !str_cmp( command, "hours" ) )
{
if( arg1[0] == '\0' || !is_number( arg1 )
|| argument[0] == '\0' || !is_number( argument ) )
{
send_to_char(
"Syntax: shop hours <#opening> <#closing>\n\r", ch );
return FALSE;
}
if( !pMob->pShop )
{
pMob->pShop = new_shop( );
shop_last->next = pMob->pShop;
}
pMob->pShop->open_hour = atoi( arg1 );
pMob->pShop->close_hour = atoi( argument );
send_to_char( "Shop hours set.\n\r", ch );
return TRUE;
}
if( !str_cmp( command, "profit" ) )
{
if( arg1[0] == '\0' || !is_number( arg1 )
|| argument[0] == '\0' || !is_number( argument ) )
{
send_to_char(
"Syntax: shop profit <#buying%> <#selling%>\n\r", ch );
return FALSE;
}
if( !pMob->pShop )
{
pMob->pShop = new_shop( );
shop_last->next = pMob->pShop;
}
pMob->pShop->profit_buy = atoi( arg1 );
pMob->pShop->profit_sell = atoi( argument );
send_to_char( "Shop profit set.\n\r", ch );
return TRUE;
}
if( !str_cmp( command, "type" ) )
{
char buf[MAX_INPUT_LENGTH];
int value;
if( arg1[0] == '\0' || !is_number( arg1 )
|| argument[0] == '\0' )
{
send_to_char( "Syntax: shop type <#0-4> <item type>\n\r", ch );
return FALSE;
}
if( atoi( arg1 ) >= MAX_TRADE )
{
sprintf( buf, "REdit: May sell %d items max.\n\r", MAX_TRADE );
send_to_char( buf, ch );
return FALSE;
}
if( flag_value( &value, type_flags, argument ) == NO_FLAG )
{
send_to_char( "REdit: That type of item is not known (? type).\n\r", ch );
return FALSE;
}
if( !pMob->pShop )
{
pMob->pShop = new_shop( );
shop_last->next = pMob->pShop;
}
pMob->pShop->buy_type[atoi( arg1 )] = value;
send_to_char( "Shop type set.\n\r", ch );
return TRUE;
}
if( !str_cmp( command, "delete" ) )
{
SHOP_DATA *pShop;
if( !pMob->pShop )
{
send_to_char( "REdit: Non-existant shop.\n\r", ch );
return FALSE;
}
pShop = pMob->pShop;
free_shop( pShop );
pMob->pShop = NULL;
send_to_char( "Shop deleted.\n\r", ch );
return TRUE;
}
medit_shop( ch, "" );
return FALSE;
}
bool gmpedit_create( CHAR_DATA *ch, const char *argument )
{
MPROG_GLOBAL *mprg;
AREA_DATA *pArea;
int value, iHash;
value = atoi( argument );
/* OLC 1.1b */
if( argument[0] == '\0' || value <= 0 || value >= INT_MAX )
{
char output[MAX_STRING_LENGTH];
sprintf( output, "Syntax: create <0 < #vnum < %d>\n\r", INT_MAX );
send_to_char( output, ch );
return FALSE;
}
pArea = get_vnum_area( value );
if( !pArea )
{
send_to_char( "GMPEdit: That vnum is not assigned an area.\n\r", ch );
return FALSE;
}
if( !IS_BUILDER( ch, pArea ) )
{
send_to_char( "GMPEdit: Vnum in an area you cannot build in.\n\r", ch );
return FALSE;
}
if( get_global_mudprog_index( value ) )
{
send_to_char( "GMPEdit: MudProg vnum already exists.\n\r", ch );
return FALSE;
}
mprg = new_mprog_global( );
mprg->area = pArea;
mprg->vnum = value;
mprg->type = GLOBAL_PROG;
iHash = value % MPROG_GLOBAL_HASH;
mprg->next = global_progs[iHash];
global_progs[iHash] = mprg;
ch->desc->pEdit = (void *)mprg;
ch->desc->interpreter = get_interpreter( "GMPEdit" );
wiznetf( ch, WIZ_CREATE, get_trust( ch ),
"%s has created a new mud program (%d).",
ch->name, value );
send_to_char( "Mud Program Created.\n\r", ch );
return TRUE;
}
bool gmpedit_show( CHAR_DATA *ch, const char *argument )
{
MPROG_GLOBAL *mprg;
BUFFER *buf = buffer_new( MAX_STRING_LENGTH );
EDIT_GMPROG( ch, mprg );
bprintf( buf, "&b[&r%5d&b]&g Type: &b[&c%s&b]&n\n\r",
mprg->vnum, flag_string( mud_prog_flags, &mprg->type ) );
bprintf( buf, "&gArea: &b[&c%4d&b]&m %s&n\n\r",
!mprg->area ? -1 : mprg->area->vnum,
!mprg->area ? "No Area" : mprg->area->name );
bprintf( buf, "&gAllowed: &b[&c%s&b]&n\n\r",
flag_string( mor_type_flags, &mprg->allowed ) );
bprintf( buf, "&gArguments(s): &w%s&n\n\r"
"&gScript:\n\r&w", mprg->arglist );
buffer_strcat( buf, mprg->comlist );
send_to_char( buf->data, ch );
send_to_char( "&n", ch );
buffer_free( buf );
return FALSE;
}
bool gmpedit_area( CHAR_DATA *ch, const char *argument )
{
MPROG_GLOBAL *mprg;
AREA_DATA *pArea;
EDIT_GMPROG( ch, mprg );
if( argument[0] == '\0' || !is_number( argument ) )
{
send_to_char( "Syntax: area <#areavnum>\n\r", ch );
return FALSE;
}
pArea = get_area_data( atoi( argument ) );
if( !pArea )
{
send_to_char( "No area there.\n\r", ch );
return FALSE;
}
if( !IS_BUILDER( ch, pArea ) )
{
send_to_char( "You can build that area.\n\r", ch );
return FALSE;
}
mprg->area = pArea;
SET_BIT( pArea->area_flags, AREA_CHANGED );
send_to_char( "GMPEdit: Mud Program area set.\n\r", ch );
return TRUE;
}
bool gmpedit_arglist( CHAR_DATA *ch, const char *argument )
{
MPROG_GLOBAL *mprg;
EDIT_GMPROG( ch, mprg );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: arglist <$name>\n\r", ch );
return FALSE;
}
free_string( mprg->arglist );
mprg->arglist = str_dup( argument );
send_to_char( "Arguments to program set.\n\r", ch );
return TRUE;
}
bool gmpedit_comlist( CHAR_DATA *ch, const char *argument )
{
MPROG_GLOBAL *mprg;
EDIT_GMPROG( ch, mprg );
if( argument[0] == '\0' )
{
string_edit( ch, &mprg->comlist );
return TRUE;
}
send_to_char( "Syntax: script - line edit\n\r", ch );
return FALSE;
}