/*
Thor Server Project
Copyright 2008 Joe Hegarty
This file is part of The Thor Server Project.
The Thor Server Project is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The Thor Server Project is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with The Thor Server Project. If not, see .
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Timers;
using System.Threading;
using ThorServer.Game.Furni;
using ThorServer.Core;
using ThorServer.Utilities;
using ThorServer.Game.Rooms;
using ThorServer.Game.Rooms.Pathfinding;
namespace ThorServer.Game.Rooms.Interactor
{
public partial class RoomInteractor
{
private bool mHasRollers = false;
private const float MaxStackHeight = 3.3f;
public void RequestDecorateRoom(int itemId, int userId)
{
if (InstanceManager.Game.Furni.FurniExists(itemId))
{
FurniInfo info = InstanceManager.Game.Furni.GetFurni(itemId);
if (info.Flags.Decoration && info.OwnerID == userId)
{
if (info.FurniSprite == "wallpaper")
{
mRoomInstance.RoomInfo.Wallpaper = int.Parse(info.FurniVar);
}
else if (info.FurniSprite == "floor")
{
mRoomInstance.RoomInfo.Floor = int.Parse(info.FurniVar);
}
InstanceManager.Game.Rooms.UpdateRoom(mRoomInstance.RoomInfo);
ClientMessage mMessage = new ClientMessage();
mMessage.Init(46); //@n
mMessage.appendString(info.FurniSprite);
mMessage.appendString("/");
mMessage.appendString(info.FurniVar);
mRoomInstance.RoomBroadcast(mMessage);
InstanceManager.Game.Furni.DeleteFurni(info.FurniID);
}
}
}
public void RequestPickupFloorStuff(int itemId, int userId)
{
if (ContainsItem(itemId))
{
FurniInfo furni = GetFurniObject(itemId);
if (furni != null)
{
if (!furni.Flags.WallItem)
{
InstanceManager.Game.Furni.PickupItem(itemId, userId);
mFloorFurni = InstanceManager.Game.Furni.GetRoomFloorFurni(mRoomInstance.RoomInfo.RoomID);
ClientMessage mMessage = new ClientMessage();
mMessage.Init(94); // A^
mMessage.appendInt(itemId);
mRoomInstance.RoomBroadcast(mMessage);
GenerateMaps();
mMessage.Init(31); //@_
mMessage.appendString(ClientMap);
mRoomInstance.RoomBroadcast(mMessage);
// Remove statuses on users effected by this item
UpdateChangedUsers(furni.PosX, furni.PosY);
Dictionary affectedTiles = GetAffectedTiles(furni);
foreach (AffectedTile affectedTile in affectedTiles.Values)
{
UpdateChangedUsers(affectedTile.X, affectedTile.Y);
}
}
}
}
}
public void RequestPickupWallItem(int itemId, int userId)
{
if (ContainsItem(itemId))
{
FurniInfo info = GetFurniObject(itemId);
if (info != null)
{
if (info.Flags.WallItem)
{
if (!info.Flags.StickyNote) //Can't pick up stickies
{
InstanceManager.Game.Furni.PickupItem(itemId, userId);
mWallFurni = InstanceManager.Game.Furni.GetRoomWallFurni(mRoomInstance.RoomInfo.RoomID);
ClientMessage mMessage = new ClientMessage();
mMessage.Init(84); // AT
mMessage.appendInt(itemId);
mRoomInstance.RoomBroadcast(mMessage);
}
}
}
}
}
public void RequestDeleteSticky(int itemId, int userId, long sessionId)
{
if (ContainsItem(itemId))
{
FurniInfo info = GetFurniObject(itemId);
if (info.Flags.StickyNote)
{
InstanceManager.Game.Furni.DeleteFurni(itemId);
mWallFurni = InstanceManager.Game.Furni.GetRoomWallFurni(mRoomInstance.RoomInfo.RoomID);
ClientMessage mMessage = new ClientMessage();
mMessage.Init(84); // AT
mMessage.appendInt(itemId);
mRoomInstance.RoomBroadcast(mMessage);
}
else
{
RequestPickupWallItem(itemId, userId);
InstanceManager.Sessions.InvokeReactorMethod(sessionId, "UpdateHandInvoker");
}
}
}
public void RequestChangeStickyData(int itemId, string newMessage, int newItemType, long sessionId)
{
if (ContainsItem(itemId))
{
FurniInfo info = GetFurniObject(itemId);
if (info != null)
{
if (info.Flags.StickyNote)
{
if (newItemType > 0) InstanceManager.Game.Furni.SetItemType(itemId, newItemType);
if (newMessage.Length > 685) newMessage = newMessage.Substring(0, 685);
newMessage = SpecialFiltering.FilterChars("2,9,47", newMessage);
InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, newMessage);
mWallFurni = InstanceManager.Game.Furni.GetRoomWallFurni(mRoomInstance.RoomInfo.RoomID);
info = GetFurniObject(itemId);
ClientMessage message = new ClientMessage();
message.Init(85); //AU
message.appendInt(itemId);
message.appendChar(9);
message.appendString(info.FurniSprite);
message.appendChar(9);
message.appendString(" ");
message.appendString(info.WallLocation);
message.appendChar(9);
message.appendString(info.Col);
mRoomInstance.RoomBroadcast(message);
}
}
}
}
public void RequestWallMoveItem(int itemId, string newPos, long sessionId)
{
FurniInfo info = InstanceManager.Game.Furni.GetFurni(itemId);
if (info.OwnerID == mRoomInstance.GetUser(sessionId).UserInfo.userId)
{
if (info.Flags.StickyNote)
{
int left = int.Parse(info.FurniVar);
if (left > 0)
{
int newFurni = InstanceManager.Game.Furni.CreateNewFurni(info.FurniTypeId, mRoomInstance.GetUser(sessionId).UserInfo.userId);
left--;
if (left == 0)
{
InstanceManager.Game.Furni.DeleteFurni(itemId);
}
else
{
InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, left.ToString());
}
itemId = newFurni;
}
else
{
InstanceManager.Game.Furni.DeleteFurni(itemId);
}
}
newPos = WallPositionCheck(newPos);
if (newPos != null)
{
InstanceManager.Game.Furni.MoveWallItem(itemId, newPos, mRoomInstance.RoomInfo.RoomID, mRoomInstance.RoomInfo.RoomOwner);
mWallFurni = InstanceManager.Game.Furni.GetRoomWallFurni(mRoomInstance.RoomInfo.RoomID);
FurniInfo newInfo = GetFurniObject(itemId);
ClientMessage mMessage = new ClientMessage();
mMessage.Init(83); //AS
mMessage.appendString(ProcessWallFurniDefinition(newInfo));
mRoomInstance.RoomBroadcast(mMessage);
}
}
}
//This function is based on the one from "Holograph Emulator"
public string WallPositionCheck(string wallPosition)
{
//:w=3,2 l=9,63 l
try
{
if (wallPosition.Contains(Convert.ToChar(13))) return null;
if (wallPosition.Contains(Convert.ToChar(9))) return null;
string[] posD = wallPosition.Split(' ');
if (posD[2] != "l" && posD[2] != "r")
return null;
string[] widD = posD[0].Substring(3).Split(',');
int widthX = int.Parse(widD[0]);
int widthY = int.Parse(widD[1]);
if (widthX < 0 || widthY < 0 || widthX > 200 || widthY > 200)
return null;
string[] lenD = posD[1].Substring(2).Split(',');
int lengthX = int.Parse(lenD[0]);
int lengthY = int.Parse(lenD[1]);
if (lengthX < 0 || lengthY < 0 || lengthX > 200 || lengthY > 200)
return null;
return ":w=" + widthX + "," + widthY + " " + "l=" + lengthX + "," + lengthY + " " + posD[2];
}
catch
{
return null;
}
}
public void RequestMoveFloorItem(int itemId, int newX, int newY, int newRot, bool firstTime, long sessionId)
{
FurniInfo item = GetFurniObject(itemId);
mFloorFurni.Remove(item);
bool result = ExecuteFloorMoveItem(item, itemId, newX, newY, newRot, firstTime, sessionId);
if (!result)
{
mFloorFurni.Add(item);
}
SendFurniMovement(firstTime, !result, itemId, sessionId);
}
private bool ExecuteFloorMoveItem(FurniInfo item, int itemId, int newX, int newY, int newRot, bool firstTime, long sessionId)
{
int furniCount = 0;
int rollerCount = 0;
//Work out new affectedTiles
Dictionary affectedTiles = GetAffectedTiles(item.L, item.W, newX, newY, newRot);
//Verify the new tiles exist
if (!ValidTile(item.PosX, item.PosY)) return false;
foreach (AffectedTile tile in affectedTiles.Values) { if (!ValidTile(tile.X, tile.Y)) return false; }
//Verify the user has rights, or owns the item if they are dropping it
if (firstTime && item.OwnerID != mRoomInstance.GetUser(sessionId).UserInfo.userId) return false;
if (!firstTime && item.RoomID != mRoomInstance.RoomInfo.RoomID) return false;
//Verify if it's the first time and not the users room, the item is tradeable
if (firstTime && mRoomInstance.RoomInfo.RoomOwner != mRoomInstance.GetUser(sessionId).UserInfo.userId && item.CanTrade == false) return false;
//Calculate the new height according to the heightmap
float newZ = mHeightMap[newX, newY];
//Is the item trying to stack on itself?
if (item.PosRotation == newRot && item.PosX == newX && item.PosY == newY && item.PosZ != newZ) return false;
//Check it's not a bad heightmap tile
if (mClientMap[newX, newY] == "x") return false;
foreach (AffectedTile tile in affectedTiles.Values) { if (mClientMap[tile.X, tile.Y] == "x") return false; }
//Check for players
if (mPlayerMap[newX, newY] && !(item.PosRotation != newRot && item.PosX == newX && item.PosY == newY)) return false;
foreach (AffectedTile tile in affectedTiles.Values) { if (mPlayerMap[tile.X, tile.Y]) return false; }
//Get the furniture counts (not including this item)
foreach (FurniInfo tmp in mFloorFurni) { furniCount++; if (tmp.Flags.IsRoller) rollerCount++; }
//Get the affected objects
List objectsOnTile = GetFurniObjects(newX, newY);
List objectsAffected = new List();
List objectsComplete = new List();
foreach (AffectedTile tile in affectedTiles.Values)
{
List objectsTmp = GetFurniObjects(tile.X, tile.Y);
if (objectsTmp != null)
{
objectsAffected.AddRange(objectsTmp);
}
}
//Check the item isn't a roller and furni exists
if (objectsComplete.Count > 0 && item.Flags.IsRoller) return false;
if (objectsOnTile == null) objectsOnTile = new List();
objectsComplete.AddRange(objectsOnTile);
if (objectsAffected == null) objectsAffected = new List();
objectsComplete.AddRange(objectsAffected);
//Check you can stack the item
if (objectsComplete.Count > 0 && !item.Flags.CanStack) return false;
//Check for nonstackable items and rollers
foreach (FurniInfo info in objectsComplete)
{
if (!info.Flags.CanStackOn || (info.Flags.IsRoller && (item.W > 1 || item.L > 1))) return false;
}
//Rotating the item, should remain at the same height for now
if (item.PosRotation != newRot && item.PosX == newX && item.PosY == newY) newZ = item.PosZ;
//Are any of the other tiles higher?
foreach (FurniInfo info in objectsAffected)
{
if (info.TotalHeight > newZ) newZ = info.TotalHeight;
}
//Impose stacking limit
if (newZ > MaxStackHeight)
{
newZ = MaxStackHeight;
}
//Impose furni limit
if (furniCount >= 125 && firstTime)
{
ClientMessage mMessage = new ClientMessage();
mMessage.Init(139); //BK
mMessage.appendString(InstanceManager.Game.Externals.GetTextValue("room_alert_furni_limit"));
mRoomInstance.SendMessage(mMessage, sessionId);
return false;
}
//Impose roller limit
if (item.Flags.IsRoller)
{
if (rollerCount >= 10 && firstTime)
{
ClientMessage mMessage = new ClientMessage();
mMessage.Init(139); //BK
mMessage.appendString(InstanceManager.Game.Externals.GetTextValue("queue_tile_limit"));
mRoomInstance.SendMessage(mMessage, sessionId);
return false;
}
}
//Ensure it's a valid rotation
if (newRot != 0 && newRot != 2 && newRot != 4 && newRot != 6 && newRot != 8) newRot = 0;
//Move the item
int oldX = item.PosX; int oldY = item.PosY;
affectedTiles = GetAffectedTiles(item);
InstanceManager.Game.Furni.MoveFloorItem(itemId, newX, newY, newZ, newRot, mRoomInstance.RoomInfo);
mFloorFurni = InstanceManager.Game.Furni.GetRoomFloorFurni(mRoomInstance.RoomInfo.RoomID);
GenerateMaps();
// Remove statuses on users affected by this item
UpdateChangedUsers(oldX, oldY);
foreach (AffectedTile affectedTile in affectedTiles.Values)
{
UpdateChangedUsers(affectedTile.X, affectedTile.Y);
}
return true;
}
public void SendFurniMovement(bool firstTime, bool badTile, int itemId, long sessionId)
{
FurniInfo newInfo = GetFurniObject(itemId);
string data = ProcessFloorFurniDefinition(newInfo);
ClientMessage mMessage = new ClientMessage();
if (firstTime)
{
mMessage.Init(93); // A]
}
else
{
mMessage.Init(95); // A_
}
mMessage.appendString(data);
if (!badTile)
{
mRoomInstance.RoomBroadcast(mMessage);
GenerateMaps();
mMessage.Init(31); //@_
mMessage.appendString(ClientMap);
mRoomInstance.RoomBroadcast(mMessage);
}
else
{
if(!firstTime) mRoomInstance.SendMessage(mMessage, sessionId);
}
}
public void TeleporterGoIn(int itemId, RoomUser user)
{
FurniInfo item = GetFurniObject(itemId);
if (item != null)
{
if (item.Flags.IsTeleport)
{
if (TilesTouching(item.PosX, item.PosY, user.CurrentX, user.CurrentY) && PlayerCheck(item.PosX, item.PosY) == false)
{
user.IsMoving = true;
user.TargetX = item.PosX;
user.TargetY = item.PosY;
user.AllowOveride = true;
user.Path.Clear();
PathFinderNode node = new PathFinderNode();
node.X = item.PosX;
node.Y = item.PosY;
user.Path.Add(node);
}
}
}
}
public void TeleporterActivate(int itemId, RoomUser user)
{
FurniInfo item = GetFurniObject(itemId);
if (item != null)
{
new ProcessTeleporterDelegate(ProcessTeleporter).BeginInvoke(item, user, null, null);
}
}
private delegate void ProcessTeleporterDelegate(FurniInfo info, RoomUser user);
private void ProcessTeleporter(FurniInfo Teleporter1, RoomUser user)
{
FurniInfo Teleporter2 = null;
Point invalidPoint = new Point(Teleporter1.PosX, Teleporter1.PosY);
if (Teleporter1.PosRotation == 0 || Teleporter1.PosRotation == 2) invalidPoint.X++;
if (Teleporter1.PosRotation == 4) invalidPoint.Y++;
if (InstanceManager.Game.Furni.FurniExists(Teleporter1.TeleportId))
{
Teleporter2 = InstanceManager.Game.Furni.GetFurni(Teleporter1.TeleportId);
}
if (!user.UserLocked)
{
user.UserLocked = true;
Thread.Sleep(1000);
if (Teleporter1.PosX == user.CurrentX && Teleporter1.PosY == user.CurrentY)
{
ClientMessage message = new ClientMessage();
if (Teleporter2 != null && Teleporter2.RoomID > 0 && Teleporter1.Flags.IsTeleport && Teleporter2.Flags.IsTeleport)
{
message.Init(89); //AY
message.appendInt(Teleporter1.FurniID);
message.appendString("/");
message.appendString(user.UserInfo.sUsername);
message.appendString("/");
message.appendString(Teleporter1.FurniSprite);
mRoomInstance.RoomBroadcast(message);
if (Teleporter2.RoomID == Teleporter1.RoomID) //Same room
{
Thread.Sleep(2000);
Teleporter2 = InstanceManager.Game.Furni.GetFurni(Teleporter1.TeleportId);
Teleporter1 = InstanceManager.Game.Furni.GetFurni(Teleporter1.FurniID);
if (Teleporter2.RoomID == Teleporter1.RoomID && Teleporter1.PosX == user.CurrentX && Teleporter1.PosY == user.CurrentY)
{
message.Init(92); //A\
message.appendInt(Teleporter2.FurniID);
message.appendString("/");
message.appendString(user.UserInfo.sUsername);
message.appendString("/");
message.appendString(Teleporter2.FurniSprite);
mRoomInstance.RoomBroadcast(message);
mPlayerMap[user.CurrentX, user.CurrentY] = false;
user.CurrentX = Teleporter2.PosX;
user.CurrentY = Teleporter2.PosY;
user.CurrentZ = Teleporter2.PosZ;
mRoomInstance.AnnounceUserStatus(user.SessionID, true);
mPlayerMap[user.CurrentX, user.CurrentY] = true;
user.UserLocked = false;
}
else
{
if (Teleporter1.PosX == user.CurrentX && Teleporter1.PosY == user.CurrentY)
{
RequestSetStuffDataFloorItem(Teleporter1.FurniID, "TRUE", user, FurniInfo.VarTypes.TempOpen);
RequestMovePlayer(user.SessionID, invalidPoint.X, invalidPoint.Y, null, true);
}
user.UserLocked = false;
}
}
else //In another room
{
InstanceManager.Sessions.GetSession(user.SessionID).authenticatedDoor = Teleporter2.FurniID;
InstanceManager.Sessions.GetSession(user.SessionID).authenticatedFlat = Teleporter2.RoomID;
message.Init(62); //@~
message.appendArgumentInt(Teleporter2.FurniID);
message.appendArgumentInt(Teleporter2.RoomID);
mRoomInstance.SendMessage(message, user.SessionID);
}
}
else //No linked teleporter exists
{
Thread.Sleep(700);
RequestSetStuffDataFloorItem(Teleporter1.FurniID, "TRUE", user, FurniInfo.VarTypes.TempOpen);
RequestMovePlayer(user.SessionID, invalidPoint.X, invalidPoint.Y, null, true);
user.UserLocked = false;
}
}
}
}
public void RequestSetStuffDataFloorItem(int itemId, string data, RoomUser user, FurniInfo.VarTypes overrideType)
{
FurniInfo item = GetFurniObject(itemId);
ClientMessage mMessage = new ClientMessage();
if (item != null)
{
if (overrideType != 0) item.VarType = overrideType;
switch (item.VarType)
{
case FurniInfo.VarTypes.TempOpen:
if (TilesTouching(item.PosX, item.PosY, user.CurrentX, user.CurrentY))
{
InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, "FALSE");
if (data == "TRUE") NotifyClientSetStuffTempOpen(itemId);
}
break;
case FurniInfo.VarTypes.TrueFalse:
if (TilesTouching(item.PosX, item.PosY, user.CurrentX, user.CurrentY))
{
if ((data == "TRUE" || data == "FALSE"))
{
InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, data);
NotifyClientSetStuffChange(itemId, data);
}
}
break;
case FurniInfo.VarTypes.DoorDivider:
if (user.HasAdmin || user.HasRights)
{
if (data == "O" || data == "C")
{
if (!PlayerCheck(item.PosX, item.PosY))
{
InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, data);
NotifyClientSetStuffChange(itemId, data);
mFloorFurni = InstanceManager.Game.Furni.GetRoomFloorFurni(mRoomInstance.RoomInfo.RoomID);
GenerateMaps();
}
}
}
break;
case FurniInfo.VarTypes.Dice:
if (TilesTouching(item.PosX, item.PosY, user.CurrentX, user.CurrentY))
{
if (data == "dice_roll" || data == "dice_off")
{
int newVal = 0;
if (data == "dice_roll") newVal = SpecialMath.RandomNumber(1, 6);
bool isRoll = newVal > 0;
int rollVal = (item.FurniID * 38) + newVal;
InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, newVal.ToString());
NotifyClientDiceRoll(item.FurniID, rollVal, isRoll);
}
}
break;
case FurniInfo.VarTypes.Bottle:
if (data == "dice_roll")
{
int newVal = SpecialMath.RandomNumber(0, 7);
bool isRoll = newVal > 0;
int rollVal = (item.FurniID * 38) + newVal;
InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, newVal.ToString());
NotifyClientDiceRoll(item.FurniID, rollVal, isRoll);
}
break;
case FurniInfo.VarTypes.OnOff:
if (data == "ON" || data == "OFF")
{
InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, data);
NotifyClientSetStuffChange(itemId, data);
}
break;
case FurniInfo.VarTypes.OpenOrClosed:
if (data == "O" || data == "C")
{
InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, data);
NotifyClientSetStuffChange(itemId, data);
}
break;
case FurniInfo.VarTypes.NumericalOff:
int tmpNum = -1;
if (int.TryParse(data, out tmpNum) || data == "OFF")
{
if (tmpNum >= -1 && tmpNum < 10 && !(tmpNum == -1 && data == "-1"))
{
InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, data);
NotifyClientSetStuffChange(itemId, data);
}
}
break;
}
}
}
public void RequestOpenPresent(int userId, int presentId, Users.UserInfo userInfo, long sessionId)
{
if (ContainsItem(presentId))
{
FurniInfo furni = GetFurniObject(presentId);
if (furni != null)
{
if (furni.Flags.Gift)
{
GiftInfo gift = InstanceManager.Game.Furni.GetGift(presentId);
int newId = 0;
InstanceManager.Game.Catalogue.BuyItem("0", gift.PurchaseCode, gift.Payload, ref userInfo, true, ref newId);
InstanceManager.Game.Furni.DeleteGift(presentId);
InstanceManager.Game.Furni.DeleteFurni(presentId);
mFloorFurni = InstanceManager.Game.Furni.GetRoomFloorFurni(mRoomInstance.RoomInfo.RoomID);
FurniInfo info = InstanceManager.Game.Furni.GetFurni(newId);
ClientMessage mMessage = new ClientMessage();
mMessage.Init(129); //BA
mMessage.appendString(info.FurniSprite);
mMessage.appendChar(13);
mMessage.appendString(info.FurniSprite);
if (info.Flags.WallItem)
{
mMessage.appendString(" ");
mMessage.appendString(info.Col);
mMessage.appendChar(13);
}
else
{
mMessage.appendChar(13);
mMessage.appendInt(info.L);
mMessage.appendChar(13);
mMessage.appendInt(info.W);
mMessage.appendChar(13);
mMessage.appendString(info.Col);
}
mRoomInstance.SendMessage(mMessage, sessionId);
mMessage.Init(94); // A^
mMessage.appendInt(presentId);
mRoomInstance.RoomBroadcast(mMessage);
GenerateMaps();
mMessage.Init(31); //@_
mMessage.appendString(ClientMap);
mRoomInstance.RoomBroadcast(mMessage);
}
}
}
}
private void NotifyClientSetStuffTempOpen(int itemId)
{
ClientMessage mMessage = new ClientMessage();
mMessage.Init(88); //AX
mMessage.appendString(itemId.ToString());
mMessage.appendChar(2);
mMessage.appendString("TRUE");
mMessage.appendChar(2);
mRoomInstance.RoomBroadcast(mMessage);
mMessage.Init(88); //AX
mMessage.appendString(itemId.ToString());
mMessage.appendChar(2);
mMessage.appendString("FALSE");
mMessage.appendChar(2);
new RoomInstance.RoomDelayBroadcastDelegate(mRoomInstance.RoomDelayBroadcast).BeginInvoke(mMessage, 1000, null, null);
}
private void NotifyClientSetStuffChange(int itemId, string data)
{
ClientMessage mMessage = new ClientMessage();
mMessage.Init(88); //AX
mMessage.appendString(itemId.ToString());
mMessage.appendChar(2);
mMessage.appendString(data);
mMessage.appendChar(2);
mRoomInstance.RoomBroadcast(mMessage);
}
private void NotifyClientDiceRoll(int itemId, int rollVal, bool isRoll)
{
ClientMessage mMessage = new ClientMessage();
mMessage.Init(90); //AZ
mMessage.appendString(itemId.ToString());
if (isRoll) mRoomInstance.RoomBroadcast(mMessage);
mMessage.appendString(" ");
mMessage.appendInt(rollVal);
if (isRoll)
{
new RoomInstance.RoomDelayBroadcastDelegate(mRoomInstance.RoomDelayBroadcast).BeginInvoke(mMessage, 2000, null, null);
}
else
{
mRoomInstance.RoomBroadcast(mMessage);
}
}
private FurniInfo GetFurniObject(int furniId)
{
foreach (FurniInfo info in mFloorFurni)
{
if (info.FurniID == furniId)
{
return info;
}
}
foreach (FurniInfo info in mWallFurni)
{
if (info.FurniID == furniId)
{
return info;
}
}
return InstanceManager.Game.Furni.GetFurni(furniId);
}
public bool ContainsItem(int furniId)
{
foreach (FurniInfo info in mFloorFurni)
{
if (info.FurniID == furniId)
{
return true;
}
}
foreach (FurniInfo info in mWallFurni)
{
if (info.FurniID == furniId)
{
return true;
}
}
return false;
}
public List GetFurniObjects(int x, int y)
{
List results = new List();
foreach (FurniInfo info in mFloorFurni)
{
if (info.PosX == x && info.PosY == y)
{
results.Add(info);
}
Dictionary pointList = GetAffectedTiles(info);
foreach (AffectedTile point in pointList.Values)
{
if (point.X == x && point.Y == y)
{
results.Add(info);
}
}
}
if (results.Count > 0)
{
return results;
}
else
{
return null;
}
}
private int FindTileOffset(FurniInfo info, int x, int y)
{
Dictionary pointList = GetAffectedTiles(info);
foreach (int tileOffset in pointList.Keys)
{
if (pointList[tileOffset].X == x && pointList[tileOffset].Y == y)
{
return pointList[tileOffset].I;
}
}
return -1;
}
public string BuildFloorObjectList()
{
int furniCount = mFloorFurni.Count();
StringBuilder sb = new StringBuilder();
foreach (FurniInfo info in mFloorFurni)
{
if (info.PublicFurni && !info.Flags.InvisibleToClient)
{
sb.Append(ProcessFloorObjectDefinition(info));
}
}
return sb.ToString();
}
public string BuildFloorFurniList()
{
int furniCount = 0;
StringBuilder sb = new StringBuilder();
foreach (FurniInfo info in mFloorFurni)
{
if (!info.PublicFurni && !info.Flags.InvisibleToClient)
{
furniCount++;
sb.Append(ProcessFloorFurniDefinition(info));
}
}
return ArgumentEncoding.encodeInt(furniCount) + sb.ToString();
}
public string BuildWallFurniList()
{
StringBuilder sb = new StringBuilder();
foreach (FurniInfo info in mWallFurni)
{
sb.Append(ProcessWallFurniDefinition(info));
sb.Append(Convert.ToChar(13));
}
return sb.ToString();
}
private string ProcessFloorObjectDefinition(FurniInfo info)
{
StringBuilder sb = new StringBuilder();
sb.Append(info.FurniID.ToString());
sb.Append(" ");
sb.Append(info.FurniSprite);
sb.Append(" ");
sb.Append(info.PosX);
sb.Append(" ");
sb.Append(info.PosY);
sb.Append(" ");
sb.Append(info.PosZ);
sb.Append(" ");
sb.Append(info.PosRotation);
sb.Append(Convert.ToChar(13).ToString());
return sb.ToString();
}
private string ProcessFloorFurniDefinition(FurniInfo info)
{
StringBuilder sb = new StringBuilder();
sb.Append(info.FurniID);
sb.Append(Convert.ToChar(2));
sb.Append(info.FurniSprite);
sb.Append(Convert.ToChar(2));
sb.Append(ArgumentEncoding.encodeInt(info.PosX));
sb.Append(ArgumentEncoding.encodeInt(info.PosY));
sb.Append(ArgumentEncoding.encodeInt(info.W));
sb.Append(ArgumentEncoding.encodeInt(info.L));
sb.Append(ArgumentEncoding.encodeInt(info.PosRotation));
sb.Append(info.PosZ.ToString().Replace(',', '.'));
sb.Append(Convert.ToChar(2));
sb.Append(info.Col);
sb.Append(Convert.ToChar(2));
sb.Append(Convert.ToChar(2));
sb.Append(ArgumentEncoding.encodeInt(info.TeleportId));
sb.Append(info.FurniVar);
sb.Append(Convert.ToChar(2));
return sb.ToString();
}
private string ProcessWallFurniDefinition(FurniInfo wallItem)
{
StringBuilder sb = new StringBuilder();
sb.Append(wallItem.FurniID.ToString());
sb.Append(Convert.ToChar(9));
sb.Append(wallItem.FurniSprite);
sb.Append(Convert.ToChar(9));
sb.Append(" ");
sb.Append(Convert.ToChar(9));
sb.Append(wallItem.WallLocation);
sb.Append(Convert.ToChar(9));
sb.Append(wallItem.Col);
return sb.ToString();
}
public class AffectedTile
{
int mX;
int mY;
int mI;
public AffectedTile(int x, int y, int i)
{
mX = x;
mY = y;
mI = i;
}
public int X
{
get
{
return mX;
}
}
public int Y
{
get
{
return mY;
}
}
public int I
{
get
{
return mI;
}
}
}
}
}