/*************************************************************************** * File: olc_act.c * * * * 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. * * * * This code was freely distributed with the The Isles 1.1 source code, * * and has been used here for OLC - OLC would not be what it is without * * all the previous coders who released their source code. * * * ***************************************************************************/ #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 <limits.h> /* OLC 1.1b */ #include "merc.h" #include "olc.h" struct olc_help_type { char *command; const void *structure; char *desc; }; bool show_version( CHAR_DATA *ch, char *argument ) { send_to_char( VERSION, ch ); send_to_char( "\n\r", ch ); send_to_char( AUTHOR, ch ); send_to_char( "\n\r", ch ); send_to_char( DATE, ch ); send_to_char( "\n\r", ch ); send_to_char( CREDITS, ch ); send_to_char( "\n\r", ch ); return FALSE; } /* * This table contains help commands and a brief description of each. * ------------------------------------------------------------------ */ const struct olc_help_type help_table[] = { { "area", area_flags, "Area attributes." }, { "room", room_flags, "Room attributes." }, { "sector", sector_flags, "Sector types, terrain." }, { "exit", exit_flags, "Exit types." }, { "type", type_flags, "Types of objects." }, { "extra", extra_flags, "Object attributes." }, { "wear", wear_flags, "Where to wear object." }, { "spec", spec_table, "Available special programs." }, { "sex", sex_flags, "Sexes." }, { "act", act_flags, "Mobile attributes." }, { "affect", affect_flags, "Mobile affects." }, { "wear-loc", wear_loc_flags, "Where mobile wears object." }, { "spells", skill_table, "Names of current spells." }, { "weapon", weapon_flags, "Type of weapon." }, { "container", container_flags, "Container status." }, { "liquid", liquid_flags, "Types of liquids." }, { "", 0, "" } }; /***************************************************************************** Name: show_flag_cmds Purpose: Displays settable flags and stats. Called by: show_help(olc_act.c). ****************************************************************************/ void show_flag_cmds( CHAR_DATA *ch, const struct flag_type *flag_table ) { char buf[ MAX_STRING_LENGTH ]; char *buf1; int flag; int col; buf1 = NULL; col = 0; for( flag = 0 ; *flag_table[flag].name ; flag++ ) { if( flag_table[flag].settable ) { sprintf( buf, "%-19.18s", flag_table[flag].name ); str_cat( &buf1, buf ); if( ++col % 4 == 0 ) str_cat( &buf1, "\n\r" ); } } if( col % 4 != 0 ) str_cat( &buf1, "\n\r" ); page_to_char( buf1, ch ); free( buf1 ); return; } /***************************************************************************** Name: show_skill_cmds Purpose: Displays all skill functions. Does remove those damn immortal commands from the list. Could be improved by: (1) Adding a check for a particular class. (2) Adding a check for a level range. Called by: show_help(olc_act.c). ****************************************************************************/ void show_skill_cmds( CHAR_DATA *ch, int tar ) { char buf[ MAX_STRING_LENGTH ]; char *buf1; int sn; int col; buf1 = NULL; col = 0; for( sn = 0 ; sn < MAX_SKILL ; sn++ ) { if( !skill_table[sn].name ) break; if( !str_cmp( skill_table[sn].name, "reserved" ) || skill_table[sn].spell_fun == spell_null ) continue; if( tar == -1 || skill_table[sn].target == tar ) { sprintf( buf, "%-19.18s", skill_table[sn].name ); str_cat( &buf1, buf ); if( ++col % 4 == 0 ) str_cat( &buf1, "\n\r" ); } } if( col % 4 != 0 ) str_cat( &buf1, "\n\r" ); page_to_char( buf1, ch ); free( buf1 ); return; } /***************************************************************************** Name: show_spec_cmds Purpose: Displays settable special functions. Called by: show_help(olc_act.c). ****************************************************************************/ void show_spec_cmds( CHAR_DATA *ch ) { char buf[ MAX_STRING_LENGTH ]; char *buf1; int spec; int col; buf1 = NULL; col = 0; send_to_char( "Preceed special functions with 'spec_'\n\r\n\r", ch ); for( spec = 0 ; *spec_table[spec].spec_fun ; spec++ ) { sprintf( buf, "%-19.18s", &spec_table[spec].spec_name[5] ); str_cat( &buf1, buf ); if( ++col % 4 == 0 ) str_cat( &buf1, "\n\r" ); } if( col % 4 != 0 ) str_cat( &buf1, "\n\r" ); page_to_char( buf1, ch ); free( buf1 ); return; } /***************************************************************************** Name: show_help Purpose: Displays help for many tables used in OLC. Called by: olc interpreters. ****************************************************************************/ bool show_help( CHAR_DATA *ch, char *argument ) { char buf[ MAX_STRING_LENGTH ]; char arg[ MAX_INPUT_LENGTH ]; char spell[ MAX_INPUT_LENGTH ]; int cnt; argument = one_argument( argument, arg ); one_argument( argument, spell ); /* * Display syntax. */ if( arg[0] == '\0' ) { send_to_char( "Syntax: ? [command]\n\r\n\r", ch ); send_to_char( "[command] [description]\n\r", ch ); for( cnt = 0 ; help_table[cnt].command[0] != '\0' ; cnt++ ) { sprintf( buf, "%-10.10s -%s\n\r", capitalize( help_table[cnt].command ), help_table[cnt].desc ); send_to_char( buf, ch ); } return FALSE; } /* * Find the command, show changeable data. * --------------------------------------- */ for( cnt = 0 ; *help_table[cnt].command ; cnt++ ) { if( arg[0] == help_table[cnt].command[0] && !str_prefix( arg, help_table[cnt].command ) ) { if( help_table[cnt].structure == spec_table ) { show_spec_cmds( ch ); return FALSE; } else if( help_table[cnt].structure == skill_table ) { if( spell[0] == '\0' ) { send_to_char( "Syntax: ? spells " "[ignore/attack/defend/self/object/all]\n\r", ch ); return FALSE; } if( !str_prefix( spell, "all" ) ) show_skill_cmds( ch, -1 ); else if( !str_prefix( spell, "ignore" ) ) show_skill_cmds( ch, TAR_IGNORE ); else if( !str_prefix( spell, "attack" ) ) show_skill_cmds( ch, TAR_CHAR_OFFENSIVE ); else if( !str_prefix( spell, "defend" ) ) show_skill_cmds( ch, TAR_CHAR_DEFENSIVE ); else if( !str_prefix( spell, "self" ) ) show_skill_cmds( ch, TAR_CHAR_SELF ); else if( !str_prefix( spell, "object" ) ) show_skill_cmds( ch, TAR_OBJ_INV ); else send_to_char( "Syntax: ? spell " "[ignore/attack/defend/self/object/all]\n\r", ch ); return FALSE; } else { show_flag_cmds( ch, help_table[cnt].structure ); return FALSE; } } } show_help( ch, "" ); return FALSE; } bool redit_mlist( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMobIndex; AREA_DATA *pArea; char buf [ MAX_STRING_LENGTH ]; char *buf1; char arg [ MAX_INPUT_LENGTH ]; bool fAll, found; int vnum; int col = 0; one_argument( argument, arg ); if( arg[0] == '\0' ) { send_to_char( "Syntax: mlist <all/name>\n\r", ch ); return FALSE; } pArea = ch->in_room->area; buf1 = NULL; fAll = !str_cmp( arg, "all" ); found = FALSE; for( vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++ ) { if( ( pMobIndex = get_mob_index( vnum ) ) ) { if( fAll || is_name( arg, pMobIndex->player_name ) ) { found = TRUE; sprintf( buf, "[%5d] %-17.16s", pMobIndex->vnum, capitalize( pMobIndex->short_descr ) ); str_cat( &buf1, buf ); if( ++col % 3 == 0 ) str_cat( &buf1, "\n\r" ); } } } if( !found ) { send_to_char( "Mobile(s) not found in this area.\n\r", ch); return FALSE; } if( col % 3 != 0 ) str_cat( &buf1, "\n\r" ); page_to_char( buf1, ch ); free( buf1 ); return FALSE; } bool redit_olist( CHAR_DATA *ch, char *argument ) { OBJ_INDEX_DATA *pObjIndex; AREA_DATA *pArea; char buf[ MAX_STRING_LENGTH ]; char *buf1; char arg[ MAX_INPUT_LENGTH ]; bool fAll, found; int vnum; int col = 0; one_argument( argument, arg ); if( arg[0] == '\0' ) { send_to_char( "Syntax: olist <all/name/item_type>\n\r", ch ); return FALSE; } pArea = ch->in_room->area; buf1 = NULL; fAll = !str_cmp( arg, "all" ); found = FALSE; for( vnum = pArea->lvnum ; vnum <= pArea->uvnum ; vnum++ ) { if( ( pObjIndex = get_obj_index( vnum ) ) ) { if( fAll || is_name( arg, pObjIndex->name ) || flag_value( type_flags, arg ) == pObjIndex->item_type ) { found = TRUE; sprintf( buf, "[%5d] %-17.16s", pObjIndex->vnum, capitalize( pObjIndex->short_descr ) ); str_cat( &buf1, buf ); if ( ++col % 3 == 0 ) str_cat( &buf1, "\n\r" ); } } } if( !found ) { send_to_char( "Object(s) not found in this area.\n\r", ch); return FALSE; } if( col % 3 != 0 ) str_cat( &buf1, "\n\r" ); send_to_char( buf1, ch ); free( buf1 ); return FALSE; } bool redit_mshow( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMob; int value; if( argument[0] == '\0' ) { send_to_char( "Syntax: mshow <vnum>\n\r", ch ); return FALSE; } if( is_number( argument ) ) { value = atoi( argument ); if( !( pMob = get_mob_index( value ) )) { send_to_char( "REdit: That mobile does not exist.\n\r", ch ); return FALSE; } ch->desc->pEdit = (void *)pMob; } medit_show( ch, argument ); ch->desc->pEdit = (void *)ch->in_room; return FALSE; } bool redit_oshow( CHAR_DATA *ch, char *argument ) { OBJ_INDEX_DATA *pObj; int value; if( argument[0] == '\0' ) { send_to_char( "Syntax: oshow <vnum>\n\r", ch ); return FALSE; } if( is_number( argument ) ) { value = atoi( argument ); if( !( pObj = get_obj_index( value ) )) { send_to_char( "REdit: That object does not exist.\n\r", ch ); return FALSE; } ch->desc->pEdit = (void *)pObj; } oedit_show( ch, argument ); ch->desc->pEdit = (void *)ch->in_room; return FALSE; } /***************************************************************************** Name: check_range( lower vnum, upper vnum ) Purpose: Ensures the range spans only one area. Called by: aedit_vnum(olc_act.c). ****************************************************************************/ bool check_range( int lower, int upper ) { AREA_DATA *pArea; int cnt = 0; for( pArea = area_first ; pArea ; pArea = pArea->next ) { /* * lower < area < upper */ if( ( lower <= pArea->lvnum && upper >= pArea->lvnum ) || ( upper >= pArea->uvnum && lower <= pArea->uvnum ) ) cnt++; if( cnt > 1 ) return FALSE; } return TRUE; } AREA_DATA *get_vnum_area( int vnum ) { AREA_DATA *pArea; for( pArea = area_first ; pArea ; pArea = pArea->next ) { if( vnum >= pArea->lvnum && vnum <= pArea->uvnum ) return pArea; } return 0; } /* * Area Editor Functions. */ bool aedit_show( CHAR_DATA *ch, char *argument ) { AREA_DATA* pArea; char buf[ MAX_STRING_LENGTH ]; char *buf1; EDIT_AREA( ch, pArea ); buf1 = NULL; sprintf( buf, "Name: [%5d] %s\n\r", pArea->vnum, pArea->name ); str_cat( &buf1, buf ); sprintf( buf, "Recall: [%5d] %s\n\r", pArea->recall, get_room_index( pArea->recall ) ? get_room_index( pArea->recall )->name : "none" ); str_cat( &buf1, buf ); sprintf( buf, "File: %s\n\r", pArea->filename ); str_cat( &buf1, buf ); sprintf( buf, "Vnums: [%d-%d]\n\r", pArea->lvnum, pArea->uvnum ); str_cat( &buf1, buf ); sprintf( buf, "Age: [%d]\n\r", pArea->age ); str_cat( &buf1, buf ); sprintf( buf, "Players: [%d]\n\r", pArea->nplayer ); str_cat( &buf1, buf ); sprintf( buf, "Security: [%d]\n\r", pArea->security ); str_cat( &buf1, buf ); sprintf( buf, "Builders: [%s]\n\r", pArea->builders ); str_cat( &buf1, buf ); sprintf( buf, "Flags: [%s]\n\r", flag_string( area_flags, pArea->area_flags ) ); str_cat( &buf1, buf ); page_to_char( buf1, ch ); free( buf1 ); return FALSE; } bool aedit_reset( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; EDIT_AREA( ch, pArea ); reset_area( pArea ); send_to_char_bw( "Area reset.\n\r", ch ); return FALSE; } bool aedit_create( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; if( top_area >= INT_MAX ) /* OLC 1.1b */ { send_to_char_bw( "We're out of vnums for new areas.\n\r", ch ); return FALSE; } pArea = new_area( ); area_last->next = pArea; area_last = pArea; /* Thanks, Walker. */ ch->desc->pEdit = ( void * )pArea; SET_BIT( pArea->area_flags, AREA_ADDED ); send_to_char( "Area Created.\n\r", ch ); return TRUE; /* OLC 1.1b */ } bool aedit_name( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; EDIT_AREA( ch, pArea ); if( argument[0] == '\0' ) { send_to_char( "Syntax: name [$name]\n\r", ch ); return FALSE; } free_string( pArea->name ); pArea->name = str_dup( argument ); send_to_char_bw( "Name set.\n\r", ch ); return TRUE; } bool aedit_file( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; char file[ MAX_STRING_LENGTH ]; int i; int length; EDIT_AREA( ch, pArea ); one_argument( argument, file ); /* Forces Lowercase */ if( argument[0] == '\0' ) { send_to_char( "Syntax: filename [$file]\n\r", ch ); return FALSE; } /* * Simple Syntax Check. */ length = strlen( argument ); /* * Allow only letters and numbers. */ for( i = 0 ; i < length ; i++ ) { if( !isalnum( file[i] ) ) { send_to_char( "Only letters and numbers are valid.\n\r", ch ); return FALSE; } } free_string( pArea->filename ); strcat( file, ".are" ); pArea->filename = str_dup( file ); send_to_char( "Filename set.\n\r", ch ); return TRUE; } bool aedit_age( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; char age[ MAX_STRING_LENGTH ]; EDIT_AREA( ch, pArea ); one_argument( argument, age ); if( !is_number( age ) || age[0] == '\0' ) { send_to_char( "Syntax: age [#age]\n\r", ch ); return FALSE; } pArea->age = atoi( age ); send_to_char( "Age set.\n\r", ch ); return TRUE; } bool aedit_recall( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; char room[ MAX_STRING_LENGTH ]; int value; EDIT_AREA( ch, pArea ); one_argument( argument, room ); if( !is_number( argument ) || argument[0] == '\0' ) { send_to_char( "Syntax: recall [#rvnum]\n\r", ch ); return FALSE; } value = atoi( room ); if( !get_room_index( value ) ) { send_to_char( "AEdit: Room vnum does not exist.\n\r", ch ); return FALSE; } pArea->recall = value; send_to_char( "Recall set.\n\r", ch ); return TRUE; } bool aedit_security( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; char sec[ MAX_STRING_LENGTH ]; char buf[ MAX_STRING_LENGTH ]; int value; EDIT_AREA( ch, pArea ); one_argument( argument, sec ); if( !is_number( sec ) || sec[0] == '\0' ) { send_to_char( "Syntax: security [#level]\n\r", ch ); return FALSE; } value = atoi( sec ); if( value > ch->pcdata->security || value < 0 ) { if( ch->pcdata->security != 0 ) { sprintf( buf, "Security is 0-%d.\n\r", ch->pcdata->security ); send_to_char( buf, ch ); } else send_to_char( "Security is 0 only.\n\r", ch ); return FALSE; } pArea->security = value; send_to_char( "Security set.\n\r", ch ); return TRUE; } bool aedit_builder( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; char name[ MAX_STRING_LENGTH ]; char buf[ MAX_STRING_LENGTH ]; EDIT_AREA( ch, pArea ); one_argument( argument, name ); if( name[0] == '\0' ) { send_to_char( "Syntax: builder [$name] -toggles builder\n\r", ch ); send_to_char( "Syntax: builder All -allows everyone\n\r", ch ); return FALSE; } name[0] = UPPER( name[0] ); if( strstr( pArea->builders, name ) != '\0' ) { pArea->builders = string_replace( pArea->builders, name, "\0" ); pArea->builders = string_unpad( pArea->builders ); if( pArea->builders[0] == '\0' ) { free_string( pArea->builders ); pArea->builders = str_dup( "None" ); } send_to_char( "Builder removed.\n\r", ch ); return TRUE; } else { buf[0] = '\0'; if( strstr( pArea->builders, "None" ) != '\0' ) { pArea->builders = string_replace( pArea->builders, "None", "\0" ); pArea->builders = string_unpad( pArea->builders ); } if( pArea->builders[0] != '\0' ) { strcat( buf, pArea->builders ); strcat( buf, " " ); } strcat( buf, name ); free_string( pArea->builders ); pArea->builders = string_proper( str_dup( buf ) ); send_to_char( "Builder added.\n\r", ch ); return TRUE; } return FALSE; } bool aedit_vnum( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; char lower[ MAX_STRING_LENGTH ]; char upper[ MAX_STRING_LENGTH ]; int ilower; int iupper; EDIT_AREA( ch, pArea ); argument = one_argument( argument, lower ); one_argument( argument, upper ); if( !is_number( lower ) || lower[0] == '\0' || !is_number( upper ) || upper[0] == '\0' ) { send_to_char( "Syntax: vnum [#lower] [#upper]\n\r", ch ); return FALSE; } if( ( ilower = atoi( lower ) ) > ( iupper = atoi( upper ) ) ) { send_to_char( "AEdit: Upper must be larger then lower.\n\r", ch ); return FALSE; } /* OLC 1.1b */ if( ilower <= 0 || ilower >= INT_MAX || iupper <= 0 || iupper >= INT_MAX ) { char output[MAX_STRING_LENGTH]; sprintf( output, "AEdit: vnum must be between 0 and %d.\n\r", INT_MAX ); send_to_char( output, ch ); return FALSE; } if( !check_range( ilower, iupper ) ) { send_to_char( "AEdit: Range must include only this area.\n\r", ch ); return FALSE; } if( get_vnum_area( ilower ) && get_vnum_area( ilower ) != pArea ) { send_to_char( "AEdit: Lower vnum already assigned.\n\r", ch ); return FALSE; } pArea->lvnum = ilower; send_to_char( "Lower vnum set.\n\r", ch ); if( get_vnum_area( iupper ) && get_vnum_area( iupper ) != pArea ) { send_to_char( "AEdit: Upper vnum already assigned.\n\r", ch ); return TRUE; /* The lower value has been set. */ } pArea->uvnum = iupper; send_to_char( "Upper vnum set.\n\r", ch ); return TRUE; } bool aedit_lvnum( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; char lower[ MAX_STRING_LENGTH ]; int ilower; int iupper; EDIT_AREA( ch, pArea ); one_argument( argument, lower ); if( !is_number( lower ) || lower[0] == '\0' ) { send_to_char( "Syntax: lvnum [#lower]\n\r", ch ); return FALSE; } if( ( ilower = atoi( lower ) ) > ( iupper = pArea->uvnum ) ) { send_to_char( "AEdit: Value must be less than the uvnum.\n\r", ch ); return FALSE; } /* OLC 1.1b */ if( ilower <= 0 || ilower >= INT_MAX || iupper <= 0 || iupper >= INT_MAX ) { char output[MAX_STRING_LENGTH]; sprintf( output, "AEdit: vnum must be between 0 and %d.\n\r", INT_MAX ); send_to_char( output, ch ); return FALSE; } if( !check_range( ilower, iupper ) ) { send_to_char( "AEdit: Range must include only this area.\n\r", ch ); return FALSE; } if( get_vnum_area( ilower ) && get_vnum_area( ilower ) != pArea ) { send_to_char( "AEdit: Lower vnum already assigned.\n\r", ch ); return FALSE; } pArea->lvnum = ilower; send_to_char( "Lower vnum set.\n\r", ch ); return TRUE; } bool aedit_uvnum( CHAR_DATA *ch, char *argument ) { AREA_DATA *pArea; char upper[ MAX_STRING_LENGTH ]; int ilower; int iupper; EDIT_AREA( ch, pArea ); one_argument( argument, upper ); if( !is_number( upper ) || upper[0] == '\0' ) { send_to_char( "Syntax: uvnum [#upper]\n\r", ch ); return FALSE; } if( ( ilower = pArea->lvnum ) > ( iupper = atoi( upper ) ) ) { send_to_char( "AEdit: Upper must be larger then lower.\n\r", ch ); return FALSE; } /* OLC 1.1b */ if( ilower <= 0 || ilower >= INT_MAX || iupper <= 0 || iupper >= INT_MAX ) { char output[MAX_STRING_LENGTH]; sprintf( output, "AEdit: vnum must be between 0 and %d.\n\r", INT_MAX ); send_to_char( output, ch ); return FALSE; } if( !check_range( ilower, iupper ) ) { send_to_char( "AEdit: Range must include only this area.\n\r", ch ); return FALSE; } if( get_vnum_area( iupper ) && get_vnum_area( iupper ) != pArea ) { send_to_char( "AEdit: Upper vnum already assigned.\n\r", ch ); return FALSE; } pArea->uvnum = iupper; send_to_char( "Upper vnum set.\n\r", ch ); return TRUE; } /* =================================================================== Room Editor Functions. =================================================================== */ bool redit_show( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *pRoom; char buf[ MAX_STRING_LENGTH ]; char *buf1; OBJ_DATA *obj; CHAR_DATA *rch; int door; bool fcnt; EDIT_ROOM( ch, pRoom ); buf1 = NULL; sprintf( buf, "Description:\n\r%s", pRoom->description ); str_cat( &buf1, buf ); sprintf( buf, "Name: [%s]\n\rArea: [%5d] %s\n\r", pRoom->name, pRoom->area->vnum, pRoom->area->name ); str_cat( &buf1, buf ); sprintf( buf, "Vnum: [%5d]\n\rSector: [%s]\n\r", pRoom->vnum, flag_string( sector_flags, pRoom->sector_type ) ); str_cat( &buf1, buf ); sprintf( buf, "Room flags: [%s]\n\r", flag_string( room_flags, pRoom->room_flags ) ); str_cat( &buf1, buf ); if( pRoom->extra_descr ) { EXTRA_DESCR_DATA *ed; str_cat( &buf1, "Desc Kwds: [" ); for( ed = pRoom->extra_descr ; ed ; ed = ed->next ) { str_cat( &buf1, ed->keyword ); if( ed->next ) str_cat( &buf1, " " ); } str_cat( &buf1, "]\n\r" ); } str_cat( &buf1, "Characters: [" ); fcnt = FALSE; for( rch = pRoom->people ; rch ; rch = rch->next_in_room ) { one_argument( rch->name, buf ); str_cat( &buf1, buf ); str_cat( &buf1, " " ); fcnt = TRUE; } if( fcnt ) { int end; end = strlen(buf1) - 1; buf1[end] = ']'; str_cat( &buf1, "\n\r" ); } else str_cat( &buf1, "none]\n\r" ); str_cat( &buf1, "Objects: [" ); fcnt = FALSE; for( obj = pRoom->contents ; obj ; obj = obj->next_content ) { one_argument( obj->name, buf ); str_cat( &buf1, buf ); str_cat( &buf1, " " ); fcnt = TRUE; } if( fcnt ) { int end; end = strlen(buf1) - 1; buf1[end] = ']'; str_cat( &buf1, "\n\r" ); } else str_cat( &buf1, "none]\n\r" ); for( door = 0 ; door < MAX_DIR ; door++ ) { EXIT_DATA *pexit; if( ( pexit = pRoom->exit[door] ) ) { char word[ MAX_INPUT_LENGTH ]; char reset_state[ MAX_STRING_LENGTH ]; char *state; int i; int length; sprintf( buf, "-%-5s to [%5d] Key: [%5d]", capitalize(dir_name[door]), pexit->to_room ? pexit->to_room->vnum : 0, pexit->key ); str_cat( &buf1, buf ); /* * Format up the exit info. * Capitalize all flags that are not part of the reset info. */ strcpy( reset_state, flag_string( exit_flags, pexit->rs_flags ) ); state = flag_string( exit_flags, pexit->exit_info ); str_cat( &buf1, " Exit flags: [" ); for( ; ; ) { state = one_argument( state, word ); if( word[0] == '\0' ) { int end; end = strlen(buf1) - 1; buf1[end] = ']'; str_cat( &buf1, "\n\r" ); break; } if( str_infix( word, reset_state ) ) { length = strlen(word); for( i = 0 ; i < length ; i++ ) word[i] = toupper( word[i] ); } str_cat( &buf1, word ); str_cat( &buf1, " " ); } if( pexit->keyword && pexit->keyword[0] != '\0' ) { sprintf( buf, "Kwds: [%s]\n\r", pexit->keyword ); str_cat( &buf1, buf ); } if( pexit->description && pexit->description[0] != '\0' ) { sprintf( buf, "%s", pexit->description ); str_cat( &buf1, buf ); } } } page_to_char( buf1, ch ); free( buf1 ); return FALSE; } /* OLC 1.1b */ /***************************************************************************** Name: change_exit Purpose: Command interpreter for changing exits. Called by: redit_<dir>. This is a local function. ****************************************************************************/ bool change_exit( CHAR_DATA *ch, char *argument, int door ) { ROOM_INDEX_DATA *pRoom; char command[MAX_INPUT_LENGTH]; char arg[MAX_INPUT_LENGTH]; char total_arg[MAX_STRING_LENGTH]; int value = 0; int rev; EDIT_ROOM( ch, pRoom ); /* Often used data. */ rev = rev_dir[door]; if( !argument ) { do_help( ch, "EXIT" ); return FALSE; } /* * Now parse the arguments. */ strcpy( total_arg, argument ); argument = one_argument( argument, command ); one_argument( argument, arg ); if( !str_cmp( command, "delete" ) ) { if( !pRoom->exit[door] ) { send_to_char( "REdit: Exit does not exist.\n\r", ch ); return FALSE; } /* * Remove To Room Exit. */ if( pRoom->exit[door]->to_room->exit[rev] ) { free_exit( pRoom->exit[door]->to_room->exit[rev] ); pRoom->exit[door]->to_room->exit[rev] = NULL; } /* * Remove this exit. */ free_exit( pRoom->exit[door] ); pRoom->exit[door] = NULL; send_to_char( "Exit unlinked.\n\r", ch ); return TRUE; } /* * Create a two-way exit. */ if( !str_cmp( command, "link" ) ) { EXIT_DATA *pExit; ROOM_INDEX_DATA *pLinkRoom; if( arg[0] == '\0' || !is_number( arg ) ) { send_to_char( "Syntax: [direction] link [vnum]\n\r", ch ); return FALSE; } if( !( pLinkRoom = get_room_index( atoi(arg) ) ) ) { send_to_char( "REdit: Non-existant room.\n\r", ch ); return FALSE; } if( !IS_BUILDER( ch, pLinkRoom->area ) ) { send_to_char( "REdit: Cannot link to that area.\n\r", ch ); return FALSE; } if( pLinkRoom->exit[rev] ) { send_to_char( "REdit: Remote side's exit exists.\n\r", ch ); return FALSE; } if( !pRoom->exit[door] ) /* No exit. */ pRoom->exit[door] = new_exit(); pRoom->exit[door]->to_room = pLinkRoom; /* Assign data. */ pRoom->exit[door]->vnum = value; pExit = new_exit(); /* No remote exit. */ pExit->to_room = ch->in_room; /* Assign data. */ pExit->vnum = ch->in_room->vnum; pLinkRoom->exit[rev] = pExit; /* Link exit to room. */ send_to_char( "Two-way link established.\n\r", ch ); return TRUE; } /* * Create room and make two-way exit. */ if( !str_cmp( command, "dig" ) ) { char buf[MAX_INPUT_LENGTH]; if( arg[0] == '\0' || !is_number( arg ) ) { send_to_char( "Syntax: [direction] dig <vnum>\n\r", ch ); return FALSE; } redit_create( ch, arg ); /* Create the room. */ sprintf( buf, "link %s", arg ); change_exit( ch, buf, door); /* Create the exits. */ return TRUE; } /* * Create one-way exit. */ if( !str_cmp( command, "room" ) ) { ROOM_INDEX_DATA *pLinkRoom; if( arg[0] == '\0' || !is_number( arg ) ) { send_to_char( "Syntax: [direction] room [vnum]\n\r", ch ); return FALSE; } if( !( pLinkRoom = get_room_index( atoi( arg ) ) ) ) { send_to_char( "REdit: Non-existant room.\n\r", ch ); return FALSE; } if( !pRoom->exit[door] ) pRoom->exit[door] = new_exit(); pRoom->exit[door]->to_room = pLinkRoom; pRoom->exit[door]->vnum = value; send_to_char( "One-way link established.\n\r", ch ); return TRUE; } if( !str_cmp( command, "remove" ) ) { if( arg[0] == '\0' ) { send_to_char( "Syntax: [direction] remove [key/name/desc]\n\r", ch ); return FALSE; } if( !pRoom->exit[door] ) { send_to_char( "REdit: Exit does not exist.\n\r", ch ); return FALSE; } if( !str_cmp( argument, "key" ) ) { pRoom->exit[door]->key = 0; send_to_char( "Exit key removed.\n\r", ch ); return TRUE; } if( !str_cmp( argument, "name" ) ) { free_string( pRoom->exit[door]->keyword ); pRoom->exit[door]->keyword = &str_empty[0]; send_to_char( "Exit name removed.\n\r", ch ); return TRUE; } if( argument[0] == 'd' && !str_prefix( argument, "description" ) ) { free_string( pRoom->exit[door]->description ); pRoom->exit[door]->description = &str_empty[0]; send_to_char( "Exit description removed.\n\r", ch ); return TRUE; } send_to_char( "Syntax: [direction] remove [key/name/desc]\n\r", ch ); return FALSE; } if( !str_cmp( command, "key" ) ) { OBJ_INDEX_DATA *pObjIndex; if( arg[0] == '\0' || !is_number( arg ) ) { send_to_char( "Syntax: [direction] key [vnum]\n\r", ch ); return FALSE; } if( !( pObjIndex = get_obj_index( atoi( arg ) ) ) ) { send_to_char( "REdit: Item does not exist.\n\r", ch ); return FALSE; } if( pObjIndex->item_type != ITEM_KEY ) { send_to_char( "REdit: Item is not a key.\n\r", ch ); return FALSE; } if( !pRoom->exit[door] ) pRoom->exit[door] = new_exit(); pRoom->exit[door]->key = pObjIndex->vnum; send_to_char( "Exit key set.\n\r", ch ); return TRUE; } if( !str_cmp( command, "name" ) ) { if( arg[0] == '\0' ) { send_to_char( "Syntax: [direction] name [string]\n\r", ch ); return FALSE; } if( !pRoom->exit[door] ) pRoom->exit[door] = new_exit(); free_string( pRoom->exit[door]->keyword ); pRoom->exit[door]->keyword = str_dup( argument ); send_to_char( "Exit name set.\n\r", ch ); return TRUE; } if( command[0] == 'd' && !str_prefix( command, "description" ) ) { if( arg[0] == '\0' ) { if( !pRoom->exit[door] ) pRoom->exit[door] = new_exit(); string_append( ch, &pRoom->exit[door]->description ); return TRUE; } send_to_char( "Syntax: [direction] desc\n\r", ch ); return FALSE; } /* * Set the exit flags, needs full argument. * ---------------------------------------- */ if( ( value = flag_value( exit_flags, total_arg ) ) != NO_FLAG ) { ROOM_INDEX_DATA *pToRoom; /* * Create an exit if none exists. */ if( !pRoom->exit[door] ) pRoom->exit[door] = new_exit(); /* * Set door bits for this room. */ TOGGLE_BIT( pRoom->exit[door]->rs_flags, value ); pRoom->exit[door]->exit_info = pRoom->exit[door]->rs_flags; /* * Set door bits of connected room. * Skip one-way exits and non-existant rooms. */ if( ( pToRoom = pRoom->exit[door]->to_room ) && pToRoom->exit[rev] ) { TOGGLE_BIT( pToRoom->exit[rev]->rs_flags, value ); pToRoom->exit[rev]->exit_info = pToRoom->exit[rev]->rs_flags; } send_to_char( "Exit flag toggled.\n\r", ch ); return TRUE; } return FALSE; } bool redit_north( CHAR_DATA *ch, char *argument ) { if( change_exit( ch, argument, DIR_NORTH ) ) return TRUE; return FALSE; } bool redit_northeast( CHAR_DATA *ch, char *argument ) { if( change_exit( ch, argument, DIR_NORTHEAST ) ) return TRUE; return FALSE; } bool redit_northwest( CHAR_DATA *ch, char *argument ) { if( change_exit( ch, argument, DIR_NORTHWEST ) ) return TRUE; return FALSE; } bool redit_south( CHAR_DATA *ch, char *argument ) { if( change_exit( ch, argument, DIR_SOUTH ) ) return TRUE; return FALSE; } bool redit_southeast( CHAR_DATA *ch, char *argument ) { if( change_exit( ch, argument, DIR_SOUTHEAST ) ) return TRUE; return FALSE; } bool redit_southwest( CHAR_DATA *ch, char *argument ) { if( change_exit( ch, argument, DIR_SOUTHWEST ) ) return TRUE; return FALSE; } bool redit_east( CHAR_DATA *ch, char *argument ) { if( change_exit( ch, argument, DIR_EAST ) ) return TRUE; return FALSE; } bool redit_west( CHAR_DATA *ch, char *argument ) { if( change_exit( ch, argument, DIR_WEST ) ) return TRUE; return FALSE; } bool redit_up( CHAR_DATA *ch, char *argument ) { if( change_exit( ch, argument, DIR_UP ) ) return TRUE; return FALSE; } bool redit_down( CHAR_DATA *ch, char *argument ) { if( change_exit( ch, argument, DIR_DOWN ) ) return TRUE; return FALSE; } /* OLC 1.1b */ bool redit_move( CHAR_DATA *ch, char *argument ) { interpret( ch, argument, FALSE ); return FALSE; } bool redit_ed( CHAR_DATA *ch, char *argument ) { EXTRA_DESCR_DATA *ed; ROOM_INDEX_DATA *pRoom; char command[ MAX_INPUT_LENGTH ]; char keyword[ MAX_INPUT_LENGTH ]; EDIT_ROOM( ch, pRoom ); argument = one_argument( argument, command ); one_argument( argument, keyword ); if( command[0] == '\0' || keyword[0] == '\0' ) { send_to_char( "Syntax: ed add [keyword]\n\r", ch ); send_to_char( " ed edit [keyword]\n\r", ch ); send_to_char( " ed delete [keyword]\n\r", ch ); send_to_char( " ed format [keyword]\n\r", ch ); return FALSE; } if( !str_cmp( command, "add" ) ) { if( keyword[0] == '\0' ) { send_to_char( "Syntax: ed add [keyword]\n\r", ch ); return FALSE; } ed = new_extra_descr(); ed->keyword = str_dup( keyword ); ed->description = str_dup( "" ); ed->next = pRoom->extra_descr; pRoom->extra_descr = ed; string_append( ch, &ed->description ); return TRUE; } if( !str_cmp( command, "edit" ) ) { if( keyword[0] == '\0' ) { send_to_char( "Syntax: ed edit [keyword]\n\r", ch ); return FALSE; } for( ed = pRoom->extra_descr ; ed ; ed = ed->next ) { if( is_name( keyword, ed->keyword ) ) break; } if( !ed ) { send_to_char( "REdit: Extra description keyword not found.\n\r", ch ); return FALSE; } string_append( ch, &ed->description ); return TRUE; } if( !str_cmp( command, "delete" ) ) { EXTRA_DESCR_DATA *ped = NULL; if( keyword[0] == '\0' ) { send_to_char( "Syntax: ed delete [keyword]\n\r", ch ); return FALSE; } for( ed = pRoom->extra_descr ; ed ; ed = ed->next ) { if( is_name( keyword, ed->keyword ) ) break; ped = ed; } if( !ed ) { send_to_char( "REdit: Extra description keyword not found.\n\r", ch ); return FALSE; } if( !ped ) pRoom->extra_descr = ed->next; else ped->next = ed->next; free_extra_descr( ed ); send_to_char( "Extra description deleted.\n\r", ch ); return TRUE; } if( !str_cmp( command, "format" ) ) { if( keyword[0] == '\0' ) { send_to_char( "Syntax: ed format [keyword]\n\r", ch ); return FALSE; } for( ed = pRoom->extra_descr ; ed ; ed = ed->next ) { if( is_name( keyword, ed->keyword ) ) break; } if( !ed ) { send_to_char( "REdit: Extra description keyword not found.\n\r", ch ); return FALSE; } /* OLC 1.1b */ if( strlen( ed->description ) >= ( MAX_STRING_LENGTH - 20 ) ) { send_to_char( "String too long to be formatted.\n\r", ch ); return FALSE; } ed->description = format_string( ed->description ); send_to_char( "Extra description formatted.\n\r", ch ); return TRUE; } redit_ed( ch, "" ); return FALSE; } bool redit_create( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *pRoom; AREA_DATA *pArea; int value; int iHash; EDIT_ROOM( ch, pRoom ); value = atoi( argument ); /* OLC 1.1b */ if( argument[0] == '\0' || value <= 0 || value >= INT_MAX ) { char output[MAX_STRING_LENGTH]; sprintf( output, "Syntax: create [0 < vnum < %d]\n\r", INT_MAX ); send_to_char( output, ch ); return FALSE; } if( argument[0] == '\0' || value <= 0 ) { send_to_char( "Syntax: create [vnum > 0]\n\r", ch ); return FALSE; } pArea = get_vnum_area( value ); if( !pArea ) { send_to_char( "REdit: That vnum is not assigned an area.\n\r", ch ); return FALSE; } if( !IS_BUILDER( ch, pArea ) ) { send_to_char( "REdit: Vnum in an area you cannot build in.\n\r", ch ); return FALSE; } if( get_room_index( value ) ) { send_to_char( "REdit: Room vnum already exists.\n\r", ch ); return FALSE; } pRoom = new_room_index(); pRoom->area = pArea; pRoom->vnum = value; if( value > top_vnum_room ) top_vnum_room = value; iHash = value % MAX_KEY_HASH; pRoom->next = room_index_hash[iHash]; room_index_hash[iHash] = pRoom; ch->desc->pEdit = (void *)pRoom; send_to_char( "Room created.\n\r", ch ); return TRUE; } bool redit_name( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM( ch, pRoom ); if( argument[0] == '\0' ) { send_to_char( "Syntax: name [name]\n\r", ch ); return FALSE; } free_string( pRoom->name ); pRoom->name = str_dup( argument ); send_to_char( "Name set.\n\r", ch ); return TRUE; } bool redit_light( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM( ch, pRoom ); if( argument[0] == '\0' || !is_number( argument ) ) { send_to_char( "Syntax: light [#intensity]\n\r", ch ); return FALSE; } pRoom->light = atoi( argument ); send_to_char( "Light Intensity Set.\n\r", ch ); return TRUE; } bool redit_desc( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM( ch, pRoom ); if( argument[0] == '\0' ) { string_append( ch, &pRoom->description ); return TRUE; } send_to_char( "Syntax: desc\n\r", ch ); return FALSE; } bool redit_format( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM( ch, pRoom ); /* OLC 1.1b */ if( strlen(pRoom->description) >= (MAX_STRING_LENGTH - 4) ) { send_to_char( "String too long to be formatted.\n\r", ch ); return FALSE; } pRoom->description = format_string( pRoom->description ); send_to_char( "String formatted.\n\r", ch ); return TRUE; } bool redit_mreset( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *pRoom; MOB_INDEX_DATA *pMobIndex; RESET_DATA *pReset; CHAR_DATA *newmob; char arg[ MAX_INPUT_LENGTH ]; char output[ MAX_STRING_LENGTH ]; EDIT_ROOM( ch, pRoom ); argument = one_argument( argument, arg ); if( arg[0] == '\0' || !is_number( arg ) ) { send_to_char( "Syntax: mreset <vnum> <max #>\n\r", ch ); return FALSE; } if( !( pMobIndex = get_mob_index( atoi( arg ) ) ) ) { send_to_char( "REdit: No mobile has that vnum.\n\r", ch ); return FALSE; } if( pMobIndex->area != pRoom->area ) { send_to_char( "REdit: No such mobile in this area.\n\r", ch ); return FALSE; } /* * Create the mobile reset. */ pReset = new_reset_data( ); pReset->command = 'M'; pReset->arg1 = pMobIndex->vnum; pReset->arg2 = is_number( argument ) ? atoi( argument ) : MAX_MOB; pReset->arg3 = pRoom->vnum; add_reset( pRoom, pReset, 0/* Last slot*/ ); /* * Create the mobile. */ newmob = create_mobile( pMobIndex ); char_to_room( newmob, pRoom ); sprintf( output, "%s (%d) has been loaded and added to resets.\n\r" "There will be a maximum of %d loaded to this room.\n\r", capitalize( pMobIndex->short_descr ), pMobIndex->vnum, pReset->arg2 ); send_to_char( output, ch ); act( "$n has created $N!", ch, NULL, newmob, TO_ROOM ); return TRUE; } struct wear_type { int wear_loc; int wear_bit; }; const struct wear_type wear_table[] = { { WEAR_NONE, ITEM_TAKE }, { WEAR_LIGHT, ITEM_LIGHT }, { WEAR_FINGER_L, ITEM_WEAR_FINGER }, { WEAR_FINGER_R, ITEM_WEAR_FINGER }, { WEAR_NECK_1, ITEM_WEAR_NECK }, { WEAR_NECK_2, ITEM_WEAR_NECK }, { WEAR_BODY, ITEM_WEAR_BODY }, { WEAR_HEAD, ITEM_WEAR_HEAD }, { WEAR_LEGS, ITEM_WEAR_LEGS }, { WEAR_FEET, ITEM_WEAR_FEET }, { WEAR_HANDS, ITEM_WEAR_HANDS }, { WEAR_ARMS, ITEM_WEAR_ARMS }, { WEAR_SHIELD, ITEM_WEAR_SHIELD }, { WEAR_ABOUT, ITEM_WEAR_ABOUT }, { WEAR_WAIST, ITEM_WEAR_WAIST }, { WEAR_WRIST_L, ITEM_WEAR_WRIST }, { WEAR_WRIST_R, ITEM_WEAR_WRIST }, { WEAR_WIELD, ITEM_WIELD }, { WEAR_HOLD, ITEM_HOLD }, { NO_FLAG, NO_FLAG } }; /***************************************************************************** Name: wear_loc Purpose: Returns the location of the bit that matches the count. 1 = first match, 2 = second match etc. Called by: oedit_reset(olc_act.c). ****************************************************************************/ int wear_loc( int bits, int count ) { int flag; for( flag = 0 ; wear_table[flag].wear_bit != NO_FLAG ; flag++ ) { if( IS_SET( bits, wear_table[flag].wear_bit ) && --count < 1 ) return wear_table[flag].wear_loc; } return NO_FLAG; } /***************************************************************************** Name: wear_bit Purpose: Converts a wear_loc into a bit. Called by: redit_oreset(olc_act.c). ****************************************************************************/ int wear_bit( int loc ) { int flag; for( flag = 0 ; wear_table[flag].wear_loc != NO_FLAG ; flag++ ) { if( loc == wear_table[flag].wear_loc ) return wear_table[flag].wear_bit; } return 0; } bool redit_oreset( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *pRoom; OBJ_INDEX_DATA *pObjIndex; RESET_DATA *pReset; CHAR_DATA *to_mob; OBJ_DATA *newobj; OBJ_DATA *to_obj; char arg1[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; char output[ MAX_STRING_LENGTH ]; int olevel = 0; EDIT_ROOM( ch, pRoom ); argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if( arg1[0] == '\0' || !is_number( arg1 ) ) { send_to_char( "Syntax: oreset <vnum> <args>\n\r", ch ); send_to_char( " -no_args = into room\n\r", ch ); send_to_char( " -<obj_name> = into obj\n\r", ch ); send_to_char( " -<mob_name> <wear_loc> = into mob\n\r", ch ); return FALSE; } if( !( pObjIndex = get_obj_index( atoi( arg1 ) ) ) ) { send_to_char( "REdit: No object has that vnum.\n\r", ch ); return FALSE; } if( pObjIndex->area != pRoom->area ) { send_to_char( "REdit: No such object in this area.\n\r", ch ); return FALSE; } /* * Load into room. */ if( arg2[0] == '\0' ) { pReset = new_reset_data(); pReset->command = 'O'; pReset->arg1 = pObjIndex->vnum; pReset->arg2 = 0; pReset->arg3 = pRoom->vnum; add_reset( pRoom, pReset, 0/* Last slot*/ ); newobj = create_object( pObjIndex ); obj_to_room( newobj, pRoom ); sprintf( output, "%s (%d) has been loaded and added to resets.\n\r", capitalize( pObjIndex->short_descr ), pObjIndex->vnum ); send_to_char( output, ch ); } else /* * Load into object's inventory. */ if( argument[0] == '\0' && ( ( to_obj = get_obj_list( ch, arg2, pRoom->contents ) ) != NULL ) ) { pReset = new_reset_data(); pReset->command = 'P'; pReset->arg1 = pObjIndex->vnum; pReset->arg2 = 0; pReset->arg3 = to_obj->pIndexData->vnum; add_reset( pRoom, pReset, 0/* Last slot*/ ); newobj = create_object( pObjIndex ); newobj->cost = 0; obj_to_obj( newobj, to_obj ); sprintf( output, "%s (%d) has been loaded into " "%s (%d) and added to resets.\n\r", capitalize( newobj->short_descr ), newobj->pIndexData->vnum, to_obj->short_descr, to_obj->pIndexData->vnum ); send_to_char( output, ch ); } else /* * Load into mobile's inventory. */ if( ( to_mob = get_char_room( ch, arg2 ) ) != NULL ) { int wear_loc; /* * Make sure the location on mobile is valid. */ if( ( wear_loc = flag_value( wear_loc_flags, argument ) ) == NO_FLAG ) { send_to_char( "REdit: Invalid wear_loc. '? wear-loc'\n\r", ch ); return FALSE; } /* * Disallow loading a sword(WEAR_WIELD) into WEAR_HEAD. */ if( !IS_SET( pObjIndex->wear_flags, wear_bit( wear_loc ) ) ) { sprintf( output, "%s (%d) has wear flags: [%s]\n\r", capitalize( pObjIndex->short_descr ), pObjIndex->vnum, flag_string( wear_flags, pObjIndex->wear_flags ) ); send_to_char( output, ch ); return FALSE; } /* * Can't load into same position. */ if( get_eq_char( to_mob, wear_loc ) ) { send_to_char( "REdit: Object already equipped.\n\r", ch ); return FALSE; } pReset = new_reset_data( ); pReset->arg1 = pObjIndex->vnum; pReset->arg2 = wear_loc; if( pReset->arg2 == WEAR_NONE ) pReset->command = 'G'; else pReset->command = 'E'; pReset->arg3 = wear_loc; add_reset( pRoom, pReset, 0/* Last slot*/ ); olevel = 0; newobj = create_object( pObjIndex ); if( to_mob->pIndexData->pShop ) /* Shop-keeper? */ { olevel = 0; newobj = create_object( pObjIndex ); if( pReset->arg2 == WEAR_NONE ) SET_BIT( newobj->extra_flags, ITEM_INVENTORY ); } else newobj = create_object( pObjIndex ); obj_to_char( newobj, to_mob ); if( pReset->command == 'E' ) equip_char( to_mob, newobj, pReset->arg3 ); sprintf( output, "%s (%d) has been loaded " "%s of %s (%d) and added to resets.\n\r", capitalize( pObjIndex->short_descr ), pObjIndex->vnum, flag_string( wear_loc_strings, pReset->arg3 ), to_mob->short_descr, to_mob->pIndexData->vnum ); send_to_char( output, ch ); } else /* Display Syntax */ { send_to_char( "REdit: That mobile isn't here.\n\r", ch ); return FALSE; } act( "$n has created $p!", ch, newobj, NULL, TO_ROOM ); return TRUE; } /* * Object Editor Functions. * Updated -Ant, Mar '96. */ void show_obj_values( CHAR_DATA *ch, OBJ_INDEX_DATA *obj ) { char buf[ MAX_STRING_LENGTH ]; char *buf1; bool found; int i; found = FALSE; buf1 = NULL; if( IS_SET( obj->item_type, ITEM_SCROLL ) ) { sprintf( buf, "Scroll Level %d spells of:", obj->scroll->level ); str_cat( &buf1, buf ); for( i = 0 ; i < 4 ; i++ ) { if( obj->scroll->spell[i] >= 0 && obj->scroll->spell[i] < MAX_SKILL ) { sprintf( buf, " '%s'", skill_table[obj->scroll->spell[i]].name ); str_cat( &buf1, buf ); } } str_cat( &buf1, ".\n\r" ); found = TRUE; } if( IS_SET( obj->item_type, ITEM_POTION ) ) { sprintf( buf, "Potion Level %d spells of:", obj->potion->level ); str_cat( &buf1, buf ); for( i = 0 ; i < 4 ; i++ ) { if( obj->potion->spell[i] >= 0 && obj->potion->spell[i] < MAX_SKILL ) { sprintf( buf, " '%s'", skill_table[obj->potion->spell[i]].name ); str_cat( &buf1, buf ); } } str_cat( &buf1, ".\n\r" ); found = TRUE; } if( IS_SET( obj->item_type, ITEM_PILL ) ) { sprintf( buf, "Pill Level %d spells of:", obj->pill->level ); str_cat( &buf1, buf ); for( i = 0 ; i < 4 ; i++ ) { if( obj->pill->spell[i] >= 0 && obj->pill->spell[i] < MAX_SKILL ) { sprintf( buf, " '%s'", skill_table[obj->pill->spell[i]].name ); str_cat( &buf1, buf ); } } str_cat( &buf1, ".\n\r" ); found = TRUE; } if( IS_SET( obj->item_type, ITEM_WAND ) ) { sprintf( buf, "Wand has %d(%d) charges of level %d", obj->wand->charges, obj->wand->max, obj->wand->level ); str_cat( &buf1, buf ); if( obj->wand->spell >= 0 && obj->wand->spell < MAX_SKILL ) { sprintf( buf, " '%s'", skill_table[obj->wand->spell].name ); str_cat( &buf1, buf ); } str_cat( &buf1, ".\n\r" ); found = TRUE; } if( IS_SET( obj->item_type, ITEM_STAFF ) ) { sprintf( buf, "Staff has %d(%d) charges of level %d", obj->staff->charges, obj->staff->max, obj->staff->level ); str_cat( &buf1, buf ); if( obj->staff->spell >= 0 && obj->staff->spell < MAX_SKILL ) { sprintf( buf, " '%s'", skill_table[obj->staff->spell].name ); str_cat( &buf1, buf ); } str_cat( &buf1, ".\n\r" ); found = TRUE; } if( IS_SET( obj->item_type, ITEM_ARMOUR ) ) { sprintf( buf, "Armor class is %d pierce, %d bash, %d slash, and %d vs. magic\n\r", obj->armour->ac[ 0 ], obj->armour->ac[ 1 ], obj->armour->ac[ 2 ], obj->armour->ac[ 3 ] ); str_cat( &buf1, buf ); found = TRUE; } if( IS_SET( obj->item_type, ITEM_LIGHT ) ) { if( obj->light->duration == -1 ) sprintf( buf, "Hours of light: Infinite(-1)\n\r" ); else sprintf( buf, "Hours of light: %d\n\r", obj->light->duration ); str_cat( &buf1, buf ); sprintf( buf, "Intensity: %d\n\r", obj->light->intensity ); str_cat( &buf1, buf ); found = TRUE; } if( IS_SET( obj->item_type, ITEM_CONTAINER ) ) { sprintf( buf, "Capacity: %d \n\rFlags : %s\n\rKey : %s (%d)\n\r", obj->cont->capacity, flag_string( container_flags, obj->cont->closed ), get_obj_index( obj->cont->key ) ? get_obj_index( obj->cont->key )->short_descr : "none", obj->cont->key ); str_cat( &buf1, buf ); found = TRUE; } if( IS_SET( obj->item_type, ITEM_DRINK_CON ) ) { sprintf( buf, "Contains : %d/%d\n\rLiquid : %s\n\rPoisoned? : %s\n\r", obj->drink->volume, obj->drink->limit, flag_string( liquid_flags, obj->drink->liquid ), obj->drink->poison != 0 ? "Yes" : "No" ); str_cat( &buf1, buf ); found = TRUE; } if( IS_SET( obj->item_type, ITEM_FOOD ) ) { sprintf( buf, "Hours of food : %d\n\rPoisoned? : %s\n\r", obj->food->bite, obj->food->poison != 0 ? "Yes" : "No" ); str_cat( &buf1, buf ); found = TRUE; } if( IS_SET( obj->item_type, ITEM_MONEY ) ) { sprintf( buf, "Amount of Gold/Silver/Copper (v0): %d/%d/%d\n\r", obj->money->gold, obj->money->silver, obj->money->copper ); str_cat( &buf1, buf ); found = TRUE; } if( IS_SET( obj->item_type, ITEM_WEAPON ) ) { str_cat( &buf1, "Weapon type is " ); switch( obj->weapon->type ) { case( WEAPON_EXOTIC ): str_cat( &buf1, "exotic\n\r" ); break; case( WEAPON_SWORD ): str_cat( &buf1, "sword\n\r" ); break; case( WEAPON_DAGGER ): str_cat( &buf1, "dagger\n\r" ); break; case( WEAPON_SPEAR ): str_cat( &buf1, "spear\n\r" ); break; case( WEAPON_MACE ): str_cat( &buf1, "mace/club\n\r" ); break; case( WEAPON_AXE ): str_cat( &buf1, "axe\n\r" ); break; case( WEAPON_POLEARM ): str_cat( &buf1, "polearm\n\r" ); break; default: str_cat( &buf1, "unknown\n\r" ); break; } if( obj->weapon->hit ) { sprintf( buf, "Hit Bonus is %d\n\r", obj->weapon->hit ); str_cat( &buf1, buf ); } sprintf( buf, "Damage is %dd%d+%d (average %d) '%s'\n\r", obj->weapon->damage[0], obj->weapon->damage[1], obj->weapon->damage[2], ( ( 1 + obj->weapon->damage[1] ) * obj->weapon->damage[0] / 2 ) + obj->weapon->damage[2], flag_string( weapon_flags, obj->weapon->message ) ); str_cat( &buf1, buf ); if( obj->weapon->flags ) { sprintf( buf, "Weapons flags: %s\n\r", flag_string( weapon_extra, obj->weapon->flags ) ); } found = TRUE; } if( !found ) { sprintf( buf, "None Of The Objects Types Require Values\n\r" ); str_cat( &buf1, buf ); } page_to_char_bw( buf1, ch ); free( buf1 ); return; } bool set_obj_values( CHAR_DATA *ch, OBJ_INDEX_DATA *pObj, int value_num, char *argument) { show_obj_values( ch, pObj ); return TRUE; } bool oedit_show( CHAR_DATA *ch, char *argument ) { OBJ_INDEX_DATA *pObj; AFFECT_DATA *paf; char buf[MAX_STRING_LENGTH]; int cnt; EDIT_OBJ( ch, pObj ); sprintf( buf, "Name: [%s]\n\rArea: [%5d] %s\n\r", pObj->name, !pObj->area ? -1 : pObj->area->vnum, !pObj->area ? "No Area" : pObj->area->name ); send_to_char( buf, ch ); sprintf( buf, "Vnum: [%5d]\n\rType: [%s]\n\r", pObj->vnum, flag_string( type_flags, pObj->item_type ) ); send_to_char( buf, ch ); sprintf( buf, "Wear flags: [%s]\n\r", flag_string( wear_flags, pObj->wear_flags ) ); send_to_char( buf, ch ); sprintf( buf, "Extra flags: [%s]\n\r", flag_string( extra_flags, pObj->extra_flags ) ); send_to_char( buf, ch ); sprintf( buf, "Weight: [%d]\n\rCost: [%d]\n\r", pObj->weight, pObj->cost ); send_to_char( buf, ch ); if ( pObj->extra_descr ) { EXTRA_DESCR_DATA *ed; send_to_char( "Ex desc kwd: ", ch ); for ( ed = pObj->extra_descr; ed; ed = ed->next ) { send_to_char( "[", ch ); send_to_char( ed->keyword, ch ); send_to_char( "]", ch ); } send_to_char( "\n\r", ch ); } sprintf( buf, "Short desc: %s\n\rLong desc:\n\r %s\n\r", pObj->short_descr, pObj->description ); send_to_char( buf, ch ); for ( cnt = 0, paf = pObj->affected; paf; paf = paf->next ) { if ( cnt == 0 ) { send_to_char( "Number Modifier Affects\n\r", ch ); send_to_char( "------ -------- -------\n\r", ch ); } sprintf( buf, "[%4d] %-8d %s\n\r", cnt, paf->modifier, flag_string( apply_flags, paf->location ) ); send_to_char( buf, ch ); cnt++; } show_obj_values( ch, pObj ); return FALSE; } /* * Need to issue warning if flag isn't valid. */ bool oedit_addaffect( CHAR_DATA *ch, char *argument ) { OBJ_INDEX_DATA *pObj; AFFECT_DATA *pAf; char loc[MAX_STRING_LENGTH]; char mod[MAX_STRING_LENGTH]; EDIT_OBJ(ch, pObj); argument = one_argument( argument, loc ); one_argument( argument, mod ); if ( loc[0] == '\0' || mod[0] == '\0' || !is_number( mod ) ) { send_to_char( "Syntax: addaffect [location] [#mod]\n\r", ch ); return FALSE; } pAf = new_affect(); pAf->location = flag_value( apply_flags, loc ); pAf->modifier = atoi( mod ); pAf->type = -1; pAf->duration = -1; pAf->bitvector = 0; pAf->next = pObj->affected; pObj->affected = pAf; send_to_char( "Affect added.\n\r", ch); return TRUE; } /* * My thanks to Hans Hvidsten Birkeland and Noam Krendel(Walker) * for really teaching me how to manipulate pointers. */ bool oedit_delaffect( CHAR_DATA *ch, char *argument ) { OBJ_INDEX_DATA *pObj; AFFECT_DATA *pAf; AFFECT_DATA *pAf_next; char affect[MAX_STRING_LENGTH]; int value; int cnt = 0; EDIT_OBJ( ch, pObj ); one_argument( argument, affect ); if( !is_number( affect ) || affect[0] == '\0' ) { send_to_char( "Syntax: delaffect [#affect]\n\r", ch ); return FALSE; } value = atoi( affect ); if( value < 0 ) { send_to_char( "Only non-negative affect-numbers allowed.\n\r", ch ); return FALSE; } if( !( pAf = pObj->affected ) ) { send_to_char( "OEdit: Non-existant affect.\n\r", ch ); return FALSE; } if( value == 0 ) /* First case: Remove first affect */ { pAf = pObj->affected; pObj->affected = pAf->next; free_affect( pAf ); } else /* Affect to remove is not the first */ { while ( ( pAf_next = pAf->next ) && ( ++cnt < value ) ) pAf = pAf_next; if( pAf_next ) /* See if it's the next affect */ { pAf->next = pAf_next->next; free_affect( pAf_next ); } else /* Doesn't exist */ { send_to_char( "No such affect.\n\r", ch ); return FALSE; } } send_to_char( "Affect removed.\n\r", ch); return TRUE; } bool oedit_name( CHAR_DATA *ch, char *argument ) { OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); if( argument[0] == '\0' ) { send_to_char( "Syntax: name [string]\n\r", ch ); return FALSE; } free_string( pObj->name ); pObj->name = str_dup( argument ); send_to_char( "Name set.\n\r", ch); return TRUE; } bool oedit_short( CHAR_DATA *ch, char *argument ) { OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); if( argument[0] == '\0' ) { send_to_char( "Syntax: short [string]\n\r", ch ); return FALSE; } free_string( pObj->short_descr ); pObj->short_descr = str_dup( argument ); pObj->short_descr[0] = LOWER( pObj->short_descr[0] ); send_to_char( "Short description set.\n\r", ch); return TRUE; } bool oedit_long( CHAR_DATA *ch, char *argument ) { OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); if( argument[0] == '\0' ) { send_to_char( "Syntax: long [string]\n\r", ch ); return FALSE; } free_string( pObj->description ); pObj->description = str_dup( argument ); pObj->description[0] = UPPER( pObj->description[0] ); send_to_char( "Long description set.\n\r", ch); return TRUE; } bool set_value( CHAR_DATA *ch, OBJ_INDEX_DATA *pObj, char *argument, int value ) { if( argument[0] == '\0' ) { set_obj_values( ch, pObj, -1, '\0' ); return FALSE; } if( set_obj_values( ch, pObj, value, argument ) ) return TRUE; return FALSE; } bool oedit_weight( CHAR_DATA *ch, char *argument ) { OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); if( argument[0] == '\0' || !is_number( argument ) ) { send_to_char( "Syntax: weight [number]\n\r", ch ); return FALSE; } pObj->weight = atoi( argument ); send_to_char( "Weight set.\n\r", ch); return TRUE; } bool oedit_requires( CHAR_DATA *ch, char *argument ) { OBJ_INDEX_DATA *pObj; char stat[ MAX_INPUT_LENGTH ]; char buf[ MAX_INPUT_LENGTH ]; sh_int value = 0; EDIT_OBJ( ch, pObj ); argument = one_argument( argument, stat ); one_argument( argument, buf ); if( stat[ 0 ] == '\0' || buf[ 0 ] == '\0' || !is_number( buf ) ) { send_to_char( "Syntax: requires <{cstat{x> <{cvalue{x>\n\r", ch ); return FALSE; } value = atoi( buf ); if( !strcmp( stat, "str" ) ) { pObj->requires[ 0 ] = value; send_to_char_bw( "Requirement set.\n\r", ch); return TRUE; } else if( !strcmp( stat, "int" ) ) { pObj->requires[ 1 ] = value; send_to_char_bw( "Requirement set.\n\r", ch); return TRUE; } else if( !strcmp( stat, "wis" ) ) { pObj->requires[ 2 ] = value; send_to_char_bw( "Requirement set.\n\r", ch); return TRUE; } else if( !strcmp( stat, "dex" ) ) { pObj->requires[ 3 ] = value; send_to_char_bw( "Requirement set.\n\r", ch); return TRUE; } else if( !strcmp( stat, "con" ) ) { pObj->requires[ 4 ] = value; send_to_char_bw( "Requirement set.\n\r", ch); return TRUE; } send_to_char_bw( "Unknown Statistic, choose from: str int wis dex con\n\r", ch ); send_to_char( "Syntax: requires <{cstat{x> <{cvalue{x>\n\r", ch ); return FALSE; } bool oedit_cost( CHAR_DATA *ch, char *argument ) { OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); if( argument[0] == '\0' || !is_number( argument ) ) { send_to_char( "Syntax: cost [number]\n\r", ch ); return FALSE; } pObj->cost = atoi( argument ); send_to_char( "Cost set.\n\r", ch); return TRUE; } bool oedit_create( CHAR_DATA *ch, char *argument ) { OBJ_INDEX_DATA *pObj; AREA_DATA *pArea; int value; int iHash; value = atoi( argument ); /* OLC 1.1b */ if( argument[0] == '\0' || value <= 0 || value >= INT_MAX ) { char output[MAX_STRING_LENGTH]; sprintf( output, "Syntax: create [0 < vnum < %d]\n\r", INT_MAX ); send_to_char( output, ch ); return FALSE; } pArea = get_vnum_area( value ); if( !pArea ) { send_to_char( "OEdit: That vnum is not assigned an area.\n\r", ch ); return FALSE; } if( !IS_BUILDER( ch, pArea ) ) { send_to_char( "OEdit: Vnum in an area you cannot build in.\n\r", ch ); return FALSE; } if( get_obj_index( value ) ) { send_to_char( "OEdit: Object vnum already exists.\n\r", ch ); return FALSE; } pObj = new_obj_index(); pObj->vnum = value; pObj->area = pArea; if( value > top_vnum_obj ) top_vnum_obj = value; iHash = value % MAX_KEY_HASH; pObj->next = obj_index_hash[iHash]; obj_index_hash[iHash] = pObj; ch->desc->pEdit = (void *)pObj; send_to_char( "Object Created.\n\r", ch ); return TRUE; } bool oedit_ed( CHAR_DATA *ch, char *argument ) { EXTRA_DESCR_DATA *ed; OBJ_INDEX_DATA *pObj; char command[MAX_INPUT_LENGTH]; char keyword[MAX_INPUT_LENGTH]; EDIT_OBJ( ch, pObj ); argument = one_argument( argument, command ); one_argument( argument, keyword ); if( command[0] == '\0' ) { send_to_char( "Syntax: ed add [keyword]\n\r", ch ); send_to_char( " ed delete [keyword]\n\r", ch ); send_to_char( " ed edit [keyword]\n\r", ch ); send_to_char( " ed format [keyword]\n\r", ch ); return FALSE; } if( !str_cmp( command, "add" ) ) { if( keyword[0] == '\0' ) { send_to_char( "Syntax: ed add [keyword]\n\r", ch ); return FALSE; } ed = new_extra_descr(); ed->keyword = str_dup( keyword ); ed->next = pObj->extra_descr; pObj->extra_descr = ed; string_append( ch, &ed->description ); return TRUE; } if( !str_cmp( command, "edit" ) ) { if( keyword[0] == '\0' ) { send_to_char( "Syntax: ed edit [keyword]\n\r", ch ); return FALSE; } for( ed = pObj->extra_descr; ed; ed = ed->next ) { if( is_name( keyword, ed->keyword ) ) break; } if( !ed ) { send_to_char( "OEdit: Extra description keyword not found.\n\r", ch ); return FALSE; } string_append( ch, &ed->description ); return TRUE; } if( !str_cmp( command, "delete" ) ) { EXTRA_DESCR_DATA *ped = NULL; if( keyword[0] == '\0' ) { send_to_char( "Syntax: ed delete [keyword]\n\r", ch ); return FALSE; } for( ed = pObj->extra_descr; ed; ed = ed->next ) { if ( is_name( keyword, ed->keyword ) ) break; ped = ed; } if( !ed ) { send_to_char( "OEdit: Extra description keyword not found.\n\r", ch ); return FALSE; } if( !ped ) pObj->extra_descr = ed->next; else ped->next = ed->next; free_extra_descr( ed ); send_to_char( "Extra description deleted.\n\r", ch ); return TRUE; } if( !str_cmp( command, "format" ) ) { EXTRA_DESCR_DATA *ped = NULL; if( keyword[0] == '\0' ) { send_to_char( "Syntax: ed format [keyword]\n\r", ch ); return FALSE; } for( ed = pObj->extra_descr ; ed ; ed = ed->next ) { if ( is_name( keyword, ed->keyword ) ) break; ped = ed; } if( !ed ) { send_to_char( "OEdit: Extra description keyword not found.\n\r", ch ); return FALSE; } /* OLC 1.1b */ if( strlen(ed->description) >= (MAX_STRING_LENGTH - 4) ) { send_to_char( "String too long to be formatted.\n\r", ch ); return FALSE; } ed->description = format_string( ed->description ); send_to_char( "Extra description formatted.\n\r", ch ); return TRUE; } oedit_ed( ch, "" ); return FALSE; } /* * Mobile Editor Functions. */ bool medit_show( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMob; char buf[MAX_STRING_LENGTH]; EDIT_MOB( ch, pMob ); sprintf( buf, "Name: [%s]\n\rArea: [%5d] %s\n\r", pMob->player_name, !pMob->area ? -1 : pMob->area->vnum, !pMob->area ? "No Area" : pMob->area->name ); send_to_char( buf, ch ); sprintf( buf, "Act: [%s]\n\r", flag_string( act_flags, pMob->act ) ); send_to_char( buf, ch ); sprintf( buf, "Vnum: [%5d]\n\rSex: [%s]\n\r", pMob->vnum, pMob->sex == SEX_MALE ? "male" : pMob->sex == SEX_FEMALE ? "female" : "neutral" ); send_to_char( buf, ch ); sprintf( buf, "Align: [%4d]\n\r", pMob->alignment ); send_to_char( buf, ch ); sprintf( buf, "Affected by: [%s]\n\r", flag_string( affect_flags, pMob->affected_by ) ); send_to_char( buf, ch ); if ( pMob->spec_fun ) { sprintf( buf, "Spec fun: [%s]\n\r", spec_string( pMob->spec_fun ) ); send_to_char( buf, ch ); } sprintf( buf, "Short descr: %s\n\rLong descr:\n\r%s", pMob->short_descr, pMob->long_descr ); send_to_char( buf, ch ); sprintf( buf, "Description:\n\r%s", pMob->description ); send_to_char( buf, ch ); if ( pMob->pShop ) { SHOP_DATA *pShop; int iTrade; pShop = pMob->pShop; sprintf( buf, "Shop data for [%5d]:\n\r" " Markup for purchaser: %d%%\n\r" " Markdown for seller: %d%%\n\r", pShop->keeper, pShop->profit_buy, pShop->profit_sell ); send_to_char( buf, ch ); sprintf( buf, " Hours: %d to %d.\n\r", pShop->open_hour, pShop->close_hour ); send_to_char( buf, ch ); for ( iTrade = 0; iTrade < MAX_TRADE; iTrade++ ) { if ( pShop->buy_type[iTrade] != 0 ) { if ( iTrade == 0 ) { send_to_char( " Number Trades Type\n\r", ch ); send_to_char( " ------ -----------\n\r", ch ); } sprintf( buf, " [%4d] %s\n\r", iTrade, flag_string( type_flags, pShop->buy_type[iTrade] ) ); send_to_char( buf, ch ); } } } return FALSE; } bool medit_create( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMob; AREA_DATA *pArea; int value; int iHash; value = atoi( argument ); /* OLC 1.1b */ if ( argument[0] == '\0' || value <= 0 || value >= INT_MAX ) { char output[MAX_STRING_LENGTH]; sprintf( output, "Syntax: create [0 < vnum < %d]\n\r", INT_MAX ); send_to_char( output, ch ); return FALSE; } pArea = get_vnum_area( value ); if ( !pArea ) { send_to_char( "MEdit: That vnum is not assigned an area.\n\r", ch ); return FALSE; } if ( !IS_BUILDER( ch, pArea ) ) { send_to_char( "MEdit: Vnum in an area you cannot build in.\n\r", ch ); return FALSE; } if ( get_mob_index( value ) ) { send_to_char( "MEdit: Mobile vnum already exists.\n\r", ch ); return FALSE; } pMob = new_mob_index(); pMob->vnum = value; pMob->area = pArea; if ( value > top_vnum_mob ) top_vnum_mob = value; pMob->act = ACT_IS_NPC; iHash = value % MAX_KEY_HASH; pMob->next = mob_index_hash[iHash]; mob_index_hash[iHash] = pMob; ch->desc->pEdit = (void *)pMob; send_to_char( "Mobile Created.\n\r", ch ); return TRUE; } bool medit_spec( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMob; EDIT_MOB(ch, pMob); if ( argument[0] == '\0' ) { send_to_char( "Syntax: spec [special function]\n\r", ch ); return FALSE; } if ( !str_cmp( argument, "none" ) ) { pMob->spec_fun = NULL; send_to_char( "Spec removed.\n\r", ch); return TRUE; } if ( spec_lookup( argument ) ) { pMob->spec_fun = spec_lookup( argument ); send_to_char( "Spec set.\n\r", ch); return TRUE; } send_to_char( "MEdit: No such special function.\n\r", ch ); return FALSE; } bool medit_align( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMob; EDIT_MOB(ch, pMob); if ( argument[0] == '\0' || !is_number( argument ) ) { send_to_char( "Syntax: alignment [number]\n\r", ch ); return FALSE; } pMob->alignment = atoi( argument ); send_to_char( "Alignment set.\n\r", ch); return TRUE; } bool medit_race( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMob; EDIT_MOB( ch, pMob ); if( argument[0] == '\0' ) { send_to_char_bw( "Syntax: race <race name>\n\r", ch ); return FALSE; } if( !( pMob->race = race_lookup_olc( argument ) ) ); { send_to_char_bw( "Unknown Race, rejected.\n\r", ch ); return FALSE; } send_to_char_bw( "Race set.\n\r", ch); return TRUE; } bool medit_exp( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMob; EDIT_MOB( ch, pMob ); if( argument[0] == '\0' || !is_number( argument ) ) { send_to_char_bw( "Syntax: exp <number>\n\r", ch ); return FALSE; } pMob->exp = atoi( argument ); send_to_char_bw( "Experience Value Set.\n\r", ch ); return TRUE; } bool medit_desc( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMob; EDIT_MOB(ch, pMob); if ( argument[0] == '\0' ) { string_append( ch, &pMob->description ); return TRUE; } send_to_char( "Syntax: desc - line edit\n\r", ch ); return FALSE; } bool medit_long( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMob; EDIT_MOB(ch, pMob); if ( argument[0] == '\0' ) { send_to_char( "Syntax: long [string]\n\r", ch ); return FALSE; } free_string( pMob->long_descr ); strcat( argument, "\n\r" ); pMob->long_descr = str_dup( argument ); pMob->long_descr[0] = UPPER( pMob->long_descr[0] ); send_to_char( "Long description set.\n\r", ch); return TRUE; } bool medit_short( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMob; EDIT_MOB(ch, pMob); if ( argument[0] == '\0' ) { send_to_char( "Syntax: short [string]\n\r", ch ); return FALSE; } free_string( pMob->short_descr ); pMob->short_descr = str_dup( argument ); send_to_char( "Short description set.\n\r", ch); return TRUE; } bool medit_name( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMob; EDIT_MOB(ch, pMob); if ( argument[0] == '\0' ) { send_to_char( "Syntax: name [string]\n\r", ch ); return FALSE; } free_string( pMob->player_name ); pMob->player_name = str_dup( argument ); send_to_char( "Name set.\n\r", ch); return TRUE; } bool medit_shop( CHAR_DATA *ch, char *argument ) { MOB_INDEX_DATA *pMob; char command[MAX_INPUT_LENGTH]; char arg1[MAX_INPUT_LENGTH]; argument = one_argument( argument, command ); argument = one_argument( argument, arg1 ); EDIT_MOB(ch, pMob); if ( command[0] == '\0' ) { send_to_char( "Syntax: shop hours [#opening] [#closing]\n\r", ch ); send_to_char( " shop profit [#buying%] [#selling%]\n\r", ch ); send_to_char( " shop type [#0-4] [item type]\n\r", ch ); send_to_char( " shop delete [#0-4]\n\r", ch ); return FALSE; } if ( !str_cmp( command, "hours" ) ) { if ( arg1[0] == '\0' || !is_number( arg1 ) || argument[0] == '\0' || !is_number( argument ) ) { send_to_char( "Syntax: shop hours [#opening] [#closing]\n\r", ch ); return FALSE; } if ( !pMob->pShop ) { pMob->pShop = new_shop(); pMob->pShop->keeper = pMob->vnum; shop_last->next = pMob->pShop; } pMob->pShop->open_hour = atoi( arg1 ); pMob->pShop->close_hour = atoi( argument ); send_to_char( "Shop hours set.\n\r", ch); return TRUE; } if ( !str_cmp( command, "profit" ) ) { if ( arg1[0] == '\0' || !is_number( arg1 ) || argument[0] == '\0' || !is_number( argument ) ) { send_to_char( "Syntax: shop profit [#buying%] [#selling%]\n\r", ch ); return FALSE; } if ( !pMob->pShop ) { pMob->pShop = new_shop(); pMob->pShop->keeper = pMob->vnum; shop_last->next = pMob->pShop; } pMob->pShop->profit_buy = atoi( arg1 ); pMob->pShop->profit_sell = atoi( argument ); send_to_char( "Shop profit set.\n\r", ch); return TRUE; } if ( !str_cmp( command, "type" ) ) { char buf[MAX_INPUT_LENGTH]; int value; if ( arg1[0] == '\0' || !is_number( arg1 ) || argument[0] == '\0' ) { send_to_char( "Syntax: shop type [#0-4] [item type]\n\r", ch ); return FALSE; } if ( atoi( arg1 ) >= MAX_TRADE ) { sprintf( buf, "REdit: May sell %d items max.\n\r", MAX_TRADE ); send_to_char( buf, ch ); return FALSE; } if ( ( value = flag_value( type_flags, argument ) ) == NO_FLAG ) { send_to_char( "REdit: That type of item is not known.\n\r", ch ); return FALSE; } if ( !pMob->pShop ) { pMob->pShop = new_shop(); pMob->pShop->keeper = pMob->vnum; shop_last->next = pMob->pShop; } pMob->pShop->buy_type[atoi( arg1 )] = value; send_to_char( "Shop type set.\n\r", ch); return TRUE; } if ( !str_cmp( command, "delete" ) ) { SHOP_DATA *pShop; SHOP_DATA *pShop_next; int value; int cnt = 0; if ( arg1[0] == '\0' || !is_number( arg1 ) ) { send_to_char( "Syntax: shop delete [#0-4]\n\r", ch ); return FALSE; } value = atoi( argument ); if ( !pMob->pShop ) { send_to_char( "REdit: Non-existant shop.\n\r", ch ); return FALSE; } if ( value == 0 ) { pShop = pMob->pShop; pMob->pShop = pMob->pShop->next; free_shop( pShop ); } else for ( pShop = pMob->pShop, cnt = 0; pShop; pShop = pShop_next, cnt++ ) { pShop_next = pShop->next; if ( cnt+1 == value ) { pShop->next = pShop_next->next; free_shop( pShop_next ); break; } } send_to_char( "Shop deleted.\n\r", ch); return TRUE; } medit_shop( ch, "" ); return FALSE; }