/*****************************************************************************
* DikuMUD (C) 1990, 1991 by: *
* Sebastian Hammer, Michael Seifert, Hans Henrik Staefeldt, Tom Madsen, *
* and Katja Nyboe. *
*---------------------------------------------------------------------------*
* MERC 2.1 (C) 1992, 1993 by: *
* Michael Chastain, Michael Quan, and Mitchell Tse. *
*---------------------------------------------------------------------------*
* SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by: Derek Snider. *
* Team: Thoric, Altrag, Blodkai, Narn, Haus, Scryn, Rennard, Swordbearer, *
* gorog, Grishnakh, Nivek, Tricops, and Fireblade. *
*---------------------------------------------------------------------------*
* SMAUG 1.7 FUSS by: Samson and others of the SMAUG community. *
* Their contributions are greatly appreciated. *
*---------------------------------------------------------------------------*
* LoP (C) 2006, 2007, 2008 by: the LoP team. *
*---------------------------------------------------------------------------*
* Online Building and Editing Module *
*****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "h/mud.h"
#include "h/sha256.h"
extern int top_affect;
extern int top_reset;
extern int top_ed;
extern bool fBootDb;
REL_DATA *first_relation = NULL, *last_relation = NULL;
void save_deity( DEITY_DATA *deity );
void update_level( CHAR_DATA *ch );
void set_gold( CHAR_DATA *ch, int amount );
char *show_big_nums( int millions, int amount );
bool char_is_class( CHAR_DATA *ch, int cnum );
void remove_clan_member( CLAN_DATA *clan, char *name );
void add_clan_member( CLAN_DATA *clan, char *name );
void remove_council_member( COUNCIL_DATA *council, char *name );
void add_council_member( COUNCIL_DATA *council, char *name );
bool check_area_conflict( AREA_DATA *carea, int low_range, int hi_range );
char *sprint_reset( RESET_DATA *pReset, short *num );
void fix_exits( void );
bool validate_spec_fun( char *name );
/*
* Exit Pull/push types
* (water, air, earth, fire)
*/
const char *ex_pmisc[] = { "undefined", "vortex", "vacuum", "slip", "ice", "mysterious" };
const char *ex_pwater[] = { "current", "wave", "whirlpool", "geyser" };
const char *ex_pair[] = { "wind", "storm", "coldwind", "breeze" };
const char *ex_pearth[] = { "landslide", "sinkhole", "quicksand", "earthquake" };
const char *ex_pfire[] = { "lava", "hotair" };
const char *trig_flags[] =
{
"up", "unlock", "lock", "d_north", "d_south",
"d_east", "d_west", "d_up", "d_down", "d_northeast",
"d_northwest", "d_southeast", "d_southwest", "d_somewhere", "door",
"container", "open", "close", "passage", "oload",
"mload", "teleport", "teleportall", "teleportplus", "death",
"cast", "rand4", "rand6", "rand10", "rand11",
"showroomdesc", "autoreturn"
};
int get_trigflag( char *flag )
{
unsigned int x;
for( x = 0; x < ( sizeof( trig_flags ) / sizeof( trig_flags[0] ) ); x++ )
if( !str_cmp( flag, trig_flags[x] ) )
return x;
return -1;
}
const char *cont_flags[] =
{
"closeable", "pickproof", "closed", "locked", "eatkey",
"r6", "r7", "r8", "r9", "r10",
"r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20",
"r21", "r22", "r23", "r24", "r25",
"r26", "r27", "r28", "r29", "r30",
"r31", "r32"
};
int get_contflag( char *flag )
{
unsigned int x;
for( x = 0; x < ( sizeof( cont_flags ) / sizeof( cont_flags[0] ) ); x++ )
if( !str_cmp( flag, cont_flags[x] ) )
return x;
return -1;
}
/*
* Note: I put them all in one big set of flags since almost all of these
* can be shared between mobs, objs and rooms for the exception of
* bribe and hitprcnt, which will probably only be used on mobs.
* ie: drop -- for an object, it would be triggered when that object is
* dropped; -- for a room, it would be triggered when anything is dropped
* -- for a mob, it would be triggered when anything is dropped
*
* Something to consider: some of these triggers can be grouped together,
* and differentiated by different arguments... for example:
* hour and time, rand and randiw, speech and speechiw
*
*/
const char *mprog_flags[] =
{
"act", "speech", "rand", "fight", "death",
"hitprcnt", "entry", "greet", "allgreet", "give",
"bribe", "hour", "time", "wear", "remove",
"sac", "look", "exa", "zap", "get",
"drop", "damage", "repair", "pull", "push",
"sleep", "rest", "leave", "script", "use",
"scrap", "open", "close", "put"
};
char *flag_string( int bitvector, const char *flagarray[] )
{
static char buf[MSL];
int x;
buf[0] = '\0';
for( x = 0; x < 32; x++ )
if( IS_SET( bitvector, 1 << x ) && flagarray[x] )
{
mudstrlcat( buf, flagarray[x], sizeof( buf ) );
/* don't catenate a blank if the last char is blank --Gorog */
if( buf[0] != '\0' && ' ' != buf[strlen( buf ) - 1] )
mudstrlcat( buf, " ", sizeof( buf ) );
}
if( ( x = strlen( buf ) ) > 0 )
buf[--x] = '\0';
return buf;
}
char *ext_class_string( EXT_BV *bitvector )
{
static char buf[MSL];
int x;
buf[0] = '\0';
for( x = 0; x < MAX_BITS; x++ )
{
if( xIS_SET( *bitvector, x ) && x < MAX_PC_CLASS && class_table[x] && class_table[x]->name )
{
mudstrlcat( buf, class_table[x]->name, sizeof( buf ) );
if( buf[0] != '\0' && buf[strlen( buf ) - 1] != ' ' )
mudstrlcat( buf, " ", sizeof( buf ) );
}
}
if( ( x = strlen( buf ) ) > 0 )
buf[--x] = '\0';
return buf;
}
char *ext_race_string( EXT_BV *bitvector )
{
static char buf[MSL];
int x;
buf[0] = '\0';
for( x = 0; x < MAX_BITS; x++ )
{
if( xIS_SET( *bitvector, x ) && x < MAX_PC_RACE && race_table[x] && race_table[x]->name )
{
mudstrlcat( buf, race_table[x]->name, sizeof( buf ) );
if( buf[0] != '\0' && buf[strlen( buf ) - 1] != ' ' )
mudstrlcat( buf, " ", sizeof( buf ) );
}
}
if( ( x = strlen( buf ) ) > 0 )
buf[--x] = '\0';
return buf;
}
char *ext_flag_string( EXT_BV *bitvector, const char *flagarray[] )
{
static char buf[MSL];
int x;
buf[0] = '\0';
for( x = 0; x < MAX_BITS; x++ )
{
if( xIS_SET( *bitvector, x ) )
{
mudstrlcat( buf, flagarray[x], sizeof( buf ) );
if( buf[0] != '\0' && buf[strlen( buf ) - 1] != ' ' )
mudstrlcat( buf, " ", sizeof( buf ) );
}
/* Lets break out once max is found...can crash otherwise */
if( !str_cmp( flagarray[x], "max" ) )
break;
}
if( ( x = strlen( buf ) ) > 0 )
buf[--x] = '\0';
return buf;
}
bool is_npc( CHAR_DATA *ch )
{
if( !ch )
{
bug( "%s: NULL ch", __FUNCTION__ );
return false;
}
if( xIS_SET( ch->act, ACT_IS_NPC ) )
return true;
return false;
}
bool is_immortal( CHAR_DATA *ch )
{
if( !ch )
{
bug( "%s: NULL ch", __FUNCTION__ );
return false;
}
if( get_trust( ( ch ) ) >= PERM_IMM )
return true;
return false;
}
bool is_avatar( CHAR_DATA *ch )
{
if( !ch )
{
bug( "%s: NULL ch", __FUNCTION__ );
return false;
}
if( ch->level >= MAX_LEVEL )
return true;
return false;
}
bool valid_destbuf( CHAR_DATA *ch, const char *function )
{
if( !ch )
{
bug( "%s: NULL ch", __FUNCTION__ );
return false;
}
if( !ch->dest_buf )
{
send_to_char( "Fatal error: report to an Immortal.\r\n", ch );
bug( "%s: [%s] is checking on a NULL ch->dest_buf", __FUNCTION__, function );
ch->substate = SUB_NONE;
return false;
}
return true;
}
bool can_rmodify( CHAR_DATA *ch, ROOM_INDEX_DATA *room )
{
int vnum = room->vnum;
AREA_DATA *pArea;
if( is_npc( ch ) )
return false;
if( get_trust( ch ) >= sysdata.perm_modify_proto )
return true;
if( !ch->pcdata || !( pArea = ch->pcdata->area ) )
{
send_to_char( "You must have an assigned area to modify this room.\r\n", ch );
return false;
}
if( vnum >= pArea->low_vnum && vnum <= pArea->hi_vnum )
return true;
send_to_char( "That room is not in your allocated range.\r\n", ch );
return false;
}
bool can_omodify( CHAR_DATA *ch, OBJ_DATA *obj )
{
int vnum = obj->pIndexData->vnum;
AREA_DATA *pArea;
if( is_npc( ch ) )
return false;
if( get_trust( ch ) >= sysdata.perm_modify_proto )
return true;
if( !is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
send_to_char( "You can't modify this object.\r\n", ch );
return false;
}
if( !ch->pcdata || !( pArea = ch->pcdata->area ) )
{
send_to_char( "You must have an assigned area to modify this object.\r\n", ch );
return false;
}
if( vnum >= pArea->low_vnum && vnum <= pArea->hi_vnum )
return true;
send_to_char( "That object is not in your allocated range.\r\n", ch );
return false;
}
bool can_oedit( CHAR_DATA *ch, OBJ_INDEX_DATA *obj )
{
int vnum = obj->vnum;
AREA_DATA *pArea;
if( is_npc( ch ) )
return false;
if( get_trust( ch ) >= PERM_BUILDER )
return true;
if( !xIS_SET( obj->extra_flags, ITEM_PROTOTYPE ) )
{
send_to_char( "You can't modify this object.\r\n", ch );
return false;
}
if( !ch->pcdata || !( pArea = ch->pcdata->area ) )
{
send_to_char( "You must have an assigned area to modify this object.\r\n", ch );
return false;
}
if( vnum >= pArea->low_vnum && vnum <= pArea->hi_vnum )
return true;
send_to_char( "That object is not in your allocated range.\r\n", ch );
return false;
}
bool can_mmodify( CHAR_DATA *ch, CHAR_DATA *mob )
{
int vnum;
AREA_DATA *pArea;
if( mob == ch )
return true;
if( !is_npc( mob ) )
{
if( get_trust( ch ) >= sysdata.perm_modify_proto && get_trust( ch ) > get_trust( mob ) )
return true;
else
send_to_char( "You can't do that.\r\n", ch );
return false;
}
vnum = mob->pIndexData->vnum;
if( is_npc( ch ) )
return false;
if( get_trust( ch ) >= sysdata.perm_modify_proto )
return true;
if( !xIS_SET( mob->act, ACT_PROTOTYPE ) )
{
send_to_char( "You can't modify this mobile.\r\n", ch );
return false;
}
if( !ch->pcdata || !( pArea = ch->pcdata->area ) )
{
send_to_char( "You must have an assigned area to modify this mobile.\r\n", ch );
return false;
}
if( vnum >= pArea->low_vnum && vnum <= pArea->hi_vnum )
return true;
send_to_char( "That mobile is not in your allocated range.\r\n", ch );
return false;
}
bool can_medit( CHAR_DATA *ch, MOB_INDEX_DATA *mob )
{
int vnum = mob->vnum;
AREA_DATA *pArea;
if( is_npc( ch ) )
return false;
if( get_trust( ch ) >= PERM_BUILDER )
return true;
if( !xIS_SET( mob->act, ACT_PROTOTYPE ) )
{
send_to_char( "You can't modify this mobile.\r\n", ch );
return false;
}
if( !ch->pcdata || !( pArea = ch->pcdata->area ) )
{
send_to_char( "You must have an assigned area to modify this mobile.\r\n", ch );
return false;
}
if( vnum >= pArea->low_vnum && vnum <= pArea->hi_vnum )
return true;
send_to_char( "That mobile is not in your allocated range.\r\n", ch );
return false;
}
int get_pc_class( char *Class )
{
int x;
for( x = 0; x < MAX_PC_CLASS; x++ )
if( class_table[x] && !str_cmp( class_table[x]->name, Class ) )
return x;
return -1;
}
int get_pc_race( char *type )
{
int i;
for( i = 0; i < MAX_PC_RACE; i++ )
if( race_table[i] && !str_cmp( type, race_table[i]->name ) )
return i;
return -1;
}
int get_pulltype( char *type )
{
unsigned int x;
if( !str_cmp( type, "none" ) || !str_cmp( type, "clear" ) )
return 0;
for( x = 0; x < ( sizeof( ex_pmisc ) / sizeof( ex_pmisc[0] ) ); x++ )
if( !str_cmp( type, ex_pmisc[x] ) )
return x;
for( x = 0; x < ( sizeof( ex_pwater ) / sizeof( ex_pwater[0] ) ); x++ )
if( !str_cmp( type, ex_pwater[x] ) )
return x + PT_WATER;
for( x = 0; x < ( sizeof( ex_pair ) / sizeof( ex_pair[0] ) ); x++ )
if( !str_cmp( type, ex_pair[x] ) )
return x + PT_AIR;
for( x = 0; x < ( sizeof( ex_pearth ) / sizeof( ex_pearth[0] ) ); x++ )
if( !str_cmp( type, ex_pearth[x] ) )
return x + PT_EARTH;
for( x = 0; x < ( sizeof( ex_pfire ) / sizeof( ex_pfire[0] ) ); x++ )
if( !str_cmp( type, ex_pfire[x] ) )
return x + PT_FIRE;
return -1;
}
int get_mpflag( char *flag )
{
unsigned int x;
for( x = 0; x < ( sizeof( mprog_flags ) / sizeof( mprog_flags[0] ) ); x++ )
if( !str_cmp( flag, mprog_flags[x] ) )
return x;
return -1;
}
/* Remove carriage returns from a line */
char *strip_cr( char *str )
{
static char newstr[MSL];
int i, j;
if( !str || str[0] == '\0' )
return (char *)"";
for( i = j = 0; str[i] != '\0'; i++ )
{
if( str[i] != '\r' )
newstr[j++] = str[i];
}
newstr[j] = '\0';
return newstr;
}
/* Removes the tildes from a line, except if it's the last character. */
void smush_tilde( char *str )
{
int len;
char last;
char *strptr;
strptr = str;
len = strlen( str );
if( len )
last = strptr[len - 1];
else
last = '\0';
for( ; *str != '\0'; str++ )
{
if( *str == '~' )
*str = '-';
}
if( len )
strptr[len - 1] = last;
}
void start_editing( CHAR_DATA *ch, char *data )
{
EDITOR_DATA *edit;
short lines, size, lpos;
char c;
if( !ch->desc )
{
bug( "%s", "Fatal: start_editing: no desc" );
return;
}
if( ch->substate == SUB_RESTRICTED )
bug( "%s", "NOT GOOD: start_editing: ch->substate == SUB_RESTRICTED" );
if( ch->editor )
stop_editing( ch );
set_char_color( AT_GREEN, ch );
send_to_char( "Begin entering your text now (/? = help /s = save /c = clear /l = list)\r\n", ch );
send_to_char( "-----------------------------------------------------------------------\r\n> ", ch );
CREATE( edit, EDITOR_DATA, 1 );
edit->numlines = 0;
edit->on_line = 0;
edit->size = 0;
size = 0;
lpos = 0;
lines = 0;
if( !data )
data = (char *)"";
if( !data )
bug( "%s: data is NULL!", __FUNCTION__ );
else
{
for( ;; )
{
c = data[size++];
if( c == '\0' )
{
edit->line[lines][lpos] = '\0';
break;
}
else if( c == '\r' );
else if( c == '\n' || lpos > ( MLS - 1 ) )
{
edit->line[lines][lpos] = '\0';
++lines;
lpos = 0;
}
else
edit->line[lines][lpos++] = c;
if( lines >= 49 || size > 4096 )
{
edit->line[lines][lpos] = '\0';
break;
}
}
}
if( lpos > 0 && lpos < ( MLS - 1 ) && lines < 49 )
{
edit->line[lines][lpos] = '~';
edit->line[lines][lpos + 1] = '\0';
++lines;
lpos = 0;
}
edit->numlines = lines;
edit->size = size;
edit->on_line = lines;
ch->editor = edit;
ch->desc->connected = CON_EDITING;
}
char *copy_buffer( CHAR_DATA *ch )
{
char buf[MSL];
char tmp[MLS + 2];
short x, len;
if( !ch )
{
bug( "%s: null ch", __FUNCTION__ );
return NULL;
}
if( !ch->editor )
{
bug( "%s: null editor", __FUNCTION__ );
return NULL;
}
buf[0] = '\0';
for( x = 0; x < ch->editor->numlines; x++ )
{
mudstrlcpy( tmp, ch->editor->line[x], sizeof( tmp ) );
len = strlen( tmp );
if( tmp != NULL && tmp[len - 1] == '~' )
tmp[len - 1] = '\0';
else
mudstrlcat( tmp, "\r\n", sizeof( tmp ) );
smash_tilde( tmp );
mudstrlcat( buf, tmp, sizeof( buf ) );
}
return STRALLOC( buf );
}
void stop_editing( CHAR_DATA *ch )
{
set_char_color( AT_PLAIN, ch );
if( ch->editor )
{
DISPOSE( ch->editor );
ch->editor = NULL;
}
send_to_char( "Editing has stopped.\r\n", ch );
ch->dest_buf = NULL;
ch->spare_ptr = NULL;
ch->substate = SUB_NONE;
if( ch->desc )
ch->desc->connected = CON_PLAYING;
}
void do_goto( CHAR_DATA *ch, char *argument )
{
char arg[MIL];
ROOM_INDEX_DATA *location, *in_room;
CHAR_DATA *fch, *fch_next, *victim;
AREA_DATA *pArea;
int vnum;
one_argument( argument, arg );
if( arg == NULL || arg[0] == '\0' )
{
send_to_char( "Goto where?\r\n", ch );
return;
}
if( !is_number( arg ) && ( fch = get_char_world( ch, arg ) ) )
{
if( !is_npc( fch ) && get_trust( ch ) < get_trust( fch )
&& xIS_SET( fch->pcdata->flags, PCFLAG_DND ) )
{
pager_printf( ch, "Sorry. %s does not wish to be disturbed.\r\n", fch->name );
pager_printf( fch, "Your DND flag just foiled %s's goto command.\r\n", ch->name );
return;
}
}
if( !( location = find_location( ch, arg ) ) )
{
vnum = atoi( arg );
if( vnum < 0 || get_room_index( vnum ) )
{
send_to_char( "You can't find that...\r\n", ch );
return;
}
if( get_trust( ch ) < PERM_BUILDER || vnum < 1 || is_npc( ch ) || !ch->pcdata->area )
{
send_to_char( "No such location.\r\n", ch );
return;
}
if( get_trust( ch ) < sysdata.perm_modify_proto )
{
if( !ch->pcdata || !( pArea = ch->pcdata->area ) )
{
send_to_char( "You must have an assigned area to create rooms.\r\n", ch );
return;
}
if( vnum < pArea->low_vnum || vnum > pArea->hi_vnum )
{
send_to_char( "That room is not within your assigned range.\r\n", ch );
return;
}
}
if( !( location = make_room( vnum, ch->pcdata->area ) ) )
{
bug( "%s: make_room failed", __FUNCTION__ );
return;
}
set_char_color( AT_WHITE, ch );
send_to_char( "Waving your hand, you form order from swirling chaos,\r\nand step into a new reality...\r\n", ch );
}
if( ( victim = room_is_dnd( ch, location ) ) )
{
send_to_pager( "That room is \"do not disturb\" right now.\r\n", ch );
pager_printf( victim, "Your DND flag just foiled %s's goto command.\r\n", ch->name );
return;
}
if( room_is_private( location ) )
{
if( get_trust( ch ) < sysdata.perm_override_private )
{
send_to_char( "That room is private right now.\r\n", ch );
return;
}
else
send_to_char( "Overriding private flag!\r\n", ch );
}
in_room = ch->in_room;
stop_fighting( ch, true );
if( !xIS_SET( ch->act, PLR_WIZINVIS ) )
{
if( ch->pcdata && ch->pcdata->bamfout )
act( AT_IMMORT, "$T", ch, NULL, ch->pcdata->bamfout, TO_ROOM );
else
act( AT_IMMORT, "$n leaves in a swirling mist.", ch, NULL, NULL, TO_ROOM );
}
ch->regoto = ch->in_room->vnum;
char_from_room( ch );
if( ch->mount )
{
char_from_room( ch->mount );
char_to_room( ch->mount, location );
}
char_to_room( ch, location );
if( !xIS_SET( ch->act, PLR_WIZINVIS ) )
{
if( ch->pcdata && ch->pcdata->bamfin )
act( AT_IMMORT, "$T", ch, NULL, ch->pcdata->bamfin, TO_ROOM );
else
act( AT_IMMORT, "$n appears in a swirling mist.", ch, NULL, NULL, TO_ROOM );
}
do_look( ch, (char *)"auto" );
if( ch->in_room == in_room )
return;
for( fch = in_room->first_person; fch; fch = fch_next )
{
fch_next = fch->next_in_room;
if( fch->master == ch && is_immortal( fch ) )
{
act( AT_ACTION, "You follow $N.", fch, NULL, ch, TO_CHAR );
do_goto( fch, argument );
}
else if( is_npc( fch ) && fch->master == ch )
{
char_from_room( fch );
char_to_room( fch, location );
}
}
}
CMDF( do_mset )
{
char arg1[MIL], arg2[MIL], arg3[MIL], buf[MSL], *origarg = argument;
int stat, v2, value, minattr, maxattr;
CHAR_DATA *victim;
bool lockvictim;
set_char_color( AT_PLAIN, ch );
if( is_npc( ch ) )
{
send_to_char( "Mob's can't mset\r\n", ch );
return;
}
if( !ch->desc )
{
send_to_char( "You have no descriptor\r\n", ch );
return;
}
switch( ch->substate )
{
default:
break;
case SUB_MOB_DESC:
if( !valid_destbuf( ch, __FUNCTION__ ) )
return;
if( !( victim = ( CHAR_DATA *) ch->dest_buf ) )
{
send_to_char( "Looks like the victim you were editing got lost along the way.\r\n", ch );
stop_editing( ch );
return;
}
if( char_died( victim ) )
{
send_to_char( "Your victim died!\r\n", ch );
stop_editing( ch );
return;
}
victim->editing = NULL;
STRFREE( victim->description );
victim->description = copy_buffer( ch );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
STRSET( victim->pIndexData->description, victim->description );
stop_editing( ch );
ch->substate = ch->tempnum;
return;
}
victim = NULL;
lockvictim = false;
if( ch->substate == SUB_REPEATCMD )
{
victim = ( CHAR_DATA *) ch->dest_buf;
if( !victim )
{
send_to_char( "Your victim died!\r\n", ch );
argument = (char *)"done";
}
if( !argument || argument[0] == '\0' || !str_cmp( argument, "stat" ) )
{
if( victim )
{
if( is_npc( victim ) )
snprintf( buf, sizeof( buf ), "%d", victim->pIndexData->vnum );
else
snprintf( buf, sizeof( buf ), "%s", victim->name );
do_mstat( ch, buf );
}
else
send_to_char( "No victim selected. Type '?' for help.\r\n", ch );
return;
}
if( !str_cmp( argument, "done" ) || !str_cmp( argument, "off" ) )
{
if( ch->dest_buf )
RelDestroy( relMSET_ON, ch, ch->dest_buf );
send_to_char( "Mset mode off.\r\n", ch );
ch->substate = SUB_NONE;
ch->dest_buf = NULL;
if( ch->pcdata && ch->pcdata->subprompt )
{
STRFREE( ch->pcdata->subprompt );
ch->pcdata->subprompt = NULL;
}
return;
}
}
if( victim )
{
lockvictim = true;
mudstrlcpy( arg1, victim->name, sizeof( arg1 ) );
argument = one_argument( argument, arg2 );
mudstrlcpy( arg3, argument, sizeof( arg3 ) );
}
else
{
lockvictim = false;
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
mudstrlcpy( arg3, argument, sizeof( arg3 ) );
}
if( !str_cmp( arg1, "on" ) )
{
send_to_char( "Usage: mset <victim|vnum> on.\r\n", ch );
return;
}
if( arg1 == NULL || arg1[0] == '\0' || ( ( arg2 == NULL || arg2[0] == '\0' ) && ch->substate != SUB_REPEATCMD ) || !str_cmp( arg1, "?" ) )
{
if( ch->substate == SUB_REPEATCMD )
{
if( victim )
send_to_char( "Usage: <field> <value>\r\n", ch );
else
send_to_char( "Usage: <victim> <field> <value>\r\n", ch );
}
else
send_to_char( "Usage: mset <victim> <field> <value>\r\n", ch );
send_to_char( "\r\n", ch );
send_to_char( "Field being one of:\r\n", ch );
send_to_char( " hp name armor absorb council dexterity\r\n", ch );
send_to_char( " qp part blood attack damroll resistant\r\n", ch );
send_to_char( " pos race class defpos defense numattacks\r\n", ch );
send_to_char( " sex rank deity immune hitroll description\r\n", ch );
send_to_char( " clan sav1 drunk maxhit affected mentalstate\r\n", ch );
send_to_char( " full sav2 favor minhit charisma susceptible\r\n", ch );
send_to_char( " gold sav3 flags nation minsnoop constitution\r\n", ch );
send_to_char( " long sav4 level speaks password intelligence\r\n", ch );
send_to_char( " luck sav5 pkill thirst practice\r\n", ch );
send_to_char( " mana spec short wisdom speaking\r\n", ch );
send_to_char( " move align title aloaded strength\r\n", ch );
return;
}
if( !victim && get_trust( ch ) < PERM_LEADER )
{
if( !( victim = get_char_room( ch, arg1 ) ) )
{
send_to_char( "They aren't here.\r\n", ch );
return;
}
}
else if( !victim )
{
if( !( victim = get_char_world( ch, arg1 ) ) )
{
send_to_char( "No one like that in all the realms.\r\n", ch );
return;
}
}
if( !can_mmodify( ch, victim ) )
return;
if( get_trust( ch ) < get_trust( victim ) && !is_npc( victim ) )
{
send_to_char( "You can't do that!\r\n", ch );
ch->dest_buf = NULL;
return;
}
if( get_trust( ch ) < PERM_HEAD && is_npc( victim ) && xIS_SET( victim->act, ACT_STATSHIELD ) )
{
send_to_char( "You can't do that!\r\n", ch );
ch->dest_buf = NULL;
return;
}
if( lockvictim )
ch->dest_buf = victim;
if( is_npc( victim ) || is_immortal( victim ) )
{
minattr = 1;
maxattr = ( MAX_LEVEL + 25 );
}
else
{
minattr = 3;
maxattr = ( MAX_LEVEL );
}
if( !str_cmp( arg2, "on" ) )
{
CHECK_SUBRESTRICTED( ch );
ch_printf( ch, "Mset mode on. (Editing %s).\r\n", victim->name );
ch->substate = SUB_REPEATCMD;
ch->dest_buf = victim;
if( ch->pcdata )
{
if( is_npc( victim ) )
snprintf( buf, sizeof( buf ), "<&CMset &W#%d&w> %%i", victim->pIndexData->vnum );
else
snprintf( buf, sizeof( buf ), "<&CMset &W%s&w> %%i", victim->name );
STRSET( ch->pcdata->subprompt, buf );
}
RelCreate( relMSET_ON, ch, victim );
return;
}
value = is_number( arg3 ) ? atoi( arg3 ) : -1;
if( atoi( arg3 ) < -1 && value == -1 )
value = atoi( arg3 );
for( stat = 0; stat < STAT_MAX; stat++ )
{
if( !str_cmp( arg2, stattypes[stat] ) )
{
if( value < minattr || value > maxattr )
{
ch_printf( ch, "%s range is %d to %d.\r\n", capitalize( stattypes[stat] ), minattr, maxattr );
return;
}
victim->perm_stats[stat] = value;
ch_printf( ch, "%s set to %d\r\n", capitalize( stattypes[stat] ), value );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->perm_stats[stat] = value;
send_to_char( "Index set too.\r\n", ch );
}
return;
}
}
if( !str_cmp( arg2, "sav1" ) )
{
victim->saving_poison_death = URANGE( -30, value, 30 );
ch_printf( ch, "Sav1 (saving_poison_death) set to %d.\r\n", victim->saving_poison_death );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->saving_poison_death = victim->saving_poison_death;
send_to_char( "Prototype Sav1 set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "sav2" ) )
{
victim->saving_wand = URANGE( -30, value, 30 );
ch_printf( ch, "Sav2 (saving_wand) set to %d.\r\n", victim->saving_wand );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->saving_wand = victim->saving_wand;
send_to_char( "Prototype Sav2 set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "sav3" ) )
{
victim->saving_para_petri = URANGE( -30, value, 30 );
ch_printf( ch, "Sav3 (saving_para_petri) set to %d.\r\n", victim->saving_para_petri );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->saving_para_petri = victim->saving_para_petri;
send_to_char( "Prototype Sav3 set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "sav4" ) )
{
victim->saving_breath = URANGE( -30, value, 30 );
ch_printf( ch, "Sav4 (saving_breath) set to %d.\r\n", victim->saving_breath );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->saving_breath = victim->saving_breath;
send_to_char( "Prototype Sav4 set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "sav5" ) )
{
victim->saving_spell_staff = URANGE( -30, value, 30 );
ch_printf( ch, "Sav5 (saving_spell_staff) set to %d.\r\n", victim->saving_spell_staff );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->saving_spell_staff = victim->saving_spell_staff;
send_to_char( "Prototype Sav5 set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "sex" ) )
{
value = get_flag( arg3, sex_names, SEX_MAX );
if( value < 0 && is_number( arg3 ) )
value = atoi( arg3 );
if( value < 0 || value >= SEX_MAX )
{
send_to_char( "Sex range is 0[neutral], 1[male], or 2[female].\r\n", ch );
return;
}
victim->sex = value;
ch_printf( ch, "Sex set to %d[%s].\r\n", victim->sex, sex_names[victim->sex] );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->sex = value;
send_to_char( "Prototype Sex set.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "class" ) )
{
MCLASS_DATA *mclass;
int uclass, mcount = 0;
bool add = false;
if( is_npc( victim ) )
{
send_to_char( "Mobiles have no reason to have a class.\r\n", ch );
return;
}
value = -1;
argument = one_argument( argument, arg2 );
if( !str_cmp( arg2, "add" ) )
add = true;
else if( is_number( arg2 ) )
value = atoi( arg2 );
if( !add && value < 0 )
{
ch_printf( ch, "Invalid class number use a number equal to or above %d.\r\n", 0 );
return;
}
uclass = get_pc_class( argument );
if( uclass < 0 && is_number( argument ) )
uclass = atoi( argument );
if( uclass < -1 || uclass >= MAX_PC_CLASS )
{
ch_printf( ch, "Class range is -1 to %d.\r\n", ( MAX_PC_CLASS - 1 ) );
return;
}
if( uclass >= 0 && char_is_class( victim, uclass ) )
{
ch_printf( ch, "They already have class [%d]%s.\r\n", uclass, dis_class_name( uclass ) );
return;
}
if( add )
{
if( uclass >= 0 )
{
if( uclass >= 0 && char_is_class( victim, uclass ) )
{
ch_printf( ch, "They already have class [%d]%s.\r\n", uclass, dis_class_name( uclass ) );
return;
}
if( !( mclass = add_mclass( victim, uclass, 2, 0, 0.0, false ) ) )
ch_printf( ch, "Failed to add [%d]%s to them.\r\n", uclass, dis_class_name( uclass ) );
else
ch_printf( ch, "Class [%d]%s has been added to them.\r\n", mclass->wclass, dis_class_name( mclass->wclass ) );
}
else
send_to_char( "Need to specify a valid class to be added.\r\n", ch );
return;
}
for( mclass = victim->pcdata->first_mclass; mclass; mclass = mclass->next )
{
if( mcount++ == value )
{
mclass->wclass = uclass;
ch_printf( ch, "Class %d has been set to [%d]%s.\r\n", value, mclass->wclass, dis_class_name( mclass->wclass ) );
break;
}
}
if( !mclass )
{
send_to_char( "There is no class in that spot on them to set.\r\n", ch );
return;
}
if( mclass->wclass == -1 )
{
if( mcount > 1 ) /* They have more then one class set */
{
UNLINK( mclass, ch->pcdata->first_mclass, ch->pcdata->last_mclass, next, prev );
DISPOSE( mclass );
update_level( ch );
send_to_char( "The class has been removed from them completely.\r\n", ch );
}
else
send_to_char( "They only have 1 class and it has been set to none.\r\n", ch );
return;
}
return;
}
if( !str_cmp( arg2, "race" ) )
{
if( is_npc( victim ) )
{
send_to_char( "Mobiles have no reason to have a race.\r\n", ch );
return;
}
value = get_pc_race( arg3 );
if( value < 0 && is_number( arg3 ) )
value = atoi( arg3 );
if( value < 0 || value >= MAX_PC_RACE )
{
ch_printf( ch, "Race range is 0 to %d.\r\n", MAX_PC_RACE - 1 );
return;
}
victim->race = value;
ch_printf( ch, "Victim's race set to %s.\r\n", dis_race_name( victim->race ) );
return;
}
if( !str_cmp( arg2, "armor" ) )
{
victim->armor = URANGE( 0, value, 1000 );
ch_printf( ch, "Armor set to %d.\r\n", victim->armor );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->ac = victim->armor;
send_to_char( "Prototype Armor set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "level" ) )
{
if( !is_npc( victim ) )
{
send_to_char( "Not on PC's.\r\n", ch );
return;
}
victim->level = URANGE( 1, value, MAX_LEVEL );
ch_printf( ch, "Level set to %d.\r\n", victim->level );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->level = victim->level;
send_to_char( "Prototype Level set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "numattacks" ) )
{
if( !is_npc( victim ) )
{
send_to_char( "Not on PC's.\r\n", ch );
return;
}
if( value < 0 || value > 20 )
{
send_to_char( "Attacks range is 0 to 20.\r\n", ch );
return;
}
victim->numattacks = URANGE( 0, value, 20 );
ch_printf( ch, "Numattacks set to %d.\r\n", victim->numattacks );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->numattacks = victim->numattacks;
send_to_char( "Prototype Numattacks set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "gold" ) )
{
int unval;
unval = is_number( arg3 ) ? atoi( arg3 ) : 0;
set_gold( victim, unval );
ch_printf( ch, "Gold set to %s.\r\n", show_big_nums( victim->mgold, victim->gold ) );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->mgold = victim->mgold;
victim->pIndexData->gold = victim->gold;
send_to_char( "Prototype Gold set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "hitroll" ) )
{
victim->hitroll = URANGE( 0, value, 85 );
ch_printf( ch, "Hitroll set to %d.\r\n", victim->hitroll );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->hitroll = victim->hitroll;
send_to_char( "Prototype Hitroll set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "damroll" ) )
{
victim->damroll = URANGE( 0, value, 65 );
ch_printf( ch, "Damroll set to %d.\r\n", victim->damroll );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->damroll = victim->damroll;
send_to_char( "Prototype Damroll set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "hp" ) )
{
victim->max_hit = UMAX( 1, value );
ch_printf( ch, "Hp set to %d.\r\n", victim->max_hit );
return;
}
if( !str_cmp( arg2, "mana" ) || !str_cmp( arg2, "blood" ) )
{
victim->max_mana = UMAX( 0, value );
ch_printf( ch, "%s set to %d.\r\n", arg2, victim->max_mana );
return;
}
if( !str_cmp( arg2, "move" ) )
{
victim->max_move = UMAX( 0, value );
ch_printf( ch, "Move set to %d.\r\n", victim->max_move );
return;
}
if( !str_cmp( arg2, "practice" ) )
{
victim->practice = URANGE( 0, value, 100 );
ch_printf( ch, "Practice set to %d.\r\n", victim->practice );
return;
}
if( !str_cmp( arg2, "align" ) )
{
victim->alignment = URANGE( -1000, value, 1000 );
ch_printf( ch, "Align set to %d.\r\n", victim->alignment );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->alignment = victim->alignment;
send_to_char( "Prototype Align set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "password" ) )
{
char *pwdnew;
if( get_trust( ch ) < PERM_HEAD )
{
send_to_char( "You can't do that.\r\n", ch );
return;
}
if( is_npc( victim ) )
{
send_to_char( "Mobs don't have passwords.\r\n", ch );
return;
}
if( strlen( arg3 ) < 5 )
{
send_to_char( "New password must be at least five characters long.\r\n", ch );
return;
}
if( arg3[0] == '!' )
{
send_to_char( "New password can't begin with the '!' character.", ch );
return;
}
pwdnew = sha256_crypt( arg3 ); /* SHA-256 Encryption */
STRSET( victim->pcdata->pwd, pwdnew );
if( xIS_SET( sysdata.save_flags, SV_PASSCHG ) )
save_char_obj( victim );
send_to_char( "Password set.\r\n", ch );
ch_printf( victim, "Your password has been changed by %s.\r\n", ch->name );
return;
}
if( !str_cmp( arg2, "rank" ) )
{
if( get_trust( ch ) < PERM_LEADER )
{
send_to_char( "You can't do that.\r\n", ch );
return;
}
if( is_npc( victim ) )
{
send_to_char( "Not on NPC's.\r\n", ch );
return;
}
STRSET( victim->pcdata->rank, argument );
send_to_char( "Rank set.\r\n", ch );
return;
}
if( !str_cmp( arg2, "qp" ) )
{
if( is_npc( victim ) )
{
send_to_char( "Not on NPC's.\r\n", ch );
return;
}
victim->pcdata->quest_curr = URANGE( 0, value, 5000 );
ch_printf( ch, "Qp set to %u.\r\n", victim->pcdata->quest_curr );
return;
}
if( !str_cmp( arg2, "favor" ) )
{
if( is_npc( victim ) )
{
send_to_char( "Not on NPC's.\r\n", ch );
return;
}
victim->pcdata->favor = URANGE( -2500, value, 2500 );
ch_printf( ch, "Favor set to %d.\r\n", victim->pcdata->favor );
return;
}
if( !str_cmp( arg2, "mentalstate" ) )
{
victim->mental_state = URANGE( -100, value, 100 );
ch_printf( ch, "Mentalstate set to %d.\r\n", victim->mental_state );
return;
}
if( !str_cmp( arg2, "thirst" ) )
{
if( is_npc( victim ) )
{
send_to_char( "Not on NPC's.\r\n", ch );
return;
}
victim->pcdata->condition[COND_THIRST] = URANGE( 0, value, 100 );
ch_printf( ch, "Thirst set to %d.\r\n", victim->pcdata->condition[COND_THIRST] );
return;
}
if( !str_cmp( arg2, "drunk" ) )
{
if( is_npc( victim ) )
{
send_to_char( "Not on NPC's.\r\n", ch );
return;
}
victim->pcdata->condition[COND_DRUNK] = URANGE( 0, value, 100 );
ch_printf( ch, "Drunk set to %d.\r\n", victim->pcdata->condition[COND_DRUNK] );
return;
}
if( !str_cmp( arg2, "full" ) )
{
if( is_npc( victim ) )
{
send_to_char( "Not on NPC's.\r\n", ch );
return;
}
victim->pcdata->condition[COND_FULL] = URANGE( 0, value, 100 );
ch_printf( ch, "Full set to %d.\r\n", victim->pcdata->condition[COND_FULL] );
return;
}
if( !str_cmp( arg2, "name" ) )
{
if( !is_npc( victim ) )
{
send_to_char( "Not on PC's.\r\n", ch );
return;
}
if( arg3 == NULL || arg3[0] == '\0' )
{
send_to_char( "Names can't be set to an empty string.\r\n", ch );
return;
}
STRSET( victim->name, arg3 );
send_to_char( "Name set.\r\n", ch );
if( xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
STRSET( victim->pIndexData->name, victim->name );
send_to_char( "Prototype Name set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "minsnoop" ) )
{
if( get_trust( ch ) < PERM_HEAD )
{
send_to_char( "You can't do that.\r\n", ch );
return;
}
if( is_npc( victim ) )
{
send_to_char( "Not on NPC's.\r\n", ch );
return;
}
if( get_trust( ch ) <= get_trust( victim ) )
{
send_to_char( "You aren't able to modify their minsnoop.\r\n", ch );
return;
}
if( value > get_trust( ch ) )
{
send_to_char( "You wouldn't be able to snoop them then.\r\n", ch );
return;
}
victim->pcdata->min_snoop = URANGE( 0, value, ( PERM_MAX - 1 ) );
ch_printf( ch, "Minsnoop set to %d[%s].\r\n", victim->pcdata->min_snoop, perms_flag[victim->pcdata->min_snoop] );
return;
}
if( !str_cmp( arg2, "clan" ) )
{
CLAN_DATA *clan;
if( get_trust( ch ) < PERM_LEADER )
{
send_to_char( "You can't do that.\r\n", ch );
return;
}
if( is_npc( victim ) )
{
send_to_char( "Not on NPC's.\r\n", ch );
return;
}
if( arg3 == NULL || arg3[0] == '\0' )
{
if( victim->pcdata->clan )
{
remove_clan_member( victim->pcdata->clan, victim->name );
save_clan( victim->pcdata->clan );
}
victim->pcdata->clan = NULL;
send_to_char( "Clan set to nothing.\r\n", ch );
return;
}
if( !( clan = get_clan( arg3 ) ) || clan->clan_type == CLAN_NATION )
{
send_to_char( "No such clan.\r\n", ch );
return;
}
if( victim->pcdata->clan )
{
remove_clan_member( victim->pcdata->clan, victim->name );
save_clan( victim->pcdata->clan );
}
if( clan->clan_type == CLAN_PLAIN )
xSET_BIT( victim->pcdata->flags, PCFLAG_DEADLY );
victim->pcdata->clan = clan;
add_clan_member( clan, victim->name );
save_clan( victim->pcdata->clan );
send_to_char( "Clan set.\r\n", ch );
return;
}
if( !str_cmp( arg2, "nation" ) )
{
CLAN_DATA *nation;
if( get_trust( ch ) < PERM_LEADER )
{
send_to_char( "You can't do that.\r\n", ch );
return;
}
if( is_npc( victim ) )
{
send_to_char( "Not on NPC's.\r\n", ch );
return;
}
if( arg3 == NULL || arg3[0] == '\0' )
{
if( victim->pcdata->nation )
{
remove_clan_member( victim->pcdata->nation, victim->name );
save_clan( victim->pcdata->nation );
}
victim->pcdata->nation = NULL;
send_to_char( "Nation set to nothing.\r\n", ch );
return;
}
if( !( nation = get_clan( arg3 ) ) || nation->clan_type != CLAN_NATION )
{
send_to_char( "No such nation.\r\n", ch );
return;
}
if( victim->pcdata->nation )
{
remove_clan_member( victim->pcdata->nation, victim->name );
save_clan( victim->pcdata->nation );
}
victim->pcdata->nation = nation;
add_clan_member( nation, victim->name );
save_clan( nation );
send_to_char( "Nation set.\r\n", ch );
return;
}
if( !str_cmp( arg2, "deity" ) )
{
DEITY_DATA *deity;
if( is_npc( victim ) )
{
send_to_char( "Not on NPC's.\r\n", ch );
return;
}
if( arg3 == NULL || arg3[0] == '\0' )
{
if( victim->pcdata->deity )
{
--victim->pcdata->deity->worshippers;
if( victim->pcdata->deity->worshippers < 0 )
victim->pcdata->deity->worshippers = 0;
save_deity( victim->pcdata->deity );
}
victim->pcdata->deity = NULL;
send_to_char( "Deity removed.\r\n", ch );
return;
}
if( !( deity = get_deity( arg3 ) ) )
{
send_to_char( "No such deity.\r\n", ch );
return;
}
if( victim->pcdata->deity )
{
--victim->pcdata->deity->worshippers;
if( victim->pcdata->deity->worshippers < 0 )
victim->pcdata->deity->worshippers = 0;
save_deity( victim->pcdata->deity );
}
victim->pcdata->deity = deity;
++deity->worshippers;
save_deity( deity );
send_to_char( "Done.\r\n", ch );
return;
}
if( !str_cmp( arg2, "council" ) )
{
COUNCIL_DATA *council;
if( get_trust( ch ) < PERM_HEAD )
{
send_to_char( "You can't do that.\r\n", ch );
return;
}
if( is_npc( victim ) )
{
send_to_char( "Not on NPC's.\r\n", ch );
return;
}
if( arg3 == NULL || arg3[0] == '\0' )
{
if( victim->pcdata->council )
{
remove_council_member( victim->pcdata->council, victim->name );
save_council( victim->pcdata->council );
}
victim->pcdata->council = NULL;
send_to_char( "Removed from council.\r\n", ch );
return;
}
if( !( council = get_council( arg3 ) ) )
{
send_to_char( "No such council.\r\n", ch );
return;
}
if( victim->pcdata->council )
{
remove_council_member( victim->pcdata->council, victim->name );
save_council( victim->pcdata->council );
}
victim->pcdata->council = council;
add_council_member( council, victim->name );
save_council( council );
send_to_char( "Done.\r\n", ch );
return;
}
if( !str_cmp( arg2, "short" ) )
{
if( arg3 == NULL || arg3[0] == '\0' )
{
send_to_char( "You can't set the short field to nothing.\r\n", ch );
return;
}
STRSET( victim->short_descr, arg3 );
send_to_char( "Short set.\r\n", ch );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
STRSET( victim->pIndexData->short_descr, victim->short_descr );
send_to_char( "Prototype Short set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "long" ) )
{
if( arg3 == NULL || arg3[0] == '\0' )
{
send_to_char( "You can't set the long field to nothing.\r\n", ch );
return;
}
mudstrlcpy( buf, arg3, sizeof( buf ) );
mudstrlcat( buf, "\r\n", sizeof( buf ) );
STRSET( victim->long_descr, buf );
send_to_char( "Long set.\r\n", ch );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
STRSET( victim->pIndexData->long_descr, victim->long_descr );
send_to_char( "Prototype Long set to match.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "description" ) )
{
if( victim->editing )
{
send_to_char( "Someone is currently editing the victim's description.\r\n", ch );
return;
}
if( arg3 != NULL && arg3[0] != '\0' )
{
STRSET( victim->description, arg3 );
send_to_char( "Description Set.\r\n", ch );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
STRSET( victim->pIndexData->description, victim->description );
send_to_char( "Prototype Description Set.\r\n", ch );
}
return;
}
CHECK_SUBRESTRICTED( ch );
if( ch->substate == SUB_REPEATCMD )
ch->tempnum = SUB_REPEATCMD;
else
ch->tempnum = SUB_NONE;
ch->substate = SUB_MOB_DESC;
ch->dest_buf = victim;
victim->editing = ch;
start_editing( ch, victim->description );
return;
}
if( !str_cmp( arg2, "title" ) )
{
if( is_npc( victim ) )
{
send_to_char( "Not on NPC's.\r\n", ch );
return;
}
set_title( victim, arg3 );
return;
}
if( !str_cmp( arg2, "spec" ) || !str_cmp( arg2, "spec_fun" ) )
{
SPEC_FUN *specfun;
if( !is_npc( victim ) )
{
send_to_char( "Not on PC's.\r\n", ch );
return;
}
if( !str_cmp( arg3, "none" ) )
{
victim->spec_fun = NULL;
STRFREE( victim->spec_funname );
send_to_char( "Special function removed.\r\n", ch );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->spec_fun = NULL;
STRFREE( victim->pIndexData->spec_funname );
}
return;
}
if( !( specfun = spec_lookup( arg3 ) ) )
{
send_to_char( "No such function.\r\n", ch );
return;
}
if( !validate_spec_fun( arg3 ) )
{
ch_printf( ch, "%s is not a valid spec_fun for mobiles.\r\n", arg3 );
return;
}
victim->spec_fun = specfun;
STRSET( victim->spec_funname, arg3 );
send_to_char( "Victim special function set.\r\n", ch );
if( xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
victim->pIndexData->spec_fun = victim->spec_fun;
STRSET( victim->pIndexData->spec_funname, arg3 );
send_to_char( "Prototype Victim special function set.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "flags" ) )
{
if( !is_npc( victim ) && get_trust( ch ) < PERM_LEADER )
{
send_to_char( "You can only modify a mobile's flags.\r\n", ch );
return;
}
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: mset <vic> flags <flag> [flag]...\r\n", ch );
return;
}
while( argument && argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
if( is_npc( victim ) )
{
value = get_flag( arg3, act_flags, ACT_MAX );
if( value < 0 || value >= ACT_MAX )
ch_printf( ch, "Unknown flag: %s\r\n", arg3 );
else if( value == ACT_PROTOTYPE && ch->level < sysdata.perm_modify_proto )
send_to_char( "You can't change the prototype flag.\r\n", ch );
else if( value == ACT_IS_NPC )
send_to_char( "If the NPC flag could be changed, it would cause many problems.\r\n", ch );
else
{
xTOGGLE_BIT( victim->act, value );
ch_printf( ch, "%s flag %s.\r\n", act_flags[value], xIS_SET( victim->act, value ) ? "set" : "removed" );
if( xIS_SET( victim->act, ACT_PROTOTYPE ) || value == ACT_PROTOTYPE )
{
xTOGGLE_BIT( victim->pIndexData->act, value );
ch_printf( ch, "%s index flag %s.\r\n", act_flags[value], xIS_SET( victim->pIndexData->act, value ) ? "set" : "removed" );
}
}
}
else
{
value = get_flag( arg3, plr_flags, PLR_MAX );
if( value < 0 || value >= PLR_MAX )
ch_printf( ch, "Unknown flag: %s\r\n", arg3 );
else if( value == PLR_IS_NPC )
send_to_char( "If the NPC flag could be changed, it would cause many problems.\r\n", ch );
else
{
xTOGGLE_BIT( victim->act, value );
ch_printf( ch, "%s flag %s.\r\n", plr_flags[value], xIS_SET( victim->act, value ) ? "set" : "removed" );
}
}
}
return;
}
if( !str_cmp( arg2, "affected" ) )
{
if( !is_npc( victim ) && get_trust( ch ) < PERM_LEADER )
{
send_to_char( "You can only modify a mobile's flags.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: mset <victim> affected <flag> [flag]...\r\n", ch );
return;
}
while( argument && argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_flag( arg3, a_flags, AFF_MAX );
if( value < 0 || value >= AFF_MAX )
ch_printf( ch, "Unknown affected: %s\r\n", arg3 );
else
{
xTOGGLE_BIT( victim->affected_by, value );
ch_printf( ch, "%s affected %s.\r\n", a_flags[value], xIS_SET( victim->affected_by, value ) ? "set" : "removed" );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
xTOGGLE_BIT( victim->pIndexData->affected_by, value );
ch_printf( ch, "%s index affected %s.\r\n", a_flags[value], xIS_SET( victim->pIndexData->affected_by, value ) ? "set" : "removed" );
}
}
}
return;
}
if( !str_cmp( arg2, "resistant" ) )
{
if( !is_npc( victim ) && get_trust( ch ) < PERM_LEADER )
{
send_to_char( "You can only modify a mobile's resistancies.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: mset <victim> resistant <flag> [flag]...\r\n", ch );
return;
}
while( argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_flag( arg3, ris_flags, RIS_MAX );
if( value < 0 || value >= RIS_MAX )
ch_printf( ch, "Unknown resistant: %s\r\n", arg3 );
else
{
xTOGGLE_BIT( victim->resistant, value );
ch_printf( ch, "%s resistant %s.\r\n", ris_flags[value], xIS_SET( victim->resistant, value ) ? "set" : "removed" );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
xTOGGLE_BIT( victim->pIndexData->resistant, value );
ch_printf( ch, "%s index resistant %s.\r\n", ris_flags[value], xIS_SET( victim->pIndexData->resistant, value ) ? "set" : "removed" );
}
}
}
return;
}
if( !str_cmp( arg2, "immune" ) )
{
if( !is_npc( victim ) && get_trust( ch ) < PERM_LEADER )
{
send_to_char( "You can only modify a mobile's immunities.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: mset <victim> immune <flag> [flag]...\r\n", ch );
return;
}
while( argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_flag( arg3, ris_flags, RIS_MAX );
if( value < 0 || value >= RIS_MAX )
ch_printf( ch, "Unknown immune: %s\r\n", arg3 );
else
{
xTOGGLE_BIT( victim->immune, value );
ch_printf( ch, "%s immune %s.\r\n", ris_flags[value], xIS_SET( victim->immune, value ) ? "set" : "removed" );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
xTOGGLE_BIT( victim->pIndexData->immune, value );
ch_printf( ch, "%s index immune %s.\r\n", ris_flags[value], xIS_SET( victim->pIndexData->immune, value ) ? "set" : "removed" );
}
}
}
return;
}
if( !str_cmp( arg2, "absorb" ) )
{
if( !is_npc( victim ) && get_trust( ch ) < PERM_LEADER )
{
send_to_char( "You can only modify a mobile's absorb.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: mset <victim> absorb <flag> [flag]...\r\n", ch );
return;
}
while( argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_flag( arg3, ris_flags, RIS_MAX );
if( value < 0 || value >= RIS_MAX )
ch_printf( ch, "Unknown absorb: %s\r\n", arg3 );
else
{
xTOGGLE_BIT( victim->absorb, value );
ch_printf( ch, "%s absorb %s.\r\n", ris_flags[value], xIS_SET( victim->absorb, value ) ? "set" : "removed" );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
xTOGGLE_BIT( victim->pIndexData->absorb, value );
ch_printf( ch, "%s index absorb %s.\r\n", ris_flags[value], xIS_SET( victim->pIndexData->absorb, value ) ? "set" : "removed" );
}
}
}
return;
}
if( !str_cmp( arg2, "susceptible" ) )
{
if( !is_npc( victim ) && get_trust( ch ) < PERM_LEADER )
{
send_to_char( "You can only modify a mobile's susceptibilities.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: mset <victim> susceptible <flag> [flag]...\r\n", ch );
return;
}
while( argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_flag( arg3, ris_flags, RIS_MAX );
if( value < 0 || value >= RIS_MAX )
ch_printf( ch, "Unknown susceptible: %s\r\n", arg3 );
else
{
xTOGGLE_BIT( victim->susceptible, value );
ch_printf( ch, "%s susceptible %s.\r\n", ris_flags[value], xIS_SET( victim->susceptible, value ) ? "set" : "removed" );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
xTOGGLE_BIT( victim->pIndexData->susceptible, value );
ch_printf( ch, "%s index susceptible %s.\r\n", ris_flags[value], xIS_SET( victim->pIndexData->susceptible, value ) ? "set" : "removed" );
}
}
}
return;
}
if( !str_cmp( arg2, "part" ) )
{
if( !is_npc( victim ) && get_trust( ch ) < PERM_LEADER )
{
send_to_char( "You can only modify a mobile's parts.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: mset <victim> part <flag> [flag]...\r\n", ch );
return;
}
while( argument && argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_flag( arg3, part_flags, PART_MAX );
if( value < 0 || value >= PART_MAX )
ch_printf( ch, "Unknown part: %s\r\n", arg3 );
else
{
xTOGGLE_BIT( victim->xflags, value );
ch_printf( ch, "%s part %s.\r\n", part_flags[value], xIS_SET( victim->xflags, value ) ? "set" : "removed" );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
xTOGGLE_BIT( victim->pIndexData->xflags, value );
ch_printf( ch, "%s index part %s.\r\n", part_flags[value], xIS_SET( victim->pIndexData->xflags, value ) ? "set" : "removed" );
}
}
}
return;
}
if( !str_cmp( arg2, "attack" ) )
{
if( !is_npc( victim ) )
{
send_to_char( "You can only modify a mobile's attacks.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: mset <victim> attack <flag> [flag]...\r\n", ch );
return;
}
while( argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_flag( arg3, attack_flags, ATCK_MAX );
if( value < 0 || value >= ATCK_MAX )
ch_printf( ch, "Unknown attack: %s\r\n", arg3 );
else
{
xTOGGLE_BIT( victim->attacks, value );
ch_printf( ch, "%s attack %s.\r\n", attack_flags[value], xIS_SET( victim->attacks, value ) ? "set" : "removed" );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
xTOGGLE_BIT( victim->pIndexData->attacks, value );
ch_printf( ch, "%s index attack %s.\r\n", attack_flags[value], xIS_SET( victim->pIndexData->attacks, value ) ? "set" : "removed" );
}
}
}
return;
}
if( !str_cmp( arg2, "defense" ) )
{
if( !is_npc( victim ) )
{
send_to_char( "You can only modify a mobile's defenses.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: mset <victim> defense <flag> [flag]...\r\n", ch );
return;
}
while( argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_flag( arg3, defense_flags, DFND_MAX );
if( value < 0 || value >= DFND_MAX )
ch_printf( ch, "Unknown defense: %s\r\n", arg3 );
else
{
xTOGGLE_BIT( victim->defenses, value );
ch_printf( ch, "%s defense %s.\r\n", defense_flags[value], xIS_SET( victim->defenses, value ) ? "set" : "removed" );
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
xTOGGLE_BIT( victim->pIndexData->defenses, value );
ch_printf( ch, "%s index defense %s.\r\n", defense_flags[value], xIS_SET( victim->pIndexData->defenses, value ) ? "set" : "removed" );
}
}
}
return;
}
if( !str_cmp( arg2, "pos" ) )
{
if( !is_npc( victim ) )
{
send_to_char( "Mobiles only.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
value = get_flag( arg3, pos_names, POS_STANDING );
if( value < 0 && is_number( arg3 ) )
value = atoi( arg3 );
if( value < 0 || value > POS_STANDING )
{
ch_printf( ch, "Position range is 0 to %d.\r\n", POS_STANDING );
return;
}
victim->position = value;
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
victim->pIndexData->position = victim->position;
send_to_char( "Done.\r\n", ch );
return;
}
if( !str_cmp( arg2, "defpos" ) )
{
if( !is_npc( victim ) )
{
send_to_char( "Mobiles only.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
value = get_flag( arg3, pos_names, POS_STANDING );
if( value < 0 && is_number( arg3 ) )
value = atoi( arg3 );
if( value < 0 || value > POS_STANDING )
{
ch_printf( ch, "Position range is 0 to %d.\r\n", POS_STANDING );
return;
}
victim->defposition = value;
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
victim->pIndexData->defposition = victim->defposition;
send_to_char( "Done.\r\n", ch );
return;
}
if( !str_cmp( arg2, "minhit" ) )
{
if( !is_npc( victim ) )
{
send_to_char( "Mobiles only.\r\n", ch );
return;
}
if( !xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
send_to_char( "Can only set minhit on prototype mobiles.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
if( value < 0 || value > 30000 )
{
send_to_char( "Minhit range is 0 to 30000.\r\n", ch );
return;
}
if( value > victim->pIndexData->maxhit )
{
ch_printf( ch, "Increasing maxhit to %d so its higher then minhit.\r\n", value + 100 );
victim->pIndexData->maxhit = ( value + 100 );
}
victim->pIndexData->minhit = value;
victim->max_hit = number_range( victim->pIndexData->minhit, victim->pIndexData->maxhit );
victim->hit = victim->max_hit;
send_to_char( "Done.\r\n", ch );
return;
}
if( !str_cmp( arg2, "maxhit" ) )
{
if( !is_npc( victim ) )
{
send_to_char( "Mobiles only.\r\n", ch );
return;
}
if( !xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
send_to_char( "Can only set maxhit on prototype mobiles.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
if( value < 100 || value > 30100 )
{
send_to_char( "Maxhit range is 100 to 30100.\r\n", ch );
return;
}
if( value <= victim->pIndexData->minhit )
{
ch_printf( ch, "Decreasing minhit to %d so its lower then maxhit.\r\n", value - 100 );
victim->pIndexData->minhit = ( value - 100 );
}
victim->pIndexData->maxhit = value;
victim->max_hit = number_range( victim->pIndexData->minhit, victim->pIndexData->maxhit );
victim->hit = victim->max_hit;
send_to_char( "Done.\r\n", ch );
return;
}
if( !str_cmp( arg2, "aloaded" ) )
{
if( is_npc( victim ) )
{
send_to_char( "Player Characters only.\r\n", ch );
return;
}
if( !victim->pcdata->area )
{
send_to_char( "Player does not have an area assigned to them.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
if( !IS_SET( victim->pcdata->area->status, AREA_LOADED ) )
{
SET_BIT( victim->pcdata->area->status, AREA_LOADED );
send_to_char( "Your area set to LOADED!\r\n", victim );
if( ch != victim )
send_to_char( "Area set to LOADED!\r\n", ch );
return;
}
else
{
REMOVE_BIT( victim->pcdata->area->status, AREA_LOADED );
send_to_char( "Your area set to NOT-LOADED!\r\n", victim );
if( ch != victim )
send_to_char( "Area set to NON-LOADED!\r\n", ch );
return;
}
}
if( !str_cmp( arg2, "pkill" ) )
{
if( is_npc( victim ) )
{
send_to_char( "Player Characters only.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
{
send_to_char( "You can't do that.\r\n", ch );
return;
}
xTOGGLE_BIT( victim->pcdata->flags, PCFLAG_DEADLY );
if( !xIS_SET( victim->pcdata->flags, PCFLAG_DEADLY ) )
{
xSET_BIT( victim->act, PLR_NICE );
send_to_char( "You're now a NON-PKILL player.\r\n", victim );
if( ch != victim )
send_to_char( "That player is now non-pkill.\r\n", ch );
if( victim->pcdata->clan && victim->pcdata->clan->clan_type == CLAN_PLAIN && !is_immortal( victim ) )
{
remove_clan_member( victim->pcdata->clan, victim->name );
save_clan( victim->pcdata->clan );
victim->pcdata->clan = NULL;
}
}
else
{
xREMOVE_BIT( victim->act, PLR_NICE );
send_to_char( "You're now a PKILL player.\r\n", victim );
if( ch != victim )
send_to_char( "That player is now pkill.\r\n", ch );
if( victim->pcdata->clan && victim->pcdata->clan->clan_type != CLAN_PLAIN && !is_immortal( victim ) )
{
remove_clan_member( victim->pcdata->clan, victim->name );
save_clan( victim->pcdata->clan );
victim->pcdata->clan = NULL;
}
}
save_char_obj( victim );
return;
}
if( !str_cmp( arg2, "speaks" ) )
{
if( !can_mmodify( ch, victim ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: mset <victim> speaks <language> [language] ...\r\n", ch );
return;
}
while( argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_langflag( arg3 );
if( value == LANG_UNKNOWN )
{
ch_printf( ch, "Unknown language: %s\r\n", arg3 );
continue;
}
else if( !is_npc( victim ) )
{
if( !( value &= VALID_LANGS ) )
{
ch_printf( ch, "Players may not know %s.\r\n", arg3 );
continue;
}
}
v2 = get_langnum( arg3 );
if( v2 == -1 )
ch_printf( ch, "Unknown language: %s\r\n", arg3 );
else
xTOGGLE_BIT( victim->speaks, v2 );
}
if( xIS_SET( victim->act, ACT_PROTOTYPE ) )
victim->pIndexData->speaks = victim->speaks;
send_to_char( "Done.\r\n", ch );
return;
}
if( !str_cmp( arg2, "speaking" ) )
{
if( !is_npc( victim ) )
{
send_to_char( "Players must choose the language they speak themselves.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: mset <victim> speaking <language> [language]...\r\n", ch );
return;
}
while( argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_langflag( arg3 );
if( value == LANG_UNKNOWN )
ch_printf( ch, "Unknown language: %s\r\n", arg3 );
else
{
v2 = get_langnum( arg3 );
if( v2 == -1 )
ch_printf( ch, "Unknown language: %s\r\n", arg3 );
else
xTOGGLE_BIT( victim->speaking, 1 << v2 );
}
}
if( is_npc( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
victim->pIndexData->speaking = victim->speaking;
send_to_char( "Done.\r\n", ch );
return;
}
/* Generate usage message. */
if( ch->substate == SUB_REPEATCMD )
{
ch->substate = SUB_RESTRICTED;
interpret( ch, origarg );
ch->substate = SUB_REPEATCMD;
ch->last_cmd = do_mset;
}
else
do_mset( ch, (char *)"" );
}
CMDF( do_oset )
{
char arg1[MIL], arg2[MIL], arg3[MIL], buf[MSL], *origarg = argument;
OBJ_DATA *obj, *tmpobj;
EXTRA_DESCR_DATA *ed;
bool lockobj;
int value, tmp, stat;
set_char_color( AT_PLAIN, ch );
if( is_npc( ch ) )
{
send_to_char( "Mob's can't oset\r\n", ch );
return;
}
if( !ch->desc )
{
send_to_char( "You have no descriptor\r\n", ch );
return;
}
switch( ch->substate )
{
default:
break;
case SUB_OBJ_EXTRA:
if( !valid_destbuf( ch, __FUNCTION__ ) )
return;
ed = ( EXTRA_DESCR_DATA *) ch->dest_buf;
STRFREE( ed->description );
ed->description = copy_buffer( ch );
tmpobj = ( OBJ_DATA *) ch->spare_ptr;
stop_editing( ch );
ch->dest_buf = tmpobj;
ch->substate = ch->tempnum;
return;
case SUB_OBJ_LONG:
if( !valid_destbuf( ch, __FUNCTION__ ) )
return;
obj = ( OBJ_DATA *) ch->dest_buf;
if( !obj )
{
send_to_char( "Your object was extracted!\r\n", ch );
stop_editing( ch );
return;
}
STRFREE( obj->description );
obj->description = copy_buffer( ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
if( can_omodify( ch, obj ) )
{
STRSET( obj->pIndexData->description, obj->description );
}
}
tmpobj = ( OBJ_DATA *) ch->spare_ptr;
stop_editing( ch );
ch->substate = ch->tempnum;
ch->dest_buf = tmpobj;
return;
}
obj = NULL;
if( ch->substate == SUB_REPEATCMD )
{
if( !( obj = ( OBJ_DATA * ) ch->dest_buf ) )
{
send_to_char( "Your object was extracted!\r\n", ch );
argument = (char *)"done";
}
if( !argument || argument[0] == '\0' || !str_cmp( argument, "stat" ) )
{
if( obj )
do_ostat( ch, obj->name );
else
send_to_char( "No object selected. Type '?' for help.\r\n", ch );
return;
}
if( !str_cmp( argument, "done" ) || !str_cmp( argument, "off" ) )
{
if( ch->dest_buf )
RelDestroy( relOSET_ON, ch, ch->dest_buf );
send_to_char( "Oset mode off.\r\n", ch );
ch->substate = SUB_NONE;
ch->dest_buf = NULL;
if( ch->pcdata && ch->pcdata->subprompt )
{
STRFREE( ch->pcdata->subprompt );
ch->pcdata->subprompt = NULL;
}
return;
}
}
if( obj )
{
lockobj = true;
mudstrlcpy( arg1, obj->name, sizeof( arg1 ) );
argument = one_argument( argument, arg2 );
mudstrlcpy( arg3, argument, sizeof( arg3 ) );
}
else
{
lockobj = false;
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
mudstrlcpy( arg3, argument, sizeof( arg3 ) );
}
if( !str_cmp( arg1, "on" ) )
{
send_to_char( "Usage: oset <object|vnum> on.\r\n", ch );
return;
}
if( arg1[0] == '\0' || arg2[0] == '\0' || !str_cmp( arg1, "?" ) )
{
if( ch->substate == SUB_REPEATCMD )
{
if( obj )
send_to_char( "Usage: <field> <value>\r\n", ch );
else
send_to_char( "Usage: <object> <field> <value>\r\n", ch );
}
else
send_to_char( "Usage: oset <object> <field> <value>\r\n", ch );
send_to_char( "\r\n", ch );
send_to_char( "Field being one of:\r\n", ch );
send_to_char( " ed v2 v5 name wear short layers actiondesc\r\n", ch );
send_to_char( " v0 v3 cost rmed flags timer weight\r\n", ch );
send_to_char( " v1 v4 long type level affect rmaffect\r\n", ch );
send_to_char( "For salves:\r\n", ch );
send_to_char( " slevel, doses, delay, spell1, spell2, spell3\r\n", ch );
send_to_char( "For armor:\r\n", ch );
send_to_char( " ac, condition\r\n", ch );
send_to_char( "For scroll/potion/pill:\r\n", ch );
send_to_char( " slevel, spell1, spell2, spell3\r\n", ch );
send_to_char( "For missileweapons and weapons:\r\n", ch );
send_to_char( " weapontype, condition\r\n", ch );
send_to_char( "For wands and staves:\r\n", ch );
send_to_char( " slevel, spell, maxcharges, charges\r\n", ch );
send_to_char( "For containers:\r\n", ch );
send_to_char( " cflags, key, capacity\r\n", ch );
send_to_char( "For levers and switches:\r\n", ch );
send_to_char( " tflags\r\n", ch );
return;
}
if( !obj && get_trust( ch ) < PERM_LEADER )
{
if( !( obj = get_obj_here( ch, arg1 ) ) )
{
send_to_char( "You can't find that here.\r\n", ch );
return;
}
}
else if( !obj )
{
if( !( obj = get_obj_world( ch, arg1 ) ) )
{
send_to_char( "There is nothing like that in all the realms.\r\n", ch );
return;
}
}
if( lockobj )
ch->dest_buf = obj;
separate_obj( obj );
value = atoi( arg3 );
if( obj->wear_loc != WEAR_NONE )
{
send_to_char( "You can't set an object that is being worn by someone.\r\n", ch );
return;
}
if( !str_cmp( arg2, "on" ) )
{
CHECK_SUBRESTRICTED( ch );
ch_printf( ch, "Oset mode on. (Editing '%s' vnum %d).\r\n", obj->name, obj->pIndexData->vnum );
ch->substate = SUB_REPEATCMD;
ch->dest_buf = obj;
if( ch->pcdata )
{
snprintf( buf, sizeof( buf ), "<&COset &W#%d&w> %%i", obj->pIndexData->vnum );
STRSET( ch->pcdata->subprompt, buf );
}
RelCreate( relOSET_ON, ch, obj );
return;
}
if( !str_cmp( arg2, "name" ) )
{
if( !can_omodify( ch, obj ) )
return;
if( arg3 == NULL || arg3[0] == '\0' )
{
send_to_char( "You can't set the name of an object to nothing.\r\n", ch );
return;
}
STRSET( obj->name, arg3 );
send_to_char( "The name has been set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
STRSET( obj->pIndexData->name, obj->name );
send_to_char( "The prototype name has been set.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "short" ) )
{
if( !can_omodify( ch, obj ) )
return;
if( arg3 == NULL || arg3[0] == '\0' )
{
send_to_char( "You can't set the short field to nothing.\r\n", ch );
return;
}
STRSET( obj->short_descr, arg3 );
send_to_char( "The short has been set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
STRSET( obj->pIndexData->short_descr, obj->short_descr );
send_to_char( "The prototype short has been set.\r\n", ch );
}
else
{
if( str_infix( "rename", obj->name ) )
{
snprintf( buf, sizeof( buf ), "%s %s", obj->name, "rename" );
STRSET( obj->name, buf );
send_to_char( "Rename has been added to the short.\r\n", ch );
}
}
return;
}
if( !str_cmp( arg2, "long" ) )
{
if( arg3 != NULL && arg3[0] != '\0' )
{
if( !can_omodify( ch, obj ) )
return;
STRSET( obj->description, arg3 );
send_to_char( "Long has been set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
STRSET( obj->pIndexData->description, obj->description );
send_to_char( "Prototype Long has been set.\r\n", ch );
}
return;
}
CHECK_SUBRESTRICTED( ch );
if( ch->substate == SUB_REPEATCMD )
ch->tempnum = SUB_REPEATCMD;
else
ch->tempnum = SUB_NONE;
if( lockobj )
ch->spare_ptr = obj;
else
ch->spare_ptr = NULL;
ch->substate = SUB_OBJ_LONG;
ch->dest_buf = obj;
start_editing( ch, obj->description );
return;
}
if( !str_cmp( arg2, "ed" ) )
{
if( arg3 == NULL || arg3[0] == '\0' )
{
send_to_char( "Usage: oset <object> ed <keywords>\r\n", ch );
return;
}
CHECK_SUBRESTRICTED( ch );
if( obj->timer )
{
send_to_char( "It's not safe to edit an extra description on an object with a timer.\r\nTurn it off first.\r\n", ch );
return;
}
if( obj->item_type == ITEM_PAPER && get_trust( ch ) < PERM_IMP )
{
send_to_char( "You can't add an extra description to a note paper at the moment.\r\n", ch );
return;
}
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
ed = SetOExtraProto( obj->pIndexData, arg3 );
else
ed = SetOExtra( obj, arg3 );
if( ch->substate == SUB_REPEATCMD )
ch->tempnum = SUB_REPEATCMD;
else
ch->tempnum = SUB_NONE;
if( lockobj )
ch->spare_ptr = obj;
else
ch->spare_ptr = NULL;
ch->substate = SUB_OBJ_EXTRA;
ch->dest_buf = ed;
start_editing( ch, ed->description );
return;
}
if( !str_cmp( arg2, "rmed" ) )
{
if( arg3 == NULL || arg3[0] == '\0' )
{
send_to_char( "Usage: oset <object> rmed <keywords>\r\n", ch );
return;
}
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
if( DelOExtraProto( obj->pIndexData, arg3 ) )
send_to_char( "Deleted.\r\n", ch );
else
send_to_char( "Not found.\r\n", ch );
return;
}
if( DelOExtra( obj, arg3 ) )
send_to_char( "Deleted.\r\n", ch );
else
send_to_char( "Not found.\r\n", ch );
return;
}
if( get_trust( ch ) < PERM_BUILDER )
{
send_to_char( "You can only oset the name, short and long right now.\r\n", ch );
return;
}
for( stat = 0; stat < STAT_MAX; stat++ )
{
if( !str_cmp( arg2, stattypes[stat] ) )
{
if( !can_omodify( ch, obj ) )
return;
obj->stat_reqs[stat] = URANGE( 0, value, 1000 );
ch_printf( ch, "%s set to %d\r\n", capitalize( stattypes[stat] ), obj->stat_reqs[stat] );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->stat_reqs[stat] = obj->stat_reqs[stat];
send_to_char( "Index set too.\r\n", ch );
}
return;
}
}
if( !str_cmp( arg2, "classes" ) )
{
bool modified = false;
if( !can_omodify( ch, obj ) )
return;
while( argument && argument[0] != '\0' )
{
argument = one_argument( argument, arg1 );
stat = get_pc_class( arg1 );
if( stat < 0 || stat >= MAX_PC_CLASS )
ch_printf( ch, "Invalid class [%s].\r\n", arg1 );
else
{
xTOGGLE_BIT( obj->class_restrict, stat );
modified = true;
}
}
if( modified )
{
send_to_char( "Classes has been set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->class_restrict = obj->class_restrict;
send_to_char( "Index Set too.\r\n", ch );
}
}
return;
}
if( !str_cmp( arg2, "races" ) )
{
bool modified = false;
if( !can_omodify( ch, obj ) )
return;
while( argument && argument[0] != '\0' )
{
argument = one_argument( argument, arg1 );
stat = get_pc_race( arg1 );
if( stat < 0 || stat >= MAX_PC_RACE )
ch_printf( ch, "Invalid race [%s].\r\n", arg1 );
else
{
xTOGGLE_BIT( obj->race_restrict, stat );
modified = true;
}
}
if( modified )
{
send_to_char( "Races has been set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->race_restrict = obj->race_restrict;
send_to_char( "Index Set too.\r\n", ch );
}
}
return;
}
if( !str_cmp( arg2, "value0" ) || !str_cmp( arg2, "v0" ) )
{
if( !can_omodify( ch, obj ) )
return;
obj->value[0] = value;
send_to_char( "Value0 set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->value[0] = value;
send_to_char( "Prototype Value0 set.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "value1" ) || !str_cmp( arg2, "v1" ) )
{
if( !can_omodify( ch, obj ) )
return;
obj->value[1] = value;
send_to_char( "Value1 set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->value[1] = value;
send_to_char( "Prototype Value1 set.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "value2" ) || !str_cmp( arg2, "v2" ) )
{
if( !can_omodify( ch, obj ) )
return;
obj->value[2] = value;
send_to_char( "Value2 set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->value[2] = value;
send_to_char( "Prototype Value2 set.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "value3" ) || !str_cmp( arg2, "v3" ) )
{
if( !can_omodify( ch, obj ) )
return;
obj->value[3] = value;
send_to_char( "Value3 set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->value[3] = value;
send_to_char( "Prototype Value3 set.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "value4" ) || !str_cmp( arg2, "v4" ) )
{
if( !can_omodify( ch, obj ) )
return;
obj->value[4] = value;
send_to_char( "Value4 set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->value[4] = value;
send_to_char( "Prototype Value4 set.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "value5" ) || !str_cmp( arg2, "v5" ) )
{
if( !can_omodify( ch, obj ) )
return;
obj->value[5] = value;
send_to_char( "Value5 set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->value[5] = value;
send_to_char( "Prototype Value5 set.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "type" ) )
{
if( !can_omodify( ch, obj ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: oset <object> type <type>\r\n", ch );
return;
}
value = get_flag( argument, o_types, ITEM_TYPE_MAX );
if( value < 1 || value >= ITEM_TYPE_MAX )
{
ch_printf( ch, "Unknown type: %s\r\n", argument );
return;
}
obj->item_type = ( short )value;
send_to_char( "Type set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->item_type = obj->item_type;
send_to_char( "Prototype Type set.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "flags" ) )
{
if( !can_omodify( ch, obj ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: oset <object> flags <flag> [flag]...\r\n", ch );
return;
}
while( argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_flag( arg3, o_flags, ITEM_MAX );
if( value < 0 || value >= ITEM_MAX )
ch_printf( ch, "Unknown flag: %s\r\n", arg3 );
else
{
if( value == ITEM_PROTOTYPE
&& get_trust( ch ) < PERM_HEAD && !is_name( "protoflag", ch->pcdata->bestowments ) )
send_to_char( "You can't change the prototype flag.\r\n", ch );
else
{
xTOGGLE_BIT( obj->extra_flags, value );
ch_printf( ch, "%s flag %s.\r\n", o_flags[value], xIS_SET( obj->extra_flags, value ) ? "set" : "removed" );
if( xIS_SET( obj->extra_flags, ITEM_PROTOTYPE ) || value == ITEM_PROTOTYPE )
{
xTOGGLE_BIT( obj->pIndexData->extra_flags, value );
ch_printf( ch, "%s index flag %s.\r\n", o_flags[value], xIS_SET( obj->pIndexData->extra_flags, value ) ? "set" : "removed" );
}
}
}
}
return;
}
if( !str_cmp( arg2, "wear" ) )
{
if( !can_omodify( ch, obj ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: oset <object> wear <flag> [flag]...\r\n", ch );
return;
}
while( argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_flag( arg3, w_flags, ITEM_WEAR_MAX );
if( value < 0 || value >= ITEM_WEAR_MAX )
ch_printf( ch, "Unknown flag: %s\r\n", arg3 );
else
{
xTOGGLE_BIT( obj->wear_flags, value );
ch_printf( ch, "%s wear flag %s.\r\n", w_flags[value], xIS_SET( obj->wear_flags, value ) ? "set" : "removed" );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
xTOGGLE_BIT( obj->pIndexData->wear_flags, value );
ch_printf( ch, "%s index wear flag %s.\r\n", w_flags[value], xIS_SET( obj->pIndexData->wear_flags, value ) ? "set" : "removed" );
}
}
}
return;
}
if( !str_cmp( arg2, "level" ) )
{
if( !can_omodify( ch, obj ) )
return;
obj->level = URANGE( 0, value, MAX_LEVEL );
send_to_char( "Level set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->level = obj->level;
send_to_char( "Prototype Level set.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "weight" ) )
{
if( !can_omodify( ch, obj ) )
return;
if( obj->carried_by )
obj->carried_by->carry_weight -= get_obj_weight( obj );
obj->weight = UMAX( 0, value );
if( obj->carried_by )
obj->carried_by->carry_weight += get_obj_weight( obj );
send_to_char( "Weight set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->weight = obj->weight;
send_to_char( "Prototype Weight set.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "cost" ) )
{
if( !can_omodify( ch, obj ) )
return;
obj->cost = UMAX( 0, value );
send_to_char( "Cost set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->cost = obj->cost;
send_to_char( "Prototoype Cost set.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "layers" ) )
{
if( !can_omodify( ch, obj ) )
return;
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->layers = UMAX( 0, value );
send_to_char( "Prototype layers set.\r\n", ch );
}
else
send_to_char( "Item must have prototype flag to set this value.\r\n", ch );
return;
}
if( !str_cmp( arg2, "timer" ) )
{
if( !can_omodify( ch, obj ) )
return;
obj->timer = value;
send_to_char( "Timer set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
send_to_char( "Just FYI prototype doesn't have a timer to set.\r\n", ch );
return;
}
if( !str_cmp( arg2, "actiondesc" ) )
{
if( !can_omodify( ch, obj ) )
return;
if( strstr( arg3, "%n" ) || strstr( arg3, "%d" ) || strstr( arg3, "%l" ) )
{
send_to_char( "Illegal characters!\r\n", ch );
return;
}
STRSET( obj->action_desc, arg3 );
send_to_char( "Actiondesc set.\r\n", ch );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
STRSET( obj->pIndexData->action_desc, obj->action_desc );
send_to_char( "Prototype Actiondesc set.\r\n", ch );
}
return;
}
/* Crash fix and name support by Shaddai */
if( !str_cmp( arg2, "affect" ) )
{
AFFECT_DATA *paf;
short loc;
int bitv = -1;
if( !can_omodify( ch, obj ) )
return;
argument = one_argument( argument, arg2 );
if( arg2 == NULL || arg2[0] == '\0' || !argument || argument[0] == 0 )
{
send_to_char( "Usage: oset <object> affect <field> <value>\r\n", ch );
return;
}
loc = get_flag( arg2, a_types, APPLY_MAX );
if( loc < 1 || loc >= APPLY_MAX )
{
ch_printf( ch, "Unknown field: %s\r\n", arg2 );
return;
}
argument = one_argument( argument, arg3 );
if( loc == APPLY_EXT_AFFECT )
{
value = get_flag( arg3, a_flags, AFF_MAX );
if( value < 0 || value >= AFF_MAX )
{
ch_printf( ch, "Unknown affected: %s\r\n", arg3 );
return;
}
}
else if( loc == APPLY_RESISTANT || loc == APPLY_IMMUNE || loc == APPLY_SUSCEPTIBLE || loc == APPLY_ABSORB )
{
value = get_flag( arg3, ris_flags, RIS_MAX );
if( value < 0 || value >= RIS_MAX )
{
ch_printf( ch, "Unknown resistant/immune/susceptible/absorb: %s\r\n", arg3 );
return;
}
}
else if( loc == APPLY_STAT )
{
bitv = get_flag( arg3, stattypes, STAT_MAX );
if( bitv < 0 || bitv >= STAT_MAX )
{
ch_printf( ch, "Unknown stat: %s\r\n", arg3 );
return;
}
argument = one_argument( argument, arg3 );
value = atoi( arg3 );
}
else
{
if( ( loc == APPLY_WEARSPELL || loc == APPLY_REMOVESPELL || loc == APPLY_STRIPSN || loc == APPLY_WEAPONSPELL )
&& !is_number( arg3 ) )
{
value = bsearch_skill_exact( arg3, gsn_first_spell, gsn_first_skill - 1 );
if( value == -1 )
{
ch_printf( ch, "Unknown spell name: %s\r\n", arg3 );
return;
}
}
else
value = atoi( arg3 );
}
CREATE( paf, AFFECT_DATA, 1 );
paf->type = -1;
paf->duration = -1;
paf->location = loc;
paf->modifier = value;
xCLEAR_BITS( paf->bitvector );
if( loc == APPLY_STAT )
xSET_BIT( paf->bitvector, bitv );
paf->next = NULL;
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
if( loc != APPLY_WEARSPELL && loc != APPLY_REMOVESPELL && loc != APPLY_STRIPSN && loc != APPLY_WEAPONSPELL )
{
CHAR_DATA *vch;
OBJ_DATA *eq;
for( vch = first_char; vch; vch = vch->next )
for( eq = vch->first_carrying; eq; eq = eq->next_content )
if( eq->pIndexData == obj->pIndexData && eq->wear_loc != WEAR_NONE )
affect_modify( vch, paf, true );
}
LINK( paf, obj->pIndexData->first_affect, obj->pIndexData->last_affect, next, prev );
send_to_char( "Prototype Affect added.\r\n", ch );
}
else
{
LINK( paf, obj->first_affect, obj->last_affect, next, prev );
send_to_char( "Extra Affect added.\r\n", ch );
}
++top_affect;
return;
}
if( !str_cmp( arg2, "rmaffect" ) )
{
AFFECT_DATA *paf;
short loc, count;
if( !can_omodify( ch, obj ) )
return;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: oset <object> rmaffect <affect#>\r\n", ch );
return;
}
loc = atoi( argument );
if( loc < 1 )
{
send_to_char( "Invalid number.\r\n", ch );
return;
}
count = 0;
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
OBJ_INDEX_DATA *pObjIndex;
pObjIndex = obj->pIndexData;
for( paf = pObjIndex->first_affect; paf; paf = paf->next )
{
if( ++count == loc )
{
loc = paf->location;
if( loc != APPLY_WEARSPELL && loc != APPLY_REMOVESPELL && loc != APPLY_STRIPSN && loc != APPLY_WEAPONSPELL )
{
CHAR_DATA *vch;
OBJ_DATA *eq;
for( vch = first_char; vch; vch = vch->next )
for( eq = vch->first_carrying; eq; eq = eq->next_content )
if( eq->pIndexData == pObjIndex && eq->wear_loc != WEAR_NONE )
affect_modify( vch, paf, false );
}
UNLINK( paf, pObjIndex->first_affect, pObjIndex->last_affect, next, prev );
DISPOSE( paf );
send_to_char( "Removed from the prototype affects.\r\n", ch );
--top_affect;
return;
}
}
send_to_char( "Not found in the prototype affects.\r\n", ch );
return;
}
else
{
for( paf = obj->first_affect; paf; paf = paf->next )
{
if( ++count == loc )
{
UNLINK( paf, obj->first_affect, obj->last_affect, next, prev );
DISPOSE( paf );
send_to_char( "Removed from the extra affects.\r\n", ch );
--top_affect;
return;
}
}
send_to_char( "Not found in the extra affects.\r\n", ch );
return;
}
}
/* Make it easier to set special object values by name than number -Thoric */
tmp = -1;
switch( obj->item_type )
{
case ITEM_MISSILE_WEAPON:
case ITEM_WEAPON:
if( !str_cmp( arg2, "weapontype" ) )
{
unsigned int x;
value = -1;
for( x = 0; x < sizeof( attack_table ) / sizeof( attack_table[0] ); x++ )
if( !str_cmp( arg3, attack_table[x] ) )
value = x;
if( value < 0 )
{
send_to_char( "Unknown weapon type.\r\n", ch );
return;
}
tmp = 3;
break;
}
if( !str_cmp( arg2, "condition" ) )
tmp = 0;
break;
case ITEM_ARMOR:
if( !str_cmp( arg2, "ac" ) )
tmp = 0;
if( !str_cmp( arg2, "condition" ) )
tmp = 1;
break;
case ITEM_SALVE:
if( !str_cmp( arg2, "slevel" ) )
tmp = 0;
if( !str_cmp( arg2, "doses" ) )
tmp = 1;
if( !str_cmp( arg2, "delay" ) )
tmp = 2;
if( !str_cmp( arg2, "spell1" ) )
tmp = 3;
if( !str_cmp( arg2, "spell2" ) )
tmp = 4;
if( !str_cmp( arg2, "spell3" ) )
tmp = 5;
if( tmp >= 3 && tmp <= 5 )
value = skill_lookup( arg3 );
break;
case ITEM_SCROLL:
case ITEM_POTION:
case ITEM_PILL:
if( !str_cmp( arg2, "slevel" ) )
tmp = 0;
if( !str_cmp( arg2, "spell1" ) )
tmp = 1;
if( !str_cmp( arg2, "spell2" ) )
tmp = 2;
if( !str_cmp( arg2, "spell3" ) )
tmp = 3;
if( tmp >= 1 && tmp <= 3 )
value = skill_lookup( arg3 );
break;
case ITEM_STAFF:
case ITEM_WAND:
if( !str_cmp( arg2, "slevel" ) )
tmp = 0;
if( !str_cmp( arg2, "maxcharges" ) )
tmp = 1;
if( !str_cmp( arg2, "charges" ) )
tmp = 2;
if( !str_cmp( arg2, "spell" ) )
{
tmp = 3;
value = skill_lookup( arg3 );
}
break;
case ITEM_CONTAINER:
if( !str_cmp( arg2, "capacity" ) )
tmp = 0;
if( !str_cmp( arg2, "cflags" ) )
{
int tmpval = 0;
tmp = 1;
argument = arg3;
while( argument && argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_contflag( arg3 );
if( value < 0 || value > 31 )
ch_printf( ch, "Invalid container flag %s\r\n", arg3 );
else
tmpval += ( 1 << value );
}
value = tmpval;
}
if( !str_cmp( arg2, "key" ) )
tmp = 2;
break;
case ITEM_SWITCH:
case ITEM_LEVER:
case ITEM_PULLCHAIN:
case ITEM_BUTTON:
if( !str_cmp( arg2, "tflags" ) )
{
int tmpval = 0;
tmp = 0;
argument = arg3;
while( argument && argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_trigflag( arg3 );
if( value < 0 || value > 31 )
ch_printf( ch, "Invalid tflag %s\r\n", arg3 );
else
tmpval += ( 1 << value );
}
value = tmpval;
}
break;
}
if( tmp >= 0 && tmp <= 5 )
{
if( !can_omodify( ch, obj ) )
return;
obj->value[tmp] = value;
ch_printf( ch, "%s set.\r\n", arg2 );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
obj->pIndexData->value[tmp] = value;
ch_printf( ch, "Prototype %s set.\r\n", arg2 );
}
return;
}
/* Generate usage message. */
if( ch->substate == SUB_REPEATCMD )
{
ch->substate = SUB_RESTRICTED;
interpret( ch, origarg );
ch->substate = SUB_REPEATCMD;
ch->last_cmd = do_oset;
}
else
do_oset( ch, (char *)"" );
return;
}
/* Returns value 0 - 9 based on directional text. */
int get_dir( char *txt )
{
char c1, c2;
c1 = txt[0];
if( c1 == '\0' )
return 0;
c2 = txt[1];
if( !str_cmp( txt, "northeast" ) || ( c1 == 'n' && c2 == 'e' ) || c1 == '6' )
return DIR_NORTHEAST;
if( !str_cmp( txt, "northwest" ) || ( c1 == 'n' && c2 == 'w' ) || c1 == '7' )
return DIR_NORTHWEST;
if( !str_cmp( txt, "southeast" ) || ( c1 == 's' && c2 == 'e' ) || c1 == '8' )
return DIR_SOUTHEAST;
if( !str_cmp( txt, "southwest" ) || ( c1 == 's' && c2 == 'w' ) || c1 == '9' )
return DIR_SOUTHWEST;
if( !str_cmp( txt, "somewhere" ) || c1 == '?' || ( c1 == '1' && c2 == '0' ) )
return DIR_SOMEWHERE;
if( c1 == 'n' || c1 == '0' )
return DIR_NORTH;
if( c1 == 'e' || c1 == '1' )
return DIR_EAST;
if( c1 == 's' || c1 == '2' )
return DIR_SOUTH;
if( c1 == 'w' || c1 == '3' )
return DIR_WEST;
if( c1 == 'u' || c1 == '4' )
return DIR_UP;
if( c1 == 'd' || c1 == '5' )
return DIR_DOWN;
return 0; /* If we get here return 0 */
}
void do_redit( CHAR_DATA *ch, char *argument )
{
ROOM_INDEX_DATA *location, *tmp;
EXTRA_DESCR_DATA *ed;
EXIT_DATA *xit, *texit;
char arg[MIL], arg2[MIL], arg3[MIL], buf[MSL], *origarg = argument;
int value, edir = 0, ekey, evnum;
static const char *dir_text[] = { "North", "East", "South", "West", "Up", "Down", "NorthEast", "NorthWest", "SouthEast", "SouthWest", "Somewhere" };
set_char_color( AT_PLAIN, ch );
if( !ch->desc )
{
send_to_char( "You have no descriptor.\r\n", ch );
return;
}
switch( ch->substate )
{
default:
break;
case SUB_ROOM_DESC:
location = ( ROOM_INDEX_DATA *) ch->dest_buf;
if( !location )
{
bug( "%s: sub_room_desc: NULL ch->dest_buf", __FUNCTION__ );
location = ch->in_room;
}
STRFREE( location->description );
location->description = copy_buffer( ch );
stop_editing( ch );
ch->substate = ch->tempnum;
return;
case SUB_ROOM_EXTRA:
ed = ( EXTRA_DESCR_DATA *) ch->dest_buf;
if( !ed )
{
bug( "%s: sub_room_extra: NULL ch->dest_buf", __FUNCTION__ );
stop_editing( ch );
return;
}
STRFREE( ed->description );
ed->description = copy_buffer( ch );
stop_editing( ch );
ch->substate = ch->tempnum;
return;
}
location = ch->in_room;
argument = one_argument( argument, arg );
if( ch->substate == SUB_REPEATCMD )
{
if( arg == NULL || arg[0] == '\0' )
{
do_rstat( ch, (char *)"" );
return;
}
if( !str_cmp( arg, "done" ) || !str_cmp( arg, "off" ) )
{
send_to_char( "Redit mode off.\r\n", ch );
if( ch->pcdata && ch->pcdata->subprompt )
{
STRFREE( ch->pcdata->subprompt );
ch->pcdata->subprompt = NULL;
}
ch->substate = SUB_NONE;
return;
}
}
if( arg[0] == '\0' || !str_cmp( arg, "?" ) )
{
if( ch->substate == SUB_REPEATCMD )
send_to_char( "Usage: <field> value\r\n", ch );
else
send_to_char( "Usage: redit <field> value\r\n", ch );
send_to_char( "\r\n", ch );
send_to_char( "Field being one of:\r\n", ch );
send_to_char( " ed rmed exkey exflags televnum\r\n", ch );
send_to_char( " exit pull bexit exname pulltype\r\n", ch );
send_to_char( " name push flags sector teledelay\r\n", ch );
send_to_char( " desc rlist exdesc tunnel\r\n", ch );
return;
}
if( !can_rmodify( ch, location ) )
return;
if( !str_cmp( arg, "on" ) )
{
CHECK_SUBRESTRICTED( ch );
send_to_char( "Redit mode on.\r\n", ch );
ch->substate = SUB_REPEATCMD;
if( ch->pcdata )
STRSET( ch->pcdata->subprompt, "<&CRedit &W#%r&w> %i" );
return;
}
if( !str_cmp( arg, "name" ) )
{
if( !argument || argument[0] == '\0' )
{
send_to_char( "Set the room name. A very brief single line room description.\r\n", ch );
send_to_char( "Usage: redit name <Room summary>\r\n", ch );
return;
}
STRSET( location->name, argument );
send_to_char( "Name set.\r\n", ch );
return;
}
if( !str_cmp( arg, "desc" ) )
{
if( ch->substate == SUB_REPEATCMD )
ch->tempnum = SUB_REPEATCMD;
else
ch->tempnum = SUB_NONE;
ch->substate = SUB_ROOM_DESC;
ch->dest_buf = location;
start_editing( ch, location->description );
return;
}
if( !str_cmp( arg, "tunnel" ) )
{
location->tunnel = URANGE( 0, atoi( argument ), 1000 );
ch_printf( ch, "Tunnel set to %d.\r\n", location->tunnel );
return;
}
if( !str_cmp( arg, "ed" ) )
{
if( !argument || argument[0] == '\0' )
{
send_to_char( "Create an extra description.\r\n", ch );
send_to_char( "You must supply keyword(s).\r\n", ch );
return;
}
CHECK_SUBRESTRICTED( ch );
ed = SetRExtra( location, argument );
if( ch->substate == SUB_REPEATCMD )
ch->tempnum = SUB_REPEATCMD;
else
ch->tempnum = SUB_NONE;
ch->substate = SUB_ROOM_EXTRA;
ch->dest_buf = ed;
start_editing( ch, ed->description );
return;
}
if( !str_cmp( arg, "rmed" ) )
{
if( !argument || argument[0] == '\0' )
{
send_to_char( "Remove an extra description.\r\n", ch );
send_to_char( "You must supply keyword(s).\r\n", ch );
return;
}
if( DelRExtra( location, argument ) )
send_to_char( "Deleted.\r\n", ch );
else
send_to_char( "Not found.\r\n", ch );
return;
}
if( !str_cmp( arg, "rlist" ) )
{
RESET_DATA *pReset;
char *rbuf;
short num;
if( !location->first_reset )
{
send_to_char( "This room has no resets to list.\r\n", ch );
return;
}
num = 0;
for( pReset = location->first_reset; pReset; pReset = pReset->next )
{
num++;
if( !( rbuf = sprint_reset( pReset, &num ) ) )
continue;
send_to_char( rbuf, ch );
}
return;
}
if( !str_cmp( arg, "flags" ) )
{
if( !argument || argument[0] == '\0' )
{
send_to_char( "Toggle the room flags.\r\n", ch );
send_to_char( "Usage: redit flags <flag> [flag]...\r\n", ch );
return;
}
while( argument[0] != '\0' )
{
argument = one_argument( argument, arg2 );
value = get_flag( arg2, r_flags, ROOM_MAX );
if( value < 0 || value >= ROOM_MAX )
ch_printf( ch, "Unknown flag: %s\r\n", arg2 );
else
{
xTOGGLE_BIT( location->room_flags, value );
/* Stopping it from being a storage room */
if( value == ROOM_STORAGEROOM && !xIS_SET( location->room_flags, value ) )
{
char storage[MSL];
snprintf( storage, sizeof( storage ), "%s%d", STORAGE_DIR, location->vnum );
if( !remove( storage ) )
send_to_char( "Removed the storage file for the room.\r\n", ch );
}
ch_printf( ch, "Flag [%d]%s has been %s.\r\n", value, arg2, xIS_SET( location->room_flags, value ) ? "set" : "removed" );
}
}
return;
}
if( !str_cmp( arg, "teledelay" ) )
{
location->tele_delay = UMAX( 0, atoi( argument ) );
ch_printf( ch, "Teledelay set to %d.\r\n", location->tele_delay );
return;
}
if( !str_cmp( arg, "televnum" ) )
{
value = URANGE( 0, atoi( argument ), MAX_VNUM );
if( value != 0 && !get_room_index( value ) )
{
send_to_char( "Not a valid room vnum.\r\n", ch );
return;
}
location->tele_vnum = value;
ch_printf( ch, "Televnum set to %d.\r\n", location->tele_vnum );
return;
}
if( !str_cmp( arg, "sector" ) )
{
value = get_flag( argument, sect_flags, SECT_MAX );
if( value < 0 && is_number( argument ) )
value = atoi( argument );
if( value < 0 || value >= SECT_MAX )
ch_printf( ch, "No such sector (%s).\r\n", argument );
else
{
location->sector_type = value;
ch_printf( ch, "Sector set to %d[%s].\r\n", location->sector_type, sect_flags[ch->in_room->sector_type] );
}
return;
}
if( !str_cmp( arg, "exkey" ) )
{
argument = one_argument( argument, arg2 );
argument = one_argument( argument, arg3 );
if( arg2[0] == '\0' || arg3[0] == '\0' )
{
send_to_char( "Usage: redit exkey <dir> <key vnum>\r\n", ch );
return;
}
edir = get_dir( arg2 );
value = atoi( arg3 );
if( !get_obj_index( value ) )
{
send_to_char( "No such key to use exist.\r\n", ch );
return;
}
if( !( xit = get_exit( location, edir ) ) )
{
send_to_char( "No exit in that direction. Use 'redit exit ...' first.\r\n", ch );
return;
}
xit->key = value;
send_to_char( "Exkey Set.\r\n", ch );
return;
}
if( !str_cmp( arg, "exname" ) )
{
argument = one_argument( argument, arg2 );
if( arg2 == NULL || arg2[0] == '\0' )
{
send_to_char( "Change or clear exit keywords.\r\n", ch );
send_to_char( "Usage: redit exname <dir> [keywords]\r\n", ch );
return;
}
edir = get_dir( arg2 );
if( !( xit = get_exit( location, edir ) ) )
{
send_to_char( "No exit in that direction. Use 'redit exit ...' first.\r\n", ch );
return;
}
STRSET( xit->keyword, argument );
send_to_char( "Exname set.\r\n", ch );
return;
}
if( !str_cmp( arg, "exflags" ) )
{
if( !argument || argument[0] == '\0' )
{
send_to_char( "Toggle or display exit flags.\r\n", ch );
send_to_char( "Usage: redit exflags <dir> <flag> [flag]...\r\n", ch );
return;
}
argument = one_argument( argument, arg2 );
edir = get_dir( arg2 );
if( !( xit = get_exit( location, edir ) ) )
{
send_to_char( "No exit in that direction. Use 'redit exit ...' first.\r\n", ch );
return;
}
if( !argument || argument[0] == '\0' )
{
snprintf( buf, sizeof( buf ), "Flags for exit direction: [ %s ] Keywords: [ %s ] Key: %d\r\n[ ",
dir_text[xit->vdir], xit->keyword, xit->key );
for( value = 0; value < EX_MAX; value++ )
{
if( xIS_SET( xit->exit_info, value ) )
{
mudstrlcat( buf, ex_flags[value], sizeof( buf ) );
mudstrlcat( buf, " ", sizeof( buf ) );
}
}
mudstrlcat( buf, "]\r\n", sizeof( buf ) );
send_to_char( buf, ch );
return;
}
while( argument && argument[0] != '\0' )
{
argument = one_argument( argument, arg2 );
value = get_flag( arg2, ex_flags, EX_MAX );
if( value < 0 || value >= EX_MAX )
ch_printf( ch, "Unknown ex_flag: %s\r\n", arg2 );
else
{
xTOGGLE_BIT( xit->exit_info, value );
ch_printf( ch, "%s exflag %s.\r\n", ex_flags[value], xIS_SET( xit->exit_info, value ) ? "set" : "removed" );
}
}
return;
}
if( !str_cmp( arg, "exit" ) )
{
bool changed = false, showmessg = false;
argument = one_argument( argument, arg2 );
argument = one_argument( argument, arg3 );
if( arg2 == NULL || arg2[0] == '\0' )
{
send_to_char( "Create, change or remove an exit.\r\n", ch );
send_to_char( "Usage: redit exit <dir> [room] [key] [keywords] [flags]\r\n", ch );
return;
}
edir = get_dir( arg2 );
if( arg3 == NULL || arg3[0] == '\0' )
evnum = 0;
else
evnum = atoi( arg3 );
xit = get_exit( location, edir );
if( !evnum )
{
if( xit )
{
ch_printf( ch, "Removed exit %s in room %d that went to room %d.\r\n", dir_text[xit->vdir], xit->rvnum, xit->vnum );
extract_exit( location, xit );
return;
}
send_to_char( "No exit in that direction.\r\n", ch );
return;
}
if( evnum < 1 || evnum > MAX_VNUM )
{
send_to_char( "Invalid room number.\r\n", ch );
return;
}
if( !( tmp = get_room_index( evnum ) ) )
{
send_to_char( "Non-existant room.\r\n", ch );
return;
}
if( !xit )
{
if( xit && get_exit_to( location, edir, tmp->vnum ) )
{
ch_printf( ch, "There is already an exit %s in room %d to %d.\r\n", dir_text[edir], xit->rvnum, xit->vnum );
return;
}
if( !( xit = make_exit( location, tmp, edir ) ) )
{
send_to_char( "Failed to make_exit.\r\n", ch );
return;
}
xit->keyword = NULL;
xit->description = NULL;
xit->key = -1;
xCLEAR_BITS( xit->exit_info );
act( AT_IMMORT, "$n reveals a hidden passage!", ch, NULL, NULL, TO_ROOM );
}
else
{
act( AT_IMMORT, "Something is different...", ch, NULL, NULL, TO_ROOM );
changed = true;
}
if( xit->to_room != tmp )
{
ch_printf( ch, "Changed exit %s in room %d from room %d to %d.\r\n", dir_text[edir], xit->rvnum, xit->vnum, evnum );
changed = true;
xit->to_room = tmp;
xit->vnum = evnum;
if( ( texit = get_exit_to( xit->to_room, rev_dir[edir], location->vnum ) ) )
{
texit->rexit = xit;
xit->rexit = texit;
}
}
/* Set the key */
argument = one_argument( argument, arg3 );
if( arg3 != NULL && arg3[0] != '\0' )
{
if( is_number( arg3 ) )
{
ekey = atoi( arg3 );
if( ekey != 0 )
{
if( !get_obj_index( ekey ) )
ch_printf( ch, "%d isn't a valid object so can't be set as a key.\r\n", ekey );
else
{
if( xit->key != ekey )
showmessg = true;
xit->key = ekey;
}
}
}
}
/* Set the keywords */
argument = one_argument( argument, arg3 );
if( arg3 != NULL && arg3[0] != '\0' )
{
if( xit->keyword && xit->keyword[0] != '\0' && str_cmp( xit->keyword, arg3 ) )
showmessg = true;
STRSET( xit->keyword, arg3 );
}
/* Set flags */
if( argument && argument[0] != '\0' )
{
while( argument && argument[0] != '\0' )
{
argument = one_argument( argument, arg3 );
value = get_flag( arg3, ex_flags, EX_MAX );
if( value < 0 || value >= EX_MAX )
ch_printf( ch, "Unknown ex_flag (%s).\r\n", arg3 );
else
{
if( !xIS_SET( xit->exit_info, value ) )
showmessg = true;
xSET_BIT( xit->exit_info, value );
}
}
}
if( !changed )
ch_printf( ch, "Added exit %s from room %d to %d.\r\n", dir_text[edir], xit->rvnum, xit->vnum );
else if( showmessg )
ch_printf( ch, "Modified exit %s from room %d to %d.\r\n", dir_text[edir], xit->rvnum, xit->vnum );
else if( xit )
{
ch_printf( ch, "Removed exit %s in room %d that went to room %d.\r\n", dir_text[xit->vdir], xit->rvnum, xit->vnum );
extract_exit( location, xit );
}
return;
}
if( !str_cmp( arg, "bexit" ) )
{
EXIT_DATA *nxit = NULL, *rxit = NULL;
char tmpcmd[MIL];
int vnum = 0, ovnum = 0;
argument = one_argument( argument, arg2 );
argument = one_argument( argument, arg3 );
if( arg2 == NULL || arg2[0] == '\0' )
{
send_to_char( "Create, change or remove a two-way exit.\r\n", ch );
send_to_char( "Usage: redit bexit <dir> [room] [key] [keywords] [flags]\r\n", ch );
return;
}
edir = get_dir( arg2 );
if( ( nxit = get_exit( location, edir ) ) )
{
ovnum = nxit->vnum;
vnum = nxit->vnum;
if( nxit->to_room )
rxit = get_exit( nxit->to_room, rev_dir[edir] );
else
rxit = NULL;
}
snprintf( tmpcmd, sizeof( tmpcmd ), "exit %s %s %s", arg2, arg3, argument );
do_redit( ch, tmpcmd );
if( ( nxit = get_exit( location, edir ) ) )
{
vnum = nxit->vnum;
if( !rxit || vnum != ovnum )
{
if( nxit->to_room )
rxit = get_exit( nxit->to_room, rev_dir[edir] );
else
rxit = NULL;
}
}
if( vnum )
{
snprintf( tmpcmd, sizeof( tmpcmd ), "%d redit exit %d %d %s", vnum, rev_dir[edir], location->vnum, argument );
do_at( ch, tmpcmd );
}
if( ovnum != 0 && ovnum != vnum )
{
snprintf( tmpcmd, sizeof( tmpcmd ), "%d redit exit %d", ovnum, rev_dir[edir] );
do_at( ch, tmpcmd );
}
return;
}
if( !str_cmp( arg, "pulltype" ) || !str_cmp( arg, "pushtype" ) )
{
int pt;
argument = one_argument( argument, arg2 );
if( arg2 == NULL || arg2[0] == '\0' )
{
ch_printf( ch, "Set the %s between this room, and the destination room.\r\n", arg );
ch_printf( ch, "Usage: redit %s <dir> <type>\r\n", arg );
return;
}
if( arg2[0] == '#' )
{
edir = atoi( arg2 + 1 );
xit = get_exit_num( location, edir );
}
else
{
edir = get_dir( arg2 );
xit = get_exit( location, edir );
}
if( xit )
{
if( ( pt = get_pulltype( argument ) ) == -1 )
ch_printf( ch, "Unknown pulltype: %s. (See help PULLTYPES)\r\n", argument );
else
{
xit->pulltype = pt;
send_to_char( "Done.\r\n", ch );
}
}
else
send_to_char( "No exit in that direction. Use 'redit exit ...' first.\r\n", ch );
return;
}
if( !str_cmp( arg, "pull" ) )
{
argument = one_argument( argument, arg2 );
if( arg2 == NULL || arg2[0] == '\0' )
{
send_to_char( "Set the 'pull' between this room, and the destination room.\r\n", ch );
send_to_char( "Usage: redit pull <dir> <force (0 to 100)>\r\n", ch );
return;
}
if( arg2[0] == '#' )
{
edir = atoi( arg2 + 1 );
xit = get_exit_num( location, edir );
}
else
{
edir = get_dir( arg2 );
xit = get_exit( location, edir );
}
if( xit )
{
xit->pull = URANGE( -100, atoi( argument ), 100 );
send_to_char( "Done.\r\n", ch );
}
else
send_to_char( "No exit in that direction. Use 'redit exit ...' first.\r\n", ch );
return;
}
if( !str_cmp( arg, "push" ) )
{
argument = one_argument( argument, arg2 );
if( arg2 == NULL || arg2[0] == '\0' )
{
send_to_char( "Set the 'push' away from the destination room in the opposite direction.\r\n", ch );
send_to_char( "Usage: redit push <dir> <force (0 to 100)>\r\n", ch );
return;
}
if( arg2[0] == '#' )
{
edir = atoi( arg2 + 1 );
xit = get_exit_num( location, edir );
}
else
{
edir = get_dir( arg2 );
xit = get_exit( location, edir );
}
if( xit )
{
xit->pull = URANGE( -100, -( atoi( argument ) ), 100 );
send_to_char( "Done.\r\n", ch );
}
else
send_to_char( "No exit in that direction. Use 'redit exit ...' first.\r\n", ch );
return;
}
if( !str_cmp( arg, "exdesc" ) )
{
argument = one_argument( argument, arg2 );
if( arg2 == NULL || arg2[0] == '\0' )
{
send_to_char( "Create or clear a description for an exit.\r\n", ch );
send_to_char( "Usage: redit exdesc <dir> [description]\r\n", ch );
return;
}
if( arg2[0] == '#' )
{
edir = atoi( arg2 + 1 );
xit = get_exit_num( location, edir );
}
else
{
edir = get_dir( arg2 );
xit = get_exit( location, edir );
}
if( xit )
{
STRFREE( xit->description );
if( argument && argument[0] != '\0' )
{
snprintf( buf, sizeof( buf ), "%s\r\n", argument );
xit->description = STRALLOC( buf );
}
send_to_char( "Done.\r\n", ch );
}
else
send_to_char( "No exit in that direction. Use 'redit exit ...' first.\r\n", ch );
return;
}
/* Generate usage message. */
if( ch->substate == SUB_REPEATCMD )
{
ch->substate = SUB_RESTRICTED;
interpret( ch, origarg );
ch->substate = SUB_REPEATCMD;
ch->last_cmd = do_redit;
}
else
do_redit( ch, (char *)"" );
}
CMDF( do_ocreate )
{
char arg[MIL], arg2[MIL];
OBJ_INDEX_DATA *pObjIndex;
OBJ_DATA *obj;
int vnum, cvnum;
if( is_npc( ch ) )
{
send_to_char( "Mobiles can't create.\r\n", ch );
return;
}
argument = one_argument( argument, arg );
vnum = is_number( arg ) ? atoi( arg ) : -1;
if( vnum == -1 || !argument || argument[0] == '\0' )
{
send_to_char( "Usage: ocreate <vnum> [copy vnum] <item name>\r\n", ch );
return;
}
if( vnum < 1 || vnum > MAX_VNUM )
{
send_to_char( "Vnum out of range.\r\n", ch );
return;
}
one_argument( argument, arg2 );
cvnum = atoi( arg2 );
if( cvnum != 0 )
argument = one_argument( argument, arg2 );
if( cvnum < 1 )
cvnum = 0;
if( get_obj_index( vnum ) )
{
send_to_char( "An object with that number already exists.\r\n", ch );
return;
}
if( get_trust( ch ) < PERM_LEADER )
{
AREA_DATA *pArea;
if( !ch->pcdata || !( pArea = ch->pcdata->area ) )
{
send_to_char( "You must have an assigned area to create objects.\r\n", ch );
return;
}
if( vnum < pArea->low_vnum || vnum > pArea->hi_vnum )
{
send_to_char( "That number is not in your allocated range.\r\n", ch );
return;
}
}
if( !( pObjIndex = make_object( vnum, cvnum, argument ) ) )
{
send_to_char( "Couldn't make_object.\r\n", ch );
log_printf( "%s: make_object failed.", __FUNCTION__ );
return;
}
if( !( obj = create_object( pObjIndex, get_trust( ch ) ) ) )
{
send_to_char( "Couldn't create_object.\r\n", ch );
log_printf( "%s: create_object failed.", __FUNCTION__ );
return;
}
obj_to_char( obj, ch );
act( AT_IMMORT, "$n makes arcane gestures, and opens $s hands to reveal $p!", ch, obj, NULL, TO_ROOM );
ch_printf( ch, "&YYou make arcane gestures, and open your hands to reveal %s!\r\nObjVnum: &W%d &YKeywords: &W%s\r\n",
pObjIndex->short_descr, pObjIndex->vnum, pObjIndex->name );
}
CMDF( do_mcreate )
{
char arg[MIL], arg2[MIL];
MOB_INDEX_DATA *pMobIndex;
CHAR_DATA *mob;
int vnum, cvnum;
if( is_npc( ch ) )
{
send_to_char( "Mobiles can't create.\r\n", ch );
return;
}
argument = one_argument( argument, arg );
vnum = is_number( arg ) ? atoi( arg ) : -1;
if( vnum == -1 || !argument || argument[0] == '\0' )
{
send_to_char( "Usage: mcreate <vnum> [cvnum] <mobile name>\r\n", ch );
return;
}
if( vnum < 1 || vnum > MAX_VNUM )
{
send_to_char( "Vnum out of range.\r\n", ch );
return;
}
one_argument( argument, arg2 );
cvnum = atoi( arg2 );
if( cvnum != 0 )
argument = one_argument( argument, arg2 );
if( cvnum < 1 )
cvnum = 0;
if( get_mob_index( vnum ) )
{
send_to_char( "A mobile with that number already exists.\r\n", ch );
return;
}
if( get_trust( ch ) < PERM_LEADER )
{
AREA_DATA *pArea;
if( !ch->pcdata || !( pArea = ch->pcdata->area ) )
{
send_to_char( "You must have an assigned area to create mobiles.\r\n", ch );
return;
}
if( vnum < pArea->low_vnum || vnum > pArea->hi_vnum )
{
send_to_char( "That number is not in your allocated range.\r\n", ch );
return;
}
}
if( !( pMobIndex = make_mobile( vnum, cvnum, argument ) ) )
{
send_to_char( "Error.\r\n", ch );
log_printf( "%s: make_mobile failed to make a mob using vnum %d.", __FUNCTION__, vnum );
return;
}
mob = create_mobile( pMobIndex );
char_to_room( mob, ch->in_room );
act( AT_IMMORT, "$n waves $s arms about, and $N appears at $s command!", ch, NULL, mob, TO_ROOM );
ch_printf( ch, "&YYou wave your arms about, and %s appears at your command!\r\nMobVnum: &W%d &YKeywords: &W%s\r\n",
pMobIndex->short_descr, pMobIndex->vnum, pMobIndex->name );
}
char *imcstrrep( const char *src, const char *sch, const char *rep );
/* Simple but nice and handy line editor. - Thoric */
void edit_buffer( CHAR_DATA *ch, char *argument )
{
DESCRIPTOR_DATA *d;
EDITOR_DATA *edit;
char cmd[MIL], buf[( MLS + 2 )];
short x, line, max_buf_lines;
bool save;
if( !ch )
return;
set_char_color( AT_GREEN, ch );
if( !( d = ch->desc ) )
{
send_to_char( "You have no descriptor.\r\n", ch );
return;
}
if( d->connected != CON_EDITING )
{
send_to_char( "You can't do that!\r\n", ch );
bug( "%s: d->connected != CON_EDITING", __FUNCTION__ );
stop_editing( ch );
d->connected = CON_PLAYING;
return;
}
if( ch->substate <= SUB_PAUSE )
{
send_to_char( "You can't do that!\r\n", ch );
bug( "%s: illegal ch->substate (%d)", __FUNCTION__, ch->substate );
stop_editing( ch );
d->connected = CON_PLAYING;
return;
}
if( !ch->editor )
{
send_to_char( "You can't do that!\r\n", ch );
bug( "%s: null editor", __FUNCTION__ );
stop_editing( ch );
d->connected = CON_PLAYING;
return;
}
edit = ch->editor;
save = false;
max_buf_lines = 24;
if( ch->substate == SUB_MPROG_EDIT || ch->substate == SUB_HELP_EDIT || ch->substate == SUB_MAP_EDIT )
max_buf_lines = 48;
if( argument[0] == '/' || argument[0] == '\\' )
{
one_argument( argument + 1, cmd );
if( !str_cmp( cmd, "?" ) )
{
send_to_char( "Editing commands\r\n---------------------------------\r\n", ch );
send_to_char( "/l list buffer\r\n", ch );
send_to_char( "/c clear buffer\r\n", ch );
send_to_char( "/d [line] delete line\r\n", ch );
send_to_char( "/g <line> goto line\r\n", ch );
send_to_char( "/i <line> insert line\r\n", ch );
send_to_char( "/a abort editing\r\n", ch );
if( get_trust( ch ) >= PERM_IMM )
send_to_char( "/! <command> execute command (do not use another editing command)\r\n", ch );
send_to_char( "/s save buffer\r\n\r\n> ", ch );
return;
}
if( !str_cmp( cmd, "c" ) )
{
memset( edit, '\0', sizeof( EDITOR_DATA ) );
edit->numlines = 0;
edit->on_line = 0;
send_to_char( "Buffer cleared.\r\n> ", ch );
return;
}
if( !str_cmp( cmd, "i" ) )
{
if( edit->numlines >= max_buf_lines )
send_to_char( "Buffer is full.\r\n> ", ch );
else
{
if( argument[2] == ' ' )
line = atoi( argument + 2 ) - 1;
else
line = edit->on_line;
if( line < 0 )
line = edit->on_line;
if( line < 0 || line > edit->numlines )
send_to_char( "Out of range.\r\n> ", ch );
else
{
for( x = ++edit->numlines; x > line; x-- )
mudstrlcpy( edit->line[x], edit->line[x - 1], MLS );
mudstrlcpy( edit->line[line], "", MLS );
send_to_char( "Line inserted.\r\n> ", ch );
}
}
return;
}
if( !str_cmp( cmd, "d" ) )
{
if( edit->numlines == 0 )
send_to_char( "Buffer is empty.\r\n> ", ch );
else
{
if( argument[2] == ' ' )
line = atoi( argument + 2 ) - 1;
else
line = edit->on_line;
/* While this might not look right should keep the last line blank */
if( line < 0 || line >= edit->numlines )
ch_printf( ch, "Out of range. Valid range is 1 - %d\r\n> ", edit->numlines );
else
{
if( line == 0 && edit->numlines == 1 )
{
memset( edit, '\0', sizeof( EDITOR_DATA ) );
edit->numlines = 0;
edit->on_line = 0;
ch_printf( ch, "Line %d deleted.\r\n> ", ( line + 1 ) );
return;
}
for( x = line; x < ( edit->numlines - 1 ); x++ )
mudstrlcpy( edit->line[x], edit->line[x + 1], MLS );
/* Clear last line, decrease numlines and clear new last line */
mudstrlcpy( edit->line[edit->numlines--], "", MLS );
mudstrlcpy( edit->line[edit->numlines], "", MLS );
if( edit->on_line > edit->numlines )
edit->on_line = edit->numlines;
ch_printf( ch, "Line %d deleted.\r\n> ", ( line + 1 ) );
}
}
return;
}
if( !str_cmp( cmd, "g" ) )
{
if( edit->numlines == 0 )
send_to_char( "Buffer is empty.\r\n> ", ch );
else
{
if( argument[2] == ' ' )
line = atoi( argument + 2 ) - 1;
else
{
send_to_char( "Goto what line?\r\n> ", ch );
return;
}
if( line < 0 )
line = edit->on_line;
if( line < 0 || line > edit->numlines )
send_to_char( "Out of range.\r\n> ", ch );
else
{
edit->on_line = line;
ch_printf( ch, "(On line %d)\r\n> ", line + 1 );
}
}
return;
}
if( !str_cmp( cmd, "l" ) )
{
if( edit->numlines == 0 )
send_to_char( "Buffer is empty.\r\n> ", ch );
else
{
send_to_char( "------------------\r\n", ch );
for( x = 0; x <= edit->numlines; x++ )
{
ch_printf( ch, "%s%2d> %s\r\n", ( ( edit->on_line + 1 ) == ( x + 1 ) ) ? "*" : " ",
( x + 1 ), edit->line[x] );
}
send_to_char( "------------------\r\n> ", ch );
}
return;
}
if( !str_cmp( cmd, "a" ) )
{
send_to_char( "\r\nAborting... ", ch );
stop_editing( ch );
return;
}
if( !str_cmp( cmd, "!" ) )
{
DO_FUN *last_cmd;
int substate = ch->substate;
if( get_trust( ch ) < PERM_IMM )
{
send_to_char( "\r\nYou don't have access to this.\r\n", ch );
return;
}
last_cmd = ch->last_cmd;
ch->substate = SUB_RESTRICTED;
interpret( ch, argument + 3 );
ch->substate = substate;
ch->last_cmd = last_cmd;
set_char_color( AT_GREEN, ch );
send_to_char( "\r\n> ", ch );
return;
}
if( !str_cmp( cmd, "s" ) )
{
d->connected = CON_PLAYING;
if( !ch->last_cmd )
return;
( *ch->last_cmd ) ( ch, (char *)"" );
return;
}
}
if( ( edit->size + strlen( argument ) + 1 ) >= ( MSL - 1 ) )
{
send_to_char( "You buffer is full.\r\n", ch );
save = true;
}
else
{
while( argument && argument[0] != '\0' )
{
int normal = strlen( argument ); /* Normal string length */
int nocolor = color_strlen( argument ); /* String length without color */
int max = ( 79 + ( normal - nocolor ) );
int countback = 0;
if( nocolor > 79 ) /* Limit of normal characters */
{
if( max > MLS ) /* Limit it all */
max = MLS;
/* Lets see if we can go backwards and find a space */
for( countback = max; countback > 0; countback-- )
{
if( argument[countback] == ' ' )
break;
}
if( countback > 0 )
max = countback;
strncpy( buf, argument, max );
buf[max] = 0;
argument += max;
/* Remove the extra space on start of next line */
if( countback > 0 )
argument++;
/* Remove starting spaces */
while( *argument == ' ' )
argument++;
send_to_char( "(Long line (excludling color) wrapped)\r\n> ", ch );
}
else if( normal > ( MLS - 2 ) ) /* Limit of size ( counting colors ) */
{
max = ( MLS - 2 );
/* Lets see if we can go backwards and find a space */
for( countback = ( MLS - 2 ); countback > 0; countback-- )
if( argument[countback] == ' ' )
break;
if( countback > 0 )
max = countback;
strncpy( buf, argument, max );
buf[max] = 0;
argument += max;
/* Remove the extra space on start of next line */
if( countback > 0 )
argument++;
/* Remove starting spaces */
while( *argument == ' ' )
argument++;
send_to_char( "(Long line (includling color) wrapped)\r\n> ", ch );
}
else
{
mudstrlcpy( buf, argument, sizeof( buf ) );
argument += strlen( argument );
}
mudstrlcpy( edit->line[edit->on_line++], buf, MLS );
if( edit->on_line > edit->numlines )
edit->numlines++;
if( edit->numlines > max_buf_lines )
{
edit->numlines = max_buf_lines;
send_to_char( "Buffer full.\r\n", ch );
save = true;
}
}
}
if( save )
{
d->connected = CON_PLAYING;
if( !ch->last_cmd )
return;
( *ch->last_cmd ) ( ch, (char *)"" );
return;
}
send_to_char( "> ", ch );
}
void assign_area( CHAR_DATA *ch )
{
char buf[MSL], buf2[MSL], taf[MFN];
AREA_DATA *tarea, *tmp;
bool created = false;
if( is_npc( ch ) )
return;
if( get_trust( ch ) >= PERM_IMM && ch->pcdata->range_lo && ch->pcdata->range_hi )
{
tarea = ch->pcdata->area;
snprintf( taf, sizeof( taf ), "%s.are", capitalize( ch->name ) );
if( !tarea )
{
for( tmp = first_build; tmp; tmp = tmp->next )
if( !str_cmp( taf, tmp->filename ) )
{
tarea = tmp;
break;
}
}
if( !tarea )
{
log_printf_plus( LOG_NORMAL, get_trust( ch ), "Creating area entry for %s", ch->name );
CREATE( tarea, AREA_DATA, 1 );
LINK( tarea, first_build, last_build, next, prev );
tarea->first_room = tarea->last_room = NULL;
snprintf( buf, sizeof( buf ), "{PROTO} %s's area in progress", ch->name );
tarea->name = STRALLOC( buf );
tarea->filename = STRALLOC( taf );
snprintf( buf2, sizeof( buf2 ), "%s", ch->name );
tarea->author = STRALLOC( buf2 );
tarea->age = 0;
tarea->nplayer = 0;
CREATE( tarea->weather, WEATHER_DATA, 1 ); /* FB */
tarea->weather->temp = 0;
tarea->weather->precip = 0;
tarea->weather->wind = 0;
tarea->weather->temp_vector = 0;
tarea->weather->precip_vector = 0;
tarea->weather->wind_vector = 0;
tarea->weather->climate_temp = 2;
tarea->weather->climate_precip = 2;
tarea->weather->climate_wind = 2;
tarea->weather->first_neighbor = NULL;
tarea->weather->last_neighbor = NULL;
tarea->weather->echo = NULL;
tarea->weather->echo_color = AT_GRAY;
created = true;
}
else
log_printf_plus( LOG_NORMAL, get_trust( ch ), "Updating area entry for %s", ch->name );
tarea->low_vnum = ch->pcdata->range_lo;
tarea->hi_vnum = ch->pcdata->range_hi;
ch->pcdata->area = tarea;
if( created )
sort_area( tarea, true );
}
}
EXTRA_DESCR_DATA *SetRExtra( ROOM_INDEX_DATA *room, char *keywords )
{
EXTRA_DESCR_DATA *ed;
for( ed = room->first_extradesc; ed; ed = ed->next )
{
if( is_name( keywords, ed->keyword ) )
break;
}
if( !ed )
{
CREATE( ed, EXTRA_DESCR_DATA, 1 );
LINK( ed, room->first_extradesc, room->last_extradesc, next, prev );
ed->keyword = STRALLOC( keywords );
ed->description = NULL;
top_ed++;
}
return ed;
}
bool DelRExtra( ROOM_INDEX_DATA *room, char *keywords )
{
EXTRA_DESCR_DATA *rmed;
for( rmed = room->first_extradesc; rmed; rmed = rmed->next )
{
if( is_name( keywords, rmed->keyword ) )
break;
}
if( !rmed )
return false;
UNLINK( rmed, room->first_extradesc, room->last_extradesc, next, prev );
STRFREE( rmed->keyword );
STRFREE( rmed->description );
DISPOSE( rmed );
top_ed--;
return true;
}
EXTRA_DESCR_DATA *SetOExtra( OBJ_DATA *obj, char *keywords )
{
EXTRA_DESCR_DATA *ed;
for( ed = obj->first_extradesc; ed; ed = ed->next )
{
if( is_name( keywords, ed->keyword ) )
break;
}
if( !ed )
{
CREATE( ed, EXTRA_DESCR_DATA, 1 );
LINK( ed, obj->first_extradesc, obj->last_extradesc, next, prev );
ed->keyword = STRALLOC( keywords );
ed->description = NULL;
top_ed++;
}
return ed;
}
bool DelOExtra( OBJ_DATA *obj, char *keywords )
{
EXTRA_DESCR_DATA *rmed;
for( rmed = obj->first_extradesc; rmed; rmed = rmed->next )
{
if( is_name( keywords, rmed->keyword ) )
break;
}
if( !rmed )
return false;
UNLINK( rmed, obj->first_extradesc, obj->last_extradesc, next, prev );
STRFREE( rmed->keyword );
STRFREE( rmed->description );
DISPOSE( rmed );
top_ed--;
return true;
}
EXTRA_DESCR_DATA *SetOExtraProto( OBJ_INDEX_DATA *obj, char *keywords )
{
EXTRA_DESCR_DATA *ed;
for( ed = obj->first_extradesc; ed; ed = ed->next )
{
if( is_name( keywords, ed->keyword ) )
break;
}
if( !ed )
{
CREATE( ed, EXTRA_DESCR_DATA, 1 );
LINK( ed, obj->first_extradesc, obj->last_extradesc, next, prev );
ed->keyword = STRALLOC( keywords );
ed->description = NULL;
top_ed++;
}
return ed;
}
bool DelOExtraProto( OBJ_INDEX_DATA *obj, char *keywords )
{
EXTRA_DESCR_DATA *rmed;
for( rmed = obj->first_extradesc; rmed; rmed = rmed->next )
{
if( is_name( keywords, rmed->keyword ) )
break;
}
if( !rmed )
return false;
UNLINK( rmed, obj->first_extradesc, obj->last_extradesc, next, prev );
STRFREE( rmed->keyword );
STRFREE( rmed->description );
DISPOSE( rmed );
top_ed--;
return true;
}
void mpedit( CHAR_DATA *ch, MPROG_DATA *mprg, int mptype, char *argument )
{
if( mptype != -1 )
{
mprg->type = mptype;
if( mprg->arglist )
STRFREE( mprg->arglist );
mprg->arglist = STRALLOC( argument );
}
ch->substate = SUB_MPROG_EDIT;
ch->dest_buf = mprg;
start_editing( ch, mprg->comlist );
}
/* Mobprogram editing - cumbersome - Thoric */
CMDF( do_mpedit )
{
char arg1[MIL], arg2[MIL], arg3[MIL], arg4[MIL];
CHAR_DATA *victim;
MPROG_DATA *mprog, *mprg, *mprg_next = NULL;
int value, mptype = -1, cnt;
set_char_color( AT_PLAIN, ch );
if( is_npc( ch ) )
{
send_to_char( "Mob's can't mpedit\r\n", ch );
return;
}
if( !ch->desc )
{
send_to_char( "You have no descriptor\r\n", ch );
return;
}
switch( ch->substate )
{
default:
break;
case SUB_RESTRICTED:
send_to_char( "You can't use this command from within another command.\r\n", ch );
return;
case SUB_MPROG_EDIT:
if( !valid_destbuf( ch, __FUNCTION__ ) )
return;
mprog = ( MPROG_DATA *) ch->dest_buf;
if( mprog->comlist )
STRFREE( mprog->comlist );
mprog->comlist = copy_buffer( ch );
stop_editing( ch );
return;
}
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
argument = one_argument( argument, arg3 );
value = atoi( arg3 );
if( arg1[0] == '\0' || arg2[0] == '\0' )
{
send_to_char( "Usage: mpedit <victim> <command> [number] <program> <value>\r\n", ch );
send_to_char( "\r\n", ch );
send_to_char( "Command being one of:\r\n", ch );
send_to_char( " add delete insert edit\r\n", ch );
send_to_char( "Program being one of:\r\n", ch );
send_to_char( " act speech rand fight hitprcnt greet allgreet\r\n", ch );
send_to_char( " entry give bribe death time hour script\r\n", ch );
return;
}
if( get_trust( ch ) < PERM_LEADER )
{
if( !( victim = get_char_room( ch, arg1 ) ) )
{
send_to_char( "They aren't here.\r\n", ch );
return;
}
}
else
{
if( !( victim = get_char_world( ch, arg1 ) ) )
{
send_to_char( "No one like that in all the realms.\r\n", ch );
return;
}
}
if( !is_npc( victim ) )
{
send_to_char( "You can't do that!\r\n", ch );
return;
}
if( get_trust( ch ) < PERM_HEAD && is_npc( victim ) && xIS_SET( victim->act, ACT_STATSHIELD ) )
{
set_pager_color( AT_IMMORT, ch );
send_to_pager( "Their godly glow prevents you from getting close enough.\r\n", ch );
return;
}
if( !can_mmodify( ch, victim ) )
return;
if( !xIS_SET( victim->act, ACT_PROTOTYPE ) )
{
send_to_char( "A mobile must have a prototype flag to be mpset.\r\n", ch );
return;
}
mprog = victim->pIndexData->mudprogs;
set_char_color( AT_GREEN, ch );
if( !str_cmp( arg2, "edit" ) )
{
if( !mprog )
{
send_to_char( "That mobile has no mob programs.\r\n", ch );
return;
}
argument = one_argument( argument, arg4 );
if( arg4[0] != '\0' )
{
mptype = get_mpflag( arg4 );
if( mptype == -1 )
{
send_to_char( "Unknown program type.\r\n", ch );
return;
}
}
else
mptype = -1;
if( value < 1 )
{
send_to_char( "Program not found.\r\n", ch );
return;
}
cnt = 0;
for( mprg = mprog; mprg; mprg = mprg->next )
{
if( ++cnt == value )
{
mpedit( ch, mprg, mptype, argument );
xCLEAR_BITS( victim->pIndexData->progtypes );
for( mprg = mprog; mprg; mprg = mprg->next )
xSET_BIT( victim->pIndexData->progtypes, mprg->type );
return;
}
}
send_to_char( "Program not found.\r\n", ch );
return;
}
if( !str_cmp( arg2, "delete" ) )
{
int num;
bool found;
if( !mprog )
{
send_to_char( "That mobile has no mob programs.\r\n", ch );
return;
}
argument = one_argument( argument, arg4 );
if( value < 1 )
{
send_to_char( "Program not found.\r\n", ch );
return;
}
cnt = 0;
found = false;
for( mprg = mprog; mprg; mprg = mprg->next )
{
if( ++cnt == value )
{
mptype = mprg->type;
found = true;
break;
}
}
if( !found )
{
send_to_char( "Program not found.\r\n", ch );
return;
}
cnt = num = 0;
for( mprg = mprog; mprg; mprg = mprg->next )
if( mprg->type == mptype )
num++;
if( value == 1 )
{
mprg_next = victim->pIndexData->mudprogs;
victim->pIndexData->mudprogs = mprg_next->next;
}
else
for( mprg = mprog; mprg; mprg = mprg_next )
{
mprg_next = mprg->next;
if( ++cnt == ( value - 1 ) )
{
mprg->next = mprg_next->next;
break;
}
}
if( mprg_next )
{
STRFREE( mprg_next->arglist );
STRFREE( mprg_next->comlist );
DISPOSE( mprg_next );
if( num <= 1 )
xREMOVE_BIT( victim->pIndexData->progtypes, mptype );
send_to_char( "Program removed.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "insert" ) )
{
if( !mprog )
{
send_to_char( "That mobile has no mob programs.\r\n", ch );
return;
}
argument = one_argument( argument, arg4 );
mptype = get_mpflag( arg4 );
if( mptype == -1 )
{
send_to_char( "Unknown program type.\r\n", ch );
return;
}
if( value < 1 )
{
send_to_char( "Program not found.\r\n", ch );
return;
}
if( value == 1 )
{
CREATE( mprg, MPROG_DATA, 1 );
xSET_BIT( victim->pIndexData->progtypes, mptype );
mpedit( ch, mprg, mptype, argument );
mprg->next = mprog;
victim->pIndexData->mudprogs = mprg;
return;
}
cnt = 1;
for( mprg = mprog; mprg; mprg = mprg->next )
{
if( ++cnt == value && mprg->next )
{
CREATE( mprg_next, MPROG_DATA, 1 );
xSET_BIT( victim->pIndexData->progtypes, mptype );
mpedit( ch, mprg_next, mptype, argument );
mprg_next->next = mprg->next;
mprg->next = mprg_next;
return;
}
}
send_to_char( "Program not found.\r\n", ch );
return;
}
if( !str_cmp( arg2, "add" ) )
{
if( ( mptype = get_mpflag( arg3 ) ) == -1 )
{
send_to_char( "Unknown program type.\r\n", ch );
return;
}
if( mprog )
for( ; mprog->next; mprog = mprog->next );
CREATE( mprg, MPROG_DATA, 1 );
if( mprog )
mprog->next = mprg;
else
victim->pIndexData->mudprogs = mprg;
xSET_BIT( victim->pIndexData->progtypes, mptype );
mpedit( ch, mprg, mptype, argument );
mprg->next = NULL;
return;
}
do_mpedit( ch, (char *)"" );
}
CMDF( do_opedit )
{
char arg1[MIL], arg2[MIL], arg3[MIL], arg4[MIL];
OBJ_DATA *obj;
MPROG_DATA *mprog, *mprg, *mprg_next = NULL;
int value, mptype = -1, cnt;
set_char_color( AT_PLAIN, ch );
if( is_npc( ch ) )
{
send_to_char( "Mob's can't opedit\r\n", ch );
return;
}
if( !ch->desc )
{
send_to_char( "You have no descriptor\r\n", ch );
return;
}
switch( ch->substate )
{
default:
break;
case SUB_RESTRICTED:
send_to_char( "You can't use this command from within another command.\r\n", ch );
return;
case SUB_MPROG_EDIT:
if( !valid_destbuf( ch, __FUNCTION__ ) )
return;
mprog = ( MPROG_DATA *) ch->dest_buf;
if( mprog->comlist )
STRFREE( mprog->comlist );
mprog->comlist = copy_buffer( ch );
stop_editing( ch );
return;
}
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
argument = one_argument( argument, arg3 );
value = atoi( arg3 );
if( arg1[0] == '\0' || arg2[0] == '\0' )
{
send_to_char( "Usage: opedit <object> <command> [number] <program> <value>\r\n\r\n", ch );
send_to_char( "Command being one of:\r\n", ch );
send_to_char( " add delete insert edit\r\n", ch );
send_to_char( "Program being one of:\r\n", ch );
send_to_char( " act speech rand wear remove sac zap\r\n", ch );
send_to_char( " get drop damage repair greet exa use\r\n", ch );
send_to_char( " pull push (for levers, pullchains, buttons)\r\n\r\n", ch );
send_to_char( "Object should be in your inventory to edit.\r\n", ch );
return;
}
if( get_trust( ch ) < PERM_LEADER )
{
if( !( obj = get_obj_carry( ch, arg1 ) ) )
{
send_to_char( "You aren't carrying that.\r\n", ch );
return;
}
}
else
{
if( !( obj = get_obj_world( ch, arg1 ) ) )
{
send_to_char( "Nothing like that in all the realms.\r\n", ch );
return;
}
}
if( !can_omodify( ch, obj ) )
return;
if( !is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
send_to_char( "An object must have a prototype flag to be opset.\r\n", ch );
return;
}
mprog = obj->pIndexData->mudprogs;
set_char_color( AT_GREEN, ch );
if( !str_cmp( arg2, "edit" ) )
{
if( !mprog )
{
send_to_char( "That object has no obj programs.\r\n", ch );
return;
}
argument = one_argument( argument, arg4 );
if( arg4[0] != '\0' )
{
mptype = get_mpflag( arg4 );
if( mptype == -1 )
{
send_to_char( "Unknown program type.\r\n", ch );
return;
}
}
else
mptype = -1;
if( value < 1 )
{
send_to_char( "Program not found.\r\n", ch );
return;
}
cnt = 0;
for( mprg = mprog; mprg; mprg = mprg->next )
{
if( ++cnt == value )
{
mpedit( ch, mprg, mptype, argument );
xCLEAR_BITS( obj->pIndexData->progtypes );
for( mprg = mprog; mprg; mprg = mprg->next )
xSET_BIT( obj->pIndexData->progtypes, mprg->type );
return;
}
}
send_to_char( "Program not found.\r\n", ch );
return;
}
if( !str_cmp( arg2, "delete" ) )
{
int num;
bool found;
if( !mprog )
{
send_to_char( "That object has no obj programs.\r\n", ch );
return;
}
argument = one_argument( argument, arg4 );
if( value < 1 )
{
send_to_char( "Program not found.\r\n", ch );
return;
}
cnt = 0;
found = false;
for( mprg = mprog; mprg; mprg = mprg->next )
{
if( ++cnt == value )
{
mptype = mprg->type;
found = true;
break;
}
}
if( !found )
{
send_to_char( "Program not found.\r\n", ch );
return;
}
cnt = num = 0;
for( mprg = mprog; mprg; mprg = mprg->next )
if( mprg->type == mptype )
num++;
if( value == 1 )
{
mprg_next = obj->pIndexData->mudprogs;
obj->pIndexData->mudprogs = mprg_next->next;
}
else
for( mprg = mprog; mprg; mprg = mprg_next )
{
mprg_next = mprg->next;
if( ++cnt == ( value - 1 ) )
{
mprg->next = mprg_next->next;
break;
}
}
if( mprg_next )
{
STRFREE( mprg_next->arglist );
STRFREE( mprg_next->comlist );
DISPOSE( mprg_next );
if( num <= 1 )
xREMOVE_BIT( obj->pIndexData->progtypes, mptype );
send_to_char( "Program removed.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "insert" ) )
{
if( !mprog )
{
send_to_char( "That object has no obj programs.\r\n", ch );
return;
}
argument = one_argument( argument, arg4 );
mptype = get_mpflag( arg4 );
if( mptype == -1 )
{
send_to_char( "Unknown program type.\r\n", ch );
return;
}
if( value < 1 )
{
send_to_char( "Program not found.\r\n", ch );
return;
}
if( value == 1 )
{
CREATE( mprg, MPROG_DATA, 1 );
xSET_BIT( obj->pIndexData->progtypes, mptype );
mpedit( ch, mprg, mptype, argument );
mprg->next = mprog;
obj->pIndexData->mudprogs = mprg;
return;
}
cnt = 1;
for( mprg = mprog; mprg; mprg = mprg->next )
{
if( ++cnt == value && mprg->next )
{
CREATE( mprg_next, MPROG_DATA, 1 );
xSET_BIT( obj->pIndexData->progtypes, mptype );
mpedit( ch, mprg_next, mptype, argument );
mprg_next->next = mprg->next;
mprg->next = mprg_next;
return;
}
}
send_to_char( "Program not found.\r\n", ch );
return;
}
if( !str_cmp( arg2, "add" ) )
{
mptype = get_mpflag( arg3 );
if( mptype == -1 )
{
send_to_char( "Unknown program type.\r\n", ch );
return;
}
if( mprog )
for( ; mprog->next; mprog = mprog->next );
CREATE( mprg, MPROG_DATA, 1 );
if( mprog )
mprog->next = mprg;
else
obj->pIndexData->mudprogs = mprg;
xSET_BIT( obj->pIndexData->progtypes, mptype );
mpedit( ch, mprg, mptype, argument );
mprg->next = NULL;
return;
}
do_opedit( ch, (char *)"" );
}
/* RoomProg Support */
void rpedit( CHAR_DATA *ch, MPROG_DATA *mprg, int mptype, char *argument )
{
if( mptype != -1 )
{
mprg->type = mptype;
STRFREE( mprg->arglist );
mprg->arglist = STRALLOC( argument );
}
ch->substate = SUB_MPROG_EDIT;
ch->dest_buf = mprg;
start_editing( ch, mprg->comlist );
}
CMDF( do_rpedit )
{
char arg1[MIL], arg2[MIL], arg3[MIL];
MPROG_DATA *mprog, *mprg, *mprg_next = NULL;
int value, mptype = -1, cnt;
set_char_color( AT_PLAIN, ch );
if( is_npc( ch ) )
{
send_to_char( "Mob's can't rpedit\r\n", ch );
return;
}
if( !ch->desc )
{
send_to_char( "You have no descriptor\r\n", ch );
return;
}
switch( ch->substate )
{
default:
break;
case SUB_RESTRICTED:
send_to_char( "You can't use this command from within another command.\r\n", ch );
return;
case SUB_MPROG_EDIT:
if( !valid_destbuf( ch, __FUNCTION__ ) )
return;
mprog = ( MPROG_DATA *) ch->dest_buf;
if( mprog->comlist )
STRFREE( mprog->comlist );
mprog->comlist = copy_buffer( ch );
stop_editing( ch );
return;
}
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
value = atoi( arg2 );
if( arg1[0] == '\0' )
{
send_to_char( "Usage: rpedit <command> [number] <program> <value>\r\n", ch );
send_to_char( "Command being one of:\r\n", ch );
send_to_char( " add delete insert edit\r\n", ch );
send_to_char( "Program being one of:\r\n", ch );
send_to_char( " act speech rand sleep rest fight entry leave death\r\n\r\n", ch );
send_to_char( "You should be standing in the room you wish to edit.\r\n", ch );
return;
}
if( !can_rmodify( ch, ch->in_room ) )
return;
mprog = ch->in_room->mudprogs;
set_char_color( AT_GREEN, ch );
if( !str_cmp( arg1, "edit" ) )
{
if( !mprog )
{
send_to_char( "This room has no room programs.\r\n", ch );
return;
}
argument = one_argument( argument, arg3 );
if( arg3[0] != '\0' )
{
mptype = get_mpflag( arg3 );
if( mptype == -1 )
{
send_to_char( "Unknown program type.\r\n", ch );
return;
}
}
else
mptype = -1;
if( value < 1 )
{
send_to_char( "Program not found.\r\n", ch );
return;
}
cnt = 0;
for( mprg = mprog; mprg; mprg = mprg->next )
{
if( ++cnt == value )
{
mpedit( ch, mprg, mptype, argument );
xCLEAR_BITS( ch->in_room->progtypes );
for( mprg = mprog; mprg; mprg = mprg->next )
xSET_BIT( ch->in_room->progtypes, mprg->type );
return;
}
}
send_to_char( "Program not found.\r\n", ch );
return;
}
if( !str_cmp( arg1, "delete" ) )
{
int num;
bool found;
if( !mprog )
{
send_to_char( "That room has no room programs.\r\n", ch );
return;
}
argument = one_argument( argument, arg3 );
if( value < 1 )
{
send_to_char( "Program not found.\r\n", ch );
return;
}
cnt = 0;
found = false;
for( mprg = mprog; mprg; mprg = mprg->next )
{
if( ++cnt == value )
{
mptype = mprg->type;
found = true;
break;
}
}
if( !found )
{
send_to_char( "Program not found.\r\n", ch );
return;
}
cnt = num = 0;
for( mprg = mprog; mprg; mprg = mprg->next )
if( mprg->type == mptype )
num++;
if( value == 1 )
{
mprg_next = ch->in_room->mudprogs;
ch->in_room->mudprogs = mprg_next->next;
}
else
{
for( mprg = mprog; mprg; mprg = mprg_next )
{
mprg_next = mprg->next;
if( ++cnt == ( value - 1 ) )
{
mprg->next = mprg_next->next;
break;
}
}
}
if( mprg_next )
{
STRFREE( mprg_next->arglist );
STRFREE( mprg_next->comlist );
DISPOSE( mprg_next );
if( num <= 1 )
xREMOVE_BIT( ch->in_room->progtypes, mptype );
send_to_char( "Program removed.\r\n", ch );
}
return;
}
if( !str_cmp( arg2, "insert" ) )
{
if( !mprog )
{
send_to_char( "That room has no room programs.\r\n", ch );
return;
}
argument = one_argument( argument, arg3 );
mptype = get_mpflag( arg2 );
if( mptype == -1 )
{
send_to_char( "Unknown program type.\r\n", ch );
return;
}
if( value < 1 )
{
send_to_char( "Program not found.\r\n", ch );
return;
}
if( value == 1 )
{
CREATE( mprg, MPROG_DATA, 1 );
xSET_BIT( ch->in_room->progtypes, mptype );
mpedit( ch, mprg, mptype, argument );
mprg->next = mprog;
ch->in_room->mudprogs = mprg;
return;
}
cnt = 1;
for( mprg = mprog; mprg; mprg = mprg->next )
{
if( ++cnt == value && mprg->next )
{
CREATE( mprg_next, MPROG_DATA, 1 );
xSET_BIT( ch->in_room->progtypes, mptype );
mpedit( ch, mprg_next, mptype, argument );
mprg_next->next = mprg->next;
mprg->next = mprg_next;
return;
}
}
send_to_char( "Program not found.\r\n", ch );
return;
}
if( !str_cmp( arg1, "add" ) )
{
mptype = get_mpflag( arg2 );
if( mptype == -1 )
{
send_to_char( "Unknown program type.\r\n", ch );
return;
}
if( mprog )
for( ; mprog->next; mprog = mprog->next );
CREATE( mprg, MPROG_DATA, 1 );
if( mprog )
mprog->next = mprg;
else
ch->in_room->mudprogs = mprg;
xSET_BIT( ch->in_room->progtypes, mptype );
mpedit( ch, mprg, mptype, argument );
mprg->next = NULL;
return;
}
do_rpedit( ch, (char *)"" );
}
CMDF( do_rdelete )
{
ROOM_INDEX_DATA *location;
if( ch->substate == SUB_RESTRICTED )
{
send_to_char( "You can't do that while in a subprompt.\r\n", ch );
return;
}
if( !argument || argument[0] == '\0' )
{
send_to_char( "Delete which room?\r\n", ch );
return;
}
/* Find the room. */
if( !( location = find_location( ch, argument ) ) )
{
send_to_char( "No such location.\r\n", ch );
return;
}
/* Does the player have the right to delete this room? */
if( get_trust( ch ) < sysdata.perm_modify_proto
&& ( location->vnum < ch->pcdata->area->low_vnum || location->vnum > ch->pcdata->area->hi_vnum ) )
{
send_to_char( "That room is not in your assigned range.\r\n", ch );
return;
}
delete_room( location );
fix_exits( ); /* Need to call this to solve a crash */
ch_printf( ch, "Room %s has been deleted.\r\n", argument );
}
CMDF( do_odelete )
{
OBJ_INDEX_DATA *obj;
int vnum;
if( ch->substate == SUB_RESTRICTED )
{
send_to_char( "You can't do that while in a subprompt.\r\n", ch );
return;
}
if( !argument || argument[0] == '\0' )
{
send_to_char( "Delete which object?\r\n", ch );
return;
}
if( !is_number( argument ) )
{
send_to_char( "You must specify the object's vnum to delete it.\r\n", ch );
return;
}
vnum = atoi( argument );
/* Find the obj. */
if( !( obj = get_obj_index( vnum ) ) )
{
send_to_char( "No such object.\r\n", ch );
return;
}
/* Does the player have the right to delete this object? */
if( get_trust( ch ) < sysdata.perm_modify_proto
&& ( obj->vnum < ch->pcdata->area->low_vnum || obj->vnum > ch->pcdata->area->hi_vnum ) )
{
send_to_char( "That object is not in your assigned range.\r\n", ch );
return;
}
delete_obj( obj );
ch_printf( ch, "Object %d has been deleted.\r\n", vnum );
}
CMDF( do_mdelete )
{
MOB_INDEX_DATA *mob;
int vnum;
if( ch->substate == SUB_RESTRICTED )
{
send_to_char( "You can't do that while in a subprompt.\r\n", ch );
return;
}
if( !argument || argument[0] == '\0' )
{
send_to_char( "Delete which mob?\r\n", ch );
return;
}
if( !is_number( argument ) )
{
send_to_char( "You must specify the mob's vnum to delete it.\r\n", ch );
return;
}
vnum = atoi( argument );
/* Find the mob. */
if( !( mob = get_mob_index( vnum ) ) )
{
send_to_char( "No such mob.\r\n", ch );
return;
}
/* Does the player have the right to delete this mob? */
if( get_trust( ch ) < sysdata.perm_modify_proto
&& ( mob->vnum < ch->pcdata->area->low_vnum || mob->vnum > ch->pcdata->area->hi_vnum ) )
{
send_to_char( "That mob is not in your assigned range.\r\n", ch );
return;
}
delete_mob( mob );
ch_printf( ch, "Mob %d has been deleted.\r\n", vnum );
}
/*
* Mobile and Object Program Copying
* Last modified Feb. 24 1999
* Mystaric
*/
void mpcopy( MPROG_DATA *source, MPROG_DATA *destination )
{
destination->type = source->type;
destination->triggered = source->triggered;
destination->resetdelay = source->resetdelay;
destination->arglist = STRALLOC( source->arglist );
destination->comlist = STRALLOC( source->comlist );
destination->next = NULL;
}
CMDF( do_opcopy )
{
char sobj[MIL], prog[MIL], num[MIL], dobj[MIL];
OBJ_DATA *source = NULL, *destination = NULL;
MPROG_DATA *source_oprog = NULL, *dest_oprog = NULL, *source_oprg = NULL, *dest_oprg = NULL;
int value = -1, optype = -1, cnt = 0;
bool COPY = false;
if( is_npc( ch ) )
{
send_to_char( "Mob's can't opcopy\r\n", ch );
return;
}
if( !ch->desc )
{
send_to_char( "You have no descriptor\r\n", ch );
return;
}
argument = one_argument( argument, sobj );
argument = one_argument( argument, prog );
if( sobj == NULL || sobj[0] == '\0' || prog == NULL || prog[0] == '\0' )
{
send_to_char( "Usage: opcopy <object1> <program> [number] <object2>\r\n", ch );
send_to_char( "Usage: opcopy <object1> all <object2>\r\n", ch );
send_to_char( "Usage: opcopy <object1> all <object2> <program>\r\n", ch );
send_to_char( "\r\n", ch );
send_to_char( "Program being one of:\r\n", ch );
send_to_char( " act speech rand wear remove sac zap get\r\n", ch );
send_to_char( " drop damage repair greet exa use\r\n", ch );
send_to_char( " pull push (for levers,pullchains,buttons)\r\n\r\n", ch );
send_to_char( "Object should be in your inventory to edit.\r\n", ch );
return;
}
if( !strcmp( prog, "all" ) )
{
argument = one_argument( argument, dobj );
argument = one_argument( argument, prog );
optype = get_mpflag( prog );
COPY = true;
}
else
{
argument = one_argument( argument, num );
argument = one_argument( argument, dobj );
value = atoi( num );
}
if( get_trust( ch ) < PERM_LEADER )
{
if( !( source = get_obj_carry( ch, sobj ) ) )
{
send_to_char( "You aren't carrying source object.\r\n", ch );
return;
}
if( !( destination = get_obj_carry( ch, dobj ) ) )
{
send_to_char( "You aren't carrying destination object.\r\n", ch );
return;
}
}
else
{
if( !( source = get_obj_world( ch, sobj ) ) )
{
send_to_char( "Can't find source object in all the realms.\r\n", ch );
return;
}
if( !( destination = get_obj_world( ch, dobj ) ) )
{
send_to_char( "Can't find destination object in all the realms.\r\n", ch );
return;
}
}
if( source == destination )
{
send_to_char( "Source and destination objects can't be the same\r\n", ch );
return;
}
if( !can_omodify( ch, destination ) )
{
send_to_char( "You can't modify destination object.\r\n", ch );
return;
}
if( !is_obj_stat( destination, ITEM_PROTOTYPE ) )
{
send_to_char( "Destination object must have prototype flag.\r\n", ch );
return;
}
set_char_color( AT_PLAIN, ch );
source_oprog = source->pIndexData->mudprogs;
dest_oprog = destination->pIndexData->mudprogs;
set_char_color( AT_GREEN, ch );
if( !source_oprog )
{
send_to_char( "Source object has no mob programs.\r\n", ch );
return;
}
if( COPY )
{
for( source_oprg = source_oprog; source_oprg; source_oprg = source_oprg->next )
{
if( optype == source_oprg->type || optype == -1 )
{
if( dest_oprog )
for( ; dest_oprog->next; dest_oprog = dest_oprog->next );
CREATE( dest_oprg, MPROG_DATA, 1 );
if( dest_oprog )
dest_oprog->next = dest_oprg;
else
{
destination->pIndexData->mudprogs = dest_oprg;
dest_oprog = dest_oprg;
}
mpcopy( source_oprg, dest_oprg );
xSET_BIT( destination->pIndexData->progtypes, dest_oprg->type );
cnt++;
}
}
if( cnt == 0 )
{
send_to_char( "No such program in source object\r\n", ch );
return;
}
ch_printf( ch, "%d programs successfully copied from %s to %s.\r\n", cnt, sobj, dobj );
return;
}
if( value < 1 )
{
send_to_char( "No such program in source object.\r\n", ch );
return;
}
optype = get_mpflag( prog );
for( source_oprg = source_oprog; source_oprg; source_oprg = source_oprg->next )
{
if( ++cnt == value && source_oprg->type == optype )
{
if( dest_oprog )
for( ; dest_oprog->next; dest_oprog = dest_oprog->next );
CREATE( dest_oprg, MPROG_DATA, 1 );
if( dest_oprog )
dest_oprog->next = dest_oprg;
else
destination->pIndexData->mudprogs = dest_oprg;
mpcopy( source_oprg, dest_oprg );
xSET_BIT( destination->pIndexData->progtypes, dest_oprg->type );
ch_printf( ch, "%s program %d from %s successfully copied to %s.\r\n", prog, value, sobj, dobj );
return;
}
}
if( !source_oprg )
{
send_to_char( "No such program in source object.\r\n", ch );
return;
}
do_opcopy( ch, (char *)"" );
}
CMDF( do_mpcopy )
{
char smob[MIL], prog[MIL], num[MIL], dmob[MIL];
CHAR_DATA *source = NULL, *destination = NULL;
MPROG_DATA *source_mprog = NULL, *dest_mprog = NULL, *source_mprg = NULL, *dest_mprg = NULL;
int value = -1, mptype = -1, cnt = 0;
bool COPY = false;
set_char_color( AT_PLAIN, ch );
if( is_npc( ch ) )
{
send_to_char( "Mob's can't opcop\r\n", ch );
return;
}
if( !ch->desc )
{
send_to_char( "You have no descriptor\r\n", ch );
return;
}
argument = one_argument( argument, smob );
argument = one_argument( argument, prog );
if( smob[0] == '\0' || prog[0] == '\0' )
{
send_to_char( "Usage: mpcopy <mobile1> <program> [number] <mobile2>\r\n", ch );
send_to_char( "Usage: mpcopy <mobile1> all <mobile2>\r\n", ch );
send_to_char( "Usage: mpcopy <mobile1> all <mobile2> <program>\r\n\r\n", ch );
send_to_char( "Program being one of:\r\n", ch );
send_to_char( " act speech rand fight hitprcnt greet allgreet\r\n", ch );
send_to_char( " entry give bribe death time hour script\r\n", ch );
return;
}
if( !strcmp( prog, "all" ) )
{
argument = one_argument( argument, dmob );
argument = one_argument( argument, prog );
mptype = get_mpflag( prog );
COPY = true;
}
else
{
argument = one_argument( argument, num );
argument = one_argument( argument, dmob );
value = atoi( num );
}
if( get_trust( ch ) < PERM_LEADER )
{
if( !( source = get_char_room( ch, smob ) ) )
{
send_to_char( "Source mobile is not present.\r\n", ch );
return;
}
if( !( destination = get_char_room( ch, dmob ) ) )
{
send_to_char( "Destination mobile is not present.\r\n", ch );
return;
}
}
else
{
if( !( source = get_char_world( ch, smob ) ) )
{
send_to_char( "Can't find source mobile\r\n", ch );
return;
}
if( !( destination = get_char_world( ch, dmob ) ) )
{
send_to_char( "Can't find destination mobile\r\n", ch );
return;
}
}
if( source == destination )
{
send_to_char( "Source and destination mobiles can't be the same\r\n", ch );
return;
}
if( get_trust( ch ) < source->level || !is_npc( source ) ||
get_trust( ch ) < destination->level || !is_npc( destination ) )
{
send_to_char( "You can't do that!\r\n", ch );
return;
}
if( !can_mmodify( ch, destination ) )
{
send_to_char( "You can't modify destination mobile.\r\n", ch );
return;
}
if( !xIS_SET( destination->act, ACT_PROTOTYPE ) )
{
send_to_char( "Destination mobile must have a prototype flag to mpcopy.\r\n", ch );
return;
}
source_mprog = source->pIndexData->mudprogs;
dest_mprog = destination->pIndexData->mudprogs;
set_char_color( AT_GREEN, ch );
if( !source_mprog )
{
send_to_char( "Source mobile has no mob programs.\r\n", ch );
return;
}
if( COPY )
{
for( source_mprg = source_mprog; source_mprg; source_mprg = source_mprg->next )
{
if( mptype == source_mprg->type || mptype == -1 )
{
if( dest_mprog )
for( ; dest_mprog->next; dest_mprog = dest_mprog->next );
CREATE( dest_mprg, MPROG_DATA, 1 );
if( dest_mprog )
dest_mprog->next = dest_mprg;
else
{
destination->pIndexData->mudprogs = dest_mprg;
dest_mprog = dest_mprg;
}
mpcopy( source_mprg, dest_mprg );
xSET_BIT( destination->pIndexData->progtypes, dest_mprg->type );
cnt++;
}
}
if( cnt == 0 )
{
send_to_char( "No such program in source mobile\r\n", ch );
return;
}
ch_printf( ch, "%d programs successfully copied from %s to %s.\r\n", cnt, smob, dmob );
return;
}
if( value < 1 )
{
send_to_char( "No such program in source mobile.\r\n", ch );
return;
}
mptype = get_mpflag( prog );
for( source_mprg = source_mprog; source_mprg; source_mprg = source_mprg->next )
{
if( ++cnt == value && source_mprg->type == mptype )
{
if( dest_mprog )
for( ; dest_mprog->next; dest_mprog = dest_mprog->next );
CREATE( dest_mprg, MPROG_DATA, 1 );
if( dest_mprog )
dest_mprog->next = dest_mprg;
else
destination->pIndexData->mudprogs = dest_mprg;
mpcopy( source_mprg, dest_mprg );
xSET_BIT( destination->pIndexData->progtypes, dest_mprg->type );
ch_printf( ch, "%s program %d from %s successfully copied to %s.\r\n", prog, value, smob, dmob );
return;
}
}
if( !source_mprg )
{
send_to_char( "No such program in source mobile.\r\n", ch );
return;
}
do_mpcopy( ch, (char *)"" );
}
CMDF( do_rpcopy )
{
char sroom[MIL], prog[MIL], num[MIL], droom[MIL];
ROOM_INDEX_DATA *source = NULL, *destination = NULL;
MPROG_DATA *source_rprog = NULL, *dest_rprog = NULL, *source_rprg = NULL, *dest_rprg = NULL;
int value = -1, rptype = -1, cnt = 0;
bool COPY = false;
set_char_color( AT_PLAIN, ch );
if( is_npc( ch ) )
{
send_to_char( "Mob's can't rpcop\r\n", ch );
return;
}
if( !ch->desc )
{
send_to_char( "You have no descriptor\r\n", ch );
return;
}
argument = one_argument( argument, sroom );
argument = one_argument( argument, prog );
if( sroom[0] == '\0' || prog[0] == '\0' )
{
send_to_char( "Usage: rpcopy <room1> <program> [number] <room2>\r\n", ch );
send_to_char( "Usage: rpcopy <room1> all <room2>\r\n", ch );
send_to_char( "Usage: rpcopy <room1> all <room2> <program>\r\n\r\n", ch );
send_to_char( "Program being one of:\r\n", ch );
send_to_char( " act speech rand fight sleep rest leave\r\n", ch );
send_to_char( " entry death time hour script\r\n", ch );
return;
}
if( !strcmp( prog, "all" ) )
{
argument = one_argument( argument, droom );
argument = one_argument( argument, prog );
rptype = get_mpflag( prog );
COPY = true;
}
else
{
argument = one_argument( argument, num );
argument = one_argument( argument, droom );
value = atoi( num );
}
if( !( source = get_room_index( atoi( sroom ) ) ) )
{
send_to_char( "Source room doesn't exist.\r\n", ch );
return;
}
if( !( destination = get_room_index( atoi( droom ) ) ) )
{
send_to_char( "Destination room doesn't exist.\r\n", ch );
return;
}
if( source == destination )
{
send_to_char( "Source and destination rooms can't be the same\r\n", ch );
return;
}
if( !can_rmodify( ch, destination ) )
{
send_to_char( "You can't modify destination room.\r\n", ch );
return;
}
source_rprog = source->mudprogs;
dest_rprog = destination->mudprogs;
set_char_color( AT_GREEN, ch );
if( !source_rprog )
{
send_to_char( "Source room has no mob programs.\r\n", ch );
return;
}
if( COPY )
{
for( source_rprg = source_rprog; source_rprg; source_rprg = source_rprg->next )
{
if( rptype == source_rprg->type || rptype == -1 )
{
if( dest_rprog )
for( ; dest_rprog->next; dest_rprog = dest_rprog->next );
CREATE( dest_rprg, MPROG_DATA, 1 );
if( dest_rprog )
dest_rprog->next = dest_rprg;
else
{
destination->mudprogs = dest_rprg;
dest_rprog = dest_rprg;
}
mpcopy( source_rprg, dest_rprg );
xSET_BIT( destination->progtypes, dest_rprg->type );
cnt++;
}
}
if( cnt == 0 )
send_to_char( "No such program in source room.\r\n", ch );
else
ch_printf( ch, "%d programs successfully copied from %s to %s.\r\n", cnt, sroom, droom );
return;
}
if( value < 1 )
{
send_to_char( "No such program in source room.\r\n", ch );
return;
}
rptype = get_mpflag( prog );
for( source_rprg = source_rprog; source_rprg; source_rprg = source_rprg->next )
{
if( ++cnt == value && source_rprg->type == rptype )
{
if( dest_rprog )
for( ; dest_rprog->next; dest_rprog = dest_rprog->next );
CREATE( dest_rprg, MPROG_DATA, 1 );
if( dest_rprog )
dest_rprog->next = dest_rprg;
else
destination->mudprogs = dest_rprg;
mpcopy( source_rprg, dest_rprg );
xSET_BIT( destination->progtypes, dest_rprg->type );
ch_printf( ch, "%s program %d from %s successfully copied to %s.\r\n", prog, value, sroom, droom );
return;
}
}
if( !source_rprg )
{
send_to_char( "No such program in source room.\r\n", ch );
return;
}
do_rpcopy( ch, (char *)"" );
}
/*
* Modify an area's climate
* Last modified: July 15, 1997 - Fireblade
*/
CMDF( do_climate )
{
char arg[MIL];
AREA_DATA *area;
/* Little error checking */
if( !ch )
{
bug( "%s: NULL character.", __FUNCTION__ );
return;
}
if( !ch->in_room )
{
bug( "%s: character not in a room.", __FUNCTION__ );
return;
}
if( !ch->in_room->area )
{
bug( "%s: character not in an area.", __FUNCTION__ );
return;
}
if( !ch->in_room->area->weather )
{
bug( "%s: area with NULL weather data.", __FUNCTION__ );
return;
}
set_char_color( AT_BLUE, ch );
area = ch->in_room->area;
argument = strlower( argument );
argument = one_argument( argument, arg );
if( arg == NULL || arg[0] == '\0' )
{
NEIGHBOR_DATA *neigh;
ch_printf( ch, "%s:\r\n", area->name );
ch_printf( ch, " Temperature: %s\r\n", temp_settings[area->weather->climate_temp] );
ch_printf( ch, " Precipitation: %s\r\n", precip_settings[area->weather->climate_precip] );
ch_printf( ch, " Wind: %s\r\n", wind_settings[area->weather->climate_wind] );
if( area->weather->first_neighbor )
send_to_char( "Neighboring weather systems:\r\n", ch );
for( neigh = area->weather->first_neighbor; neigh; neigh = neigh->next )
ch_printf( ch, " %s\r\n", neigh->name );
return;
}
else if( !str_cmp( arg, "temp" ) )
{
int i;
argument = one_argument( argument, arg );
for( i = 0; i < MAX_CLIMATE; i++ )
{
if( str_cmp( arg, temp_settings[i] ) )
continue;
area->weather->climate_temp = i;
ch_printf( ch, "The climate temperature for %s is now %s.\r\n", area->name, temp_settings[i] );
break;
}
if( i == MAX_CLIMATE )
{
send_to_char( "Possible temperature settings:\r\n", ch );
for( i = 0; i < MAX_CLIMATE; i++ )
ch_printf( ch, " %s\r\n", temp_settings[i] );
}
return;
}
else if( !str_cmp( arg, "precip" ) )
{
int i;
argument = one_argument( argument, arg );
for( i = 0; i < MAX_CLIMATE; i++ )
{
if( str_cmp( arg, precip_settings[i] ) )
continue;
area->weather->climate_precip = i;
ch_printf( ch, "The climate precipitation for %s is now %s.\r\n", area->name, precip_settings[i] );
break;
}
if( i == MAX_CLIMATE )
{
send_to_char( "Possible precipitation settings:\r\n", ch );
for( i = 0; i < MAX_CLIMATE; i++ )
ch_printf( ch, " %s\r\n", precip_settings[i] );
}
return;
}
else if( !str_cmp( arg, "wind" ) )
{
int i;
argument = one_argument( argument, arg );
for( i = 0; i < MAX_CLIMATE; i++ )
{
if( str_cmp( arg, wind_settings[i] ) )
continue;
area->weather->climate_wind = i;
ch_printf( ch, "The climate wind for %s is now %s.\r\n", area->name, wind_settings[i] );
break;
}
if( i == MAX_CLIMATE )
{
send_to_char( "Possible wind settings:\r\n", ch );
for( i = 0; i < MAX_CLIMATE; i++ )
ch_printf( ch, " %s\r\n", wind_settings[i] );
}
return;
}
else if( !str_cmp( arg, "neighbor" ) )
{
NEIGHBOR_DATA *neigh;
AREA_DATA *tarea;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Add or remove which area?\r\n", ch );
return;
}
/* look for a matching list item */
for( neigh = area->weather->first_neighbor; neigh; neigh = neigh->next )
{
if( nifty_is_name( argument, neigh->name ) )
break;
}
/* if the a matching list entry is found, remove it */
if( neigh )
{
/* look for the neighbor area in question */
if( !( tarea = neigh->address ) )
tarea = get_area( neigh->name );
/* if there is an actual neighbor area remove its entry to this area */
if( tarea )
{
NEIGHBOR_DATA *tneigh;
tarea = neigh->address;
for( tneigh = tarea->weather->first_neighbor; tneigh; tneigh = tneigh->next )
{
if( !strcmp( area->name, tneigh->name ) )
break;
}
UNLINK( tneigh, tarea->weather->first_neighbor, tarea->weather->last_neighbor, next, prev );
STRFREE( tneigh->name );
DISPOSE( tneigh );
}
UNLINK( neigh, area->weather->first_neighbor, area->weather->last_neighbor, next, prev );
ch_printf( ch, "The weather in %s and %s no longer affect each other.\r\n", neigh->name, area->name );
STRFREE( neigh->name );
DISPOSE( neigh );
}
else /* add an entry */
{
if( !( tarea = get_area( argument ) ) )
{
send_to_char( "No such area exists.\r\n", ch );
return;
}
else if( tarea == area )
{
ch_printf( ch, "%s already affects its own weather.\r\n", area->name );
return;
}
/* add the entry */
CREATE( neigh, NEIGHBOR_DATA, 1 );
neigh->name = STRALLOC( tarea->name );
neigh->address = tarea;
LINK( neigh, area->weather->first_neighbor, area->weather->last_neighbor, next, prev );
/* add an entry to the neighbor's list */
CREATE( neigh, NEIGHBOR_DATA, 1 );
neigh->name = STRALLOC( area->name );
neigh->address = area;
LINK( neigh, tarea->weather->first_neighbor, tarea->weather->last_neighbor, next, prev );
ch_printf( ch, "The weather in %s and %s now affect one another.\r\n", tarea->name, area->name );
}
return;
}
else
{
send_to_char( "Climate may only be followed by one of the following fields:\r\n", ch );
send_to_char( " temp\r\n", ch );
send_to_char( " precip\r\n", ch );
send_to_char( " wind\r\n", ch );
send_to_char( " neighbor\r\n", ch );
return;
}
}
/*
* Relations created to fix a crash bug with oset on and rset on
* code by: gfinello@mail.karmanet.it
*/
void RelCreate( relation_type tp, void *actor, void *subject )
{
REL_DATA *tmp;
if( tp < relMSET_ON || tp > relOSET_ON )
{
bug( "%s: invalid type (%d)", __FUNCTION__, tp );
return;
}
if( !actor )
{
bug( "%s: NULL actor", __FUNCTION__ );
return;
}
if( !subject )
{
bug( "%s: NULL subject", __FUNCTION__ );
return;
}
for( tmp = first_relation; tmp; tmp = tmp->next )
{
if( tmp->Type == tp && tmp->Actor == actor && tmp->Subject == subject )
{
bug( "%s: duplicated relation", __FUNCTION__ );
return;
}
}
CREATE( tmp, REL_DATA, 1 );
tmp->Type = tp;
tmp->Actor = actor;
tmp->Subject = subject;
LINK( tmp, first_relation, last_relation, next, prev );
}
/*
* Relations created to fix a crash bug with oset on and rset on
* code by: gfinello@mail.karmanet.it
*/
void RelDestroy( relation_type tp, void *actor, void *subject )
{
REL_DATA *rq;
if( tp < relMSET_ON || tp > relOSET_ON )
{
bug( "%s: invalid type (%d)", __FUNCTION__, tp );
return;
}
if( !actor )
{
bug( "%s: NULL actor", __FUNCTION__ );
return;
}
if( !subject )
{
bug( "%s: NULL subject", __FUNCTION__ );
return;
}
for( rq = first_relation; rq; rq = rq->next )
{
if( rq->Type == tp && rq->Actor == actor && rq->Subject == subject )
{
UNLINK( rq, first_relation, last_relation, next, prev );
DISPOSE( rq );
break;
}
}
}
CMDF( do_rdig )
{
ROOM_INDEX_DATA *location = NULL, *in_room;
EXIT_DATA *pexit;
int edir, start, end, i;
if( !ch || is_npc( ch ) || !ch->in_room )
return;
if( get_trust( ch ) < PERM_BUILDER || !ch->pcdata->area )
{
send_to_char( "You aren't able to use rdig.\r\n", ch );
return;
}
if( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: rdig <direction>\r\n", ch );
return;
}
if( ch->pcdata->area )
{
start = ch->pcdata->area->low_vnum;
end = ch->pcdata->area->hi_vnum;
}
else
{
start = ch->pcdata->range_lo;
end = ch->pcdata->range_hi;
}
/* Get what way this will be going */
edir = get_dir( argument );
in_room = ch->in_room;
if( ( pexit = get_exit( in_room, edir ) ) )
{
send_to_char( "You can't dig that way because an exit already exist there.\r\n", ch );
return;
}
/* See if we can make a new room */
for( i = start; i <= end; i++ )
{
if( !get_room_index( i ) )
{
if( !( location = make_room( i, ch->pcdata->area ) ) )
{
bug( "%s: make_room failed", __FUNCTION__ );
return;
}
break; /* Made a new room so break out */
}
}
if( !location )
{
send_to_char( "You don't have any vnums free for use.\r\n", ch );
return;
}
location->area = ch->pcdata->area;
STRSET( location->name, in_room->name );
STRSET( location->description, in_room->description );
xSET_BITS( location->room_flags, in_room->room_flags );
location->light = in_room->light;
location->sector_type = in_room->sector_type;
pexit = make_exit( in_room, location, edir );
pexit->keyword = NULL;
pexit->description = NULL;
pexit->key = -1;
xCLEAR_BITS( pexit->exit_info );
pexit = make_exit( location, in_room, rev_dir[ edir ] );
pexit->keyword = NULL;
pexit->description = NULL;
pexit->key = -1;
xCLEAR_BITS( pexit->exit_info );
send_to_char( "Waving your hand, you form order from swirling chaos,\r\nand step into a new reality...\r\n", ch );
char_from_room( ch );
char_to_room( ch, location );
do_look( ch, (char *)"auto" );
}
CMDF( do_aexit )
{
AREA_DATA *tarea, *otherarea;
EXIT_DATA *pexit;
ROOM_INDEX_DATA *room;
int i, vnum, lrange, trange;
bool found = false;
if( !ch )
return;
if( !ch->in_room )
{
send_to_char( "You're in a NULL room!\r\n", ch );
return;
}
if( !( tarea = ch->in_room->area ) )
{
send_to_char( "You're in a NULL area!\r\n", ch );
return;
}
pager_printf( ch, "\r\nExits leading to %s.\r\n", tarea->filename );
for( otherarea = first_area; otherarea; otherarea = otherarea->next )
{
if( tarea == otherarea )
continue;
trange = otherarea->hi_vnum;
lrange = otherarea->low_vnum;
for( vnum = lrange; vnum <= trange; vnum++ )
{
if( !( room = get_room_index( vnum ) ) )
continue;
if( xIS_SET( room->room_flags, ROOM_TELEPORT ) )
{
if( room->tele_vnum >= tarea->low_vnum && room->tele_vnum <= tarea->hi_vnum )
{
pager_printf( ch, " From: %5d To : %5d (Teleport)\r\n", vnum, room->tele_vnum );
found = true;
}
}
for( i = 0; i < MAX_DIR + 1; i++ )
{
if( !( pexit = get_exit( room, i ) ) )
continue;
if( pexit->to_room->area == tarea )
{
pager_printf( ch, " From: %5d To : %5d (%s)\r\n", vnum, pexit->vnum, dir_name[i] );
found = true;
}
}
}
}
if( !found )
pager_printf( ch, " There are no exits leading to %s.\r\n", tarea->filename );
found = false;
trange = tarea->hi_vnum;
lrange = tarea->low_vnum;
pager_printf(ch, "\r\nExits leading from %s.\r\n", tarea->filename);
for( vnum = lrange; vnum <= trange; vnum++ )
{
if( !( room = get_room_index( vnum ) ) )
continue;
if( xIS_SET( room->room_flags, ROOM_TELEPORT ) && ( room->tele_vnum < lrange || room->tele_vnum > trange ) )
{
pager_printf( ch, " To : %5d From: %5d (Teleport)\r\n", room->tele_vnum, vnum );
found = true;
}
for( i = 0; i < MAX_DIR + 1; i++ )
{
if( !( pexit = get_exit( room, i ) ) )
continue;
if( pexit->to_room->area != tarea )
{
pager_printf(ch, " To : %5d From: %5d (%s)\r\n", pexit->vnum, vnum, dir_name[i] );
found = true;
}
}
}
if( !found )
pager_printf( ch, " There are no exits leading from %s.\r\n", tarea->filename );
}