diff --git a/Content.Server/GameObjects/Components/GUI/HumanInventoryControllerComponent.cs b/Content.Server/GameObjects/Components/GUI/HumanInventoryControllerComponent.cs index 7b373a9016..bc881cf344 100644 --- a/Content.Server/GameObjects/Components/GUI/HumanInventoryControllerComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/HumanInventoryControllerComponent.cs @@ -2,6 +2,7 @@ using Robust.Server.GameObjects.Components.Container; using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Network; +using Robust.Shared.Localization; using Robust.Shared.Timers; using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines; @@ -23,15 +24,17 @@ namespace Content.Server.GameObjects _inventory = Owner.GetComponent(); } - bool IInventoryController.CanEquip(Slots slot, IEntity entity, bool flagsCheck) + bool IInventoryController.CanEquip(Slots slot, IEntity entity, bool flagsCheck, out string reason) { var slotMask = SlotMasks[slot]; + reason = null; if ((slotMask & (SlotFlags.POCKET | SlotFlags.IDCARD)) != SlotFlags.NONE) { // Can't wear stuff in ID card or pockets unless you have a uniform. if (_inventory.GetSlotItem(Slots.INNERCLOTHING) == null) { + reason = Loc.GetString("You need a uniform to store something in your pockets!"); return false; } @@ -44,6 +47,10 @@ namespace Content.Server.GameObjects { return true; } + else if (!flagsCheck) + { + reason = Loc.GetString("This is too large!"); + } } } diff --git a/Content.Server/GameObjects/Components/GUI/IInventoryController.cs b/Content.Server/GameObjects/Components/GUI/IInventoryController.cs index ade34691ef..af6ddc9725 100644 --- a/Content.Server/GameObjects/Components/GUI/IInventoryController.cs +++ b/Content.Server/GameObjects/Components/GUI/IInventoryController.cs @@ -14,7 +14,14 @@ namespace Content.Server.GameObjects /// The slot to be equipped into. /// The entity to equip. /// Whether the entity passes default slot masks & flags checks. + /// The translated reason why the item cannot be equiped, if this function returns false. Can be null. /// True if the entity can be equipped, false otherwise - bool CanEquip(Slots slot, IEntity entity, bool flagsCheck) => flagsCheck; + bool CanEquip(Slots slot, IEntity entity, bool flagsCheck, out string reason) + { + reason = null; + return flagsCheck; + } + + bool CanEquip(Slots slot, IEntity entity, bool flagsCheck) => CanEquip(slot, entity, flagsCheck, out var _); } } diff --git a/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs b/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs index db412a8467..25a5517cfc 100644 --- a/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks.Dataflow; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces; using Content.Shared.GameObjects; using Robust.Server.GameObjects.Components.Container; using Robust.Server.Interfaces.Player; @@ -11,6 +12,7 @@ using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.GameObjects.Components; using Robust.Shared.Interfaces.Network; using Robust.Shared.IoC; +using Robust.Shared.Localization; using Robust.Shared.Map; using Robust.Shared.Players; using Robust.Shared.ViewVariables; @@ -24,6 +26,7 @@ namespace Content.Server.GameObjects { #pragma warning disable 649 [Dependency] private readonly IEntitySystemManager _entitySystemManager; + [Dependency] private readonly IServerNotifyManager _serverNotifyManager; #pragma warning restore 649 [ViewVariables] @@ -91,8 +94,9 @@ namespace Content.Server.GameObjects /// /// The slot to put the item in. /// The item to insert into the slot. + /// The translated reason why the item cannot be equiped, if this function returns false. Can be null. /// True if the item was successfully inserted, false otherwise. - public bool Equip(Slots slot, ItemComponent item) + public bool Equip(Slots slot, ItemComponent item, out string reason) { if (item == null) { @@ -100,7 +104,7 @@ namespace Content.Server.GameObjects "Clothing must be passed here. To remove some clothing from a slot, use Unequip()"); } - if (!CanEquip(slot, item)) + if (!CanEquip(slot, item, out reason)) { return false; } @@ -117,18 +121,21 @@ namespace Content.Server.GameObjects return true; } - public bool Equip(Slots slot, IEntity entity) => Equip(slot, entity.GetComponent()); + public bool Equip(Slots slot, ItemComponent item) => Equip(slot, item, out var _); + public bool Equip(Slots slot, IEntity entity) => Equip(slot, entity.GetComponent()); /// /// Checks whether an item can be put in the specified slot. /// /// The slot to check for. /// The item to check for. + /// The translated reason why the item cannot be equiped, if this function returns false. Can be null. /// True if the item can be inserted into the specified slot. - public bool CanEquip(Slots slot, ItemComponent item) + public bool CanEquip(Slots slot, ItemComponent item, out string reason) { var pass = false; + reason = null; if (!ActionBlockerSystem.CanEquip(Owner)) return false; @@ -139,16 +146,23 @@ namespace Content.Server.GameObjects { pass = true; } + else + { + reason = Loc.GetString("This doesn't fit."); + } } if (Owner.TryGetComponent(out IInventoryController controller)) { - pass = controller.CanEquip(slot, item.Owner, pass); + pass = controller.CanEquip(slot, item.Owner, pass, out var controllerReason); + reason = controllerReason ?? reason; } return pass && SlotContainers[slot].CanInsert(item.Owner); } + public bool CanEquip(Slots slot, ItemComponent item) => CanEquip(slot, item, out var _); + public bool CanEquip(Slots slot, IEntity entity) => CanEquip(slot, entity.GetComponent()); /// @@ -282,9 +296,12 @@ namespace Content.Server.GameObjects if (activeHand != null && activeHand.Owner.TryGetComponent(out ItemComponent clothing)) { hands.Drop(hands.ActiveIndex); - if (!Equip(msg.Inventoryslot, clothing)) + if (!Equip(msg.Inventoryslot, clothing, out var reason)) { hands.PutInHand(clothing); + + if (reason != null) + _serverNotifyManager.PopupMessage(Owner, Owner, reason); } } break; diff --git a/Content.Server/GameObjects/Components/Items/Clothing/ClothingComponent.cs b/Content.Server/GameObjects/Components/Items/Clothing/ClothingComponent.cs index 1d60955d62..1d5c187da4 100644 --- a/Content.Server/GameObjects/Components/Items/Clothing/ClothingComponent.cs +++ b/Content.Server/GameObjects/Components/Items/Clothing/ClothingComponent.cs @@ -4,11 +4,14 @@ using Robust.Shared.Utility; using System; using System.Collections.Generic; using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Items; +using Robust.Shared.IoC; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines; +using Robust.Shared.Interfaces.GameObjects; namespace Content.Server.GameObjects { @@ -17,6 +20,10 @@ namespace Content.Server.GameObjects [ComponentReference(typeof(StoreableComponent))] public class ClothingComponent : ItemComponent, IUse { +#pragma warning disable 649 + [Dependency] private readonly IServerNotifyManager _serverNotifyManager; +#pragma warning restore 649 + public override string Name => "Clothing"; public override uint? NetID => ContentNetIDs.CLOTHING; @@ -82,16 +89,38 @@ namespace Content.Server.GameObjects hands.Drop(Owner); inv.Unequip(slot); hands.PutInHand(item); + + if (!TryEquip(inv, slot, eventArgs.User)) + { + hands.Drop(item.Owner); + inv.Equip(slot, item); + hands.PutInHand(Owner.GetComponent()); + } } else { hands.Drop(Owner); + if (!TryEquip(inv, slot, eventArgs.User)) + hands.PutInHand(Owner.GetComponent()); } - return inv.Equip(slot, this); + return true; } return false; } + + private bool TryEquip(InventoryComponent inv, Slots slot, IEntity user) + { + if (!inv.Equip(slot, this, out var reason)) + { + if (reason != null) + _serverNotifyManager.PopupMessage(Owner, user, reason); + + return false; + } + + return true; + } } }