// --------------------------------------------------------------------------
// Citadel: HallEdit.CPP
//
// Code for the aide/sysop to edit halls.

#include "ctdl.h"
#pragma hdrstop

#include "room.h"
#include "msg.h"
#include "libovl.h"
#include "log.h"
#include "group.h"
#include "hall.h"
#include "miscovl.h"


// --------------------------------------------------------------------------
// Contents
//
// globalhall() 	adds/removes rooms from current hall
// hallfunc()		adds/removes room from current hall
// xhallfunc()		called by hallfunc() for each hall
// killhall()		sysop special to kill a hall
// newhall()		sysop special to add a new hall
// renamehall() 	sysop special to rename a hall
// windowfunc() 	windows/unwindows room from current hall

static int xhallfunc(int roomslot, h_slot hallslot, int xyn, Bool AddToAideMsg);


// --------------------------------------------------------------------------
// globalhall(): Adds/removes rooms from hall.

void globalhall(void)
	{
	label hallname;

	Bool changed_room = FALSE;

	doCR();

	do
		{
		getString(cfg.Lhall_nym, hallname, LABELSIZE, TRUE,
				ECHO, HallData->GetEntry(TI()thisHall)->GetName());

		if (*hallname == '?')
			{
			ListHalls(FALSE);
			}
		} while (*hallname == '?');

	normalizeString(hallname);
	if (!*hallname)
		{
		return;
		}

	h_slot hallslot = partialhall(hallname);

	if (hallslot == CERROR)
		{
		CRmPrintfCR(getmsg(157), cfg.Lhall_nym, hallname);
		return;
		}

	for (r_slot roomslot = 0; roomslot < cfg.maxrooms; roomslot++)
		{
		if (IsRoomInuse(roomslot))
			{
			const int ret = xhallfunc(roomslot, hallslot, 3, TRUE);

			if (ret == CERROR)
				{
				break;
				}

			if (ret)
				{
				changed_room = TRUE;
				}
			}
		}

	if (changed_room)
		{
		amPrintf(getsysmsg(322), bn, TI()CurrentUser->GetName(),
				cfg.Lhall_nym, HallData->GetEntry(hallslot)->GetName(), bn);

		SaveAideMess(HallData->GetEntry(hallslot)->IsOwned() ?
				HallData->GetEntry(hallslot)->IsBoolGroup() ?
				GroupData->GetEntry(1)->GetName() :
				GroupData->GetEntry(HallData->GetEntry(hallslot)->
				GetGroupNumber())->GetName() : NULL);
		}

	HallData->Save();
	}


// --------------------------------------------------------------------------
// hallfunc(): Adds/removes room from hall.

void hallfunc(void)
	{
	label roomname;
	label hallname;

	SetDoWhat(AIDEHALL);

	if (TI()CurrentUser->IsUsePersonalHall())
		{
		CRCRmPrintfCR(getmsg(477), cfg.Lhall_nym);
		return;
		}

	do
		{
		getString(getmsg(1279), roomname, LABELSIZE, TRUE, ECHO,
				GetRoomName(TI()thisRoom));

		if (*roomname == '?')
			{
			ListAllRooms(FALSE, TRUE, FALSE);
			}
		} while (*roomname == '?');

	normalizeString(roomname);
	if (!*roomname)
		{
		return;
		}

	r_slot roomslot = RoomExists(roomname);

	if (roomslot == CERROR)
		{
		roomslot = PartialRoomExists(roomname, TI()thisRoom, TRUE);
		}

	if (roomslot == CERROR)
		{
		CRmPrintfCR(getmsg(1066), cfg.Lroom_nym, roomname);
		return;
		}

	do
		{
		getString(cfg.Lhall_nym, hallname, LABELSIZE, TRUE, ECHO,
				HallData->GetEntry(TI()thisHall)->GetName());

		if (*hallname == '?')
			{
			ListHalls(FALSE);
			}
		} while (*hallname == '?');

	normalizeString(hallname);
	if (!*hallname)
		{
		return;
		}

	const h_slot hallslot = partialhall(hallname);

	if (hallslot == CERROR)
		{
		CRmPrintfCR(getmsg(157), cfg.Lhall_nym, hallname);
		return;
		}

	if (xhallfunc(roomslot, hallslot, 0, FALSE))
		{
		HallData->Save();
		}
	}


// --------------------------------------------------------------------------
// xhallfunc(): Called by hallfunc() for each hall.
//
// Return value:
//	TRUE	Room added/removed to/from hall.
//	FALSE	Room not added/removed to/from hall.
//	CERROR	User chose to abort operation.

static int xhallfunc(int roomslot, h_slot hallslot, int xyn, Bool AddToAideMsg)
	{
	const Bool StartInHall = HallData->GetEntry(hallslot)->IsRoomInHall(roomslot);

	char string[100];
	sprintf(string, StartInHall ? getmsg(482) : getmsg(485), cfg.Lroom_nym,
			GetRoomName(roomslot), cfg.Lhall_nym,
			HallData->GetEntry(hallslot)->GetName());

	const int yn = getYesNo(string, xyn);

	if (yn == 2)
		{
		return (CERROR);
		}

	if (yn)
		{
		HallData->GetEntry(hallslot)->SetRoomInHall(roomslot, !StartInHall);

		char TrapString[256];
		sprintf(TrapString, StartInHall ? getmsg(483) : getmsg(486),
				GetRoomName(roomslot),
				HallData->GetEntry(hallslot)->GetName(),
				TI()CurrentUser->GetName());

		trap(TrapString, T_AIDE);

		if (!AddToAideMsg)
			{
			Message *Msg = new Message;

			if (Msg)
				{
				sprintf(TrapString, StartInHall ? getmsg(1372) : getmsg(1373),
						cfg.Uroom_nym, GetRoomName(roomslot), cfg.Lhall_nym,
						HallData->GetEntry(hallslot)->GetName(),
						TI()CurrentUser->GetName());

				Msg->SetText(TrapString);

				if (HallData->GetEntry(hallslot)->IsOwned())
					{
					if (HallData->GetEntry(hallslot)->IsBoolGroup())
						{
						// Reserved_2
						Msg->SetGroup(GroupData->GetEntry(1)->
								GetName());
						}
					else
						{
						Msg->SetGroup(GroupData->GetEntry(HallData->
								GetEntry(hallslot)->GetGroupNumber())->
								GetName());
						}
					}

				Msg->SetRoomNumber(AIDEROOM);
				systemMessage(Msg);

				delete Msg;
				}
			else
				{
				mPrintf(getmsg(188), getmsg(695));
				}
			}
		else
			{
			amPrintf(StartInHall ? getmsg(484) : getmsg(487),
					GetRoomName(roomslot), bn);
			}
		}

	return (yn);
	}


// --------------------------------------------------------------------------
// killhall(): sysop special to kill a hall.

Bool killhall(const char *hn)
	{
	int empty = TRUE, i;
	label hallname;
	h_slot hallslot;
	char string[100];

	if (!hn)
		{
		doCR();

		do
			{
			getString(cfg.Lhall_nym, hallname, LABELSIZE, TRUE, ECHO,
					HallData->GetEntry(TI()thisHall)->GetName());

			if (*hallname == '?')
				{
				ListHalls(FALSE);
				}
			} while (*hallname == '?');

		normalizeString(hallname);
		if (!*hallname)
			{
			return (FALSE);
			}

		hallslot = partialhall(hallname);
		}
	else
		{
		hallslot = hallexists(hn);
		}

	if (hallslot == CERROR)
		{
		if (!hn)
			{
			CRmPrintfCR(getmsg(157), cfg.Lhall_nym, hallname);
			}

		return (FALSE);
		}

	if (hallslot == 0 || hallslot == 1)
		{
		if (!hn)
			{
			CRmPrintfCR(getmsg(766), HallData->GetEntry(0)->GetName(),
					HallData->GetEntry(1)->GetName(), cfg.Lhalls_nym);
			}

		return (FALSE);
		}

	// Check hall for any rooms
	for (i = 0; i < cfg.maxrooms && empty; i++)
		{
		if (IsRoomInuse(i) &&
				HallData->GetEntry(hallslot)->IsRoomInHall(i))
			{
			empty = FALSE;
			}
		}

	if (!empty && !hn)
		{
		CRmPrintfCR(getmsg(1120), cfg.Uhall_nym,
				HallData->GetEntry(hallslot)->GetName(), cfg.Lrooms_nym);

		TI()UserControl.SetOutFlag(OUTOK);

		TI()MRO.Verbose = FALSE;

		if (!TI()CurrentUser->IsWideRoom())
			{
			prtList(LIST_START);
			}

		for (i = 0; i < cfg.maxrooms && (TI()UserControl.GetOutFlag() != OUTSKIP); i++)
			{
			if (IsRoomInuse(i) &&
					HallData->GetEntry(hallslot)->IsRoomInHall(i))
				{
				printroomVer(i, FALSE);
				}
			}

		if (!TI()CurrentUser->IsWideRoom())
			{
			prtList(LIST_END);
			}
		else
			{
			doCR();
			}

		sprintf(string, getmsg(697), cfg.Lhall_nym,
				HallData->GetEntry(hallslot)->GetName());
		}

	TI()UserControl.SetOutFlag(IMPERVIOUS);

	if (hn || getYesNo(string, 0))
		{
		char trapstr[256];

		HallData->GetEntry(hallslot)->SetInuse(FALSE);
		HallData->GetEntry(hallslot)->SetOwned(FALSE);

		for (i = 0; i < cfg.maxrooms; i++)
			{
			HallData->GetEntry(hallslot)->SetRoomInHall(i, FALSE);
			HallData->GetEntry(hallslot)->SetWindowedIntoHall(i, FALSE);
			}

		HallData->Save();

		sprintf(trapstr, getmsg(489), HallData->GetEntry(hallslot)->GetName());
		trap(trapstr, T_SYSOP);

		if (TI()thisHall == hallslot)
			{
			TI()thisHall = 0;
			}

		return (TRUE);
		}
	else
		{
		return (FALSE);
		}
	}


// --------------------------------------------------------------------------
// newhall(): Sysop special to add a new hall.

Bool newhall(const char *name, const char *group, r_slot room)
	{
	label hallname, groupname;
	h_slot i, slot = 0;
	int groupslot;
	Bool test;

	// search for a free hall slot
	for (i = 0; i < cfg.maxhalls && !slot ; i++)
		{
		if (!HallData->GetEntry(i)->IsInuse())
			{
			slot = i;
			}
		}

	if (!slot)
		{
		if (!name)
			{
			CRmPrintf(getmsg(490), cfg.Uhall_nym);
			}

		return (FALSE);
		}

	if (name)
		{
		if (hallexists(name) != CERROR)
			{
			return (FALSE);
			}
		else
			{
			CopyStringToBuffer(hallname, name, LABELSIZE);
			}
		}
	else
		{
		test = FALSE;

		do
			{
			doCR();

			do
				{
				getString(cfg.Lhall_nym, hallname, LABELSIZE, TRUE, ECHO, ns);

				if (*hallname == '?')
					{
					ListHalls(FALSE);
					}
				} while (*hallname == '?');

			if (!*hallname)
				{
				return (FALSE);
				}

			if (hallexists(hallname) != CERROR)
				{
				CRmPrintf(getsysmsg(198), hallname, cfg.Lhall_nym);
				}
			else
				{
				test = TRUE;
				}

			} while (!test);
		}

	if (group)
		{
		if (*group)
			{
			groupslot = FindGroupByPartialName(group, FALSE);

			if (groupslot == CERROR)
				{
				return (FALSE);
				}
			}

		CopyStringToBuffer(groupname, group, LABELSIZE);
		}
	else
		{
		test = FALSE;

		do
			{
			char Prompt[128];

			sprintf(Prompt, getsysmsg(199), cfg.Lgroup_nym, cfg.Lhall_nym);

			do
				{
				getString(Prompt, groupname, LABELSIZE, TRUE, ECHO, ns);

				if (*groupname == '?')
					{
					ListGroups(TRUE);
					}
				} while (*groupname == '?');

			if (!*groupname)
				{
				test = TRUE;
				}
			else
				{
				groupslot = FindGroupByPartialName(groupname, FALSE);

				if (groupslot == CERROR)
					{
					CRmPrintfCR(getmsg(947), cfg.Lgroup_nym);
					}
				else
					{
					test = TRUE;
					}
				}

			} while (!test);
		}

	if (!*groupname)
		{
		HallData->GetEntry(slot)->SetOwned(FALSE);
		}
	else
		{
		HallData->GetEntry(slot)->SetOwned(TRUE);
		HallData->GetEntry(slot)->SetGroupNumber(groupslot);
		}

	HallData->GetEntry(slot)->SetName(hallname);
	HallData->GetEntry(slot)->SetInuse(TRUE);

	// make current room a window into current hall so we can get back
	HallData->GetEntry(TI()thisHall)->SetWindowedIntoHall(room, TRUE);

	// clear all rooms from new hall
	for (i = 0; i < cfg.maxrooms; i++)
		{
		HallData->GetEntry(slot)->SetRoomInHall(i, FALSE);
		HallData->GetEntry(slot)->SetWindowedIntoHall(i, FALSE);
		}

	// put current room in hall
	HallData->GetEntry(slot)->SetRoomInHall(room, TRUE);

	// make current room a window into new hall
	HallData->GetEntry(slot)->SetWindowedIntoHall(room, TRUE);

	if (name || getYesNo(getmsg(57), 0))
		{
		HallData->Save();

		char trapstr[256];
		sprintf(trapstr, getsysmsg(200), HallData->GetEntry(slot)->GetName());
		trap(trapstr, T_SYSOP);

		if (!name)
			{
			TI()thisHall = slot;
			}

		return (TRUE);
		}
	else
		{
		HallData->Load();
		return (FALSE);
		}
	}


// --------------------------------------------------------------------------
// renamehall(): Sysop special to rename a hall.

Bool renamehall(void)
	{
	label hallname, newname;
	g_slot groupslot;
	h_slot hallslot;
	char trapstr[256];

	Bool prtMess = !TI()CurrentUser->IsExpert();
	Bool quit = FALSE;

	doCR();

	do
		{
		getString(cfg.Lhall_nym, hallname, LABELSIZE, TRUE, ECHO,
				HallData->GetEntry(TI()thisHall)->GetName());

		if (*hallname == '?')
			{
			ListHalls(FALSE);
			}
		} while (*hallname == '?');

	normalizeString(hallname);
	if (!*hallname)
		{
		return (FALSE);
		}

	hallslot = partialhall(hallname);

	if (hallslot == CERROR)
		{
		CRmPrintfCR(getmsg(157), cfg.Lhall_nym, hallname);
		return (FALSE);
		}

	do
		{
		if (prtMess)
			{
			doCR();
			TI()UserControl.SetOutFlag(OUTOK);

			mPrintfCR(getsysmsg(201), HallData->GetEntry(hallslot)->GetName());

			if (HallData->GetEntry(hallslot)->IsOwned() &&
					HallData->GetEntry(hallslot)->IsBoolGroup())
				{
				mPrintf(getsysmsg(202), ns);
				ShowBooleanExpression(HallData->GetEntry(hallslot)->GetGroupExpression(), ShowGroup);
				}
			else
				{
				mPrintf(getsysmsg(202), HallData->GetEntry(hallslot)->IsOwned() ?
					GroupData->GetEntry(HallData->GetEntry(hallslot)->GetGroupNumber())->GetName() :
					getsysmsg(203));
				}

			doCR();

			if (!cfg.nonAideRoomOk)
				{
				displayYesNo(getsysmsg(204), HallData->GetEntry(hallslot)->IsEnterRoom());
				doCR();
				}
			else
				{
				HallData->GetEntry(hallslot)->SetEnterRoom(TRUE);
				}

			mPrintfCR(getsysmsg(205), HallData->GetEntry(hallslot)->IsDescribed() ?
					HallData->GetEntry(hallslot)->GetDescriptionFile() : getsysmsg(179));

			CRmPrintfCR(getmsg(868));

			prtMess = !TI()CurrentUser->IsExpert();
			}

		const int c = DoMenuPrompt(getmsg(616), NULL);

		if (!(HaveConnectionToUser()))
			{
			GroupData->Load();
			return (FALSE);
			}

		switch (toupper(c))
			{
			case 'N':
				{
				mPrintfCR(getmsg(248));

				char Prompt[128];

				sprintf(Prompt, getsysmsg(207), cfg.Lhall_nym);

				do
					{
					getString(Prompt, newname, LABELSIZE, TRUE, ECHO,
							HallData->GetEntry(hallslot)->GetName());

					if (*newname == '?')
						{
						ListHalls(FALSE);
						}
					} while (*newname == '?');

				normalizeString(newname);

				if (*newname && (hallexists(newname) != CERROR) &&
						!SameString(newname,
						HallData->GetEntry(hallslot)->GetName()))
					{
					CRmPrintfCR(getsysmsg(198), newname, cfg.Lhall_nym);
					}
				else
					{
					if (*newname)
						{
						HallData->GetEntry(hallslot)->SetName(newname);
						}
					}

				break;
				}

			case 'G':
				{
				char Prompt[128];

				mPrintfCR(getsysmsg(209), cfg.Lgroup_nym);

				if (HallData->GetEntry(hallslot)->IsBoolGroup())
					{
					CRmPrintf(getsysmsg(45));
					ShowBooleanExpression(HallData->GetEntry(hallslot)->
							GetGroupExpression(), ShowGroup);
					doCR();
					}

				char GroupName[256];

				sprintf(Prompt, getsysmsg(199), cfg.Lgroup_nym,
						cfg.Lhall_nym);

				do
					{
					getString(Prompt, GroupName, 255, TRUE, ECHO,
							(HallData->GetEntry(hallslot)->IsOwned() &&
							!HallData->GetEntry(hallslot)->IsBoolGroup()) ?
							GroupData->GetEntry(HallData->GetEntry(hallslot)->
							GetGroupNumber())->GetName() : ns);

					if (*GroupName == '?')
						{
						ListGroups(TRUE);
						}
					} while (*GroupName == '?');

				if (SameString(GroupName, spc))
					{
					HallData->GetEntry(hallslot)->SetOwned(FALSE);
					HallData->GetEntry(hallslot)->SetBoolGroup(FALSE);
					}
				else
					{
					groupslot = FindGroupByPartialName(GroupName, FALSE);

					if (*GroupName && (groupslot != CERROR))
						{
						HallData->GetEntry(hallslot)->SetOwned(TRUE);
						HallData->GetEntry(hallslot)->SetBoolGroup(FALSE);
						HallData->GetEntry(hallslot)->SetGroupNumber(groupslot);
						}
					else
						{
						if (*GroupName)
							{
							BoolExpr Expression;

							if (!CreateBooleanExpression(GroupName,
									TestGroupExists, Expression))
								{
								CRmPrintfCR(getmsg(946), cfg.Lgroup_nym,
										GroupName);
								}
							else
								{
								HallData->GetEntry(hallslot)->SetOwned(TRUE);
								HallData->GetEntry(hallslot)->SetBoolGroup(TRUE);
								HallData->GetEntry(hallslot)->SetGroupExpression(Expression);
								}
							}
						}
					}

				break;
				}


			case 'U':
				{
				if (!cfg.nonAideRoomOk)
					{
					HallData->GetEntry(hallslot)->SetEnterRoom(changeYesNo(getsysmsg(211),
							HallData->GetEntry(hallslot)->IsEnterRoom()));
					}
				else
					{
					BadMenuSelection(c);
					HallData->GetEntry(hallslot)->SetEnterRoom(TRUE);
					}

				break;
				}

			case 'D':
				{
				mPrintfCR(getsysmsg(213));

				if (getYesNo(getsysmsg(214),
						HallData->GetEntry(hallslot)->IsDescribed()))
					{
					label InputString;

					getString(getsysmsg(215), InputString, 12, FALSE, ECHO,
							HallData->GetEntry(hallslot)->GetDescriptionFile());

					normalizeString(InputString);

					HallData->GetEntry(hallslot)->SetDescriptionFile(InputString);

					if (InputString[0])
						{
						HallData->GetEntry(hallslot)->SetDescribed(TRUE);
						}
					else
						{
						HallData->GetEntry(hallslot)->SetDescribed(FALSE);
						}
					}
				else
					{
					HallData->GetEntry(hallslot)->SetDescribed(FALSE);
					}

				break;
				}

			case 'S':
				{
				mPrintfCR(getmsg(60));

				if (getYesNo(getmsg(652), FALSE))
					{
					quit = TRUE;
					}

				break;
				}

			case ESC:
			case 'A':
				{
				mPrintfCR(getmsg(653));

				if (getYesNo(getmsg(654), TRUE))
					{
					if (!GroupData->Load())
						{
						mPrintf(getmsg(656));
						}

					return (FALSE);
					}

				break;
				}

			case '\r':
			case '\n':
			case '?':
				{
				mPrintfCR(getmsg(351));

				prtMess = TRUE;
				break;
				}

			default:
				{
				BadMenuSelection(c);
				break;
				}
			}
		} while (!quit);

	sprintf(trapstr, getsysmsg(216), hallname,
			HallData->GetEntry(hallslot)->GetName());

	trap(trapstr, T_SYSOP);
	HallData->Save();

	return (TRUE);
	}


// --------------------------------------------------------------------------
// windowfunc(): Windows/unwindows room from current hall.

void windowfunc(void)
	{
	r_slot roomslot;
	h_slot hallslot;

	Bool test;

	SetDoWhat(AIDEWINDOW);

	if (TI()CurrentUser->IsUsePersonalHall())
		{
		CRCRmPrintfCR(getmsg(477), cfg.Lhall_nym);
		return;
		}

	do
		{
		label roomname;

		getString(getmsg(1279), roomname, LABELSIZE, TRUE, ECHO,
				GetRoomName(TI()thisRoom));

		if (!*roomname)
			{
			return;
			}

		if (*roomname == '?')
			{
			ListAllRooms(FALSE, FALSE, FALSE);
			test = FALSE;
			}
		else
			{
			roomslot = RoomExists(roomname);

			if (roomslot == CERROR)
				{
				roomslot = PartialRoomExists(roomname, TI()thisRoom, TRUE);
				}

			test = TRUE;
			if (roomslot == CERROR)
				{
				CRmPrintf(getmsg(157), cfg.Lroom_nym, roomname);
				test = FALSE;
				}
			}
		} while (!test);

	do
		{
		label hallname;

		getString(cfg.Lhall_nym, hallname, LABELSIZE, TRUE, ECHO,
				HallData->GetEntry(TI()thisHall)->GetName());

		normalizeString(hallname);
		if (!*hallname)
			{
			return;
			}

		if (*hallname == '?')
			{
			ListHalls(FALSE);
			test = FALSE;
			}
		else
			{
			hallslot = partialhall(hallname);

			test = TRUE;
			if (hallslot == CERROR)
				{
				CRmPrintfCR(getmsg(157), cfg.Lhall_nym, hallname);
				test = FALSE;
				}
			}
		} while (!test);

	if (HallData->GetEntry(hallslot)->IsWindowedIntoHall(roomslot))
		{
		char string[256];

		sprintf(string, getmsg(493), cfg.Lroom_nym, GetRoomName(roomslot),
				cfg.Lhall_nym, HallData->GetEntry(hallslot)->GetName());

		if (getYesNo(string,0))
			{
			HallData->GetEntry(hallslot)->SetWindowedIntoHall(roomslot, FALSE);

			char TrapString[256];
			sprintf(TrapString, getmsg(494),
					HallData->GetEntry(hallslot)->GetName(),
					GetRoomName(roomslot), TI()CurrentUser->GetName());

			trap(TrapString, T_AIDE);

			Message *Msg = new Message;

			if (Msg)
				{
				sprintf(TrapString, getmsg(1374), cfg.Uhall_nym,
						HallData->GetEntry(hallslot)->GetName(),
						cfg.Lroom_nym, GetRoomName(roomslot),
						TI()CurrentUser->GetName());

				Msg->SetText(TrapString);

				if (HallData->GetEntry(hallslot)->IsOwned())
					{
					if (HallData->GetEntry(hallslot)->IsBoolGroup())
						{
						Msg->SetGroup(GroupData->GetEntry(1)->
								GetName());
						}
					else
						{
						Msg->SetGroup(GroupData->GetEntry(HallData->
								GetEntry(hallslot)->GetGroupNumber())->
								GetName());
						}
					}

				Msg->SetRoomNumber(AIDEROOM);
				systemMessage(Msg);

				delete Msg;
				}
			else
				{
				mPrintf(getmsg(188), getmsg(702));
				}

			HallData->Save();
			}
		}
	else
		{
		char string[256];

		sprintf(string, getmsg(495), cfg.Lroom_nym, GetRoomName(roomslot),
				cfg.Lhall_nym, HallData->GetEntry(hallslot)->GetName());

		if (getYesNo(string,0))
			{
			HallData->GetEntry(hallslot)->SetWindowedIntoHall(roomslot, TRUE);

			char TrapString[256];
			sprintf(TrapString, getmsg(496),
					HallData->GetEntry(hallslot)->GetName(),
					GetRoomName(roomslot), TI()CurrentUser->GetName());

			trap(TrapString, T_AIDE);

			Message *Msg = new Message;

			if (Msg)
				{
				sprintf(TrapString, getmsg(1375), cfg.Uhall_nym,
						HallData->GetEntry(hallslot)->GetName(),
						cfg.Lroom_nym, GetRoomName(roomslot),
						TI()CurrentUser->GetName());
				Msg->SetText(TrapString);

				if (HallData->GetEntry(hallslot)->IsOwned())
					{
					if (HallData->GetEntry(hallslot)->IsBoolGroup())
						{
						Msg->SetGroup(GroupData->GetEntry(1)->
								GetName());
						}
					else
						{
						Msg->SetGroup(GroupData->GetEntry(HallData->
								GetEntry(hallslot)->GetGroupNumber())->
								GetName());
						}
					}

				Msg->SetRoomNumber(AIDEROOM);
				systemMessage(Msg);

				delete Msg;
				}
			else
				{
				mPrintf(getmsg(188), getmsg(702));
				}

			HallData->Save();

			//Maybe add target room to target hall too if not already there
			if (!HallData->GetEntry(hallslot)->IsRoomInHall(roomslot))
				{
				xhallfunc(roomslot, hallslot, 1, FALSE);
				}
			}
		}
	}
