/*************************************************************************** * 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. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * _/ _/_/_/ _/ _/ _/ ACK! MUD is modified * * _/_/ _/ _/ _/ _/ Merc2.0/2.1/2.2 code * * _/ _/ _/ _/_/ _/ (c)Stephen Dooley 1994 * * _/_/_/_/ _/ _/ _/ "This mud has not been * * _/ _/ _/_/_/ _/ _/ _/ tested on animals." * * * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ #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 no more than %d in room.\n\r",pObj->vnum,pObj->name, pReset->arg2); 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> <max number in room>\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=( is_number( arg3 ) ? atoi( arg3 ) : 1 ); 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; MOB_INDEX_DATA *mob; bool found; short 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: 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; }