/*~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
~ Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, ~
~ Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. ~
~ ~
~ Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael ~
~ Chastain, Michael Quan, and Mitchell Tse. ~
~ ~
~ Ack 2.2 improvements copyright (C) 1994 by Stephen Dooley ~
~ ACK!MUD is modified Merc2.0/2.1/2.2 code (c)Stephen Zepp 1998 Ver: 4.3 ~
~ ~
~ In order to use any part of this PA Diku Mud, you must comply with ~
~ both the original Diku license in 'license.doc' as well the Merc ~
~ license in 'license.txt', and the Ack!Mud license in 'ack_license.txt'.~
~ In particular, you may not remove any of these copyright notices. ~
~ ~
~ _______ _____ ~
~ / __ /\ / ___ \ 222222 PA_MUD by Amnon Kruvi ~
~ /______/ / / /___\ \ 2 PA_MUD is modified ~
~ / _______/ / _______ \ 2 Ack!Mud, v4.3 ~
~ /_/ /_/ \_\ 2 ~
~ 2 ~
~ 2222222 ~
~ ~
~ ~
~ Years of work have been invested to create DIKU, Merc, Ack and PA. ~
~ Please show your respect by following the licenses, and issuing ~
~ credits where due. ~
~ ~
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-*/
#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 "ack.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.)
Object item type : tab_item_types : number
Object extra flags : tab_obj_flags : bit_vector
Object wear flags : tab_wear_flags : bit_vector
Wear locations : tab_wear_loc : 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 };
bool fClanModified = FALSE; // For save_clan_table
/*
* 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;
DECLARE_DO_FUN( build_set_bedit );
DECLARE_DO_FUN( build_set_oedit );
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_listbuildings );
DECLARE_DO_FUN( build_uobjs );
DECLARE_DO_FUN( build_findhelp );
DECLARE_DO_FUN( build_commands );
DECLARE_DO_FUN( build_clone );
/* build_functions */
DECLARE_DO_FUN ( build_showobj );
DECLARE_DO_FUN ( build_findobject );
DECLARE_DO_FUN ( build_help );
DECLARE_DO_FUN ( build_helpedit );
DECLARE_DO_FUN ( build_setbuilding );
DECLARE_DO_FUN ( build_setobject );
DECLARE_DO_FUN ( build_stop );
DECLARE_DO_FUN ( build_addobject );
DECLARE_DO_FUN ( build_delwarn );
DECLARE_DO_FUN ( build_delobject );
DECLARE_DO_FUN ( build_delhelp );
DECLARE_DO_FUN ( build_addhelp );
DECLARE_DO_FUN ( build_addbuilding );
DECLARE_DO_FUN ( build_keyhelp );
/* 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 },
{ "goto", do_goto, POS_STANDING, 0, LOG_NORMAL },
{ "purge", do_purge, POS_STANDING, 0, LOG_NORMAL },
{ "who", do_who, 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 },
{ "showobject", build_showobj, POS_STANDING, 0, LOG_NORMAL },
{ "findarea", build_findarea, 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 },
{ "keyhelp", build_keyhelp, POS_STANDING, 0, LOG_NORMAL },
{ "set", build_set, POS_STANDING, 0, LOG_NORMAL },
{ "setarea", build_setarea, POS_STANDING,MAX_LEVEL,LOG_NORMAL },
{ "stop", build_stop, POS_STANDING, 0, LOG_ALWAYS },
{ "addobject", build_addobject,POS_STANDING, 0, LOG_NORMAL },
{ "delobjec", build_delwarn, POS_STANDING, 0, LOG_NORMAL },
{ "delobject", build_delobject,POS_STANDING, 0, LOG_NORMAL },
{ "delhelp", build_delhelp, POS_STANDING, 84, LOG_ALWAYS },
{ "findhelp", build_findhelp, POS_STANDING, 0, LOG_NORMAL },
{ "addhelp", build_addhelp, POS_STANDING, 0, LOG_NORMAL },
{ "oedit", build_set_oedit, POS_STANDING, 0, LOG_NORMAL },
{ "bedit", build_set_bedit, 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 },
{ "values", build_listvalues,POS_STANDING, 0, LOG_NORMAL },
{ "buildings", build_listbuildings,POS_STANDING, 0, LOG_NORMAL },
{ "addbuilding", build_addbuilding, POS_STANDING, 0, LOG_NORMAL },
{ "check_area", do_check_area, POS_STANDING,MAX_LEVEL+1,LOG_NORMAL},
{ "check_areas", do_check_areas, POS_STANDING,MAX_LEVEL+1,LOG_ALWAYS},
{ "clone", build_clone, POS_STANDING, 0, LOG_NORMAL },
{ "say", do_say, POS_STANDING, 0, LOG_NORMAL },
{ "areasave", do_areasave, 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 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_ed;
extern int top_help;
extern int top_obj_index;
extern int top_room;
extern HELP_DATA * help_last;
extern AREA_DATA * area_last;
extern AREA_DATA * area_first;
#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 *);
ROOM_INDEX_DATA * new_room( AREA_DATA * pArea, sh_int vnum )
{
ROOM_INDEX_DATA * pRoomIndex;
GET_FREE(pRoomIndex, rid_free);
pRoomIndex->area = pArea;
pRoomIndex->vnum = vnum;
return pRoomIndex;
}
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;
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( ch, 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 );
safe_strcat( MSL, out, buf );
if ( ++col % 3 == 0 )
safe_strcat( MSL, out, "\n\r" );
}
safe_strcat( MSL, out, "\n\r" );
send_to_char( out, 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];
OBJ_INDEX_DATA *obj;
int cnt;
char *foo = NULL;
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;
}
sprintf( buf, "\n\r@@WName: @@y%s @@WLevel: @@y%d.\n\r", obj->name, obj->level );
safe_strcat( MSL, buf1, buf );
sprintf( buf, "@@WVnum: @@y%d. @@WType: @@y%s.\n\r",
obj->vnum, tab_item_types[ (obj->item_type)-1 ].text );
safe_strcat( MSL, buf1, buf );
sprintf( buf, "@@WShort description: @@y%s.\n\r@@WLong description: @@y%s\n\r",
obj->short_descr, obj->description );
safe_strcat( MSL, buf1, buf );
/*
sprintf( buf, "@@WItem type: @@y%s.\n\r",rev_table_lookup(tab_item_types,obj->item_type));
safe_strcat( MSL, buf1, buf);
*/
sprintf( buf, "@@WWear bits: @@y%s\n\r",
bit_table_lookup(tab_wear_flags,obj->wear_flags) );
safe_strcat( MSL, buf1, buf );
sprintf( buf, "@@WExtra bits: @@y%s\n\r",
bit_table_lookup(tab_obj_flags,obj->extra_flags) );
safe_strcat( MSL, buf1, buf );
sprintf( buf, "@@WWeight: @@y%d.\n\r", obj->weight );
sprintf( buf+strlen(buf), "@@WHeat: @@y%d.\n\r", obj->heat );
sprintf( buf+strlen(buf), "@@WBuilding: @@y%s.\n\r", (obj->building<0||obj->building>=MAX_BUILDING)?"Unknown":build_table[obj->building].name );
sprintf( buf+strlen(buf), "@@WCost: @@y%ld.\n\r", obj->cost );
sprintf( buf+strlen(buf), "@@WImage: @@y%s.\n\r", obj->image );
safe_strcat( MSL, buf1, buf );
if ( obj->image && ch->desc->mxp && IS_SET(ch->config,CONFIG_IMAGE) )
{
sprintf( buf, "\e[1z" );
sprintf( buf+strlen(buf), MXPTAG(ch->desc,"IMAGE %s ALIGN=Bottom"), obj->image );
sprintf( buf+strlen(buf), " " );
safe_strcat(MAX_STRING_LENGTH, buf1, buf );
}
safe_strcat( MSL, buf1, "@@WObject Values:\n\r" );
for ( cnt = 0; cnt < MAX_OBJECT_VALUES; cnt++ )
{
sprintf( buf, "@@W[Value%-2d: @@y%6d@@W] %s",
cnt, obj->value[cnt],
rev_table_lookup( tab_value_meanings, (obj->item_type * MAX_OBJECT_VALUES ) + cnt ) );
safe_strcat( MSL, buf1, buf );
if ( is_name( "ArmorType", rev_table_lookup( tab_value_meanings, ( obj->item_type * MAX_OBJECT_VALUES ) + cnt ) ) )
{
foo = ( obj->value[cnt] == -2 ) ? "All" : ( obj->value[cnt] == 1 ) ? "Bulletproof" : (obj->value[cnt] == 2) ? "Blastproof" : (obj->value[cnt] == 3 ) ? "Acidproof" : ( obj->value[cnt] == 4 ) ? "Flameproof" : (obj->value[cnt]==5) ? "Laserproof" : (obj->value[cnt] == -1) ? "General" : "INVALID!";
if ( foo[0] == '\0' )
sprintf( buf, " @@R(INVALID!)@@g\n\r" );
else
sprintf( buf, " @@y(%s)@@g\n\r", foo );
}
if ( !str_cmp( "Main Type", rev_table_lookup( tab_value_meanings, ( obj->item_type * MAX_OBJECT_VALUES ) + cnt ) ) )
{
foo = ( obj->value[cnt] == -2 ) ? "All" : ( obj->value[cnt] == 1 ) ? "Bulletproof" : (obj->value[cnt] == 2) ? "Blastproof" : (obj->value[cnt] == 3 ) ? "Acidproof" : ( obj->value[cnt] == 4 ) ? "Flameproof" : (obj->value[cnt]==5) ? "Laserproof" : (obj->value[cnt] == -1) ? "General" : "INVALID!";
if ( foo[0] == '\0' )
sprintf( buf, " @@R(INVALID!)@@g\n\r" );
else
sprintf( buf, " @@y(%s)@@g\n\r", foo );
}
else if ( is_name( "Building", rev_table_lookup( tab_value_meanings, ( obj->item_type * MAX_OBJECT_VALUES ) + cnt ) ) )
{
sprintf( buf, " @@y(%s)@@g\n\r", (obj->value[cnt]<MAX_BUILDING && obj->value[cnt]>0) ? build_table[obj->value[cnt]].name : "Invalid" );
}
else if ( is_name( "AmmoType", rev_table_lookup( tab_value_meanings, ( obj->item_type * MAX_OBJECT_VALUES ) + cnt ) ) )
{
sprintf( buf, " @@y(%s)@@g\n\r", (obj->value[cnt]>= 0 && obj->value[cnt]<MAX_AMMO) ? clip_table[obj->value[cnt]].name : "Invalid" );
}
else if ( is_name( "Vehicle", rev_table_lookup( tab_value_meanings, ( obj->item_type * MAX_OBJECT_VALUES ) + cnt ) ) )
{
if ( obj->value[cnt] > 0 && obj->value[cnt] < MAX_VEHICLE )
foo = vehicle_desc[obj->value[cnt]];
else
foo = "INVALID!";
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" );
safe_strcat( MSL, buf1, buf );
}
send_to_char( buf1, ch );
if (obj->item_type == ITEM_WEAPON && (obj->value[cnt]>= 0 && obj->value[cnt]<MAX_AMMO))
{
sprintf( buf, "\n\r@@W%-10s PDam: %d BDam: %d Speed: %d\n\r Hit %%: %d Explodes: %d@@g\n\r",
clip_table[obj->value[2]].name,
clip_table[obj->value[2]].dam+obj->value[7],
clip_table[obj->value[2]].builddam+obj->value[8],
clip_table[obj->value[2]].speed+obj->value[9],
clip_table[obj->value[2]].miss+obj->value[10],
clip_table[obj->value[2]].explode
);
send_to_char(buf,ch);
}
return;
}
#define DISPLAY_BRIEFDOORS 1
#define DISPLAY_RESETS 2
#define DISPLAY_FULLDOORS 4
#define DISPLAY_DESC 8
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_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 ) );
safe_strcat( MSL, 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_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;
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 heat 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;
}
/*
* Snarf the value (which need not be numeric).
*/
value = atol( arg3 );
/*
* Set something.
*/
if ( !str_prefix("value",arg2))
{
// num=arg2[5]-'0';
num = atoi(arg2+5);
if (num<0 || num>=MAX_OBJECT_VALUES)
{
sprintf( buf, "Value%d: ", num );
send_to_char(buf,ch);
send_to_char("Value0-14.\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' || arg2[1]=='1'))
{
// num=arg2[1]-'0';
num = atoi(arg2+1);
if ( num<0 || num>=MAX_OBJECT_VALUES)
{
send_to_char("v0-v14.\n\r",ch);
return;
}
if ( value == -999 )
value = pObj->value[num]+1;
pObj->value[num]=value;
return;
}
if ( !str_cmp( arg2, "extra" ) )
{
num=1;
argn=arg3;
/*
if (argn[0]=='+')
{
num=1;
argn++;
}
if (argn[0]=='-')
{
num=0;
argn++;
}
*/
value= multi_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;
}
pObj->extra_flags ^= value;
sprintf( buf, "New values for @@WExtra bits: @@y%s. \n\r",
bit_table_lookup( tab_obj_flags, pObj->extra_flags ) );
send_to_char( buf, ch );
/*
if (num==1)
SET_BIT(pObj->extra_flags,value);
else
REMOVE_BIT(pObj->extra_flags,value);
*/
return;
}
if ( !str_cmp( arg2, "wear" ) )
{
num=1;
argn=arg3;
/*
if (argn[0]=='+')
{
num=1;
argn++;
}
if (argn[0]=='-')
{
num=0;
argn++;
}
*/
value = multi_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;
}
pObj->wear_flags ^= value;
sprintf( buf, "New values for @@WWear bits: @@y%s. @@N\n\r",
bit_table_lookup( tab_wear_flags, pObj->wear_flags ) );
send_to_char( buf, ch );
/*
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;
}
pObj->item_type=value;
return;
}
if ( !str_cmp( arg2, "weight" ) )
{
pObj->weight = value;
return;
}
if ( !str_cmp( arg2, "heat" ) )
{
pObj->heat = value;
return;
}
if ( !str_cmp( arg2, "building" ) )
{
if ( !is_number(arg3) )
{
int i;
for ( i=0;i<MAX_BUILDING;i++ )
{
if ( !str_prefix(arg3,build_table[i].name) )
{
value=i;
}
}
}
if ( value < 0 || value >= MAX_BUILDING )
{
send_to_char( "No such building.\n\r", ch );
return;
}
pObj->building = value;
return;
}
if ( !str_cmp( arg2, "cost" ) )
{
pObj->cost = value;
return;
}
if ( !str_cmp( arg2, "image" ) )
{
if ( !str_cmp(arg3,"remove") )
{
free_string(pObj->image);
pObj->image = NULL;
return;
}
build_strdup(&pObj->image,arg3,TRUE,ch);
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;
}
/*
* Generate usage message.
*/
build_setobject( ch, "" );
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 ( ch->trust <= LEVEL_IMMORTAL )
{
if ( IS_SET(ch->act, PLR_BUILDER) )
REMOVE_BIT(ch->act, PLR_BUILDER);
}
if ( !IS_SET( ch->act, PLR_BUILDER ) )
{
send_to_char( "You aren't allowed to build!\n\r", ch );
return;
}
/* Test for BUILD MONITOR LOG */
sprintf( log_buf, "Log: %s has entered the Builder.", ch->name);
monitor_chan( ch, log_buf, MONITOR_BUILD );
ch->position=POS_BUILDING;
send_to_char("Building commands are now operative. Type stop to stop building.\n\r",ch);
}
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;
int looper;
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_trust(ch) <= 81 && (vnum<1101 || vnum>1199) )
{
send_to_char( "Your vnums are 1101 to 1199.\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->name = str_dup(arg2);
pObjIndex->short_descr = &str_empty[0];
pObjIndex->description = &str_empty[0];
pObjIndex->owner = &str_empty[0];
pObjIndex->image = &str_empty[0];
pObjIndex->level = 1;
pObjIndex->item_type = 1;
pObjIndex->extra_flags = 0;
pObjIndex->wear_flags = 0;
for ( looper = 0; looper < 10; looper++ )
pObjIndex->value[looper] = 0;
pObjIndex->weight = 1;
pObjIndex->heat = 1;
pObjIndex->building = -1;
pObjIndex->cost = 1;
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;
}
int old_ovnum=0;
void build_delwarn( CHAR_DATA *ch, char *argument )
{
send_to_char( "You must spell it out completely.\n\r", ch);
return;
}
void build_delobject( CHAR_DATA *ch, char *argument )
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
AREA_DATA * pArea;
CHAR_DATA *vch;
OBJ_INDEX_DATA * pObjIndex;
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);
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 = ch->in_room->area;
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);
}
/* Now delete structure */
PUT_FREE(pObjIndex, oid_free);
top_obj_index--;
send_to_char("Done.\n\r",ch);
return;
}
void build_help(CHAR_DATA * ch,char * argument)
{
char buf[MAX_STRING_LENGTH];
HELP_DATA *pHelp;
if ( argument[0] != '\0' ) /* If an argument supplied... */
{
sprintf( buf, "BUILD_%s", argument ); /* Format text to send */
for ( pHelp = first_help; pHelp != NULL; pHelp = pHelp->next )
{
if ( pHelp->level > get_trust( ch ) )
continue;
if ( is_name( buf, pHelp->keyword ) )
{
do_help( ch, buf ); /* Try and find BUILD_<helpname> in helps */
return;
}
}
do_help( ch, argument );
return;
}
do_help( ch, "build_summary" );
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';
safe_strcat( MSL, filename,STRING_FILE_DIR);
safe_strcat( MSL, 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);
safe_strcat( MSL, *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
{
int i;
char arg[MSL];
bool fAll = FALSE;
OBJ_INDEX_DATA *pObjIndex;
if ( !str_prefix("next",argument) )
{
argument = one_argument(argument,arg);
if ( argument[0] == '\0' )
fAll = TRUE;
for (i=ch->build_vnum+1;i<32766;i++ )
{
if ( (pObjIndex = get_obj_index(i)) == NULL )
continue;
if ( fAll || is_name( argument, tab_item_types[(pObjIndex->item_type)-1 ].text ) )
{
ch->build_vnum = i;
break;
}
}
}
else
{
for (i=ch->build_vnum+1;i<32766;i++ )
{
if ( (pObjIndex = get_obj_index(i)) == NULL )
continue;
if ( fAll || is_name( argument,pObjIndex->name ) )
{
ch->build_vnum = i;
break;
}
}
}
}
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_bedit( CHAR_DATA *ch, char *argument )
{
int i;
if ( get_trust(ch) < 83 )
{
send_to_char( "You may not use the building-edit option.\n\r", ch );
return;
}
ch->act_build = ACT_BUILD_BEDIT;
ch->build_vnum = -1;
if ( is_number( argument ) )
{
ch->build_vnum = atoi( argument );
if ( ch->build_vnum >= MAX_BUILDING || ch->build_vnum < 1 )
ch->build_vnum = -1;
}
else
{
for ( i=0;i<MAX_BUILDING;i++ )
if ( !str_prefix(argument,build_table[i].name) )
{
ch->build_vnum = i;
break;
}
}
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 */
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_BEDIT:
if ( vnum < 0 || vnum >= MAX_BUILDING )
{
sprintf( buf2, "No such building.\n\r" );
found = FALSE;
}
else
sprintf( buf2, "Building exists: %s\n\r", build_table[vnum].name );
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_BEDIT:
if ( ch->build_vnum == -1 )
send_to_char( "No vnum has been selected!\n\r", ch );
else
{
sprintf( buf, "%d", ch->build_vnum );
show_building_info(ch,ch->build_vnum);
}
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_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, "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 ( !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( " 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];
if ( ch->build_vnum == -1 )
{
send_to_char( "No vnum is set!!\n\r", ch );
return;
}
switch( ch->act_build )
{
case ACT_BUILD_OEDIT:
sprintf( buf, "%d %s", ch->build_vnum, argument );
build_setobject( ch, buf );
break;
case ACT_BUILD_BEDIT:
sprintf( buf, "%d %s", ch->build_vnum, argument );
build_setbuilding( ch, buf );
break;
}
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 armor\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 < 10; foo++ )
{
if ( !str_cmp(rev_table_lookup(tab_value_meanings, value + foo),"Unused" ) )
continue;
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_listbuildings( CHAR_DATA *ch, char *argument )
{
int i;
char buf[MSL];
for ( i = 1;i<MAX_BUILDING;i++ )
{
sprintf( buf, "%s%d. %s\n\r", build_table[i].disabled?"@@e":"@@W",i, build_table[i].name );
send_to_char( buf, ch );
}
return;
}
int get_dir(char dir)
{
char * temp;
if ( dir=='\0'
|| (temp=strchr(cDirs,dir))==NULL)
return -1;
return temp-cDirs;
}
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 );
safe_strcat( MSL, used, buf );
foo = curvnum;
last = 1;
break;
case 1:
break;
case 2:
if ( foo != curvnum-1 )
{
sprintf( buf, "-%d", curvnum-1 );
safe_strcat( MSL, free, buf );
}
sprintf( buf, " %d", curvnum );
safe_strcat( MSL, used, buf );
foo = curvnum;
last = 1;
}
}
else
{
switch( last )
{
case 0:
sprintf( buf, "%d", curvnum );
safe_strcat( MSL, free, buf );
foo = curvnum;
last = 2;
break;
case 1:
if ( foo != curvnum -1 )
{
sprintf( buf, "-%d", curvnum-1 );
safe_strcat( MSL, used, buf );
}
sprintf( buf, " %d", curvnum );
safe_strcat( MSL, 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 );
safe_strcat( MSL, used, buf );
break;
case 2:
if ( foo != curvnum -1 )
{
sprintf( buf, "-%d.", curvnum-1 );
safe_strcat( MSL, used, buf );
}
sprintf( buf, " %d.", curvnum );
safe_strcat( MSL, free, buf );
break;
}
}
else
{
switch( last )
{
case 1:
if ( foo != curvnum -1 )
{
sprintf( buf, "-%d.", curvnum-1 );
safe_strcat( MSL, used, buf );
}
sprintf( buf, " %d.", curvnum );
safe_strcat( MSL, free, buf );
break;
case 2:
if ( foo != curvnum -1 )
sprintf( buf, "-%d.", curvnum );
else
sprintf( buf, " %d.", curvnum );
safe_strcat( MSL, 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;
}
/** 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_keyhelp( CHAR_DATA *ch, char *argument )
{
HELP_DATA *pHelp;
AREA_DATA *area;
BUILD_DATA_LIST *plist;
char arg[MAX_STRING_LENGTH];
char arg2[MAX_STRING_LENGTH];
int number;
int count;
argument = one_argument(argument,arg2);
number = number_argument( arg2, arg );
count =0;
if ( arg[0] == '\0' )
{
send_to_char( "Usage: KEYHELP <keyword> <new keywords>\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 ) || pHelp->keyword[0] == '\0' )
&& ( ++count == number ) )
break;
if ( pHelp == NULL )
{
send_to_char( "Couldn't find that keyword.\n\r", ch );
return;
}
if ( argument[0] == '\0' )
mreturn ("Change it to what?\n\r", ch );
build_strdup( &pHelp->keyword, argument, 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;
AREA_DATA *area;
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;
/* find helps area, or use system if not set */
for ( area = first_area; area; area = area->next )
if ( !str_cmp( area->keyword, "helps" ) )
break;
if ( area == NULL )
area = first_area;
LINK(pList, area->first_area_help_text,
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 build_delhelp( 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: DELHELP <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;
}
/* 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 )
{
send_to_char( "GONE!\n\r", ch );
UNLINK(plist, area->first_area_help_text, area->last_area_help_text, next, prev);
PUT_FREE(plist, build_free);
top_help--;
UNLINK( pHelp, first_help, last_help, next, prev);
PUT_FREE( pHelp, help_free );
area_modified( area );
break;
}
}
}
}
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: 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, "obj" ) )
{
OBJ_INDEX_DATA *obj;
OBJ_INDEX_DATA *this_obj;
int looper;
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;
}
/* 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;
for ( looper = 0; looper < MAX_OBJECT_VALUES; looper++ )
this_obj->value[looper] = obj->value[looper];
this_obj->weight = obj->weight;
this_obj->heat = obj->heat;
this_obj->building = obj->building;
this_obj->cost = obj->cost;
if ( this_obj->image != NULL )
free_string(this_obj->image);
this_obj->image = str_dup(obj->image);
send_to_char( "Object cloned.\n\r", ch );
return;
}
return;
}
void build_setbuilding( CHAR_DATA *ch, char *argument )
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
int value,num,type,i;
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( "\n\r", ch );
send_to_char( "Numeric fields:\n\r", ch );
send_to_char( " hp shield rank iron copper gold\n\r", ch );
send_to_char( " silver rocks sticks logs max\n\r", ch );
send_to_char( "\n\r", ch );
send_to_char( "String fields:\n\r", ch );
send_to_char( " name symbol requires buildon help\n\r", ch );
return;
}
if ( ( type = atoi(arg1) ) < 1 || type >= MAX_BUILDING )
{
send_to_char( "Illegal building number.\n\r", ch );
return;
}
if ( !str_cmp("reload",arg2))
{
send_to_char("Reloading...\n\r", ch );
load_building_t();
send_to_char( "Reloaded.\n\r", ch );
return;
}
if ( !str_cmp("save",arg2))
{
send_to_char("Saving...\n\r",ch);
save_building_table();
send_to_char("Saved.\n\r",ch);
return;
}
if ( !str_cmp("disable",arg2))
{
build_table[type].disabled = !build_table[type].disabled;
if ( build_table[type].disabled )
send_to_char( "Building disabled!!\n\r", ch );
else
send_to_char( "Building re-enabled.\n\r", ch );
return;
}
/*
* Snarf the value (which need not be numeric).
*/
if ( arg3[0] == '\0' )
{
send_to_char( "You need to provide a new value.\n\r", ch );
return;
}
value = atol( arg3 );
/*
* Set something.
*/
if ( !str_prefix("hp",arg2))
{
build_table[type].hp = value;
return;
}
else if ( !str_prefix("shield",arg2))
{
build_table[type].shield = value;
return;
}
else if ( !str_prefix("v10",arg2))
{
build_table[type].value[10] = value;
return;
}
else if ( !str_prefix("v0",arg2))
{
build_table[type].value[0] = value;
return;
}
else if ( !str_prefix("v1",arg2))
{
build_table[type].value[1] = value;
return;
}
else if ( !str_prefix("v2",arg2))
{
build_table[type].value[2] = value;
return;
}
else if ( !str_prefix("v3",arg2))
{
build_table[type].value[3] = value;
return;
}
else if ( !str_prefix("v4",arg2))
{
build_table[type].value[4] = value;
return;
}
else if ( !str_prefix("v5",arg2))
{
build_table[type].value[5] = value;
return;
}
else if ( !str_prefix("v6",arg2))
{
build_table[type].value[6] = value;
return;
}
else if ( !str_prefix("v7",arg2))
{
build_table[type].value[7] = value;
return;
}
else if ( !str_prefix("v8",arg2))
{
build_table[type].value[8] = value;
return;
}
else if ( !str_prefix("v9",arg2))
{
build_table[type].value[9] = value;
return;
}
else if ( !str_prefix("max",arg2))
{
build_table[type].max = value;
return;
}
else if ( !str_prefix("cost",arg2))
{
build_table[type].cost = value;
return;
}
else if ( !str_prefix("tick",arg2))
{
build_table[type].tick = value;
return;
}
else if ( !str_prefix( arg2, "rank" ) )
{
build_table[type].rank = value;
return;
}
else if ( !str_prefix( arg2, "neutral" ) )
{
build_table[type].military = !build_table[type].military;
send_to_char( "Toggled.\n\r", ch );
return;
}
else if ( !str_prefix( arg2, "type" ) )
{
extern char *building_title[MAX_BUILDING_TYPES];
char buf[MSL];
if ( arg3[0] == '\0' )
{
for ( i=0;i<MAX_BUILDING_TYPES;i++ )
{
sprintf( buf, "%s\n\r", building_title[i] );
send_to_char(buf,ch);
}
return;
}
for ( i=0;i<=MAX_BUILDING_TYPES;i++ )
{
if ( i >= MAX_BUILDING_TYPES )
continue;
if ( !str_prefix(arg3,building_title[i]) )
{
value = i;
break;
}
}
if ( value < 0 || value >= MAX_BUILDING_TYPES )
{
send_to_char( "Invalid type.\n\r", ch );
return;
}
build_table[type].act = value;
return;
}
else if ( !str_prefix( arg2, "levelrequirements" ) )
{
build_table[type].requirements_l = value;
return;
}
else if ( !str_prefix( arg2, "name" ) )
{
free_string(build_table[type].name);
build_table[type].name = str_dup(strip_out(arg3,"~"));
return;
}
else if ( !str_prefix( arg2, "symbol" ) )
{
free_string(build_table[type].symbol);
build_table[type].symbol = str_dup(strip_out(arg3,"~"));
return;
}
else if ( !str_prefix( arg2, "help" ) )
{
free_string(build_help_table[type].help);
if ( !str_cmp(arg3,"$edit") )
build_strdup( &build_help_table[type].help, "$edit", TRUE, ch );
else
build_help_table[type].help = str_dup(strip_out(arg3,"~"));
return;
}
else if ( !str_prefix( arg2, "desc" ) )
{
free_string(build_table[type].desc);
if ( !str_cmp(arg3,"$edit") )
build_strdup( &build_table[type].desc, "$edit", TRUE, ch );
else
build_table[type].desc = str_dup(strip_out(arg3,"~"));
return;
}
else if ( !str_prefix( arg2, "requires" ) )
{
for ( i=0;i<MAX_BUILDING;i++ )
{
if ( !str_prefix(arg3,build_table[i].name) )
{
if ( i == type )
{
send_to_char( "You can't set it to require itself.\n\r", ch );
return;
}
build_table[type].requirements = i;
send_to_char( "Set.\n\r", ch );
return;
}
}
send_to_char( "No such building.\n\r", ch );
return;
}
else if ( !str_prefix( arg2, "buildon" ) )
{
bool ok = FALSE;
bool ter[SECT_MAX];
int open = -1;
for ( num=0;num<SECT_MAX;num++ )
ter[num] = FALSE;
for ( i=0;i<SECT_MAX;i++ )
{
if ( !str_prefix(arg3,wildmap_table[i].name) )
{
ok = TRUE;
break;
}
}
if ( !ok )
{
send_to_char( "No such sector type.\n\r", ch );
return;
}
ok = FALSE;
for ( num=0;num<MAX_BUILDON;num++ )
{
if ( (ter[build_table[type].buildon[num]] || build_table[type].buildon[num] < 0 || build_table[type].buildon[num] > SECT_MAX ) && open == -1 )
open = num;
if ( build_table[type].buildon[num] == i )
{
build_table[type].buildon[num] = -1;
if ( !ok )
{
send_to_char( "Sector removed.\n\r", ch );
ok = TRUE;
}
}
if ( build_table[type].buildon[num] >= 0 && build_table[type].buildon[num] < SECT_MAX )
ter[build_table[type].buildon[num]] = TRUE;
}
if ( ok )
return;
if ( open == -1 )
{
send_to_char( "No open slots, remove at least one sector type to add this one.\n\r", ch );
return;
}
build_table[type].buildon[open] = i;
send_to_char( "Sector added.\n\r", ch );
return;
}
else if ( !str_cmp( arg2, "change_all_sectors" ) )
{
char buf[MSL];
int oldsect=-1,newsect=-1;
int changes = 0;
argument = one_argument(argument,arg3);
if ( argument[0] == '\0' )
{
send_to_char( "Change the sector to what new type?\n\r", ch );
return;
}
for ( i=0;i<SECT_MAX;i++ )
{
if ( !str_prefix(arg3,wildmap_table[i].name) && oldsect == -1 )
{
oldsect = i;
}
else if ( !str_prefix(argument,wildmap_table[i].name) && newsect == -1 )
{
newsect = i;
}
}
if ( oldsect == -1 || newsect == -1 )
{
send_to_char( "One of the sectors you inputted was invalid.\n\r", ch );
return;
}
for ( type = 1;type < MAX_BUILDING;type++ )
{
for ( num=0;num<5;num++ )
{
if ( build_table[type].buildon[num] == oldsect )
{
build_table[type].buildon[num] = newsect;
changes++;
}
}
}
sprintf ( buf, "%d changes were made.\n\r", changes );
send_to_char(buf,ch);
return;
}
build_setbuilding(ch,"");
return;
}
void build_addbuilding( CHAR_DATA *ch, char *argument )
{
int i=MAX_BUILDING,j;
if ( MAX_BUILDING >= MAX_POSSIBLE_BUILDING )
{
send_to_char( "No more building slots to add.\n\rPlease change MAX_POSSIBLE_BUILDINGS in the code.\n\r", ch );
return;
}
if ( build_table[i].name != NULL)
free_string(build_table[i].name);
if ( build_table[i].desc != NULL)
free_string(build_table[i].desc);
if ( build_table[i].symbol != NULL)
free_string(build_table[i].symbol);
if ( build_help_table[i].help != NULL)
free_string(build_help_table[i].help);
build_table[i].type = i;
build_table[i].name = str_dup(" ");
build_table[i].symbol = str_dup("[ ]");
build_table[i].desc = str_dup(" ");
build_help_table[i].help = str_dup(" ");
build_table[i].hp = 1;
build_table[i].shield = 1;
build_table[i].cost = 0;
for ( j=0;j<MAX_BUILDON;j++ )
build_table[i].buildon[j] = 1;
build_table[i].requirements = 1;
build_table[i].requirements_l = 1;
build_table[i].military = 1;
build_table[i].rank = 0;
build_table[i].act = 0;
build_table[i].max = 100;
build_table[i].disabled = TRUE;
build_table[i].tick = 10;
ch->build_vnum = i;
MAX_BUILDING = MAX_BUILDING + 1;
send_to_char( "Building added.\n\r", ch );
return;
}