SmaugWizard/Backup/
SmaugWizard/Backup/L/
SmaugWizard/Boards/
SmaugWizard/Building/
SmaugWizard/Corpses/
SmaugWizard/Councils/
SmaugWizard/Deity/
SmaugWizard/Gods/
SmaugWizard/MudProgs/
SmaugWizard/Player/L/
SmaugWizard/Src/
SmaugWizard/Src/res/
/****************************************************************************
 * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame      |				*
 * -----------------------------------------------------------|   \\._.//	*
 * SmaugWiz (C) 1998 by Russ Pillsbury (Windows NT version)   |   (0...0)	*
 * -----------------------------------------------------------|    ).:.(	*
 * SMAUG (C) 1994, 1995, 1996 by Derek Snider                 |    {o o}	*
 * -----------------------------------------------------------|   / ' ' \	*
 * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus,      |~'~.VxvxV.~'~*
 * Scryn, Swordbearer, Rennard, Tricops, and Gorog.           |				*
 * ------------------------------------------------------------------------ *
 * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael        *
 * Chastain, Michael Quan, and Mitchell Tse.                                *
 * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,          *
 * Michael Seifert, Hans Henrik Staerfeldt, Tom Madsen, and Katja Nyboe.    *
 * ------------------------------------------------------------------------ *
 *			    Smaug Room Menu Implementation file							*
 ****************************************************************************/

#include	"stdafx.h"

#define		ROOMMENU_CPP

#include	"smaug.h"
#include	"SysData.h"
#include	"mobiles.h"
#include	"affect.h"
#include	"objects.h"
#include	"rooms.h"
#include	"Exits.h"
#include	"roommenu.h"
#include	"descriptor.h"
#include	"character.h"

CMenuData	*RoomMenuData [];
CMenuData	RoomPage_C [];


void CRoomMenu::Display (CCharacter& Ch, int page)
{
	m_HelpMenu = DIM (RoomMenus) - 1;
	m_PageNr = page;

	if (m_PageNr < 0 || m_PageNr > m_HelpMenu) then m_PageNr = m_HelpMenu;

	m_CurrPageLines = GetLineCount (RoomMenus [m_PageNr]);
	m_pPageData = RoomMenuData [m_PageNr];
	m_nDataItems = m_pPageData ? GetItemCount (m_pPageData) : 0;

	// clear page & home cursor
	Ch.SendText ("\x1b[2J");

	// print the menu page
	Ch.GetDesc ()->WriteToBuffer (RoomMenus [m_PageNr]);

	// fill in fields
	DisplayData (Ch);
}


void CRoomMenu::DisplayData (CCharacter& Ch)
{
	static char	*DirName [] = { "North", "East", "South", "West", "Up",
								"Down", "North East", "North West",
								"South East", "South West", "Somewhere" };

	// Write in the room name
	Ch.SendTextf ("\x1b[1;35H[%5u:%-10.10s]-----[%c]", m_Vnum, NCCP ma_Name,
		m_bProto ? 'P' : 'N');

	m_Base [0] = (char*) this;
	m_Base [1] = NULL;

	if (m_pPageData == RoomPage_C) {
		Ch.SendColorf ("\x1b[4;35H&Y %s Exit ", DirName [m_CurrExit]);
		m_Base [1] = (char*) mc_pExits [m_CurrExit];
	}

	CSmaugMenu::DisplayData (Ch);
}


BOOL CRoomMenu::Edit (CCharacter& Ch, char* argument, const char* command)
{
	if (command [0] == '-') {
		if (m_pPageData == RoomPage_C)
			argument = SetExit (argument);
		Display (Ch, (char) argument [0]);
		return TRUE;
	}
	if (argument [0] == '-') return FALSE;

	m_Base [0] = (char*) this;
	m_Base [1] = NULL;

	if (m_pPageData == RoomPage_C)
		m_Base [1] = (char*) mc_pExits [m_CurrExit];

	return CSmaugMenu::Edit (Ch, argument, command);
}


void CRoomMenu::Save (CCharacter& Ch)
{
	CRoomIndexData	&Idx = *m_pIdx;

	// Save a-page items
	Idx.SetName (ma_Name);
	Idx.SetDescription (ma_Desc);

	// Save b-page items
	// clear all the flags and start over
	Idx.SetRoomFlags (0);

	if (m_bProto) then Idx.SetPrototype ();
	if (mb_Dark) then Idx.SetDark ();
	if (mb_Death) then Idx.SetDeathRoom ();
	if (mb_NoMob) then Idx.SetNoMob ();
	if (mb_Indoors) then Idx.SetIndoors ();
	if (mb_Lawful) then Idx.SetLawful ();
	if (mb_NoMagic) then Idx.SetNoMagic ();
	if (mb_PetShop) then Idx.SetPetShop ();
	if (mb_Neutral) then Idx.SetNeutral ();
	if (mb_NoDrop) then Idx.SetNoDrop ();
	if (mb_Safe) then Idx.SetSafe ();
	if (mb_Chaotic) then Idx.SetChaotic ();
	if (mb_NoDropAll) then Idx.SetNoDropAll ();
	if (mb_Teleport) then Idx.SetTelePort ();
	if (mb_Donation) then Idx.SetDonationRoom ();
	if (mb_NoRecall) then Idx.SetNoRecall ();
	if (mb_Private) then Idx.SetPrivate ();
	if (mb_Solitary) then Idx.SetSolitary ();
	if (mb_NoAstral) then Idx.SetNoAstral ();
	if (mb_Tunnel) then Idx.SetTunnel ();
	if (mb_Silent) then Idx.SetSilent ();
	if (mb_NoSummon) then Idx.SetNoSummon ();
	if (mb_ClanStore) then Idx.SetClanStoreRoom ();
	if (mb_LogSpeech) then Idx.SetLogSpeech ();
	if (mb_NoFloor) then Idx.SetNoFloor ();

	Idx.sector_type = mb_SectorType;

	// Save c-page items (exits)
	for (int d=DIR_NORTH; d <= DIR_SOMEWHERE; ++d) {
		if (! mc_pExits [d]->IsEmpty ())
			mc_pExits [d]->Unload (Idx, (dir_types) d);
	}
}


CRoomMenu::CRoomMenu (CRoomIndexData& Idx)
{
	m_pIdx = &Idx;
	m_Vnum = Idx.vnum;				// keep vnum for display
	m_CurrExit = 0;
	m_bProto = Idx.IsPrototype ();

	// load local a-page items
	ma_Name = Idx.GetName ();
	ma_Desc = Idx.GetDescription ();


	// load local b-page items
	mb_Dark = Idx.IsDark ();
	mb_Death = Idx.IsDeathRoom ();
	mb_NoMob = Idx.IsNoMob ();
	mb_Indoors = Idx.IsIndoors ();
	mb_Lawful = Idx.IsLawful ();
	mb_NoMagic = Idx.IsNoMagic ();
	mb_PetShop = Idx.IsPetShop ();
	mb_Neutral = Idx.IsNeutral ();
	mb_NoDrop = Idx.IsNoDrop ();
	mb_Safe = Idx.IsSafe ();
	mb_Chaotic = Idx.IsChaotic ();
	mb_NoDropAll = Idx.IsNoDropAll ();
	mb_Teleport = Idx.IsTelePort ();
	mb_Donation = Idx.IsDonationRoom ();
	mb_NoRecall = Idx.IsNoRecall ();
	mb_Private = Idx.IsPrivate ();
	mb_Solitary = Idx.IsSolitary ();
	mb_NoAstral = Idx.IsNoAstral ();
	mb_Tunnel = Idx.IsTunnel ();
	mb_Silent = Idx.IsSilent ();
	mb_NoSummon = Idx.IsNoSummon ();
	mb_ClanStore = Idx.IsClanStoreRoom ();
	mb_LogSpeech = Idx.IsLogSpeech ();
	mb_NoFloor = Idx.HasNoFloor ();

	mb_SectorType = Idx.sector_type;


	// load local c-page items (exits)
	for (int d=DIR_NORTH; d <= DIR_SOMEWHERE; ++d) {
		mc_pExits [d] = new CXMenuData (Idx, (dir_types) d);
		mc_Direction [d] = ! mc_pExits [d]->IsEmpty ();
	}
}



CXMenuData::CXMenuData (CRoomIndexData& Idx, dir_types dir)
{	
	m_Door = m_Closed = m_Locked = m_Hidden = FALSE;
	m_Secret = m_Disabled = m_PickProof = m_NoPass = m_CanClimb = FALSE;
	m_Fly = m_Climb = m_Dig = m_Auto = FALSE;
	m_CanEnter = m_CanLeave = m_CanSearch = m_IsWindow = FALSE;
	m_CanLook = m_NoBash = m_NoMob = FALSE;
	
	m_Vnum = m_KeyVnum = 0;

	// Use TRUE to get disabled exits
	CExitData	&Ex = *get_exit (&Idx, dir, TRUE);

	if (&Ex) {
		m_Door = Ex.IsDoor ();
		m_Closed = Ex.IsClosed ();
		m_Locked = Ex.IsLocked ();
		m_Secret = Ex.IsSecret ();
		m_Disabled = Ex.IsDisabled ();
		m_Hidden = Ex.IsHidden ();
		m_PickProof = Ex.IsPickProof ();
		m_NoPass = Ex.IsNoPass ();
		m_CanClimb = Ex.CanClimb ();
		m_Fly = Ex.IsFly ();
		m_Climb = Ex.IsClimb ();
		m_Dig = Ex.IsDig ();
		m_Auto = Ex.CanAuto ();
		m_CanEnter = Ex.CanEnter ();
		m_CanLeave = Ex.CanLeave ();
		m_CanSearch = Ex.CanSearch ();
		m_IsWindow = Ex.IsWindow ();
		m_CanLook = Ex.CanLook ();
		m_NoBash = Ex.IsBashProof ();
		m_NoMob = Ex.IsNoMob ();

		m_Vnum = Ex.vnum;
		m_KeyVnum = Ex.key;
		if (Ex.GetToRoom ())
			m_RoomName = Ex.GetToRoom ()->GetName ();

		CObjIndexData	*pObjIndex = OIdxTable.GetObj (m_KeyVnum);
		if (pObjIndex)
			m_KeyName = pObjIndex->GetName ();
		else
			m_KeyName = "No (or Unknown) Key";

		m_Desc = Ex.description;

		CString	keys = Ex.keyword;
		char	*buf = keys.GetBuffer (keys.GetLength () + 1);
		for (int i=0; i < DIM (m_KeyWords); ++i) {
			m_KeyWords [i] = ParseWord (buf);
		}
	}
}


void CXMenuData::Unload (CRoomIndexData& Idx, dir_types dir)
{
	CExitData	*ex = get_exit (&Idx, dir);

	// Not checking ToRoom for validity here since it was already checked
	// by the edit routine when the vnum was entered.
	CRoomIndexData *ToRoom = RoomTable.GetRoom (m_Vnum);
	BOOL	bNewExit = ex == NULL;
	if (bNewExit) then ex = make_exit (&Idx, ToRoom, dir);

	ex->SetFlags (0);					// clear all flags

	if (m_Door) then ex->SetDoor ();
	if (m_Closed) then ex->SetClosed ();
	if (m_Locked) then ex->SetLocked ();
	if (m_Secret) then ex->SetSecret ();
	if (m_Disabled) then ex->SetDisabled ();
	if (m_Hidden) then ex->SetHidden ();
	if (m_PickProof) then ex->SetPickProof ();
	if (m_NoPass) then ex->SetNoPass ();
	if (m_CanClimb) then ex->SetCanClimb ();
	if (m_Fly) then ex->SetFly ();
	if (m_Climb) then ex->SetClimb ();
	if (m_Dig) then ex->SetDig ();
	if (m_Auto) then ex->SetCanAuto ();
	if (m_CanEnter) then ex->SetCanEnter ();
	if (m_CanLeave) then ex->SetCanLeave ();
	if (m_CanSearch) then ex->SetCanSearch ();
	if (m_IsWindow) then ex->SetWindow ();
	if (m_CanLook) then ex->SetCanLook ();
	if (m_NoBash) then ex->SetBashProof ();
	if (m_NoMob) then ex->SetNoMob ();

	ex->vnum = m_Vnum;
	ex->key = m_KeyVnum;

	STRFREE (ex->description);
	ex->description = STRALLOC (m_Desc);

	CString	keys;
	for (int i=0; i < DIM (m_KeyWords); ++i)
		if (! m_KeyWords [i].IsEmpty ())
			keys += m_KeyWords [i] + ' ';
	keys.TrimRight ();

	STRFREE (ex->keyword);
	ex->keyword = STRALLOC (keys);
}


BOOL CXMenuData::IsEmpty ()
{
	if (m_Door | m_Secret | m_Closed | m_PickProof | m_Locked
		| m_NoPass | m_Vnum | m_KeyVnum) return FALSE;
	
	return m_RoomName.IsEmpty () && m_KeyName.IsEmpty ()
		&& m_Desc.IsEmpty ();
};


char *CRoomMenu::SetExit (char* arg)
{
	static char	*DirAbbr [] = { "N", "E", "S", "W", "U", "D",
								"NE", "NW", "SE", "SW", "SO" };

	for (int i=0; i < DIM (DirAbbr); ++i)
		if (! strcmp (arg, DirAbbr [i])) {
			m_CurrExit = i;
			arg [0] = 'c';
			break;
		}

	return arg;
}


CRoomMenu::~CRoomMenu ()
{
	for (int i=0; i < DIM (mc_pExits); ++i)
		delete mc_pExits [i];
}


#define		OFFSET(aa)	offsetof(CRoomMenu,aa)

CMenuData	RoomPage_A [] = {
	{ '1', 'a', 4, 10, 67, OFFSET(ma_Name), MT_CSTRING, 0, NULL },
	{ '1', 'b', 7, 2, 75, OFFSET(ma_Desc), MT_CSTRING, 0, MenuStringEditFn, 5,2,75 },
	{ 0, 0, 0, 0, 0, 0, MT_END }
};


CMenuData	RoomPage_B [] = {
	{ '1', 'a', 2, 26, 1, OFFSET(mb_Dark), MT_BOOL, 0, NULL },
	{ '1', 'b', 3, 26, 1, OFFSET(mb_Indoors), MT_BOOL, 0, NULL },
	{ '1', 'c', 4, 26, 1, OFFSET(mb_PetShop), MT_BOOL, 0, NULL },
	{ '1', 'd', 5, 26, 1, OFFSET(mb_Safe), MT_BOOL, 0, NULL },
	{ '1', 'e', 6, 26, 1, OFFSET(mb_Teleport), MT_BOOL, 0, NULL },
	{ '1', 'f', 7, 26, 1, OFFSET(mb_Private), MT_BOOL, 0, NULL },
	{ '1', 'g', 8, 26, 1, OFFSET(mb_Tunnel), MT_BOOL, 0, NULL },
	{ '1', 'h', 9, 26, 1, OFFSET(mb_ClanStore), MT_BOOL, 0, NULL },

	{ '1', 'i', 2, 42, 1, OFFSET(mb_Death), MT_BOOL, 0, NULL },
	{ '1', 'j', 3, 42, 1, OFFSET(mb_Lawful), MT_BOOL, 0, NULL },
	{ '1', 'k', 4, 42, 1, OFFSET(mb_Neutral), MT_BOOL, 0, NULL },
	{ '1', 'l', 5, 42, 1, OFFSET(mb_Chaotic), MT_BOOL, 0, NULL },
	{ '1', 'm', 6, 42, 1, OFFSET(mb_Donation), MT_BOOL, 0, NULL },
	{ '1', 'n', 7, 42, 1, OFFSET(mb_Solitary), MT_BOOL, 0, NULL },
	{ '1', 'o', 8, 42, 1, OFFSET(mb_Silent), MT_BOOL, 0, NULL },
	{ '1', 'p', 9, 42, 1, OFFSET(mb_LogSpeech), MT_BOOL, 0, NULL },

	{ '1', 'q', 2, 60, 1, OFFSET(mb_NoMob), MT_BOOL, 0, NULL },
	{ '1', 'r', 3, 60, 1, OFFSET(mb_NoMagic), MT_BOOL, 0, NULL },
	{ '1', 's', 4, 60, 1, OFFSET(mb_NoDrop), MT_BOOL, 0, NULL },
	{ '1', 't', 5, 60, 1, OFFSET(mb_NoDropAll), MT_BOOL, 0, NULL },
	{ '1', 'u', 6, 60, 1, OFFSET(mb_NoRecall), MT_BOOL, 0, NULL },
	{ '1', 'v', 7, 60, 1, OFFSET(mb_NoAstral), MT_BOOL, 0, NULL },
	{ '1', 'w', 8, 60, 1, OFFSET(mb_NoSummon), MT_BOOL, 0, NULL },
	{ '1', 'x', 9, 60, 1, OFFSET(mb_NoFloor), MT_BOOL, 0, NULL },

	{ '2', 'a', 11, 24, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 0,14 },
	{ '2', 'b', 12, 24, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 1,14 },
	{ '2', 'c', 13, 24, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 2,14 },
	{ '2', 'd', 14, 24, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 3,14 },
	{ '2', 'e', 15, 24, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 4,14 },

	{ '2', 'f', 11, 44, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 5,14 },
	{ '2', 'g', 12, 44, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 6,14 },
	{ '2', 'h', 13, 44, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 7,14 },
	{ '2', 'i', 14, 44, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 8,14 },

	{ '2', 'j', 11, 58, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 9,14 },
	{ '2', 'k', 12, 58, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 10,14 },
	{ '2', 'l', 13, 58, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 11,14 },
	{ '2', 'm', 14, 63, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 12,14 },
	{ '2', 'n', 15, 63, 1, OFFSET(mb_SectorType), MT_GROUP, 0, NULL, 13,14 },
	{ 0, 0, 0, 0, 0, 0, MT_END }
};


#define		XOFFSET(aa)	offsetof(CXMenuData,aa)

CMenuData	RoomPage_C [] = {
	{ 0, 0, 2, 18, 1, OFFSET(mc_Direction [0]), MT_BOOL, 0, NULL },
	{ 0, 0, 2, 36, 1, OFFSET(mc_Direction [1]), MT_BOOL, 0, NULL },
	{ 0, 0, 2, 27, 1, OFFSET(mc_Direction [2]), MT_BOOL, 0, NULL },
	{ 0, 0, 2, 45, 1, OFFSET(mc_Direction [3]), MT_BOOL, 0, NULL },
	{ 0, 0, 2, 53, 1, OFFSET(mc_Direction [4]), MT_BOOL, 0, NULL },
	{ 0, 0, 2, 61, 1, OFFSET(mc_Direction [5]), MT_BOOL, 0, NULL },
	{ 0, 0, 3, 18, 1, OFFSET(mc_Direction [6]), MT_BOOL, 0, NULL },
	{ 0, 0, 3, 27, 1, OFFSET(mc_Direction [7]), MT_BOOL, 0, NULL },
	{ 0, 0, 3, 36, 1, OFFSET(mc_Direction [8]), MT_BOOL, 0, NULL },
	{ 0, 0, 3, 45, 1, OFFSET(mc_Direction [9]), MT_BOOL, 0, NULL },
	{ 0, 0, 3, 61, 1, OFFSET(mc_Direction [10]), MT_BOOL, 0, NULL },
	{ '1', 'a', 5, 24, 1, XOFFSET(m_Door), MT_BOOL, 1, NULL },
	{ '1', 'b', 6, 24, 1, XOFFSET(m_Closed), MT_BOOL, 1, NULL },
	{ '1', 'c', 7, 24, 1, XOFFSET(m_Locked), MT_BOOL, 1, NULL },
	{ '1', 'd', 8, 24, 1, XOFFSET(m_Hidden), MT_BOOL, 1, NULL },
	{ '1', 'e', 9, 24, 1, XOFFSET(m_Secret), MT_BOOL, 1, NULL },
	{ '1', 'f', 5, 40, 1, XOFFSET(m_Disabled), MT_BOOL, 1, NULL },
	{ '1', 'g', 6, 40, 1, XOFFSET(m_PickProof), MT_BOOL, 1, NULL },
	{ '1', 'h', 7, 40, 1, XOFFSET(m_NoPass), MT_BOOL, 1, NULL },
	{ '1', 'i', 8, 40, 1, XOFFSET(m_CanClimb), MT_BOOL, 1, NULL },
	{ '1', 'j', 9, 40, 1, XOFFSET(m_CanLook), MT_BOOL, 1, NULL },
	{ '1', 'k', 5, 53, 1, XOFFSET(m_Fly), MT_BOOL, 1, NULL },
	{ '1', 'l', 6, 53, 1, XOFFSET(m_Climb), MT_BOOL, 1, NULL },
	{ '1', 'm', 7, 53, 1, XOFFSET(m_Dig), MT_BOOL, 1, NULL },
	{ '1', 'n', 8, 53, 1, XOFFSET(m_Auto), MT_BOOL, 1, NULL },
	{ '1', 'o', 9, 53, 1, XOFFSET(m_NoMob), MT_BOOL, 1, NULL },
	{ '1', 'p', 5, 70, 1, XOFFSET(m_CanEnter), MT_BOOL, 1, NULL },
	{ '1', 'q', 6, 70, 1, XOFFSET(m_CanLeave), MT_BOOL, 1, NULL },
	{ '1', 'r', 7, 70, 1, XOFFSET(m_CanSearch), MT_BOOL, 1, NULL },
	{ '1', 's', 8, 70, 1, XOFFSET(m_IsWindow), MT_BOOL, 1, NULL },
	{ '1', 't', 9, 70, 1, XOFFSET(m_NoBash), MT_BOOL, 1, NULL },

	{ '2', 'a', 13, 13, 7, XOFFSET(m_Vnum), MT_INT, 1, NULL },
	{ 0, 0, 13, 22, 23, XOFFSET(m_RoomName), MT_CSTRING, 1, NULL },
	{ '2', 'b', 14, 13, 7, XOFFSET(m_KeyVnum), MT_INT, 1, NULL },
	{ 0, 0, 14, 22, 23, XOFFSET(m_KeyName), MT_CSTRING, 1, NULL },
	{ '2', 'c', 16, 2, 70, XOFFSET(m_Desc), MT_CSTRING, 1, MenuStringFn },
	{ '2', 'd', 12, 48, 12, XOFFSET(m_KeyWords [0]), MT_CSTRING, 1, MenuStringFn },
	{ '2', 'e', 13, 48, 12, XOFFSET(m_KeyWords [1]), MT_CSTRING, 1, MenuStringFn },
	{ '2', 'f', 14, 48, 12, XOFFSET(m_KeyWords [2]), MT_CSTRING, 1, MenuStringFn },
	{ '2', 'g', 15, 48, 12, XOFFSET(m_KeyWords [3]), MT_CSTRING, 1, MenuStringFn },
	{ '2', 'h', 12, 62, 12, XOFFSET(m_KeyWords [4]), MT_CSTRING, 1, MenuStringFn },
	{ '2', 'i', 13, 62, 12, XOFFSET(m_KeyWords [5]), MT_CSTRING, 1, MenuStringFn },
	{ '2', 'j', 14, 62, 12, XOFFSET(m_KeyWords [6]), MT_CSTRING, 1, MenuStringFn },
	{ '2', 'k', 15, 62, 12, XOFFSET(m_KeyWords [7]), MT_CSTRING, 1, MenuStringFn },
	{ 0, 0, 0, 0, 0, 0, MT_END }
};


CMenuData	*RoomMenuData [] = { RoomPage_A, RoomPage_B, RoomPage_C, NULL };