#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "merc.h"
#include "tables.h"
/* This program provides the interpreting of building commands */
/* The tables are now in buildtab.c: (This file was getting a bit big.)
Mob type flags : tab_mob_flags : bit_vector
Mob affected by : tab_affected_by : bit_vector
Object item type : tab_item_types : number
Object extra flags : tab_obj_flags : bit_vector
Object wear flags : tab_wear_flags : bit_vector
Object affect types : tab_obj_aff : number
Class types : tab_class : bit_vector
Wear locations : tab_wear_loc : number
Room flags : tab_room_flags : bit_vector
Sector types : tab_sector_types : number
Door types : tab_door_types : bit_vector
Door states : tab_door_states : number
*/
#define MAX_STRING 2097152
/*
* Directions.
*/
const char * sDirs[]={ "North", "East ", "South", "West ", "Up ", "Down " };
const char * cDirs="NESWUD";
int RevDirs[]={ 2, 3, 0, 1, 5, 4 };
/*
* Sex.
* Used in #MOBILES.
*/
#define NEUTRAL 0
#define MALE 1
#define FEMALE 2
/* Interp. vars et al.
*
*/
/*
* Command logging types.
*/
#define LOG_NORMAL 0
#define LOG_ALWAYS 1
#define LOG_NEVER 2
/*
* God Levels
*/
#define L_GOD MAX_LEVEL
#define L_SUP L_GOD - 1
#define L_DEI L_SUP - 1
#define L_ANG L_DEI - 1
#define L_HER L_ANG - 1
/*
* Log-all switch.
*/
extern bool fLogAll;
/* -S- Additions */
DECLARE_DO_FUN( build_set_medit );
DECLARE_DO_FUN( build_set_oedit );
DECLARE_DO_FUN( build_set_redit );
DECLARE_DO_FUN( build_set_nedit );
DECLARE_DO_FUN( build_setvnum );
DECLARE_DO_FUN( build_list );
DECLARE_DO_FUN( build_set );
DECLARE_DO_FUN( build_listvalues );
DECLARE_DO_FUN( build_listweapons );
DECLARE_DO_FUN( build_listliquids );
DECLARE_DO_FUN( build_listspells );
DECLARE_DO_FUN( build_urooms );
DECLARE_DO_FUN( build_uobjs );
DECLARE_DO_FUN( build_umobs );
DECLARE_DO_FUN( build_findhelp );
DECLARE_DO_FUN( build_commands );
DECLARE_DO_FUN( build_clone );
/* build_functions */
DECLARE_DO_FUN ( build_showmob );
DECLARE_DO_FUN ( build_showroom );
DECLARE_DO_FUN ( build_showobj );
DECLARE_DO_FUN ( build_findmob );
DECLARE_DO_FUN ( build_findmobroom );
DECLARE_DO_FUN ( build_findroom );
DECLARE_DO_FUN ( build_findobject );
DECLARE_DO_FUN ( build_help );
DECLARE_DO_FUN ( build_helpedit );
DECLARE_DO_FUN ( build_setmob );
DECLARE_DO_FUN ( build_setroom );
DECLARE_DO_FUN ( build_setobject );
DECLARE_DO_FUN ( build_stop );
DECLARE_DO_FUN ( build_dig );
DECLARE_DO_FUN ( build_addobject );
DECLARE_DO_FUN ( build_addmob );
DECLARE_DO_FUN ( build_delwarn );
DECLARE_DO_FUN ( build_delroom );
DECLARE_DO_FUN ( build_delmob );
DECLARE_DO_FUN ( build_delobject );
DECLARE_DO_FUN ( build_showresets );
DECLARE_DO_FUN ( build_addreset );
DECLARE_DO_FUN ( build_delreset );
DECLARE_DO_FUN ( build_forcereset );
DECLARE_DO_FUN ( build_addhelp );
/* Functions in buildare.c: */
DECLARE_DO_FUN ( build_showarea );
DECLARE_DO_FUN ( build_findarea );
DECLARE_DO_FUN ( build_addarea );
DECLARE_DO_FUN ( build_setarea );
DECLARE_DO_FUN ( build_makearea );
/* Commands */
const struct cmd_type build_cmd_table [] =
{
/*
* Common movement commands.
*/
{ "north", do_north, POS_STANDING, 0, LOG_NORMAL },
{ "east", do_east, POS_STANDING, 0, LOG_NORMAL },
{ "south", do_south, POS_STANDING, 0, LOG_NORMAL },
{ "west", do_west, POS_STANDING, 0, LOG_NORMAL },
{ "up", do_up, POS_STANDING, 0, LOG_NORMAL },
{ "down", do_down, POS_STANDING, 0, LOG_NORMAL },
{ "goto", do_goto, POS_STANDING, 0, LOG_NORMAL },
/*
* Building commands.
*/
{ "look", do_look, POS_STANDING, 0, LOG_NORMAL },
{ "list", build_list, POS_STANDING, 0, LOG_NORMAL },
{ "x", build_list, POS_STANDING, 0, LOG_NORMAL },
{ "commands", build_commands, POS_STANDING, 0, LOG_NORMAL },
{ "showarea", build_showarea, POS_STANDING, 0, LOG_NORMAL },
{ "showmob", build_showmob, POS_STANDING, 0, LOG_NORMAL },
{ "showroom", build_showroom, POS_STANDING, 0, LOG_NORMAL },
{ "showobject", build_showobj, POS_STANDING, 0, LOG_NORMAL },
{ "showresets", build_showresets,POS_STANDING, 0, LOG_NORMAL },
{ "findarea", build_findarea, POS_STANDING, 0, LOG_NORMAL },
{ "findmob", build_findmob, POS_STANDING, 0, LOG_NORMAL },
{ "findmobroom", build_findmobroom,POS_STANDING, 0, LOG_NORMAL },
{ "findroom", build_findroom, POS_STANDING, 0, LOG_NORMAL },
{ "findobject", build_findobject,POS_STANDING, 0, LOG_NORMAL },
{ "help", build_help, POS_STANDING, 0, LOG_NORMAL },
{ "helpedit", build_helpedit, POS_STANDING, 0, LOG_NORMAL },
{ "set", build_set, POS_STANDING, 0, LOG_NORMAL },
/* { "setmob", build_setmob, POS_STANDING, 0, LOG_NORMAL }, */
/* { "setroom", build_setroom, POS_STANDING, 0, LOG_NORMAL }, */
/* { "setobj", build_setobject,POS_STANDING, 0, LOG_NORMAL }, */
{ "setarea", build_setarea, POS_STANDING,MAX_LEVEL-1,LOG_NORMAL },
/* { "areasave", do_savearea, POS_STANDING, 0, LOG_ALWAYS }, */
{ "stop", build_stop, POS_STANDING, 0, LOG_ALWAYS },
{ "dig", build_dig, POS_STANDING, 0, LOG_NORMAL },
{ "addarea", build_makearea, POS_STANDING,MAX_LEVEL-1,LOG_NORMAL },
{"makearea", build_makearea,POS_STANDING,L_SUP,LOG_NORMAL},
{ "addobject", build_addobject,POS_STANDING, 0, LOG_NORMAL },
{ "addmob", build_addmob, POS_STANDING, 0, LOG_NORMAL },
{ "addreset", build_addreset, POS_STANDING, 0, LOG_NORMAL },
{ "delroo", build_delwarn, POS_STANDING, 0, LOG_NORMAL },
{ "delobjec", build_delwarn, POS_STANDING, 0, LOG_NORMAL },
{ "delmobil", build_delwarn, POS_STANDING, 0, LOG_NORMAL },
{ "delroom", build_delroom, POS_STANDING, 0, LOG_NORMAL },
{ "delobject", build_delobject,POS_STANDING, 0, LOG_NORMAL },
{ "delreset", build_delreset, POS_STANDING, 0, LOG_NORMAL },
{ "delmobile", build_delmob, POS_STANDING, 0, LOG_NORMAL },
{ "forcereset", build_forcereset,POS_STANDING, 0, LOG_NORMAL },
{ "findhelp", build_findhelp, POS_STANDING, 0, LOG_NORMAL },
{ "addhelp", build_addhelp, POS_STANDING, 0, LOG_NORMAL },
{ "redit", build_set_redit, POS_STANDING, 0, LOG_NORMAL },
{ "oedit", build_set_oedit, POS_STANDING, 0, LOG_NORMAL },
{ "medit", build_set_medit, POS_STANDING, 0, LOG_NORMAL },
{ "nedit", build_set_nedit, POS_STANDING, 0, LOG_NORMAL },
{ "setvnum", build_setvnum, POS_STANDING, 0, LOG_NORMAL },
{ "vset", build_setvnum, POS_STANDING, 0, LOG_NORMAL },
{ "uobjs", build_uobjs, POS_STANDING, 0, LOG_NORMAL },
{ "urooms", build_urooms, POS_STANDING, 0, LOG_NORMAL },
{ "umobs", build_umobs, POS_STANDING, 0, LOG_NORMAL },
{ "values", build_listvalues,POS_STANDING, 0, LOG_NORMAL },
{ "liquids", build_listliquids,POS_STANDING, 0, LOG_NORMAL },
{ "weapons", build_listweapons,POS_STANDING, 0, LOG_NORMAL },
{ "spells", build_listspells, POS_STANDING, 0, LOG_NORMAL },
{ "check_area", do_check_area, POS_STANDING,MAX_LEVEL,LOG_NORMAL},
{ "check_areas", do_check_areas, POS_STANDING,MAX_LEVEL,LOG_ALWAYS},
{ "clone", build_clone, POS_STANDING, 0, LOG_NORMAL },
/*
* End of list.
*/
{ "", 0, POS_DEAD, 0, LOG_NORMAL }
};
/* Building memory management
* Using the linked list approach for various sized bits.
* Store array of sizes, pointing to linked list.
*/
#define MAX_MEM_SIZES 20
int build_freesize[MAX_MEM_SIZES];
void * build_freepointer[MAX_MEM_SIZES];
int build_numsizes=0;
/* String function */
/* moved build_strdup to merc.h - Stephen */
char * build_simpstrdup(char *);
void build_editstr(char * * dest, char * src, CHAR_DATA * ch);
void build_finishedstr( char * orig, char * * dest,CHAR_DATA * ch,bool saved);
/* Variables declared in db.c, which we need */
extern MOB_INDEX_DATA * mob_index_hash [MAX_KEY_HASH];
extern OBJ_INDEX_DATA * obj_index_hash [MAX_KEY_HASH];
extern ROOM_INDEX_DATA * room_index_hash [MAX_KEY_HASH];
extern char * string_hash [MAX_KEY_HASH];
extern char * string_space;
extern char * top_string;
extern char str_empty [1];
extern int top_affect;
extern int top_area;
extern int top_ed;
extern int top_exit;
extern int top_help;
extern int top_mob_index;
extern int top_obj_index;
extern int top_reset;
extern int top_room;
extern int top_shop;
extern HELP_DATA * help_last;
extern AREA_DATA * area_last;
extern AREA_DATA * area_first;
extern SHOP_DATA * first_shop;
extern SHOP_DATA * last_shop;
#define MAX_PERM_BLOCK 131072
extern int nAllocString;
extern int sAllocString;
extern int nAllocPerm;
extern int sAllocPerm;
/* extern int fBootDb; */
/* local functions */
char * build_docount(int *);
char * reset_to_text(BUILD_DATA_LIST **,int *);
void build_interpret( CHAR_DATA *ch, char *argument )
{
char command[MAX_INPUT_LENGTH];
char logline[MAX_INPUT_LENGTH];
char buffer[MAX_INPUT_LENGTH];
int cmd;
/* int trust; Unused var*/
bool found;
/*
* Strip leading spaces.
*/
while ( isspace(*argument) )
argument++;
if ( argument[0] == '\0' )
return;
/*
* Grab the command word.
* Special parsing so ' can be a command,
* also no spaces needed after punctuation.
*/
strcpy( logline, argument );
if ( !isalpha(argument[0]) && !isdigit(argument[0]) )
{
command[0] = argument[0];
command[1] = '\0';
argument++;
while ( isspace(*argument) )
argument++;
}
else
{
argument = one_argument( argument, command );
}
/*
* Look for command in command table.
*/
found = FALSE;
for ( cmd = 0; build_cmd_table[cmd].name[0] != '\0'; cmd++ )
{
if ( command[0] == build_cmd_table[cmd].name[0]
&& !str_prefix( command, build_cmd_table[cmd].name )
&& get_trust(ch) >= build_cmd_table[cmd].level )
{
found = TRUE;
break;
}
}
/*
* Log and snoop.
*/
if ( build_cmd_table[cmd].log == LOG_NEVER )
strcpy( logline, "XXXXXXXX XXXXXXXX XXXXXXXX" );
if ( ( !IS_NPC(ch) && IS_SET(ch->act, PLR_LOG) )
|| fLogAll
|| build_cmd_table[cmd].log == LOG_ALWAYS )
{
sprintf( log_buf, "Log %s: %s", ch->name, logline );
log_string( log_buf );
monitor_chan( log_buf, MONITOR_BUILD );
}
if ( ch->desc != NULL && ch->desc->snoop_by != NULL )
{
write_to_buffer( ch->desc->snoop_by, "% ", 2 );
write_to_buffer( ch->desc->snoop_by, logline, 0 );
write_to_buffer( ch->desc->snoop_by, "\n\r", 2 );
}
if ( !found )
{
sprintf(buffer,"%s %s",command,argument);
build_set(ch,buffer);
return;
}
/*
* Dispatch the command.
*/
(*build_cmd_table[cmd].do_fun) ( ch, argument );
/* make sure that if in Redit, vnum is at new room. */
if ( ch->act_build == ACT_BUILD_REDIT && ch->build_vnum != ch->in_room->vnum )
{
ch->build_vnum = ch->in_room->vnum;
send_to_char( "Redit: Vnum changed to new room.\n\r", ch );
}
tail_chain( );
return;
}
/* -S- Addition: */
void build_commands( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char out[MAX_STRING_LENGTH];
int cmd;
int col = 0;
sprintf( out, "Building / Editing Commands Available to You:\n\r" );
for ( cmd = 0; build_cmd_table[cmd].name[0] != '\0'; cmd++ )
{
if ( build_cmd_table[cmd].level > get_trust( ch ) )
continue;
sprintf( buf, "%-20s ", build_cmd_table[cmd].name );
strcat( out, buf );
if ( ++col % 3 == 0 )
strcat( out, "\n\r" );
}
strcat( out, "\n\r" );
send_to_char( out, ch );
return;
}
void build_showmob( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH];
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
MOB_INDEX_DATA *pMob;
/* RESET_DATA *pReset; Unused var */
SHOP_DATA *pShop;
bool is_shopkeeper=0;
int iTrade;
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if ( arg1[0] == '\0' )
{
send_to_char( "showmob <vnum>\n\r", ch );
return;
}
if ( !is_number(arg1) )
{
send_to_char( "must be a vnum.\n\r", ch );
return;
}
if ( ( pMob = get_mob_index(atoi(arg1)) ) == NULL )
{
send_to_char( "Cannot find a mob with that vnum.\n\r", ch );
return;
}
if (! build_canread(pMob->area,ch,1))
return;
buf1[0] = '\0';
sprintf( buf, "@@WName: @@y%s. @@WClass: @@y%s.\n\r",
pMob->player_name, tab_mob_class[pMob->class].text );
strcat( buf1, buf );
sprintf( buf, "@@WVnum: @@y%d. @@WSex: @@y%s. ",
pMob->vnum,
pMob->sex == SEX_MALE ? "male" :
pMob->sex == SEX_FEMALE ? "female" : "neutral"
);
strcat( buf1, buf );
sprintf( buf,
" @@WLv: @@y%d. @@WAlign: @@y%d.\n\r", pMob->level, pMob->alignment );
strcat( buf1, buf );
sprintf( buf, "@@WModifiers: AC: @@y%d. @@WHitroll: @@y%d. @@WDamroll: @@y%d.\n\r",
pMob->ac_mod,
pMob->hr_mod,
pMob->dr_mod );
strcat( buf1, buf );
sprintf( buf, "@@WMob Flags:@@y\n\r%s",
show_values( tab_mob_flags, pMob->act, TRUE ) );
strcat( buf1, buf );
sprintf( buf, "@@WAffected by:@@y\n\r%s",
show_values( tab_affected_by, pMob->affected_by, TRUE ) );
strcat( buf1, buf );
sprintf( buf, "@@WSkill_Flags:@@y %s\n\r",
bit_table_lookup( tab_mob_skill, pMob->skills ) );
strcat( buf1, buf );
sprintf( buf, "@@WCast_Flags:@@y %s\n\r",
bit_table_lookup( tab_mob_cast, pMob->cast ) );
strcat( buf1, buf );
sprintf( buf, "@@WDef_Flags:@@y %s\n\r",
bit_table_lookup( tab_mob_def, pMob->def ) );
strcat( buf1, buf );
sprintf( buf, "@@WShort description: @@y%s.\n\r@@WLong description: @@y%s",
pMob->short_descr,
pMob->long_descr[0] != '\0' ? pMob->long_descr : "(none).\n\r" );
strcat( buf1, buf );
if ( pMob->spec_fun != 0 )
{
sprintf(buf,"@@WMobile has spec fun: @@y%s\n\r",rev_spec_lookup(pMob->spec_fun) );
strcat( buf1, buf);
}
if ( (pShop=pMob->pShop) != 0)
{
is_shopkeeper=1;
strcat( buf1, "@@WMobile is a shopkeeper, will buy @@y");
for ( iTrade = 0; iTrade < MAX_TRADE; iTrade++ )
{
if (pShop->buy_type[iTrade]>0)
{
strcat( buf1, tab_item_types[pShop->buy_type[iTrade]-1].text);
strcat( buf1, " ");
}
}
strcat( buf1, "\n\r");
sprintf(buf,"@@WOpens at @@y%i @@Whrs, shuts at @@y%i @@Whours, profbuy:@@y%i, @@Wprofsell:@@y%i.\n\r",
pShop->open_hour, pShop->close_hour, pShop->profit_buy, pShop->profit_sell);
strcat( buf1, buf);
}
strcat( buf1, "@@g" );
send_to_char( buf1, ch );
return;
}
void build_showobj( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
AFFECT_DATA *paf;
OBJ_INDEX_DATA *obj;
int cnt;
char *foo;
int fubar;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "Show what object?\n\r", ch );
return;
}
if ( !is_number(arg) )
{
send_to_char( "must be a vnum.\n\r", ch );
return;
}
buf1[0] = '\0';
if ( ( obj = get_obj_index( atoi(arg) ) ) == NULL )
{
send_to_char( "Object vnum not found.\n\r", ch );
return;
}
if ( !build_canread( obj->area, ch, 1) )
return;
sprintf( buf, "@@WName: @@y%s @@WLevel: @@y%d.\n\r", obj->name, obj->level );
strcat( buf1, buf );
sprintf( buf, "@@WVnum: @@y%d. @@WType: @@y%s.\n\r",
obj->vnum, tab_item_types[ (obj->item_type)-1 ].text );
strcat( buf1, buf );
sprintf( buf, "@@WShort description: @@y%s.\n\r@@WLong description: @@y%s\n\r",
obj->short_descr, obj->description );
strcat( buf1, buf );
/*
sprintf( buf, "@@WItem type: @@y%s.\n\r",rev_table_lookup(tab_item_types,obj->item_type));
strcat( buf1, buf);
*/
sprintf( buf, "@@WWear bits: @@y%s\n\r@@WExtra bits: @@y%s.\n\r",
bit_table_lookup(tab_wear_flags,obj->wear_flags),
extra_bit_name( obj->extra_flags ) );
/* bit_table_lookup(tab_extra_flags, obj->extra_flags ) );
I think another bit_table_lookup is better! Zen */
strcat( buf1, buf );
sprintf( buf, "@@WItem_applies: @@y%s.\n\r",
bit_table_lookup( tab_item_apply, obj->item_apply ) );
strcat( buf1, buf );
sprintf( buf, "@@WWeight: @@y%d.\n\r", obj->weight );
strcat( buf1, buf );
strcat( buf1, "@@WObject Values:\n\r" );
for ( cnt = 0; cnt < 4; cnt++ )
{
sprintf( buf, "@@W[Value%d : @@y%6d@@W] %s",
cnt, obj->value[cnt],
rev_table_lookup( tab_value_meanings, (obj->item_type *10 ) + cnt ) );
strcat( buf1, buf );
if ( is_name( "Spell", rev_table_lookup( tab_value_meanings, ( obj->item_type * 10 ) + cnt ) ) )
{
fubar = obj->value[cnt];
if ( fubar < 0 || fubar > MAX_SKILL )
sprintf( buf, " @@R(INVALID!)@@g\n\r" );
else
sprintf( buf, " @@y(%s)@@g\n\r",
skill_table[fubar].name );
}
else if ( is_name( "Liquid", rev_table_lookup( tab_value_meanings, ( obj->item_type * 10 ) + cnt ) ) )
{
foo = str_dup(rev_table_lookup( tab_drink_types, obj->value[cnt] ) );
if ( foo[0] == '\0' )
sprintf( buf, " @@R(INVALID!)@@g\n\r" );
else
sprintf( buf, " @@y(%s)@@g\n\r", foo );
}
else if ( is_name( "Weapon", rev_table_lookup( tab_value_meanings, ( obj->item_type * 10 ) + cnt ) ) )
{
foo = rev_table_lookup( tab_weapon_types, obj->value[cnt] );
if ( foo[0] == '\0' )
sprintf( buf, " @@R(INVALID!)@@g\n\r" );
else
sprintf( buf, " @@y(%s)@@g\n\r", foo );
}
else
sprintf( buf, "@@g\n\r" );
strcat( buf1, buf );
}
if ( obj->obj_fun != NULL )
{
sprintf( buf, "@@WObject has objfun: @@y%s.@@g\n\r",
rev_obj_fun_lookup( obj->obj_fun ) );
strcat( buf1, buf );
}
if ( obj->first_exdesc != NULL )
{
EXTRA_DESCR_DATA *ed;
strcat( buf1, "@@WExtra description keywords: '@@y" );
for ( ed = obj->first_exdesc; ed != NULL; ed = ed->next )
{
strcat( buf1, ed->keyword );
if ( ed->next != NULL )
strcat( buf1, " " );
}
strcat( buf1, "'@@g.\n\r" );
}
for ( paf = obj->first_apply; paf != NULL; paf = paf->next )
{
sprintf( buf, "@@WAffects @@y%s @@Wby @@y%d@@g.\n\r",
affect_loc_name( paf->location ), paf->modifier );
strcat( buf1, buf );
}
send_to_char( buf1, ch );
return;
}
#define DISPLAY_BRIEFDOORS 1
#define DISPLAY_RESETS 2
#define DISPLAY_FULLDOORS 4
#define DISPLAY_DESC 8
void build_showroom( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH];
char arg1[MAX_INPUT_LENGTH];
ROOM_INDEX_DATA *location;
BUILD_DATA_LIST *Pointer;
int door;
int display;
argument=one_argument( argument, arg1);
location = ch->in_room;
if (!build_canread(location->area, ch, 1))
return;
display=0;
if (arg1[0]=='\0')
{
display=DISPLAY_BRIEFDOORS | DISPLAY_RESETS | DISPLAY_DESC;
strcat(buf1,"Can also use showroom brief/doors/resets/desc/all.\n\r");
}
else
if ( !is_name(arg1,"brief doors resets desc all") )
{
send_to_char("Syntax: Showroom brief/doors/resets/desc/all.\n\r",ch);
return;
}
if (!str_cmp(arg1,"brief"))
display=DISPLAY_BRIEFDOORS;
if (!str_cmp(arg1,"doors"))
display=DISPLAY_FULLDOORS;
if (!str_cmp(arg1,"resets"))
display=DISPLAY_RESETS;
if (!str_cmp(arg1,"desc"))
display=DISPLAY_DESC;
if (!str_cmp(arg1,"all"))
display=DISPLAY_FULLDOORS | DISPLAY_RESETS | DISPLAY_DESC;
buf1[0] = '\0';
sprintf( buf, "@@WName: @@y%s.\n\r@@WArea: @@y%s.\n\r",
location->name,
location->area->name );
strcat( buf1, buf );
sprintf( buf,
"@@WVnum: @@y%d. @@WSector:\n\r @@y%s",
location->vnum,
show_values( tab_sector_types, location->sector_type, FALSE ) );
strcat( buf1, buf );
sprintf( buf, "@@WFlags:\n\r@@y%s",
show_values( tab_room_flags, location->room_flags, TRUE ) );
strcat( buf1, buf );
if ( (display & DISPLAY_DESC) )
{
sprintf( buf, "@@WDescr: \n\r@@y%s", location->description);
strcat( buf1,buf);
}
if ( location->first_exdesc != NULL )
{
EXTRA_DESCR_DATA *ed;
strcat( buf1, "@@WExtra description keywords:@@y '" );
for ( ed = location->first_exdesc; ed; ed = ed->next )
{
strcat( buf1, ed->keyword );
if ( ed->next != NULL )
strcat( buf1, " " );
}
strcat( buf1, "'.\n\r" );
}
/*
* Exits
*/
if ( (display & (DISPLAY_BRIEFDOORS | DISPLAY_FULLDOORS) ) )
for ( door = 0; door <= 5; door++ )
{
EXIT_DATA *pexit;
OBJ_INDEX_DATA *pKeyObj;
if ( ( pexit = location->exit[door] ) != NULL )
{
if ( (display & DISPLAY_FULLDOORS) )
{
if (pexit->key>0)
pKeyObj=get_obj_index(pexit->key);
else
pKeyObj=NULL;
sprintf( buf,"@@WExit: @@y%7s @@W: To @@y%5i %s\n\r",sDirs[door],
pexit->to_room != NULL ? pexit->to_room->vnum : 0,
pexit->to_room != NULL ? pexit->to_room->name : "");
strcat(buf1,buf);
sprintf( buf," @@WKey: @@y%5i %s, @@WExit Type:@@y %s\n\r",
pKeyObj != NULL ? pKeyObj->vnum : 0,
pKeyObj != NULL ? pKeyObj->name : "None",
bit_table_lookup(tab_door_types,pexit->exit_info));
strcat(buf1,buf);
if (pexit->keyword != NULL && pexit->keyword[0]!='\0')
{
sprintf( buf,"@@WKeyword(s): @@y%s. ",pexit->keyword);
strcat(buf1,buf);
}
sprintf(buf,"@@WDesc: @@y%s",pexit->description[0] != '\0'
? pexit->description : "(none).\n\r" );
strcat(buf1,buf);
}
else
{
if (pexit->key>0)
strcat(buf1,"@@yK");
/* New way of showing doors... move to relevant place if it works */
sprintf( buf,"%s: (%s) @@WTo: @@y(%i) %s, %s\n\r", sDirs[door],
pexit->keyword,
pexit->to_room != NULL ? pexit->to_room->vnum : 0,
pexit->to_room != NULL ? pexit->to_room->name : "Unknown",
bit_table_lookup(tab_door_types,pexit->exit_info)
);
strcat(buf1,buf);
}
}
}
/* Show resets for room */
if ( (display & DISPLAY_RESETS ) &&
location->first_room_reset != NULL)
{
strcat (buf1, "@@WResets:\n\r");
for (Pointer=location->first_room_reset; Pointer; )
strcat(buf1,reset_to_text(&Pointer,NULL));
}
strcat( buf1, "@@g" );
send_to_char( buf1, ch );
return;
}
void build_showresets( CHAR_DATA *ch, char *argument)
{
char buf1[MAX_STRING_LENGTH];
ROOM_INDEX_DATA *location;
BUILD_DATA_LIST *Pointer;
int count;
count=0;
buf1[0]='\0';
location=ch->in_room;
if (!build_canread(location->area,ch,1))
return;
strcat (buf1, "Room Resets:\n\r");
for (Pointer=location->first_room_reset; Pointer != NULL; )
strcat(buf1,reset_to_text(&Pointer,&count));
send_to_char(buf1,ch);
}
/* spec: rewrote to catch errors and count how many resets it handled */
char *reset_to_text(BUILD_DATA_LIST **pList, int * pcount)
{
char buf[MAX_STRING_LENGTH];
static char buf1[MAX_STRING_LENGTH];
MOB_INDEX_DATA * pMob;
OBJ_INDEX_DATA * pObj;
RESET_DATA * pReset;
buf[0]='\0';
buf1[0]='\0';
pReset=(*pList)->data;
strcat(buf1, build_docount(pcount));
if ((*pList)->is_free) /* sanity check */
strcat(buf1, " **LIST IS FREE** "); /* Bad Thing! */
if (pReset->is_free)
strcat(buf1, " **RESET IS FREE** ");
(*pList)=(*pList)->next;
switch (pReset->command)
{
default:
sprintf(buf, " stray '%c' reset: %d %d %d.\n\r",
pReset->command, pReset->arg1, pReset->arg2, pReset->arg3);
strcat(buf1, buf);
break;
case 'G':
pObj=get_obj_index(pReset->arg1);
if (pObj)
sprintf(buf, " stray 'give' reset: object [%d] %s.\n\r",
pReset->arg1, pObj->name);
else
sprintf(buf, " stray 'give' reset: object %d (unknown).\n\r",
pReset->arg1);
strcat(buf1, buf);
break;
case 'E':
pObj=get_obj_index(pReset->arg1);
if (pObj)
sprintf(buf, " stray 'equip' reset: object [%d] %s, on %s.\n\r",
pReset->arg1, pObj->name, tab_wear_loc[(pReset->arg3)].text);
else
sprintf(buf, " stray 'equip' reset: object [%d] (unknown), on %s.\n\r",
pReset->arg1, tab_wear_loc[(pReset->arg3)].text);
strcat(buf1, buf);
break;
case 'A': /* AutoMessage for room */
sprintf( buf1, "Message: (%d-%d) %s\n\r",
pReset->arg2, pReset->arg3, pReset->notes );
strcat( buf1, buf );
break;
case 'M': /* Load mob */
pMob=get_mob_index(pReset->arg1);
if (pMob != NULL)
sprintf(buf," [%d] %s (limit of %d).\n\r",pMob->vnum,
pMob->player_name,pReset->arg2);
else
sprintf(buf, " [%d] (unknown) (limit of %d).\n\r", pReset->arg1,
pReset->arg2);
strcat(buf1, buf);
/* scan for give and equip commands for this mob */
while (*pList)
{
pReset=(*pList)->data;
if (pReset->command!='G' && pReset->command!='E')
break;
(*pList)=(*pList)->next;
strcat(buf1,build_docount(pcount));
if (pReset->command=='G')
{
pObj=get_obj_index(pReset->arg1);
if (pObj != NULL)
{
if (pMob->pShop != NULL)
strcat(buf1," sells ");
else
strcat(buf1," with ");
sprintf(buf,"[%d] %s.\n\r",pObj->vnum,pObj->name);
strcat(buf1,buf);
}
else
{
sprintf(buf, "[%d] unknown object in give reset!\n\r",
pReset->arg1);
strcat(buf1, buf);
}
}
else if (pReset->command=='E')
{
pObj=get_obj_index(pReset->arg1);
if (pObj != NULL)
sprintf(buf," equiped with [%d] %s, on %s.\n\r",pObj->vnum,
pObj->name,tab_wear_loc[(pReset->arg3)].text);
else
sprintf(buf, "[%d] unknown object equipped on %s.\n\r",
pReset->arg1, tab_wear_loc[pReset->arg3].text);
strcat(buf1, buf);
}
}
break;
case 'O': /* Load object to room */
pObj=get_obj_index(pReset->arg1);
if (pObj != NULL)
sprintf(buf," [%d] %s.\n\r",pObj->vnum,pObj->name);
else
sprintf(buf, " [%d] unknown object reset!\n\r", pReset->arg1);
strcat(buf1, buf);
break;
case 'D': /* close/lock doors */
buf[0]='\0';
switch(pReset->arg3)
{
default:
sprintf(buf, " Illegal door state %d for door %d\n\r",
pReset->arg1,pReset->arg2);
case 0:
sprintf(buf," Open door %s.\n\r",sDirs[pReset->arg2]);
break;
case 1:
sprintf(buf," Close door %s.\n\r",sDirs[pReset->arg2]);
break;
case 2:
sprintf(buf," Close and lock door %s.\n\r",sDirs[pReset->arg2]);
break;
}
strcat(buf1,buf);
break;
case 'R': /* randomise exits */
sprintf(buf," Randomize doors up to number %d.\n\r",pReset->arg2);
strcat(buf1,buf);
break;
}
return buf1;
}
char * build_docount(int * pcount)
{
static char buf[20];
buf[0] = '\0';
if (pcount != NULL)
sprintf(buf,"%d) ",++*pcount);
else
buf[0]='\0';
return buf;
}
void build_findmob( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
MOB_INDEX_DATA *pMobIndex;
BUILD_DATA_LIST *Pointer;
AREA_DATA * Area;
int nMatch;
bool fAll;
bool found;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "find which mob?\n\r", ch );
return;
}
if ( !(Area=ch->in_room->area) )
{
send_to_char( "Don't know what area you're in.\n\r", ch);
return;
}
if (!build_canread(Area,ch,1))
return;
if ( !(Pointer=Area->first_area_mobile) )
{
send_to_char( "No mobiles in this area.\n\r",ch);
return;
}
buf1[0] = '\0';
fAll = !str_cmp( arg, "all" );
found = FALSE;
nMatch = 0;
for ( ; Pointer != NULL; Pointer=Pointer->next )
{
nMatch++;
pMobIndex=Pointer->data;
if ( fAll || is_name( arg, pMobIndex->player_name ) )
{
found = TRUE;
sprintf( buf, "[%5d] %s\n\r",
pMobIndex->vnum, capitalize( pMobIndex->short_descr ) );
strcat( buf1, buf );
}
}
if ( !found )
{
send_to_char( "Nothing like that in this area.\n\r", ch );
return;
}
send_to_char( buf1, ch );
return;
}
void build_findmobroom( CHAR_DATA *ch, char * argument)
{
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
ROOM_INDEX_DATA *pRoom;
RESET_DATA *pReset;
AREA_DATA * Area;
int vnum,found;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "find which mob vnum?\n\r", ch );
return;
}
if (!is_number(arg))
{
send_to_char( "syntax: findmobroom vnum.\n\r", ch);
return;
}
vnum=atoi(arg);
found=0;
buf1[0]='\0';
if ( !(Area=ch->in_room->area) )
{
send_to_char( "Don't know what area you're in.\n\r", ch);
return;
}
if (!build_canread(Area,ch,1))
return;
for ( pReset=Area->first_reset; pReset != NULL; pReset=pReset->next )
{
if ( pReset->command=='M' && pReset->arg1==vnum )
{
found = TRUE;
pRoom=get_room_index(pReset->arg3);
if (pRoom != NULL)
sprintf( buf, "[%5d] %s\n\r",pRoom->vnum, capitalize( pRoom->name ) );
else
sprintf( buf, "[%5d] Unknown\n\r",pReset->arg3);
strcat( buf1, buf );
}
}
if ( !found )
{
send_to_char( "Mob not found in any room.\n\r", ch );
return;
}
send_to_char( buf1, ch );
return;
}
void build_findobject( CHAR_DATA *ch, char * argument)
{
/* extern int top_obj_index; Unused Var */
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
OBJ_INDEX_DATA *pObjIndex;
BUILD_DATA_LIST *pList;
AREA_DATA * Area;
int nMatch;
bool fAll;
bool found;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "Find what object?\n\r", ch );
return;
}
if ( !(Area=ch->in_room->area) )
{
send_to_char( "Don't know what area you're in.\n\r", ch);
return;
}
if (!build_canread(Area,ch,1))
return;
if ( !(pList=Area->first_area_object) )
{
send_to_char( "No objects in this area.\n\r",ch);
return;
}
buf1[0] = '\0';
fAll = !str_cmp( arg, "all" );
found = FALSE;
nMatch = 0;
for ( ; pList != NULL; pList=pList->next )
{
pObjIndex = pList->data;
nMatch++;
if ( fAll || is_name( arg, pObjIndex->name ) )
{
found = TRUE;
sprintf( buf, "[%5d] %s\n\r",
pObjIndex->vnum, capitalize( pObjIndex->short_descr ) );
strcat( buf1, buf );
}
}
if ( !found )
{
send_to_char( "Nothing like that in the area.\n\r", ch );
return;
}
send_to_char( buf1, ch );
return;
}
void build_findroom( CHAR_DATA *ch, char * argument)
{
/* extern int top_room_index; Unused Var */
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
ROOM_INDEX_DATA *pRoomIndex;
BUILD_DATA_LIST *pList;
AREA_DATA * Area;
int nMatch;
bool fAll;
bool found;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "Find what room?\n\r", ch );
return;
}
if ( !(Area=ch->in_room->area) )
{
send_to_char( "Don't know what area you're in.\n\r", ch);
return;
}
if (!build_canread(Area,ch,1))
return;
if ( !(pList=Area->first_area_room) )
{
send_to_char( "No rooms in this area.\n\r",ch);
return;
}
buf1[0] = '\0';
fAll = !str_cmp( arg, "all" );
found = FALSE;
nMatch = 0;
for ( ; pList != NULL; pList=pList->next )
{
pRoomIndex = pList->data;
nMatch++;
if ( fAll || is_name( arg, pRoomIndex->name ) )
{
found = TRUE;
sprintf( buf, "[%5d] %s\n\r",
pRoomIndex->vnum, capitalize( pRoomIndex->name ) );
strcat( buf1, buf );
}
}
if ( !found )
{
send_to_char( "Nothing like that in the area.\n\r", ch );
return;
}
send_to_char( buf1, ch );
return;
}
/* -S- : More 'intelligent' way to handle things perhaps? */
void build_setmob( CHAR_DATA *ch, char * argument)
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
char arg4 [MAX_INPUT_LENGTH];
char buf [MAX_STRING_LENGTH];
/* char buf2 [MAX_STRING_LENGTH]; unused */
/* char buffer[MAX_STRING_LENGTH]; unused */
/* char name[MAX_INPUT_LENGTH]; unused */
MOB_INDEX_DATA *pMob;
/* char *argn, *oldperm; unused */
int value, num;
int lvalue; /* lookup value */
AREA_DATA * pArea;
smash_tilde( argument );
argument = one_argument( argument, arg1 ); /* vnum */
argument = one_argument( argument, arg2 );
strcpy( arg3, argument );
/** Changes to old setmob: *********************************
Check through the tables, to see if the
builder has entered the name of an entry. If so, toggle
entry( new way of showing bits set is now used )
Otherwise, check for other values being set, or huh? :P
************************************************************/
if ( arg1[0] == '\0' || arg2[0] == '\0' )
{
send_to_char( "Syntax: [set] <field> <value>\n\r", ch );
send_to_char( "or: [set] <string> <value>\n\r", ch );
send_to_char( "or: [set] edit <string>\n\r", ch );
send_to_char( "or: [set] shop <shopspec> <value>\n\r", ch );
send_to_char( "\n\r", ch );
send_to_char( "Field being one of:\n\r", ch );
send_to_char( " sex level align aff act\n\r", ch );
send_to_char( " class clan position race\n\r", ch );
send_to_char( " skill cast def\n\r", ch );
send_to_char( " hr_mod dr_mod ac_mod\n\r", ch );
send_to_char( "String being one of:\n\r", ch );
send_to_char( " name short long desc spec\n\r", ch );
send_to_char( "Use [set] spec - to clear spec_fun\n\r", ch );
send_to_char( "Shopspec being one of:\n\r", ch );
send_to_char( " trade0 - trade4 profbuy profsell openhour\n\r",ch );
send_to_char( " closehour clear\n\r", ch );
return;
}
if (!is_number(arg1))
{
send_to_char("Must be a vnum for first arg.\n\r",ch);
return;
}
if ( ( pMob = get_mob_index( atoi(arg1) ) ) == NULL )
{
send_to_char( "Cannot find mob with that vnum.\n\r", ch );
return;
}
pArea=pMob->area;
if (!build_canwrite(pArea,ch,1))
return;
/*
* Snarf the value (which need not be numeric).
*/
value = is_number( arg3 ) ? atoi( arg3 ) : -1;
/* Check for act flags */
lvalue=table_lookup(tab_mob_flags,arg2);
if ( lvalue != 0 )
{
/* Then we've found a value */
if ( IS_SET( pMob->act, lvalue ) )
REMOVE_BIT( pMob->act, lvalue );
else
SET_BIT( pMob->act, lvalue );
send_to_char( "OK. Act Flag toggled.\n\r", ch );
area_modified( pArea );
return;
}
/* Check for affected_by flags */
lvalue=table_lookup( tab_affected_by, arg2 );
if ( lvalue != 0 )
{
/* Then we've found a value */
if ( IS_SET( pMob->affected_by, lvalue ) )
REMOVE_BIT( pMob->affected_by, lvalue );
else
SET_BIT( pMob->affected_by, lvalue );
send_to_char( "OK. Affected_by Flag toggled.\n\r", ch );
area_modified( pArea );
return;
}
if ( !str_cmp( arg2, "skills" ) )
{
lvalue = table_lookup( tab_mob_skill, arg3 );
if ( lvalue == 0 )
{
sprintf( buf, "You can toggle the following flags:\n\r" );
table_printout( tab_mob_skill, buf+strlen(buf) );
send_to_char( buf, ch );
return;
}
/* Toggle flag */
if ( IS_SET( pMob->skills, lvalue ) )
REMOVE_BIT( pMob->skills, lvalue );
else
SET_BIT( pMob->skills, lvalue );
send_to_char( "Ok.\n\r", ch );
area_modified( pArea );
return;
}
if ( !str_cmp( arg2, "cast" ) )
{
lvalue = table_lookup( tab_mob_cast, arg3 );
if ( lvalue == 0 )
{
sprintf( buf, "You can toggle the following flags:\n\r" );
table_printout( tab_mob_cast, buf+strlen(buf) );
send_to_char( buf, ch );
return;
}
/* Toggle flag */
if ( IS_SET( pMob->cast, lvalue ) )
REMOVE_BIT( pMob->cast, lvalue );
else
SET_BIT( pMob->cast, lvalue );
send_to_char( "Ok.\n\r", ch );
area_modified( pArea );
return;
}
if ( !str_cmp( arg2, "def" ) )
{
lvalue = table_lookup( tab_mob_def, arg3 );
if ( lvalue == 0 )
{
sprintf( buf, "You can toggle the following flags:\n\r" );
table_printout( tab_mob_def, buf+strlen(buf) );
send_to_char( buf, ch );
return;
}
/* Toggle flag */
if ( IS_SET( pMob->def, lvalue ) )
REMOVE_BIT( pMob->def, lvalue );
else
SET_BIT( pMob->def, lvalue );
send_to_char( "Ok.\n\r", ch );
area_modified( pArea );
return;
}
if ( !str_cmp( arg2, "class" ) )
{
lvalue = table_lookup( tab_mob_class, arg3 );
if ( lvalue == -1 )
{
sprintf( buf, "You can use the following classes:\n\r" );
table_printout( tab_mob_class, buf+strlen(buf) );
send_to_char(buf, ch );
return;
}
pMob->class = lvalue;
send_to_char( "Ok.\n\r", ch );
area_modified( pArea );
return;
}
if ( !str_cmp( arg2, "position" ) )
{
if ( !str_prefix( arg3, "standing" ) )
value = POS_STANDING;
else if ( !str_prefix( arg3, "resting" ) )
value = POS_RESTING;
else if ( !str_prefix( arg3, "sleeping" ) )
value = POS_SLEEPING;
else
{
send_to_char( "position must be standing, resting or sleeping.\n\r", ch );
return;
}
pMob->position = value;
area_modified( pArea );
send_to_char( "Ok.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "sex" ) )
{
value = -1;
if ( arg3[0] == 'm' && !str_prefix( arg3, "male" ) )
value = SEX_MALE;
else if ( arg3[0] == 'f' && !str_prefix( arg3, "female" ) )
value = SEX_FEMALE;
else if ( arg3[0] == 'n' && !str_prefix( arg3, "neutral" ) )
value = SEX_NEUTRAL;
if ( value == -1 )
{
send_to_char( "Must be male, female or neutral.\n\r", ch );
return;
}
pMob->sex = value;
area_modified( pArea );
return;
}
if ( !str_cmp( arg2, "level" ) )
{
if ( value < 1 || value > 140 )
{
send_to_char( "Level range is 1 to 140.\n\r", ch );
return;
}
pMob->level = value;
area_modified(pArea);
return;
}
if ( !str_cmp( arg2, "align" ) )
{
if ( value < -1000 || value > 1000 )
{
send_to_char( "Alignment range is -1000 to 1000.\n\r", ch );
return;
}
pMob->alignment = value;
area_modified(pArea);
return;
}
if ( !str_cmp( arg2, "ac_mod" ) )
{
if (value < -2500 || value > 500)
{
send_to_char( "ac_mod range is -2500 to 500.\n\r", ch );
return;
}
pMob->ac_mod = value;
area_modified(pArea);
return;
}
if ( !str_cmp( arg2, "hr_mod" ) )
{
if (value < -10 || value > 1000)
{
send_to_char( "hr_mod range is -10 to 1000.\n\r", ch );
return;
}
pMob->hr_mod = value;
area_modified(pArea);
return;
}
if ( !str_cmp( arg2, "dr_mod" ) )
{
if (value < -10 || value > 1000)
{
send_to_char( "dr_mod range is -10 to 1000.\n\r", ch );
return;
}
pMob->dr_mod = value;
area_modified(pArea);
return;
}
if ( !str_cmp( arg2, "edit" ) )
{
if ( is_name( arg3, "desc name short long" ) )
sprintf( buf, "%s %s $edit", arg1, arg3 );
else
sprintf( buf, " " );
build_setmob( ch, buf );
return;
}
if ( !str_cmp( arg2, "name" ) )
{
build_strdup(&pMob->player_name, arg3, TRUE, ch );
area_modified(pArea);
return;
}
if ( !str_cmp( arg2, "short" ) )
{
build_strdup(&pMob->short_descr, arg3, TRUE, ch );
area_modified(pArea);
return;
}
if ( !str_cmp( arg2, "long" ) )
{
build_strdup(&pMob->long_descr, arg3, TRUE, ch );
area_modified(pArea);
return;
}
if ( !str_cmp( arg2,"desc" ) )
{
build_strdup(&pMob->description, arg3, TRUE, ch);
area_modified(pArea);
return;
}
if ( !str_cmp( arg2, "spec" ) )
{
BUILD_DATA_LIST * pList;
if ( arg3[0]=='-' )
{
if (pMob->spec_fun == NULL)
return;
pMob->spec_fun = NULL;
for (pList=pArea->first_area_specfunc; pList != NULL; pList=pList->next)
{
if ( (MOB_INDEX_DATA *) pList->data == pMob)
break;
}
if (pList != NULL)
{
UNLINK(pList, pArea->first_area_specfunc,
pArea->last_area_specfunc, next, prev);
PUT_FREE(pList, build_free);
}
return;
}
if ( ( pMob->spec_fun = spec_lookup( arg3 ) ) == 0 )
{
sprintf(buf,"Valid spec funs are :\n\r");
print_spec_lookup(buf+strlen(buf));
send_to_char(buf,ch);
return;
}
/* Add to area linked list */
/* First see if there is one for this char already */
for (pList=pArea->first_area_specfunc; pList != NULL; pList=pList->next)
if ( (MOB_INDEX_DATA *) pList->data == pMob)
break;
if (pList == NULL)
{
GET_FREE(pList, build_free);
pList->data = pMob;
LINK(pList, pArea->first_area_specfunc,
pArea->last_area_specfunc, next, prev);
}
area_modified(pArea);
return;
}
if ( !str_cmp( arg2, "shop" ) )
{
SHOP_DATA * pShop;
BUILD_DATA_LIST * pList;
int iTrade;
argument=one_argument(argument,arg3);
strcpy( arg4, argument );
pArea=pMob->area;
pShop=pMob->pShop;
if ( !str_cmp(arg3, "clear") )
{
if (pShop!=NULL)
{
UNLINK(pShop, first_shop, last_shop, next, prev);
top_shop--; /* Reduce shop count */
for (pList=pArea->first_area_shop; pList != NULL; pList = pList->next)
{
if (pShop==pList->data)
break;
}
if (pList != NULL)
{
UNLINK(pList, pArea->first_area_shop, pArea->last_area_shop,
next, prev);
PUT_FREE(pList, build_free);
}
pMob->pShop=NULL; /* Take away link from mob */
PUT_FREE(pShop, shop_free); /* Free the memory it occupies */
}
area_modified(pArea);
return;
}
if ( (str_prefix("trade",arg3)
&& !is_name(arg3,"profbuy profsell openhour closehour") ) )
{
/* Usage message */
build_setmob( ch,"" );
return;
}
area_modified(pArea);
if (pShop==NULL)
{
GET_FREE(pShop, shop_free);
if (pShop==NULL) /* Couldn't alloc space. */
{
send_to_char( "Out of memory, please reboot ASAP.\n\r",ch);
return;
}
GET_FREE(pList, build_free);
if (pList==NULL)
{
send_to_char( "Out of memory, please reboot ASAP.\n\r",ch);
return;
}
pShop->keeper=pMob->vnum;
pMob->pShop=pShop; /* Add link to mob */
pList->data=pShop; /* Add to area list */
LINK(pList, pArea->first_area_shop, pArea->last_area_shop,
next, prev);
LINK(pShop, first_shop, last_shop, next, prev);
top_shop++; /* Increment number of shops */
for ( iTrade = 0; iTrade < MAX_TRADE; iTrade++ )
pShop->buy_type[iTrade] = 0;
pShop->profit_buy = 100;
pShop->profit_sell = 100;
pShop->open_hour = 0;
pShop->close_hour = 23;
}
if ( ! str_prefix("trade",arg3) )
{
num=arg3[5] - '0';
if (num<0 || num>MAX_TRADE)
{
sprintf(buf, "trade must be between 0 and %i\n\r",MAX_TRADE);
send_to_char(buf,ch);
return;
}
value=table_lookup(tab_item_types,arg4);
if (value==0)
{
sprintf(buf,"Item type must be one of the following:\n\r");
table_printout(tab_item_types,buf+strlen(buf));
send_to_char(buf,ch);
}
pShop->buy_type[num]=value;
return;
}
value=is_number(arg4) ? atoi(arg4) : -1;
if ( ! str_cmp("profbuy",arg3) )
{
if (value < 0)
{
send_to_char("Profbuy must be a number more than 0.\n\r",ch);
return;
}
if ( value < 100 )
{
send_to_char("WARNING: Profbuy should be over 100.\n\r",ch);
return;
}
pShop->profit_buy=value;
return;
}
if ( ! str_cmp("profsell",arg3) )
{
if ( value < 0)
{
send_to_char("Profsell must be a number more than 0.\n\r",ch);
return;
}
if ( value > 100 )
{
send_to_char("WARNING: Profsell should be over 100.\n\r",ch);
return;
}
pShop->profit_sell=value;
return;
}
if ( ! str_cmp("openhour",arg3) )
{
if ( value <0 || value > 24 )
{
send_to_char("Openhour must be a number between 0 and 24.\n\r",ch);
return;
}
pShop->open_hour=value;
return;
}
if ( ! str_cmp("closehour",arg3) )
{
if ( value <0 || value > 24 )
{
send_to_char("closehour must be a number between 0 and 24.\n\r",ch);
return;
}
pShop->close_hour=value;
return;
}
}
/*
* Generate usage message.
*/
build_setmob( ch, "" );
return;
}
/* spec: nuke any stray resets for a changed exit */
void nuke_exit_resets(ROOM_INDEX_DATA *pRoomIndex, int door)
{
BUILD_DATA_LIST *pList, *pListNext;
RESET_DATA *pReset;
AREA_DATA *pArea=pRoomIndex->area;
for (pList=pRoomIndex->first_room_reset; pList; pList=pListNext)
{
pListNext=pList->next;
pReset=pList->data;
if (pReset->command=='D' &&
pReset->arg2==door)
{
/* nuke this reset */
UNLINK(pList, pRoomIndex->first_room_reset, pRoomIndex->last_room_reset,
next, prev);
PUT_FREE(pList, build_free);
UNLINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
PUT_FREE(pReset, reset_free);
}
}
}
void build_setroom( CHAR_DATA *ch, char * argument)
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
char arg4 [MAX_INPUT_LENGTH];
char arg5 [MAX_INPUT_LENGTH];
char buf [MAX_STRING_LENGTH];
char * argn;
ROOM_INDEX_DATA *location;
int value,num;
smash_tilde( argument );
argument = one_argument( argument, arg1 );
strcpy( arg2, argument );
if ( arg1[0] == '\0' )
{
send_to_char( "Syntax: [set] <arguments> \n\r", ch );
send_to_char( " Or: [set] <string> value\n\r", ch );
send_to_char( " Or: [set] edit <string>\n\r", ch );
send_to_char( "\n\r", ch );
send_to_char( "Arguments being one of:\n\r", ch );
send_to_char( " flags +/-<ascii-flag> \n\r", ch );
send_to_char( " sector <ascii-sector-type>\n\r", ch );
send_to_char( " door <door-number> to <vnum> [onesided]\n\r", ch );
send_to_char( " keyword <string>\n\r", ch );
send_to_char( " desc <string>\n\r", ch );
send_to_char( " key <vnum> [onesided]\n\r", ch );
send_to_char( " type <ascii-type> [onesided]\n\r", ch );
send_to_char( " clear [onesided]\n\r", ch );
send_to_char( " extra <keyword> <string>\n\r", ch );
send_to_char( " extra -<keyword>\n\r", ch );
send_to_char( "String being one of:\n\r", ch );
send_to_char( " name desc\n\r", ch );
return;
}
location=get_room_index( ch->build_vnum );
if ( location == NULL )
{
send_to_char( "Invalid vnum selected!\n\r", ch );
return;
}
if (!build_canwrite(location->area,ch,1))
return;
area_modified(location->area);
/* Check for flags first, then other values... */
value = table_lookup( tab_room_flags, arg1 );
if ( value != 0 )
{
/* Flag found */
if ( IS_SET( location->room_flags, value ) )
REMOVE_BIT( location->room_flags, value );
else
SET_BIT( location->room_flags, value );
sprintf( buf, "@@WRoom flag @@y%s@@W toggled to @@y%s@@W.@@g\n\r",
rev_table_lookup( tab_room_flags, value ),
IS_SET( location->room_flags, value ) ? "ON" : "OFF" );
send_to_char( buf, ch );
return;
}
value = table_lookup( tab_sector_types, arg1 );
if ( value >= 1 )
{
/* Sector found */
location->sector_type = value;
sprintf( buf, "@@WSector type set to @@y%s@@W.@@g\n\r",
rev_table_lookup( tab_sector_types, value ) );
send_to_char( buf, ch );
return;
}
if ( !str_cmp( arg1, "edit" )
&& is_name( arg2, "name desc" ) )
{
sprintf( buf, "%s $edit", arg2 );
build_setroom( ch, buf );
return;
}
if ( !str_cmp( arg1, "name" ) )
{
build_strdup(&location->name, arg2, TRUE, ch);
return;
}
if ( !str_cmp( arg1, "desc"))
{
build_strdup(&location->description,arg2,TRUE,ch);
return;
}
if ( !str_cmp( arg1, "extra"))
{
EXTRA_DESCR_DATA *ed;
bool found;
argument=one_argument( argument, arg2);
strcpy(arg3,argument);
argn=arg2;
if (argn[0]=='-')
{
argn++;
found=FALSE;
for (ed=location->first_exdesc; ed!=NULL; ed=ed->next)
{
if (is_name(argn,ed->keyword))
{
found=TRUE;
break;
}
}
if (! found)
{
send_to_char("Keyword not found.\n\r",ch);
return;
}
/* Delete description */
free_string(ed->keyword); /* Free string memory */
free_string(ed->description);
UNLINK(ed, location->first_exdesc, location->last_exdesc,
next, prev);
PUT_FREE(ed, exdesc_free);
top_ed--;
return;
}
found=FALSE;
for (ed=location->first_exdesc; ed!=NULL; ed=ed->next)
if (is_name(arg2,ed->keyword))
{
found=TRUE;
break;
}
if (!found)
{
GET_FREE(ed, exdesc_free);
build_strdup(&ed->keyword,arg2,FALSE,ch);
build_strdup(&ed->description,arg3,FALSE,ch);
LINK(ed, location->first_exdesc, location->last_exdesc, next, prev);
top_ed++;
return;
}
build_strdup(&ed->description,arg3,TRUE,ch);
return;
}
/* spec: remove resets referring to this door if we clear the 'door'
* state
*/
if ( ! str_cmp(arg1,"door"))
{
EXIT_DATA * pExit;
int door;
char * temp;
ROOM_INDEX_DATA * pDestRoom;
EXIT_DATA * pDestExit;
argument=one_argument(argument,arg2);
argument=one_argument(argument,arg3);
strcpy(arg4,argument);
if (is_number(arg2))
door=atoi(arg2);
else
{
if ( ( temp=index( cDirs, UPPER(arg2[0]) ) ) != NULL )
door=temp-cDirs;
else
door=-1;
}
if (door<0 || door>5)
{
send_to_char("Door number must be a number between 0 and 5, or NSEWUD\n\r",ch);
return;
}
pExit=location->exit[door];
if (! str_cmp(arg3,"clear"))
{
ROOM_INDEX_DATA * pDestRoom;
if (pExit==NULL)
return;
pDestRoom=get_room_index(pExit->vnum);
if ( pDestRoom == NULL )
return;
if (!build_canwrite(pDestRoom->area,ch,0))
{
send_to_char("You cannot change this exit.",ch);
return;
}
/* Delete exit */
free_string(pExit->description);
free_string(pExit->keyword);
PUT_FREE(pExit, exit_free);
location->exit[door]=NULL;
top_exit--;
/* spec: nuke any resets for it */
nuke_exit_resets(location, door);
/* Delete corresponding exit on other side */
if (str_cmp(arg4,"onesided") && pDestRoom!=NULL)
{
pExit=pDestRoom->exit[RevDirs[door]];
if (pExit != NULL)
if (pExit->vnum == location->vnum)
{
free_string(pExit->description);
free_string(pExit->keyword);
PUT_FREE(pExit, exit_free);
pDestRoom->exit[RevDirs[door]]=NULL;
top_exit--;
/* spec: nuke any resets for it */
nuke_exit_resets(pDestRoom, RevDirs[door]);
area_modified(pDestRoom->area);
}
else
send_to_char("Note: Door in exit room does not point to this door, so not deleted.",ch);
else
send_to_char("Note: There is no corresponding exit in the room pointed to by this exit.",ch);
}
}
if (! is_name(arg3,"to key desc keyword type"))
{
build_setroom(ch,"");
return;
}
if (pExit==NULL)
{
GET_FREE(pExit, exit_free);
pExit->to_room=NULL;
pExit->vnum=0;
pExit->description=&str_empty[0];
pExit->keyword=&str_empty[0];
pExit->exit_info=0;
pExit->key=-1;
top_exit++;
location->exit[door]=pExit;
}
pDestRoom=pExit->to_room; /* Setup pDestRoom to point to dest. room */
if ( pDestRoom != NULL )
{
pDestExit=pDestRoom->exit[RevDirs[door]]; /* Setup pDestExit to exit from DestRoom to here. */
if (pDestExit != NULL && pDestExit->to_room != location)
pDestExit=NULL;
}
else
pDestExit=NULL;
if (! str_cmp(arg3,"to"))
{
ROOM_INDEX_DATA * pRoom;
argument=one_argument(argument,arg4);
argument=one_argument(argument,arg5);
if (!is_number(arg4))
{
send_to_char("Room number must be a vnum\n\r",ch);
return;
}
value=atoi(arg4);
if ( !(pRoom=get_room_index(value)))
{
send_to_char("No such vnum.\n\r",ch);
return;
}
if ( !build_canwrite(pRoom->area,ch,0))
{
send_to_char("You cannot connect to this room.\n\r",ch);
return;
}
if ( pDestRoom != NULL
&& !build_canwrite(pDestRoom->area,ch,0) )
{
send_to_char("You cannot change the destination of this exit.",ch);
return;
}
if (str_cmp(arg5,"onesided")) /* If NOT onesided, do checks */
{
if ( pDestRoom != NULL && pDestExit != NULL) /* If already connected */
{
free_string(pDestExit->description);
free_string(pDestExit->keyword);
PUT_FREE(pDestExit, exit_free);
pDestRoom->exit[RevDirs[door]]=NULL;
top_exit--;
/* spec: nuke exit resets */
nuke_exit_resets(pDestRoom, RevDirs[door]);
}
if ( !(pDestExit=pRoom->exit[RevDirs[door]])) /* If exit hasn't been made on other side */
{
/* Create door coming other way. */
GET_FREE(pDestExit, exit_free);
pDestExit->to_room=location;
pDestExit->vnum=location->vnum;
pDestExit->description=&str_empty[0];
build_strdup(&pDestExit->keyword,pExit->keyword,FALSE,ch);
pDestExit->exit_info=pExit->exit_info;
pDestExit->key=pExit->exit_info;
top_exit++;
pRoom->exit[RevDirs[door]]=pDestExit;
area_modified(pRoom->area);
}
if ( pDestExit->to_room != location )
{
sprintf(buf,"The door in room %i going %s points to room [%i] %s.\n\r",
value,
sDirs[RevDirs[door]],
pDestExit->vnum,
pDestExit->to_room != NULL ? pDestExit->to_room->name : ""
);
send_to_char(buf,ch);
}
}
pExit->vnum = value;
pExit->to_room = pRoom;
return;
}
if (! str_cmp(arg3,"keyword") )
{
build_strdup(&pExit->keyword,arg4,TRUE,ch);
return;
}
if (! str_cmp(arg3,"desc"))
{
build_strdup(&pExit->description,arg4,TRUE,ch);
return;
}
if (! str_cmp(arg3,"key"))
{
OBJ_INDEX_DATA * pObject;
argument=one_argument(argument,arg4);
argument=one_argument(argument,arg5);
if (arg4[0]=='\0')
{
pExit->key=-1;
return;
}
if (!is_number(arg4))
{
send_to_char("Object number must be a vnum, or blank.\n\r",ch);
return;
}
if ( !(pObject=get_obj_index(atoi(arg4))))
{
send_to_char("No such vnum.\n\r",ch);
return;
}
pExit->key = pObject->vnum;
if (pDestExit && str_cmp(arg5,"onesided"))
pDestExit->key = pObject->vnum;
return;
}
if (! str_cmp(arg3,"type"))
{
argument=one_argument(argument,arg4);
argument=one_argument(argument,arg5);
/* Make SURE that closed/locked flags are NOT set. -S- */
/* Resets set these bits, nothing else :P */
argn=arg4;
num=1;
if (argn[0]=='-')
{
num=0;
argn++;
}
if (argn[0]=='+')
{
num=1;
argn++;
}
value=table_lookup(tab_door_types,argn);
if (value==0)
{
sprintf(buf,"Possible door types are +/-:\n\r");
table_printout(tab_door_types,buf+strlen(buf));
send_to_char(buf,ch);
return;
}
if ( value == EX_CLOSED || value == EX_LOCKED )
{
send_to_char( "To CLOSE or LOCK a door, use a reset.\n\r", ch );
return;
}
if (num==1)
{
if (pDestExit && str_cmp(arg5,"onesided"))
{
SET_BIT(pDestExit->exit_info,value);
area_modified(pDestRoom->area);
}
SET_BIT(pExit->exit_info,value);
}
else
{
if (pDestExit && str_cmp(arg5,"onesided"))
{
REMOVE_BIT(pDestExit->exit_info,value);
if (IS_SET(value, EX_ISDOOR))
nuke_exit_resets(pDestRoom, RevDirs[door]);
area_modified(pDestRoom->area);
}
REMOVE_BIT(pExit->exit_info,value);
if (IS_SET(value, EX_ISDOOR))
nuke_exit_resets(location, door);
}
return;
}
}
/*
* Generate usage message.
*/
build_setroom( ch, "" );
return;
}
void build_setobject( CHAR_DATA *ch, char *argument )
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
char buf [MAX_STRING_LENGTH];
char * argn;
OBJ_INDEX_DATA * pObj;
AREA_DATA *pArea;
int value,num;
smash_tilde( argument );
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
strcpy( arg3, argument );
if ( arg1[0] == '\0' || arg2[0] == '\0' )
{
send_to_char( "Syntax: [set] <field> <value>\n\r", ch );
send_to_char( "or: [set] <string> <value>\n\r", ch );
send_to_char( "\n\r", ch );
send_to_char( "Field being one of:\n\r", ch );
send_to_char( " value0 value1 value2 value3\n\r", ch );
send_to_char( " level extra wear weight aff type\n\r", ch );
send_to_char( "\n\r", ch );
send_to_char( "String being one of:\n\r", ch );
send_to_char( " name short long ed objfun\n\r", ch );
send_to_char( "Use [set] objfun - to clear objfun.\n\r", ch );
return;
}
if ( ( pObj = get_obj_index( atoi(arg1) ) ) == NULL )
{
send_to_char( "Vnum not found.\n\r", ch );
return;
}
pArea = pObj->area;
if (!build_canwrite(pArea,ch,1))
return;
/* Check for extra flag: clan_eq */
if ( IS_SET( pObj->extra_flags, ITEM_CLAN_EQ ) && get_trust(ch) != 85 )
{
send_to_char( "Only a Creator can set Clan-Eq.\n\r", ch );
return;
}
area_modified(pObj->area);
/*
* Snarf the value (which need not be numeric).
*/
value = atol( arg3 );
/*
* Set something.
*/
if ( !str_prefix("value",arg2))
{
num=arg2[5]-'0';
if (num<0 || num>3)
{
send_to_char("Value0/1/2/3.\n\r",ch);
return;
}
pObj->value[num]=value;
return;
}
if ( !str_cmp( arg2, "level" ) )
{
if ( value < 1 || value > 120 )
{
send_to_char( "item level is 1 to 120.\n\r", ch );
return;
}
pObj->level = value;
return;
}
if ( UPPER(arg2[0])=='V' && arg2[2]=='\0')
{
num=arg2[1]-'0';
if ( num<0 || num>3)
{
send_to_char("v0/v1/v2/v3.\n\r",ch);
return;
}
pObj->value[num]=value;
return;
}
if ( !str_cmp( arg2, "objfun" ) )
{
BUILD_DATA_LIST * pList;
if ( arg3[0]=='-' )
{
if (pObj->obj_fun == NULL)
return;
pObj->obj_fun = NULL;
for (pList=pArea->first_area_objfunc; pList != NULL; pList=pList->next)
{
if ( (OBJ_INDEX_DATA *) pList->data == pObj)
break;
}
if (pList != NULL)
{
UNLINK(pList, pArea->first_area_objfunc, pArea->last_area_objfunc,
next, prev);
PUT_FREE(pList, build_free);
}
return;
}
if ( ( pObj->obj_fun = obj_fun_lookup( arg3 ) ) == 0 )
{
sprintf(buf,"Valid obj funs are :\n\r");
print_obj_fun_lookup(buf+strlen(buf));
send_to_char(buf,ch);
return;
}
/* Add to area linked list */
/* First see if there is one for this char already */
for (pList=pArea->first_area_objfunc; pList != NULL; pList=pList->next)
if ( (OBJ_INDEX_DATA *) pList->data == pObj)
break;
if (pList == NULL)
{
GET_FREE(pList, build_free);
pList->data = pObj;
LINK(pList, pArea->first_area_objfunc, pArea->last_area_objfunc,
next, prev);
}
area_modified(pArea);
return;
}
if ( !str_cmp( arg2, "extra" ) )
{
num=1;
argn=arg3;
if (argn[0]=='+')
{
num=1;
argn++;
}
if (argn[0]=='-')
{
num=0;
argn++;
}
value=table_lookup(tab_obj_flags,argn);
if (value==0)
{
sprintf(buf,"Values for extra flags are +/- :\n\r");
table_printout(tab_obj_flags,buf+strlen(buf));
send_to_char(buf,ch);
return;
}
if (num==1)
SET_BIT(pObj->extra_flags,value);
else
REMOVE_BIT(pObj->extra_flags,value);
return;
}
if ( !str_cmp( arg2, "magic" ) )
{
num=1;
argn = arg3;
if ( argn[0] == '+' )
argn++;
if ( argn[0] == '-' )
{
num=0;
argn++;
}
value = table_lookup(tab_item_apply, argn );
if ( value == 0 )
{
sprintf( buf, "Values for magical applies are +/- :\n\r" );
table_printout( tab_item_apply, buf+strlen(buf) );
send_to_char( buf, ch );
return;
}
if ( num == 1 )
SET_BIT( pObj->item_apply, value );
else
REMOVE_BIT( pObj->item_apply, value );
return;
}
if ( !str_cmp( arg2, "wear" ) )
{
num=1;
argn=arg3;
if (argn[0]=='+')
{
num=1;
argn++;
}
if (argn[0]=='-')
{
num=0;
argn++;
}
value=table_lookup(tab_wear_flags,argn);
if (value==0)
{
sprintf(buf,"Values for wear flags are +/- :\n\r");
table_printout(tab_wear_flags,buf+strlen(buf));
send_to_char(buf,ch);
return;
}
if (num==1)
SET_BIT(pObj->wear_flags,value);
else
REMOVE_BIT(pObj->wear_flags,value);
return;
}
if ( !str_cmp( arg2, "type" ) )
{
value=table_lookup(tab_item_types,arg3);
if (value==0)
{
sprintf(buf,"Values for item types are :\n\r");
table_printout(tab_item_types,buf+strlen(buf));
send_to_char(buf,ch);
return;
}
if ( value == ITEM_CLAN_EQ && get_trust(ch) != 85 )
{
send_to_char( "Only a CREATOR may set this flag.\n\r", ch );
return;
}
pObj->item_type=value;
return;
}
if ( !str_cmp( arg2, "weight" ) )
{
pObj->weight = value;
return;
}
if ( !str_cmp( arg2, "name" ) )
{
build_strdup(&pObj->name,arg3,TRUE,ch);
return;
}
if ( !str_cmp( arg2, "short" ) )
{
build_strdup(&pObj->short_descr,arg3,TRUE,ch);
return;
}
if ( !str_cmp( arg2, "long" ) )
{
build_strdup(&pObj->description,arg3,TRUE,ch);
return;
}
if ( !str_cmp( arg2, "ed" ) )
{
EXTRA_DESCR_DATA *ed;
int found;
argument = one_argument( argument, arg3 );
if ( argument == NULL )
{
send_to_char( "Syntax: setobject <object> ed [-]<keyword> <string>\n\r",
ch );
return;
}
if (arg3[0]=='-')
{
/* Find and delete keyword */
argn=arg3+1;
found=FALSE;
for (ed=pObj->first_exdesc;ed != NULL;ed=ed->next)
{
if (is_name(argn,ed->keyword))
{
found=TRUE;
break;
}
}
if (!found)
{
send_to_char("Keyword not found.\n\r",ch);
return;
}
UNLINK(ed, pObj->first_exdesc, pObj->last_exdesc, next, prev);
free_string(ed->keyword); /* Free string memory */
free_string(ed->description);
PUT_FREE(ed, exdesc_free);
return;
}
GET_FREE(ed, exdesc_free);
build_strdup(&ed->keyword,arg3,FALSE,ch);
build_strdup(&ed->description,argument,FALSE,ch);
LINK(ed, pObj->first_exdesc, pObj->last_exdesc, next, prev);
return;
}
if ( !str_cmp( arg2, "aff" ) )
{
AFFECT_DATA *paf;
int found,location,neg;
argument = one_argument( argument, arg3 );
if ( argument == NULL )
{
send_to_char( "Syntax: setobject <object> aff [-]<location> <mod>\n\r",
ch );
return;
}
argn=arg3;
neg=0;
if (argn[0]=='-')
{
neg=1;
argn++;
}
location=table_lookup(tab_obj_aff,argn);
if (location==0)
{
sprintf(buf,"Location can be one of the following [-]:\n\r");
table_printout(tab_obj_aff,buf+strlen(buf));
send_to_char(buf,ch);
return;
}
found=FALSE;
for (paf=pObj->first_apply;paf != NULL;paf=paf->next)
{
if (paf->location==location)
{
found=TRUE;
break;
}
}
if (neg==1)
{
if (!found)
{
send_to_char("Location not found.\n\r",ch);
return;
}
UNLINK(paf, pObj->first_apply, pObj->last_apply, next, prev);
PUT_FREE(paf, affect_free); /* Put on free list */
return;
}
if (!found)
{
GET_FREE(paf, affect_free);
paf->location = location;
paf->modifier = atoi(argument);
LINK(paf, pObj->first_apply, pObj->last_apply, next, prev);
}
else
paf->modifier = atoi(argument);
return;
}
/*
* Generate usage message.
*/
build_setobject( ch, "" );
return;
}
void build_dig( CHAR_DATA *ch, char *argument )
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
char buffer[MAX_INPUT_LENGTH];
ROOM_INDEX_DATA *pRoomIndex;
ROOM_INDEX_DATA *pCurRoom;
int vnum,dir;
char * temp;
int iHash;
int door;
EXIT_DATA * pExit;
BUILD_DATA_LIST * pList;
AREA_DATA * pArea;
smash_tilde( argument );
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
strcpy( arg3, argument );
if ( arg1[0] == '\0' || arg2[0] == '\0')
{
send_to_char( "Syntax: dig <dir> <vnum> [onesided]\n\r", ch );
return;
}
if (! (temp=index(cDirs,UPPER(arg1[0]))) )
{
send_to_char( "Direction must be one of NSEWUP\n\r",ch);
return;
}
dir=temp-cDirs;
if ( ch->in_room->exit[dir] != NULL)
{
send_to_char( "There is already an exit in that direction\n.",ch);
return;
}
vnum=is_number(arg2) ? atoi(arg2) : -1;
if (vnum<0 || vnum > MAX_VNUM )
{
send_to_char( "Vnum must be between 0 and 32767.\n\r",ch);
return;
}
if (get_room_index(vnum) != NULL)
{
send_to_char( "There is already a room with that vnum.\n\r",ch);
return;
}
pCurRoom=ch->in_room;
pArea=pCurRoom->area;
if (!build_canwrite(pArea,ch,1))
return;
if (vnum < pArea->min_vnum || vnum > pArea->max_vnum)
{
sprintf(buffer,"Vnum must be between %i and %i.\n\r",pArea->min_vnum, pArea->max_vnum);
send_to_char(buffer,ch);
return;
}
/* Create room */
GET_FREE(pRoomIndex, rid_free);
pRoomIndex->first_person = NULL;
pRoomIndex->last_person = NULL;
pRoomIndex->first_content = NULL;
pRoomIndex->last_content = NULL;
pRoomIndex->first_exdesc = NULL;
pRoomIndex->last_exdesc = NULL;
pRoomIndex->area = pCurRoom->area;
pRoomIndex->vnum = vnum;
pRoomIndex->name = str_dup("New room");
pRoomIndex->description = str_dup("No description");
pRoomIndex->room_flags = 0;
pRoomIndex->sector_type = pCurRoom->sector_type;
pRoomIndex->light = 0;
for ( door = 0; door <= 5; door++ )
pRoomIndex->exit[door] = NULL;
pRoomIndex->first_room_reset = NULL;
pRoomIndex->last_room_reset = NULL;
/* Add room to hash table */
iHash = vnum % MAX_KEY_HASH;
SING_TOPLINK(pRoomIndex, room_index_hash[iHash], next);
/* Add room into area list. */
GET_FREE(pList, build_free);
pList->data = pRoomIndex;
LINK(pList, pCurRoom->area->first_area_room,
pCurRoom->area->last_area_room, next, prev);
top_room++;
/* Create door */
GET_FREE(pExit, exit_free);
pExit->to_room=pRoomIndex;
pExit->vnum=vnum;
pExit->description=&str_empty[0];
pExit->keyword=&str_empty[0];
pExit->exit_info=0;
pExit->key=-1;
top_exit++;
pCurRoom->exit[dir]=pExit;
if ( str_cmp(arg3,"onesided")) /* If NOT onesided */
{
GET_FREE(pExit, exit_free);
pExit->to_room=pCurRoom;
pExit->vnum=pCurRoom->vnum;
pExit->description=&str_empty[0];
pExit->keyword=&str_empty[0];
pExit->exit_info=0;
pExit->key=-1;
top_exit++;
pRoomIndex->exit[RevDirs[dir]]=pExit;
}
return;
}
void build_stop( CHAR_DATA *ch, char *argument )
{
ch->position=POS_STANDING;
send_to_char( "Building stopped.\n\r", ch );
}
void do_build( CHAR_DATA *ch, char *argument )
{
if ( !IS_SET( ch->act, PLR_BUILDER ) )
{
send_to_char( "You aren't allowed to build!\n\r", ch );
return;
}
ch->position=POS_BUILDING;
do_help( ch, "build_bmotd" ); /* motd for builders -S- */
send_to_char("Building commands are now operative. Type stop to stop building.\n\r",ch);
}
void build_addmob( CHAR_DATA *ch, char *argument )
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char buffer[MAX_INPUT_LENGTH];
MOB_INDEX_DATA * pMobIndex;
/* ROOM_INDEX_DATA *room; unused */
AREA_DATA * pArea;
BUILD_DATA_LIST * pList;
int vnum;
int iHash;
smash_tilde( argument );
argument = one_argument( argument, arg1 );
strcpy( arg2, argument );
if ( arg1[0] == '\0' || arg2[0] == '\0')
{
send_to_char( "Syntax: addmob <vnum> <name>\n\r", ch );
return;
}
vnum=is_number(arg1) ? atoi(arg1) : -1;
if (vnum<0 || vnum > 32767 )
{
send_to_char( "Vnum must be between 0 and 32767.\n\r",ch);
return;
}
if (get_mob_index(vnum) != NULL)
{
send_to_char( "There is already a mob with that vnum.\n\r",ch);
return;
}
pArea=ch->in_room->area; /* bugger. this might need fixing!! */
if (!build_canwrite(pArea,ch,1))
return;
if (vnum < pArea->min_vnum || vnum > pArea->max_vnum)
{
sprintf(buffer,"Vnum must be between %i and %i.\n\r",pArea->min_vnum, pArea->max_vnum);
send_to_char(buffer,ch);
return;
}
ch->build_vnum = vnum;
ch->act_build = ACT_BUILD_MEDIT;
GET_FREE(pMobIndex, mid_free);
pMobIndex->vnum = vnum;
pMobIndex->area = pArea;
pMobIndex->player_name = str_dup(arg2);
pMobIndex->short_descr = &str_empty[0];
pMobIndex->long_descr = &str_empty[0];
pMobIndex->description = &str_empty[0];
pMobIndex->act = ACT_IS_NPC;
pMobIndex->affected_by = 0;
pMobIndex->pShop = NULL;
pMobIndex->alignment = 0;
pMobIndex->level = 1;
pMobIndex->sex = SEX_MALE;
pMobIndex->ac_mod = 0;
pMobIndex->hr_mod = 0;
pMobIndex->dr_mod = 0;
pMobIndex->spec_fun = NULL;
pMobIndex->pShop = NULL;
pMobIndex->count = 0;
pMobIndex->killed = 0;
pMobIndex->target = NULL;
pMobIndex->first_mprog = NULL;
pMobIndex->last_mprog = NULL;
pMobIndex->progtypes = 0;
iHash = vnum % MAX_KEY_HASH;
SING_TOPLINK(pMobIndex, mob_index_hash[iHash], next);
GET_FREE(pList, build_free);
pList->data = pMobIndex;
LINK(pList, pArea->first_area_mobile, pArea->last_area_mobile,
next, prev);
top_mob_index++;
kill_table[URANGE(0, pMobIndex->level, MAX_LEVEL-1)].number++;
return;
}
void build_addobject( CHAR_DATA *ch, char *argument )
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char buffer[MAX_INPUT_LENGTH];
OBJ_INDEX_DATA * pObjIndex;
AREA_DATA * pArea;
BUILD_DATA_LIST *pList;
int vnum;
int iHash;
smash_tilde( argument );
argument = one_argument( argument, arg1 );
strcpy( arg2, argument );
if ( arg1[0] == '\0' || arg2[0] == '\0')
{
send_to_char( "Syntax: addobject <vnum> <name>\n\r", ch );
return;
}
vnum=is_number(arg1) ? atoi(arg1) : -1;
if (vnum<0 || vnum > 32767 )
{
send_to_char( "Vnum must be between 0 and 32767.\n\r",ch);
return;
}
if (get_obj_index(vnum) != NULL)
{
send_to_char( "There is already an object with that vnum.\n\r",ch);
return;
}
pArea=ch->in_room->area;
if (!build_canwrite(pArea,ch,1))
return;
if (vnum < pArea->min_vnum || vnum > pArea->max_vnum)
{
sprintf(buffer,"Vnum must be between %i and %i.\n\r",pArea->min_vnum, pArea->max_vnum);
send_to_char(buffer,ch);
return;
}
ch->build_vnum = vnum;
ch->act_build = ACT_BUILD_OEDIT;
GET_FREE(pObjIndex, oid_free);
pObjIndex->vnum = vnum;
pObjIndex->area = pArea;
pObjIndex->name = str_dup(arg2);
pObjIndex->short_descr = &str_empty[0];
pObjIndex->description = &str_empty[0];
pObjIndex->owner = &str_empty[0];
pObjIndex->level = 1;
pObjIndex->item_type = 1;
pObjIndex->extra_flags = 0;
pObjIndex->wear_flags = 0;
pObjIndex->item_apply = 1;
pObjIndex->value[0] = 0;
pObjIndex->value[1] = 0;
pObjIndex->value[2] = 0;
pObjIndex->value[3] = 0;
pObjIndex->weight = 1;
pObjIndex->cost = 0;
pObjIndex->first_exdesc = NULL;
pObjIndex->last_exdesc = NULL;
pObjIndex->first_apply = NULL;
pObjIndex->last_apply = NULL;
iHash = vnum % MAX_KEY_HASH;
SING_TOPLINK(pObjIndex, obj_index_hash[iHash], next);
GET_FREE(pList, build_free);
pList->data = pObjIndex;
LINK(pList, pArea->first_area_object, pArea->last_area_object,
next, prev);
top_obj_index++;
return;
}
void build_addreset( CHAR_DATA *ch, char *argument )
{
RESET_DATA * pReset;
RESET_DATA * pMobReset;
BUILD_DATA_LIST * pList;
BUILD_DATA_LIST * pMobList;
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
char arg4 [MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
char command;
int rarg1,rarg2,rarg3;
char *rauto = "";
ROOM_INDEX_DATA * pRoomIndex;
int vnum,num;
int found;
char * temp;
AREA_DATA * pArea;
MOB_INDEX_DATA * pMob;
OBJ_INDEX_DATA * pObj;
EXIT_DATA *pExit;
smash_tilde( argument );
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
argument = one_argument( argument, arg3 );
argument = one_argument( argument, arg4 );
if ( arg1[0] == '\0' || (arg2[0] == '\0' && strcmp( arg1, "message" ) ) )
{
send_to_char( "addreset mob <vnum> <limit>\n\r", ch );
send_to_char( " obj <vnum>\n\r", ch );
send_to_char( " equip <n.mob-vnum> <obj-vnum> <location>\n\r", ch );
send_to_char( " give <n.mob-vnum> <obj-vnum>\n\r", ch );
send_to_char( " door <dir> <state>\n\r", ch );
send_to_char( " rand <num-dirs>\n\r", ch );
send_to_char( " message <min_lev> <max_lev> <text>\n\r", ch );
return;
}
if (! is_name(arg1,"mob obj equip message give door rand"))
{
build_addreset(ch,"");
return;
}
command='*';
rarg1=0; rarg2=0; rarg3=0;
pRoomIndex=ch->in_room;
pArea=pRoomIndex->area;
pMobReset=NULL;
pMobList=NULL;
if (!build_canwrite(pArea,ch,1))
return;
if (! str_cmp(arg1,"mob"))
{
vnum=is_number(arg2) ? atoi(arg2) : -1;
if (vnum<0 || vnum > MAX_VNUM)
{
sprintf(buf,"Vnum must be between 0 and %i.\n\r",MAX_VNUM);
send_to_char(buf,ch);
return;
}
if (! (pMob=get_mob_index(vnum)))
{
send_to_char("Mob not found.\n\r",ch);
return;
}
if (!build_canread(pMob->area,ch,0))
{
send_to_char("You cannot use that mob.\n\r",ch);
return;
}
num=is_number(arg3) ? atoi(arg3) : -1;
if (num<0)
{
send_to_char("Limit must be a number more than 0.\n\r",ch);
return;
}
command='M';
rarg1=vnum;
rarg2=num;
rarg3=pRoomIndex->vnum;
}
if ( !str_cmp( arg1, "message" ) )
{
if (!is_number(arg2) || !is_number(arg3) )
{
send_to_char( "Must specify TWO levels: min and max before message.\n\r", ch );
return;
}
rarg1 = pRoomIndex->vnum;
rarg2 = atoi(arg2);
rarg3 = atoi(arg3);
rauto = str_dup(arg4);
command = 'A';
}
if (! str_cmp(arg1,"obj"))
{
vnum=is_number(arg2) ? atoi(arg2) : -1;
if (vnum<0 || vnum > MAX_VNUM)
{
sprintf(buf,"Vnum must be between 0 and %i.\n\r",MAX_VNUM);
send_to_char(buf,ch);
return;
}
if (! (pObj=get_obj_index(vnum)) )
{
send_to_char("Object not found.\n\r",ch);
return;
}
if (! build_canread(pObj->area,ch,0))
{
send_to_char("You cannot use that object.\n\r",ch);
return;
}
if ( IS_SET(pObj->extra_flags, ITEM_CLAN_EQ ) && !IS_IMMORTAL( ch ) )
{
send_to_char( "You can't use that object for a reset.\n\r", ch );
return;
}
command='O';
rarg1=vnum;
rarg2=0;
rarg3=pRoomIndex->vnum;
}
if (! str_cmp(arg1,"equip"))
{
num=number_argument(arg2,buf);
if (num==0)
{
send_to_char("Count portion of vnum cannot be 0.\n\r",ch);
return;
}
vnum=is_number(buf) ? atoi(buf) : -1;
found=num;
for (pMobList=pRoomIndex->first_room_reset;pMobList != NULL; pMobList=pMobList->next)
{
pMobReset=pMobList->data;
if (pMobReset->command=='M' && pMobReset->arg1==vnum)
{
found--;
if (found==0) break;
}
}
if (found==num)
{
send_to_char("None of that mob loaded in the room resets.\n\r",ch);
return;
}
if (found>0)
{
send_to_char("Not enough of that mob loaded in the room resets.\n\r",ch);
return;
}
vnum=is_number(arg3) ? atoi(arg3) : -1;
if (! (pObj=get_obj_index(vnum)) )
{
send_to_char("Object not found.\n\r",ch);
return;
}
if ( IS_SET(pObj->extra_flags, ITEM_CLAN_EQ ) && !IS_IMMORTAL( ch ) )
{
send_to_char( "You can't use that object for a reset.\n\r", ch );
return;
}
if (!build_canread(pObj->area,ch,0))
{
send_to_char("You cannot use that object.\n\r",ch);
return;
}
rarg1=vnum;
num=table_lookup(tab_wear_loc,arg4);
if (num==-2)
{
sprintf(buf,"Location must be one of the following:\n\r");
table_printout(tab_wear_loc,buf+strlen(buf));
send_to_char(buf,ch);
return;
}
rarg2=0;
rarg3=num;
command='E';
}
if (! str_cmp(arg1,"give"))
{
num=number_argument(arg2,buf);
if (num==0)
{
send_to_char("Count portion of vnum cannot be 0.\n\r",ch);
return;
}
vnum=is_number(buf) ? atoi(buf) : -1;
found=num;
for (pMobList=pRoomIndex->first_room_reset;pMobList != NULL; pMobList=pMobList->next)
{
pMobReset=pMobList->data;
if (pMobReset->command=='M' && pMobReset->arg1==vnum)
{
found--;
if (found==0) break;
}
}
if (found==num)
{
send_to_char("None of that mob loaded in the room resets.\n\r",ch);
return;
}
if (found>0)
{
send_to_char("Not enough of that mob loaded in the room resets.\n\r",ch);
return;
}
vnum=is_number(arg3) ? atoi(arg3) : -1;
if (! (pObj=get_obj_index(vnum)) )
{
send_to_char("Object not found.\n\r",ch);
return;
}
if ( IS_SET(pObj->extra_flags, ITEM_CLAN_EQ ) && !IS_IMMORTAL( ch ) )
{
send_to_char( "You can't use that object for a reset.\n\r", ch );
return;
}
if (!build_canread(pObj->area,ch,0))
{
send_to_char("You cannot use that object.\n\r",ch);
return;
}
rarg1=vnum;
rarg2=0;
rarg3=0;
command='G';
}
if (! str_cmp(arg1,"door"))
{
temp=index(cDirs,UPPER(arg2[0]));
if (!temp)
{
send_to_char("Direction must be one of NSEWUP.\n\r", ch);
return;
}
rarg1=pRoomIndex->vnum;
rarg2=temp-cDirs;
if ((pExit=pRoomIndex->exit[rarg2])==NULL ||
!IS_SET(pExit->exit_info, EX_ISDOOR))
{
send_to_char("That exit isn't a door.\n\r", ch);
return;
}
num=table_lookup(tab_door_states,arg3);
if (num<0)
{
sprintf(buf,"Door state can be one of the following:\n\r");
table_printout(tab_door_states,buf+strlen(buf));
send_to_char(buf,ch);
return;
}
rarg3=num;
command='D';
}
if (! str_cmp(arg1,"rand"))
{
num=is_number(arg2) ? atoi(arg2) : -1;
if (num<1 || num>6)
{
send_to_char("Number of doors must be from 1 to 6.\n\r",ch);
return;
}
rarg1=pRoomIndex->vnum;
rarg2=num;
command='R';
}
if (command=='*')
{
bug("build_addreset: Shouldn't have come this far.\n\r",0);
build_addreset(ch,"");
return;
}
/* Now create new pReset */
GET_FREE(pReset, reset_free);
pReset->command=command;
pReset->arg1=rarg1;
pReset->arg2=rarg2;
pReset->arg3=rarg3;
if ( command == 'A' )
pReset->notes = rauto;
GET_FREE(pList, build_free);
pList->data=pReset;
if (pMobReset != NULL)
{
pReset->next=pMobReset->next;
pMobReset->next=pReset;
pReset->prev = pMobReset;
if ( pReset->next )
pReset->next->prev = pReset;
else
pRoomIndex->area->last_reset = pReset;
pList->next=pMobList->next;
pMobList->next=pList;
pList->prev = pMobList;
if ( pList->next )
pList->next->prev = pList;
else
pRoomIndex->last_room_reset = pList;
}
else
{
pArea=pRoomIndex->area;
LINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
LINK(pList, pRoomIndex->first_room_reset, pRoomIndex->last_room_reset,
next, prev);
}
area_modified( pArea );
return;
}
/* spec: rewrote the internals of this, it might work somewhat more reliably
* now :) .. please, someone put the reset lists out of their misery.. */
void build_delreset( CHAR_DATA *ch, char *argument )
{
RESET_DATA * pReset;
BUILD_DATA_LIST * pList;
BUILD_DATA_LIST * pNextList;
char arg1 [MAX_INPUT_LENGTH];
ROOM_INDEX_DATA * pRoomIndex;
int found;
AREA_DATA * pArea;
smash_tilde( argument );
argument = one_argument( argument, arg1 );
if ( arg1[0] == '\0' || !is_number(arg1))
{
send_to_char( "delreset <reset-number> (type showresets for numbers)\n\r",
ch );
return;
}
found=atoi(arg1);
if (found<=0)
{
send_to_char( "Reset number must be more than 0.\n\r",ch);
return;
}
pReset=NULL;
pRoomIndex=ch->in_room;
pArea=pRoomIndex->area;
if (!build_canwrite(pArea,ch,1))
return;
for (pList=pRoomIndex->first_room_reset; pList; pList=pList->next)
if (--found==0)
break;
if (found > 0 || !pList)
{
send_to_char("Could not find reset.\n\r",ch);
return;
}
pReset=pList->data;
if (!pReset)
{
bugf("delreset: pList returned null in search for reset number %d",
atoi(arg1));
send_to_char("bug: Could not do deletion.\n\r",ch);
return;
}
pArea=pRoomIndex->area;
/* Special for MOB resets, also take out following resets. */
if (pReset->command=='M')
{
pNextList = pList->next;
/* free the mob reset */
UNLINK(pList, pRoomIndex->first_room_reset,
pRoomIndex->last_room_reset, next, prev);
PUT_FREE(pList, build_free);
UNLINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
PUT_FREE(pReset, reset_free);
/* free any give/equip resets following it */
for (pList=pNextList; pList; pList=pNextList)
{
pNextList=pList->next;
if (pReset->command!='E' && pReset->command!='G')
break;
UNLINK(pList, pRoomIndex->first_room_reset,
pRoomIndex->last_room_reset, next, prev);
PUT_FREE(pList, build_free);
UNLINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
PUT_FREE(pReset, reset_free);
}
}
else
{
/* Just get rid of the one reset */
pNextList=pList->next;
UNLINK(pList, pRoomIndex->first_room_reset, pRoomIndex->last_room_reset,
next, prev);
PUT_FREE(pList, build_free);
UNLINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
PUT_FREE(pReset, reset_free);
}
send_to_char("Done.\n\r",ch);
return;
}
void build_delwarn( CHAR_DATA *ch, char *argument )
{
send_to_char("You must spell out delroom, delobject or delmobile in full.\n\r",ch);
return;
}
void build_delroom( CHAR_DATA *ch, char *argument )
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
ROOM_INDEX_DATA * pRoomIndex;
AREA_DATA * pArea;
BUILD_DATA_LIST * pList;
int vnum;
static int old_vnum=0;
smash_tilde( argument );
argument = one_argument( argument, arg1 );
strcpy( arg2, argument );
if ( arg1[0] == '\0')
{
send_to_char( "Syntax: delroom <vnum>\n\r", ch );
return;
}
if (is_number(arg1))
{
vnum=atoi(arg1);
if (! (pRoomIndex = get_room_index(vnum)))
{
send_to_char( "Vnum not found.\n\r", ch);
return;
}
if (!build_canwrite(pRoomIndex->area,ch,1))
return;
if ( (pRoomIndex->first_person) != NULL)
{
send_to_char( "You cannot delete the room while people are in it!.\n\r",ch);
return;
}
old_vnum=vnum;
sprintf(buf, "Are you sure you want to delete room [%d] %s?\n\r",vnum,pRoomIndex->name);
strcat(buf,"Type delroom ok if you are sure.\n\r");
send_to_char(buf,ch);
return;
}
if ( str_cmp(arg1,"ok")) /* arg1 is NOT ok. */
{
/* Usage message */
build_delroom( ch, "");
return;
}
if ( old_vnum == 0)
{
send_to_char( "First specify a room number.\n\r",ch);
return;
}
/* Now do deletion *gulp* */
vnum=old_vnum;
old_vnum=0;
pRoomIndex = get_room_index(vnum);
pArea=pRoomIndex->area;
{
/* 'purge' room */
CHAR_DATA *victim;
CHAR_DATA *vnext;
OBJ_DATA *obj;
OBJ_DATA *obj_next;
for ( victim = pRoomIndex->first_person; victim != NULL; victim = vnext )
{
vnext = victim->next_in_room;
if ( IS_NPC(victim) && victim != ch )
extract_char( victim, TRUE );
}
for ( obj = pRoomIndex->first_content; obj != NULL; obj = obj_next )
{
obj_next = obj->next_in_room;
extract_obj( obj );
}
}
if ( (pRoomIndex->first_person) != NULL)
{
send_to_char( "You cannot delete the room while people are in it!.\n\r",ch);
old_vnum=0;
return;
}
/* Scan other rooms for exits pointing to this one, and delete exits. */
/* Delete all exits from this room too */
{
ROOM_INDEX_DATA * pSrchRoom;
EXIT_DATA * pExit;
int door;
for (pList=pArea->first_area_room;pList != NULL;pList=pList->next)
{
pSrchRoom=pList->data;
for (door=0;door<=5;door++)
{
if ( (pExit=pSrchRoom->exit[door]) != NULL
&& (pExit->to_room == pRoomIndex ||
pSrchRoom == pRoomIndex) )
{
/* Get rid of exit. */
free_string(pExit->description);
free_string(pExit->keyword);
PUT_FREE(pExit, exit_free);
pSrchRoom->exit[door]=NULL;
top_exit--;
/* spec: do the resets thing */
nuke_exit_resets(pSrchRoom, door);
}
}
}
}
/* Remove room from area list */
for ( pList = pArea->first_area_room; pList; pList = pList->next )
if ( pList->data == pRoomIndex )
break;
if ( pList )
{
UNLINK(pList, pArea->first_area_room, pArea->last_area_room, next, prev);
PUT_FREE(pList, build_free);
}
/* Remove room from vnum hash table */
{
int iHash;
iHash = vnum % MAX_KEY_HASH;
SING_UNLINK(pRoomIndex, room_index_hash[iHash], next, ROOM_INDEX_DATA);
}
/* wipe off resets referencing room. */
{
BUILD_DATA_LIST * pNext;
RESET_DATA * pReset;
RESET_DATA * pNextReset;
int iLastMobRoom;
int found;
/* First get rid of data lists referencing the resets we want to kill. */
for (pList=pRoomIndex->first_room_reset;pList != NULL; pList=pNext)
{
pNext=pList->next;
PUT_FREE(pList, build_free);
}
/* Now kill resets from area reset list, and free memory */
iLastMobRoom=0;
for (pReset=pArea->first_reset;pReset != NULL; pReset = pNextReset)
{
pNextReset=pReset->next;
found=0;
switch (pReset->command)
{
case 'M':
iLastMobRoom=pReset->arg3;
if (pReset->arg3 == vnum) found=1;
break;
case 'O':
if (pReset->arg3 == vnum) found=1; break;
case 'D':
case 'R':
if (pReset->arg1 == vnum) found=1; break;
case 'G':
case 'E':
if (iLastMobRoom==vnum) found=1; break;
}
if (found)
{
UNLINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
PUT_FREE(pReset, reset_free);
top_reset--;
}
}
}
/* Now get rid of exits and free memory */
{
EXIT_DATA * pExit;
int door;
for (door=0; door<=5; door++)
{
if ( (pExit=pRoomIndex->exit[door]) != NULL)
{
free_string(pExit->keyword);
free_string(pExit->description);
PUT_FREE(pExit, exit_free);
pRoomIndex->exit[door]=NULL;
top_exit--;
/* spec: resets aren't a problem, since they will get freed anyway */
}
}
}
/* Get rid of extra descriptions */
{
EXTRA_DESCR_DATA *pNext;
EXTRA_DESCR_DATA *pEd;
for (pEd=pRoomIndex->first_exdesc;pEd != NULL; pEd = pNext)
{
pNext=pEd->next;
free_string(pEd->keyword);
free_string(pEd->description);
PUT_FREE(pEd, exdesc_free);
}
}
/* Now get rid of strings associated with room */
free_string(pRoomIndex->name);
free_string(pRoomIndex->description);
/* Now kill actual struct */
PUT_FREE(pRoomIndex, rid_free);
top_room--;
send_to_char("Done.\n\r",ch);
return;
}
int old_ovnum=0;
void build_delobject( CHAR_DATA *ch, char *argument )
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
CHAR_DATA *vch;
OBJ_INDEX_DATA * pObjIndex;
AREA_DATA * pArea;
BUILD_DATA_LIST * pList;
int vnum;
smash_tilde( argument );
argument = one_argument( argument, arg1 );
strcpy( arg2, argument );
if ( arg1[0] == '\0')
{
send_to_char( "Syntax: delobject <vnum>\n\r", ch );
return;
}
if (is_number(arg1))
{
vnum=atoi(arg1);
if (! (pObjIndex = get_obj_index(vnum)))
{
send_to_char( "Vnum not found.\n\r", ch);
}
if (!build_canwrite(pObjIndex->area,ch,1))
return;
old_ovnum=vnum;
sprintf(buf, "Are you sure you want to delete object: [%d] %s?\n\r",vnum,pObjIndex->name);
strcat(buf,"Type delobject ok if you are sure.\n\r");
send_to_char(buf,ch);
return;
}
if ( str_cmp(arg1,"ok")) /* arg1 is NOT ok. */
{
/* Usage message */
build_delobject( ch, "");
return;
}
if ( old_ovnum == 0)
{
send_to_char( "First specify a object number.\n\r",ch);
return;
}
/* make sure that NO one else has build_vnum set to this room!! */
for ( vch = first_char; vch != NULL; vch = vch->next )
if ( vch->build_vnum == old_ovnum )
vch->build_vnum = -1;
/* Now do deletion *gulp* */
vnum=old_ovnum;
old_ovnum=0;
pObjIndex = get_obj_index(vnum);
pArea=pObjIndex->area;
/* Things to get rid of: Resets, Affect, Extra descs, struct */
/* Remove room from area list */
for ( pList = pArea->first_area_object; pList; pList = pList->next )
if ( pList->data == pObjIndex )
break;
{
UNLINK(pList, pArea->first_area_object, pArea->last_area_object,
next, prev);
PUT_FREE(pList, build_free);
}
/* Remove object from vnum hash table */
{
int iHash;
iHash = vnum % MAX_KEY_HASH;
SING_UNLINK(pObjIndex, obj_index_hash[iHash], next, OBJ_INDEX_DATA);
}
/* wipe off resets referencing Obj. */
{
/* BUILD_DATA_LIST * pNext; Unused var */
RESET_DATA * pReset;
RESET_DATA * pNextReset;
int found;
/* Now kill resets from area reset list, and free memory */
for (pReset=pArea->first_reset;pReset != NULL; pReset = pNextReset)
{
pNextReset=pReset->next;
found=0;
switch (pReset->command)
{
case 'O':
if (pReset->arg1 == vnum) found=1; break;
case 'P':
if (pReset->arg1 == vnum || pReset->arg3 == vnum) found=1; break;
case 'G':
case 'E':
if (pReset->arg1==vnum) found=1; break;
}
if (found)
{
UNLINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
PUT_FREE(pReset, reset_free);
top_reset--;
}
}
}
/* Get rid of extra descriptions */
{
EXTRA_DESCR_DATA *pNext;
EXTRA_DESCR_DATA *pEd;
for (pEd=pObjIndex->first_exdesc;pEd != NULL; pEd = pNext)
{
pNext=pEd->next;
free_string(pEd->keyword);
free_string(pEd->description);
PUT_FREE(pEd, exdesc_free);
}
}
/* Get rid of affects */
{
AFFECT_DATA *paf;
AFFECT_DATA *pNext;
for (paf=pObjIndex->first_apply; paf != NULL; paf = pNext)
{
pNext=paf->next;
PUT_FREE(paf, affect_free);
}
}
/* Free strings */
free_string(pObjIndex->name);
free_string(pObjIndex->short_descr);
free_string(pObjIndex->description);
/* Now delete structure */
PUT_FREE(pObjIndex, oid_free);
top_obj_index--;
send_to_char("Done.\n\r",ch);
return;
}
int old_mob_vnum=0;
void build_delmob( CHAR_DATA *ch, char *argument )
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
CHAR_DATA *vch;
MOB_INDEX_DATA * pMobIndex;
AREA_DATA * pArea;
BUILD_DATA_LIST * pList;
int vnum;
smash_tilde( argument );
argument = one_argument( argument, arg1 );
strcpy( arg2, argument );
if ( arg1[0] == '\0')
{
send_to_char( "Syntax: delmobile <vnum>\n\r", ch );
return;
}
if (is_number(arg1))
{
vnum=atoi(arg1);
if (! (pMobIndex = get_mob_index(vnum)))
{
send_to_char( "Vnum not found.\n\r", ch);
}
if (!build_canwrite(pMobIndex->area,ch,1))
return;
old_mob_vnum=vnum;
sprintf(buf, "Are you sure you want to delete mobile: [%d] %s?\n\r",vnum,pMobIndex->player_name);
strcat(buf,"Type delmobile ok if you are sure.\n\r");
send_to_char(buf,ch);
return;
}
if ( str_cmp(arg1,"ok")) /* arg1 is NOT ok. */
{
/* Usage message */
build_delmob( ch, "");
return;
}
if ( old_mob_vnum == 0)
{
send_to_char( "First specify a mobile number.\n\r",ch);
return;
}
/* make sure that NO one else has build_vnum set to this mob!! */
for ( vch = first_char; vch != NULL; vch = vch->next )
if ( vch->build_vnum == old_ovnum )
vch->build_vnum = -1;
/* Now do deletion *gulp* */
vnum=old_mob_vnum;
old_mob_vnum=0;
pMobIndex = get_mob_index(vnum);
pArea=pMobIndex->area;
/* Things to get rid of: Resets, Affect, Extra descs, struct */
/* Take mobile out of area list */
for ( pList = pArea->first_area_mobile; pList; pList = pList->next )
if ( pList->data == pMobIndex )
break;
if ( pList )
{
UNLINK(pList, pArea->first_area_mobile, pArea->last_area_mobile,
next, prev);
PUT_FREE(pList, build_free);
}
/* Get rid of mobile from world */
{
CHAR_DATA * wch;
CHAR_DATA * wchnext;
for ( wch = first_char; wch != NULL ; wch = wchnext )
{
wchnext=wch->next;
if (wch->pIndexData==pMobIndex)
extract_char(wch,TRUE);
}
}
/* Remove mobile from vnum hash table */
{
int iHash;
iHash = vnum % MAX_KEY_HASH;
SING_UNLINK(pMobIndex, mob_index_hash[iHash], next, MOB_INDEX_DATA);
}
/* wipe off resets referencing Mob. */
{
RESET_DATA * pReset;
RESET_DATA * pNextReset;
int found;
int iLastMob;
/* Now kill resets from area reset list, and free memory */
iLastMob=0;
for (pReset=pArea->first_reset;pReset != NULL; pReset = pNextReset)
{
pNextReset=pReset->next;
found=0;
switch (pReset->command)
{
case 'M':
iLastMob=pReset->arg1;
if (pReset->arg1 == vnum) found=1; break;
case 'G':
case 'E':
if (iLastMob==vnum) found=1; break;
}
if (found)
{
UNLINK(pReset, pArea->first_reset, pArea->last_reset, next, prev);
PUT_FREE(pReset, reset_free);
top_reset--;
}
}
}
/* Get rid of shop */
if (pMobIndex->pShop != NULL)
{
SHOP_DATA * pShop;
pShop=pMobIndex->pShop;
/* Take out of pList */
UNLINK(pList, pArea->first_area_shop, pArea->last_area_shop,
next, prev);
PUT_FREE(pList, build_free);
/* Take out of pShop linked list */
UNLINK(pShop, first_shop, last_shop, next, prev);
/* Now free shop structure */
PUT_FREE(pShop, shop_free);
}
/* Get rid of mobprogs */
{
MPROG_DATA * pMobProg;
MPROG_DATA * pNextMobProg;
for (pMobProg=pMobIndex->first_mprog;pMobProg != NULL; pMobProg=pNextMobProg)
{
pNextMobProg=pMobProg->next;
free_string(pMobProg->arglist);
free_string(pMobProg->comlist);
free_string(pMobProg->filename);
PUT_FREE(pMobProg, mprog_free);
}
}
/* Free strings */
free_string(pMobIndex->player_name);
free_string(pMobIndex->short_descr);
free_string(pMobIndex->description);
/* Now delete structure */
PUT_FREE(pMobIndex, mid_free);
top_mob_index--;
send_to_char("Done.\n\r",ch);
return;
}
void build_help(CHAR_DATA * ch,char * argument)
{
char buf[MAX_STRING_LENGTH];
if ( argument[0] != '\0' ) /* If an argument supplied... */
{
sprintf( buf, "BUILD_%s", argument ); /* Format text to send */
do_help( ch, buf ); /* Try and find BUILD_<helpname> in helps */
return;
}
do_help( ch, "build_summary" );
return;
}
void reset_area(AREA_DATA *);
void build_forcereset(CHAR_DATA *ch, char * argument)
{
AREA_DATA * pArea;
pArea=ch->in_room->area;
if (! build_canwrite(pArea,ch,0))
{
send_to_char("You cannot reset this area.\n\r",ch);
return;
}
reset_area(pArea);
build_save_flush();
send_to_char("Done.\n\r",ch);
return;
}
char * build_simpstrdup( char * buf)
{
char * rvalue;
build_strdup(&rvalue,buf,FALSE,NULL);
return rvalue;
}
#define STRING_FILE_DIR "temp/"
/* spec- rewritten to work correctly with SSM */
void build_strdup( char * * dest, char * src, bool freesrc, CHAR_DATA * ch)
{
/* Does the same as fread_string plus more, if there is enough memory. */
FILE *infile;
char *filechar;
char filename[255];
char *old_destp;
char *out;
char buf[MSL];
if (src[0]=='$') /* Special functions */
{
src++;
if (src[0]!='$')
{
/* Check for edit, new, clear */
if (is_name(src,"edit new clear") && ch != NULL)
{
if (! str_cmp(src,"clear") )
{
if (freesrc && (*dest)!=NULL)
free_string(*dest);
*dest=&str_empty[0];
return;
}
if ( (!str_cmp(src,"edit")) && freesrc )
{
old_destp=*dest;
build_editstr(dest,*dest,ch);
if ( (old_destp) != NULL)
free_string(old_destp);
return;
}
/* If clear, or freesrc is FALSE, start with a blank sheet. */
build_editstr(dest,"",ch);
return;
}
if (freesrc && (*dest)!=NULL)
free_string(*dest);
/* Read in a file */
fclose( fpReserve );
filename[0]='\0';
strcat(filename,STRING_FILE_DIR);
strcat(filename,src);
infile=fopen(filename,"r");
if (!infile)
filechar=str_dup("Could not open file.\n\r");
else
{
/* fBootDb=1; */
/* spec- we can't do the fBootDb thing, since SSM has already
* freed the hash table
*/
filechar=fread_string(infile);
/* fBootDb=0; */
}
fpReserve=fopen( NULL_FILE, "r");
*dest=filechar;
return;
}
}
if (freesrc && (*dest)!=NULL)
free_string(*dest);
/* spec- call str_dup to do most of the work */
/* SSM still uses a single string block, so we're relatively safe here */
if (src >= string_space && src < top_string)
{
*dest=str_dup(src);
return;
}
/* spec- rewrite of the ugly fread_string close, to use str_dup */
/* do literal \n -> LF etc. conversions to a buffer, then str_dup it */
/* we assume here that the src string is <MSL (should be safe to do so) */
out=buf;
while (*src)
{
switch (*src)
{
default:
*out++=*src++;
break;
case '\n':
*out++='\n';
*out++='\r';
src++;
break;
case '\r':
src++;
break;
case '\\':
switch (*++src)
{
case 'n':
*out++='\n';
break;
case 'r':
*out++='\r';
break;
default:
*out++='\\';
*out++=*src;
break;
}
if (*src) /* don't overrun here.. */
src++;
}
}
*out=0;
*dest=str_dup(buf);
}
void build_editstr(char * * dest, char * src, CHAR_DATA * ch)
{
/* Starts a character editing. write_start sets *dest to the buffer*/
char * orig;
orig=str_dup( src );
send_to_char("Editing string. Type .help for help.\n\r",ch);
write_start(dest,build_finishedstr,orig,ch);
if (*dest != &str_empty[0] )
{
send_to_char(src,ch);
strcat(*dest,src); /* Add src string into the buffer */
}
else
{
free_string(orig);
}
return;
}
void build_finishedstr( char * orig, char * * dest, CHAR_DATA * ch, bool saved)
{
if (!saved)
{
*dest=str_dup(orig);
}
free_string(orig);
return;
}
void build_set_oedit( CHAR_DATA *ch, char *argument )
{
OBJ_INDEX_DATA *obj;
ch->act_build = ACT_BUILD_OEDIT;
if ( is_number( argument ) )
{
ch->build_vnum = atoi( argument );
if ( ( obj = get_obj_index( ch->build_vnum) ) == NULL )
ch->build_vnum = -1;
}
else
ch->build_vnum = -1;
send_to_char( ch->build_vnum == -1 ? "No vnum set. Use setvnum.\n\r"
: "Vnum now set. " , ch );
return;
}
void build_set_redit( CHAR_DATA *ch, char *argument )
{
ch->build_vnum = ch->in_room->vnum;
ch->act_build = ACT_BUILD_REDIT;
send_to_char( "Now in Redit mode. Vnum set to current room.\n\r", ch );
return;
}
void build_set_medit( CHAR_DATA *ch, char *argument )
{
MOB_INDEX_DATA *mob;
ch->act_build = ACT_BUILD_MEDIT;
if ( is_number( argument ) )
{
ch->build_vnum = atoi( argument );
if ( ( mob = get_mob_index( ch->build_vnum ) ) == NULL )
ch->build_vnum = -1;
}
else
ch->build_vnum = -1;
send_to_char( ch->build_vnum == -1 ? "No vnum set. Use setvnum.\n\r"
: "Vnum now set. " , ch );
return;
}
void build_set_nedit( CHAR_DATA *ch, char *argument )
{
ch->act_build = ACT_BUILD_NOWT;
ch->build_vnum = -1;
send_to_char( "You are no longer in ANY editing mode.\n\r", ch );
return;
}
void build_setvnum( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
int vnum;
OBJ_INDEX_DATA *obj;
/* ROOM_INDEX_DATA *room; unused */
MOB_INDEX_DATA *mob;
bool found;
sh_int inc= 0;
if ( argument[0] == '\0' )
{
send_to_char( "USAGE: setvnum <vnum>, or v n(dec)/m(inc)\n\r", ch );
return;
}
if ( !is_number( argument ) )
if ( !str_cmp( argument, "m" ) )
inc = 1;
else if ( !str_cmp( argument, "n" ) )
inc = -1;
else
{
send_to_char( "Argument must be numeric. [vnum]\n\r", ch );
return;
}
if ( is_number( argument ) )
vnum = atoi( argument );
else
{
vnum = ch->build_vnum + inc;
}
sprintf( buf, "Current vnum now set to: %d.\n\r", vnum );
found = TRUE;
switch ( ch->act_build )
{
case ACT_BUILD_OEDIT:
if ( ( obj = get_obj_index( vnum ) ) == NULL )
{
sprintf( buf2, "No object with that vnum exists. Use addobject first.\n\r" );
found = FALSE;
}
else
sprintf( buf2, "Object exists: %s\n\r", obj->short_descr );
break;
case ACT_BUILD_REDIT:
/* do_goto( ch, itoa( vnum ) ); */
ch->build_vnum = ch->in_room->vnum;
send_to_char( "Vnum set to current room vnum.\n\r", ch );
break;
case ACT_BUILD_MEDIT:
if ( ( mob = get_mob_index( vnum ) ) == NULL )
{
sprintf( buf2, "No mobile with that vnum exists. Use addmob first.\n\r" );
found = FALSE;
}
else
sprintf( buf2, "Mobile exists: %s\n\r", mob->short_descr );
break;
default:
sprintf( buf2, "Please set your editing mode first!!\n\r" );
}
send_to_char( buf, ch );
send_to_char( buf2, ch );
if ( found )
{
ch->build_vnum = vnum;
send_to_char( "New vnum IS set.\n\r", ch );
build_list( ch, "" );
}
else
{
send_to_char( "New vnum NOT set - still at old value.\n\r", ch );
}
return;
}
void build_list( CHAR_DATA *ch, char *argument )
{
/* do show obj|mob|room according to ch->act_build -S- */
char buf[MAX_STRING_LENGTH];
bool found;
found = FALSE;
if ( argument[0] == '\0'|| ( ch->act_build == ACT_BUILD_REDIT
&& is_name( argument, "brief doors resets desc all" ) ) )
{
switch ( ch->act_build )
{
case ACT_BUILD_NOWT:
send_to_char( "Not in any editing mode. Nothing to show!\n\r", ch );
break;
case ACT_BUILD_OEDIT:
if ( ch->build_vnum == -1 )
send_to_char( "No vnum has been selected!\n\r", ch );
else
{
sprintf( buf, "%d", ch->build_vnum );
build_showobj( ch, buf );
}
break;
case ACT_BUILD_REDIT:
if ( ch->build_vnum == -1 )
send_to_char( "No vnum has been selected!\n\r", ch );
else
{
build_showroom( ch, argument );
}
break;
case ACT_BUILD_MEDIT:
if ( ch->build_vnum == -1 )
send_to_char( "No vnum has been selected!\n\r", ch );
else
{
sprintf( buf, "%d", ch->build_vnum );
build_showmob( ch, buf );
}
break;
}
return;
}
if ( ch->act_build == ACT_BUILD_NOWT )
{
send_to_char( "You must be in an editing mode first!\n\r", ch );
return;
}
/* Ok, now arg is valid. See if it applic. to edit mode */
if ( !strcmp( argument, "flags" ) )
{
found = TRUE;
switch ( ch->act_build )
{
case ACT_BUILD_REDIT:
sprintf(buf,"Valid room flags are :\n\r");
wide_table_printout(tab_room_flags,buf+strlen(buf));
send_to_char(buf,ch);
break;
case ACT_BUILD_MEDIT:
sprintf(buf,"Valid mob flags are :\n\r");
wide_table_printout(tab_mob_flags,buf+strlen(buf));
send_to_char(buf,ch);
break;
case ACT_BUILD_OEDIT:
sprintf(buf,"Valid object flags are :\n\r");
wide_table_printout(tab_obj_flags,buf+strlen(buf));
send_to_char(buf,ch);
break;
}
}
if ( !strcmp( argument, "aff" ) )
{
switch( ch->act_build )
{
case ACT_BUILD_OEDIT:
sprintf(buf,"Valid object affects are :\n\r");
wide_table_printout(tab_obj_aff,buf+strlen(buf));
send_to_char(buf,ch);
found = TRUE;
break;
case ACT_BUILD_MEDIT:
sprintf(buf,"Valid mob affects are :\n\r");
wide_table_printout(tab_affected_by,buf+strlen(buf));
send_to_char(buf,ch);
found = TRUE;
break;
default:
send_to_char( "Only valid when in Oedit or Medit modes.\n\r", ch );
}
}
if ( !strcmp( argument, "types" ) )
{
if ( ch->act_build != ACT_BUILD_OEDIT )
{
send_to_char( "Only valid when in Oedit mode.\n\r", ch );
return;
}
found = TRUE;
sprintf(buf,"Valid object types are :\n\r");
wide_table_printout(tab_item_types,buf+strlen(buf));
send_to_char(buf,ch);
}
if ( !strcmp( argument, "wear" ) )
{
if ( ch->act_build != ACT_BUILD_OEDIT )
{
send_to_char( "Only valid when in Oedit mode.\n\r", ch );
return;
}
found = TRUE;
sprintf(buf,"Valid object wear flags are :\n\r");
wide_table_printout(tab_wear_flags,buf+strlen(buf));
send_to_char(buf,ch);
}
if ( !strcmp( argument, "loc" ) )
{
if ( ch->act_build != ACT_BUILD_OEDIT )
{
send_to_char( "Only valid when in Oedit mode.\n\r", ch );
return;
}
found = TRUE;
sprintf(buf,"Valid object wear locations are :\n\r");
wide_table_printout(tab_wear_loc,buf+strlen(buf));
send_to_char(buf,ch);
}
if ( !strcmp( argument, "sec" ) )
{
if ( ch->act_build != ACT_BUILD_REDIT )
{
send_to_char( "Only valid when in Redit mode.\n\r", ch );
return;
}
found = TRUE;
sprintf(buf,"Valid room sector types are :\n\r");
wide_table_printout(tab_sector_types,buf+strlen(buf));
send_to_char(buf,ch);
}
if ( !strcmp( argument, "exit" ) )
{
if ( ch->act_build != ACT_BUILD_REDIT )
{
send_to_char( "Only valid when in Redit mode.", ch );
return;
}
found = TRUE;
sprintf(buf,"Valid room door types are :\n\r");
wide_table_printout(tab_door_types,buf+strlen(buf));
send_to_char(buf,ch);
sprintf(buf,"Valid room door states are :\n\r");
wide_table_printout(tab_door_states,buf+strlen(buf));
send_to_char(buf,ch);
}
if ( !found )
{
send_to_char( "You may display the following values:\n\r\n\r", ch );
send_to_char( "Edit Mode: Values:\n\r---------- -------\n\r", ch );
send_to_char( " Redit FLAGS - room flags.\n\r", ch );
send_to_char( " SEC - room sector types.\n\r", ch );
send_to_char( " EXIT - door states / types.\n\r", ch );
send_to_char( " Medit FLAGS - mob flags.\n\r", ch );
send_to_char( " AFF - mob affected_by values.\n\r", ch );
send_to_char( " Oedit TYPES - object types.\n\r", ch );
send_to_char( " FLAGS - object flags.\n\r", ch );
send_to_char( " WEAR - object wear flags.\n\r", ch );
send_to_char( " LOC - object wear locations.\n\r", ch );
send_to_char( " AFF - object affected_by values.\n\r", ch );
return;
}
return;
}
void build_set( CHAR_DATA *ch, char *argument )
{
/* Call setroom/mob/obj with argument, and vnum, etc. */
char buf[MAX_STRING_LENGTH];
switch( ch->act_build )
{
case ACT_BUILD_OEDIT:
if ( ch->build_vnum == -1 )
{
send_to_char( "No vnum is set!!\n\r", ch );
return;
}
sprintf( buf, "%d %s", ch->build_vnum, argument );
build_setobject( ch, buf );
break;
case ACT_BUILD_REDIT:
if ( ch->build_vnum == -1 )
{
send_to_char( "No vnum is set!!\n\r", ch );
return;
}
build_setroom( ch, argument );
break;
case ACT_BUILD_MEDIT:
if ( ch->build_vnum == -1 )
{
send_to_char( "No vnum is set!!\n\r", ch );
return;
}
sprintf( buf, "%d %s", ch->build_vnum, argument );
build_setmob( ch, buf );
break;
default:
send_to_char( "You are not in any editing mode!\n\r", ch );
}
return;
}
void build_listvalues( CHAR_DATA *ch, char *argument )
{
/* Lookup what the 4 values mean for the given object type -S- */
int value;
int foo;
char buf[MAX_STRING_LENGTH];
if ( argument[0] == '\0' )
{
send_to_char( "USAGE: values <item-type-name>\n\r", ch );
send_to_char( "Eg: values staff\n\r", ch );
return;
}
value=table_lookup(tab_item_types,argument);
if (value==0)
{
sprintf(buf,"Valid object types are :\n\r");
wide_table_printout(tab_item_types,buf+strlen(buf));
send_to_char(buf,ch);
return;
}
send_to_char( "Details for value0,...,value3 are:\n\r", ch );
value*= 10;
for ( foo = 0; foo < 4; foo++ )
{
sprintf( buf, "@@W[Value@@y%d@@W] : @@y%s@@g\n\r",
foo, rev_table_lookup(tab_value_meanings, value + foo) );
send_to_char( buf, ch );
}
return;
}
void build_listweapons( CHAR_DATA *ch, char *argument )
{
/* list weapon types, along with values */
char buf[MAX_STRING_LENGTH];
int foo;
/* Need values as well, so rehash table_printout */
for ( foo = 0; tab_weapon_types[foo].text != NULL; foo ++ )
{
sprintf( buf, "@@W%2ld - @@y%10s. ", tab_weapon_types[foo].value,
tab_weapon_types[foo].text );
send_to_char( buf, ch );
if ( (foo+1) % 2 == 0 )
send_to_char( "\n\r", ch );
}
send_to_char( "@@g\n\r", ch );
return;
}
void build_listliquids( CHAR_DATA *ch, char *argument )
{
/* list liquid types, along with values */
char buf[MAX_STRING_LENGTH];
int foo;
/* Need values as well, so rehash table_printout */
for ( foo = 0; tab_drink_types[foo].text != NULL; foo ++ )
{
sprintf( buf, "%2ld - %12s. ", tab_drink_types[foo].value,
tab_drink_types[foo].text );
send_to_char( buf, ch );
if ( (foo+1) % 2 == 0 )
send_to_char( "\n\r", ch );
}
send_to_char( "\n\r", ch );
return;
}
void build_listspells( CHAR_DATA *ch, char *argument )
{
/* List spells -S- */
int sn;
char buf[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
int type;
bool fall;
if ( argument[0] == '\0' )
{
send_to_char( "USAGE: spells < target_type >\n\r", ch );
send_to_char( "target type being one of: ign - picks own target\n\r", ch );
send_to_char( " off - offensive\n\r", ch );
send_to_char( " def - defensive\n\r", ch );
send_to_char( " slf - personal-only (self)\n\r", ch );
send_to_char( " obj - object-only\n\r", ch );
send_to_char( " all - list ALL spells\n\r", ch );
return;
}
fall = FALSE;
type = -1;
buf2[0] = '\0';
if ( !strcmp( argument, "all" ) ) fall = TRUE;
else if ( !strcmp( argument, "ign" ) ) type = TAR_IGNORE;
else if ( !strcmp( argument, "off" ) ) type = TAR_CHAR_OFFENSIVE;
else if ( !strcmp( argument, "def" ) ) type = TAR_CHAR_DEFENSIVE;
else if ( !strcmp( argument, "slf" ) ) type = TAR_CHAR_SELF;
else if ( !strcmp( argument, "obj" ) ) type = TAR_OBJ_INV;
else
{
send_to_char( "Option not recognized.\n\r", ch );
build_listspells( ch, "" ); /* usage message */
return;
}
sprintf( buf2, "List of spells for option %s:\n\r", argument );
for ( sn = 0; sn < MAX_SKILL; sn++ )
{
if ( skill_table[sn].name == NULL )
break;
if ( skill_table[sn].slot == 0 )
continue;
if ( skill_table[sn].target == type || fall )
{
sprintf( buf, "@@W[Spell No: %4d] @@y%s@@g\n\r", sn,
skill_table[sn].name );
strcat( buf2, buf );
}
}
send_to_char( buf2, ch );
return;
}
int get_dir(char dir)
{
char * temp;
if ( dir=='\0'
|| (temp=strchr(cDirs,dir))==NULL)
return -1;
return temp-cDirs;
}
void build_urooms( CHAR_DATA *ch, char *argument )
{
/* List vnum usage for area... */
int curvnum;
char buf[MAX_STRING_LENGTH];
char free[MAX_STRING_LENGTH];
char used[MAX_STRING_LENGTH];
AREA_DATA *area;
int last = 0; /* 0 = start, 1 = used, 2 = free */
int foo = 0; /* holds start of free/used vnums, so no 3001-3001 */
area=ch->in_room->area;
/* Rooms */
sprintf( free, "(Free) " );
sprintf( used, "(Used) " );
for ( curvnum = area->min_vnum; curvnum < area->max_vnum; curvnum ++ )
{
if ( get_room_index( curvnum ) != NULL )
{
switch( last )
{
case 0:
sprintf( buf, "%d", curvnum );
strcat( used, buf );
foo = curvnum;
last = 1;
break;
case 1:
break;
case 2:
if ( foo != curvnum-1 )
{
sprintf( buf, "-%d", curvnum-1 );
strcat( free, buf );
}
sprintf( buf, " %d", curvnum );
strcat( used, buf );
foo = curvnum;
last = 1;
}
}
else
{
switch( last )
{
case 0:
sprintf( buf, "%d", curvnum );
strcat( free, buf );
foo = curvnum;
last = 2;
break;
case 1:
if ( foo != curvnum -1 )
{
sprintf( buf, "-%d", curvnum-1 );
strcat( used, buf );
}
sprintf( buf, " %d", curvnum );
strcat( free, buf );
last =2;
foo = curvnum;
break;
case 2:
break;
}
}
}
curvnum = area->max_vnum;
if ( get_room_index( curvnum ) != NULL )
{
switch( last )
{
case 1:
if ( foo != ( curvnum-1 ) )
sprintf( buf, "-%d.", curvnum );
else
sprintf( buf, " %d.", curvnum );
strcat( used, buf );
break;
case 2:
if ( foo != curvnum -1 )
{
sprintf( buf, "-%d.", curvnum-1 );
strcat( used, buf );
}
sprintf( buf, " %d.", curvnum );
strcat( free, buf );
break;
}
}
else
{
switch( last )
{
case 1:
if ( foo != curvnum -1 )
{
sprintf( buf, "-%d.", curvnum-1 );
strcat( used, buf );
}
sprintf( buf, " %d.", curvnum );
strcat( free, buf );
break;
case 2:
if ( foo != curvnum -1 )
sprintf( buf, "-%d.", curvnum );
else
sprintf( buf, " %d.", curvnum );
strcat( free, buf );
break;
}
}
sprintf( buf, "Room vnum usage summary:\n\r\n\r%s\n\r\n\r%s\n\r", used, free );
send_to_char( buf, ch );
return;
}
void build_uobjs( CHAR_DATA *ch, char *argument )
{
/* List vnum usage for area... */
int curvnum;
char buf[MAX_STRING_LENGTH];
char free[MAX_STRING_LENGTH];
char used[MAX_STRING_LENGTH];
AREA_DATA *area;
int last = 0; /* 0 = start, 1 = used, 2 = free */
int foo = 0; /* holds start of free/used vnums, so no 3001-3001 */
area=ch->in_room->area;
/* Rooms */
sprintf( free, "(Free) " );
sprintf( used, "(Used) " );
for ( curvnum = area->min_vnum; curvnum < area->max_vnum; curvnum ++ )
{
if ( get_obj_index( curvnum ) != NULL )
{
switch( last )
{
case 0:
sprintf( buf, "%d", curvnum );
strcat( used, buf );
foo = curvnum;
last = 1;
break;
case 1:
break;
case 2:
if ( foo != curvnum-1 )
{
sprintf( buf, "-%d", curvnum-1 );
strcat( free, buf );
}
sprintf( buf, " %d", curvnum );
strcat( used, buf );
foo = curvnum;
last = 1;
}
}
else
{
switch( last )
{
case 0:
sprintf( buf, "%d", curvnum );
strcat( free, buf );
foo = curvnum;
last = 2;
break;
case 1:
if ( foo != curvnum -1 )
{
sprintf( buf, "-%d", curvnum-1 );
strcat( used, buf );
}
sprintf( buf, " %d", curvnum );
strcat( free, buf );
last =2;
foo = curvnum;
break;
case 2:
break;
}
}
}
curvnum = area->max_vnum;
if ( get_obj_index( curvnum ) != NULL )
{
switch( last )
{
case 1:
if ( foo != ( curvnum-1 ) )
sprintf( buf, "-%d.", curvnum );
else
sprintf( buf, " %d.", curvnum );
strcat( used, buf );
break;
case 2:
if ( foo != curvnum -1 )
{
sprintf( buf, "-%d.", curvnum-1 );
strcat( used, buf );
}
sprintf( buf, " %d.", curvnum );
strcat( free, buf );
break;
}
}
else
{
switch( last )
{
case 1:
if ( foo != curvnum -1 )
{
sprintf( buf, "-%d.", curvnum-1 );
strcat( used, buf );
}
sprintf( buf, " %d.", curvnum );
strcat( free, buf );
break;
case 2:
if ( foo != curvnum -1 )
sprintf( buf, "-%d.", curvnum );
else
sprintf( buf, " %d.", curvnum );
strcat( free, buf );
break;
}
}
sprintf( buf, "Object vnum usage summary:\n\r\n\r%s\n\r\n\r%s\n\r", used, free );
send_to_char( buf, ch );
return;
}
void build_umobs( CHAR_DATA *ch, char *argument )
{
/* List vnum usage for area... */
int curvnum;
char buf[MAX_STRING_LENGTH];
char free[MAX_STRING_LENGTH];
char used[MAX_STRING_LENGTH];
AREA_DATA *area;
int last = 0; /* 0 = start, 1 = used, 2 = free */
int foo = 0; /* holds start of free/used vnums, so no 3001-3001 */
area=ch->in_room->area;
sprintf( free, "(Free) " );
sprintf( used, "(Used) " );
for ( curvnum = area->min_vnum; curvnum < area->max_vnum; curvnum ++ )
{
if ( get_mob_index( curvnum ) != NULL )
{
switch( last )
{
case 0:
sprintf( buf, "%d", curvnum );
strcat( used, buf );
foo = curvnum;
last = 1;
break;
case 1:
break;
case 2:
if ( foo != curvnum-1 )
{
sprintf( buf, "-%d", curvnum-1 );
strcat( free, buf );
}
sprintf( buf, " %d", curvnum );
strcat( used, buf );
foo = curvnum;
last = 1;
}
}
else
{
switch( last )
{
case 0:
sprintf( buf, "%d", curvnum );
strcat( free, buf );
foo = curvnum;
last = 2;
break;
case 1:
if ( foo != curvnum -1 )
{
sprintf( buf, "-%d", curvnum-1 );
strcat( used, buf );
}
sprintf( buf, " %d", curvnum );
strcat( free, buf );
last =2;
foo = curvnum;
break;
case 2:
break;
}
}
}
curvnum = area->max_vnum;
if ( get_mob_index( curvnum ) != NULL )
{
switch( last )
{
case 1:
if ( foo != ( curvnum-1 ) )
sprintf( buf, "-%d.", curvnum );
else
sprintf( buf, " %d.", curvnum );
strcat( used, buf );
break;
case 2:
if ( foo != curvnum -1 )
{
sprintf( buf, "-%d.", curvnum-1 );
strcat( used, buf );
}
sprintf( buf, " %d.", curvnum );
strcat( free, buf );
break;
}
}
else
{
switch( last )
{
case 1:
if ( foo != curvnum -1 )
{
sprintf( buf, "-%d.", curvnum-1 );
strcat( used, buf );
}
sprintf( buf, " %d.", curvnum );
strcat( free, buf );
break;
case 2:
if ( foo != curvnum -1 )
sprintf( buf, "-%d.", curvnum );
else
sprintf( buf, " %d.", curvnum );
strcat( free, buf );
break;
}
}
sprintf( buf, "Mobile vnum usage summary:\n\r\n\r%s\n\r\n\r%s\n\r", used, free );
send_to_char( buf, ch );
return;
}
/** Help Editor
We want to be able to edit ANY help, so 3.bank etc should work,
in case we have helps with the same keyword(s).
**/
void build_findhelp( CHAR_DATA *ch, char *argument )
{
HELP_DATA *pHelp;
char buf[MAX_STRING_LENGTH];
char arg[MAX_STRING_LENGTH];
int cnt = 0;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "Usage: Findhelp <keyword>\n\r", ch );
return;
}
for ( pHelp = first_help; pHelp != NULL; pHelp = pHelp->next )
{
if ( is_name( arg, pHelp->keyword ) )
{
cnt++;
sprintf( buf, "[%2d] <%s> \n\r%1.100s\n\r", cnt, pHelp->keyword, pHelp->text );
send_to_char( buf, ch );
}
}
if ( cnt == 0 )
send_to_char( "Couldn't find that keyword.\n\r", ch );
return;
}
void build_helpedit( CHAR_DATA *ch, char *argument )
{
HELP_DATA *pHelp;
AREA_DATA *area;
BUILD_DATA_LIST *plist;
char arg[MAX_STRING_LENGTH];
int number;
int count;
number = number_argument( argument, arg );
count =0;
if ( arg[0] == '\0' )
{
send_to_char( "Usage: HELPEDIT <keyword>\n\r", ch );
return;
}
/** Now try and find the keyword **/
for ( pHelp = first_help; pHelp != NULL; pHelp = pHelp->next )
if ( is_name( arg, pHelp->keyword )
&& ( ++count == number ) )
break;
if ( pHelp == NULL )
{
send_to_char( "Couldn't find that keyword.\n\r", ch );
return;
}
build_strdup( &pHelp->text, "$edit", TRUE, ch );
/* Mark the help's area as modified so the help saves... */
for ( area = first_area; area != NULL; area = area->next )
{
if ( area->first_area_help_text != NULL )
{
for ( plist = area->first_area_help_text; plist != NULL; plist = plist->next )
{
if ( plist->data == pHelp )
{
area_modified( area );
break;
}
}
}
}
return;
}
void build_addhelp( CHAR_DATA *ch, char *argument )
{
HELP_DATA *pHelp;
BUILD_DATA_LIST *pList;
char arg[MAX_STRING_LENGTH];
int level;
argument = one_argument( argument, arg );
if ( !is_number( arg ) || argument[0] == '\0' )
{
send_to_char( "Usage: ADDHELP <level> <keyword(s)>.\n\r", ch );
return;
}
level = atoi( arg );
if ( level < -1 || level > 85 )
{
send_to_char( "Level must be between -1 and 85.\n\r", ch );
return;
}
GET_FREE(pHelp, help_free);
pHelp->level = level;
pHelp->keyword = str_dup( argument );
pHelp->text = str_dup( "NEW HELP. DELETE THIS LINE FIRST!" );
LINK(pHelp, first_help, last_help, next, prev);
/* MAG Mod */
GET_FREE(pList, build_free);
pList->data = pHelp;
LINK(pList, last_area->first_area_help_text,
last_area->last_area_help_text, next, prev);
top_help++;
send_to_char( "Help added. Use HELPEDIT <keyword> to edit it.\n\r", ch );
return;
}
/*
void do_all_help_save()
{
FILE * fp;
char help_file_name[MAX_STRING_LENGTH];
if ( ( fp = fopen( help_file, "w" ) ) == NULL )
{
bug( "Save Help Table: fopen", 0 );
perror( "failed open of helpfile.dat in do_help_save" );
}
else
{
HELP_DATA *pHelp;
BUILD_SATA_LIST *Pointer;
for (pointer = first_help; pointer != NULL, pointer = pointer_next )
{
pHelp=Pointer->data;
fprintf( fp,"%i %s~\n",pHelp->level,pHelp->keyword);
if (isspace(pHelp->text[0]))
fprintf( fp,".%s~\n",pHelp->text);
else
fprintf(fp,"%s~\n",pHelp->text);
}
fflush( fp );
fclose( fp );
return;
}
void do_all_help_load()
{
HELP_DATA *pHelp;
BUILD_DATA_LIST *pointer;
FILE * fp;
char help_file[MAX_STRING_LENGTH];
if ( ( fp = fopen( help_file, "r" ) ) == NULL )
{
bug( "Help Table: fopen", 0 );
perror( "failed open of helpfile.dat in do_help_load" );
}
for ( pointer = first_help; pointer != NULL; pointer = pointer_next )
{
GET_FREE(pHelp, help_free);
pHelp->level = fread_number( fp );
pHelp->keyword = fread_string( fp );
if ( pHelp->keyword[0] == '$' )
break;
pHelp->text = fread_string( fp );
LINK(pHelp, first_help, last_help, next, prev);
top_help++;
}
fclose ( fp );
return;
}
*/
/* NOTE--NEED TO MAKE SURE WE GET MOTD, TOO--I THINK IT WIL BE OKAY ZEN */
void build_clone( CHAR_DATA *ch, char *argument )
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
/*
* Allow builder to clone a room/mob/object -
* Takes existing r/m/o and makes new copy with relevant details
* copied across...
*/
if ( argument[0] == '\0' ) /* Show help info */
{
send_to_char( "Usage: CLONE <type> <vnum>\n\r", ch );
send_to_char( "Where <type> is one of: mob room obj\n\r", ch );
send_to_char( " <vnum> is the vnum of the type you want to clone.\n\r", ch );
send_to_char( "[The item will be copied onto the exisiting item you are editing]\n\r", ch );
return;
}
argument = one_argument( argument, arg1 ); /* room/mob/obj */
argument = one_argument( argument, arg2 ); /* vnum to clone to */
/* Check arguments */
if ( arg1[0] == '\0'
|| arg2[0] == '\0'
|| !is_number( arg2 )
|| !is_name( arg1, "room obj mob" ) )
{
build_clone( ch, "" );
return;
}
if ( !str_cmp( arg1, "room" ) )
{
ROOM_INDEX_DATA *room;
ROOM_INDEX_DATA *in_room = ch->in_room;
/* EXTRA_DESCR_DATA *ed */
if ( ch->act_build != ACT_BUILD_REDIT )
{
send_to_char( "You must be in REDIT mode to clone a room.\n\r", ch );
return;
}
if ( ( room = get_room_index( atoi(arg2) ) ) == NULL )
{
send_to_char( "Sorry, no such room with that vnum.\n\r", ch );
return;
}
if ( in_room == NULL )
{
send_to_char( "Don't know what room you're in!!\n\r", ch );
return;
}
/* Check builder can read room, and write to in_room */
if ( !build_canread( room->area, ch, 0 ) )
{
send_to_char( "Sorry, you don't have authorization to read that room.\n\r", ch );
return;
}
if ( !build_canwrite( in_room->area, ch, 0 ) )
{
send_to_char( "Sorry, you don't have authorization to write into this room.\n\r", ch );
return;
}
/* Copy details across..... */
if ( in_room->name != NULL )
free_string( in_room->name );
in_room->name = str_dup( room->name );
if ( in_room->description != NULL )
free_string( in_room->description );
in_room->description = str_dup( room->description );
in_room->sector_type = room->sector_type;
in_room->room_flags = room->room_flags;
/* FIXME:
* Copy extra descriptions
*/
send_to_char( "Room cloned.\n\r", ch );
return;
}
if ( !str_cmp( arg1, "obj" ) )
{
OBJ_INDEX_DATA *obj;
OBJ_INDEX_DATA *this_obj;
if ( ch->act_build != ACT_BUILD_OEDIT )
{
send_to_char( "You must be in OEDIT mode to clone an object.\n\r", ch );
return;
}
if ( ( this_obj = get_obj_index( ch->build_vnum ) ) == NULL )
{
send_to_char( "You must select a valid object in OEDIT before you clone.\n\r", ch );
return;
}
if ( ( obj = get_obj_index( atoi(arg2) ) ) == NULL )
{
send_to_char( "That object does not exist to be cloned.\n\r", ch );
return;
}
if ( !build_canread( obj->area, ch, 0 ) )
{
send_to_char( "Sorry, you don't have authorization to read that object.\n\r", ch );
return;
}
if ( !build_canwrite( this_obj->area, ch, 0 ) )
{
send_to_char( "Sorry, you don't have authorization to write to this object.\n\r", ch );
return;
}
/* Copy details across... */
if ( this_obj->name != NULL )
free_string( this_obj->name );
this_obj->name = str_dup( obj->name );
this_obj->level = obj->level;
if ( this_obj->short_descr != NULL )
free_string( this_obj->short_descr );
this_obj->short_descr = str_dup( obj->short_descr );
if ( this_obj->description != NULL )
free_string( this_obj->description );
this_obj->description = str_dup( obj->description );
this_obj->item_type = obj->item_type;
this_obj->extra_flags = obj->extra_flags;
this_obj->wear_flags = obj->wear_flags;
this_obj->item_apply = obj->item_apply;
this_obj->value[0] = obj->value[0];
this_obj->value[1] = obj->value[1];
this_obj->value[2] = obj->value[2];
this_obj->value[3] = obj->value[3];
this_obj->weight = obj->weight;
/* FIXME:
* Copy extra descriptions
* handle obj_funs
*/
send_to_char( "Object cloned.\n\r", ch );
return;
}
if ( !str_cmp( arg1, "mob" ) )
{
MOB_INDEX_DATA *mob;
MOB_INDEX_DATA *this_mob;
if ( ch->act_build != ACT_BUILD_MEDIT )
{
send_to_char( "You must be in MEDIT mode to clone mobiles.\n\r", ch );
return;
}
if ( ( this_mob = get_mob_index( ch->build_vnum ) ) == NULL )
{
send_to_char( "You must select a valid mobile in MEDIT before you clone mobiles.\n\r", ch );
return;
}
if ( ( mob = get_mob_index( atoi( arg2 ) ) ) == NULL )
{
send_to_char( "That mobile does not exist to be cloned.\n\r", ch );
return;
}
if ( !build_canread( mob->area, ch, 0 ) )
{
send_to_char( "Sorry, you do not have authorization to read that mobile.\n\r", ch );
return;
}
if ( !build_canwrite( this_mob->area, ch, 0 ) )
{
send_to_char( "Sorry, you do not have authorization to write to this mobile.\n\r", ch );
return;
}
/* Copy details across... */
if ( this_mob->player_name != NULL )
free_string( this_mob->player_name );
this_mob->player_name = str_dup( mob->player_name );
if ( this_mob->short_descr != NULL )
free_string( this_mob->short_descr );
this_mob->short_descr = str_dup( mob->short_descr );
if ( this_mob->long_descr != NULL )
free_string( this_mob->long_descr );
this_mob->long_descr = str_dup( mob->long_descr );
if ( this_mob->description != NULL )
free_string( this_mob->description );
this_mob->description = str_dup( mob->description );
this_mob->act = mob->act;
this_mob->affected_by = mob->affected_by;
this_mob->alignment = mob->alignment;
this_mob->level = mob->level;
this_mob->sex = mob->sex;
this_mob->ac_mod = mob->ac_mod;
this_mob->hr_mod = mob->hr_mod;
this_mob->dr_mod = mob->dr_mod;
this_mob->cast = mob->cast;
this_mob->def = mob->def;
this_mob->skills = mob->skills;
/* FIXME:
* Copy shop details (if any) across
* handle spec_fun
* ignore mob_progs?
*/
send_to_char( "Mobile cloned.\n\r", ch );
return;
}
return;
}