mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
243 lines
8.5 KiB
C#
243 lines
8.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
using Lidgren.Network;
|
|
using SS3D_shared;
|
|
using SS3D_shared.HelperClasses;
|
|
|
|
namespace SS3d_server.Modules.Items
|
|
{
|
|
public class ItemManager
|
|
{
|
|
private Map.Map map;
|
|
private SS3DNetserver netServer;
|
|
private Mobs.MobManager mobManager;
|
|
private Dictionary<ushort, Item> itemDict; // ItemID, Item
|
|
private List<ushort> itemsToSend;
|
|
ushort lastID = 0;
|
|
private string itemAssemblyName;
|
|
private DateTime lastItemUpdateSent = DateTime.Now;
|
|
private double itemUpdateTime = 100;
|
|
private float fallSpeed = 5.0f; // Just a constant now (not acceleration) for testing.
|
|
|
|
|
|
public ItemManager(SS3DNetserver _netServer, Map.Map _map, Mobs.MobManager _mobManager)
|
|
{
|
|
netServer = _netServer;
|
|
map = _map;
|
|
mobManager = _mobManager;
|
|
itemDict = new Dictionary<ushort, Item>();
|
|
itemAssemblyName = typeof(Item).Assembly.ToString();
|
|
itemsToSend = new List<ushort>();
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
TimeSpan updateSpan = DateTime.Now - lastItemUpdateSent;
|
|
if (updateSpan.TotalMilliseconds > itemUpdateTime)
|
|
{
|
|
foreach (Item item in itemDict.Values)
|
|
{
|
|
UpdateItemPosition(item.itemID);
|
|
}
|
|
foreach (ushort itemID in itemsToSend)
|
|
{
|
|
SendItemUpdate(itemID);
|
|
}
|
|
itemsToSend.Clear();
|
|
lastItemUpdateSent = DateTime.Now;
|
|
}
|
|
|
|
}
|
|
|
|
private void UpdateItemPosition(ushort itemID)
|
|
{
|
|
Vector3 currentPos = itemDict[itemID].serverInfo.position;
|
|
Point arrayPosition = map.GetTileArrayPositionFromWorldPosition(currentPos);
|
|
double heightAboveTile = itemDict[itemID].serverInfo.position.Y - (map.GetHeightAboveTileAt(currentPos) + 1.0f);
|
|
if (heightAboveTile > 1.0)
|
|
{
|
|
if (heightAboveTile > fallSpeed)
|
|
{
|
|
itemDict[itemID].serverInfo.position.Y -= fallSpeed;
|
|
itemsToSend.Add(itemID);
|
|
}
|
|
else
|
|
{
|
|
itemDict[itemID].serverInfo.position.Y -= heightAboveTile;
|
|
itemsToSend.Add(itemID);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public void HandleNetMessage(NetIncomingMessage message)
|
|
{
|
|
ItemMessage messageType = (ItemMessage)message.ReadByte();
|
|
switch (messageType)
|
|
{
|
|
case ItemMessage.CreateItem:
|
|
HandleCreateItem(message);
|
|
break;
|
|
case ItemMessage.ClickItem:
|
|
HandleClickItem(message);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
private void HandleCreateItem(NetIncomingMessage message)
|
|
{
|
|
string name = message.ReadString();
|
|
float x = message.ReadFloat();
|
|
float y = message.ReadFloat();
|
|
float z = message.ReadFloat();
|
|
|
|
Type type = Type.GetType(name + "," + itemAssemblyName);
|
|
|
|
object newItem = Activator.CreateInstance(type);
|
|
lastID++;
|
|
|
|
itemDict[lastID] = (Item)newItem;
|
|
itemDict[lastID].serverInfo.position = new Vector3(x, y, z);
|
|
itemDict[lastID].itemID = lastID;
|
|
|
|
SendCreateItem(lastID);
|
|
}
|
|
|
|
private void HandleClickItem(NetIncomingMessage message)
|
|
{
|
|
ushort itemID = message.ReadUInt16();
|
|
ushort mobID = netServer.clientList[message.SenderConnection].mobID;
|
|
|
|
if (itemDict[itemID].holder == null && mobManager.mobDict[mobID].heldItem == null)
|
|
{
|
|
itemDict[itemID].holder = mobManager.mobDict[mobID];
|
|
mobManager.mobDict[mobID].heldItem = itemDict[itemID];
|
|
SendPickupItem(itemID, mobID);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
public void CreateItem(Type type, Vector3 pos)
|
|
{
|
|
object newItem = Activator.CreateInstance(type);
|
|
lastID++;
|
|
|
|
itemDict[lastID] = (Item)newItem;
|
|
itemDict[lastID].serverInfo.position = pos;
|
|
itemDict[lastID].itemID = lastID;
|
|
|
|
SendCreateItem(lastID);
|
|
}
|
|
|
|
// Message size ~288 bits (about 0.036kb).
|
|
// This means on map load if we had 40 players, and 500 items,
|
|
// to send every item to every player at round start would be
|
|
// around 720kb in total.
|
|
private void SendCreateItem(ushort itemID)
|
|
{
|
|
if (!itemDict.Keys.Contains(itemID))
|
|
{
|
|
return;
|
|
}
|
|
|
|
NetOutgoingMessage message = netServer.netServer.CreateMessage();
|
|
|
|
message.Write((byte)NetMessage.ItemMessage);
|
|
message.Write((byte)ItemMessage.CreateItem);
|
|
|
|
message.Write(itemDict[itemID].GetType().FullName);
|
|
message.Write(itemID);
|
|
message.Write((float)itemDict[itemID].serverInfo.position.X);
|
|
message.Write((float)itemDict[itemID].serverInfo.position.Y);
|
|
message.Write((float)itemDict[itemID].serverInfo.position.Z);
|
|
|
|
netServer.SendMessageToAll(message);
|
|
Console.WriteLine("Item sent with ID: " + itemID);
|
|
}
|
|
|
|
private void SendCreateItem(ushort itemID, NetConnection netConnection)
|
|
{
|
|
if (!itemDict.Keys.Contains(itemID))
|
|
{
|
|
return;
|
|
}
|
|
|
|
NetOutgoingMessage message = netServer.netServer.CreateMessage();
|
|
|
|
message.Write((byte)NetMessage.ItemMessage);
|
|
message.Write((byte)ItemMessage.CreateItem);
|
|
|
|
message.Write(itemDict[itemID].GetType().FullName);
|
|
message.Write(itemID);
|
|
message.Write((float)itemDict[itemID].serverInfo.position.X);
|
|
message.Write((float)itemDict[itemID].serverInfo.position.Y);
|
|
message.Write((float)itemDict[itemID].serverInfo.position.Z);
|
|
|
|
|
|
netServer.SendMessageTo(message, netConnection);
|
|
Console.WriteLine("Item sent with ID: " + itemID);
|
|
}
|
|
|
|
private void SendItemUpdate(ushort itemID)
|
|
{
|
|
if (!itemDict.Keys.Contains(itemID))
|
|
{
|
|
return;
|
|
}
|
|
Vector3 pos = itemDict[itemID].serverInfo.position;
|
|
|
|
NetOutgoingMessage message = netServer.netServer.CreateMessage();
|
|
message.Write((byte)NetMessage.ItemMessage);
|
|
message.Write((byte)ItemMessage.InterpolationPacket);
|
|
message.Write(itemID);
|
|
message.Write((float)pos.X);
|
|
message.Write((float)pos.Y);
|
|
message.Write((float)pos.Z);
|
|
netServer.SendMessageToAll(message);
|
|
}
|
|
|
|
private void SendPickupItem(ushort itemID, ushort mobID)
|
|
{
|
|
NetOutgoingMessage message = netServer.netServer.CreateMessage();
|
|
message.Write((byte)NetMessage.ItemMessage);
|
|
message.Write((byte)ItemMessage.PickUpItem);
|
|
message.Write(mobID);
|
|
message.Write(itemID);
|
|
netServer.SendMessageToAll(message);
|
|
}
|
|
|
|
private void SendPickupItem(ushort itemID, ushort mobID, NetConnection netConnection)
|
|
{
|
|
NetOutgoingMessage message = netServer.netServer.CreateMessage();
|
|
message.Write((byte)NetMessage.ItemMessage);
|
|
message.Write((byte)ItemMessage.PickUpItem);
|
|
message.Write(mobID);
|
|
message.Write(itemID);
|
|
netServer.SendMessageTo(message, netConnection);
|
|
}
|
|
|
|
// A new player is joining so lets send them everything we know!
|
|
// Each module should probably have one of these.
|
|
public void NewPlayer(NetConnection netConnection)
|
|
{
|
|
foreach (Item item in itemDict.Values)
|
|
{
|
|
if (item == null)
|
|
{
|
|
continue;
|
|
}
|
|
SendCreateItem(item.itemID, netConnection);
|
|
if (item.holder != null)
|
|
{
|
|
SendPickupItem(item.itemID, item.holder.mobID, netConnection);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|