/* *************************************************
* file: redit.cc *
* authors: Andrew Hynek, Nick Robertson, Jon Lin, *
* Phrodo, Demise, Terra, Washu *
* purpose: Room Editor for AwakeOLC, a *
* component of AwakeMUD *
* (c) 1997-1999 Andrew Hynek, (c) 2001 *
* The AwakeMUD Consortium *
************************************************* */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "structs.h"
#include "awake.h"
#include "interpreter.h"
#include "comm.h"
#include "utils.h"
#include "db.h"
#include "newdb.h"
#include "boards.h"
#include "screen.h"
#include "olc.h"
#include "memory.h"
#include "constants.h"
#include "handler.h"
extern class memoryClass *Mem;
#define ROOM d->edit_room
extern sh_int r_mortal_start_room;
extern sh_int r_immort_start_room;
extern sh_int r_frozen_start_room;
extern vnum_t r_newbie_start_room;
extern int olc_state;
extern void char_to_room(struct char_data * ch, int room);
// extern funcs
extern char *cleanup(char *dest, const char *src);
extern bool resize_world_array();
/* function protos */
void redit_disp_extradesc_menu(struct descriptor_data * d);
void redit_disp_exit_menu(struct descriptor_data * d);
void redit_disp_exit_flag_menu(struct descriptor_data * d);
void redit_disp_flag_menu(struct descriptor_data * d);
void redit_disp_sector_menu(struct descriptor_data * d);
void redit_disp_menu(struct descriptor_data * d);
void redit_parse(struct descriptor_data * d, char *arg);
void write_world_to_disk(int vnum);
/**************************************************************************
Menu functions
**************************************************************************/
void redit_disp_light_menu(struct descriptor_data *d, bool light)
{
CLS(CH);
int i = light ? 1 : 5, max = light ? 5 : 10;
send_to_char("0) Normal\r\n", CH);
for (int x = 1; i < max; i++)
send_to_char(CH, "%d) %s\r\n", x++, light_levels[i]);
send_to_char("Select Light Option: ", CH);
if (light)
d->edit_mode = REDIT_LIGHT;
else d->edit_mode = REDIT_SMOKE;
}
void redit_disp_combat_menu(struct descriptor_data *d)
{
CLS(CH);
send_to_char(CH, "1) Crowd: ^c%d^n\r\n"
"2) Cover: ^c%d^n\r\n"
"3) Room Type: ^c%s^n\r\n"
"4) X: ^c%dm^n\r\n"
"5) Y: ^c%dm^n\r\n"
"6) Z: ^c%.2fm^n\r\n"
"q) Return to previous menu\r\n"
"Select Option: ", d->edit_room->crowd, d->edit_room->cover, room_types[d->edit_room->type],
d->edit_room->x, d->edit_room->y, d->edit_room->z);
d->edit_mode = REDIT_COMBAT;
}
void redit_disp_barrier_menu(struct descriptor_data *d)
{
CLS(CH);
for (register int counter = 0; counter < NUM_BARRIERS; ++counter)
send_to_char(CH, "%2d) %s\r\n", counter + 1, barrier_names[counter]);
send_to_char("Enter construction category, 0 to return: ", CH);
}
void redit_disp_material_menu(struct descriptor_data *d)
{
CLS(CH);
for (register int counter = 0; counter < NUM_MATERIALS; ++counter)
send_to_char(CH, "%2d) %s\r\n", counter + 1, material_names[counter]);
send_to_char("Enter material type, 0 to return: ", CH);
}
/* For extra descriptions */
void redit_disp_extradesc_menu(struct descriptor_data * d)
{
struct extra_descr_data *extra_desc =
(struct extra_descr_data *) * d->misc_data;
send_to_char(CH, "Extra descript menu\r\n"
"0) Quit\r\n"
"1) Keyword: %s%s%s\r\n"
"2) Description:\r\n%s\r\n", CCCYN(CH, C_CMP),
extra_desc->keyword, CCNRM(CH, C_CMP),
(extra_desc->description ? extra_desc->description : "(none)"));
send_to_char(CH, "3) %s\r\n"
"Enter Choice:\r\n",
(extra_desc->next ? "Another description set. (not viewed)" : "Another description"));
d->edit_mode = REDIT_EXTRADESC_MENU;
}
/* For exits */
void redit_disp_exit_menu(struct descriptor_data * d)
{
CLS(CH);
#define DOOR d->edit_room->dir_option[d->edit_number2]
/* if exit doesn't exist, alloc/create it and clear it*/
if(!DOOR)
{
DOOR = new room_direction_data;
memset((char *) DOOR, 0, sizeof (struct room_direction_data));
DOOR->barrier = 4;
DOOR->condition = DOOR->barrier;
DOOR->material = 5;
}
send_to_char(CH, "1) Exit to: %s%d%s\r\n"
"2) Description: %s\r\n",
CCCYN(CH, C_CMP), DOOR->to_room_vnum, CCNRM(CH, C_CMP),
(DOOR->general_description ? DOOR->general_description : "(None)"));
send_to_char(CH, "3) Door names: %s%s%s\r\n"
"4) Key vnum: %s%d%s\r\n"
"5) Door flag: %s%s%s\r\n",
CCCYN(CH, C_CMP), (DOOR->keyword ? DOOR->keyword : "(none)"),
CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), DOOR->key, CCNRM(CH, C_CMP),
CCCYN(CH, C_CMP), (IS_SET(DOOR->exit_info, EX_ISDOOR) ?
(IS_SET(DOOR->exit_info, EX_PICKPROOF) ? "Pickproof" : "Regular door") :
"No door"), CCNRM(CH, C_CMP));
send_to_char(CH, "6) Lock level: %s%d%s\r\n"
"7) Material Type: %s%s%s\r\n"
"8) Barrier Rating: %s%d%s\r\n",
CCCYN(CH, C_CMP), DOOR->key_level,
CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), material_names[(int)DOOR->material],
CCNRM(CH, C_CMP), CCCYN(CH, C_CMP), DOOR->barrier, CCNRM(CH, C_CMP));
send_to_char(CH, "9) Hidden Rating: %s%d%s\r\n"
"a) Purge exit.\r\n"
"Enter choice, 0 to quit:",
CCCYN(CH, C_CMP), DOOR->hidden, CCNRM(CH, C_CMP));
d->edit_mode = REDIT_EXIT_MENU;
}
/* For exit flags */
void redit_disp_exit_flag_menu(struct descriptor_data * d)
{
send_to_char( "0) No door\r\n"
"1) Closeable door\r\n"
"2) Pickproof\r\n"
"Enter choice:", CH);
}
/* For jackpoint */
void redit_disp_mtx_menu(struct descriptor_data * d)
{
CLS(CH);
send_to_char(CH, "0) To Host: ^c%ld^n\r\n", d->edit_room->matrix);
send_to_char(CH, "1) Access Mod: ^c%d^n\r\n", d->edit_room->access);
send_to_char(CH, "2) Trace Mod: ^c%d^n\r\n", d->edit_room->trace);
send_to_char(CH, "3) I/O Speed: ^c%d^n\r\n", d->edit_room->io);
send_to_char(CH, "4) Base Bandwidth: ^c%d^n\r\n", d->edit_room->bandwidth);
send_to_char(CH, "5) Parent RTG: ^c%ld^n\r\n", d->edit_room->rtg);
send_to_char(CH, "6) Commlink Number: ^c%d^n\r\n", d->edit_room->jacknumber);
send_to_char(CH, "7) Physical Address: ^c%s^n\r\n", d->edit_room->address);
send_to_char(CH, "q) Return to Main Menu\r\nEnter Choice: ");
d->edit_mode = REDIT_MATRIX;
}
/* For room flags */
void redit_disp_flag_menu(struct descriptor_data * d)
{
int counter;
CLS(CH);
for (counter = 0; counter < ROOM_MAX; counter += 2)
{
send_to_char(CH, "%2d) %-10s %2d) %-10s\r\n",
counter + 1, room_bits[counter],
counter + 2, counter + 1 < ROOM_MAX ?
room_bits[counter + 1] : "");
}
ROOM->room_flags.PrintBits(buf1, MAX_STRING_LENGTH, room_bits, ROOM_MAX);
send_to_char(CH, "Room flags: %s%s%s\r\n"
"Enter room flags, 0 to quit:", CCCYN(CH, C_CMP),
buf1, CCNRM(CH, C_CMP));
d->edit_mode = REDIT_FLAGS;
}
/* for sector type */
void redit_disp_sector_menu(struct descriptor_data * d)
{
int counter;
CLS(CH);
for (counter = 0; counter < NUM_SPIRITS; counter += 2)
{
sprintf(buf, "%2d) %-10s %2d) %-10s\r\n",
counter, spirits[counter].name,
counter + 1, counter + 1 < NUM_SPIRITS ?
spirits[counter + 1].name : "");
send_to_char(buf, d->character);
}
send_to_char("Enter domain:", d->character);
d->edit_mode = REDIT_SECTOR;
}
/* the main menu */
void redit_disp_menu(struct descriptor_data * d)
{
CLS(CH);
d->edit_mode = REDIT_MAIN_MENU;
send_to_char(CH, "Room number: %s%d%s\r\n"
"1) Room name: %s%s%s\r\n",
CCCYN(CH, C_CMP),
d->edit_number, CCNRM(CH, C_CMP),
CCCYN(CH, C_CMP), d->edit_room->name, CCNRM(CH, C_CMP));
send_to_char(CH, "2) Room Desc:\r\n%s\r\n", d->edit_room->description);
send_to_char(CH, "3) Night Desc: \r\n%s\r\n", d->edit_room->night_desc);
send_to_char(CH, "Room zone: %s%d%s\r\n",
CCCYN(CH, C_CMP),
zone_table[d->edit_room->zone].number,
CCNRM(CH, C_CMP));
ROOM->room_flags.PrintBits(buf2, MAX_STRING_LENGTH, room_bits, ROOM_MAX);
send_to_char(CH, "4) Room flags: %s%s%s\r\n",
CCCYN(CH, C_CMP),
buf2, CCNRM(CH,
C_CMP));
sprinttype(d->edit_room->sector_type, spirit_name, buf2);
send_to_char(CH, "5) Domain type: %s%s%s\r\n",CCCYN(CH, C_CMP), buf2, CCNRM(CH, C_CMP));
if (d->edit_room->dir_option[NORTH])
send_to_char(CH, "6) Exit north to: %s%d%s\r\n", CCCYN(CH, C_CMP),
d->edit_room->dir_option[NORTH]->to_room_vnum, CCNRM(CH, C_CMP));
else
send_to_char( "6) Exit north to: (none)\r\n", CH);
if (d->edit_room->dir_option[NORTHEAST])
send_to_char(CH, "7) Exit northeast to: %s%d%s\r\n", CCCYN(CH, C_CMP),
d->edit_room->dir_option[NORTHEAST]->to_room_vnum, CCNRM(CH, C_CMP));
else
send_to_char( "7) Exit northeast to: (none)\r\n", CH);
if (d->edit_room->dir_option[EAST])
send_to_char(CH, "8) Exit east to: %s%d%s\r\n", CCCYN(CH, C_CMP),
d->edit_room->dir_option[EAST]->to_room_vnum, CCNRM(CH, C_CMP));
else
send_to_char( "8) Exit east to: (none)\r\n", CH);
if (d->edit_room->dir_option[SOUTHEAST])
send_to_char(CH, "9) Exit southeast to: %s%d%s\r\n", CCCYN(CH, C_CMP),
d->edit_room->dir_option[SOUTHEAST]->to_room_vnum, CCNRM(CH, C_CMP));
else
send_to_char( "9) Exit southeast to: (none)\r\n", CH);
if (d->edit_room->dir_option[SOUTH])
send_to_char(CH, "a) Exit south to: %s%d%s\r\n", CCCYN(CH, C_CMP),
d->edit_room->dir_option[SOUTH]->to_room_vnum, CCNRM(CH, C_CMP));
else
send_to_char( "a) Exit south to: (none)\r\n", CH);
if (d->edit_room->dir_option[SOUTHWEST])
send_to_char(CH, "b) Exit southwest to: %s%d%s\r\n", CCCYN(CH, C_CMP),
d->edit_room->dir_option[SOUTHWEST]->to_room_vnum, CCNRM(CH, C_CMP));
else
send_to_char( "b) Exit southwest to: (none)\r\n", CH);
if (d->edit_room->dir_option[WEST])
send_to_char(CH, "c) Exit west to: %s%d%s\r\n", CCCYN(CH, C_CMP),
d->edit_room->dir_option[WEST]->to_room_vnum, CCNRM(CH, C_CMP));
else
send_to_char( "c) Exit west to: (none)\r\n", CH);
if (d->edit_room->dir_option[NORTHWEST])
send_to_char(CH, "d) Exit northwest to: %s%d%s\r\n", CCCYN(CH, C_CMP),
d->edit_room->dir_option[NORTHWEST]->to_room_vnum, CCNRM(CH, C_CMP));
else
send_to_char( "d) Exit northwest to: (none)\r\n", CH);
if (d->edit_room->dir_option[UP])
send_to_char(CH, "e) Exit up to: %s%d%s\r\n", CCCYN(CH, C_CMP),
d->edit_room->dir_option[UP]->to_room_vnum, CCNRM(CH, C_CMP));
else
send_to_char( "e) Exit up to: (none)\r\n", CH);
if (d->edit_room->dir_option[DOWN])
send_to_char(CH, "f) Exit down to: %s%d%s\r\n", CCCYN(CH, C_CMP),
d->edit_room->dir_option[DOWN]->to_room_vnum, CCNRM(CH, C_CMP));
else
send_to_char( "f) Exit down to: (none)\r\n", CH);
send_to_char( "g) Edit Jackpoint\r\n", CH);
send_to_char(CH, "h) Light Level: ^c%s^n\r\n", light_levels[d->edit_room->vision[0]]);
send_to_char(CH, "i) Smoke Level: ^c%s^n\r\n", light_levels[d->edit_room->vision[1]]);
send_to_char(CH, "j) Combat Options: Crowd (^c%d^n) Cover: (^c%d^n) Room Type: (^c%s^n) X: (^c%d^n) Y: (^c%d^n) Z: (^c%.2f^n)\r\n",
d->edit_room->crowd, d->edit_room->cover, room_types[d->edit_room->type], d->edit_room->x, d->edit_room->y, d->edit_room->z);
send_to_char(CH, "k) Background Count: ^c%d (%s)^n\r\n", d->edit_room->background[0], background_types[d->edit_room->background[1]]);
send_to_char(CH, "l) Extra descriptions\r\n", d->character);
if (d->edit_room->sector_type == SPIRIT_LAKE || d->edit_room->sector_type == SPIRIT_SEA ||
d->edit_room->sector_type == SPIRIT_RIVER)
send_to_char(CH, "m) Current rating: %s%d%s\r\n", CCCYN(CH, C_CMP),
ROOM->rating, CCNRM(CH, C_CMP));
send_to_char("q) Quit and save\r\n", d->character);
send_to_char("x) Exit and abort\r\n", d->character);
send_to_char("Enter your choice:\r\n", d->character);
}
/**************************************************************************
The main loop
**************************************************************************/
void redit_parse(struct descriptor_data * d, char *arg)
{
extern struct room_data *world;
SPECIAL(cpu);
SPECIAL(datastore);
SPECIAL(input_output);
SPECIAL(spu);
SPECIAL(system_access);
SPECIAL(slave);
int number;
int room_num;
switch (d->edit_mode)
{
case REDIT_CONFIRM_EDIT:
switch (*arg) {
case 'y':
case 'Y':
// put the allocation over here!
redit_disp_menu(d);
break;
case 'n':
case 'N':
/* player doesn't want to edit, free entire temp room */
STATE(d) = CON_PLAYING;
if (d->edit_room)
Mem->DeleteRoom(d->edit_room);
d->edit_room = NULL;
PLR_FLAGS(d->character).RemoveBit(PLR_EDITING);
char_to_room(CH, GET_WAS_IN(CH));
GET_WAS_IN(CH) = NOWHERE;
break;
default:
send_to_char("That's not a valid choice!\r\n", d->character);
send_to_char("Do you wish to edit it?\r\n", d->character);
break;
}
break; /* end of REDIT_CONFIRM_EDIT */
case REDIT_CONFIRM_SAVESTRING:
switch (*arg) {
case 'y':
case 'Y': {
int counter2;
if (!from_ip_zone(d->edit_number)) {
sprintf(buf,"%s wrote new room #%ld",
GET_CHAR_NAME(d->character), d->edit_number);
mudlog(buf, d->character, LOG_WIZLOG, TRUE);
}
room_num = real_room(d->edit_number);
if (room_num > 0) {
/* copy people/object pointers over to the temp room
as a temporary measure */
d->edit_room->contents = world[room_num].contents;
d->edit_room->people = world[room_num].people;
// we use free_room here because we are not ready to turn it over
// to the stack just yet as we are gonna use it immediately
free_room(world + room_num);
/* now copy everything over! */
world[room_num] = *d->edit_room;
} else {
/* hm, we can't just copy.. gotta insert a new room */
int counter;
int counter2;
int found = 0;
// check first if you need to resize it
if ((top_of_world + 1) >= top_of_world_array)
// if it cannot resize, free the edit_room and return
if (!resize_world_array()) {
send_to_char("Unable to save, OLC temporarily unavailable.\r\n"
,CH);
Mem->DeleteRoom(d->edit_room);
olc_state = 0;
d->edit_room = NULL;
PLR_FLAGS(d->character).RemoveBit(PLR_EDITING);
STATE(d) = CON_PLAYING;
char_to_room(CH, GET_WAS_IN(CH));
GET_WAS_IN(CH) = NOWHERE;
return;
}
/* count thru world tables */
for (counter = 0; counter < top_of_world + 1; counter++) {
if (!found) {
/* check if current virtual is bigger than our virtual */
if (world[counter].number > d->edit_number) {
// now, zoom backwards through the list copying over
for (counter2 = top_of_world + 1; counter2 > counter; counter2--) {
world[counter2] = world[counter2 - 1];
}
world[counter] = *(d->edit_room);
world[counter].number = d->edit_number;
world[counter].func = NULL;
found = TRUE;
}
} else {
// okay, it has been found and inserted
// anything in a room after the one inserted needs their
// real numbers increased
struct char_data *temp_ch;
struct obj_data *temp_obj;
struct veh_data *temp_veh;
for (temp_ch = world[counter].people; temp_ch;
temp_ch = temp_ch->next_in_room) {
if (temp_ch->in_room != NOWHERE)
temp_ch->in_room++;
}
for (temp_veh = world[counter].vehicles; temp_veh;
temp_veh = temp_veh->next_veh) {
if (temp_veh->in_room != NOWHERE)
temp_veh->in_room++;
}
/* move objects */
for (temp_obj = world[counter].contents; temp_obj;
temp_obj = temp_obj->next_content)
if (temp_obj->in_room != -1)
temp_obj->in_room++;
} // end else
} // end 'insert' for-loop
/* if place not found, insert at end */
if (!found) {
world[top_of_world + 1] = *d->edit_room;
world[top_of_world + 1].number = d->edit_number;
world[top_of_world + 1].func = NULL;
}
top_of_world++;
/* now this is the *real* room_num */
room_num = real_room(d->edit_number);
/* now zoom through the character list and update anyone in limbo */
struct char_data * temp_ch;
for (temp_ch = character_list; temp_ch; temp_ch = temp_ch->next) {
if (GET_WAS_IN(temp_ch) >= room_num)
GET_WAS_IN(temp_ch)++;
}
/* update zone tables */
{
int zone, cmd_no;
for (zone = 0; zone <= top_of_zone_table; zone++)
for (cmd_no = 0; cmd_no < zone_table[zone].num_cmds; cmd_no++)
{
switch (ZCMD.command) {
case 'M':
ZCMD.arg3 = (ZCMD.arg3 >= room_num ? ZCMD.arg3 + 1 :
ZCMD.arg3);
break;
case 'O':
if (ZCMD.arg3 != NOWHERE)
ZCMD.arg3 =
(ZCMD.arg3 >= room_num ?
ZCMD.arg3 + 1 : ZCMD.arg3);
break;
case 'D':
ZCMD.arg1 =
(ZCMD.arg1 >= room_num ?
ZCMD.arg1 + 1 : ZCMD.arg1);
break;
case 'R': /* rem obj from room */
ZCMD.arg1 =
(ZCMD.arg1 >= room_num ?
ZCMD.arg1 + 1 : ZCMD.arg1);
break;
}
}
}
/* update load rooms, to fix creeping load room problem */
if (room_num <= r_mortal_start_room)
r_mortal_start_room++;
if (room_num <= r_immort_start_room)
r_immort_start_room++;
if (room_num <= r_frozen_start_room)
r_frozen_start_room++;
if (room_num <= r_newbie_start_room)
r_newbie_start_room++;
/* go through the world. if any of the old rooms indicated an exit
* to our new room, we have to change it */
for (counter = 0; counter < top_of_world + 1; counter++) {
for (counter2 = 0; counter2 < NUM_OF_DIRS; counter2++) {
/* if exit exists */
if (world[counter].dir_option[counter2]) {
/* increment r_nums for rooms bigger than or equal to new one
* because we inserted room */
if (world[counter].dir_option[counter2]->to_room >= room_num)
world[counter].dir_option[counter2]->to_room += 1;
/* if an exit to the new room is indicated, change to_room */
if (world[counter].dir_option[counter2]->to_room_vnum == d->edit_number)
world[counter].dir_option[counter2]->to_room = room_num;
}
}
}
} // end 'insert' else
/* resolve all vnum doors to rnum doors in the newly edited room */
int opposite;
for (counter2 = 0; counter2 < NUM_OF_DIRS; counter2++) {
if (world[room_num].dir_option[counter2]) {
world[room_num].dir_option[counter2]->to_room =
real_room(world[room_num].dir_option[counter2]->to_room_vnum);
if (counter2 < NUM_OF_DIRS) {
opposite = world[room_num].dir_option[counter2]->to_room;
if (opposite != NOWHERE && world[opposite].dir_option[rev_dir[counter2]] &&
world[opposite].dir_option[rev_dir[counter2]]->to_room == room_num) {
world[opposite].dir_option[rev_dir[counter2]]->material =
world[room_num].dir_option[counter2]->material;
world[opposite].dir_option[rev_dir[counter2]]->barrier =
world[room_num].dir_option[counter2]->barrier;
world[opposite].dir_option[rev_dir[counter2]]->condition =
world[room_num].dir_option[counter2]->condition;
}
}
}
}
send_to_char("Writing room to disk.\r\n", d->character);
write_world_to_disk(d->character->player_specials->saved.zonenum);
send_to_char("Saved.\r\n", CH);
/* do NOT free strings! just the room structure */
Mem->ClearRoom(d->edit_room);
d->edit_room = NULL;
PLR_FLAGS(d->character).RemoveBit(PLR_EDITING);
STATE(d) = CON_PLAYING;
char_to_room(CH, GET_WAS_IN(CH));
GET_WAS_IN(CH) = NOWHERE;
send_to_char("Done.\r\n", d->character);
break;
}
case 'n':
case 'N':
send_to_char("Room not saved, aborting.\r\n", d->character);
STATE(d) = CON_PLAYING;
PLR_FLAGS(d->character).RemoveBit(PLR_EDITING);
/* free everything up, including strings etc */
if (d->edit_room)
Mem->DeleteRoom(d->edit_room);
d->edit_room = NULL;
d->edit_number = 0;
char_to_room(CH, GET_WAS_IN(CH));
GET_WAS_IN(CH) = NOWHERE;
break;
default:
send_to_char("Invalid choice!\r\n", d->character);
send_to_char("Do you wish to save this room internally?", d->character);
break;
}
break; /* end of REDIT_CONFIRM_SAVESTRING */
case REDIT_MAIN_MENU:
switch (LOWER(*arg)) {
case 'q':
d->edit_mode = REDIT_CONFIRM_SAVESTRING;
redit_parse(d, "y");
break;
case 'x':
d->edit_mode = REDIT_CONFIRM_SAVESTRING;
redit_parse(d, "n");
break;
case '1':
send_to_char("Enter room name:", d->character);
d->edit_mode = REDIT_NAME;
break;
case '2':
send_to_char("Enter room description:\r\n", d->character);
d->edit_mode = REDIT_DESC;
d->str = new (char *);
if (!d->str) {
mudlog("Malloc failed!", NULL, LOG_SYSLOG, TRUE);
shutdown();
}
*(d->str) = NULL;
d->max_str = MAX_MESSAGE_LENGTH;
d->mail_to = 0;
break;
case '3':
send_to_char("Enter room nighttime desc description:\r\n", d->character);
d->edit_mode = REDIT_NDESC;
d->str = new (char *);
if (!d->str) {
mudlog("Malloc failed!", NULL, LOG_SYSLOG, TRUE);
shutdown();
}
*(d->str) = NULL;
d->max_str = MAX_MESSAGE_LENGTH;
d->mail_to = 0;
break;
case '4':
redit_disp_flag_menu(d);
break;
case '5':
redit_disp_sector_menu(d);
break;
case '6':
d->edit_number2 = NORTH;
redit_disp_exit_menu(d);
break;
case '7':
d->edit_number2 = NORTHEAST;
redit_disp_exit_menu(d);
break;
case '8':
d->edit_number2 = EAST;
redit_disp_exit_menu(d);
break;
case '9':
d->edit_number2 = SOUTHEAST;
redit_disp_exit_menu(d);
break;
case 'a':
d->edit_number2 = SOUTH;
redit_disp_exit_menu(d);
break;
case 'b':
d->edit_number2 = SOUTHWEST;
redit_disp_exit_menu(d);
break;
case 'c':
d->edit_number2 = WEST;
redit_disp_exit_menu(d);
break;
case 'd':
d->edit_number2 = NORTHWEST;
redit_disp_exit_menu(d);
break;
case 'e':
d->edit_number2 = UP;
redit_disp_exit_menu(d);
break;
case 'f':
d->edit_number2 = DOWN;
redit_disp_exit_menu(d);
break;
case 'g':
redit_disp_mtx_menu(d);
break;
case 'h':
redit_disp_light_menu(d, 1);
break;
case 'i':
redit_disp_light_menu(d, 0);
break;
case 'j':
redit_disp_combat_menu(d);
break;
case 'k':
send_to_char("Enter Background Count: ", CH);
d->edit_mode = REDIT_BACKGROUND;
break;
case 'l':
/* if extra desc doesn't exist . */
if (!d->edit_room->ex_description) {
d->edit_room->ex_description = new extra_descr_data;
memset((char *) d->edit_room->ex_description, 0,
sizeof(struct extra_descr_data));
}
d->misc_data = (void **) &(d->edit_room->ex_description);
redit_disp_extradesc_menu(d);
break;
// new stuff here
case 'm':
if (ROOM->sector_type == SPIRIT_LAKE || ROOM->sector_type == SPIRIT_SEA || ROOM->sector_type == SPIRIT_RIVER) {
send_to_char("Enter current rating (1 to 20): ", CH);
d->edit_mode = REDIT_LIBRARY_RATING;
} else {
redit_disp_menu(d);
return;
}
break;
default:
send_to_char("Invalid choice!", d->character);
redit_disp_menu(d);
break;
}
break;
case REDIT_MATRIX:
switch (LOWER(*arg)) {
case '0':
send_to_char(CH, "Enter Destination Host: ");
d->edit_mode = REDIT_HOST;
break;
case '1':
send_to_char(CH, "Enter Access Modifier: ");
d->edit_mode = REDIT_ACCESS;
break;
case '2':
send_to_char(CH, "Enter Trace Modifier: ");
d->edit_mode = REDIT_TRACE;
break;
case '3':
send_to_char(CH, "Enter I/O Speed (-1 For Tap, 0 For Unlimited): ");
d->edit_mode = REDIT_IO;
break;
case '4':
send_to_char(CH, "Enter Base Bandwidth (-1 For Tap, 0 For Unlimited): ");
d->edit_mode = REDIT_BASE;
break;
case '5':
send_to_char(CH, "Enter Parent RTG: ");
d->edit_mode = REDIT_PARENT;
break;
case '6':
send_to_char(CH, "Enter Commlink Number (8 numbers): ");
d->edit_mode = REDIT_COMMLINK;
break;
case '7':
send_to_char(CH, "Enter Physical Address Description: ");
d->edit_mode = REDIT_ADDRESS;
break;
case 'q':
redit_disp_menu(d);
break;
default:
send_to_char("Invalid choice! Enter Choice: ", d->character);
break;
}
break;
case REDIT_HOST:
number = atoi(arg);
if (real_host(number) < 0)
send_to_char("Invalid host!\r\nEnter destination host: ", CH);
else {
d->edit_room->matrix = number;
redit_disp_mtx_menu(d);
}
break;
case REDIT_PARENT:
number = atoi(arg);
if (real_host(number) < 0)
send_to_char("Invalid host!\r\nEnter Parent RTG: ", CH);
else {
d->edit_room->rtg = number;
redit_disp_mtx_menu(d);
}
break;
case REDIT_COMMLINK:
d->edit_room->jacknumber = atoi(arg);
redit_disp_mtx_menu(d);
break;
case REDIT_IO:
if ((number = atoi(arg)) < -1)
send_to_char("Invalid host!\r\nEnter I/O Speed: ", CH);
else {
d->edit_room->io = number;
redit_disp_mtx_menu(d);
}
break;
case REDIT_BASE:
if ((number = atoi(arg)) < -1)
send_to_char("Invalid host!\r\nEnter Base Bandwidth: ", CH);
else {
d->edit_room->bandwidth = number;
redit_disp_mtx_menu(d);
}
break;
case REDIT_ACCESS:
d->edit_room->access = atoi(arg);
redit_disp_mtx_menu(d);
break;
case REDIT_TRACE:
d->edit_room->trace = atoi(arg);
redit_disp_mtx_menu(d);
break;
case REDIT_ADDRESS:
if (d->edit_room->address)
delete [] d->edit_room->address;
d->edit_room->address = str_dup(arg);
redit_disp_mtx_menu(d);
break;
case REDIT_BACKGROUND2:
number = atoi(arg);
if (number < 0 || number > AURA_PLAYERCOMBAT - 1) {
send_to_char(CH, "Number must be between 0 and %d. Enter Type: ", AURA_PLAYERCOMBAT - 1);
return;
}
d->edit_room->background[1] = number;
redit_disp_menu(d);
break;
case REDIT_BACKGROUND:
d->edit_room->background[0] = atoi(arg);
for (number = 0; number < AURA_PLAYERCOMBAT; number++)
send_to_char(CH, "%d) %s\r\n", number, background_types[number]);
send_to_char("Enter background count type: ", CH);
d->edit_mode = REDIT_BACKGROUND2;
break;
case REDIT_NAME:
if (d->edit_room->name)
delete [] d->edit_room->name;
d->edit_room->name = str_dup(arg);
redit_disp_menu(d);
break;
case REDIT_DESC:
/* we will NEVER get here */
break;
case REDIT_FLAGS:
number = atoi(arg);
if ((number < 0) || (number > ROOM_MAX)) {
send_to_char("That's not a valid choice!\r\n", d->character);
redit_disp_flag_menu(d);
} else {
if (number == 0)
/* back out */
redit_disp_menu(d);
else {
/* toggle bits */
if (ROOM->room_flags.IsSet(number-1)) {
ROOM->room_flags.RemoveBit(number-1);
} else
ROOM->room_flags.SetBit(number-1);
redit_disp_flag_menu(d);
}
}
break;
case REDIT_COMBAT:
switch (*arg) {
case '1':
send_to_char("Amount of crowd (0-None, 10-Busy City Street): ", CH);
d->edit_mode = REDIT_CROWD;
break;
case '2':
send_to_char("Amount of cover (0-None, 10-Can Barely Move): ", CH);
d->edit_mode = REDIT_COVER;
break;
case '3':
CLS(CH);
for (int i = 0; i < 11; i++)
send_to_char(CH, "%2d) %s\r\n", i, room_types[i]);
send_to_char("Room Type: ", CH);
d->edit_mode = REDIT_TYPE;
break;
case '4':
send_to_char("Room Length: ", CH);
d->edit_mode = REDIT_X;
break;
case '5':
send_to_char("Room Width: ", CH);
d->edit_mode = REDIT_Y;
break;
case '6':
send_to_char("Room Height in meters: ", CH);
d->edit_mode = REDIT_Z;
break;
default:
redit_disp_menu(d);
}
break;
case REDIT_COVER:
number = atoi(arg);
if (number >= 0 && number <= 10)
d->edit_room->cover = number;
redit_disp_combat_menu(d);
break;
case REDIT_CROWD:
number = atoi(arg);
if (number >= 0 && number <= 10)
d->edit_room->crowd = number;
redit_disp_combat_menu(d);
break;
case REDIT_TYPE:
number = atoi(arg);
if (number >= 0 && number < 11)
d->edit_room->type = number;
redit_disp_combat_menu(d);
break;
case REDIT_X:
d->edit_room->x = atoi(arg);
redit_disp_combat_menu(d);
break;
case REDIT_Y:
d->edit_room->y = atoi(arg);
redit_disp_combat_menu(d);
break;
case REDIT_Z:
d->edit_room->z = atof(arg);
redit_disp_combat_menu(d);
break;
case REDIT_LIGHT:
number = atoi(arg);
if (number < 0 || number >= 5) {
send_to_char("Invalid input. Select Light Options:", CH);
return;
} else {
d->edit_room->vision[0] = number;
redit_disp_menu(d);
}
break;
case REDIT_SMOKE:
number = atoi(arg);
if (number == 0) {
d->edit_room->vision[1] = 0;
redit_disp_menu(d);
} else if (number < 1 || number > 5) {
send_to_char("Invalid input. Select Light Options:", CH);
return;
} else {
d->edit_room->vision[1] = number + 4;
redit_disp_menu(d);
}
break;
case REDIT_SECTOR:
number = atoi(arg);
if (number < 0 || number >= NUM_SPIRITS) {
send_to_char("Invalid choice!", d->character);
redit_disp_sector_menu(d);
} else {
d->edit_room->sector_type = number;
redit_disp_menu(d);
}
break;
case REDIT_EXIT_MENU:
switch (*arg) {
case '0':
redit_disp_menu(d);
break;
case '1':
d->edit_mode = REDIT_EXIT_NUMBER;
send_to_char("Exit to room number:", d->character);
break;
case '2':
d->edit_mode = REDIT_EXIT_DESCRIPTION;
d->str = new (char *);
if (!d->str) {
mudlog("Malloc failed!", NULL, LOG_SYSLOG, TRUE);
shutdown();
}
*(d->str) = NULL;
d->max_str = MAX_MESSAGE_LENGTH;
d->mail_to = 0;
send_to_char("Enter exit description:\r\n", d->character);
break;
case '3':
d->edit_mode = REDIT_EXIT_KEYWORD;
send_to_char("Enter keywords:", d->character);
break;
case '4':
d->edit_mode = REDIT_EXIT_KEY;
send_to_char("Enter key number:", d->character);
break;
case '5':
redit_disp_exit_flag_menu(d);
d->edit_mode = REDIT_EXIT_DOORFLAGS;
break;
case '6':
d->edit_mode = REDIT_EXIT_KEY_LEV;
send_to_char("Enter lock level:", CH);
break;
case '7':
d->edit_mode = REDIT_EXIT_MATERIAL;
redit_disp_material_menu(d);
break;
case '8':
d->edit_mode = REDIT_EXIT_BARRIER;
redit_disp_barrier_menu(d);
break;
case '9':
d->edit_mode = REDIT_EXIT_HIDDEN;
send_to_char("Enter hidden rating of the exit: ", CH);
break;
case 'a':
/* delete exit */
if (d->edit_room->dir_option[d->edit_number2]->keyword)
delete [] d->edit_room->dir_option[d->edit_number2]->keyword;
if (d->edit_room->dir_option[d->edit_number2]->general_description)
delete [] d->edit_room->dir_option[d->edit_number2]->general_description;
delete d->edit_room->dir_option[d->edit_number2];
d->edit_room->dir_option[d->edit_number2] = NULL;
redit_disp_menu(d);
break;
default:
send_to_char("Invalid choice!\r\n", d->character);
break;
}
break;
case REDIT_EXIT_NUMBER:
number = atoi(arg);
if (number < 0)
send_to_char("Invalid choice!\r\nExit to room number:", d->character);
else {
d->edit_room->dir_option[d->edit_number2]->to_room_vnum = number;
redit_disp_exit_menu(d);
}
break;
case REDIT_EXIT_DESCRIPTION:
/* we should NEVER get here */
break;
case REDIT_EXIT_KEYWORD:
if (d->edit_room->dir_option[d->edit_number2]->keyword)
delete [] d->edit_room->dir_option[d->edit_number2]->keyword;
d->edit_room->dir_option[d->edit_number2]->keyword = str_dup(arg);
redit_disp_exit_menu(d);
break;
case REDIT_EXIT_KEY:
number = atoi(arg);
d->edit_room->dir_option[d->edit_number2]->key = number;
redit_disp_exit_menu(d);
break;
case REDIT_EXIT_KEY_LEV:
number = atoi(arg);
DOOR->key_level = MAX(0, MIN(50, number));
redit_disp_exit_menu(d);
break;
case REDIT_EXIT_HIDDEN:
number = atoi(arg);
DOOR->hidden = MAX(0, MIN(50, number));
redit_disp_exit_menu(d);
break;
case REDIT_EXIT_MATERIAL:
number = atoi(arg);
if (number == 0)
redit_disp_exit_menu(d);
else if (number > 0 && number <= NUM_MATERIALS) {
DOOR->material = number - 1;
redit_disp_exit_menu(d);
} else
redit_disp_material_menu(d);
break;
case REDIT_EXIT_BARRIER:
number = atoi(arg);
if (number == 0)
redit_disp_exit_menu(d);
else if (number > 0 && number <= NUM_BARRIERS) {
DOOR->condition = DOOR->barrier = barrier_ratings[number - 1];
redit_disp_exit_menu(d);
} else
redit_disp_barrier_menu(d);
break;
case REDIT_LIBRARY_RATING:
number = atoi(arg);
if ((number < 0) || (number > 20)) {
send_to_char("Value must be between 1 and 20.\r\n", CH);
send_to_char("Enter current rating: ", CH);
} else {
ROOM->rating = number;
redit_disp_menu(d);
}
break;
case REDIT_EXIT_DOORFLAGS:
number = atoi(arg);
if ((number < 0) || (number > 2)) {
send_to_char("That's not a valid choice!\r\n", d->character);
redit_disp_exit_flag_menu(d);
} else {
/* doors are a bit idiotic, don't you think? :) */
if (number == 0)
d->edit_room->dir_option[d->edit_number2]->exit_info = 0;
else if (number == 1)
d->edit_room->dir_option[d->edit_number2]->exit_info = EX_ISDOOR;
else if (number == 2)
d->edit_room->dir_option[d->edit_number2]->exit_info =
EX_ISDOOR | EX_PICKPROOF;
/* jump out to menu */
redit_disp_exit_menu(d);
}
break;
case REDIT_EXTRADESC_KEY:
if (((struct extra_descr_data *) *d->misc_data)->keyword)
delete [] (((struct extra_descr_data *) *d->misc_data)->keyword);
((struct extra_descr_data *) * d->misc_data)->keyword = str_dup(arg);
redit_disp_extradesc_menu(d);
break;
case REDIT_EXTRADESC_MENU:
number = atoi(arg);
switch (number) {
case 0: {
/* if something got left out, delete the extra desc
when backing out to menu */
if (!((struct extra_descr_data *) * d->misc_data)->keyword ||
!((struct extra_descr_data *) * d->misc_data)->description) {
if (((struct extra_descr_data *) * d->misc_data)->keyword)
delete [] ((struct extra_descr_data *) * d->misc_data)->keyword;
if (((struct extra_descr_data *) * d->misc_data)->description)
delete [] ((struct extra_descr_data *) * d->misc_data)->description;
delete (struct extra_descr_data *) *d->misc_data;
*d->misc_data = NULL;
}
/* else, we don't need to do anything.. jump to menu */
redit_disp_menu(d);
}
break;
case 1:
d->edit_mode = REDIT_EXTRADESC_KEY;
send_to_char("Enter keywords, separated by spaces:", d->character);
break;
case 2:
d->edit_mode = REDIT_EXTRADESC_DESCRIPTION;
send_to_char("Enter extra description:\r\n", d->character);
d->str = new (char *);
if (!d->str) {
mudlog("Malloc failed!", NULL, LOG_SYSLOG, TRUE);
shutdown();
}
*(d->str) = NULL;
d->max_str = MAX_MESSAGE_LENGTH;
d->mail_to = 0;
break;
case 3:
if (!((struct extra_descr_data *) *d->misc_data)->keyword ||
!((struct extra_descr_data *) *d->misc_data)->description) {
send_to_char("You can't edit the next extra desc without completing this one.\r\n", d->character);
redit_disp_extradesc_menu(d);
} else {
struct extra_descr_data *new_extra;
if (((struct extra_descr_data *) * d->misc_data)->next)
d->misc_data = (void **) &((struct extra_descr_data *) * d->misc_data)->next;
else {
/* make new extra, attach at end */
new_extra = new extra_descr_data;
memset((char *) new_extra, 0, sizeof(extra_descr_data));
((struct extra_descr_data *) * d->misc_data)->next = new_extra;
d->misc_data =
(void **) &((struct extra_descr_data *) * d->misc_data)->next;
}
redit_disp_extradesc_menu(d);
}
}
break;
default:
/* we should never get here */
break;
}
}
// world saving routine
#define RM world[realcounter]
void write_world_to_disk(int vnum)
{
long counter, counter2, realcounter;
int znum = real_zone(vnum);
FILE *fp;
struct extra_descr_data *ex_desc;
// ideally, this would just fill a VTable with vals...maybe one day
sprintf(buf, "%s/%d.wld", WLD_PREFIX,
zone_table[znum].number);
fp = fopen(buf, "w+");
for (counter = zone_table[znum].number * 100;
counter <= zone_table[znum].top; counter++) {
realcounter = real_room(counter);
if (realcounter >= 0) {
if (!strcmp("An unfinished room", RM.name))
continue;
fprintf(fp, "#%ld\n", counter);
fprintf(fp, "Name:\t%s\n",
RM.name ? RM.name : "An unnamed room");
fprintf(fp, "Desc:$\n%s~\n",
cleanup(buf2, RM.description ? RM.description :
"You see an empty room"));
if (RM.night_desc)
fprintf(fp, "NightDesc:$\n%s~\n", cleanup(buf2, RM.night_desc));
fprintf(fp,
"Flags:\t%s\n"
"SecType:\t%s\n"
"MatrixExit:\t%ld\n",
RM.room_flags.ToString(),
spirit_name[RM.sector_type],
RM.matrix);
if (real_host(RM.matrix) > 0)
fprintf(fp, "IO:\t%d\n"
"Bandwidth:\t%d\n"
"Access:\t%d\n"
"Trace:\t%d\n"
"RTG:\t%ld\n"
"JackID:\t%d\n"
"Address:\t%s\n",
RM.io, RM.bandwidth, RM.access, RM.trace, RM.rtg, RM.jacknumber, RM.address);
fprintf(fp, "Crowd:\t%d\n"
"Cover:\t%d\n"
"X:\t%d\n"
"Y:\t%d\n"
"Z:\t%.2f\n"
"RoomType:\t%d\n", RM.crowd, RM.cover, RM.x, RM.y, RM.z, RM.type);
fprintf(fp ,
"[POINTS]\n"
"\tSpecIdx:\t%d\n"
"\tRating:\t%d\n"
"\tLight:\t%d\n"
"\tSmoke:\t%d\n"
"\tBackground:\t%d\n"
"\tBackgroundType:\t%d\n",
RM.spec, RM.rating, RM.vision[0], RM.vision[1], RM.background[0], RM.background[1]);
for (counter2 = 0; counter2 < NUM_OF_DIRS; counter2++) {
room_direction_data *ptr = RM.dir_option[counter2];
if (ptr) {
int temp_door_flag;
fprintf(fp, "[EXIT %s]\n", fulldirs[counter2]);
if (ptr->keyword)
fprintf(fp, "\tKeywords:\t%s\n", ptr->keyword);
if (ptr->general_description)
fprintf(fp, "\tDesc:$\n%s~\n",
cleanup(buf2, ptr->general_description));
/* door flags need special handling, unfortunately. argh! */
if (IS_SET(ptr->exit_info, EX_ISDOOR)) {
if (IS_SET(ptr->exit_info, EX_PICKPROOF))
temp_door_flag = 2;
else
temp_door_flag = 1;
} else
temp_door_flag = 0;
fprintf(fp,
"\tToVnum:\t%ld\n"
"\tFlags:\t%d\n"
"\tMaterial:\t%s\n"
"\tBarrier:\t%d\n",
ptr->to_room_vnum,
temp_door_flag,
material_names[(int)ptr->material],
ptr->barrier);
if (DBIndex::IsValidV(ptr->key))
fprintf(fp, "\tKeyVnum:\t%ld\n", ptr->key);
if (ptr->key_level > 0)
fprintf(fp, "\tLockRating:\t%d\n", ptr->key_level);
if (ptr->hidden > 0)
fprintf(fp, "\tHiddenRating:\t%d\n", ptr->hidden);
}
}
if (RM.ex_description) {
int y = 0;
for (ex_desc = RM.ex_description; ex_desc; ex_desc = ex_desc->next) {
if (ex_desc->keyword && ex_desc->description) {
fprintf(fp,
"[EXTRADESC %d]\n"
"\tKeywords:\t%s\n"
"\tDesc:$\n%s~\n",
y, ex_desc->keyword,
cleanup(buf2, ex_desc->description));
}
y++;
}
}
fprintf(fp, "BREAK\n");
}
}
fprintf(fp, "END\n");
fclose(fp);
write_index_file("wld");
/* do NOT free strings! just the room structure */
}
#undef RM