using System;
using System.Threading;
using Woodpecker.Core;
using Woodpecker.Net.Game.Messages;
using Woodpecker.Game.Rooms.Units;
using Woodpecker.Game.Rooms.Instances.Interaction;
namespace Woodpecker.Game.Rooms.Instances
{
///
/// Represents an instance of a room.
///
public partial class roomInstance
{
#region Fields
///
/// The database ID of the room this room instance represents.
///
public int roomID;
///
/// The Woodpecker.Game.Rooms.roomInformation object containing information about the room.
///
public roomInformation Information;
private Thread roomWorker;
#endregion
#region Constructors
///
/// Tries to initialize the room instance for a given room. The room is destroyed on errors.
///
/// The database ID of the room to construct an instance of.
public roomInstance(int ID)
{
this.roomID = ID;
this.Information = Engine.Game.Rooms.getRoomInformation(ID);
if (this.Information == null) // Invalid room
{
Engine.Game.Rooms.destroyRoomInstance(ID);
return;
}
this.loadItems();
this.generateFloorMap();
this.gridUnit = new bool[this.gridState.GetUpperBound(0) + 1, this.gridState.GetUpperBound(1) + 1];
if (this.Information.isUserFlat)
{
foreach (Items.floorItem lItem in this.floorItems)
{
if (lItem.Definition.Behaviour.canStandOnTop && lItem.Definition.Sprite == "nest")
this.loadRoomPet(lItem.ID, 0, 0);
}
}
this.roomWorker = new Thread(workerLoop);
this.roomWorker.Start();
Logging.Log("Initialized room instance for room " + this.roomID + ".", Logging.logType.roomInstanceEvent);
}
#endregion
#region Methods
///
/// Removes all users from the room and nullifies all objects.
///
public void Destroy()
{
this.roomWorker.Abort();
this.roomWorker = null;
if (this.userAmount > 0) // Users in room
{
// Broadcoast 'kick' message
serverMessage Notify = new serverMessage(18); // "@R"
sendMessage(Notify);
Notify = null;
Type pCommonReactor = typeof(roomReactor);// new roomReactor().GetType();
Type pFlatReactor = typeof(flatReactor);
lock (this.roomUsers)
{
foreach (roomUser lRoomUser in this.roomUsers.Values)
{
if (this.Information.isUserFlat)
lRoomUser.Session.gameConnection.reactorHandler.unRegister(pFlatReactor);
else
lRoomUser.Session.gameConnection.reactorHandler.unRegister(pCommonReactor);
lRoomUser.Session.roomID = 0;
lRoomUser.Session.roomInstance = null;
}
}
this.roomUsers.Clear();
}
this.updateUserAmount();
this.roomUsers = null;
this.roomUnitIdentifiers.Clear(); this.roomUnitIdentifiers = null;
this.enteringSessions.Clear(); this.enteringSessions = null;
this.saveItems();
this.unloadItems();
this.Information = null;
this.gridState = null;
this.gridHeight = null;
this.gridUnit = null;
}
///
/// Sends a string with a server message to all active room users.
///
/// The message string to send. Use char1 for breaking messages.
public void sendMessage(string Message)
{
Logging.Log("Sending to room " + this.roomID + ": " + Message, Logging.logType.serverMessageEvent);
lock (roomUsers)
{
foreach (roomUser lUser in this.roomUsers.Values)
{
lUser.Session.gameConnection.sendMessage(Message);
}
}
}
///
/// Sends a serverMessage object to all active room users in the room.
///
/// The serverMessage object to send.
public void sendMessage(serverMessage Message)
{
this.sendMessage(Message.ToString());
}
#region Delayed message sending
///
/// Sends a string with a server message to all active room users, after a given delay in milliseconds.
///
/// The message string to send. Use char1 for breaking messages.
/// The amount of milliseconds to sleep before sending the message.
public void sendMessage(string Message, int delayMilliseconds)
{
new broadcoastDelayedMessage(this.sendDelayedMessage).BeginInvoke(Message, delayMilliseconds, null, null);
}
///
/// Sends a serverMessage object to all active room users in the room, after a given delay in milliseconds.
///
/// The serverMessage object to send.
/// The amount of milliseconds to sleep before sending the message.
public void sendMessage(serverMessage Message, int delayMilliseconds)
{
this.sendMessage(Message.ToString(), delayMilliseconds);
}
private delegate void broadcoastDelayedMessage(string Message, int delayMilliseconds);
///
/// Sends a string with a server message to all active room users, after a given delay in milliseconds. Invoke this method on a separate thread.
///
/// The message string to send. Use char1 for breaking messages.
/// The amount of milliseconds to sleep before sending the message.
private void sendDelayedMessage(string Message, int delayMilliseconds)
{
Thread.Sleep(delayMilliseconds);
this.sendMessage(Message);
}
#endregion
private void workerLoop()
{
try
{
while (this.roomWorker != null)
{
if (this.hasPets)
this.runPetActors();
this.refreshRoomUnitStatuses();
if (this.hasRollers)
this.runRollers();
Thread.Sleep(460); // 460
}
}
catch (ThreadAbortException) { }
}
#endregion
}
}