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; } } } }