using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects;
using Content.Shared.GameObjects.Components.Storage;
using SS14.Server.GameObjects;
using SS14.Server.GameObjects.Components.Container;
using SS14.Server.Interfaces.Player;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Serialization;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.Network;
using SS14.Shared.IoC;
using SS14.Shared.Log;
using System.Collections.Generic;
namespace Content.Server.GameObjects
{
///
/// Storage component for containing entities within this one, matches a UI on the client which shows stored entities
///
public class ServerStorageComponent : SharedStorageComponent, IAttackby, IUse
{
private Container storage;
private int StorageUsed = 0;
private int StorageCapacityMax = 10000;
public override void OnAdd()
{
base.OnAdd();
storage = ContainerManagerComponent.Create("storagebase", Owner);
}
public override void ExposeData(EntitySerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref StorageCapacityMax, "Capacity", 10000);
}
///
/// Removes from the storage container and updates the stored value
///
///
///
bool Remove(IEntity toremove)
{
if(storage.Remove(toremove))
{
StorageUsed -= toremove.GetComponent().ObjectSize;
UpdateClientInventory();
return true;
}
return false;
}
///
/// Inserts into the storage container
///
///
///
bool Insert(IEntity toinsert)
{
if(CanInsert(toinsert) && storage.Insert(toinsert))
{
StorageUsed += toinsert.GetComponent().ObjectSize;
UpdateClientInventory();
return true;
}
return false;
}
///
/// Verifies the object can be inserted by checking if it is storeable and if it keeps under the capacity limit
///
///
///
bool CanInsert(IEntity toinsert)
{
if(toinsert.TryGetComponent(out StoreableComponent store))
{
if (store.ObjectSize <= (StorageCapacityMax - StorageUsed))
return true;
}
return false;
}
///
/// Inserts storeable entities into this storage container if possible, otherwise return to the hand of the user
///
///
///
///
bool IAttackby.Attackby(IEntity user, IEntity attackwith)
{
var hands = user.GetComponent();
//Check that we can drop the item from our hands first otherwise we obviously cant put it inside
if(hands.Drop(hands.ActiveIndex))
{
var inserted = Insert(attackwith);
if (inserted)
{
return true;
}
else
{
//Return the object to the hand since its too big or something like that
hands.PutInHand(attackwith.GetComponent());
}
}
return false;
}
///
/// Sends a message to open the storage UI
///
///
///
bool IUse.UseEntity(IEntity user)
{
SendNetworkMessage(new OpenStorageUIMessage());
return false;
}
///
/// Updates the storage UI on all clients telling them of the entities stored in this container
///
private void UpdateClientInventory()
{
Dictionary storedentities = new Dictionary();
foreach (var entities in storage.ContainedEntities)
{
storedentities.Add(entities.Uid, entities.GetComponent().ObjectSize);
}
SendNetworkMessage(new StorageHeldItemsMessage(storedentities, StorageUsed, StorageCapacityMax));
}
///
/// Receives messages to remove entities from storage, verifies the player can do them,
/// and puts the removed entity in hand or on the ground
///
///
///
///
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
{
base.HandleMessage(message, netChannel, component);
switch (message)
{
case RemoveEntityMessage msg:
var playerMan = IoCManager.Resolve();
var session = playerMan.GetSessionByChannel(netChannel);
var playerentity = session.AttachedEntity;
var ourtransform = Owner.GetComponent();
var playertransform = playerentity.GetComponent();
if (playertransform.LocalPosition.InRange(ourtransform.LocalPosition, 2)
&& (ourtransform.IsMapTransform || playertransform.ContainsEntity(ourtransform)))
{
var remove = (RemoveEntityMessage)message;
var entity = IoCManager.Resolve().GetEntity(remove.EntityUid);
if (entity != null && storage.Contains(entity))
{
Remove(entity);
UpdateClientInventory();
var item = entity.GetComponent();
if (item != null && playerentity.TryGetComponent(out HandsComponent hands))
{
if (hands.PutInHand(item))
return;
}
entity.GetComponent().WorldPosition = Owner.GetComponent().WorldPosition;
}
}
break;
}
}
}
}