Of Hats and Hardsuit Helmets (#5263)
* Now you can toggle your helm with a hat on * Added container to toggleable clothing in YAML. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fixed YAML fail. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
c9faffdfa5
commit
ec041a0f22
|
|
@ -16,7 +16,7 @@ using Robust.Shared.Utility;
|
|||
|
||||
namespace Content.Shared.Clothing.EntitySystems;
|
||||
|
||||
public sealed class ToggleableClothingSystem : EntitySystem
|
||||
public sealed partial class ToggleableClothingSystem : EntitySystem // DeltaV - Made Partial
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly INetManager _netMan = default!;
|
||||
|
|
@ -140,10 +140,12 @@ public sealed class ToggleableClothingSystem : EntitySystem
|
|||
|| toggleCom.Container == null)
|
||||
return;
|
||||
|
||||
var parent = Transform(uid).ParentUid; // DeltaV - Allow hats under toggleable helms
|
||||
if (!_inventorySystem.TryUnequip(Transform(uid).ParentUid, toggleCom.Slot, force: true))
|
||||
return;
|
||||
|
||||
_containerSystem.Insert(uid, toggleCom.Container);
|
||||
TryEquipUnderClothing(parent, component); // DeltaV - Allow hats under toggleable helms
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
|
|
@ -156,11 +158,17 @@ public sealed class ToggleableClothingSystem : EntitySystem
|
|||
if (_timing.ApplyingState)
|
||||
return;
|
||||
|
||||
var wasAttachedUnequipped = false; // DeltaV - Allow hats under toggleable helms
|
||||
|
||||
// If the attached clothing is not currently in the container, this just assumes that it is currently equipped.
|
||||
// This should maybe double check that the entity currently in the slot is actually the attached clothing, but
|
||||
// if its not, then something else has gone wrong already...
|
||||
if (component.Container != null && component.Container.ContainedEntity == null && component.ClothingUid != null)
|
||||
_inventorySystem.TryUnequip(args.Equipee, component.Slot, force: true, triggerHandContact: true);
|
||||
wasAttachedUnequipped = _inventorySystem.TryUnequip(args.Equipee, component.Slot, force: true, triggerHandContact: true); // DeltaV - Allow hats under toggleable helms
|
||||
|
||||
// DeltaV - If the toggleable helm was uneqipped, try to equip whats in the under clothing container
|
||||
if (wasAttachedUnequipped && !TryEquipUnderClothing(args.Equipee, component))
|
||||
TryDropUnderClothing(component);
|
||||
}
|
||||
|
||||
private void OnRemoveToggleable(EntityUid uid, ToggleableClothingComponent component, ComponentRemove args)
|
||||
|
|
@ -240,15 +248,30 @@ public sealed class ToggleableClothingSystem : EntitySystem
|
|||
return;
|
||||
|
||||
var parent = Transform(target).ParentUid;
|
||||
|
||||
// Begin DeltaV - Allow hats under toggleable helms!
|
||||
var wasAttachedUnequipped = false; // We want to track if the toggleable item was unequipped, assume false for now.
|
||||
|
||||
if (component.Container.ContainedEntity == null)
|
||||
_inventorySystem.TryUnequip(user, parent, component.Slot, force: true);
|
||||
else if (_inventorySystem.TryGetSlotEntity(parent, component.Slot, out var existing))
|
||||
{
|
||||
_popupSystem.PopupClient(Loc.GetString("toggleable-clothing-remove-first", ("entity", existing)),
|
||||
user, user);
|
||||
}
|
||||
wasAttachedUnequipped = _inventorySystem.TryUnequip(user, parent, component.Slot, force: true);
|
||||
|
||||
else
|
||||
{
|
||||
if (_inventorySystem.TryGetSlotEntity(parent, component.Slot, out var existing)
|
||||
&& !TryStoreUnderClothing(existing.Value, component))
|
||||
{
|
||||
_popupSystem.PopupClient(Loc.GetString("toggleable-clothing-remove-first", ("entity", existing)),
|
||||
user, user);
|
||||
return;
|
||||
}
|
||||
|
||||
_inventorySystem.TryEquip(user, parent, component.ClothingUid.Value, component.Slot, triggerHandContact: true);
|
||||
}
|
||||
|
||||
// If the toggleable clothing was uneqipped, try to equip whats in the under clothing container
|
||||
if (wasAttachedUnequipped && !TryEquipUnderClothing(user, parent, component))
|
||||
TryDropUnderClothing(component);
|
||||
// END DeltaV
|
||||
}
|
||||
|
||||
private void OnGetActions(EntityUid uid, ToggleableClothingComponent component, GetItemActionsEvent args)
|
||||
|
|
@ -264,6 +287,7 @@ public sealed class ToggleableClothingSystem : EntitySystem
|
|||
private void OnInit(EntityUid uid, ToggleableClothingComponent component, ComponentInit args)
|
||||
{
|
||||
component.Container = _containerSystem.EnsureContainer<ContainerSlot>(uid, component.ContainerId);
|
||||
component.UnderClothingContainer = _containerSystem.EnsureContainer<ContainerSlot>(uid, component.UnderClothingContainerId); // Wayfarer - Allow hats under toggleable helms!
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
using Robust.Shared.Containers;
|
||||
|
||||
namespace Content.Shared.Clothing.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Extends upstream's ToggleableClothingComponent.
|
||||
///
|
||||
/// This portion of the ToggleableClothingComponent stores the clothing item under the toggled piece.
|
||||
/// Currently only supports a single piece of clothing, but pretty much all entities with ToggleableClothing
|
||||
/// are just hardsuit helmets.
|
||||
/// </summary>
|
||||
public sealed partial class ToggleableClothingComponent : Component
|
||||
{
|
||||
public const string DefaultUnderneathClothingContainerId = "toggleable-under-clothing";
|
||||
|
||||
/// <summary>
|
||||
/// The container ID of <see cref="UnderClothingContainer"/>.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public string UnderClothingContainerId = DefaultUnderneathClothingContainerId;
|
||||
|
||||
/// <summary>
|
||||
/// The container where the item that the toggled clothing replaced is put.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public ContainerSlot? UnderClothingContainer;
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
using Content.Shared.Clothing.Components;
|
||||
|
||||
namespace Content.Shared.Clothing.EntitySystems;
|
||||
|
||||
/// <summary>
|
||||
/// Extends upstream's ToggleableClothingSystem.
|
||||
///
|
||||
/// Provides methods that store and re-equip clothing when toggleable clothing is put on or taken off.
|
||||
/// Sidenote; god, I hate naming things.
|
||||
/// </summary>
|
||||
public sealed partial class ToggleableClothingSystem : EntitySystem
|
||||
{
|
||||
/// <summary>
|
||||
/// Tries to store clothing in <see cref="ToggleableClothingComponent.UnderClothingContainer"/>
|
||||
/// </summary>
|
||||
/// <param name="clothing">The clothing to be stored.</param>
|
||||
/// <param name="component">The ToggleableClothingComponent to store the clothing in.</param>
|
||||
/// <returns>True if clothing can be inserted and was inserted.</returns>
|
||||
private bool TryStoreUnderClothing(EntityUid clothing, ToggleableClothingComponent component)
|
||||
{
|
||||
if (component.UnderClothingContainer == null)
|
||||
return false;
|
||||
|
||||
// There is already something in there? Either way, return false because we
|
||||
// expect one thing.
|
||||
if (component.UnderClothingContainer.ContainedEntity.HasValue)
|
||||
return false;
|
||||
|
||||
return _containerSystem.Insert(clothing, component.UnderClothingContainer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to equip any stored clothing kept in <see cref="ToggleableClothingComponent.UnderClothingContainer"/>.
|
||||
/// </summary>
|
||||
/// <param name="actor">The person wearing the ToggleableClothing.</param>
|
||||
/// <param name="component">The ToggleableClothingComponent to check for an stored items.</param>
|
||||
/// <returns>True if something was equipped OR if there is nothing to equip.</returns>
|
||||
private bool TryEquipUnderClothing(EntityUid actor, ToggleableClothingComponent component)
|
||||
{
|
||||
return TryEquipUnderClothing(actor, actor, component);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to equip any stored clothing kept in <see cref="ToggleableClothingComponent.UnderClothingContainer"/>.
|
||||
/// </summary>
|
||||
/// <param name="actor">The person trying to equip the clothing.</param>
|
||||
/// <param name="target">The person who to equip the clothing on.</param>
|
||||
/// <param name="component">The ToggleableClothingComponent to check for an stored items.</param>
|
||||
/// <returns>True if something was equipped OR if there is nothing to equip.</returns>
|
||||
private bool TryEquipUnderClothing(EntityUid actor, EntityUid target, ToggleableClothingComponent component)
|
||||
{
|
||||
// if there is no UnderClothingContainer, then why are we here?
|
||||
if (component.UnderClothingContainer == null)
|
||||
return true;
|
||||
|
||||
// if nothing is contained so technically dropping nothing counts as a success
|
||||
if (!component.UnderClothingContainer.ContainedEntity.HasValue)
|
||||
return true;
|
||||
|
||||
return _inventorySystem.TryEquip(actor, target, component.UnderClothingContainer.ContainedEntity.Value, component.Slot, force: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to equip any stored clothing kept in <see cref="ToggleableClothingComponent.UnderClothingContainer"/>.
|
||||
/// </summary>
|
||||
/// <param name="actor">The person trying to equip the clothing.</param>
|
||||
/// <param name="component">The AttachedClothing of the ToggleableClothing to check for an stored items.</param>
|
||||
/// <returns>True if something was equipped OR if there is nothing to equip.</returns>
|
||||
private bool TryEquipUnderClothing(EntityUid actor, AttachedClothingComponent component)
|
||||
{
|
||||
if (!TryComp<ToggleableClothingComponent>(component.AttachedUid, out var toggleableComp))
|
||||
return false;
|
||||
|
||||
return TryEquipUnderClothing(actor, toggleableComp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to drop any stored clothing kept in <see cref="ToggleableClothingComponent.UnderClothingContainer"/>.
|
||||
/// </summary>
|
||||
/// <param name="component">The ToggleableClothingComponent that is holding the item to be dropped.</param>
|
||||
/// <returns>True if there is not an item to be dropped OR it was successfully dropped.</returns>
|
||||
private bool TryDropUnderClothing(ToggleableClothingComponent component)
|
||||
{
|
||||
// if there is no UnderClothingContainer, then why are we here?
|
||||
if (component.UnderClothingContainer == null)
|
||||
return true;
|
||||
|
||||
// if nothing is contained so technically dropping nothing counts as a success
|
||||
if (!component.UnderClothingContainer.ContainedEntity.HasValue)
|
||||
return true;
|
||||
|
||||
return _containerSystem.TryRemoveFromContainer(component.UnderClothingContainer.ContainedEntity.Value);
|
||||
}
|
||||
}
|
||||
|
|
@ -162,6 +162,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
|
||||
- type: entity
|
||||
parent: ClothingNeckBase
|
||||
|
|
@ -188,6 +189,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
- type: TypingIndicatorClothing
|
||||
proto: moth
|
||||
|
||||
|
|
@ -207,6 +209,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
- type: TypingIndicatorClothing
|
||||
proto: alien
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
storagebase: !type:Container
|
||||
ents: []
|
||||
|
||||
|
|
@ -137,6 +138,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
- type: GroupExamine
|
||||
- type: Tag
|
||||
tags:
|
||||
|
|
@ -201,6 +203,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
storagebase: !type:Container
|
||||
ents: []
|
||||
|
||||
|
|
|
|||
|
|
@ -1189,6 +1189,7 @@
|
|||
- type: ContainerContainer # Delta V-Brings back clownsuit but make it make sense
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
|
||||
#Mime Hardsuit
|
||||
- type: entity
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
- type: Tag
|
||||
tags:
|
||||
- CorgiWearable
|
||||
|
|
@ -173,6 +174,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
- type: Tag
|
||||
tags:
|
||||
- CorgiWearable
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
- type: ProtectedFromStepTriggers
|
||||
slots: WITHOUT_POCKET
|
||||
- type: Tag
|
||||
|
|
@ -255,6 +256,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
- type: ProtectedFromStepTriggers
|
||||
slots: WITHOUT_POCKET
|
||||
|
||||
|
|
@ -275,6 +277,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
- type: Construction
|
||||
graph: ClothingOuterSuitIan
|
||||
node: suit
|
||||
|
|
@ -308,6 +311,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
|
||||
- type: entity
|
||||
parent: ClothingOuterSuitCarp
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {} # DeltaV - Allow hats under toggleable clothing
|
||||
storagebase: !type:Container
|
||||
ents: []
|
||||
|
||||
|
|
|
|||
|
|
@ -19,13 +19,8 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot
|
||||
showEnts: false
|
||||
occludes: true
|
||||
ent: null
|
||||
toggleable-under-clothing: !type:ContainerSlot {}
|
||||
storagebase: !type:Container
|
||||
showEnts: false
|
||||
occludes: true
|
||||
ents: []
|
||||
|
||||
- type: entity
|
||||
parent: ClothingOuterHardsuitSyndie
|
||||
|
|
|
|||
|
|
@ -43,14 +43,9 @@
|
|||
clothingPrototype: ClothingHeadHatHoodWinterMailCarrier
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
storagebase: !type:Container
|
||||
showEnts: False
|
||||
occludes: True
|
||||
ents: []
|
||||
toggleable-clothing: !type:ContainerSlot
|
||||
showEnts: False
|
||||
occludes: True
|
||||
ent: null
|
||||
toggleable-under-clothing: !type:ContainerSlot {}
|
||||
storagebase: !type:Container
|
||||
- type: Sprite
|
||||
sprite: Nyanotrasen/Clothing/OuterClothing/WinterCoats/mail_winter_coat.rsi
|
||||
- type: Clothing
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot { }
|
||||
toggleable-under-clothing: !type:ContainerSlot {}
|
||||
- type: Armor
|
||||
modifiers:
|
||||
coefficients:
|
||||
|
|
@ -96,6 +97,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {}
|
||||
- type: Tag
|
||||
tags:
|
||||
- CorgiWearable
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
- type: ContainerContainer
|
||||
containers:
|
||||
toggleable-clothing: !type:ContainerSlot {}
|
||||
toggleable-under-clothing: !type:ContainerSlot {}
|
||||
storagebase: !type:Container
|
||||
ents: []
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue