/**************************************************************************/ // redit.cpp - OLC Based room editor /*************************************************************************** * The Dawn of Time v1.69r (c)1997-2004 Michael Garratt * * >> A number of people have contributed to the Dawn codebase, with the * * majority of code written by Michael Garratt - www.dawnoftime.org * * >> To use this source code, you must fully comply with all the licenses * * in licenses.txt... In particular, you may not remove this copyright * * notice. * *************************************************************************** * >> Original Diku Mud copyright (c)1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, & Katja Nyboe. * * >> Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * >> ROM 2.4 is copyright 1993-1995 Russ Taylor and has been brought to * * you by the ROM consortium: Russ Taylor(rtaylor@pacinfo.com), * * Gabrielle Taylor(gtaylor@pacinfo.com) & Brian Moore(rom@rom.efn.org) * * >> Oblivion 1.2 is copyright 1996 Wes Wagner * **************************************************************************/ #include "include.h" // dawn standard includes #include "olc.h" #include "security.h" #include "lockers.h" DECLARE_OLC_FUN( redit_create ); /**************************************************************************/ extern gameset_value_type gameset_value[]; /**************************************************************************/ // True if room is private. bool room_pc_private( ROOM_INDEX_DATA *pRoomIndex ) { char_data *rch; int count = 0; if (pRoomIndex->owner != NULL && pRoomIndex->owner[0] != '\0') return true; for ( rch = pRoomIndex->people; rch != NULL; rch = rch->next_in_room ) { if ( !IS_NPC(rch)){ count++; } } if ( IS_SET(pRoomIndex->room_flags, ROOM_PRIVATE) && count >= 2 ) return true; if ( IS_SET(pRoomIndex->room_flags, ROOM_SOLITARY) && count >= 1 ) return true; if ( IS_SET(pRoomIndex->room_flags, ROOM_IMP_ONLY) && count >= 1 ) return true; return false; } /**************************************************************************/ // Entry point for editing room_index_data. void do_redit( char_data *ch, char *argument ) { ROOM_INDEX_DATA *pRoom, *pRoom2; char arg1[MSL]; char_data *rch; if (!HAS_SECURITY(ch,2)) { ch->println( "You must have an olc security 2 or higher to use this command." ); return; } argument = one_argument( argument, arg1 ); pRoom = ch->in_room; if ( !str_cmp( arg1, "reset" ) ) { if ( !IS_BUILDER( ch, pRoom->area, BUILDRESTRICT_ROOMS ) ) { ch->println( "Insufficient security to modify the rooms of the area you are in." ); return; } reset_room( pRoom, true ); ch->printlnf( "Room %d reset.", pRoom->vnum); ch->println( "note: you can use the rpurge command to purge the room of mobs/objects." ); return; } else if ( !str_cmp( arg1, "create" ) || !str_cmp( arg1, "?" ) ) { if ( argument[0] == '\0' || atoi( argument ) == 0 || !str_cmp( arg1, "?" )) { ch->println( "Syntax: redit create [vnum]" ); ch->println( " typing redit by itself will edit the room you are in." ); return; } if ( redit_create( ch, argument ) ) { for (rch = ch->in_room->people; rch; rch = rch->next_in_room) { if (IS_IMMORTAL(rch)) { act("($n leaves the room via REDIT)",ch,NULL,rch,TO_VICT); } } char_from_room( ch ); char_to_room( ch, (ROOM_INDEX_DATA *) ch->desc->pEdit ); SET_BIT( pRoom->area->olc_flags, OLCAREA_CHANGED ); pRoom = ch->in_room; } } else { // support 'redit .' syntax to edit the current room if(!IS_NULLSTR(arg1) && arg1[0]=='.' && arg1[1]=='\0'){ arg1[0]='\0'; } if(!IS_NULLSTR(arg1) && !is_number(arg1)){ ch->printlnf("'%s' is not a number!", arg1); return; }; pRoom2 = get_room_index(atoi(arg1)); // make sure the room exists if (!pRoom2 && !IS_NULLSTR(arg1)){ ch->printlnf("Room %d does not exist.", atoi(arg1)); return; } // check for privacy - count only pc's for check if (pRoom2 && !IS_ADMIN(ch) && !is_room_owner(ch,pRoom2) && room_pc_private(pRoom2) ) { ch->println( "That room is private right now (mobs ignored in olc private checks)." ); return; } if ( (pRoom2 != NULL) && IS_BUILDER(ch,pRoom2->area, BUILDRESTRICT_ROOMS) ) { for (rch = ch->in_room->people; rch; rch = rch->next_in_room) { if (IS_IMMORTAL(rch)) { act("($n leaves the room via REDIT)",ch,NULL,rch,TO_VICT); } } char_from_room( ch ); char_to_room( ch, pRoom2 ); for (rch = ch->in_room->people; rch; rch = rch->next_in_room) { if (IS_IMMORTAL(rch)) { act("($n enters the room via REDIT)",ch,NULL,rch,TO_VICT); } } pRoom = ch->in_room; }else if (atoi(arg1) != 0){ ch->println( "Insufficient security to edit the room with that vnum." ); return; } } if ( !IS_BUILDER( ch, pRoom->area, BUILDRESTRICT_ROOMS ) ) { ch->println( "Insufficient security to edit the room you are currently in." ); return; } // officially reserved vnum range if(ch->in_room_vnum()<500){ ch->println("Warning: all mobs, rooms and objects below vnum 500 are officially reserved for the dawn codebase."); if(!HAS_SECURITY(ch,9)){ ch->println("As a result of this reservation, only those with security 9 can edit in that vnum range."); return; } } ch->desc->editor = ED_ROOM; ch->wraplnf( "`=rYou are now editing the room '`r%s`=r' vnum: `Y%d`x", ch->in_room->name, ch->in_room->vnum); ch->println( "`=rType `=Cdone`=r to finish editing."); return; } /**************************************************************************/ bool redit_show( char_data *ch, char * ) { ROOM_INDEX_DATA *pRoom; char buf [MSL]; char buf1 [2*MSL]; OBJ_DATA *obj; char_data *rch; int door; bool fcnt; EDIT_ROOM(ch, pRoom); sprintf(buf, "`=rVnum: `=v%5d `=rArea[%d]: `=x%-25s ", pRoom->vnum, pRoom->area? pRoom->area->vnum:0, pRoom->area? pRoom->area->name:"`=RNo Area!!!`x"); if(IS_SET(ch->dyn,DYN_SHOWFLAGS)){ ch->println( buf ); }else{ ch->print( buf ); } mxp_display_olc_flags(ch, sector_types, pRoom->sector_type, "sector", "Sector Type:"); ch->printlnf("`=rName: `r%s `=rOwner: `=x%s `=rClan: `=x%s`x", pRoom->name, IS_NULLSTR(pRoom->owner)?"`=$(none)":pRoom->owner, pRoom->clan ? pRoom->clan->m_pName : "`=$(none)" ); ch->printf("`=rDescription:\r\n `=R%s`x", pRoom->description ); ch->printlnf("`=rHealth recovery: `=v%3d%% `=rMana recovery: `=v%d%%", pRoom->heal_rate , pRoom->mana_rate ); mxp_display_olc_flags(ch, room_flags, pRoom->room_flags, "room", "Room Flags: "); mxp_display_olc_flags(ch, room2_flags, pRoom->room2_flags, "room2", "Room2 Flags:"); // start of characters in room fcnt = false; strcpy( buf1, FORMATF("`=rCharacters(%d): [`B", pRoom->number_in_room) ); for ( rch = pRoom->people; rch; rch = rch->next_in_room ) { one_argument( rch->name, buf ); strcat( buf1, buf ); strcat( buf1, " " ); fcnt = true; } if ( fcnt ) { buf1[str_len(buf1) - 1] = '\0'; strcat( buf1, "`=r]\r\n" ); } else { strcat( buf1, "none`=r]\r\n" ); } // end of characters in room // start of objects in room strcat( buf1, "`=rObjects: `=r[`g" ); fcnt = false; for ( obj = pRoom->contents; obj; obj = obj->next_content ) { one_argument( obj->name, buf ); strcat( buf1, buf ); strcat( buf1, " " ); fcnt = true; } if ( fcnt ) { buf1[str_len(buf1) - 1] = '\0'; strcat( buf1, "`=r]\r\n" ); } else { strcat( buf1, "none`=r]`x\r\n" ); } // end of objects in room for ( door = 0; door < MAX_DIR; door++ ) { EXIT_DATA *pexit; if ( ( pexit = pRoom->exit[door] ) ) { char word[MIL]; char reset_state[MSL]; char *state; int i, length; sprintf( buf, "`=r-`Y%-5s `=rto [`Y%5d`=r] Key: [`x%5d`=r] ", capitalize(dir_name[door]), pexit->u1.to_room ? pexit->u1.to_room->vnum : 0, pexit->key ); strcat( 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 ); strcat( buf1, " Exit flags: [`x" ); for (; ;) { state = one_argument( state, word ); if ( word[0] == '\0' ) { buf1[str_len(buf1) - 1] = '\0'; strcat( buf1, "`=r]\r\n" ); break; } if ( str_infix( word, reset_state ) ) { length = str_len(word); for (i = 0; i < length; i++) word[i] = UPPER(word[i]); } strcat( buf1, word ); strcat( buf1, " " ); } if ( pexit->keyword && pexit->keyword[0] != '\0' ) { sprintf( buf, "`=rKwds: [`x%s`=r]\r\n", pexit->keyword ); strcat( buf1, buf ); } if ( pexit->description && pexit->description[0] != '\0' ) { sprintf( buf, " `=R%s`x", pexit->description ); strcat( buf1, buf ); } } } ch->print( buf1 ); ch->printlnf( "`=rMSP: `x%s", IS_NULLSTR(pRoom->msp_sound)?"`=Rnone`x":pRoom->msp_sound); ch->println( "`=rhint: type `=Cusedby`=r to see exits and portals the lead into this room."); if(lockers->room_has_lockers(pRoom)){ ch->println("`=r---============== L O C K E R D E T A I L S ============================---"); ch->printlnf("`=rQuantity=`=v%d `=@(%d in use) `=rInitial rent=`=v%d `=rgold `=@(includes 1 month rent)\r\n" "`=rOngoing rent=`=v%d `=rgold per year `=rWeight(v0)=`=v%d `=rCapacity(v3)=`=v%d, `=rPickProof=`=v%d", pRoom->lockers->quantity, lockers->count_used_lockers_in_room(pRoom->vnum), pRoom->lockers->initial_rent, pRoom->lockers->ongoing_rent, pRoom->lockers->weight, pRoom->lockers->capacity, pRoom->lockers->pick_proof); } // display any room echos ch->println("`=r---============== R O O M E C H O E S ==================================---"); int recount=0; for( room_echo_data *re = pRoom->echoes; re; re = re->next ) { if(re==pRoom->echoes){ ch->println("[##] >=Hr <=Hr % -==EchoText==-`x"); } ch->printlnf( "`=r[%2d] `=v%4s %4s %3d `=x'%s'`x", recount++, convert24hourto12hour(re->firsthour), convert24hourto12hour(re->lasthour), re->percentage, re->echotext); if(has_colour(re->echotext)){ // display black and white if colour in echo ch->print("`S"); ch->printlnfbw( "[%2d] %4s %4s %3d '%s'", recount-1, convert24hourto12hour(re->firsthour), convert24hourto12hour(re->lasthour), re->percentage, re->echotext); ch->print("`x"); }; } if(recount==0){ ch->println("`=Rnone - add using 'addecho'.`x"); } show_char_extended(ch, pRoom->extra_descr, false); return false; } /**************************************************************************/ bool change_exit( char_data *ch, char *argument, int door ) { ROOM_INDEX_DATA *pRoom; ROOM_INDEX_DATA *pToRoom; int rev; char command[MIL]; char arg[MIL]; int value; // record the full argument incase exit flags are being specified char fullarg[MIL]; strcpy(fullarg, argument); // get the first arg, check if it is a command argument = one_argument( argument, command ); one_argument( argument, arg ); // no arguments - normal move if ( IS_NULLSTR(command)) { move_char( ch, door, true ); return false; } // help if ( command[0] == '?' ) { do_help( ch, "OLC-EXIT" ); return false; } // editing commands EDIT_ROOM(ch, pRoom); if ( !str_cmp( command, "remove" ) || !str_cmp( command, "delete" )) { ROOM_INDEX_DATA *pToRoom; sh_int rev; if ( !pRoom->exit[door] ) { ch->println( "There is no exit in that direction to remove." ); return false; } /* * Remove ToRoom Exit if it leads to current room. */ rev = rev_dir[door]; pToRoom = pRoom->exit[door]->u1.to_room; if ( pToRoom && pToRoom->exit[rev] && pToRoom->exit[rev]->u1.to_room==pRoom) { free_exit( pToRoom->exit[rev] ); pToRoom->exit[rev] = NULL; } /* * Remove this exit. */ free_exit( pRoom->exit[door] ); pRoom->exit[door] = NULL; ch->println( "Exit removed." ); return true; } if ( !str_cmp( command, "link" ) ) { EXIT_DATA *pExit; if ( arg[0] == '\0' || !is_number( arg ) ) { ch->println( "Syntax: [direction] link [vnum]" ); return false; } value = atoi( arg ); if ( !get_room_index( value ) ) { ch->println( "REdit: Cannot link to non-existant room." ); return false; } if ( !IS_BUILDER( ch, get_room_index( value )->area, BUILDRESTRICT_EXITS ) ) { ch->println( "REdit: Cannot link to that area." ); return false; } if ( get_room_index( value )->exit[rev_dir[door]] ) { ch->println( "REdit: Remote side's exit already exists." ); return false; } if ( !pRoom->exit[door] ) { pRoom->exit[door] = new_exit(); } pRoom->exit[door]->u1.to_room = get_room_index( value ); pRoom = get_room_index( value ); door = rev_dir[door]; pExit = new_exit(); pExit->u1.to_room = ch->in_room; pRoom->exit[door] = pExit; // Mark the area the reverse door went on as changed - Kal Feb 01 if(pRoom->area){ SET_BIT( pRoom->area->olc_flags, OLCAREA_CHANGED ); } ch->println( "Two-way link established." ); return true; } if (!str_cmp (command, "dig")) { if(IS_NULLSTR(arg)) { // find the first unused room vnum in the area int newvnum = ch->in_room->area->min_vnum-1; pToRoom=ch->in_room; // make sure the while loop actually starts while(pToRoom){ newvnum++; if (newvnum > ch->in_room->area->max_vnum){ ch->printlnf("Dig Error: No more free room vnums in area range %d to %d.", ch->in_room->area->min_vnum, ch->in_room->area->max_vnum); return false; } pToRoom = get_room_index(newvnum); } // create a room with that vnum, and link it in redit_create(ch, FORMATF("%d", newvnum)); change_exit(ch, FORMATF("link %d", newvnum), door); ch->printlnf("Created new room %d %s", newvnum, dir_name[door]); return true; } else { if (!is_number( arg ) ){ ch->println( "Syntax: <direction> dig [vnum]" ); return false; } redit_create( ch, arg ); change_exit( ch, FORMATF("link %s", arg ), door); return true; } } if ( !str_cmp( command, "room" ) ) { if ( arg[0] == '\0' || !is_number( arg ) ) { ch->println( "Syntax: [direction] room [vnum]" ); return false; } if ( !pRoom->exit[door] ) { pRoom->exit[door] = new_exit(); } value = atoi( arg ); if ( !get_room_index( value ) ) { ch->println( "REdit: Cannot link to non-existant room." ); return false; } pRoom->exit[door]->u1.to_room = get_room_index( value ); ch->println( "One-way link established." ); return true; } /*** KEYS ***/ if ( !str_cmp( command, "key" ) || !str_cmp( command, "onesidedkey" )) { OBJ_INDEX_DATA *pObj; if ( arg[0] == '\0' || !is_number( arg ) ) { ch->println( "Syntax: <direction> key <vnum>" ); return false; } if ( !pRoom->exit[door] ) { ch->println( "That exit doesn't exist." ); return false; } value = atoi( arg ); pObj=get_obj_index( value ); if ( !pObj ) { ch->println( "REdit: Item doesn't exist." ); return false; } ch->printlnf( "`=rUsing object Vnum: `x%-5d `=rType: " "`x%-10s as key (from %s areafile).", pObj->vnum, flag_string( item_types, pObj->item_type ), pObj->area ? pObj->area->file_name : "`RNo Area!!!`x"); if(!IS_SET(pRoom->exit[door]->rs_flags, EX_ISDOOR)){ ch->println( "`YAutomatic:`x setting `GDOOR`x flag `GON`x for the exit."); change_exit( ch, "door", door ); } if(!IS_SET(pRoom->exit[door]->rs_flags, EX_CLOSED)){ ch->println( "`YAutomatic:`x setting `GDOOR`x to `GCLOSED`x."); change_exit( ch, "closed", door ); } if ( pObj->item_type != ITEM_KEY ) { ch->println( "`RWarning:`x That object is not of type key." ); } // do reverse side pToRoom = pRoom->exit[door]->u1.to_room; rev = rev_dir[door]; if (pToRoom->exit[rev]){ if (!str_cmp( command, "key" )) { if(pToRoom->exit[rev]->u1.to_room==pRoom){ ch->printf("`GKey vnum on other side automatically set to %d,`x\r\n" "`Snote: Use 'onesidedkey' to not set the key on the other side.`x\r\n", value); pToRoom->exit[rev]->key=value; // Mark the area the reverse door went on as changed - Kal Feb 01 if(pToRoom->area){ SET_BIT( pToRoom->area->olc_flags, OLCAREA_CHANGED ); } }else{ ch->printf("`RWarning:`x The exit going %s from %d (here) to %d doesn't link 2 ways.\r\n" "i.e. The exit going %s from %d doesn't go to %d...\r\n" "Therefore the key vnum not been set on that side.\r\n", dir_name[door], pRoom->vnum, pToRoom->vnum, dir_name[rev], pToRoom->vnum, pRoom->vnum); } } else { ch->println("`Ronesidedkey used... this side of the door key only affected.`x"); } }else{ ch->println( "`RWarning:`x That exit is a oneway exit." ); } ch->printlnf( "Exit key changed from %d to %d.", pRoom->exit[door]->key, value); pRoom->exit[door]->key = value; return true; } if ( !str_cmp( command, "name" ) ) { if ( arg[0] == '\0' ) { ch->println( "Syntax: <direction> name <string>" ); ch->println( " <direction> name none" ); return false; } if ( !pRoom->exit[door] ) { ch->println( "That exit doesn't exist." ); return false; } if (str_cmp(arg,"none")){ ch->printlnf( "Exit name changed from '%s' to '%s'.", pRoom->exit[door]->keyword, arg); replace_string(pRoom->exit[door]->keyword, arg ); }else{ ch->printlnf( "Exit name cleared (was '%s').", pRoom->exit[door]->keyword); replace_string(pRoom->exit[door]->keyword, "" ); } return true; } if ( !str_prefix( command, "description" ) ) { if ( arg[0] == '\0' ) { if ( !pRoom->exit[door] ) { ch->println( "That exit doesn't exist." ); return false; } if(ch->desc && pRoom->area){ // if the string as changed, this is used to flag the area file saving ch->desc->changed_flag=&pRoom->area->olc_flags; } string_append( ch, &pRoom->exit[door]->description ); return true; } ch->println( "Syntax: [direction] desc" ); return false; } // Set the exit flags, needs full argument. // ---------------------------------------- if ( ( value = flag_value( exit_flags, fullarg) ) != NO_FLAG ) { if ( !pRoom->exit[door] ) { ch->println( "Exit doesn't exit." ); return false; } // This room. TOGGLE_BIT(pRoom->exit[door]->rs_flags, value); // Don't toggle exit_info because it can be changed by players. pRoom->exit[door]->exit_info = pRoom->exit[door]->rs_flags; if(value==EX_ONEWAY){ if(IS_SET(pRoom->exit[door]->rs_flags, EX_ONEWAY)){ ch->println( "Oneway exit flag set" ); }else{ ch->println( "Oneway exit flag removed" ); } }else{ if (pRoom->exit[door]->rs_flags && !IS_SET(pRoom->exit[door]->rs_flags , EX_ISDOOR) ) { SET_BIT(pRoom->exit[door]->rs_flags , EX_ISDOOR); ch->println( "Door flag added on this side of door." ); if (IS_SET(value, EX_ISDOOR)) ch->println( "note: to remove door exit flag, remove all other exit flags first." ); } /* * Connected room. */ pToRoom = pRoom->exit[door]->u1.to_room; rev = rev_dir[door]; if(pToRoom->exit[rev] && pToRoom->exit[rev]->u1.to_room==pRoom){ if (IS_SET(pRoom->exit[door]->rs_flags, value)){ SET_BIT(pToRoom->exit[rev]->rs_flags, value); }else{ REMOVE_BIT(pToRoom->exit[rev]->rs_flags, value); } pToRoom->exit[rev]->exit_info = pToRoom->exit[rev]->rs_flags; if (pToRoom->exit[rev]->rs_flags && !IS_SET(pToRoom->exit[rev]->rs_flags , EX_ISDOOR) ) { SET_BIT(pToRoom->exit[rev]->rs_flags , EX_ISDOOR); ch->println( "Door flag added on OTHER side of door." ); if (IS_SET(value, EX_ISDOOR)) ch->println( "note: to remove door exit flag, remove all other exit flags first." ); } // Mark the area the reverse door went on as changed - Kal Feb 01 if(pToRoom->area){ SET_BIT( pToRoom->area->olc_flags, OLCAREA_CHANGED ); } ch->println( "Exit flag toggled this side, set/removed on otherside." ); }else{ ch->printf("`RWarning:`x The exit going %s from %d (here) to %d doesn't link 2 ways.\r\n" "i.e. The exit going %s from %d doesn't go to %d...\r\n" "Therefore the exit flags have not been set on that side.\r\n", dir_name[door], pRoom->vnum, pToRoom->vnum, dir_name[rev], pToRoom->vnum, pRoom->vnum); } } return true; } ch->wrapln("Unrecognised exit command/exit flags, read help `=_OLC-EXIT for " "more help on olc exits and olc exit flags."); ch->wraplnf("Exit flags include: %s", flag_string(exit_flags, -1)); return false; } /**************************************************************************/ // direction commands section to deal with exits bool redit_north( char_data *ch, char * argument) { if ( change_exit( ch, argument, DIR_NORTH ) ) 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_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; } bool redit_northeast( char_data *ch, char * argument) { if ( change_exit( ch, argument, DIR_NORTHEAST ) ) 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_northwest( char_data *ch, char * argument) { if ( change_exit( ch, argument, DIR_NORTHWEST ) ) return true; return false; } /**************************************************************************/ bool redit_ed( char_data *ch, char * argument) { return( generic_ed (ch, argument) ); } /**************************************************************************/ bool redit_create( char_data *ch, char * argument) { AREA_DATA *pArea; ROOM_INDEX_DATA *pRoom; int value; int iHash; EDIT_ROOM(ch, pRoom); value = atoi( argument ); if ( argument[0] == '\0' || value <= 0 ) { ch->println( "Syntax: create [vnum > 0]" ); return false; } pArea = get_vnum_area( value ); if ( !pArea ) { ch->println( "REdit: That vnum is not assigned an area." ); return false; } if ( !IS_BUILDER( ch, pArea, BUILDRESTRICT_ROOMS)) { ch->println( "REdit: Vnum in an area you cannot build in." ); return false; } if ( get_room_index( value ) ) { ch->println( "REdit: Room vnum already exists." ); return false; } // officially reserved vnum range if(value<500){ ch->println("Warning: all mobs, rooms and objects below vnum 500 are officially reserved for the dawn codebase."); if(!HAS_SECURITY(ch,9)){ ch->println("As a result of this reservation, only those with security 9 can edit in that vnum range."); 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; ch->printlnf( "Room %d created.", pRoom->vnum); return true; } /**************************************************************************/ bool redit_name( char_data *ch, char * argument) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); if ( IS_NULLSTR(argument)) { ch->println( "Syntax: name <string>" ); return false; } ch->printlnf( "Room name changed from '%s' to '%s'.", pRoom->name, argument); replace_string( pRoom->name, argument); return true; } /**************************************************************************/ bool redit_desc( char_data *ch, char * argument) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); if ( IS_NULLSTR(argument) ) { if(ch->desc && pRoom->area){ // if the string as changed, this is used to flag the area file saving ch->desc->changed_flag=&pRoom->area->olc_flags; } string_append( ch, &pRoom->description ); return true; } ch->println( "Syntax: desc" ); return false; } /**************************************************************************/ bool redit_heal( char_data *ch, char * argument) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); if(is_number(argument)){ ch->printlnf( "Healing HP regen rate changed from %d to %d.", pRoom->heal_rate, atoi( argument )); pRoom->heal_rate= atoi ( argument ); return true; } ch->println( "Syntax : heal <#xnumber>" ); return false; } /**************************************************************************/ bool redit_mana( char_data *ch, char * argument) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); if(is_number(argument)){ ch->printlnf( "Mana regen rate changed from %d to %d.", pRoom->mana_rate, atoi( argument )); pRoom->mana_rate = atoi ( argument ); return true; } ch->println( "Syntax : mana <#xnumber>" ); return false; } /**************************************************************************/ void do_clanlist(char_data *ch, char *); /**************************************************************************/ bool redit_clan( char_data *ch, char * argument) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); if(IS_NULLSTR(argument)){ ch->println("Syntax: clan <clanname>"); ch->println("Syntax: clan none"); do_clanlist(ch,""); return false; } if(!str_cmp(argument, "none")){ ch->printlnf("Clan cleared - was '%s`x'", pRoom->clan?pRoom->clan->cname():"none already"); pRoom->clan=NULL; return true; } CClanType* newclan=clan_lookup(argument); if(!newclan){ ch->printlnf("There is no clan called '%s'", argument); return false; } if(!pRoom->clan){ ch->printlnf("Room clan set to '%s'", newclan->cname()); }else{ if(newclan==pRoom->clan){ ch->printlnf("This room is already owned by the '%s`x' clan.", newclan->cname()); return false; } ch->printlnf("Room clan changed from '%s`x' to '%s`x'", pRoom->clan->cname(), newclan->cname()); } pRoom->clan = newclan; return true; } /**************************************************************************/ bool redit_wrap( char_data *ch, char * ) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); pRoom->description = format_string( pRoom->description ); ch->println( "Room description wordwrapped." ); return true; } /**************************************************************************/ bool redit_mreset( char_data *ch, char * argument) { ROOM_INDEX_DATA *pRoom; MOB_INDEX_DATA *pMobIndex; char_data *newmob; char arg [ MIL ]; char arg2 [ MIL ]; RESET_DATA *pReset; EDIT_ROOM(ch, pRoom); argument = one_argument( argument, arg ); argument = one_argument( argument, arg2 ); if ( arg[0] == '\0' || !is_number( arg ) ) { ch->println( "Syntax: mreset <vnum> <max #x> <mix #x>" ); return false; } if ( !( pMobIndex = get_mob_index( atoi( arg ) ) ) ) { ch->println( "REdit: No mobile has that vnum." ); return false; } if ( pMobIndex->area != pRoom->area ) { ch->println( "REdit: No such mobile in this area." ); return false; } /* * Create the mobile reset. */ pReset = new_reset_data(); pReset->command = 'M'; pReset->arg1 = pMobIndex->vnum; pReset->arg2 = is_number( arg2 ) ? atoi( arg2 ) : MAX_MOB; pReset->arg3 = pRoom->vnum; pReset->arg4 = is_number( argument ) ? atoi (argument) : 1; add_reset( pRoom, pReset, 0/* Last slot*/ ); /* * Create the mobile. */ newmob = create_mobile( pMobIndex, 0 ); char_to_room( newmob, pRoom ); ch->printf("%s (%d) has been loaded and added to resets.\r\n" "There will be a maximum of %d loaded to this room.\r\n", capitalize( pMobIndex->short_descr ), pMobIndex->vnum, pReset->arg2 ); 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, OBJWEAR_TAKE }, { WEAR_LIGHT, ITEM_LIGHT }, { WEAR_FINGER_L, OBJWEAR_FINGER }, { WEAR_FINGER_R, OBJWEAR_FINGER }, { WEAR_NECK_1, OBJWEAR_NECK }, { WEAR_NECK_2, OBJWEAR_NECK }, { WEAR_TORSO, OBJWEAR_TORSO }, { WEAR_HEAD, OBJWEAR_HEAD }, { WEAR_LEGS, OBJWEAR_LEGS }, { WEAR_FEET, OBJWEAR_FEET }, { WEAR_HANDS, OBJWEAR_HANDS }, { WEAR_ARMS, OBJWEAR_ARMS }, { WEAR_SHIELD, OBJWEAR_SHIELD }, { WEAR_ABOUT, OBJWEAR_ABOUT }, { WEAR_WAIST, OBJWEAR_WAIST }, { WEAR_WRIST_L, OBJWEAR_WRIST }, { WEAR_WRIST_R, OBJWEAR_WRIST }, { WEAR_WIELD, OBJWEAR_WIELD }, { WEAR_HOLD, OBJWEAR_HOLD }, { WEAR_LODGED_ARM, OBJWEAR_LODGED_ARM }, { WEAR_LODGED_LEG, OBJWEAR_LODGED_LEG }, { WEAR_LODGED_RIB, OBJWEAR_LODGED_RIB }, { WEAR_SHEATHED, OBJWEAR_SHEATHED }, { WEAR_CONCEALED, OBJWEAR_CONCEALED }, { WEAR_EYES, OBJWEAR_EYES }, { WEAR_EAR_L, OBJWEAR_EAR }, { WEAR_EAR_R, OBJWEAR_EAR }, { WEAR_FACE, OBJWEAR_FACE }, { WEAR_ANKLE_L, OBJWEAR_ANKLE }, { WEAR_ANKLE_R, OBJWEAR_ANKLE }, { WEAR_BACK, OBJWEAR_BACK }, { NO_FLAG, 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; OBJ_DATA *newobj; OBJ_DATA *to_obj; char_data *to_mob; char vnum[MIL]; char name[MIL]; int olevel = 0; RESET_DATA *pReset; EDIT_ROOM(ch, pRoom); argument = one_argument( argument, vnum); argument = one_argument( argument, name); if ( IS_NULLSTR(vnum) || !is_number( vnum ) ) { ch->println( "Syntax: oreset <vnum> = reset object into room" ); ch->println( "Syntax: oreset <vnum> <objname> = reset object into object" ); ch->println( "Syntax: oreset <vnum> <mobname> <wearloc> = reset object onto mob" ); return false; } if ( !( pObjIndex = get_obj_index( atoi( vnum ) ) ) ) { ch->printlnf( "redit_oreset(): No object has vnum '%s'.", vnum); return false; } if ( pObjIndex->area != pRoom->area ) { ch->printlnf( "redit_oreset(): Object vnum '%s' doesn't belong to this area.", vnum ); return false; } if(IS_NULLSTR(name)){ // no name, load into room. pReset = new_reset_data(); pReset->command = 'O'; pReset->arg1 = pObjIndex->vnum; pReset->arg2 = 0; pReset->arg3 = pRoom->vnum; pReset->arg4 = 0; add_reset( pRoom, pReset, 0/* Last slot*/ ); newobj = create_object( pObjIndex); obj_to_room( newobj, pRoom ); ch->printlnf("%s (%d) has been loaded and added to resets.", capitalize( pObjIndex->short_descr ), pObjIndex->vnum ); act( "$n has created $p!", ch, newobj, NULL, TO_ROOM ); return true; } // name, but no wear location - therefore object inside object if(IS_NULLSTR(argument)){ to_obj = get_obj_list( ch, name, pRoom->contents ); if(!to_obj){ ch->printlnf("redit_oreset(): Couldn't find any object '%s' currently in the room.", name); return false; } pReset = new_reset_data(); pReset->command = 'P'; pReset->arg1 = pObjIndex->vnum; pReset->arg2 = 0; pReset->arg3 = to_obj->pIndexData->vnum; pReset->arg4 = 1; add_reset( pRoom, pReset, 0); newobj = create_object( pObjIndex); obj_to_obj( newobj, to_obj ); newobj->cost = 0; ch->printf("%s (%d) has been loaded into " "%s (%d) and added to resets.\r\n", capitalize( newobj->short_descr ), newobj->pIndexData->vnum, to_obj->short_descr, to_obj->pIndexData->vnum ); ch->printlnf("%s (%d) has been loaded and added to resets.", capitalize( pObjIndex->short_descr ), pObjIndex->vnum ); act( "$n has created $p and put it inside another object!", ch, newobj, NULL, TO_ROOM ); return true; } // because the object hasnt been loaded into the room or another object // the reset must be loading the object onto a mob // format of the command oreset <vnum> <mobname> <wearlocation> to_mob = get_char_room( ch, name); if(!to_mob){ ch->printlnf("redit_oreset(): Couldn't find any mobile '%s' currently in the room to load the object onto.", name); return false; } int wear_loc= flag_value( wear_location_types, argument ); if(wear_loc==NO_FLAG){ ch->printlnf("redit_oreset(): Invalid wear_loc '%s'", argument); ch->println("Valid wear locations include:"); show_olc_flags_types(ch, wear_location_types); ch->printlnf("%s (%d) has wear flags: [%s]", capitalize( pObjIndex->short_descr ), pObjIndex->vnum, flag_string( wear_flags, pObjIndex->wear_flags ) ); return false; } // Disallow loading a sword(WEAR_WIELD) into WEAR_HEAD. if ( !IS_SET( pObjIndex->wear_flags, wear_bit(wear_loc) ) ) { ch->printlnf("redit_oreset(): %s (%d) has wear flags: [%s]", capitalize( pObjIndex->short_descr ), pObjIndex->vnum, flag_string( wear_flags, pObjIndex->wear_flags ) ); return false; } // Can't load into same position. if ( get_eq_char( to_mob, wear_loc ) ) { ch->printlnf( "redit_oreset(): The '%s' wear location is already in use.", argument); return false; } { // create the object onto mobile reset 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); olevel = URANGE( 0, to_mob->level - 2, LEVEL_HERO ); if ( to_mob->pIndexData->pShop ) // Shop-keeper? { switch ( pObjIndex->item_type ) { default: olevel = 0; break; case ITEM_PILL: olevel = number_range( 0, 10 ); break; case ITEM_POTION: olevel = number_range( 0, 10 ); break; case ITEM_SCROLL: olevel = number_range( 5, 15 ); break; case ITEM_WAND: olevel = number_range( 10, 20 ); break; case ITEM_STAFF: olevel = number_range( 15, 25 ); break; case ITEM_ARMOR: olevel = number_range( 5, 15 ); break; case ITEM_WEAPON: if ( pReset->command == 'G' ){ olevel = number_range( 5, 15 ); }else{ olevel = number_fuzzy( olevel ); } break; } if ( pReset->arg2 == WEAR_NONE ){ ch->println("Automatically adding the extra 'inventory' flag to object due to the 'none' wear location onto a shopkeeper."); SET_BIT( pObjIndex->extra_flags, OBJEXTRA_INVENTORY ); } } newobj = create_object( pObjIndex); obj_to_char( newobj, to_mob ); if ( pReset->command == 'E' ){ equip_char( to_mob, newobj, pReset->arg3 ); } } ch->printlnf("%s (%d) has been loaded %s of %s (%d) and added to resets.", capitalize( pObjIndex->short_descr ), pObjIndex->vnum, flag_string( wear_location_strings_types, pReset->arg3 ), to_mob->short_descr, to_mob->pIndexData->vnum ); act( "$n has created $p!", ch, newobj, NULL, TO_ROOM ); return true; } /**************************************************************************/ // duplicate the rooms data from another // written by Kalahn - June 98 bool redit_copy(char_data *ch, char *argument) { ROOM_INDEX_DATA *pRoom; ROOM_INDEX_DATA *pSrc; // source room char arg1[MIL]; int value; argument = one_argument( argument, arg1 ); if ( !is_number( arg1 ) ) { ch->println( "Syntax: rcopy <source room vnum>" ); ch->println( " - copies the source room over the room you are currently editing!" ); ch->println( " Apart from exits, room specials and resets at this stage." ); ch->println( " (warning copies over everything else!)" ); return false; } value = atoi( arg1 ); if ( !( pSrc = get_room_index( value ) ) ) { ch->println( "REdit_copy: The source vnum does not exist." ); return false; } if ( !IS_BUILDER( ch, pSrc->area, BUILDRESTRICT_ROOMS ) && !IS_IMMORTAL(ch)) { ch->println( "Insufficient security to copy rooms from the area that room is stored in." ); return false; } // needs to deal with ROOM_SPEC_DATA // - whole spec data system needs to be supported by olc // - doesn't copy resets // ROOM_SPEC_DATA * spec_data; // RESET_DATA * reset_first; // RESET_DATA * reset_last; EDIT_ROOM(ch, pRoom); // copy the object details pRoom->name = str_dup(pSrc->name); pRoom->description = str_dup(pSrc->description); pRoom->owner = str_dup(pSrc->owner); pRoom->room_flags = pSrc->room_flags; pRoom->sector_type = pSrc->sector_type; pRoom->heal_rate = pSrc->heal_rate; pRoom->mana_rate = pSrc->mana_rate; pRoom->clan = pSrc->clan; // COPY THE EXTENDED DESCRIPTIONS pRoom->extra_descr = dup_extdescr_list(pSrc->extra_descr); ch->wraplnf( "`=rCopied room '%s'[%d] to vnum %d", pSrc->name, pSrc->vnum, pRoom->vnum); return true; } /**************************************************************************/ bool redit_owner( char_data *ch, char * argument) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); if(IS_NULLSTR(argument)){ ch->println( "Syntax: owner [owner]" ); ch->println( " owner none" ); return false; } if (!str_cmp(argument, "none")){ ch->printlnf("Owner cleared - was '%s'", pRoom->owner); replace_string(pRoom->owner, ""); }else{ ch->printlnf("Owner changed from '%s' to '%s'", pRoom->owner, argument); replace_string(pRoom->owner, argument ); } return true; } /**************************************************************************/ /**************************************************************************/ bool redit_rlist( char_data *ch, char * argument) { ROOM_INDEX_DATA *pRoomIndex; AREA_DATA *pArea; char buf [ MSL ]; BUFFER *buf1; char arg [ MIL ]; bool found; int vnum; int col = 0; if (!HAS_SECURITY(ch,1)) { ch->println("The olist command is an olc command, you dont have olc permissions." ); return false; } if ( !IS_BUILDER( ch, ch->in_room->area, BUILDRESTRICT_ROOMS ) && IS_IMMORTAL(ch)) { ch->println( "rlist: Invalid security for listing rooms in this area." ); return false; } one_argument( argument, arg ); pArea = ch->in_room->area; buf1=new_buf(); /* buf1[0] = '\0'; */ found = false; for ( vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++ ) { if ( ( pRoomIndex = get_room_index( vnum ) ) ) { found = true; sprintf( buf, CC"x[%5d] %-17.16s", vnum, capitalize( pRoomIndex->name ) ); add_buf( buf1, buf ); if ( ++col % 3 == 0 ) add_buf( buf1, "\r\n" ); } } if ( !found ) { ch->println( "Room(s) not found in this area." ); return false; } if ( col % 3 != 0 ) add_buf( buf1, "\r\n" ); ch->sendpage(buf_string(buf1)); free_buf(buf1); return false; } /**************************************************************************/ DECLARE_DO_FUN( do_mlist ); /**************************************************************************/ bool redit_mlist( char_data *ch, char * argument) { do_mlist(ch, argument); return false; } /**************************************************************************/ DECLARE_DO_FUN( do_olist ); /**************************************************************************/ bool redit_olist( char_data *ch, char * argument) { do_olist(ch, argument); return false; } /**************************************************************************/ bool redit_room( char_data *ch, char * argument) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); return olc_generic_flag_toggle(ch, argument, "room", "room", room_flags, &pRoom->room_flags); } /**************************************************************************/ bool redit_room2( char_data *ch, char * argument) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); return olc_generic_flag_toggle(ch, argument, "room2", "room2", room2_flags, &pRoom->room2_flags); } /**************************************************************************/ bool redit_sector( char_data *ch, char * argument) { int value; ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); if(IS_NULLSTR(argument)){ show_olc_options(ch, sector_types, "sector", "sector", pRoom->sector_type); return false; } if ( ( value = flag_value( sector_types, argument) ) != NO_FLAG ) { pRoom->sector_type = value; ch->println( "Sector type set." ); return true; } return false; } /**************************************************************************/ bool redit_msp_roomsound(char_data *ch, char *argument) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); if ( IS_NULLSTR( argument )) { ch->println("Syntax: `=Cmspsound [string]`x"); ch->println(" `=Cmspsound -`x clears the value\r\n"); ch->println(" Associates the .wav or .mid [string] to appropriate skill/spell."); ch->println(" Will only accept existing filenames residing in the msp dir."); return false; } free_string( pRoom->msp_sound ); if(strcmp(argument,"-")) { if ( file_exists( MSP_DIR"%s", argument )) { pRoom->msp_sound = str_dup( argument ); ch->println("MSP Sound set sucessfully."); return true; } else { ch->println("MSP file not found."); return false; } }else{ pRoom->msp_sound = NULL; ch->println("MSP Sound cleared."); } return true; } /**************************************************************************/ void do_aroomlist(char_data *ch, char *argument ) { ROOM_INDEX_DATA *pRoomIndex; AREA_DATA *pArea; char arg0[MIL]; char arg1[MIL]; int vlowrange = 0; int vhighrange = 0; int numrooms = 0; int vnum; bool args = false; if (!HAS_SECURITY(ch,1)) { ch->printf("The aroomlist command is an olc command, " "you dont have olc permissions.\r\n" ); return; } argument = one_argument( argument, arg0 ); argument = one_argument( argument, arg1 ); if ( !IS_BUILDER( ch, ch->in_room->area, BUILDRESTRICT_ROOMS ) && !IS_IMMORTAL(ch)) { ch->println("aroomlist: Invalid security for viewing rooms in this area."); return; } pArea = ch->in_room->area; // Argument and dummy checks if ( !IS_NULLSTR( arg0 ) && !IS_NULLSTR( arg1 )) { vlowrange = atoi( arg0 ); vhighrange = atoi( arg1 ); args = true; if ( vlowrange < pArea->min_vnum || vlowrange > pArea->max_vnum ) { ch->printlnf("aroomlist: Vnum value %d isn't within this area.", vlowrange ); return; } else if ( vhighrange < pArea->min_vnum || vhighrange > pArea->max_vnum ) { ch->printlnf("aroomlist: Vnum value %d isn't within this area.", vhighrange ); return; } else if ( vlowrange > vhighrange ) { ch->println("aroomlist: Vnum 1 must be less than Vnum 2."); return; } } if ( vlowrange < 1 ) vlowrange = pArea->min_vnum; if ( vhighrange < 1 ) vhighrange = (UMIN( pArea->max_vnum, ( vlowrange + 100 ))-1); ch->printf("`x"// " L N I S N N N N A N N N\r\n" " D I O N P S L O H E O O N O O O\r\n" " A G M D R A T P R I I E W L W O S T S F S\r\n" " R H O R I F R E C M M R B A H O C I P L C\r\n" " VNUMS K T B S V E Y T L P M O I W R C R M K Y N SECTOR NAME\r\n" ); for ( vnum = vlowrange; vnum <= vhighrange; vnum++ ) { if ( ( pRoomIndex = get_room_index( vnum ) ) ) { ch->printf(" %-5d ", pRoomIndex->vnum); ch->printlnf("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %-7s %-10s", IS_SET( pRoomIndex->room_flags, ROOM_DARK ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_LIGHT ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_NO_MOB ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_INDOORS ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_PRIVATE ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_SAFE ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_SOLITARY ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_PET_SHOP ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_NO_RECALL ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_IMP_ONLY ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_GODS_ONLY ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_HEROES_ONLY ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_NEWBIES_ONLY ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_LAW ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_NOWHERE ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_OOC ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_NOSCRY ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_ANTIMAGIC ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_NOSPEAK ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_NOFLY ) ? "x" : " " , IS_SET( pRoomIndex->room_flags, ROOM_NOSCAN ) ? "x" : " " , flag_string( sector_types, pRoomIndex->sector_type ), !IS_NULLSTR( pRoomIndex->name) ? pRoomIndex->name : "(UNNAMED)"); numrooms++; } } ch->printlnf("\r\nTotal rooms: %d", numrooms ); if ( !args && numrooms == 100 ) ch->println("`ROnly the first 100 vnums were shown.\r\nTry using aroomlist <vnum1> <vnum2> to see a better range..."); return; } /**************************************************************************/ void do_setrooms(char_data *ch, char *argument ) { ROOM_INDEX_DATA *pRoom = NULL; AREA_DATA *pArea; bool adding = false, sector = false; bool heal = false, mana = false; char arg0[MIL]; // 0 cause I added it last and didn't want to change things :) char arg1[MIL]; char arg2[MIL]; char arg3[MIL]; int value; int vnum; int lowvnum; int highvnum; argument = one_argument( argument, arg0 ); argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); argument = one_argument( argument, arg3 ); if (!HAS_SECURITY(ch,1)) { ch->println( "The setrooms command is an olc command, " "you dont have olc permissions." ); return; } if ( !IS_BUILDER( ch, ch->in_room->area, BUILDRESTRICT_ROOMS ) && !IS_IMMORTAL(ch)) { ch->println( "setrooms: Invalid security for setting rooms in this area." ); return; } if ( IS_NULLSTR( arg0 ) || IS_NULLSTR( arg1 ) || IS_NULLSTR( arg2 ) || IS_NULLSTR( arg3 )) { ch->println( "Syntax: setrooms add <vnum1> <vnum2> <roomflag>" ); ch->println( "Syntax: setrooms remove <vnum1> <vnum2> <roomflag>" ); ch->println( "Syntax: setrooms sector <vnum1> <vnum2> <value>" ); ch->println( "Syntax: setrooms heal <vnum1> <vnum2> <value>" ); ch->println( "Syntax: setrooms mana <vnum1> <vnum2> <value>" ); return; } pArea = ch->in_room->area; lowvnum = atoi( arg1 ); highvnum = atoi( arg2 ); // determine if we are adding or removing if ( !str_cmp( arg0, "add" )) { adding= true; } else if ( !str_cmp( arg0, "remove" )) { adding= false; } else if ( !str_cmp( arg0, "sector" )) { sector = true; } else if ( !str_cmp( arg0, "heal" )) { heal = true; } else if ( !str_cmp( arg0, "mana" )) { mana = true; } else { ch->println( "Syntax: setrooms <`=Cadd`x/`=Cremove`x/`=Csector`x/`=Cheal`x/`=Cmana`x> <vnum1> <vnum2> <value>" ); ch->println( " use add or remove for roomflags." ); return; } // Filter out bad vnum1 and vnum2 ranges if ( lowvnum >= highvnum ) { ch->println("`RError:`x vnum1 must be lower than vnum2."); return; } if ( lowvnum < pArea->min_vnum ) { ch->println("`RError:`x vnum1 is lower than the lowest vnum of this area."); ch->printlnf(" vnum1 must be at least %d, '%s' is not.", pArea->min_vnum, arg1 ); return; } if ( highvnum > pArea->max_vnum ) { ch->println("`RError:`x vnum2 is higher than the highest vnum of this area."); ch->printlnf(" vnum2 must be at lower than or equal to %d, '%s' is not.", pArea->max_vnum, arg1); return; } // see if arg0 is sector, if it is value must be a valid sector type if ( sector ) { if (( value = sector_lookup( arg3 )) < 0 ) { ch->printlnf( "`RError:`x %s is not a valid sector type.", arg3 ); return; } } else if ( mana || heal ) { value = atoi( arg3 ); } else { value = flag_value( room_flags, arg3 ); // Check if arg3 is a valid room flag if ( value == NO_FLAG ) { ch->printlnf("`RError:`x %s in not a valid room flag.", arg3 ); return; } } for ( vnum = lowvnum; vnum <= highvnum; vnum++ ) { pRoom = get_room_index( vnum ); if(!pRoom){ continue; } if ( sector ) { pRoom->sector_type = value; SET_BIT( pRoom->area->olc_flags, OLCAREA_CHANGED ); continue; } if ( heal ) { pRoom->heal_rate = value; SET_BIT( pRoom->area->olc_flags, OLCAREA_CHANGED ); continue; } if ( mana ) { pRoom->mana_rate = value; SET_BIT( pRoom->area->olc_flags, OLCAREA_CHANGED ); continue; } if ( adding ){ SET_BIT( pRoom->room_flags, value ); SET_BIT( pRoom->area->olc_flags, OLCAREA_CHANGED ); }else{ REMOVE_BIT( pRoom->room_flags, value ); SET_BIT( pRoom->area->olc_flags, OLCAREA_CHANGED ); } } ch->println( "Done." ); return; } /**************************************************************************/ // Kal bool redit_addecho( char_data *ch, char * argument) { if ( IS_NULLSTR(argument)){ ch->println( "Syntax: addecho <firsthour> <secondhour> <percentage> echotext" ); ch->println( "For the echotext to be displayed to all in the room the following must be met."); ch->println( "IC time hour is inbetween <firsthour> and <secondhour> (inclusive)." ); ch->println( "A random number between 1 and 100 must be less than or equal to <percentage>" ); ch->println( "e.g. addecho 19 22 10 a owl hoots in the distance."); ch->println( " (will be displayed from 7pm to 10pm 10% of the time on the tick)" ); ch->println( "e.g. addecho 7 5 3 a bird sings. "); ch->println( " (will be displayed from 7am thru to 5am the next day 3% of the time on the tick)" ); return false; } ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); char low[MIL]; char high[MIL]; char percentage[MIL]; argument=one_argument(argument, low); argument=one_argument(argument, high); argument=one_argument(argument, percentage); if(IS_NULLSTR(argument)){ redit_addecho(ch,""); return false; } if(!is_number(low) || !is_number(high) || !is_number(percentage)){ ch->println("<firsthour> <lasthour> and <percentage> must all be numbers"); redit_addecho(ch,""); return false; } int ilow=atoi(low); int ihigh=atoi(high); int ipercentage=atoi(percentage); if(ilow<0 || ilow>23 || ihigh<0 || ihigh>23){ ch->println("<firsthour> and <lasthour> must be between 0 and 23 (0=midnight, 23= 11pm)"); redit_addecho(ch,""); return false; } if(ipercentage<1 ||ipercentage>100){ ch->println("<percentage> must be between 1 and 100."); redit_addecho(ch,""); return false; } // allocate our new echo room_echo_data *re=new_room_echo(); replace_string(re->echotext, argument); re->firsthour=ilow; re->lasthour=ihigh; re->percentage=ipercentage; // add to the list of echos re->next=pRoom->echoes; pRoom->echoes=re; ch->printlnf( "RoomEcho %d(%s) %d(%s) %d%% '%s' added.", re->firsthour, convert24hourto12hour(re->firsthour), re->lasthour, convert24hourto12hour(re->lasthour), re->percentage, re->echotext); ch->println( "Use `=Cdelecho`x to remove room echoes"); return true; } /**************************************************************************/ // Kal bool redit_delecho(char_data *ch, char *argument) { if ( IS_NULLSTR(argument)){ ch->println( "Syntax: delecho <echo#>" ); ch->println( "Removes a room echo listed in olc's redit show."); ch->println( "<echo#> is the number of the echo in the list." ); return false; } ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); char num[MIL]; one_argument( argument, num); if (IS_NULLSTR(num) || !is_number( num)) { ch->println("The single parameter must be a number"); redit_delecho(ch, ""); return false; } int value = atoi(num); if(value < 0){ ch->println("Only positive room echo numbers are valid ."); return false; } if( !pRoom->echoes){ ch->println("This room doesn't have any echos to remove."); return false; } // remove the room echo room_echo_data *list; room_echo_data *list_next; int cnt = 0; list = pRoom->echoes; if ( value == 0 ){ pRoom->echoes= list->next; free_room_echo( list ); }else{ while ( (list_next = list->next) && (++cnt < value ) ) list = list_next; if(list_next) { list->next = list_next->next; free_room_echo(list_next); } else { ch->printlnf("No room echo number %d.", value); return false; } } ch->printlnf("Room echo %d removed", value); return true; } /**************************************************************************/ // show which rooms/objects link to this room - Kal bool redit_usedby( char_data *ch, char * ) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); int i; ch->titlebarf("ROOMS WITH EXITS LEADING INTO ROOM %d", pRoom->vnum); for(i=0; i<MAX_KEY_HASH; i++){ for(ROOM_INDEX_DATA *r= room_index_hash[i]; r; r= r->next ) { for ( int door = 0; door < MAX_DIR; door++ ) { if ( r->exit[door] && r->exit[door]->u1.to_room==pRoom) { ch->printlnf("`x Room %5d leads %s into %d (from area '%s%s`x')", r->vnum, dir_name[door], pRoom->vnum, colour_table[(r->area->vnum%14)+1].code, r->area->name); } } } } ch->titlebarf("PORTALS LEADING INTO ROOM %d", pRoom->vnum); for(i=0; i<MAX_KEY_HASH; i++){ for(OBJ_INDEX_DATA *o= obj_index_hash[i]; o; o= o->next ) { if(o->item_type==ITEM_PORTAL && o->value[3]==pRoom->vnum){ ch->printlnf(" Object %5d is a portal which leads to %d (from area '%s%s`x')", o->vnum, pRoom->vnum, get_vnum_area(o->vnum)?colour_table[(get_vnum_area(o->vnum)->vnum%14)+1].code:"", get_vnum_area(o->vnum)?get_vnum_area(o->vnum)->name:"unknown"); } } } ch->titlebar(""); return false; } /**************************************************************************/ bool redit_delete( char_data *ch, char *) { ch->println("If you want to delete a room, use the 'rdelete' command"); return false; } /**************************************************************************/ // redit room delete code - Kal, Jan 2001 bool redit_rdelete( char_data *ch, char *argument ) { ROOM_INDEX_DATA *pRoom; ROOM_INDEX_DATA *pDeleteRoom; EDIT_ROOM(ch, pRoom); int no_delete_count=0; int door; int i; if(IS_NULLSTR(argument)){ ch->titlebar("RDELETE SYNTAX"); ch->println("rdelete confirm - delete the current room"); ch->println("rdelete <number> confirm - delete room vnum <number>"); ch->println("Any room that you delete must meet the following conditions:"); ch->println("* Must be in the same area that you are current editing."); ch->println("* Must have no rooms leading into it from outside the current area."); ch->println("* Must not have any portals leading into the room."); ch->println("* Must not have any lockers."); ch->println("* No players are in the room you are deleting (except you)."); ch->println("* Room must not be a pet shop container room (previous room having pet_shop flag)."); ch->println("* None of the game setting vnums make use of the room."); ch->println("If you are in the room when you delete it... you will be moved to another room in the area."); ch->wrapln("NOTE: It is strongly recommended that you check no mobprogs transfer into the room " "you are wanting to remove... the easiest method to do this is 'textsearch mobprog <roomvnum>'."); return false; } // support specifying the room by number char arg1[MIL]; argument=one_argument(argument, arg1); if(is_number(arg1)){ pDeleteRoom=get_room_index(atoi(arg1)); if(!pDeleteRoom){ ch->printlnf("redit_rdelete(): There is no room number %s to delete.", arg1); return false; } if(pDeleteRoom->area!=pRoom->area){ ch->printlnf("redit_rdelete(): Room %s (%s) is not in the same area as the room you are currently editing.", arg1, pDeleteRoom->name); return false; } argument=one_argument(argument, arg1); // put the word 'confirm' into arg1 }else{ pDeleteRoom=pRoom; // deleting the room we are currently in } // security check if ( !IS_BUILDER( ch, pDeleteRoom->area, BUILDRESTRICT_ROOMS) ){ ch->printlnf( "Insufficient security to delete room %d.", pDeleteRoom->vnum ); return false; } // confirm they are using 'confirm' if(str_cmp(arg1, "confirm")){ ch->println("You must confirm your intention to delete a room."); redit_rdelete(ch,""); return false; } if(!IS_NULLSTR(ltrim_string(argument))){ ch->println("Incorrect syntax - too many arguments, or arguments in wrong order."); redit_rdelete(ch, ""); return false; } // We have the room they are wanting to delete and they have // confirmed they want to delete it, check they are allowed. // ch->println("* Must have no rooms leading into it from outside the current area."); for(i=0; i<MAX_KEY_HASH; i++){ for(ROOM_INDEX_DATA *r= room_index_hash[i]; r; r= r->next ) { for ( door = 0; door < MAX_DIR; door++ ) { if ( r->exit[door] && r->exit[door]->u1.to_room==pRoom && r->area!=pRoom->area) { ch->printlnf("`x Room %5d leads %s into %d (from area '%s%s`x')", r->vnum, dir_name[door], pRoom->vnum, colour_table[(r->area->vnum%14)+1].code, r->area->name); no_delete_count++; } } } } // ch->println("* Must not have any portals leading into the room."); for(i=0; i<MAX_KEY_HASH; i++){ for(OBJ_INDEX_DATA *o= obj_index_hash[i]; o; o= o->next ) { if(o->item_type==ITEM_PORTAL && o->value[3]==pRoom->vnum){ ch->printlnf(" Object %5d is a portal which leads to %d (from area '%s%s`x')", o->vnum, pRoom->vnum, get_vnum_area(o->vnum)?colour_table[(get_vnum_area(o->vnum)->vnum%14)+1].code:"", get_vnum_area(o->vnum)?get_vnum_area(o->vnum)->name:"unknown"); no_delete_count++; } } } // ch->println("* No players are in the room you are deleting."); for(char_data *p=pDeleteRoom->people; p; p=p->next_in_room){ if(!IS_NPC(p) && p!=ch){ ch->printlnf("%s is in room %d", PERS(p, ch), pDeleteRoom->vnum); no_delete_count++; } } // ch->println("* Must not have any lockers."); if(pDeleteRoom->lockers){ ch->printlnf("room %d has some lockers assigned.", pDeleteRoom->vnum); no_delete_count++; } // ch->println("* Room must not be a pet shop container room (previous room having pet_shop flag)."); { int petshop_vnum=pDeleteRoom->vnum-1; if(get_room_index(petshop_vnum) && IS_SET(get_room_index(petshop_vnum)->room_flags, ROOM_PET_SHOP)){ ch->printlnf("Previous room (%d - %s) is a pet shop!", petshop_vnum, get_room_index(petshop_vnum)->name); no_delete_count++; } } // ch->println("* None of the game setting vnums make use of the room."); for(i=0; !IS_NULLSTR(gameset_value[i].name); i++){ if(gameset_value[i].category!=GSVC_ROOM){ continue; } // get our numeric value int value=GSINT(gameset_value[i].offset); if(value==pDeleteRoom->vnum){ ch->printlnf("Game setting value '%s (%s)' makes use of room %d.", gameset_value[i].name, gameset_value[i].description, value); no_delete_count++; } } if(no_delete_count){ ch->printlnf("The reason%s listed above prevent%s room %d from being deleted.", (no_delete_count==1?"":"s"), (no_delete_count==1?"s":""), pDeleteRoom->vnum); return false; } // *** delete the room // first move them out of the room if necessary if(pRoom==pDeleteRoom){ // - look for an exit within the area for ( door = 0; door < MAX_DIR; door++ ) { if ( pRoom->exit[door] && pRoom->exit[door]->u1.to_room!=pRoom && pRoom->exit[door]->u1.to_room->area==pRoom->area) { ch->printlnf("Moving you %s to room %d", dir_name[door], pRoom->exit[door]->u1.to_room->vnum); char_from_room(ch); char_to_room(ch, pRoom->exit[door]->u1.to_room); EDIT_ROOM(ch, pRoom); break; } } // find any room in the area to move them to if(pRoom==pDeleteRoom){ for(i=pRoom->area->min_vnum; i<=pRoom->area->max_vnum; i++){ if(pRoom->vnum!=i && get_room_index(i)){ ch->printlnf("Moving you to room %d (in same area)", i); char_from_room(ch); char_to_room(ch, get_room_index(i)); EDIT_ROOM(ch, pRoom); break; } } } // move them to limbo if all else fails if(pRoom==pDeleteRoom){ ch->printlnf("Moving you to room %d (LIMBO) - couldn't find anywhere else to move you to!", ROOM_VNUM_LIMBO); char_from_room(ch); char_to_room(ch, get_room_index(ROOM_VNUM_LIMBO)); EDIT_ROOM(ch, pRoom); edit_done(ch); } } // player definately out of pDeleteRoom, deallocate all its contents. { char_data *vnext, *victim; OBJ_DATA *obj, *obj_next; if(pDeleteRoom->people){ ch->println("Purging room mobiles..."); } for ( victim = pDeleteRoom->people; victim; victim = vnext ) { vnext = victim->next_in_room; extract_char( victim, true ); } if(pDeleteRoom->contents){ ch->println("Purging objects in room..."); } for ( obj = pDeleteRoom->contents; obj; obj = obj_next ) { obj_next = obj->next_content; extract_obj( obj ); } } // remove all the resets if(pDeleteRoom->reset_first) { ch->println("Deallocating room resets..."); reset_data *rnext, *reset; for(reset=pDeleteRoom->reset_first; reset; reset=rnext){ rnext=reset->next; free_reset_data( reset); } pDeleteRoom->reset_first=NULL; } // remove all the exits leading out of the room { bool no_exits_removed=true; for ( door = 0; door < MAX_DIR; door++ ){ if(!pDeleteRoom->exit[door]){ continue; } if(no_exits_removed){ ch->println("Removing exits leading out of the room..."); no_exits_removed=false; } // remove exit leading out free_exit( pDeleteRoom->exit[door] ); pDeleteRoom->exit[door]=NULL; } } // remove all the exits leading into the room { bool no_exits_removed=true; for(i=0; i<MAX_KEY_HASH; i++){ for(ROOM_INDEX_DATA *r= room_index_hash[i]; r; r= r->next ) { for ( door = 0; door < MAX_DIR; door++ ) { if ( r->exit[door] && r->exit[door]->u1.to_room==pDeleteRoom) { if(no_exits_removed){ ch->println("Removing exits leading into room..."); no_exits_removed=false; } free_exit( r->exit[door] ); r->exit[door]=NULL; } } } } } // remove all the room echoes if(pDeleteRoom->echoes) { ch->println("Removing room echoes..."); room_echo_data *echo, *echo_next; for(echo= pDeleteRoom->echoes; echo; echo=echo_next){ echo_next=echo->next; free_room_echo( echo ); } pDeleteRoom->echoes=NULL; } // remove extended descriptions if(pDeleteRoom->extra_descr) { ch->println("Removing room extra descriptions..."); EXTRA_DESCR_DATA *ed, *ec_next; for ( ed = pRoom->extra_descr; ed; ed = ec_next ){ ec_next=ed->next; free_extra_descr( ed ); } pRoom->extra_descr=NULL; } ch->println("Deleting room..."); int v=pDeleteRoom->vnum; // remove room from hash table { i=pDeleteRoom->vnum% MAX_KEY_HASH; // check if we are the first entry in the hash table if(pDeleteRoom== room_index_hash[i]){ room_index_hash[i]=room_index_hash[i]->next; }else{ ROOM_INDEX_DATA *prev=room_index_hash[i]; if(!prev){ bugf("redit_rdelete(): Trying to free room vnum %d, but not found in room_index_hash[%d]!", pDeleteRoom->vnum, i); }else{ for( ; prev->next; prev=prev->next ) { if(prev->next==pDeleteRoom){ prev->next=pDeleteRoom->next; // remove the room from the link break; } } } } } free_room_index(pDeleteRoom); top_room--; ch->printlnf("Room %d Deleted.",v); return true; } /**************************************************************************/ bool redit_setlockers( char_data *ch, char * argument) { int value; ROOM_INDEX_DATA *pRoom; EDIT_ROOM(ch, pRoom); if(IS_NULLSTR(argument)){ ch->println("Syntax : setlockers <quantity> <intitial rent> <ongoing rent> <weight> <capacity> <pickproof>" ); ch->println("<quantity> = the number of lockers in the room."); ch->println("<initial rent> = the amount of gold to be allocated a locker, and pay for the first IC months rent of it."); ch->println("<ongoing rent> = the amount of gold to pay for 1 IC years rent of the locker."); ch->println("<weight> = this is the v0 value of the locker container object."); ch->println("<capacity> = this is the v3 value of the locker container object."); ch->println("<pickproof> = 1=very hard to pick, 2=random chance it will be on purchase, 3=pickproof."); ch->println("Syntax : lockers clear - remove all room lockers." ); ch->println("Note: only admin can set lockers in a room."); return false; } if(!IS_ADMIN(ch)){ ch->println("Only admin can edit the locker configuration of a room."); return false; } // check if they are trying to clear the lockers int inuse=lockers->count_used_lockers_in_room(pRoom->vnum); if(!str_cmp(argument, "clear")){ if(inuse){ ch->printlnf("There %s currently %d locker%s in use. Manually remove these first with the 'locker delete' command.", inuse==1?"is":"are", inuse, inuse==1?"":"s"); return false; } if(!pRoom->lockers){ ch->println("There are no lockers setup in this room."); return false; } ch->println("Removing locker allocation, previous locker details:"); ch->printlnf(" quantity=%d, initial rent=%d, ongoing rent=%d, " "weight(v0)=%d, capacity(v3)=%d, pickproof=%d", pRoom->lockers->quantity, pRoom->lockers->initial_rent, pRoom->lockers->ongoing_rent, pRoom->lockers->weight, pRoom->lockers->capacity, pRoom->lockers->pick_proof); delete pRoom->lockers; pRoom->lockers=NULL; return true; } // split up the five arguments int i; char args[6][MIL]; for(i=0; i<6; i++){ argument = one_argument( argument, args[i]); if(IS_NULLSTR(args[i])){ ch->println("All six arguments must be completed."); redit_setlockers(ch,""); return false; } if(!is_number(args[i])){ ch->printlnf("All six arguments must be numeric, argument %d (%s) is not.", i+1, args[i]); redit_setlockers(ch,""); return false; } value=atoi(args[i]); if(value<1){ ch->printlnf("All six arguments must be 1 or greater, argument %d is not.", i+1); return false; } } int quantity =atoi(args[0]); int intitial_rent =atoi(args[1]); int ongoing_rent =atoi(args[2]); int weight =atoi(args[3]); int capacity =atoi(args[4]); int pickproof =atoi(args[5]); if(capacity>weight){ ch->printlnf("It makes no sense for the capacity (%d) to be greater than weight (%d).", capacity, weight); return false; } if(pickproof<1 || pickproof>3){ ch->printlnf("Pickproof setting must be in the range 1 to 3 not (%d).", pickproof); return false; } // we know all arguments are above 0, so if there are currently no lockers, we are adding some if(!pRoom->lockers){ pRoom->lockers=new locker_room_data; pRoom->lockers->quantity=0; pRoom->lockers->initial_rent=0; pRoom->lockers->ongoing_rent=0; pRoom->lockers->weight=0; pRoom->lockers->capacity=0; pRoom->lockers->pick_proof=0; } if(quantity<inuse){ ch->printlnf("There %s currently %d locker%s in use. You can not set the quantity to less than this.", value==1?"is":"are", value, value==1?"":"s"); return false; } ch->println("Changing locker allocation, previous locker details:"); ch->printlnf("Quantity=%d, initial rent=%d, ongoing rent=%d, " "weight(v0)=%d, capacity(v3)=%d, pickproof=%d", pRoom->lockers->quantity, pRoom->lockers->initial_rent, pRoom->lockers->ongoing_rent, pRoom->lockers->weight, pRoom->lockers->capacity, pRoom->lockers->pick_proof); pRoom->lockers->quantity=quantity; pRoom->lockers->initial_rent=intitial_rent; pRoom->lockers->ongoing_rent=ongoing_rent; pRoom->lockers->weight=weight; pRoom->lockers->capacity=capacity; pRoom->lockers->pick_proof=pickproof; ch->println("Updated locker details:"); ch->printlnf("quantity=%d, initial rent=%d, ongoing rent=%d, " "weight(v0)=%d, capacity(v3)=%d, pickproof=%d", pRoom->lockers->quantity, pRoom->lockers->initial_rent, pRoom->lockers->ongoing_rent, pRoom->lockers->weight, pRoom->lockers->capacity, pRoom->lockers->pick_proof); ch->println("Note: the weight, capacity and pickproof settings of any existing lockers are unaffected."); return true; } /**************************************************************************/ /**************************************************************************/