/*************************************************************************** * 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 Envy Diku Mud, you must comply with * * the original Diku license in 'license.doc', the Merc license in * * 'license.txt', as well as the Envy license in 'license.nvy'. * * In particular, you may not remove either of these copyright notices. * * * * 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. * * * * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * * * * Code Adapted and Improved by Abandoned Realms Mud * * and Aabahran: The Forsaken Lands Mud by Virigoth * * * * Continued Production of this code is available at www.flcodebase.com * ***************************************************************************/ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #include "olc.h" #include "cabal.h" #include "recycle.h" #include "tome.h" #include "clan.h" #define DIF(a,b) (~((~a)|(b))) AREA_DATA *get_area_data args( ( int vnum ) ); extern int top_reset; extern int top_area; extern int top_exit; extern int top_ed; extern int top_room; extern int top_mprog_index; extern int top_oprog_index; extern int top_rprog_index; extern char *string_space; extern char *top_string; PROG_CODE * mpcode_free; PROG_CODE * opcode_free; PROG_CODE * rpcode_free; AREA_DATA * area_free; EXTRA_DESCR_DATA * extra_descr_free; EXIT_DATA * exit_free; ROOM_INDEX_DATA * room_index_free; OBJ_INDEX_DATA * obj_index_free; SHOP_DATA * shop_free; MOB_INDEX_DATA * mob_index_free; RESET_DATA * reset_free; HELP_DATA * help_free; HELP_DATA * help_last; void free_extra_descr( EXTRA_DESCR_DATA *pExtra ); void free_affect( AFFECT_DATA *af ); /* Executed from comm.c. Minimizes compiling when changes are made. */ bool run_olc_editor( DESCRIPTOR_DATA *d ) { switch ( d->editor ) { case ED_AREA: aedit( d->character, d->incomm ); break; case ED_ROOM: redit( d->character, d->incomm ); break; case ED_OBJECT: oedit( d->character, d->incomm ); break; case ED_MOBILE: medit( d->character, d->incomm ); break; case ED_ARMY: armedit(d->character, d->incomm ); break; case ED_TRAP: tedit( d->character, d->incomm ); break; case ED_HELP: hedit( d->character, d->incomm ); break; case ED_CABAL: cedit( d->character, d->incomm ); break; case ED_MPCODE: mpedit( d->character, d->incomm );break; case ED_OPCODE: opedit( d->character, d->incomm );break; case ED_RPCODE: rpedit( d->character, d->incomm );break; default: return FALSE; } return TRUE; } char *olc_ed_name( CHAR_DATA *ch ) { static char buf[10]; buf[0] = '\0'; switch (ch->desc->editor) { case ED_AREA: sprintf( buf, "AEdit" ); break; case ED_ROOM: sprintf( buf, "REdit" ); break; case ED_TRAP: sprintf( buf, "TEdit" ); break; case ED_HELP: sprintf( buf, "HEdit" ); break; case ED_CABAL: sprintf( buf, "CEdit" ); break; case ED_OBJECT: sprintf( buf, "OEdit" ); break; case ED_MOBILE: sprintf( buf, "MEdit" ); break; case ED_MPCODE: sprintf( buf, "MPEdit" ); break; case ED_OPCODE: sprintf( buf, "OPEdit" ); break; case ED_RPCODE: sprintf( buf, "RPEdit" ); break; default: sprintf( buf, " " ); break; } return buf; } char *olc_ed_vnum( CHAR_DATA *ch ) { AREA_DATA *pArea; ROOM_INDEX_DATA *pRoom; OBJ_INDEX_DATA *pObj; MOB_INDEX_DATA *pMob; CABAL_INDEX_DATA *pCab; HELP_DATA *pHelp; PROG_CODE *pMprog; PROG_CODE *pOprog; PROG_CODE *pRprog; static char buf[10]; buf[0] = '\0'; switch ( ch->desc->editor ) { case ED_AREA: pArea = (AREA_DATA *)ch->desc->pEdit; sprintf( buf, "%d", pArea ? pArea->vnum : 0 ); break; case ED_ROOM: pRoom = ch->in_room; sprintf( buf, "%d", pRoom ? pRoom->vnum : 0 ); break; case ED_OBJECT: pObj = (OBJ_INDEX_DATA *)ch->desc->pEdit; sprintf( buf, "%d", pObj ? pObj->vnum : 0 ); break; case ED_MOBILE: pMob = (MOB_INDEX_DATA *)ch->desc->pEdit; sprintf( buf, "%d", pMob ? pMob->vnum : 0 ); break; case ED_CABAL: pCab = (CABAL_INDEX_DATA *)ch->desc->pEdit; sprintf( buf, "%d", pCab ? pCab->vnum : 0 ); break; case ED_HELP: pHelp = (HELP_DATA *)ch->desc->pEdit; sprintf( buf, "%d", pHelp ? pHelp->vnum : 0 ); break; case ED_MPCODE: pMprog = (PROG_CODE *)ch->desc->pEdit; sprintf( buf, "%d", pMprog ? pMprog->vnum : 0 ); break; case ED_OPCODE: pOprog = (PROG_CODE *)ch->desc->pEdit; sprintf( buf, "%d", pOprog ? pOprog->vnum : 0 ); break; case ED_RPCODE: pRprog = (PROG_CODE *)ch->desc->pEdit; sprintf( buf, "%d", pRprog ? pRprog->vnum : 0 ); break; default: sprintf( buf, " " ); break; } return buf; } /* Format up the commands from given table. * * Called by show_commands(olc_act.c). */ void show_olc_cmds( CHAR_DATA *ch, const struct olc_cmd_type *olc_table ) { char buf [ MSL ]; char buf1 [ MSL ]; int cmd; int col; buf1[0] = '\0'; col = 0; for (cmd = 0; olc_table[cmd].name != NULL; cmd++) { sprintf( buf, "%-15.15s", olc_table[cmd].name ); strcat( buf1, buf ); if ( ++col % 5 == 0 ) strcat( buf1, "\n\r" ); } if ( col % 5 != 0 ) strcat( buf1, "\n\r" ); send_to_char( buf1, ch ); return; } /* Display all olc commands. * * Called by olc interpreters. */ bool show_commands( CHAR_DATA *ch, char *argument ) { switch (ch->desc->editor) { case ED_AREA: show_olc_cmds( ch, aedit_table ); break; case ED_ROOM: show_olc_cmds( ch, redit_table ); break; case ED_TRAP: show_olc_cmds( ch, tedit_table ); break; case ED_HELP: show_olc_cmds( ch, hedit_table ); break; case ED_CABAL: show_olc_cmds( ch, cedit_table ); break; case ED_OBJECT: show_olc_cmds( ch, oedit_table ); break; case ED_MOBILE: show_olc_cmds( ch, medit_table ); break; case ED_MPCODE: show_olc_cmds( ch, mpedit_table ); break; case ED_OPCODE: show_olc_cmds( ch, opedit_table ); break; case ED_RPCODE: show_olc_cmds( ch, rpedit_table ); break; } return FALSE; } /* Interpreter Table */ const struct olc_cmd_type aedit_table[] = { /* { command function }, */ { "age", aedit_age }, { "bastion", aedit_bastion }, { "builder", aedit_builder }, { "commands", show_commands }, { "create", aedit_create }, { "filename", aedit_file }, { "name", aedit_name }, { "prefix", aedit_prefix }, { "reset", aedit_reset }, { "security", aedit_security }, { "show", aedit_show }, { "vnum", aedit_vnum }, { "lvnum", aedit_lvnum }, { "uvnum", aedit_uvnum }, { "credits", aedit_credits }, { "?", show_help }, { "version", show_version }, { "aflag", aedit_flags }, { "crime", aedit_crime }, { "startroom", aedit_startroom }, { NULL, 0, } }; const struct olc_cmd_type redit_table[] = { /* { command function }, */ { "commands", show_commands }, { "create", redit_create }, { "desc", redit_desc }, { "ndesc", redit_ndesc }, { "ed", redit_ed }, { "format", redit_format }, { "name", redit_name }, { "show", redit_show }, { "heal", redit_heal }, { "mana", redit_mana }, { "watch", redit_watch }, { "temp", redit_temp }, { "cabal", redit_cabal }, { "north", redit_north }, { "south", redit_south }, { "east", redit_east }, { "west", redit_west }, { "up", redit_up }, { "down", redit_down }, { "sector", redit_sector }, { "room", redit_room }, /* New reset commands. */ { "mreset", redit_mreset }, { "oreset", redit_oreset }, { "treset", redit_treset }, { "mlist", redit_mlist }, { "rlist", redit_rlist }, { "olist", redit_olist }, { "mshow", redit_mshow }, { "oshow", redit_oshow }, { "?", show_help }, { "version", show_version }, { "copy", redit_copy }, /* New prog commands */ { "addprog", redit_addrprog }, { "delprog", redit_delrprog }, { NULL, 0, } }; const struct olc_cmd_type oedit_table[] = { /* { command function }, */ { "addaffect", oedit_addaffect }, { "addapply", oedit_addapply }, { "commands", show_commands }, { "cost", oedit_cost }, { "create", oedit_create }, { "delaffect", oedit_delaffect }, { "ed", oedit_ed }, { "long", oedit_long }, { "name", oedit_name }, { "short", oedit_short }, { "show", oedit_show }, { "v0", oedit_value0 }, { "v1", oedit_value1 }, { "v2", oedit_value2 }, { "v3", oedit_value3 }, { "v4", oedit_value4 }, { "weight", oedit_weight }, { "condition", oedit_condition }, { "shots", oedit_condition }, { "material", oedit_material }, { "extra", oedit_extra }, { "wear", oedit_wear }, { "type", oedit_type }, { "level", oedit_level }, { "?", show_help }, { "version", show_version }, { "copy", oedit_copy }, { "cabal", oedit_cabal }, { "race", oedit_race }, { "class", oedit_class }, { "message", oedit_message }, /* new prog commands */ { "addprog", oedit_addoprog }, { "delprog", oedit_deloprog }, { NULL, 0, } }; const struct olc_cmd_type medit_table[] = { /* { command function }, */ { "alignment", medit_align }, { "cabal", medit_cabal }, { "commands", show_commands }, { "create", medit_create }, { "desc", medit_desc }, { "level", medit_level }, { "long", medit_long }, { "name", medit_name }, { "shop", medit_shop }, { "short", medit_short }, { "show", medit_show }, { "spec", medit_spec }, { "sex", medit_sex }, { "act", medit_act }, { "act2", medit_act2 }, { "affect2", medit_affect2 }, { "affect1", medit_affect }, { "armor", medit_ac }, { "imm", medit_imm }, { "res", medit_res }, { "vuln", medit_vuln }, { "off", medit_off }, { "size", medit_size }, { "hitdice", medit_hitdice }, { "manadice", medit_manadice }, { "damdice", medit_damdice }, { "race", medit_race }, { "position", medit_position }, { "gold", medit_gold }, { "hitroll", medit_hitroll }, { "damtype", medit_damtype }, { "group", medit_group }, { "?", show_help }, { "version", show_version }, { "copy", medit_copy }, /* New prog commands */ { "addprog", medit_addmprog }, { "delprog", medit_delmprog }, { NULL, 0, } }; const struct olc_cmd_type armedit_table[] = { /*{ command function }, */ { "?", show_help }, { "create", armedit_create }, { "show", armedit_show }, { "type", armedit_type }, { "cost", armedit_cost }, { "support", armedit_support }, { "flags", armedit_flags }, { "offense", armedit_offense }, { "hitpoints", armedit_hitpoint}, { "armor", armedit_armor }, { "noun", armedit_noun }, { "short", armedit_short }, { "long", armedit_long }, { "description", armedit_descr }, { "copy", armedit_copy }, { NULL, 0, } }; /* trap table */ const struct olc_cmd_type tedit_table[] ={ /*{ command function }, */ { "?", show_help }, { "create", tedit_create }, { "show", tedit_show }, { "name", tedit_name }, { "echo", tedit_echo }, { "oecho", tedit_oecho }, { "level", tedit_level }, { "type", tedit_type }, { "flag", tedit_flag }, { "v0", tedit_v0 }, { "v1", tedit_v1 }, { "v2", tedit_v2 }, { "v3", tedit_v3 }, { "v4", tedit_v4 }, { NULL, 0, } }; /* help table */ const struct olc_cmd_type hedit_table[] ={ /*{ command function }, */ { "?", show_help }, { "create", hedit_create }, { "show", hedit_show }, { "keyword", hedit_key }, { "level", hedit_level }, { "type", hedit_type }, { "text", hedit_text }, { NULL, 0, } }; /* help table */ const struct olc_cmd_type cedit_table[] ={ /*{ command function }, */ { "?", show_help }, { "create", cedit_create }, { "show", cedit_show }, { "name", cedit_name }, { "filename", cedit_file_name }, { "msggate", cedit_msggate }, { "ongate", cedit_ongate }, { "offgate", cedit_offgate }, { "city", cedit_city }, { "enemy", cedit_enemy }, { "anchor", cedit_anchor }, { "guard", cedit_guard }, { "pit", cedit_pit }, { "whoname", cedit_whoname }, { "immortal", cedit_imm }, { "currency", cedit_currency }, { "clan", cedit_clan }, { "members", cedit_members }, { "maxrooms", cedit_max_room }, { "levels", cedit_levels }, { "rank", cedit_rank }, { "franks", cedit_frank }, { "mranks", cedit_mrank }, { "flag", cedit_flag }, { "progress", cedit_progress }, { "align", cedit_align }, { "ethos", cedit_ethos }, { "race", cedit_race }, { "class", cedit_class }, { "skill", cedit_skill }, { "vote", cedit_vote }, { "room", cedit_room }, { "avatar", cedit_avatar }, { "parent", cedit_parent }, { "army", cedit_army }, { "tower", cedit_tower }, { "prefix", cedit_prefix }, { "tax", cedit_tax }, { NULL, 0, } }; /* Returns pointer to area with given vnum. * * Called by do_aedit(olc.c). */ AREA_DATA *get_area_data( int vnum ) { AREA_DATA *pArea; for (pArea = area_first; pArea; pArea = pArea->next ) if (pArea->vnum == vnum) return pArea; return 0; } /* retusn area data by name */ AREA_DATA *get_area_data_str( char* name ){ AREA_DATA *pArea; for (pArea = area_first; pArea; pArea = pArea->next ) if (!str_cmp(pArea->name, name)) return pArea; return 0; } /* Resets builder information on completion. * * Called by aedit, redit, oedit, medit(olc.c) */ bool edit_done( CHAR_DATA *ch ) { ch->desc->pEdit = NULL; ch->desc->editor = 0; return FALSE; } /* Area Interpreter. * * Called by do_aedit. */ void aedit( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; char command[MIL]; char arg[MIL]; int cmd; int value; EDIT_AREA(ch, pArea); smash_tilde( argument ); strcpy( arg, argument ); argument = one_argument( argument, command ); if ( !IS_BUILDER( ch, pArea ) ) { send_to_char( "AEdit: Insufficient security to modify area.\n\r", ch ); edit_done( ch ); return; } if ( !str_cmp(command, "done") ) { edit_done( ch ); return; } if ( !IS_BUILDER( ch, pArea ) ) { interpret( ch, arg ); return; } if ( command[0] == '\0' ) { aedit_show( ch, argument ); return; } if ( ( value = flag_value( area_flags, command ) ) != NO_FLAG ) { TOGGLE_BIT(pArea->area_flags, value); send_to_char( "Flag toggled.\n\r", ch ); SET_BIT( pArea->area_flags, AREA_CHANGED ); return; } for ( cmd = 0; aedit_table[cmd].name != NULL; cmd++ ) if ( !str_prefix( command, aedit_table[cmd].name ) ) { if ( (*aedit_table[cmd].olc_fun) ( ch, argument ) ) { SET_BIT( pArea->area_flags, AREA_CHANGED ); return; } else return; } interpret( ch, arg ); return; } /* Room Interpreter * * Called by do_redit. */ void redit( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *pRoom; AREA_DATA *pArea; char arg[MSL]; char command[MIL]; int cmd; int value; EDIT_ROOM(ch, pRoom); pArea = pRoom->area; smash_tilde( argument ); strcpy( arg, argument ); argument = one_argument( argument, command ); if ( !IS_BUILDER( ch, pArea ) ) { send_to_char( "REdit: Insufficient security to modify room.\n\r", ch ); edit_done( ch ); return; } if ( !str_cmp(command, "done") ) { edit_done( ch ); return; } if ( !IS_BUILDER( ch, pArea ) ) { interpret( ch, arg ); return; } if ( command[0] == '\0' ) { redit_show( ch, argument ); return; } if ( ( value = flag_value( room_flags, command ) ) != NO_FLAG ) { TOGGLE_BIT(pRoom->room_flags, value); SET_BIT( pArea->area_flags, AREA_CHANGED ); send_to_char( "Room flag toggled.\n\r", ch ); return; } if ( ( value = flag_value( room_flags2, command ) ) != NO_FLAG ) { TOGGLE_BIT(pRoom->room_flags2, value); SET_BIT( pArea->area_flags, AREA_CHANGED ); send_to_char( "Room flag toggled.\n\r", ch ); return; } if ( ( value = flag_value( sector_flags, command ) ) != NO_FLAG ) { pRoom->sector_type = value; SET_BIT( pArea->area_flags, AREA_CHANGED ); send_to_char( "Sector type set.\n\r", ch ); return; } for ( cmd = 0; redit_table[cmd].name != NULL; cmd++ ) if ( !str_prefix( command, redit_table[cmd].name ) ) { if ( (*redit_table[cmd].olc_fun) ( ch, argument ) ) { SET_BIT( pArea->area_flags, AREA_CHANGED ); return; } else return; } interpret( ch, arg ); return; } /* Object Interpreter * * Called by do_oedit. */ void oedit( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; OBJ_INDEX_DATA *pObj; char arg[MSL]; char command[MIL]; int cmd; smash_tilde( argument ); strcpy( arg, argument ); argument = one_argument( argument, command ); EDIT_OBJ(ch, pObj); pArea = pObj->area; if ( !IS_BUILDER( ch, pArea ) ) { send_to_char( "OEdit: Insufficient security to modify area.\n\r", ch ); edit_done( ch ); return; } if ( !str_cmp(command, "done") ) { edit_done( ch ); return; } if ( !IS_BUILDER( ch, pArea ) ) { interpret( ch, arg ); return; } if ( command[0] == '\0' ) { oedit_show( ch, argument ); return; } for ( cmd = 0; oedit_table[cmd].name != NULL; cmd++ ) if ( !str_prefix( command, oedit_table[cmd].name ) ) { if ( (*oedit_table[cmd].olc_fun) ( ch, argument ) ) { SET_BIT( pArea->area_flags, AREA_CHANGED ); return; } else return; } interpret( ch, arg ); return; } /* Mobile Interpreter. * * called by do_medit. */ void medit( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; MOB_INDEX_DATA *pMob; char command[MIL]; char arg[MSL]; int cmd; smash_tilde( argument ); strcpy( arg, argument ); argument = one_argument( argument, command ); EDIT_MOB(ch, pMob); pArea = pMob->area; if ( !IS_BUILDER( ch, pArea ) ) { send_to_char( "MEdit: Insufficient security to modify area.\n\r", ch ); edit_done( ch ); return; } if ( !str_cmp(command, "done") ) { edit_done( ch ); return; } if ( !IS_BUILDER( ch, pArea ) ) { interpret( ch, arg ); return; } if ( command[0] == '\0' ) { medit_show( ch, argument ); return; } for ( cmd = 0; medit_table[cmd].name != NULL; cmd++ ) if ( !str_prefix( command, medit_table[cmd].name ) ) { if ( (*medit_table[cmd].olc_fun) ( ch, argument ) ) { SET_BIT( pArea->area_flags, AREA_CHANGED ); return; } else return; } interpret( ch, arg ); return; } /* Amry Interpreter. * * called by do_armedit. */ void armedit( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; ARMY_INDEX_DATA *pai; char command[MIL]; char arg[MSL]; int cmd; smash_tilde( argument ); strcpy( arg, argument ); argument = one_argument( argument, command ); EDIT_ARMY(ch, pai); pArea = pai->area; if ( !IS_BUILDER( ch, pArea ) ) { send_to_char( "MEdit: Insufficient security to modify area.\n\r", ch ); edit_done( ch ); return; } if ( !str_cmp(command, "done") ) { edit_done( ch ); return; } if ( !IS_BUILDER( ch, pArea ) ) { interpret( ch, arg ); return; } if ( command[0] == '\0' ) { armedit_show( ch, argument ); return; } for ( cmd = 0; armedit_table[cmd].name != NULL; cmd++ ) if ( !str_prefix( command, armedit_table[cmd].name ) ){ if ( (*armedit_table[cmd].olc_fun) ( ch, argument ) ){ SET_BIT( pArea->area_flags, AREA_CHANGED ); return; } else return; } interpret( ch, arg ); return; } const struct editor_cmd_type editor_table[] = { /* { command function }, */ { "area", do_aedit }, { "room", do_redit }, { "object", do_oedit }, { "mobile", do_medit }, { "army", do_armedit }, { "trap", do_tedit }, { "help", do_hedit }, { "cabal", do_cedit }, { "mprog", do_mpedit }, { "rprog", do_rpedit }, { "oprog", do_opedit }, { NULL, 0, } }; /* Entry point for all editors. */ void do_olc( CHAR_DATA *ch, char *argument ) { char command[MIL]; int cmd; argument = one_argument( argument, command ); if ( command[0] == '\0' ) { do_help( ch, "olc" ); return; } if ((mud_data.mudport == 6666) && (get_trust(ch) < 60)){ send_to_char("Main port access limited to Implementor trust.\n\r", ch); return; } for ( cmd = 0; editor_table[cmd].name != NULL; cmd++ ) if ( !str_prefix( command, editor_table[cmd].name ) ) { (*editor_table[cmd].do_fun) ( ch, argument ); return; } do_help( ch, "olc" ); return; } /* Entry point for editing area_data. */ void do_aedit( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; int value; char value2[MSL]; char arg[MSL]; pArea = ch->in_room->area; argument = one_argument(argument,arg); if ( is_number( arg ) ) { value = atoi( arg ); if ( !( pArea = get_area_data( value ) ) ) { send_to_char( "That area vnum does not exist.\n\r", ch ); return; } } else if ( !str_cmp( arg, "create" ) ) { if (!IS_NPC(ch) && (ch->pcdata->security < 9) ) { send_to_char("Insufficient security to modify area.\n\r",ch); return; } argument = one_argument(argument,value2); value = atoi (value2); if (get_area_data(value) != NULL) { send_to_char("Esa area ya existe!",ch); return; } pArea = new_area(); area_last->next = pArea; area_last = pArea; SET_BIT( pArea->area_flags, AREA_ADDED ); send_to_char("Area created.\n\r",ch); } if (!IS_BUILDER(ch,pArea)) { send_to_char("Insufficient security to modify area.\n\r",ch); return; } ch->desc->pEdit = (void *)pArea; ch->desc->editor = ED_AREA; return; } /* Entry point for editing room_index_data. */ void do_redit( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *pRoom, *pRoom2; char arg1[MSL]; argument = one_argument( argument, arg1 ); pRoom = ch->in_room; if ( !str_cmp( arg1, "reset" ) ) { if ( !IS_BUILDER( ch, pRoom->area ) ) { send_to_char("Insufficient security to modify room.\n\r",ch); return; } reset_room( pRoom ); send_to_char( "Room reset.\n\r", ch ); return; } else if ( !str_cmp( arg1, "create" ) ) { if ( argument[0] == '\0' || atoi( argument ) == 0 ) { send_to_char( "Syntax: edit room create [vnum]\n\r", ch ); return; } if ( redit_create( ch, argument ) ) { char_from_room( ch ); char_to_room( ch, ch->desc->pEdit ); SET_BIT( pRoom->area->area_flags, AREA_CHANGED ); pRoom = ch->in_room; } } else { pRoom2 = get_room_index(atoi(arg1)); if ( (pRoom2 != NULL) && IS_BUILDER(ch,pRoom2->area) ) { char_from_room( ch ); char_to_room( ch, pRoom2 ); pRoom = ch->in_room; } else if (atoi(arg1) != 0) { send_to_char("Insufficient security to modify room.\n\r",ch); return; } } if ( !IS_BUILDER( ch, pRoom->area ) ) { send_to_char("Insufficient security to modify area.\n\r",ch); return; } ch->desc->pEdit = (void *)pRoom; ch->desc->editor = ED_ROOM; return; } /* Entry point for editing obj_index_data. */ void do_oedit( CHAR_DATA *ch, char *argument ) { OBJ_INDEX_DATA *pObj; AREA_DATA *pArea; char arg1[MSL]; int value; if ( IS_NPC(ch) ) return; argument = one_argument( argument, arg1 ); if ( is_number( arg1 ) ) { value = atoi( arg1 ); if ( !( pObj = get_obj_index( value ) ) ) { send_to_char( "OEdit: That vnum does not exist.\n\r", ch ); return; } if ( !IS_BUILDER( ch, pObj->area ) ) { send_to_char("Insufficient security to modify objects.\n\r",ch); return; } ch->desc->pEdit = (void *)pObj; ch->desc->editor = ED_OBJECT; return; } else if ( !str_cmp( arg1, "create" ) ) { value = atoi( argument ); if ( argument[0] == '\0' || value == 0 ) { send_to_char( "Syntax: edit object create [vnum]\n\r", ch ); return; } pArea = get_vnum_area( value ); if ( !pArea ) { send_to_char( "OEdit: That vnum is not assigned an area.\n\r", ch ); return; } if ( !IS_BUILDER( ch, pArea ) ) { send_to_char("Insufficient security to modify objects.\n\r",ch); return; } if ( oedit_create( ch, argument ) ) { SET_BIT( pArea->area_flags, AREA_CHANGED ); ch->desc->editor = ED_OBJECT; } return; } send_to_char( "OEdit: There is no default object to edit.\n\r", ch ); return; } /* Entry point for editing mob_index_data. */ void do_medit( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMob; AREA_DATA *pArea; int value; char arg1[MSL]; argument = one_argument( argument, arg1 ); if ( is_number( arg1 ) ) { value = atoi( arg1 ); if ( !( pMob = get_mob_index( value ) )) { send_to_char( "MEdit: That vnum does not exist.\n\r", ch ); return; } if ( !IS_BUILDER( ch, pMob->area ) ) { send_to_char("Insufficient security to modify mobs.\n\r",ch); return; } ch->desc->pEdit = (void *)pMob; ch->desc->editor = ED_MOBILE; return; } else if ( !str_cmp( arg1, "create" ) ) { value = atoi( argument ); if ( arg1[0] == '\0' || value == 0 ) { send_to_char( "Syntax: edit mobile create [vnum]\n\r", ch ); return; } pArea = get_vnum_area( value ); if ( !pArea ) { send_to_char( "OEdit: That vnum is not assigned an area.\n\r", ch ); return; } if ( !IS_BUILDER( ch, pArea ) ) { send_to_char( "Insufficient security to edit mobs.\n\r" , ch ); return; } if ( medit_create( ch, argument ) ) { SET_BIT( pArea->area_flags, AREA_CHANGED ); ch->desc->editor = ED_MOBILE; } return; } send_to_char( "MEdit: There is no default mobile to edit.\n\r", ch ); return; } /* Entry point for editing army_index_data. */ void do_armedit( CHAR_DATA *ch, char *argument ) { ARMY_INDEX_DATA *pai; AREA_DATA *pArea; int value; char arg1[MSL]; argument = one_argument( argument, arg1 ); if ( is_number( arg1 ) ) { value = atoi( arg1 ); if ( !( pai = get_army_index( value ) )) { send_to_char( "ArmEdit: That vnum does not exist.\n\r", ch ); return; } if ( !IS_BUILDER( ch, pai->area ) ) { send_to_char("Insufficient security to modify armies.\n\r",ch); return; } ch->desc->pEdit = (void *)pai; ch->desc->editor = ED_ARMY; return; } else if ( !str_cmp( arg1, "create" ) ) { value = atoi( argument ); if ( arg1[0] == '\0' || value == 0 ) { send_to_char( "Syntax: edit area create [vnum]\n\r", ch ); return; } pArea = get_vnum_area( value ); if ( !pArea ) { send_to_char( "OEdit: That vnum is not assigned an area.\n\r", ch ); return; } if ( !IS_BUILDER( ch, pArea ) ) { send_to_char( "Insufficient security to edit mobs.\n\r" , ch ); return; } if ( armedit_create( ch, argument ) ) { SET_BIT( pArea->area_flags, AREA_CHANGED ); ch->desc->editor = ED_ARMY; } return; } send_to_char( "ArmEdit: There is no default mobile to edit.\n\r", ch ); return; } void do_tedit(CHAR_DATA *ch, char *argument){ TRAP_INDEX_DATA* pTrap; char command[MIL]; argument = one_argument(argument, command); if( is_number(command) ){ int vnum = atoi(command); AREA_DATA *ad; if ( (pTrap = get_trap_index(vnum)) == NULL ){ send_to_char("TEdit : That vnum does not exist.\n\r", ch); return; } ad = get_vnum_area(vnum); if ( ad == NULL ){ send_to_char( "TEdit : Vnum is not assigned an area.\n\r", ch ); return; } if ( !IS_BUILDER(ch, ad) ){ send_to_char("TEdit : Insufficient security to modify area.\n\r", ch ); return; } ch->desc->pEdit = (void *)pTrap; ch->desc->editor = ED_TRAP; return; } if ( !str_cmp(command, "create") ){ if (argument[0] == '\0'){ send_to_char( "Syntax : tedit create [vnum]\n\r", ch ); return; } tedit_create(ch, argument); return; } send_to_char( "Syntax : tedit [vnum]\n\r", ch ); send_to_char( " tedit create [vnum]\n\r", ch ); return; } void do_hedit(CHAR_DATA *ch, char *argument){ HELP_DATA* pHelp; char command[MIL]; argument = one_argument(argument, command); if( is_number(command) ){ int vnum = atoi(command); if ( (pHelp = get_help_index(vnum)) == NULL ){ send_to_char("HEdit : That vnum does not exist.\n\r", ch); return; } ch->desc->pEdit = (void *)pHelp; ch->desc->editor = ED_HELP; return; } if ( !str_cmp(command, "create") ){ hedit_create(ch, argument); return; } send_to_char( "Syntax : hedit [vnum]\n\r", ch ); send_to_char( " hedit create\n\r", ch ); return; } void do_cedit(CHAR_DATA *ch, char *argument){ CABAL_INDEX_DATA* pCab; char command[MIL]; argument = one_argument(argument, command); if( is_number(command) ){ int vnum = atoi(command); if ( (pCab = get_cabal_index(vnum)) == NULL ){ send_to_char("CEdit : That vnum does not exist.\n\r", ch); return; } ch->desc->pEdit = (void *)pCab; ch->desc->editor = ED_CABAL; return; } if ( !str_cmp(command, "create") ){ if (get_trust(ch) < IMPLEMENTOR){ sendf(ch, "Requires level %d trust.\n\r", IMPLEMENTOR); return; } cedit_create(ch, argument); return; } send_to_char( "Syntax : cedit [vnum]\n\r", ch ); send_to_char( " cedit create\n\r", ch ); return; } void display_resets( CHAR_DATA *ch ) { ROOM_INDEX_DATA *pRoom; RESET_DATA *pReset; MOB_INDEX_DATA *pMob = NULL; char buf [ MSL ]; char final [ MSL ]; int iReset = 0; EDIT_ROOM(ch, pRoom); final[0] = '\0'; send_to_char ( " No. Loads Description Location Vnum Wo Ar Description\n\r" "==== ======== ============= =================== ======== ===== ===========\n\r", ch ); for ( pReset = pRoom->reset_first; pReset; pReset = pReset->next ) { OBJ_INDEX_DATA *pObj; MOB_INDEX_DATA *pMobIndex; OBJ_INDEX_DATA *pObjIndex; OBJ_INDEX_DATA *pObjToIndex; ROOM_INDEX_DATA *pRoomIndex; TRAP_INDEX_DATA *pTrap; final[0] = '\0'; sprintf( final, "[%2d] ", ++iReset ); switch ( pReset->command ) { default: sprintf( buf, "Bad reset command: %c.", pReset->command ); strcat( final, buf ); break; case 'M': if ( !( pMobIndex = get_mob_index( pReset->arg1 ) ) ) { sprintf( buf, "Load Mobile - Bad Mob %d\n\r", pReset->arg1 ); strcat( final, buf ); continue; } if ( !( pRoomIndex = get_room_index( pReset->arg3 ) ) ) { sprintf( buf, "Load Mobile - Bad Room %d\n\r", pReset->arg3 ); strcat( final, buf ); continue; } pMob = pMobIndex; sprintf( buf, "M[%5d] %-13.13s in room R[%5d] %2d-%2d %-15.15s\n\r", pReset->arg1, pMob->short_descr, pReset->arg3, pReset->arg2, pReset->arg4, pRoomIndex->name ); strcat( final, buf ); { ROOM_INDEX_DATA *pRoomIndexPrev; pRoomIndexPrev = get_room_index( pRoomIndex->vnum - 1 ); if ( pRoomIndexPrev && IS_SET( pRoomIndexPrev->room_flags, ROOM_PET_SHOP ) ) final[5] = 'P'; } break; case 'O': if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) ) { sprintf( buf, "Load Object - Bad Object %d\n\r", pReset->arg1 ); strcat( final, buf ); continue; } pObj = pObjIndex; if ( !( pRoomIndex = get_room_index( pReset->arg3 ) ) ) { sprintf( buf, "Load Object - Bad Room %d\n\r", pReset->arg3 ); strcat( final, buf ); continue; } sprintf( buf, "O[%5d] %-13.13s in room R[%5d] %-15.15s\n\r", pReset->arg1, pObj->short_descr, pReset->arg3, pRoomIndex->name ); strcat( final, buf ); break; case 'P': if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) ) { sprintf( buf, "Put Object - Bad Object %d\n\r", pReset->arg1 ); strcat( final, buf ); continue; } pObj = pObjIndex; if ( !( pObjToIndex = get_obj_index( pReset->arg3 ) ) ) { sprintf( buf, "Put Object - Bad To Object %d\n\r", pReset->arg3 ); strcat( final, buf ); continue; } sprintf( buf, "O[%5d] %-13.13s inside O[%5d] %2d %-15.15s\n\r", pReset->arg1, pObj->short_descr, pReset->arg3, pReset->arg4, pObjToIndex->short_descr ); strcat( final, buf ); break; case 'G': case 'E': if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) ) { sprintf( buf, "Give/Equip Object - Bad Object %d\n\r", pReset->arg1 ); strcat( final, buf ); continue; } pObj = pObjIndex; if ( !pMob ) { sprintf( buf, "Give/Equip Object - No Previous Mobile\n\r" ); strcat( final, buf ); break; } sprintf( buf, "O[%5d] %-13.13s %-19.19s M[%5d] %-15.15s\n\r", pReset->arg1, pObj->short_descr, (pReset->command == 'G') ? flag_string( wear_loc_strings, WEAR_NONE ) : flag_string( wear_loc_strings, pReset->arg3 ), pMob->vnum, pMob->short_descr ); strcat( final, buf ); break; case 'D': pRoomIndex = get_room_index( pReset->arg1 ); sprintf( buf, "R[%5d] %s door of %-19.19s reset to %s\n\r", pReset->arg1, capitalize( dir_name[ pReset->arg2 ] ), pRoomIndex->name, flag_string( door_resets, pReset->arg3 ) ); strcat( final, buf ); break; case 'R': if ( !( pRoomIndex = get_room_index( pReset->arg1 ) ) ) { sprintf( buf, "Randomize Exits - Bad Room %d\n\r", pReset->arg1 ); strcat( final, buf ); continue; } sprintf( buf, "R[%5d] Exits are randomized in %s\n\r", pReset->arg1, pRoomIndex->name ); strcat( final, buf ); break; case 'T': if ( (pTrap = get_trap_index( pReset->arg1 )) == NULL){ sprintf( buf, "Load Trap - Bad Trap %d\n\r", pReset->arg1 ); strcat( final, buf ); continue; } if ( (pRoomIndex = get_room_index( pReset->arg3 )) == NULL ){ sprintf( buf, "Load Trap - Bad Room %d\n\r", pReset->arg3 ); strcat( final, buf ); continue; } sprintf( buf, "T[%5d] %-13.13s ", pReset->arg1, pTrap->name); strcat( final, buf ); if (pReset->arg2 == TRAP_ON_EXIT){ sprintf( buf, "on %s exit R[%5d] lv[%2d] %s\n\r", dir_name[pReset->arg4], pReset->arg3, pTrap->level, trap_table[pTrap->type].name); strcat( final, buf ); } else if (pReset->arg2 == TRAP_ON_OBJ){ sprintf( buf, "on previous obj R[%5d] lv[%2d] %s\n\r", pReset->arg3, pTrap->level, trap_table[pTrap->type].name); strcat( final, buf ); } else{ sprintf(buf, "TRAP TYPE ERROR \n\r"); strcat( final, buf ); } } send_to_char( final, ch ); } return; } /* Inserts a new reset in the given index slot. * * Called by do_resets(olc.c). */ void add_reset( ROOM_INDEX_DATA *room, RESET_DATA *pReset, int index ) { RESET_DATA *reset; int iReset = 0; if ( !room->reset_first ) { room->reset_first = pReset; room->reset_last = pReset; pReset->next = NULL; return; } index--; if ( index == 0 ) { pReset->next = room->reset_first; room->reset_first = pReset; return; } for ( reset = room->reset_first; reset->next; reset = reset->next ) if ( ++iReset == index ) break; pReset->next = reset->next; reset->next = pReset; if ( !pReset->next ) room->reset_last = pReset; SET_BIT( room->area->area_flags, AREA_CHANGED ); return; } void do_resets( CHAR_DATA *ch, char *argument ) { char arg1[MIL]; char arg2[MIL]; char arg3[MIL]; char arg4[MIL]; char arg5[MIL]; char arg6[MIL]; char arg7[MIL]; RESET_DATA *pReset = NULL; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); argument = one_argument( argument, arg3 ); argument = one_argument( argument, arg4 ); argument = one_argument( argument, arg5 ); argument = one_argument( argument, arg6 ); argument = one_argument( argument, arg7 ); if ( !IS_BUILDER( ch, ch->in_room->area ) ) { send_to_char( "Resets: Invalid security for editing this area.\n\r", ch ); return; } if (mud_data.mudport != TEST_PORT && get_trust(ch) < MASTER){ send_to_char("This command avaliable on test port only.\n\r", ch); return; } if ( arg1[0] == '\0' ) { if ( ch->in_room->reset_first ) { send_to_char("Resets: M = mobile, R = room, O = object, P = pet, S= shopkeeper T = trap\n\r", ch ); display_resets( ch ); } else send_to_char( "No resets in this room.\n\r", ch ); } if ( is_number( arg1 ) ) { ROOM_INDEX_DATA *pRoom = ch->in_room; if ( !str_cmp( arg2, "delete" ) ) { int insert_loc = atoi( arg1 ); if ( !ch->in_room->reset_first ) { send_to_char( "No resets in this area.\n\r", ch ); return; } if ( insert_loc-1 <= 0 ) { pReset = pRoom->reset_first; pRoom->reset_first = pRoom->reset_first->next; if ( !pRoom->reset_first ) pRoom->reset_last = NULL; } else { int iReset = 0; RESET_DATA *prev = NULL; for ( pReset = pRoom->reset_first; pReset; pReset = pReset->next ) { if ( ++iReset == insert_loc ) break; prev = pReset; } if ( !pReset ) { send_to_char( "Reset not found.\n\r", ch ); return; } if ( prev ) prev->next = prev->next->next; else pRoom->reset_first = pRoom->reset_first->next; for ( pRoom->reset_last = pRoom->reset_first; pRoom->reset_last->next; pRoom->reset_last = pRoom->reset_last->next ); } free_reset_data( pReset ); send_to_char( "Reset deleted.\n\r", ch ); SET_BIT( ch->in_room->area->area_flags, AREA_CHANGED ); } else if ( (!str_cmp( arg2, "mob" ) && is_number( arg3 )) || (!str_cmp( arg2, "obj" ) && is_number( arg3 )) || (!str_cmp( arg2, "trap" ) && is_number( arg3 )) ) { if ( !str_cmp( arg2, "trap" ) ){ int type = 0; int exit = 0; if (get_trap_index( is_number(arg3) ? atoi( arg3 ) : 1 ) == NULL){ send_to_char("Trap doesn't exist.\n\r",ch); return; } if (IS_NULLSTR(arg4)){ send_to_char("OBJ or EXIT trap?\n\r", ch); return; } if (!str_cmp("obj", arg4)) type = TRAP_ON_OBJ; else if (!str_cmp("exit", arg4)){ type = TRAP_ON_EXIT; if ( (exit = dir_lookup(arg5)) < 0 || exit >= MAX_DOOR){ send_to_char("Invalid exit.\n\r", ch); return; } } else{ send_to_char("OBJ or EXIT trap?\n\r", ch); return; } pReset = new_reset_data(); pReset->command = 'T'; pReset->arg1 = atoi( arg3 ); pReset->arg2 = type; pReset->arg3 = ch->in_room->vnum; pReset->arg4 = exit; } else if ( !str_cmp( arg2, "mob" ) ) { if (get_mob_index( is_number(arg3) ? atoi( arg3 ) : 1 ) == NULL) { send_to_char("Mob doesn't exist.\n\r",ch); return; } pReset = new_reset_data(); pReset->command = 'M'; pReset->arg1 = atoi( arg3 ); pReset->arg2 = is_number( arg4 ) ? atoi( arg4 ) : 1; pReset->arg3 = ch->in_room->vnum; pReset->arg4 = is_number( arg5 ) ? atoi( arg5 ) : 1; } else if ( !str_cmp( arg2, "obj" ) ) { pReset = new_reset_data(); pReset->arg1 = atoi( arg3 ); if ( !str_prefix( arg4, "inside" ) ) { OBJ_INDEX_DATA *temp; temp = get_obj_index(is_number(arg5) ? atoi(arg5) : 1); if ( ( temp->item_type != ITEM_CONTAINER ) && ( temp->item_type != ITEM_CORPSE_NPC ) ) { send_to_char( "Object 2 is not a container\n\r.", ch); return; } pReset->command = 'P'; pReset->arg2 = is_number( arg6 ) ? atoi( arg6 ) : 1; pReset->arg3 = is_number( arg5 ) ? atoi( arg5 ) : 1; pReset->arg4 = is_number( arg7 ) ? atoi( arg7 ) : 1; } else if ( !str_cmp( arg4, "room" ) ) { if (get_obj_index(atoi(arg3)) == NULL) { send_to_char( "Vnum doesn't exist.\n\r",ch); return; } pReset->command = 'O'; pReset->arg2 = 0; pReset->arg3 = ch->in_room->vnum; pReset->arg4 = 0; } else { if ( flag_value( wear_loc_flags, arg4 ) == NO_FLAG ) { send_to_char( "Resets: '? wear-loc'\n\r", ch ); return; } if (get_obj_index(atoi(arg3)) == NULL) { send_to_char( "Vnum no existe.\n\r",ch); return; } pReset->arg1 = atoi(arg3); pReset->arg3 = flag_value( wear_loc_flags, arg4 ); if ( pReset->arg3 == WEAR_NONE ) pReset->command = 'G'; else pReset->command = 'E'; } } add_reset( ch->in_room, pReset, atoi( arg1 ) ); SET_BIT( ch->in_room->area->area_flags, AREA_CHANGED ); send_to_char( "Reset added.\n\r", ch ); } else if (!str_cmp( arg2, "random") && is_number(arg3)) { if (atoi(arg3) < 1 || atoi(arg3) > 6) { send_to_char("Invalid argument.\n\r", ch); return; } pReset = new_reset_data (); pReset->command = 'R'; pReset->arg1 = ch->in_room->vnum; pReset->arg2 = atoi(arg3); add_reset( ch->in_room, pReset, atoi( arg1 ) ); SET_BIT( ch->in_room->area->area_flags, AREA_CHANGED ); send_to_char( "Random exits reset added.\n\r", ch); } else { send_to_char( "Syntax: RESET <number> OBJ <vnum> <wear_loc>\n\r", ch ); send_to_char( " RESET <number> OBJ <vnum> inside <vnum> [limit] [count]\n\r", ch ); send_to_char( " RESET <number> OBJ <vnum> room\n\r", ch ); send_to_char( " RESET <number> MOB <vnum> [max # area] [max # room]\n\r", ch ); send_to_char( " RESET <number> TRAP <vnum> OBJ\n\r", ch ); send_to_char( " RESET <number> TRAP <vnum> EXIT <dir>\n\r", ch ); send_to_char( " RESET <number> DELETE\n\r", ch ); send_to_char( " RESET <number> RANDOM [# exits]\n\r", ch ); } } else { send_to_char( "Syntax: RESET <number> OBJ <vnum> <wear_loc>\n\r", ch ); send_to_char( " RESET <number> OBJ <vnum> inside <vnum> [limit] [count]\n\r", ch ); send_to_char( " RESET <number> OBJ <vnum> room\n\r", ch ); send_to_char( " RESET <number> MOB <vnum> [max # area] [max # room]\n\r", ch ); send_to_char( " RESET <number> TRAP <vnum> OBJ\n\r", ch ); send_to_char( " RESET <number> TRAP <vnum> EXIT <dir>\n\r", ch ); send_to_char( " RESET <number> DELETE\n\r", ch ); send_to_char( " RESET <number> RANDOM [# exits]\n\r", ch ); } return; } /* Normal command to list areas and display area information. * * Called by interpreter(interp.c) */ void do_alist( CHAR_DATA *ch, char *argument ) { BUFFER* buffer; char buf [ MSL ]; AREA_DATA *pArea; buffer = new_buf(); sprintf( buf, "[%3s] [%4s] [%-20s] (%-5s-%5s) [%-10s] %3s [%-10s]\n\r", "Num", "Idle", "Area Name", "lvnum", "uvnum", "Filename", "Sec", "Builders" ); add_buf(buffer, buf); for ( pArea = area_first; pArea; pArea = pArea->next ){ sprintf( buf, "[%3d] [%4d] %-22.22s (%-5d-%5d) %-12.12s [%d] [%-10.10s]\n\r", pArea->vnum, pArea->idle, pArea->name, pArea->min_vnum, pArea->max_vnum, pArea->file_name, pArea->security, pArea->builders ); add_buf(buffer, buf); } page_to_char(buf_string(buffer),ch); free_buf(buffer); return; } /* OLC_SAVE.C * This takes care of saving all the .are information. * Notes: * -If a good syntax checker is used for setting vnum ranges of areas * then it would become possible to just cycle through vnums instead * of using the iHash stuff and checking that the room or reset or * mob etc is part of that area. */ /* Verbose writes reset data in plain english into the comments * section of the resets. It makes areas considerably larger but * may aid in debugging. */ /* #define VERBOSE */ /* Returns a string without \r and ~. */ char *fix_string( const char *str ) { static char strfix[MSL*2]; int i; int o; if ( str == NULL ) return '\0'; for ( o = i = 0; str[i+o] != '\0'; i++ ) { if (str[i+o] == '\r' || str[i+o] == '~') o++; strfix[i] = str[i+o]; } strfix[i] = '\0'; return strfix; } /* Saves the listing of files to be loaded at startup. * * Called by do_asave(olc_save.c). */ void save_area_list() { FILE *fp; AREA_DATA *pArea; if ( ( fp = fopen( "area.lst", "w" ) ) == NULL ) { bug( "Save_area_list: fopen", 0 ); fp = fopen( NULL_FILE, "r" ); fclose (fp); perror( "area.lst" ); } else { /* Add any help files that need to be loaded at * * startup to this section. */ fprintf( fp, "social.are\n" ); for( pArea = area_first; pArea; pArea = pArea->next ){ fprintf( fp, "%s\n", pArea->file_name ); } fprintf( fp, "$\n" ); fclose( fp ); } return; } /* Used in save_mobile and save_object below. Writes * * flags on the form fread_flag reads. * * buf[] must hold at least 32+1 characters. */ char *fwrite_flag( long flags, char buf[] ) { char offset; char *cp; buf[0] = '\0'; if ( flags == 0 ) { strcpy( buf, "0" ); return buf; } for ( offset = 0, cp = buf; offset < 32; offset++ ) if ( flags & ( (long)1 << offset ) ) { if ( offset <= 'Z' - 'A' ) *(cp++) = 'A' + offset; else *(cp++) = 'a' + offset - ( 'Z' - 'A' + 1 ); } *cp = '\0'; return buf; } /* save all the helps to the file */ void save_helps(){ FILE *fp; HELP_DATA *pHelp; CABAL_INDEX_DATA* pCab; int vnum = 0; fclose( fpReserve ); if ( ( fp = fopen( HELP_FILE, "w" ) ) == NULL ){ fp = fopen( NULL_FILE, "r" ); fclose (fp); perror( HELP_FILE ); } else{ for ( pHelp = help_first; pHelp != NULL; pHelp = pHelp->next ){ /* vnum */ fprintf( fp, "#%d\n", ++vnum); /* level/type */ fprintf( fp, "%d ", pHelp->level); /* decide if we print anything special for race etc.*/ switch (pHelp->level){ case HELP_RACE: /* special races helps */ if (pHelp->type < 0){ if (pHelp->type == -1){ fprintf( fp, "%s~ ", "avatar" ); break; } } else fprintf( fp, "%s~ ", race_table[pHelp->type].name ); break; case HELP_CLASS: fprintf( fp, "%s~ ", class_table[pHelp->type].name ); break; case HELP_CABAL: pCab = get_cabal_index( pHelp->type ); fprintf( fp, "%s~ ", pCab ? pCab->name : "cabal" ); break; case HELP_PSALM: fprintf( fp, "%s~ ", psalm_table[pHelp->type].name ); break; case HELP_ALL: default: break; } /* print the keywords */ fprintf( fp, "%s~\n", pHelp->keyword ); /* print text */ fprintf( fp, "%s~\n\n", pHelp->text ); } } fprintf( fp, "#0" ); fclose( fp ); fpReserve = fopen( NULL_FILE, "r" ); } /* Save one mobile to file, new format * * Called by save_mobiles (below). */ void save_mobile( FILE *fp, MOB_INDEX_DATA *pMobIndex ) { PROG_LIST *pMprog; sh_int race = pMobIndex->race; char buf[MSL]; long temp; fprintf( fp, "#%d\n", pMobIndex->vnum ); fprintf( fp, "%s~\n", pMobIndex->player_name ); fprintf( fp, "%s~\n", pMobIndex->short_descr ); fprintf( fp, "%s~\n", fix_string( pMobIndex->long_descr ) ); fprintf( fp, "%s~\n", fix_string( pMobIndex->description) ); fprintf( fp, "%s~\n", race_table[race].name ); fprintf( fp, "%s ", fwrite_flag( pMobIndex->act, buf ) ); fprintf( fp, "%s ", fwrite_flag( pMobIndex->act2, buf ) ); fprintf( fp, "%s ", fwrite_flag( pMobIndex->affected_by, buf ) ); fprintf( fp, "%s ", fwrite_flag( pMobIndex->affected2_by, buf ) ); fprintf( fp, "%d %d\n", pMobIndex->alignment , pMobIndex->group); fprintf( fp, "%d ", pMobIndex->level ); fprintf( fp, "%d ", pMobIndex->hitroll ); fprintf( fp, "%dd%d+%d ", pMobIndex->hit[DICE_NUMBER], pMobIndex->hit[DICE_TYPE], pMobIndex->hit[DICE_BONUS] ); fprintf( fp, "%dd%d+%d ", pMobIndex->mana[DICE_NUMBER], pMobIndex->mana[DICE_TYPE], pMobIndex->mana[DICE_BONUS] ); fprintf( fp, "%dd%d+%d ", pMobIndex->damage[DICE_NUMBER], pMobIndex->damage[DICE_TYPE], pMobIndex->damage[DICE_BONUS] ); fprintf( fp, "%s\n", attack_table[pMobIndex->dam_type].name ); fprintf( fp, "%d %d %d %d\n", pMobIndex->ac[AC_PIERCE] / 10, pMobIndex->ac[AC_BASH] / 10, pMobIndex->ac[AC_SLASH] / 10, pMobIndex->ac[AC_EXOTIC] / 10 ); fprintf( fp, "%s ", fwrite_flag( pMobIndex->off_flags, buf ) ); fprintf( fp, "%s ", fwrite_flag( pMobIndex->imm_flags, buf ) ); fprintf( fp, "%s ", fwrite_flag( pMobIndex->res_flags, buf ) ); fprintf( fp, "%s\n", fwrite_flag( pMobIndex->vuln_flags, buf ) ); fprintf( fp, "%s %s ", position_table[pMobIndex->start_pos].short_name, position_table[pMobIndex->default_pos].short_name); fprintf( fp, "%s ", sex_table[pMobIndex->sex].name); fprintf( fp, "%s~\n", pMobIndex->pCabal ? pMobIndex->pCabal->name : "none"); fprintf( fp, "%ld\n", pMobIndex->gold ); fprintf( fp, "%s ", fwrite_flag( pMobIndex->form, buf ) ); fprintf( fp, "%s ", fwrite_flag( pMobIndex->parts, buf ) ); fprintf( fp, "%s ", size_table[pMobIndex->size].name ); fprintf( fp, "0\n"); if ((temp = DIF(race_table[race].act,pMobIndex->act))) fprintf( fp, "F act %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].act2,pMobIndex->act2))) fprintf( fp, "F act2 %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].aff,pMobIndex->affected_by))) fprintf( fp, "F aff %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].off,pMobIndex->off_flags))) fprintf( fp, "F off %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].imm,pMobIndex->imm_flags))) fprintf( fp, "F imm %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].res,pMobIndex->res_flags))) fprintf( fp, "F res %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].vuln,pMobIndex->vuln_flags))) fprintf( fp, "F vul %s\n", fwrite_flag(temp, buf) ); /* if ((temp = DIF(race_table[race].form,pMobIndex->form))) fprintf( fp, "F for %s\n", fwrite_flag(temp, buf) ); if ((temp = DIF(race_table[race].parts,pMobIndex->parts))) fprintf( fp, "F par %s\n", fwrite_flag(temp, buf) );*/ for (pMprog = pMobIndex->mprogs; pMprog; pMprog = pMprog->next) { fprintf(fp, "P %s %d %s~\n", prog_type_to_name(pMprog->trig_type), pMprog->vnum, pMprog->trig_phrase); } return; } /* Save #MOBILES secion of an area file. * * Called by: save_area(olc_save.c). */ /* This function is for new mobprogs only, Will MERGE them later. */ void save_new_mobprogs( FILE *fp, AREA_DATA *pArea ) { PROG_CODE *pMprog; int i; //old save_mobprog below prints this. fprintf(fp, "#MOBPROGS\n"); for( i = pArea->min_vnum; i <= pArea->max_vnum; i++ ) { if ( (pMprog = get_prog_index(i, PRG_MPROG) ) != NULL) { fprintf(fp, "#%d\n", i); fprintf(fp, "%s~\n", fix_string(pMprog->code)); } } fprintf(fp,"#0\n\n"); return; } void save_mobprogs( FILE *fp, AREA_DATA *pArea ) { int iHash; TRIGFILE_DATA *ptrigfile; MOB_INDEX_DATA *pMobIndex; fprintf( fp, "#MOBPROGS\n" ); /* Write new progs */ save_new_mobprogs( fp, pArea); for( iHash = 0; iHash < MAX_KEY_HASH; iHash++ ) for( pMobIndex = mob_index_hash[iHash]; pMobIndex; pMobIndex = pMobIndex->next ) if ( pMobIndex && pMobIndex->area == pArea && pMobIndex->progtypes ) for ( ptrigfile = pMobIndex->trigfile; ptrigfile; ptrigfile = ptrigfile->next ) fprintf( fp, "M %d %d %s NL\n", pMobIndex->vnum, ptrigfile->dowhen, ptrigfile->name ); fprintf( fp, "S\n\n\n\n\n" ); return; } void save_objprogs( FILE *fp, AREA_DATA *pArea ) { PROG_CODE *pOprog; int i; fprintf(fp, "#OBJPROGS\n"); for( i = pArea->min_vnum; i <= pArea->max_vnum; i++ ) { if ( (pOprog = get_prog_index(i, PRG_OPROG) ) != NULL) { fprintf(fp, "#%d\n", i); fprintf(fp, "%s~\n", fix_string(pOprog->code)); } } fprintf(fp,"#0\n\n"); return; } void save_roomprogs( FILE *fp, AREA_DATA *pArea ) { PROG_CODE *pRprog; int i; fprintf(fp, "#ROOMPROGS\n"); for( i = pArea->min_vnum; i <= pArea->max_vnum; i++ ) { if ( (pRprog = get_prog_index(i,PRG_RPROG) ) != NULL) { fprintf(fp, "#%d\n", i); fprintf(fp, "%s~\n", fix_string(pRprog->code)); } } fprintf(fp,"#0\n\n"); return; } void save_mobiles( FILE *fp, AREA_DATA *pArea ) { int i; MOB_INDEX_DATA *pMob; fprintf( fp, "#MOBILES\n" ); for( i = pArea->min_vnum; i <= pArea->max_vnum; i++ ) if ( (pMob = get_mob_index( i )) ){ save_mobile( fp, pMob ); } fprintf( fp, "#0\n\n\n\n" ); return; } /* Save one object to file. * * Called by: save_objects (below). */ void save_object( FILE *fp, OBJ_INDEX_DATA *pObjIndex ) { char letter; AFFECT_DATA *pAf; EXTRA_DESCR_DATA *pEd; OBJ_SPELL_DATA *pOs; char buf[MSL]; PROG_LIST *pOprog; if (pObjIndex->item_type == ITEM_PROJECTILE) SET_BIT( pObjIndex->wear_flags, ITEM_WEAR_QUIVER); fprintf( fp, "#%d\n", pObjIndex->vnum ); fprintf( fp, "%s~\n", pObjIndex->name ); fprintf( fp, "%s~\n", pObjIndex->short_descr ); fprintf( fp, "%s~\n", fix_string( pObjIndex->description ) ); fprintf( fp, "%s~\n", pObjIndex->material ); fprintf( fp, "%s ", item_name(pObjIndex->item_type)); fprintf( fp, "%s ", fwrite_flag( pObjIndex->extra_flags, buf ) ); fprintf( fp, "%s\n", fwrite_flag( pObjIndex->wear_flags, buf ) ); /* Using fwrite_flag to write most values gives a strange * * looking area file, consider making a case for each * * item type later. */ switch ( pObjIndex->item_type ) { default: fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[0], buf ) ); fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[1], buf ) ); fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[2], buf ) ); fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[3], buf ) ); fprintf( fp, "%s\n", fwrite_flag( pObjIndex->value[4], buf ) ); break; case ITEM_LIGHT: fprintf( fp, "0 0 %d 0 0\n", pObjIndex->value[2] < 1 ? 999 : pObjIndex->value[2] ); break; case ITEM_MONEY: fprintf( fp, "%d %d 0 0 0\n", pObjIndex->value[0], pObjIndex->value[1]); break; case ITEM_DRINK_CON: fprintf( fp, "%d %d '%s' %d 0\n", pObjIndex->value[0], pObjIndex->value[1], liq_table[pObjIndex->value[2]].liq_name, pObjIndex->value[3]); break; case ITEM_FOUNTAIN: fprintf( fp, "%d %d '%s' 0 0\n", pObjIndex->value[0], pObjIndex->value[1], liq_table[pObjIndex->value[2]].liq_name); break; case ITEM_CONTAINER: fprintf( fp, "%d %s %d %d %d\n", pObjIndex->value[0], fwrite_flag( pObjIndex->value[1], buf ), pObjIndex->value[2], pObjIndex->value[3], pObjIndex->value[4]); break; case ITEM_FOOD: fprintf( fp, "%d %d 0 %s %d\n", pObjIndex->value[0], pObjIndex->value[1], fwrite_flag( pObjIndex->value[3], buf ), pObjIndex->value[4] ); break; case ITEM_WEAPON: fprintf( fp, "%s %d %d %s %s\n", weapon_name(pObjIndex->value[0]), pObjIndex->value[1], pObjIndex->value[2], attack_table[pObjIndex->value[3]].name, fwrite_flag( pObjIndex->value[4], buf ) ); break; case ITEM_THROW: fprintf( fp, "%d %d %d %s %s\n", pObjIndex->value[0], pObjIndex->value[1], pObjIndex->value[2], attack_table[pObjIndex->value[3]].name, fwrite_flag( pObjIndex->value[4], buf ) ); break; case ITEM_ARMOR: fprintf( fp, "%d %d %d %d %d\n", pObjIndex->value[0], pObjIndex->value[1], pObjIndex->value[2], pObjIndex->value[3], pObjIndex->value[4]); break; case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: case ITEM_RELIC: case ITEM_ARTIFACT: case ITEM_HERB: /* Timer, Eaten, Herb, Brew, None */ fprintf( fp, "%d '%s' '%s' '%s' '%s'\n", pObjIndex->value[0] > 0 ? pObjIndex->value[0] : 0, pObjIndex->value[1] != -1 ? skill_table[pObjIndex->value[1]].name : "", pObjIndex->value[2] != -1 ? skill_table[pObjIndex->value[2]].name : "", pObjIndex->value[3] != -1 ? skill_table[pObjIndex->value[3]].name : "", pObjIndex->value[4] != -1 ? skill_table[pObjIndex->value[4]].name : ""); break; case ITEM_STAFF: case ITEM_WAND: fprintf( fp, "%d ", pObjIndex->value[0] ); fprintf( fp, "%d ", pObjIndex->value[1] ); fprintf( fp, "%d '%s' 0\n", pObjIndex->value[2], pObjIndex->value[3] != -1 ? skill_table[pObjIndex->value[3]].name : "(null)" ); break; case ITEM_INSTRUMENT: fprintf( fp, "0 0 0 0 %s\n", fwrite_flag( pObjIndex->value[4], buf ) ); break; case ITEM_SOCKET: fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[0], buf ) ); fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[1], buf ) ); fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[2], buf ) ); fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[3], buf ) ); fprintf( fp, "%s\n", fwrite_flag( IS_SOC_STAT(pObjIndex, SOCKET_WEAPON) ? pObjIndex->value[4] : 0, buf ) ); break; case ITEM_RANGED: fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[0], buf ) ); fprintf( fp, "%d ", pObjIndex->value[1]); fprintf( fp, "%d ", pObjIndex->value[2]); fprintf( fp, "%d ", pObjIndex->value[3]); fprintf( fp, "%s\n", fwrite_flag( pObjIndex->value[4], buf ) ); break; case ITEM_PROJECTILE: fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[0], buf ) ); fprintf( fp, "%d ", pObjIndex->value[1]); fprintf( fp, "%d ", pObjIndex->value[2]); fprintf( fp, "%s ", attack_table[pObjIndex->value[3]].name); fprintf( fp, "%s ", fwrite_flag( pObjIndex->value[4], buf ) ); break; } fprintf( fp, "%d ", pObjIndex->level ); fprintf( fp, "%d ", pObjIndex->weight ); fprintf( fp, "%d ", pObjIndex->cost ); if ( pObjIndex->condition > 90 ) letter = 'P'; else if ( pObjIndex->condition > 75 ) letter = 'G'; else if ( pObjIndex->condition > 50 ) letter = 'A'; else if ( pObjIndex->condition > 25 ) letter = 'W'; else if ( pObjIndex->condition > 10 ) letter = 'D'; else if ( pObjIndex->condition > 0 ) letter = 'B'; else letter = 'R'; fprintf( fp, "%c\n", letter ); if (pObjIndex->pCabal) fprintf( fp, "C\n%s~\n", pObjIndex->pCabal->name ); if (pObjIndex->race) fprintf( fp, "R\n%d\n", pObjIndex->race ); if (pObjIndex->class >= 0) fprintf( fp, "L\n%d\n", pObjIndex->class ); for( pEd = pObjIndex->extra_descr; pEd; pEd = pEd->next ) fprintf( fp, "E\n%s~\n%s~\n", pEd->keyword, fix_string( pEd->description ) ); for ( pOs = pObjIndex->spell; pOs; pOs = pOs->next ) fprintf( fp, "T\n%d %d %d\n%s~\n%s~\n", pOs->spell, pOs->target, pOs->percent, pOs->message, pOs->message2 ); if (pObjIndex->message) fprintf( fp, "M\n%s~\n%s~\n%s~\n%s~\n", pObjIndex->message->onself, pObjIndex->message->onother, pObjIndex->message->offself, pObjIndex->message->offother ); for( pAf = pObjIndex->affected; pAf; pAf = pAf->next ) fprintf( fp, "F\n%s %d %d %s\n", pAf->where == TO_IMMUNE ? "I" : pAf->where==TO_RESIST ? "R" : pAf->where == TO_VULN ? "V" : pAf->where == TO_SKILL ? "S" : "A", pAf->location, pAf->modifier, fwrite_flag(pAf->bitvector, buf) ); for (pOprog = pObjIndex->oprogs; pOprog; pOprog = pOprog->next) { fprintf(fp, "P %s %d %s~\n", prog_type_to_name(pOprog->trig_type), pOprog->vnum, pOprog->trig_phrase); } return; } /* Save #OBJECTS section of an area file. * * Called by save_area(olc_save.c). */ void save_objects( FILE *fp, AREA_DATA *pArea ) { int i; OBJ_INDEX_DATA *pObj; fprintf( fp, "#OBJECTS\n" ); for( i = pArea->min_vnum; i <= pArea->max_vnum; i++ ) if ( (pObj = get_obj_index( i )) ) save_object( fp, pObj ); fprintf( fp, "#0\n\n\n\n" ); return; } /* SAVE #TRAPS section of an area file */ /* called save_area */ /* This function is for new mobprogs only, Will MERGE them later. */ void save_traps( FILE *fp, AREA_DATA *pArea ){ char buf[MIL]; TRAP_INDEX_DATA *pTrap; int i; fprintf(fp, "#TRAPS\n"); for( i = pArea->min_vnum; i <= pArea->max_vnum; i++ ){ if ( (pTrap = get_trap_index(i)) != NULL){ fprintf(fp, "#%d\n", i); /* common things */ fprintf( fp, "%s~\n%s~\n%s~\n%s %d %s\n", pTrap->name, pTrap->echo, pTrap->oEcho, trap_table[pTrap->type].name, pTrap->level, fwrite_flag(pTrap->flags, buf)); /* based on type */ switch (pTrap->type){ default: case TTYPE_DUMMY: fprintf( fp, "%d %d %d %d %d\n", pTrap->value[0], pTrap->value[1], pTrap->value[2], pTrap->value[3], pTrap->value[4]); break; case TTYPE_DAMAGE: fprintf( fp, "%s %d %d %d %d\n", attack_table[pTrap->value[0]].name, pTrap->value[1], pTrap->value[2], pTrap->value[3], pTrap->value[4]); break; case TTYPE_XDAMAGE: fprintf( fp, "%s~ %d %d %d %d\n", IS_GEN(pTrap->value[0]) ? effect_table[pTrap->value[0]].name : skill_table[pTrap->value[0]].name, pTrap->value[1], pTrap->value[2], pTrap->value[3], pTrap->value[4]); break; case TTYPE_SPELL: fprintf( fp, "%s~ %d %s~ %d %d\n", skill_table[pTrap->value[0]].name, pTrap->value[1], skill_table[pTrap->value[2]].name, pTrap->value[3], pTrap->value[4]); break; case TTYPE_MOB: fprintf( fp, "%d %d %d %d %d\n", pTrap->value[0], pTrap->value[1], pTrap->value[2], pTrap->value[3], pTrap->value[4]); break; } } } fprintf(fp,"#0\n\n"); return; } /* writes a singel room */ void write_room( FILE* fp, ROOM_INDEX_DATA* pRoomIndex ){ EXTRA_DESCR_DATA *pEd; EXIT_DATA *pExit; PROG_LIST *pRprog; int door; Double_List *tmp_list; char buf[MIL]; fprintf( fp, "%s~\n", pRoomIndex->name ); fprintf( fp, "%s~\n", fix_string( pRoomIndex->description ) ); if (pRoomIndex->description2 != NULL) fprintf( fp, "%s~\n", fix_string( pRoomIndex->description2 ) ); else fprintf( fp, "~\n" ); fprintf( fp, "0 " ); fprintf( fp, "%d ", pRoomIndex->room_flags ); fprintf( fp, "%d ", pRoomIndex->room_flags2 ); fprintf( fp, "%d\n", pRoomIndex->sector_type ); for ( pEd = pRoomIndex->extra_descr; pEd; pEd = pEd->next ) fprintf( fp, "E\n%s~\n%s~\n", pEd->keyword, fix_string( pEd->description ) ); for( door = 0; door < MAX_DIR; door++ ) { if ( ( pExit = pRoomIndex->exit[door] ) && pExit->to_room ){ /* we check if this is a non virtual room leading to virtual */ if (pRoomIndex->vnum > 0 && !IS_VIRROOM(pRoomIndex) && IS_VIRROOM(pExit->to_room)) continue; fprintf( fp, "D%d\n", pExit->orig_door ); fprintf( fp, "%s~\n", fix_string( pExit->description ) ); fprintf( fp, "%s~\n", pExit->keyword ); fprintf( fp, "%s %d %d\n", fwrite_flag(pExit->rs_flags, buf), pExit->key, pExit->to_room->vnum ); } } if (pRoomIndex->mana_rate != 100 || pRoomIndex->heal_rate != 100) fprintf ( fp, "M %d H %d\n",pRoomIndex->mana_rate, pRoomIndex->heal_rate); if (pRoomIndex->pCabal) fprintf ( fp, "C %s~\n" , pRoomIndex->pCabal->name ); if (pRoomIndex->temp != 72) fprintf ( fp, "T %d\n" , pRoomIndex->temp ); tmp_list = pRoomIndex->watch_vnums; while (tmp_list != NULL) { fprintf ( fp, "W %d\n" , (int) tmp_list->cur_entry ); tmp_list = tmp_list->next_node; } for (pRprog = pRoomIndex->rprogs; pRprog; pRprog = pRprog->next){ fprintf(fp, "P %s %d %s~\n", prog_type_to_name(pRprog->trig_type), pRprog->vnum, pRprog->trig_phrase); } fprintf( fp, "S\n" ); } /* Save #ROOMS section of an area file. * * Called by save_area(olc_save.c). */ void save_rooms( FILE *fp, AREA_DATA *pArea ) { ROOM_INDEX_DATA *pRoomIndex; int iHash; fprintf( fp, "#ROOMS\n" ); for( iHash = 0; iHash < MAX_KEY_HASH; iHash++ ){ for( pRoomIndex = room_index_hash[iHash]; pRoomIndex; pRoomIndex = pRoomIndex->next ) if ( pRoomIndex->area == pArea && !IS_VIRROOM( pRoomIndex) ){ fprintf( fp, "#%d\n", pRoomIndex->vnum ); write_room( fp, pRoomIndex ); } } fprintf( fp, "#0\n\n\n\n" ); return; } /* Save #SPECIALS section of area file. * * Called by save_area(olc_save.c). */ void save_specials( FILE *fp, AREA_DATA *pArea ) { int iHash; MOB_INDEX_DATA *pMobIndex; fprintf( fp, "#SPECIALS\n" ); for( iHash = 0; iHash < MAX_KEY_HASH; iHash++ ) for( pMobIndex = mob_index_hash[iHash]; pMobIndex; pMobIndex = pMobIndex->next ) if ( pMobIndex && pMobIndex->area == pArea && pMobIndex->spec_fun ) #if defined( VERBOSE ) fprintf( fp, "M %d %s Load to: %s\n", pMobIndex->vnum, spec_name( pMobIndex->spec_fun ), pMobIndex->short_descr ); #else fprintf( fp, "M %d %s\n", pMobIndex->vnum, spec_name( pMobIndex->spec_fun ) ); #endif fprintf( fp, "S\n\n\n\n" ); return; } /* writes a single room's resets */ void write_resets( FILE* fp, ROOM_INDEX_DATA* pRoom ){ RESET_DATA *pReset; MOB_INDEX_DATA *pLastMob = NULL; OBJ_INDEX_DATA *pLastObj; TRAP_INDEX_DATA *pTrap; char buf[MIL]; for ( pReset = pRoom->reset_first; pReset; pReset = pReset->next ){ switch ( pReset->command ){ default: bug( "Save_resets: bad command %c.", pReset->command ); break; #if defined( VERBOSE ) case 'M': pLastMob = get_mob_index( pReset->arg1 ); fprintf( fp, "M 0 %d %d %d %d Load %s\n", pReset->arg1, pReset->arg2, pReset->arg3, pReset->arg4, pLastMob->short_descr ); break; case 'O': pLastObj = get_obj_index( pReset->arg1 ); pRoom = get_room_index( pReset->arg3 ); fprintf( fp, "O 0 %d 0 %d %s loaded to %s\n", pReset->arg1, pReset->arg3, capitalize(pLastObj->short_descr), pRoom->name ); break; case 'P': pLastObj = get_obj_index( pReset->arg1 ); fprintf( fp, "P 0 %d %d %d %d %s put inside %s\n", pReset->arg1, pReset->arg2, pReset->arg3, pReset->arg4, capitalize(get_obj_index( pReset->arg1 )->short_descr), pLastObj->short_descr ); break; case 'G': fprintf( fp, "G 0 %d 0 %s is given to %s\n", pReset->arg1, capitalize(get_obj_index( pReset->arg1 )->short_descr), pLastMob ? pLastMob->short_descr : "!NO_MOB!" ); if ( !pLastMob ) { sprintf( buf, "Save_resets: !NO_MOB! in [%s]", pArea->file_name ); bug( buf, 0 ); } break; case 'E': fprintf( fp, "E 0 %d 0 %d %s is loaded %s of %s\n", pReset->arg1, pReset->arg3, capitalize(get_obj_index( pReset->arg1 )->short_descr), flag_string( wear_loc_strings, pReset->arg3 ), pLastMob ? pLastMob->short_descr : "!NO_MOB!" ); if ( !pLastMob ) { sprintf( buf, "Save_resets: !NO_MOB! in [%s]", pArea->file_name ); bug( buf, 0 ); } break; case 'D': break; case 'R': pRoom = get_room_index( pReset->arg1 ); fprintf( fp, "R 0 %d %d Randomize %s\n", pReset->arg1, pReset->arg2, pRoom->name ); break; #endif #if !defined( VERBOSE ) case 'M': pLastMob = get_mob_index( pReset->arg1 ); fprintf( fp, "M 0 %d %d %d %d\n", pReset->arg1, pReset->arg2, pReset->arg3, pReset->arg4 ); break; case 'O': pLastObj = get_obj_index( pReset->arg1 ); pRoom = get_room_index( pReset->arg3 ); fprintf( fp, "O 0 %d 0 %d\n", pReset->arg1, pReset->arg3 ); break; case 'P': pLastObj = get_obj_index( pReset->arg1 ); fprintf( fp, "P 0 %d %d %d %d\n", pReset->arg1, pReset->arg2, pReset->arg3, pReset->arg4 ); break; case 'T': pTrap = get_trap_index( pReset->arg1 ); fprintf( fp, "T 0 %d %d %d %d\n", pReset->arg1, pReset->arg2, pReset->arg3, pReset->arg4 ); break; case 'G': fprintf( fp, "G 0 %d 0\n", pReset->arg1 ); if ( !pLastMob ) { sprintf( buf, "Save_resets: !NO_MOB! in [%d]", pReset->arg1 ); bug( buf, 0 ); } break; case 'E': fprintf( fp, "E 0 %d 0 %d\n", pReset->arg1, pReset->arg3 ); if ( !pLastMob ) { sprintf( buf, "Save_resets: !NO_MOB! in [%d]", pReset->arg1 ); bug( buf, 0 ); } break; case 'D': break; case 'R': pRoom = get_room_index( pReset->arg1 ); fprintf( fp, "R 0 %d %d\n", pReset->arg1, pReset->arg2 ); break; #endif } } } /* Saves the #RESETS section of an area file. * * Called by save_area(olc_save.c) */ void save_resets( FILE *fp, AREA_DATA *pArea ) { ROOM_INDEX_DATA *pRoom; int iHash; fprintf( fp, "#RESETS\n" ); for( iHash = 0; iHash < MAX_KEY_HASH; iHash++ ){ for( pRoom = room_index_hash[iHash]; pRoom; pRoom = pRoom->next ){ if ( pRoom->area == pArea && !IS_VIRROOM( pRoom ) ){ write_resets( fp, pRoom ); } }//end for room in hash cell }//end for each hash cell fprintf( fp, "S\n\n\n\n" ); return; } /* Saves the #SHOPS section of an area file. * * Called by save_area(olc_save.c) */ void save_shops( FILE *fp, AREA_DATA *pArea ) { SHOP_DATA *pShopIndex; MOB_INDEX_DATA *pMobIndex; int iHash; int iTrade; fprintf( fp, "#SHOPS\n" ); for( iHash = 0; iHash < MAX_KEY_HASH; iHash++ ) for( pMobIndex = mob_index_hash[iHash]; pMobIndex; pMobIndex = pMobIndex->next ) if ( pMobIndex && pMobIndex->area == pArea && pMobIndex->pShop) { pShopIndex = pMobIndex->pShop; fprintf( fp, "%d ", pShopIndex->keeper ); for ( iTrade = 0; iTrade < MAX_TRADE; iTrade++ ) { if ( pShopIndex->buy_type[iTrade] != 0 ) fprintf( fp, "%d ", pShopIndex->buy_type[iTrade] ); else fprintf( fp, "0 "); } fprintf( fp, "%d %d ", pShopIndex->profit_buy, pShopIndex->profit_sell ); fprintf( fp, "%d %d\n", pShopIndex->open_hour, pShopIndex->close_hour ); } fprintf( fp, "0\n\n\n\n" ); return; } /* Save an area, note that this format is new. * * Called by do_asave(olc_save.c). */ void save_area( AREA_DATA *pArea ) { FILE *fp; int i = 0, flag; fclose( fpReserve ); if ( !( fp = fopen( pArea->file_name, "w" ) ) ) { bug( "Open_area: fopen", 0 ); fp = fopen( NULL_FILE, "r" ); fclose (fp); perror( pArea->file_name ); } /* clear off the flags which should not be saved */ flag = pArea->area_flags; for (i = 0; area_flags[i].name; i ++){ if (area_flags[i].settable == FALSE) flag &= ~area_flags[i].bit; } fprintf( fp, "#AREADATA\n" ); fprintf( fp, "Name %s~\n", pArea->name ); fprintf( fp, "Pref %s~\n", pArea->prefix ); fprintf( fp, "Builders %s~\n", fix_string( pArea->builders ) ); fprintf( fp, "VNUMs %d %d\n", pArea->min_vnum, pArea->max_vnum ); fprintf( fp, "Max_Bastions %d\n", pArea->bastion_max); fprintf( fp, "Credits %s~\n", pArea->credits ); fprintf( fp, "Security %d\n", pArea->security ); fprintf( fp, "Startroom %d\n", pArea->startroom ); fprintf( fp, "Flags %d\n", flag ); fprintf( fp, "Crimes %d ", MAX_CRIME ); /* print crimes */ for (i = 0; i < MAX_CRIME; i++){ fprintf( fp, "%d ", pArea->crimes[i] ); } fprintf( fp, "\n" ); fprintf( fp, "End\n\n\n\n" ); save_cabal_indexes( fp, pArea ); save_mobiles( fp, pArea ); save_objects( fp, pArea ); save_rooms( fp, pArea ); save_army_indexes( fp, pArea ); save_specials( fp, pArea ); save_traps( fp, pArea ); save_resets( fp, pArea ); save_shops( fp, pArea ); save_mobprogs( fp, pArea ); save_objprogs( fp, pArea ); save_roomprogs( fp, pArea ); fprintf( fp, "#$\n" ); fclose( fp ); fpReserve = fopen( NULL_FILE, "r" ); return; } /* Entry point for saving area data. * * Called by interpreter(interp.c) */ void do_asave( CHAR_DATA *ch, char *argument ) { char arg1 [MIL]; AREA_DATA *pArea; FILE *fp; int value; fp = NULL; if ( !ch ) { save_area_list(); for( pArea = area_first; pArea; pArea = pArea->next ) { REMOVE_BIT( pArea->area_flags, AREA_CHANGED ); save_area( pArea ); } return; } smash_tilde( argument ); strcpy( arg1, argument ); if ( arg1[0] == '\0' ) { send_to_char( "Syntax:\n\r", ch ); send_to_char( " asave <vnum> - saves a particular area\n\r", ch ); send_to_char( " asave list - saves the area.lst file\n\r", ch ); send_to_char( " asave help - saves the help files\n\r", ch ); send_to_char( " asave cabal - saves the cabal file\n\r", ch ); send_to_char( " asave area - saves the area being edited\n\r", ch ); send_to_char( " asave tomes - saves the library tomes\n\r", ch ); send_to_char( " asave changed - saves all changed zones\n\r", ch ); send_to_char( " asave armies - saves all armies\n\r", ch ); send_to_char( " asave world - saves the world! (db dump)\n\r", ch ); send_to_char( "\n\r", ch ); return; } value = atoi( arg1 ); if ( !( pArea = get_area_data( value ) ) && is_number( arg1 ) ) { send_to_char( "That area does not exist.\n\r", ch ); return; } if ( is_number( arg1 ) ) { if ( !IS_BUILDER( ch, pArea ) ) { send_to_char( "You are not a builder for this area.\n\r", ch ); return; } save_area_list(); save_area( pArea ); return; } if ( !str_cmp( "world", arg1 ) ) { save_area_list(); save_helps(); send_to_char("Helps saved.\n\r", ch); save_armies(); save_cabals(FALSE, ch); for( pArea = area_first; pArea; pArea = pArea->next ) { if ( !IS_BUILDER( ch, pArea ) ) continue; REMOVE_BIT( pArea->area_flags, AREA_CHANGED ); save_area( pArea ); } send_to_char( "You saved the world.\n\r", ch ); return; } if ( !str_cmp( "changed", arg1 ) ) { char buf[MIL]; save_area_list(); save_helps(); save_cabals(TRUE, ch); send_to_char( "Saved zones:\n\r", ch ); sprintf( buf, "None.\n\r" ); for( pArea = area_first; pArea; pArea = pArea->next ) { if ( !IS_BUILDER( ch, pArea ) ) continue; if ( IS_SET(pArea->area_flags, AREA_CHANGED) ) { REMOVE_BIT( pArea->area_flags, AREA_CHANGED ); save_area( pArea ); sprintf( buf, "%24s - '%s'\n\r", pArea->name, pArea->file_name ); send_to_char( buf, ch ); } } if ( !str_cmp( buf, "None.\n\r" ) ) send_to_char( buf, ch ); return; } if ( !str_cmp( arg1, "armies" ) ){ save_armies(); return; } if ( !str_cmp( arg1, "list" ) ) { save_area_list(); return; } if ( !str_cmp( arg1, "tomes" ) ) { SaveTomes(); return; } if ( !str_cmp( arg1, "cabal" ) || !str_cmp( arg1, "cabals" ) ) { save_cabals(FALSE, ch); return; } if ( !str_cmp( arg1, "clan" ) || !str_cmp( arg1, "clans" ) ) { SaveClans(); return; } if ( !str_cmp( arg1, "help" ) ) { save_helps(); send_to_char("Helps saved.\n\r", ch); return; } if ( !str_cmp( arg1, "area" ) ) { if ( ch->desc->editor == 0 ) { send_to_char( "You are not editing an area, therefore an area vnum is required.\n\r", ch ); return; } switch (ch->desc->editor) { case ED_AREA: pArea = (AREA_DATA *)ch->desc->pEdit; break; case ED_ROOM: pArea = ch->in_room->area; break; case ED_OBJECT: pArea = ( (OBJ_INDEX_DATA *)ch->desc->pEdit )->area; break; case ED_MOBILE: pArea = ( (MOB_INDEX_DATA *)ch->desc->pEdit )->area; break; default: pArea = ch->in_room->area; break; } if ( !IS_BUILDER( ch, pArea ) ) { send_to_char( "You are not a builder for this area.\n\r", ch ); return; } save_area_list(); REMOVE_BIT( pArea->area_flags, AREA_CHANGED ); save_area( pArea ); send_to_char( "Area saved.\n\r", ch ); return; } do_asave( ch, "" ); return; } /* The code below uses a table lookup system that is based on suggestions * * from Russ Taylor. There are many routines in handler.c that would benefit * * with the use of tables. You may consider simplifying your code base by * * implementing a system like below with such functions. */ struct flag_stat_type { const struct flag_type *structure; bool stat; }; /* This table catagorizes the tables following the lookup * * functions below into stats and flags. Flags can be toggled * * but stats can only be assigned. Update this table when a * * new set of flags is installed. */ const struct flag_stat_type flag_stat_table[] = { /* { structure stat }, */ /* OLC FLAGS */ { area_flags, FALSE }, { sex_flags, TRUE }, { exit_flags, FALSE }, { door_resets, TRUE }, { room_flags, FALSE }, { sector_flags, TRUE }, { type_flags, TRUE }, { extra_flags, FALSE }, { socket_flags, FALSE }, { wear_flags, FALSE }, { act_flags, FALSE }, { affect_flags, FALSE }, { affect2_flags, FALSE }, { apply_flags, TRUE }, { wear_loc_flags, TRUE }, { wear_loc_strings, TRUE }, { container_flags, FALSE }, { cabal_flags, FALSE }, { cabal_progress_flags, FALSE }, { croom_flags, FALSE }, { army_types, TRUE }, { army_flags, FALSE }, /* ROM specific flags: */ { crime_table, FALSE }, { punish_table, FALSE }, { pact_flags, FALSE }, { form_flags, FALSE }, { part_flags, FALSE }, { ac_type, TRUE }, { size_flags, TRUE }, { position_flags, TRUE }, { off_flags, FALSE }, { imm_flags, FALSE }, { res_flags, FALSE }, { vuln_flags, FALSE }, { weapon_class, TRUE }, { weapon_type2, FALSE }, { apply_types, TRUE }, { room_flags2, FALSE }, { special_flags, FALSE }, { 0, 0 } }; /* Returns TRUE if the table is a stat table and FALSE if flag. * * Called by flag_value and flag_string. * * This function is local and used only in bit.c. */ bool is_stat( const struct flag_type *flag_table ) { int flag; for (flag = 0; flag_stat_table[flag].structure; flag++) if ( flag_stat_table[flag].structure == flag_table && flag_stat_table[flag].stat ) return TRUE; return FALSE; } /* returns flag value regarldess of settable bit */ int flag_lookup_abs (const char *name, const struct flag_type *flag_table) { int flag; for (flag = 0; flag_table[flag].name != NULL; flag++) if ( !str_cmp( name, flag_table[flag].name)) return flag_table[flag].bit; return NO_FLAG; } /* This function is Russ Taylor's creation. Thanks Russ! 8 * All code copyright (C) Russ Taylor, permission to use and/or distribute * * has NOT been granted. Use only in this OLC package has been granted. */ /* Returns the value of a single, settable flag from the table. * * Called by flag_value and flag_string. * * This function is local and used only in bit.c. */ int flag_lookup2 (const char *name, const struct flag_type *flag_table) { int flag; for (flag = 0; flag_table[flag].name != NULL; flag++) if ( !str_cmp( name, flag_table[flag].name ) && flag_table[flag].settable ) return flag_table[flag].bit; return NO_FLAG; } /* Returns the value of the flags entered. Multi-flags accepted. * * Called by olc.c and olc_act.c. */ int flag_value( const struct flag_type *flag_table, char *argument) { char word[MIL]; int bit; int marked = 0; bool found = FALSE; if ( is_stat( flag_table ) ) { one_argument( argument, word ); if ( ( bit = flag_lookup2( word, flag_table ) ) != NO_FLAG ) return bit; else return NO_FLAG; } for (; ;) { argument = one_argument( argument, word ); if ( word[0] == '\0' ) break; if ( ( bit = flag_lookup2( word, flag_table ) ) != NO_FLAG ) { SET_BIT( marked, bit ); found = TRUE; } } if ( found ) return marked; else return NO_FLAG; } /* Returns string with name(s) of the flags or stat entered. * * Called by act_olc.c, olc.c, and olc_save.c. */ char *flag_string( const struct flag_type *flag_table, int bits ) { static char buf[512]; int flag; buf[0] = '\0'; for (flag = 0; flag_table[flag].name != NULL; flag++) { if ( !is_stat( flag_table ) && IS_SET(bits, flag_table[flag].bit) ) { strcat( buf, " " ); strcat( buf, flag_table[flag].name ); } else if ( flag_table[flag].bit == bits ) { strcat( buf, " " ); strcat( buf, flag_table[flag].name ); break; } } return (buf[0] != '\0') ? buf+1 : "none"; } RESET_DATA *new_reset_data( void ) { RESET_DATA *pReset; if ( !reset_free ) { pReset = alloc_perm( sizeof(*pReset) ); top_reset++; } else { pReset = reset_free; reset_free = reset_free->next; } pReset->next = NULL; pReset->command = 'X'; pReset->arg1 = 0; pReset->arg2 = 0; pReset->arg3 = 0; pReset->arg4 = 0; return pReset; } void free_reset_data( RESET_DATA *pReset ) { pReset->next = reset_free; reset_free = pReset; return; } AREA_DATA *new_area( void ) { AREA_DATA *pArea; char buf[MIL]; int count; if ( !area_free ) { pArea = alloc_perm( sizeof(*pArea) ); top_area++; } else { pArea = area_free; area_free = area_free->next; } memset(pArea, 0, sizeof(*pArea )); pArea->next = NULL; pArea->name = str_dup( "New area" ); pArea->pCabal = NULL; pArea->towers = NULL; pArea->exits = NULL; pArea->raid = NULL; pArea->last_raid = 0; pArea->area_flags = 0; pArea->security = 1; pArea->prefix = str_empty; pArea->builders = str_dup( "None" ); pArea->min_vnum = 0; pArea->max_vnum = 0; pArea->age = 0; pArea->bastion_max = 0; pArea->bastion_current = 0; for (count = 0; count < MAX_CRIME; count++) { pArea->crimes[count] = 0; } pArea->idle = 0; pArea->nplayer = 0; pArea->empty = TRUE; sprintf( buf, "area%d.are", pArea->vnum ); pArea->file_name = str_dup( buf ); pArea->vnum = top_area-1; pArea->credits = str_dup( "{ All }" ); return pArea; } void free_area( AREA_DATA *pArea ) { free_string( pArea->name ); free_string( pArea->file_name ); free_string( pArea->builders ); free_string( pArea->credits ); pArea->next = area_free->next; area_free = pArea; return; } EXIT_DATA *new_exit( void ) { EXIT_DATA *pExit; if ( !exit_free ) { pExit = alloc_perm( sizeof(*pExit) ); top_exit++; } else { pExit = exit_free; exit_free = exit_free->next; } pExit->to_room = NULL; pExit->vnum = 0; pExit->next = NULL; pExit->next_in_area = NULL; pExit->traps = NULL; pExit->exit_info = 0; pExit->key = 0; pExit->orig_door = 0; pExit->keyword = &str_empty[0]; pExit->description = &str_empty[0]; pExit->rs_flags = 0; return pExit; } void free_exit( EXIT_DATA *pExit ) { free_string( pExit->keyword ); free_string( pExit->description ); pExit->next = exit_free; exit_free = pExit; return; } ROOM_INDEX_DATA *new_room_index( void ) { ROOM_INDEX_DATA *pRoom; int door; if ( !room_index_free ) { pRoom = alloc_perm( sizeof(*pRoom) ); top_room++; } else { pRoom = room_index_free; room_index_free = room_index_free->next; } pRoom->next = NULL; pRoom->area = NULL; pRoom->vnum = 0; pRoom->pCabal = NULL; pRoom->people = NULL; pRoom->contents = NULL; pRoom->name = &str_empty[0]; pRoom->description = &str_empty[0]; pRoom->description2 = &str_empty[0]; pRoom->extra_descr = NULL; pRoom->watch_vnums = NULL; pRoom->rprogs = NULL; pRoom->room_flags = 0; pRoom->room_flags2 = 0; pRoom->sector_type = 0; pRoom->light = 0; pRoom->heal_rate = 100; pRoom->mana_rate = 100; pRoom->temp = 72; for ( door=0; door < MAX_DIR; door++ ) pRoom->exit[door] = NULL; memset(&pRoom->room_armies, 0, sizeof( ARMY_ROOM_DATA )); return pRoom; } void free_room_index( ROOM_INDEX_DATA *pRoom ) { int door; EXTRA_DESCR_DATA *pExtra; RESET_DATA *pReset; if (pRoom == NULL) return; /* in order to free this we have to check if its a string in shared space, or perm-allocated */ if (pRoom->name > string_space && pRoom->name < top_string ){ free_string( pRoom->name ); } if (pRoom->description > string_space && pRoom->description < top_string ){ free_string( pRoom->description ); } if (pRoom->description2 > string_space && pRoom->description2 < top_string ){ free_string( pRoom->description2 ); } while (pRoom->rprogs ){ PROG_LIST* pr = pRoom->rprogs; pRoom->rprogs = pr->next; free_rprog( pr ); } for ( door = 0; door < MAX_DIR; door++ ){ if ( pRoom->exit[door] ) free_exit( pRoom->exit[door] ); } while ( (pExtra = pRoom->extra_descr)){ pRoom->extra_descr = pExtra->next; free_extra_descr( pExtra ); } while ( (pReset = pRoom->reset_first)){ pRoom->reset_first = pReset->next; free_reset_data( pReset ); } while ( pRoom->watch_vnums ){ Double_List * tmp_list = pRoom->watch_vnums; pRoom->watch_vnums = tmp_list->next_node; free (tmp_list); } pRoom->next = room_index_free; room_index_free = pRoom; return; } extern AFFECT_DATA *affect_free; extern AFFECT_DATA *skill_free; SHOP_DATA *new_shop( void ) { SHOP_DATA *pShop; int buy; if ( !shop_free ) { pShop = alloc_perm( sizeof(*pShop) ); top_shop++; } else { pShop = shop_free; shop_free = shop_free->next; } if ( shop_first == NULL ) shop_first = pShop; if ( shop_last != NULL ) shop_last->next = pShop; shop_last = pShop; pShop->next = NULL; pShop->keeper = 0; for ( buy=0; buy<MAX_TRADE; buy++ ) pShop->buy_type[buy] = 0; pShop->profit_buy = 100; pShop->profit_sell = 100; pShop->open_hour = 0; pShop->close_hour = 23; return pShop; } void free_shop( SHOP_DATA *pShop ) { pShop->next = shop_free; shop_free = pShop; return; } OBJ_INDEX_DATA *new_obj_index( void ) { OBJ_INDEX_DATA *pObj; int value; if ( !obj_index_free ) { pObj = alloc_perm( sizeof(*pObj) ); top_obj_index++; } else { pObj = obj_index_free; obj_index_free = obj_index_free->next; } pObj->next = NULL; pObj->extra_descr = NULL; pObj->affected = NULL; pObj->area = NULL; pObj->name = str_dup( "no name" ); pObj->short_descr = str_dup( "(no short description)" ); pObj->description = str_dup( "(no description)" ); pObj->vnum = 0; pObj->item_type = ITEM_TRASH; pObj->extra_flags = 0; pObj->wear_flags = 0; pObj->count = 0; pObj->class = -1; pObj->race = 0; pObj->weight = 0; pObj->cost = 0; pObj->material = str_dup( "unknown" ); pObj->condition = 100; for ( value = 0; value < 5; value++ ) pObj->value[value] = 0; pObj->new_format = TRUE; return pObj; } void free_obj_index( OBJ_INDEX_DATA *pObj ) { EXTRA_DESCR_DATA *pExtra; AFFECT_DATA *pAf; OBJ_SPELL_DATA *os, *os_next; int num_times = 0; for (os = pObj->spell; os != NULL; os = os_next) { os_next = os->next; free_string(os->message); free_string(os->message2); /* break out of loop if stupid number of times through */ if (num_times++ > STUPID_NUMBER_OF_SPELLS) { break; } } if (pObj->message) { free_string(pObj->message->onself); free_string(pObj->message->onother); free_string(pObj->message->offself); free_string(pObj->message->offother); } free_string( pObj->name ); free_string( pObj->short_descr ); free_string( pObj->description ); free_oprog( pObj->oprogs ); free_string( pObj->material ); for ( pAf = pObj->affected; pAf; pAf = pAf->next ) free_affect( pAf ); for ( pExtra = pObj->extra_descr; pExtra; pExtra = pExtra->next ) free_extra_descr( pExtra ); pObj->next = obj_index_free; obj_index_free = pObj; return; } MOB_INDEX_DATA *new_mob_index( void ) { MOB_INDEX_DATA *pMob; if ( !mob_index_free ) { pMob = alloc_perm( sizeof(*pMob) ); top_mob_index++; } else { pMob = mob_index_free; mob_index_free = mob_index_free->next; } pMob->next = NULL; pMob->spec_fun = NULL; pMob->pShop = NULL; pMob->area = NULL; pMob->player_name = str_dup( "no name" ); pMob->short_descr = str_dup( "(no short description)" ); pMob->long_descr = str_dup( "(no long description)\n\r" ); pMob->description = &str_empty[0]; pMob->vnum = 0; pMob->count = 0; pMob->killed = 0; pMob->sex = 0; pMob->pCabal = NULL; pMob->level = 0; pMob->act = ACT_IS_NPC; pMob->act2 = 0; pMob->affected_by = 0; pMob->alignment = 0; pMob->hitroll = 0; pMob->race = race_lookup( "human" ); pMob->form = 0; pMob->parts = 0; pMob->imm_flags = 0; pMob->res_flags = 0; pMob->vuln_flags = 0; pMob->off_flags = 0; pMob->size = SIZE_MEDIUM; pMob->ac[AC_PIERCE] = 0; pMob->ac[AC_BASH] = 0; pMob->ac[AC_SLASH] = 0; pMob->ac[AC_EXOTIC] = 0; pMob->hit[DICE_NUMBER] = 0; pMob->hit[DICE_TYPE] = 0; pMob->hit[DICE_BONUS] = 0; pMob->mana[DICE_NUMBER] = 0; pMob->mana[DICE_TYPE] = 0; pMob->mana[DICE_BONUS] = 0; pMob->damage[DICE_NUMBER] = 0; pMob->damage[DICE_TYPE] = 0; pMob->damage[DICE_NUMBER] = 0; pMob->start_pos = POS_STANDING; pMob->default_pos = POS_STANDING; pMob->gold = 0; pMob->new_format = TRUE; return pMob; } void free_mob_index( MOB_INDEX_DATA *pMob ) { TRIGFILE_DATA *tf, *tf_next; MPROG_DATA *mp, *mp_next; for (tf = pMob->trigfile; tf != NULL; tf = tf_next) { tf_next = tf->next; free_string(tf->name); } for (mp = pMob->mobprogs; mp != NULL; mp = mp_next) { mp_next = mp->next; free_string(mp->arglist); free_string(mp->comlist); } free_string( pMob->player_name ); free_string( pMob->short_descr ); free_string( pMob->long_descr ); free_string( pMob->description ); free_shop( pMob->pShop ); pMob->next = mob_index_free; mob_index_free = pMob; return; } /* Clears string and puts player into editing mode. */ void string_edit( CHAR_DATA *ch, char **pString ) { send_to_char( "-========- Entering EDIT Mode -=========-\n\r", ch ); send_to_char( " Type .h on a new line for help\n\r", ch ); send_to_char( " Terminate with a ~ or @ on a blank line.\n\r", ch ); send_to_char( "-=======================================-\n\r", ch ); if ( *pString == NULL ) *pString = str_dup( "" ); else **pString = '\0'; ch->desc->pString = pString; return; } /* Puts player into append mode for given string. * * Called by (many)olc_act.c */ void string_append( CHAR_DATA *ch, char **pString ) { send_to_char( "-=======- Entering APPEND Mode -========-\n\r", ch ); send_to_char( " Type .h on a new line for help\n\r", ch ); send_to_char( " Terminate with a ~ or @ on a blank line.\n\r", ch ); send_to_char( "-=======================================-\n\r", ch ); if ( *pString == NULL ) *pString = str_dup( "" ); send_to_char( *pString, ch ); if ( *(*pString + strlen( *pString ) - 1) != '\r' ) send_to_char( "\n\r", ch ); ch->desc->pString = pString; return; } /* Substitutes one string for another. * * Called by string_add(string.c) (aedit_builder)olc_act.c. */ char * string_replace( char * orig, char * old, char * new ) { char xbuf[MSL]; int i; xbuf[0] = '\0'; strcpy( xbuf, orig ); if ( strstr( orig, old ) != NULL ) { i = strlen( orig ) - strlen( strstr( orig, old ) ); xbuf[i] = '\0'; strcat( xbuf, new ); strcat( xbuf, &orig[i+strlen( old )] ); free_string( orig ); } return str_dup( xbuf ); } /* Interpreter for string editing. * * Called by game_loop_xxxx(comm.c). */ void string_add( CHAR_DATA *ch, char *argument ) { char buf[MSL]; smash_tilde( argument ); if ( *argument == '.' ) { char arg1 [MIL]; char arg2 [MIL]; char arg3 [MIL]; argument = one_argument( argument, arg1 ); argument = first_arg( argument, arg2, FALSE ); argument = first_arg( argument, arg3, FALSE ); if ( !str_cmp( arg1, ".c" ) ) { send_to_char( "String cleared.\n\r", ch ); free_string( *ch->desc->pString ); *ch->desc->pString = str_dup( "" ); return; } if ( !str_cmp( arg1, ".s" ) ) { send_to_char( "String so far:\n\r", ch ); send_to_char( *ch->desc->pString, ch ); return; } if ( !str_cmp( arg1, ".r" ) ) { if ( arg2[0] == '\0' ) { send_to_char( "usage: .r \"old string\" \"new string\"\n\r", ch ); return; } smash_tilde( arg3 ); *ch->desc->pString = string_replace( *ch->desc->pString, arg2, arg3 ); sprintf( buf, "'%s' replaced with '%s'.\n\r", arg2, arg3 ); send_to_char( buf, ch ); return; } if ( !str_cmp( arg1, ".f" ) ) { *ch->desc->pString = format_string( *ch->desc->pString ); send_to_char( "String formatted.\n\r", ch ); return; } if ( !str_cmp( arg1, ".h" ) ) { send_to_char( "Sedit help (commands on blank line): \n\r", ch ); send_to_char( ".r 'old' 'new' - replace a substring \n\r", ch ); send_to_char( " (requires '', \"\") \n\r", ch ); send_to_char( ".h - get help (this info)\n\r", ch ); send_to_char( ".s - show string so far \n\r", ch ); send_to_char( ".f - (word wrap) string \n\r", ch ); send_to_char( ".c - clear string so far \n\r", ch ); send_to_char( "@ - end string \n\r", ch ); return; } send_to_char( "SEdit: Invalid dot command.\n\r", ch ); return; } if ( *argument == '~' || *argument == '@' ) { if ( ch->desc->editor == ED_MPCODE ) /* for the mobprogs */ { MOB_INDEX_DATA *mob; int hash; PROG_LIST *mpl; PROG_CODE *mpc; EDIT_MPCODE(ch, mpc); if ( mpc != NULL ) for ( hash = 0; hash < MAX_KEY_HASH; hash++ ) for ( mob = mob_index_hash[hash]; mob; mob = mob->next ) for ( mpl = mob->mprogs; mpl; mpl = mpl->next ) if ( mpl->vnum == mpc->vnum ) { sprintf( buf, "Fixing mob %d.\n\r", mob->vnum ); send_to_char( buf, ch ); mpl->code = mpc->code; } } if ( ch->desc->editor == ED_OPCODE ) /* for the objprogs */ { OBJ_INDEX_DATA *obj; int hash; PROG_LIST *opl; PROG_CODE *opc; EDIT_OPCODE(ch, opc); if ( opc != NULL ) for ( hash = 0; hash < MAX_KEY_HASH; hash++ ) for ( obj = obj_index_hash[hash]; obj; obj = obj->next ) for ( opl = obj->oprogs; opl; opl = opl->next ) if ( opl->vnum == opc->vnum ) { sprintf( buf, "Fixing object %d.\n\r", obj->vnum ); send_to_char( buf, ch ); opl->code = opc->code; } } if ( ch->desc->editor == ED_RPCODE ) /* for the roomprogs */ { ROOM_INDEX_DATA *room; int hash; PROG_LIST *rpl; PROG_CODE *rpc; EDIT_RPCODE(ch, rpc); if ( rpc != NULL ) for ( hash = 0; hash < MAX_KEY_HASH; hash++ ) for ( room = room_index_hash[hash]; room; room = room->next ) for ( rpl = room->rprogs; rpl; rpl = rpl->next ) if ( rpl->vnum == rpc->vnum ) { sprintf( buf, "Fixing room %d.\n\r", room->vnum ); send_to_char( buf, ch ); rpl->code = rpc->code; } } ch->desc->pString = NULL; return; } strcpy( buf, *ch->desc->pString ); if ( strlen( buf ) + strlen( argument ) >= ( MSL - 4 ) ) { send_to_char( "String too long, last line skipped.\n\r", ch ); ch->desc->pString = NULL; return; } smash_tilde( argument ); strcat( buf, argument ); strcat( buf, "\n\r" ); free_string( *ch->desc->pString ); *ch->desc->pString = str_dup( buf ); return; } /* Special string formating and word-wrapping. * * Called by string_add(string.c) (many)olc_act.c */ char *format_string( char *oldstring ) { char xbuf[MSL]; char xbuf2[MSL]; char *rdesc; int i=0; bool cap=TRUE; xbuf[0]=xbuf2[0]=0; i=0; for (rdesc = oldstring; *rdesc; rdesc++){ /* New Line */ if (*rdesc=='\n'){ /* check for empty seperator lines */ if (*(rdesc + 1) && *(rdesc + 2) && *(rdesc + 3) && *(rdesc + 2) == ' ' && *(rdesc + 3) == '\n'){ xbuf[i++]= '\n'; xbuf[i++]= '\r'; xbuf[i++]= '\n'; xbuf[i++]= '\r'; rdesc += 4; } else if (xbuf[i-1] != ' '){ xbuf[i]=' '; i++; } } /* return */ else if (*rdesc=='\r'){ if (xbuf[i-1] != ' '){ xbuf[i]=' '; i++; } } /* Space */ else if (*rdesc==' '){ if (xbuf[i-1] != ' '){ xbuf[i]=' '; i++; } } /* bracket */ else if (*rdesc==')'){ if (xbuf[i-1]==' ' && xbuf[i-2]==' ' && (xbuf[i-3]=='.' || xbuf[i-3]=='?' || xbuf[i-3]=='!')){ xbuf[i-2]=*rdesc; xbuf[i-1]=' '; xbuf[i]=' '; i++; } else{ xbuf[i]=*rdesc; i++; } } else if (*rdesc=='.' || *rdesc=='?' || *rdesc=='!'){ if (xbuf[i-1]==' ' && xbuf[i-2]==' ' && (xbuf[i-3]=='.' || xbuf[i-3]=='?' || xbuf[i-3]=='!')) { xbuf[i-2]=*rdesc; if (*(rdesc+1) != '\"'){ xbuf[i-1]=' '; xbuf[i]=' '; i++; } else{ xbuf[i-1]='\"'; xbuf[i]=' '; xbuf[i+1]=' '; i+=2; rdesc++; } } else{ xbuf[i]=*rdesc; if (*(rdesc+1) != '\"'){ xbuf[i+1]=' '; xbuf[i+2]=' '; i += 3; } else{ xbuf[i+1]='\"'; xbuf[i+2]=' '; xbuf[i+3]=' '; i += 4; rdesc++; } } cap = TRUE; } else{ xbuf[i]=*rdesc; if ( cap ){ cap = FALSE; xbuf[i] = UPPER( xbuf[i] ); } i++; } } xbuf[i]=0; strcpy(xbuf2,xbuf); rdesc=xbuf2; xbuf[0]=0; for ( ; ; ) { bool fSkip = FALSE; for (i=0; i<77; i++) if (!*(rdesc+i)) break; if (i<77) break; /* check for already existing returns first */ for (i=(xbuf[0]?76:73) ; i ; i--){ if (*(rdesc+i)=='\r'){ *(rdesc+i)=0; strcat(xbuf,rdesc); strcat(xbuf,"\r"); rdesc += i+1; while (*rdesc == ' ') rdesc++; fSkip = TRUE; break; } } if (fSkip) continue; /* check for spaces now */ for (i=(xbuf[0]?76:73) ; i ; i--) if (*(rdesc+i)==' ') break; if (i) { *(rdesc+i)=0; strcat(xbuf,rdesc); strcat(xbuf,"\n\r"); rdesc += i+1; while (*rdesc == ' ') rdesc++; } else { //bug ("No spaces", 0); *(rdesc+75)=0; strcat(xbuf,rdesc); strcat(xbuf,"-\n\r"); rdesc += 76; } } while (*(rdesc+i) && (*(rdesc+i)==' ' )) // || *(rdesc+i)=='\n' || *(rdesc+i)=='\r')) i--; *(rdesc+i+1)=0; strcat(xbuf,rdesc); if (xbuf[strlen(xbuf)-2] != '\n') strcat(xbuf,"\n\r"); free_string(oldstring); return(str_dup(xbuf)); } /* Used above in string_add. Because this function does not * * modify case if fCase is FALSE and because it understands * * parenthesis, it would probably make a nice replacement * * for one_argument. */ /* Pick off one argument from a string and return the rest. * * Understands quates, parenthesis (barring ) ('s) and percentages. * * Called by string_add(string.c) */ char *first_arg( char *argument, char *arg_first, bool fCase ) { char cEnd; while ( *argument == ' ' ) argument++; cEnd = ' '; if ( *argument == '\'' || *argument == '"' || *argument == '%' || *argument == '(' ) { if ( *argument == '(' ) { cEnd = ')'; argument++; } else cEnd = *argument++; } while ( *argument != '\0' ) { if ( *argument == cEnd ) { argument++; break; } if ( fCase ) *arg_first = LOWER(*argument); else *arg_first = *argument; arg_first++; argument++; } *arg_first = '\0'; while ( *argument == ' ' ) argument++; return argument; } /* Used in olc_act.c for aedit_builders. */ char * string_unpad( char * argument ) { char buf[MSL]; char *s; s = argument; while ( *s == ' ' ) s++; strcpy( buf, s ); s = buf; if ( *s != '\0' ) { while ( *s != '\0' ) s++; s--; while( *s == ' ' ) s--; s++; *s = '\0'; } free_string( argument ); return str_dup( buf ); } /* Same as capitalize but changes the pointer's data. * * Used in olc_act.c in aedit_builder. */ char * string_proper( char * argument ) { char *s; s = argument; while ( *s != '\0' ) { if ( *s != ' ' ) { *s = UPPER(*s); while ( *s != ' ' && *s != '\0' ) s++; } else s++; } return argument; } PROG_CODE *new_mpcode(void) { PROG_CODE *NewCode; if (!mpcode_free) { NewCode = alloc_perm(sizeof(*NewCode) ); top_mprog_index++; } else { NewCode = mpcode_free; mpcode_free = mpcode_free->next; } NewCode->vnum = 0; NewCode->code = str_dup(""); NewCode->next = NULL; return NewCode; } PROG_CODE *new_opcode(void) { PROG_CODE *NewCode; if (!opcode_free) { NewCode = alloc_perm(sizeof(*NewCode) ); top_oprog_index++; } else { NewCode = opcode_free; opcode_free = opcode_free->next; } NewCode->vnum = 0; NewCode->code = str_dup(""); NewCode->next = NULL; return NewCode; } PROG_CODE *new_rpcode(void) { PROG_CODE *NewCode; if (!rpcode_free) { NewCode = alloc_perm(sizeof(*NewCode) ); top_rprog_index++; } else { NewCode = rpcode_free; rpcode_free = rpcode_free->next; } NewCode->vnum = 0; NewCode->code = str_dup(""); NewCode->next = NULL; return NewCode; } void free_opcode(PROG_CODE *pOcode) { free_string(pOcode->code); pOcode->next = opcode_free; opcode_free = pOcode; return; } void free_rpcode(PROG_CODE *pRcode) { free_string(pRcode->code); pRcode->next = rpcode_free; rpcode_free = pRcode; return; } void free_mpcode(PROG_CODE *pMcode) { free_string(pMcode->code); pMcode->next = mpcode_free; mpcode_free = pMcode; return; }