/***************************************************************************
* File: olc_act.c *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
* *
* This code was freely distributed with the The Isles 1.1 source code, *
* and has been used here for OLC - OLC would not be what it is without *
* all the previous coders who released their source code. *
* *
***************************************************************************/
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <limits.h> /* OLC 1.1b */
#include "merc.h"
#include "olc.h"
struct olc_help_type
{
char *command;
const void *structure;
char *desc;
};
bool show_version( CHAR_DATA *ch, char *argument )
{
send_to_char( VERSION, ch );
send_to_char( "\n\r", ch );
send_to_char( AUTHOR, ch );
send_to_char( "\n\r", ch );
send_to_char( DATE, ch );
send_to_char( "\n\r", ch );
send_to_char( CREDITS, ch );
send_to_char( "\n\r", ch );
return FALSE;
}
/*
* This table contains help commands and a brief description of each.
* ------------------------------------------------------------------
*/
const struct olc_help_type help_table[] =
{
{ "area", area_flags, "Area attributes." },
{ "room", room_flags, "Room attributes." },
{ "sector", sector_flags, "Sector types, terrain." },
{ "exit", exit_flags, "Exit types." },
{ "type", type_flags, "Types of objects." },
{ "extra", extra_flags, "Object attributes." },
{ "wear", wear_flags, "Where to wear object." },
{ "spec", spec_table, "Available special programs." },
{ "sex", sex_flags, "Sexes." },
{ "act", act_flags, "Mobile attributes." },
{ "affect", affect_flags, "Mobile affects." },
{ "wear-loc", wear_loc_flags, "Where mobile wears object." },
{ "spells", skill_table, "Names of current spells." },
{ "weapon", weapon_flags, "Type of weapon." },
{ "container", container_flags, "Container status." },
{ "liquid", liquid_flags, "Types of liquids." },
{ "", 0, "" }
};
/*****************************************************************************
Name: show_flag_cmds
Purpose: Displays settable flags and stats.
Called by: show_help(olc_act.c).
****************************************************************************/
void show_flag_cmds( CHAR_DATA *ch, const struct flag_type *flag_table )
{
char buf[ MAX_STRING_LENGTH ];
char *buf1;
int flag;
int col;
buf1 = NULL;
col = 0;
for( flag = 0 ; *flag_table[flag].name ; flag++ )
{
if( flag_table[flag].settable )
{
sprintf( buf, "%-19.18s", flag_table[flag].name );
str_cat( &buf1, buf );
if( ++col % 4 == 0 )
str_cat( &buf1, "\n\r" );
}
}
if( col % 4 != 0 )
str_cat( &buf1, "\n\r" );
page_to_char( buf1, ch );
free( buf1 );
return;
}
/*****************************************************************************
Name: show_skill_cmds
Purpose: Displays all skill functions.
Does remove those damn immortal commands from the list.
Could be improved by:
(1) Adding a check for a particular class.
(2) Adding a check for a level range.
Called by: show_help(olc_act.c).
****************************************************************************/
void show_skill_cmds( CHAR_DATA *ch, int tar )
{
char buf[ MAX_STRING_LENGTH ];
char *buf1;
int sn;
int col;
buf1 = NULL;
col = 0;
for( sn = 0 ; sn < MAX_SKILL ; sn++ )
{
if( !skill_table[sn].name )
break;
if( !str_cmp( skill_table[sn].name, "reserved" )
|| skill_table[sn].spell_fun == spell_null )
continue;
if( tar == -1 || skill_table[sn].target == tar )
{
sprintf( buf, "%-19.18s", skill_table[sn].name );
str_cat( &buf1, buf );
if( ++col % 4 == 0 )
str_cat( &buf1, "\n\r" );
}
}
if( col % 4 != 0 )
str_cat( &buf1, "\n\r" );
page_to_char( buf1, ch );
free( buf1 );
return;
}
/*****************************************************************************
Name: show_spec_cmds
Purpose: Displays settable special functions.
Called by: show_help(olc_act.c).
****************************************************************************/
void show_spec_cmds( CHAR_DATA *ch )
{
char buf[ MAX_STRING_LENGTH ];
char *buf1;
int spec;
int col;
buf1 = NULL;
col = 0;
send_to_char( "Preceed special functions with 'spec_'\n\r\n\r", ch );
for( spec = 0 ; *spec_table[spec].spec_fun ; spec++ )
{
sprintf( buf, "%-19.18s", &spec_table[spec].spec_name[5] );
str_cat( &buf1, buf );
if( ++col % 4 == 0 )
str_cat( &buf1, "\n\r" );
}
if( col % 4 != 0 )
str_cat( &buf1, "\n\r" );
page_to_char( buf1, ch );
free( buf1 );
return;
}
/*****************************************************************************
Name: show_help
Purpose: Displays help for many tables used in OLC.
Called by: olc interpreters.
****************************************************************************/
bool show_help( CHAR_DATA *ch, char *argument )
{
char buf[ MAX_STRING_LENGTH ];
char arg[ MAX_INPUT_LENGTH ];
char spell[ MAX_INPUT_LENGTH ];
int cnt;
argument = one_argument( argument, arg );
one_argument( argument, spell );
/*
* Display syntax.
*/
if( arg[0] == '\0' )
{
send_to_char( "Syntax: ? [command]\n\r\n\r", ch );
send_to_char( "[command] [description]\n\r", ch );
for( cnt = 0 ; help_table[cnt].command[0] != '\0' ; cnt++ )
{
sprintf( buf, "%-10.10s -%s\n\r",
capitalize( help_table[cnt].command ),
help_table[cnt].desc );
send_to_char( buf, ch );
}
return FALSE;
}
/*
* Find the command, show changeable data.
* ---------------------------------------
*/
for( cnt = 0 ; *help_table[cnt].command ; cnt++ )
{
if( arg[0] == help_table[cnt].command[0]
&& !str_prefix( arg, help_table[cnt].command ) )
{
if( help_table[cnt].structure == spec_table )
{
show_spec_cmds( ch );
return FALSE;
}
else
if( help_table[cnt].structure == skill_table )
{
if( spell[0] == '\0' )
{
send_to_char( "Syntax: ? spells "
"[ignore/attack/defend/self/object/all]\n\r", ch );
return FALSE;
}
if( !str_prefix( spell, "all" ) )
show_skill_cmds( ch, -1 );
else if( !str_prefix( spell, "ignore" ) )
show_skill_cmds( ch, TAR_IGNORE );
else if( !str_prefix( spell, "attack" ) )
show_skill_cmds( ch, TAR_CHAR_OFFENSIVE );
else if( !str_prefix( spell, "defend" ) )
show_skill_cmds( ch, TAR_CHAR_DEFENSIVE );
else if( !str_prefix( spell, "self" ) )
show_skill_cmds( ch, TAR_CHAR_SELF );
else if( !str_prefix( spell, "object" ) )
show_skill_cmds( ch, TAR_OBJ_INV );
else
send_to_char( "Syntax: ? spell "
"[ignore/attack/defend/self/object/all]\n\r", ch );
return FALSE;
}
else
{
show_flag_cmds( ch, help_table[cnt].structure );
return FALSE;
}
}
}
show_help( ch, "" );
return FALSE;
}
bool redit_mlist( CHAR_DATA *ch, char *argument )
{
MOB_INDEX_DATA *pMobIndex;
AREA_DATA *pArea;
char buf [ MAX_STRING_LENGTH ];
char *buf1;
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 = NULL;
fAll = !str_cmp( arg, "all" );
found = FALSE;
for( vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++ )
{
if( ( pMobIndex = get_mob_index( vnum ) ) )
{
if( fAll || is_name( arg, pMobIndex->player_name ) )
{
found = TRUE;
sprintf( buf, "[%5d] %-17.16s",
pMobIndex->vnum, capitalize( pMobIndex->short_descr ) );
str_cat( &buf1, buf );
if( ++col % 3 == 0 )
str_cat( &buf1, "\n\r" );
}
}
}
if( !found )
{
send_to_char( "Mobile(s) not found in this area.\n\r", ch);
return FALSE;
}
if( col % 3 != 0 )
str_cat( &buf1, "\n\r" );
page_to_char( buf1, ch );
free( buf1 );
return FALSE;
}
bool redit_olist( CHAR_DATA *ch, char *argument )
{
OBJ_INDEX_DATA *pObjIndex;
AREA_DATA *pArea;
char buf[ MAX_STRING_LENGTH ];
char *buf1;
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 = NULL;
fAll = !str_cmp( arg, "all" );
found = FALSE;
for( vnum = pArea->lvnum ; vnum <= pArea->uvnum ; vnum++ )
{
if( ( pObjIndex = get_obj_index( vnum ) ) )
{
if( fAll || is_name( arg, pObjIndex->name )
|| flag_value( type_flags, arg ) == pObjIndex->item_type )
{
found = TRUE;
sprintf( buf, "[%5d] %-17.16s",
pObjIndex->vnum, capitalize( pObjIndex->short_descr ) );
str_cat( &buf1, buf );
if ( ++col % 3 == 0 )
str_cat( &buf1, "\n\r" );
}
}
}
if( !found )
{
send_to_char( "Object(s) not found in this area.\n\r", ch);
return FALSE;
}
if( col % 3 != 0 )
str_cat( &buf1, "\n\r" );
send_to_char( buf1, ch );
free( buf1 );
return FALSE;
}
bool redit_mshow( CHAR_DATA *ch, 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 ) )
{
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, 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 ) )
{
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, char *argument )
{
AREA_DATA* pArea;
char buf[ MAX_STRING_LENGTH ];
char *buf1;
EDIT_AREA( ch, pArea );
buf1 = NULL;
sprintf( buf, "Name: [%5d] %s\n\r", pArea->vnum, pArea->name );
str_cat( &buf1, buf );
sprintf( buf, "Recall: [%5d] %s\n\r", pArea->recall,
get_room_index( pArea->recall )
? get_room_index( pArea->recall )->name : "none" );
str_cat( &buf1, buf );
sprintf( buf, "File: %s\n\r", pArea->filename );
str_cat( &buf1, buf );
sprintf( buf, "Vnums: [%d-%d]\n\r", pArea->lvnum, pArea->uvnum );
str_cat( &buf1, buf );
sprintf( buf, "Age: [%d]\n\r", pArea->age );
str_cat( &buf1, buf );
sprintf( buf, "Players: [%d]\n\r", pArea->nplayer );
str_cat( &buf1, buf );
sprintf( buf, "Security: [%d]\n\r", pArea->security );
str_cat( &buf1, buf );
sprintf( buf, "Builders: [%s]\n\r", pArea->builders );
str_cat( &buf1, buf );
sprintf( buf, "Flags: [%s]\n\r", flag_string( area_flags, pArea->area_flags ) );
str_cat( &buf1, buf );
page_to_char( buf1, ch );
free( buf1 );
return FALSE;
}
bool aedit_reset( CHAR_DATA *ch, char *argument )
{
AREA_DATA *pArea;
EDIT_AREA( ch, pArea );
reset_area( pArea );
send_to_char_bw( "Area reset.\n\r", ch );
return FALSE;
}
bool aedit_create( CHAR_DATA *ch, char *argument )
{
AREA_DATA *pArea;
if( top_area >= INT_MAX ) /* OLC 1.1b */
{
send_to_char_bw( "We're out of vnums for new areas.\n\r", ch );
return FALSE;
}
pArea = new_area( );
area_last->next = pArea;
area_last = pArea; /* Thanks, Walker. */
ch->desc->pEdit = ( void * )pArea;
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, 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_bw( "Name set.\n\r", ch );
return TRUE;
}
bool aedit_file( CHAR_DATA *ch, char *argument )
{
AREA_DATA *pArea;
char file[ MAX_STRING_LENGTH ];
int i;
int length;
EDIT_AREA( ch, pArea );
one_argument( argument, file ); /* Forces Lowercase */
if( argument[0] == '\0' )
{
send_to_char( "Syntax: filename [$file]\n\r", ch );
return FALSE;
}
/*
* Simple Syntax Check.
*/
length = strlen( argument );
/*
* 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;
}
}
free_string( pArea->filename );
strcat( file, ".are" );
pArea->filename = str_dup( file );
send_to_char( "Filename set.\n\r", ch );
return TRUE;
}
bool aedit_age( CHAR_DATA *ch, 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' )
{
send_to_char( "Syntax: age [#age]\n\r", ch );
return FALSE;
}
pArea->age = atoi( age );
send_to_char( "Age set.\n\r", ch );
return TRUE;
}
bool aedit_recall( CHAR_DATA *ch, 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_security( CHAR_DATA *ch, 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 || value < 0 )
{
if( ch->pcdata->security != 0 )
{
sprintf( buf, "Security is 0-%d.\n\r", ch->pcdata->security );
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, 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( strstr( pArea->builders, name ) != '\0' )
{
pArea->builders = string_replace( pArea->builders, name, "\0" );
pArea->builders = string_unpad( pArea->builders );
if( pArea->builders[0] == '\0' )
{
free_string( pArea->builders );
pArea->builders = str_dup( "None" );
}
send_to_char( "Builder removed.\n\r", ch );
return TRUE;
}
else
{
buf[0] = '\0';
if( strstr( pArea->builders, "None" ) != '\0' )
{
pArea->builders = string_replace( pArea->builders, "None", "\0" );
pArea->builders = string_unpad( pArea->builders );
}
if( pArea->builders[0] != '\0' )
{
strcat( buf, pArea->builders );
strcat( buf, " " );
}
strcat( buf, name );
free_string( pArea->builders );
pArea->builders = string_proper( str_dup( buf ) );
send_to_char( "Builder added.\n\r", ch );
return TRUE;
}
return FALSE;
}
bool aedit_vnum( CHAR_DATA *ch, 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, 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, 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, char *argument )
{
ROOM_INDEX_DATA *pRoom;
char buf[ MAX_STRING_LENGTH ];
char *buf1;
OBJ_DATA *obj;
CHAR_DATA *rch;
int door;
bool fcnt;
EDIT_ROOM( ch, pRoom );
buf1 = NULL;
sprintf( buf, "Description:\n\r%s", pRoom->description );
str_cat( &buf1, buf );
sprintf( buf, "Name: [%s]\n\rArea: [%5d] %s\n\r",
pRoom->name, pRoom->area->vnum, pRoom->area->name );
str_cat( &buf1, buf );
sprintf( buf, "Vnum: [%5d]\n\rSector: [%s]\n\r",
pRoom->vnum, flag_string( sector_flags, pRoom->sector_type ) );
str_cat( &buf1, buf );
sprintf( buf, "Room flags: [%s]\n\r",
flag_string( room_flags, pRoom->room_flags ) );
str_cat( &buf1, buf );
if( pRoom->extra_descr )
{
EXTRA_DESCR_DATA *ed;
str_cat( &buf1, "Desc Kwds: [" );
for( ed = pRoom->extra_descr ; ed ; ed = ed->next )
{
str_cat( &buf1, ed->keyword );
if( ed->next )
str_cat( &buf1, " " );
}
str_cat( &buf1, "]\n\r" );
}
str_cat( &buf1, "Characters: [" );
fcnt = FALSE;
for( rch = pRoom->people ; rch ; rch = rch->next_in_room )
{
one_argument( rch->name, buf );
str_cat( &buf1, buf );
str_cat( &buf1, " " );
fcnt = TRUE;
}
if( fcnt )
{
int end;
end = strlen(buf1) - 1;
buf1[end] = ']';
str_cat( &buf1, "\n\r" );
}
else
str_cat( &buf1, "none]\n\r" );
str_cat( &buf1, "Objects: [" );
fcnt = FALSE;
for( obj = pRoom->contents ; obj ; obj = obj->next_content )
{
one_argument( obj->name, buf );
str_cat( &buf1, buf );
str_cat( &buf1, " " );
fcnt = TRUE;
}
if( fcnt )
{
int end;
end = strlen(buf1) - 1;
buf1[end] = ']';
str_cat( &buf1, "\n\r" );
}
else
str_cat( &buf1, "none]\n\r" );
for( door = 0 ; door < MAX_DIR ; door++ )
{
EXIT_DATA *pexit;
if( ( pexit = pRoom->exit[door] ) )
{
char word[ MAX_INPUT_LENGTH ];
char reset_state[ MAX_STRING_LENGTH ];
char *state;
int i;
int length;
sprintf( buf, "-%-5s to [%5d] Key: [%5d]",
capitalize(dir_name[door]),
pexit->to_room ? pexit->to_room->vnum : 0,
pexit->key );
str_cat( &buf1, buf );
/*
* Format up the exit info.
* Capitalize all flags that are not part of the reset info.
*/
strcpy( reset_state, flag_string( exit_flags, pexit->rs_flags ) );
state = flag_string( exit_flags, pexit->exit_info );
str_cat( &buf1, " Exit flags: [" );
for( ; ; )
{
state = one_argument( state, word );
if( word[0] == '\0' )
{
int end;
end = strlen(buf1) - 1;
buf1[end] = ']';
str_cat( &buf1, "\n\r" );
break;
}
if( str_infix( word, reset_state ) )
{
length = strlen(word);
for( i = 0 ; i < length ; i++ )
word[i] = toupper( word[i] );
}
str_cat( &buf1, word );
str_cat( &buf1, " " );
}
if( pexit->keyword && pexit->keyword[0] != '\0' )
{
sprintf( buf, "Kwds: [%s]\n\r", pexit->keyword );
str_cat( &buf1, buf );
}
if( pexit->description && pexit->description[0] != '\0' )
{
sprintf( buf, "%s", pexit->description );
str_cat( &buf1, buf );
}
}
}
page_to_char( buf1, ch );
free( buf1 );
return FALSE;
}
/* 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, char *argument, int door )
{
ROOM_INDEX_DATA *pRoom;
char command[MAX_INPUT_LENGTH];
char arg[MAX_INPUT_LENGTH];
char total_arg[MAX_STRING_LENGTH];
int value = 0;
int rev;
EDIT_ROOM( ch, pRoom );
/* Often used data. */
rev = rev_dir[door];
if( !argument )
{
do_help( ch, "EXIT" );
return FALSE;
}
/*
* Now parse the arguments.
*/
strcpy( total_arg, argument );
argument = one_argument( argument, command );
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->exit[rev] )
{
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]->to_room = pLinkRoom; /* Assign data. */
pRoom->exit[door]->vnum = value;
pExit = new_exit(); /* No remote exit. */
pExit->to_room = ch->in_room; /* Assign data. */
pExit->vnum = ch->in_room->vnum;
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]->to_room = pLinkRoom;
pRoom->exit[door]->vnum = value;
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( argument, "key" ) )
{
pRoom->exit[door]->key = 0;
send_to_char( "Exit key removed.\n\r", ch );
return TRUE;
}
if( !str_cmp( argument, "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( argument[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" ) )
{
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]->key = pObjIndex->vnum;
send_to_char( "Exit key set.\n\r", ch );
return TRUE;
}
if( !str_cmp( command, "name" ) )
{
if( arg[0] == '\0' )
{
send_to_char( "Syntax: [direction] name [string]\n\r", ch );
return FALSE;
}
if( !pRoom->exit[door] )
pRoom->exit[door] = new_exit();
free_string( pRoom->exit[door]->keyword );
pRoom->exit[door]->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();
string_append( 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( ( value = flag_value( exit_flags, total_arg ) ) != NO_FLAG )
{
ROOM_INDEX_DATA *pToRoom;
/*
* Create an exit if none exists.
*/
if( !pRoom->exit[door] )
pRoom->exit[door] = new_exit();
/*
* 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, char *argument )
{
if( change_exit( ch, argument, DIR_NORTH ) )
return TRUE;
return FALSE;
}
bool redit_northeast( CHAR_DATA *ch, char *argument )
{
if( change_exit( ch, argument, DIR_NORTHEAST ) )
return TRUE;
return FALSE;
}
bool redit_northwest( CHAR_DATA *ch, char *argument )
{
if( change_exit( ch, argument, DIR_NORTHWEST ) )
return TRUE;
return FALSE;
}
bool redit_south( CHAR_DATA *ch, char *argument )
{
if( change_exit( ch, argument, DIR_SOUTH ) )
return TRUE;
return FALSE;
}
bool redit_southeast( CHAR_DATA *ch, char *argument )
{
if( change_exit( ch, argument, DIR_SOUTHEAST ) )
return TRUE;
return FALSE;
}
bool redit_southwest( CHAR_DATA *ch, char *argument )
{
if( change_exit( ch, argument, DIR_SOUTHWEST ) )
return TRUE;
return FALSE;
}
bool redit_east( CHAR_DATA *ch, char *argument )
{
if( change_exit( ch, argument, DIR_EAST ) )
return TRUE;
return FALSE;
}
bool redit_west( CHAR_DATA *ch, char *argument )
{
if( change_exit( ch, argument, DIR_WEST ) )
return TRUE;
return FALSE;
}
bool redit_up( CHAR_DATA *ch, char *argument )
{
if( change_exit( ch, argument, DIR_UP ) )
return TRUE;
return FALSE;
}
bool redit_down( CHAR_DATA *ch, char *argument )
{
if( change_exit( ch, argument, DIR_DOWN ) )
return TRUE;
return FALSE;
}
/* OLC 1.1b */
bool redit_move( CHAR_DATA *ch, char *argument )
{
interpret( ch, argument, FALSE );
return FALSE;
}
bool redit_ed( CHAR_DATA *ch, char *argument )
{
EXTRA_DESCR_DATA *ed;
ROOM_INDEX_DATA *pRoom;
char command[ MAX_INPUT_LENGTH ];
char keyword[ MAX_INPUT_LENGTH ];
EDIT_ROOM( ch, pRoom );
argument = one_argument( argument, command );
one_argument( argument, keyword );
if( command[0] == '\0' || keyword[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( keyword[0] == '\0' )
{
send_to_char( "Syntax: ed add [keyword]\n\r", ch );
return FALSE;
}
ed = new_extra_descr();
ed->keyword = str_dup( keyword );
ed->description = str_dup( "" );
ed->next = pRoom->extra_descr;
pRoom->extra_descr = ed;
string_append( ch, &ed->description );
return TRUE;
}
if( !str_cmp( command, "edit" ) )
{
if( keyword[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( keyword, ed->keyword ) )
break;
}
if( !ed )
{
send_to_char( "REdit: Extra description keyword not found.\n\r", ch );
return FALSE;
}
string_append( ch, &ed->description );
return TRUE;
}
if( !str_cmp( command, "delete" ) )
{
EXTRA_DESCR_DATA *ped = NULL;
if( keyword[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( keyword, 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( keyword[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( keyword, 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 - 20 ) )
{
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, char *argument )
{
ROOM_INDEX_DATA *pRoom;
AREA_DATA *pArea;
int value;
int iHash;
EDIT_ROOM( ch, pRoom );
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;
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, 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_light( CHAR_DATA *ch, char *argument )
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM( ch, pRoom );
if( argument[0] == '\0' || !is_number( argument ) )
{
send_to_char( "Syntax: light [#intensity]\n\r", ch );
return FALSE;
}
pRoom->light = atoi( argument );
send_to_char( "Light Intensity Set.\n\r", ch );
return TRUE;
}
bool redit_desc( CHAR_DATA *ch, char *argument )
{
ROOM_INDEX_DATA *pRoom;
EDIT_ROOM( ch, pRoom );
if( argument[0] == '\0' )
{
string_append( ch, &pRoom->description );
return TRUE;
}
send_to_char( "Syntax: desc\n\r", ch );
return FALSE;
}
bool redit_format( CHAR_DATA *ch, 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, char *argument )
{
ROOM_INDEX_DATA *pRoom;
MOB_INDEX_DATA *pMobIndex;
RESET_DATA *pReset;
CHAR_DATA *newmob;
char arg[ MAX_INPUT_LENGTH ];
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;
pReset->arg3 = pRoom->vnum;
add_reset( pRoom, pReset, 0/* Last slot*/ );
/*
* Create the mobile.
*/
newmob = create_mobile( pMobIndex );
char_to_room( newmob, pRoom );
sprintf( output, "%s (%d) has been loaded and added to resets.\n\r"
"There will be a maximum of %d loaded to this room.\n\r",
capitalize( pMobIndex->short_descr ),
pMobIndex->vnum,
pReset->arg2 );
send_to_char( output, ch );
act( "$n has created $N!", ch, NULL, newmob, TO_ROOM );
return TRUE;
}
struct wear_type
{
int wear_loc;
int wear_bit;
};
const struct wear_type wear_table[] =
{
{ WEAR_NONE, ITEM_TAKE },
{ WEAR_LIGHT, ITEM_LIGHT },
{ WEAR_FINGER_L, ITEM_WEAR_FINGER },
{ WEAR_FINGER_R, ITEM_WEAR_FINGER },
{ WEAR_NECK_1, ITEM_WEAR_NECK },
{ WEAR_NECK_2, ITEM_WEAR_NECK },
{ WEAR_BODY, ITEM_WEAR_BODY },
{ WEAR_HEAD, ITEM_WEAR_HEAD },
{ WEAR_LEGS, ITEM_WEAR_LEGS },
{ WEAR_FEET, ITEM_WEAR_FEET },
{ WEAR_HANDS, ITEM_WEAR_HANDS },
{ WEAR_ARMS, ITEM_WEAR_ARMS },
{ WEAR_SHIELD, ITEM_WEAR_SHIELD },
{ WEAR_ABOUT, ITEM_WEAR_ABOUT },
{ WEAR_WAIST, ITEM_WEAR_WAIST },
{ WEAR_WRIST_L, ITEM_WEAR_WRIST },
{ WEAR_WRIST_R, ITEM_WEAR_WRIST },
{ WEAR_WIELD, ITEM_WIELD },
{ WEAR_HOLD, ITEM_HOLD },
{ 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[flag].wear_bit != NO_FLAG ; flag++ )
{
if( IS_SET( bits, wear_table[flag].wear_bit )
&& --count < 1 )
return wear_table[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[flag].wear_loc != NO_FLAG ; flag++ )
{
if( loc == wear_table[flag].wear_loc )
return wear_table[flag].wear_bit;
}
return 0;
}
bool redit_oreset( CHAR_DATA *ch, char *argument )
{
ROOM_INDEX_DATA *pRoom;
OBJ_INDEX_DATA *pObjIndex;
RESET_DATA *pReset;
CHAR_DATA *to_mob;
OBJ_DATA *newobj;
OBJ_DATA *to_obj;
char arg1[ MAX_INPUT_LENGTH ];
char arg2[ MAX_INPUT_LENGTH ];
char output[ MAX_STRING_LENGTH ];
int olevel = 0;
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_args = 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;
pReset->arg3 = pRoom->vnum;
add_reset( pRoom, pReset, 0/* Last slot*/ );
newobj = create_object( pObjIndex );
obj_to_room( newobj, pRoom );
sprintf( output, "%s (%d) has been loaded and added to resets.\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 ) ) != NULL ) )
{
pReset = new_reset_data();
pReset->command = 'P';
pReset->arg1 = pObjIndex->vnum;
pReset->arg2 = 0;
pReset->arg3 = to_obj->pIndexData->vnum;
add_reset( pRoom, pReset, 0/* Last slot*/ );
newobj = create_object( pObjIndex );
newobj->cost = 0;
obj_to_obj( newobj, to_obj );
sprintf( output, "%s (%d) has been loaded into "
"%s (%d) and added to resets.\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( ( wear_loc = flag_value( 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,
"%s (%d) has wear flags: [%s]\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( 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';
pReset->arg3 = wear_loc;
add_reset( pRoom, pReset, 0/* Last slot*/ );
olevel = 0;
newobj = create_object( pObjIndex );
if( to_mob->pIndexData->pShop ) /* Shop-keeper? */
{
olevel = 0;
newobj = create_object( pObjIndex );
if( pReset->arg2 == WEAR_NONE )
SET_BIT( newobj->extra_flags, ITEM_INVENTORY );
}
else
newobj = create_object( pObjIndex );
obj_to_char( newobj, to_mob );
if( pReset->command == 'E' )
equip_char( to_mob, newobj, pReset->arg3 );
sprintf( output, "%s (%d) has been loaded "
"%s of %s (%d) and added to resets.\n\r",
capitalize( pObjIndex->short_descr ),
pObjIndex->vnum,
flag_string( wear_loc_strings, pReset->arg3 ),
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( "$n has created $p!", ch, newobj, NULL, TO_ROOM );
return TRUE;
}
/*
* Object Editor Functions.
* Updated -Ant, Mar '96.
*/
void show_obj_values( CHAR_DATA *ch, OBJ_INDEX_DATA *obj )
{
char buf[ MAX_STRING_LENGTH ];
char *buf1;
bool found;
int i;
found = FALSE;
buf1 = NULL;
if( IS_SET( obj->item_type, ITEM_SCROLL ) )
{
sprintf( buf, "Scroll Level %d spells of:", obj->scroll->level );
str_cat( &buf1, buf );
for( i = 0 ; i < 4 ; i++ )
{
if( obj->scroll->spell[i] >= 0 && obj->scroll->spell[i] < MAX_SKILL )
{
sprintf( buf, " '%s'",
skill_table[obj->scroll->spell[i]].name );
str_cat( &buf1, buf );
}
}
str_cat( &buf1, ".\n\r" );
found = TRUE;
}
if( IS_SET( obj->item_type, ITEM_POTION ) )
{
sprintf( buf, "Potion Level %d spells of:", obj->potion->level );
str_cat( &buf1, buf );
for( i = 0 ; i < 4 ; i++ )
{
if( obj->potion->spell[i] >= 0 && obj->potion->spell[i] < MAX_SKILL )
{
sprintf( buf, " '%s'",
skill_table[obj->potion->spell[i]].name );
str_cat( &buf1, buf );
}
}
str_cat( &buf1, ".\n\r" );
found = TRUE;
}
if( IS_SET( obj->item_type, ITEM_PILL ) )
{
sprintf( buf, "Pill Level %d spells of:", obj->pill->level );
str_cat( &buf1, buf );
for( i = 0 ; i < 4 ; i++ )
{
if( obj->pill->spell[i] >= 0 && obj->pill->spell[i] < MAX_SKILL )
{
sprintf( buf, " '%s'",
skill_table[obj->pill->spell[i]].name );
str_cat( &buf1, buf );
}
}
str_cat( &buf1, ".\n\r" );
found = TRUE;
}
if( IS_SET( obj->item_type, ITEM_WAND ) )
{
sprintf( buf, "Wand has %d(%d) charges of level %d",
obj->wand->charges,
obj->wand->max,
obj->wand->level );
str_cat( &buf1, buf );
if( obj->wand->spell >= 0 && obj->wand->spell < MAX_SKILL )
{
sprintf( buf, " '%s'",
skill_table[obj->wand->spell].name );
str_cat( &buf1, buf );
}
str_cat( &buf1, ".\n\r" );
found = TRUE;
}
if( IS_SET( obj->item_type, ITEM_STAFF ) )
{
sprintf( buf, "Staff has %d(%d) charges of level %d",
obj->staff->charges,
obj->staff->max,
obj->staff->level );
str_cat( &buf1, buf );
if( obj->staff->spell >= 0 && obj->staff->spell < MAX_SKILL )
{
sprintf( buf, " '%s'",
skill_table[obj->staff->spell].name );
str_cat( &buf1, buf );
}
str_cat( &buf1, ".\n\r" );
found = TRUE;
}
if( IS_SET( obj->item_type, ITEM_ARMOUR ) )
{
sprintf( buf,
"Armor class is %d pierce, %d bash, %d slash, and %d vs. magic\n\r",
obj->armour->ac[ 0 ],
obj->armour->ac[ 1 ],
obj->armour->ac[ 2 ],
obj->armour->ac[ 3 ] );
str_cat( &buf1, buf );
found = TRUE;
}
if( IS_SET( obj->item_type, ITEM_LIGHT ) )
{
if( obj->light->duration == -1 )
sprintf( buf, "Hours of light: Infinite(-1)\n\r" );
else
sprintf( buf, "Hours of light: %d\n\r", obj->light->duration );
str_cat( &buf1, buf );
sprintf( buf, "Intensity: %d\n\r", obj->light->intensity );
str_cat( &buf1, buf );
found = TRUE;
}
if( IS_SET( obj->item_type, ITEM_CONTAINER ) )
{
sprintf( buf, "Capacity: %d \n\rFlags : %s\n\rKey : %s (%d)\n\r",
obj->cont->capacity,
flag_string( container_flags, obj->cont->closed ),
get_obj_index( obj->cont->key )
? get_obj_index( obj->cont->key )->short_descr
: "none",
obj->cont->key );
str_cat( &buf1, buf );
found = TRUE;
}
if( IS_SET( obj->item_type, ITEM_DRINK_CON ) )
{
sprintf( buf, "Contains : %d/%d\n\rLiquid : %s\n\rPoisoned? : %s\n\r",
obj->drink->volume,
obj->drink->limit,
flag_string( liquid_flags, obj->drink->liquid ),
obj->drink->poison != 0 ? "Yes" : "No" );
str_cat( &buf1, buf );
found = TRUE;
}
if( IS_SET( obj->item_type, ITEM_FOOD ) )
{
sprintf( buf, "Hours of food : %d\n\rPoisoned? : %s\n\r",
obj->food->bite,
obj->food->poison != 0 ? "Yes" : "No" );
str_cat( &buf1, buf );
found = TRUE;
}
if( IS_SET( obj->item_type, ITEM_MONEY ) )
{
sprintf( buf, "Amount of Gold/Silver/Copper (v0): %d/%d/%d\n\r",
obj->money->gold,
obj->money->silver,
obj->money->copper );
str_cat( &buf1, buf );
found = TRUE;
}
if( IS_SET( obj->item_type, ITEM_WEAPON ) )
{
str_cat( &buf1, "Weapon type is " );
switch( obj->weapon->type )
{
case( WEAPON_EXOTIC ):
str_cat( &buf1, "exotic\n\r" );
break;
case( WEAPON_SWORD ):
str_cat( &buf1, "sword\n\r" );
break;
case( WEAPON_DAGGER ):
str_cat( &buf1, "dagger\n\r" );
break;
case( WEAPON_SPEAR ):
str_cat( &buf1, "spear\n\r" );
break;
case( WEAPON_MACE ):
str_cat( &buf1, "mace/club\n\r" );
break;
case( WEAPON_AXE ):
str_cat( &buf1, "axe\n\r" );
break;
case( WEAPON_POLEARM ):
str_cat( &buf1, "polearm\n\r" );
break;
default:
str_cat( &buf1, "unknown\n\r" );
break;
}
if( obj->weapon->hit )
{
sprintf( buf, "Hit Bonus is %d\n\r",
obj->weapon->hit );
str_cat( &buf1, buf );
}
sprintf( buf, "Damage is %dd%d+%d (average %d) '%s'\n\r",
obj->weapon->damage[0],
obj->weapon->damage[1],
obj->weapon->damage[2],
( ( 1 + obj->weapon->damage[1] )
* obj->weapon->damage[0] / 2 ) + obj->weapon->damage[2],
flag_string( weapon_flags, obj->weapon->message ) );
str_cat( &buf1, buf );
if( obj->weapon->flags )
{
sprintf( buf, "Weapons flags: %s\n\r",
flag_string( weapon_extra, obj->weapon->flags ) );
}
found = TRUE;
}
if( !found )
{
sprintf( buf, "None Of The Objects Types Require Values\n\r" );
str_cat( &buf1, buf );
}
page_to_char_bw( buf1, ch );
free( buf1 );
return;
}
bool set_obj_values( CHAR_DATA *ch, OBJ_INDEX_DATA *pObj, int value_num, char *argument)
{
show_obj_values( ch, pObj );
return TRUE;
}
bool oedit_show( CHAR_DATA *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *paf;
char buf[MAX_STRING_LENGTH];
int cnt;
EDIT_OBJ( ch, pObj );
sprintf( buf, "Name: [%s]\n\rArea: [%5d] %s\n\r",
pObj->name,
!pObj->area ? -1 : pObj->area->vnum,
!pObj->area ? "No Area" : pObj->area->name );
send_to_char( buf, ch );
sprintf( buf, "Vnum: [%5d]\n\rType: [%s]\n\r",
pObj->vnum,
flag_string( type_flags, pObj->item_type ) );
send_to_char( buf, ch );
sprintf( buf, "Wear flags: [%s]\n\r",
flag_string( wear_flags, pObj->wear_flags ) );
send_to_char( buf, ch );
sprintf( buf, "Extra flags: [%s]\n\r",
flag_string( extra_flags, pObj->extra_flags ) );
send_to_char( buf, ch );
sprintf( buf, "Weight: [%d]\n\rCost: [%d]\n\r",
pObj->weight, pObj->cost );
send_to_char( buf, ch );
if ( pObj->extra_descr )
{
EXTRA_DESCR_DATA *ed;
send_to_char( "Ex desc kwd: ", ch );
for ( ed = pObj->extra_descr; ed; ed = ed->next )
{
send_to_char( "[", ch );
send_to_char( ed->keyword, ch );
send_to_char( "]", ch );
}
send_to_char( "\n\r", ch );
}
sprintf( buf, "Short desc: %s\n\rLong desc:\n\r %s\n\r",
pObj->short_descr, pObj->description );
send_to_char( buf, ch );
for ( cnt = 0, paf = pObj->affected; paf; paf = paf->next )
{
if ( cnt == 0 )
{
send_to_char( "Number Modifier Affects\n\r", ch );
send_to_char( "------ -------- -------\n\r", ch );
}
sprintf( buf, "[%4d] %-8d %s\n\r", cnt,
paf->modifier,
flag_string( apply_flags, paf->location ) );
send_to_char( buf, ch );
cnt++;
}
show_obj_values( ch, pObj );
return FALSE;
}
/*
* Need to issue warning if flag isn't valid.
*/
bool oedit_addaffect( CHAR_DATA *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
char loc[MAX_STRING_LENGTH];
char mod[MAX_STRING_LENGTH];
EDIT_OBJ(ch, pObj);
argument = one_argument( argument, loc );
one_argument( argument, mod );
if ( loc[0] == '\0' || mod[0] == '\0' || !is_number( mod ) )
{
send_to_char( "Syntax: addaffect [location] [#mod]\n\r", ch );
return FALSE;
}
pAf = new_affect();
pAf->location = flag_value( apply_flags, loc );
pAf->modifier = atoi( mod );
pAf->type = -1;
pAf->duration = -1;
pAf->bitvector = 0;
pAf->next = pObj->affected;
pObj->affected = pAf;
send_to_char( "Affect 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, 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, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: name [string]\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, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: short [string]\n\r", ch );
return FALSE;
}
free_string( pObj->short_descr );
pObj->short_descr = str_dup( argument );
pObj->short_descr[0] = LOWER( pObj->short_descr[0] );
send_to_char( "Short description set.\n\r", ch);
return TRUE;
}
bool oedit_long( CHAR_DATA *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' )
{
send_to_char( "Syntax: long [string]\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 set_value( CHAR_DATA *ch, OBJ_INDEX_DATA *pObj, 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;
}
bool oedit_weight( CHAR_DATA *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' || !is_number( argument ) )
{
send_to_char( "Syntax: weight [number]\n\r", ch );
return FALSE;
}
pObj->weight = atoi( argument );
send_to_char( "Weight set.\n\r", ch);
return TRUE;
}
bool oedit_requires( CHAR_DATA *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
char stat[ MAX_INPUT_LENGTH ];
char buf[ MAX_INPUT_LENGTH ];
sh_int value = 0;
EDIT_OBJ( ch, pObj );
argument = one_argument( argument, stat );
one_argument( argument, buf );
if( stat[ 0 ] == '\0' || buf[ 0 ] == '\0' || !is_number( buf ) )
{
send_to_char( "Syntax: requires <{cstat{x> <{cvalue{x>\n\r", ch );
return FALSE;
}
value = atoi( buf );
if( !strcmp( stat, "str" ) )
{
pObj->requires[ 0 ] = value;
send_to_char_bw( "Requirement set.\n\r", ch);
return TRUE;
}
else if( !strcmp( stat, "int" ) )
{
pObj->requires[ 1 ] = value;
send_to_char_bw( "Requirement set.\n\r", ch);
return TRUE;
}
else if( !strcmp( stat, "wis" ) )
{
pObj->requires[ 2 ] = value;
send_to_char_bw( "Requirement set.\n\r", ch);
return TRUE;
}
else if( !strcmp( stat, "dex" ) )
{
pObj->requires[ 3 ] = value;
send_to_char_bw( "Requirement set.\n\r", ch);
return TRUE;
}
else if( !strcmp( stat, "con" ) )
{
pObj->requires[ 4 ] = value;
send_to_char_bw( "Requirement set.\n\r", ch);
return TRUE;
}
send_to_char_bw( "Unknown Statistic, choose from: str int wis dex con\n\r", ch );
send_to_char( "Syntax: requires <{cstat{x> <{cvalue{x>\n\r", ch );
return FALSE;
}
bool oedit_cost( CHAR_DATA *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ( ch, pObj );
if( argument[0] == '\0' || !is_number( argument ) )
{
send_to_char( "Syntax: cost [number]\n\r", ch );
return FALSE;
}
pObj->cost = atoi( argument );
send_to_char( "Cost set.\n\r", ch);
return TRUE;
}
bool oedit_create( CHAR_DATA *ch, 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;
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 Created.\n\r", ch );
return TRUE;
}
bool oedit_ed( CHAR_DATA *ch, char *argument )
{
EXTRA_DESCR_DATA *ed;
OBJ_INDEX_DATA *pObj;
char command[MAX_INPUT_LENGTH];
char keyword[MAX_INPUT_LENGTH];
EDIT_OBJ( ch, pObj );
argument = one_argument( argument, command );
one_argument( argument, keyword );
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( keyword[0] == '\0' )
{
send_to_char( "Syntax: ed add [keyword]\n\r", ch );
return FALSE;
}
ed = new_extra_descr();
ed->keyword = str_dup( keyword );
ed->next = pObj->extra_descr;
pObj->extra_descr = ed;
string_append( ch, &ed->description );
return TRUE;
}
if( !str_cmp( command, "edit" ) )
{
if( keyword[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( keyword, ed->keyword ) )
break;
}
if( !ed )
{
send_to_char( "OEdit: Extra description keyword not found.\n\r", ch );
return FALSE;
}
string_append( ch, &ed->description );
return TRUE;
}
if( !str_cmp( command, "delete" ) )
{
EXTRA_DESCR_DATA *ped = NULL;
if( keyword[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( keyword, 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" ) )
{
EXTRA_DESCR_DATA *ped = NULL;
if( keyword[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( keyword, ed->keyword ) )
break;
ped = ed;
}
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, char *argument )
{
MOB_INDEX_DATA *pMob;
char buf[MAX_STRING_LENGTH];
EDIT_MOB( ch, pMob );
sprintf( buf, "Name: [%s]\n\rArea: [%5d] %s\n\r",
pMob->player_name,
!pMob->area ? -1 : pMob->area->vnum,
!pMob->area ? "No Area" : pMob->area->name );
send_to_char( buf, ch );
sprintf( buf, "Act: [%s]\n\r",
flag_string( act_flags, pMob->act ) );
send_to_char( buf, ch );
sprintf( buf, "Vnum: [%5d]\n\rSex: [%s]\n\r",
pMob->vnum,
pMob->sex == SEX_MALE ? "male" :
pMob->sex == SEX_FEMALE ? "female" : "neutral" );
send_to_char( buf, ch );
sprintf( buf,
"Align: [%4d]\n\r",
pMob->alignment );
send_to_char( buf, ch );
sprintf( buf, "Affected by: [%s]\n\r",
flag_string( affect_flags, pMob->affected_by ) );
send_to_char( buf, ch );
if ( pMob->spec_fun )
{
sprintf( buf, "Spec fun: [%s]\n\r", spec_string( pMob->spec_fun ) );
send_to_char( buf, ch );
}
sprintf( buf, "Short descr: %s\n\rLong descr:\n\r%s",
pMob->short_descr,
pMob->long_descr );
send_to_char( buf, ch );
sprintf( buf, "Description:\n\r%s", pMob->description );
send_to_char( buf, ch );
if ( pMob->pShop )
{
SHOP_DATA *pShop;
int iTrade;
pShop = pMob->pShop;
sprintf( buf,
"Shop data for [%5d]:\n\r"
" Markup for purchaser: %d%%\n\r"
" Markdown for seller: %d%%\n\r",
pShop->keeper, pShop->profit_buy, pShop->profit_sell );
send_to_char( buf, ch );
sprintf( buf, " Hours: %d to %d.\n\r",
pShop->open_hour, pShop->close_hour );
send_to_char( buf, ch );
for ( iTrade = 0; iTrade < MAX_TRADE; iTrade++ )
{
if ( pShop->buy_type[iTrade] != 0 )
{
if ( iTrade == 0 ) {
send_to_char( " Number Trades Type\n\r", ch );
send_to_char( " ------ -----------\n\r", ch );
}
sprintf( buf, " [%4d] %s\n\r", iTrade,
flag_string( type_flags, pShop->buy_type[iTrade] ) );
send_to_char( buf, ch );
}
}
}
return FALSE;
}
bool medit_create( CHAR_DATA *ch, 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;
if ( value > top_vnum_mob )
top_vnum_mob = value;
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;
send_to_char( "Mobile Created.\n\r", ch );
return TRUE;
}
bool medit_spec( CHAR_DATA *ch, 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 = NULL;
send_to_char( "Spec removed.\n\r", ch);
return TRUE;
}
if ( spec_lookup( argument ) )
{
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_align( CHAR_DATA *ch, char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB(ch, pMob);
if ( argument[0] == '\0' || !is_number( argument ) )
{
send_to_char( "Syntax: alignment [number]\n\r", ch );
return FALSE;
}
pMob->alignment = atoi( argument );
send_to_char( "Alignment set.\n\r", ch);
return TRUE;
}
bool medit_race( CHAR_DATA *ch, char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB( ch, pMob );
if( argument[0] == '\0' )
{
send_to_char_bw( "Syntax: race <race name>\n\r", ch );
return FALSE;
}
if( !( pMob->race = race_lookup_olc( argument ) ) );
{
send_to_char_bw( "Unknown Race, rejected.\n\r", ch );
return FALSE;
}
send_to_char_bw( "Race set.\n\r", ch);
return TRUE;
}
bool medit_exp( CHAR_DATA *ch, char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB( ch, pMob );
if( argument[0] == '\0' || !is_number( argument ) )
{
send_to_char_bw( "Syntax: exp <number>\n\r", ch );
return FALSE;
}
pMob->exp = atoi( argument );
send_to_char_bw( "Experience Value Set.\n\r", ch );
return TRUE;
}
bool medit_desc( CHAR_DATA *ch, char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB(ch, pMob);
if ( argument[0] == '\0' )
{
string_append( ch, &pMob->description );
return TRUE;
}
send_to_char( "Syntax: desc - line edit\n\r", ch );
return FALSE;
}
bool medit_long( CHAR_DATA *ch, char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB(ch, pMob);
if ( argument[0] == '\0' )
{
send_to_char( "Syntax: long [string]\n\r", ch );
return FALSE;
}
free_string( pMob->long_descr );
strcat( argument, "\n\r" );
pMob->long_descr = str_dup( argument );
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, char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB(ch, pMob);
if ( argument[0] == '\0' )
{
send_to_char( "Syntax: short [string]\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, char *argument )
{
MOB_INDEX_DATA *pMob;
EDIT_MOB(ch, pMob);
if ( argument[0] == '\0' )
{
send_to_char( "Syntax: name [string]\n\r", ch );
return FALSE;
}
free_string( pMob->player_name );
pMob->player_name = str_dup( argument );
send_to_char( "Name set.\n\r", ch);
return TRUE;
}
bool medit_shop( CHAR_DATA *ch, 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();
pMob->pShop->keeper = pMob->vnum;
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();
pMob->pShop->keeper = pMob->vnum;
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 ( ( value = flag_value( type_flags, argument ) ) == NO_FLAG )
{
send_to_char( "REdit: That type of item is not known.\n\r", ch );
return FALSE;
}
if ( !pMob->pShop )
{
pMob->pShop = new_shop();
pMob->pShop->keeper = pMob->vnum;
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;
SHOP_DATA *pShop_next;
int value;
int cnt = 0;
if ( arg1[0] == '\0' || !is_number( arg1 ) )
{
send_to_char( "Syntax: shop delete [#0-4]\n\r", ch );
return FALSE;
}
value = atoi( argument );
if ( !pMob->pShop )
{
send_to_char( "REdit: Non-existant shop.\n\r", ch );
return FALSE;
}
if ( value == 0 )
{
pShop = pMob->pShop;
pMob->pShop = pMob->pShop->next;
free_shop( pShop );
}
else
for ( pShop = pMob->pShop, cnt = 0; pShop; pShop = pShop_next, cnt++ )
{
pShop_next = pShop->next;
if ( cnt+1 == value )
{
pShop->next = pShop_next->next;
free_shop( pShop_next );
break;
}
}
send_to_char( "Shop deleted.\n\r", ch);
return TRUE;
}
medit_shop( ch, "" );
return FALSE;
}