New Feature: Slot blockers (#35172)
* First commit * More comments * Update * Update * For Beloved Maintainers * Beck T, my beloved * Update * Old stuff * Update EquipAttemptEvents.cs * Update UnequipAttemptEvent.cs --------- Co-authored-by: beck-thompson <107373427+beck-thompson@users.noreply.github.com>
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
namespace Content.Shared.Inventory.Events;
|
namespace Content.Shared.Inventory.Events;
|
||||||
|
|
||||||
public abstract class EquipAttemptBase(EntityUid equipee, EntityUid equipTarget, EntityUid equipment,
|
public abstract class EquipAttemptBase(EntityUid equipee, EntityUid equipTarget, EntityUid equipment,
|
||||||
SlotDefinition slotDefinition) : CancellableEntityEventArgs
|
SlotDefinition slotDefinition) : CancellableEntityEventArgs, IInventoryRelayEvent
|
||||||
{
|
{
|
||||||
|
public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The entity performing the action. NOT necessarily the one actually "receiving" the equipment.
|
/// The entity performing the action. NOT necessarily the one actually "receiving" the equipment.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
namespace Content.Shared.Inventory.Events;
|
namespace Content.Shared.Inventory.Events;
|
||||||
|
|
||||||
public abstract class UnequipAttemptEventBase(EntityUid unequipee, EntityUid unEquipTarget, EntityUid equipment,
|
public abstract class UnequipAttemptEventBase(EntityUid unequipee, EntityUid unEquipTarget, EntityUid equipment,
|
||||||
SlotDefinition slotDefinition) : CancellableEntityEventArgs
|
SlotDefinition slotDefinition) : CancellableEntityEventArgs, IInventoryRelayEvent
|
||||||
{
|
{
|
||||||
|
public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The entity performing the action. NOT necessarily the same as the entity whose equipment is being removed..
|
/// The entity performing the action. NOT necessarily the same as the entity whose equipment is being removed..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ public partial class InventorySystem
|
|||||||
SubscribeLocalEvent<InventoryComponent, SelfBeforeClimbEvent>(RelayInventoryEvent);
|
SubscribeLocalEvent<InventoryComponent, SelfBeforeClimbEvent>(RelayInventoryEvent);
|
||||||
SubscribeLocalEvent<InventoryComponent, CoefficientQueryEvent>(RelayInventoryEvent);
|
SubscribeLocalEvent<InventoryComponent, CoefficientQueryEvent>(RelayInventoryEvent);
|
||||||
SubscribeLocalEvent<InventoryComponent, ZombificationResistanceQueryEvent>(RelayInventoryEvent);
|
SubscribeLocalEvent<InventoryComponent, ZombificationResistanceQueryEvent>(RelayInventoryEvent);
|
||||||
|
SubscribeLocalEvent<InventoryComponent, IsEquippingTargetAttemptEvent>(RelayInventoryEvent);
|
||||||
|
SubscribeLocalEvent<InventoryComponent, IsUnequippingTargetAttemptEvent>(RelayInventoryEvent);
|
||||||
|
|
||||||
// by-ref events
|
// by-ref events
|
||||||
SubscribeLocalEvent<InventoryComponent, RefreshFrictionModifiersEvent>(RefRelayInventoryEvent);
|
SubscribeLocalEvent<InventoryComponent, RefreshFrictionModifiersEvent>(RefRelayInventoryEvent);
|
||||||
|
|||||||
16
Content.Shared/Inventory/SlotBlockComponent.cs
Normal file
16
Content.Shared/Inventory/SlotBlockComponent.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Inventory;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to prevent items from being unequipped and equipped from slots that are listed in <see cref="Slots"/>.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SlotBlockSystem))]
|
||||||
|
public sealed partial class SlotBlockComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Slots that this entity should block.
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true), AutoNetworkedField]
|
||||||
|
public SlotFlags Slots = SlotFlags.NONE;
|
||||||
|
}
|
||||||
35
Content.Shared/Inventory/SlotBlockSystem.cs
Normal file
35
Content.Shared/Inventory/SlotBlockSystem.cs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
using Content.Shared.Inventory.Events;
|
||||||
|
|
||||||
|
namespace Content.Shared.Inventory;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles prevention of items being unequipped and equipped from slots that are blocked by <see cref="SlotBlockComponent"/>.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class SlotBlockSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<SlotBlockComponent, InventoryRelayedEvent<IsEquippingTargetAttemptEvent>>(OnEquipAttempt);
|
||||||
|
SubscribeLocalEvent<SlotBlockComponent, InventoryRelayedEvent<IsUnequippingTargetAttemptEvent>>(OnUnequipAttempt);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEquipAttempt(Entity<SlotBlockComponent> ent, ref InventoryRelayedEvent<IsEquippingTargetAttemptEvent> args)
|
||||||
|
{
|
||||||
|
if (args.Args.Cancelled || (args.Args.SlotFlags & ent.Comp.Slots) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
args.Args.Reason = Loc.GetString("slot-block-component-blocked", ("item", ent));
|
||||||
|
args.Args.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUnequipAttempt(Entity<SlotBlockComponent> ent, ref InventoryRelayedEvent<IsUnequippingTargetAttemptEvent> args)
|
||||||
|
{
|
||||||
|
if (args.Args.Cancelled || (args.Args.SlotFlags & ent.Comp.Slots) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
args.Args.Reason = Loc.GetString("slot-block-component-blocked", ("item", ent));
|
||||||
|
args.Args.Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
slot-block-component-blocked = This slot is blocked by {$item}!
|
||||||
@@ -105,6 +105,8 @@
|
|||||||
id: ClothingHeadEVAHelmetBase
|
id: ClothingHeadEVAHelmetBase
|
||||||
name: base space helmet
|
name: base space helmet
|
||||||
components:
|
components:
|
||||||
|
- type: SlotBlock
|
||||||
|
slots: [ears, eyes, mask]
|
||||||
- type: BreathMask
|
- type: BreathMask
|
||||||
- type: Item
|
- type: Item
|
||||||
size: Normal
|
size: Normal
|
||||||
@@ -140,6 +142,8 @@
|
|||||||
name: base hardsuit helmet
|
name: base hardsuit helmet
|
||||||
categories: [ HideSpawnMenu ]
|
categories: [ HideSpawnMenu ]
|
||||||
components:
|
components:
|
||||||
|
- type: SlotBlock
|
||||||
|
slots: [ears, eyes, mask]
|
||||||
- type: BreathMask
|
- type: BreathMask
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
state: icon # default state used by most inheritors
|
state: icon # default state used by most inheritors
|
||||||
@@ -181,11 +185,13 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
abstract: true
|
abstract: true
|
||||||
# No parent since it isn't an item
|
# No parent since it isn't an item
|
||||||
# must parent both this and the desired helmet base when using
|
# must parent both this and the desired helmet base when using
|
||||||
id: ClothingHeadSuitWithLightBase
|
id: ClothingHeadSuitWithLightBase
|
||||||
name: base hardsuit helmet with light
|
name: base hardsuit helmet with light
|
||||||
categories: [ HideSpawnMenu ]
|
categories: [ HideSpawnMenu ]
|
||||||
components:
|
components:
|
||||||
|
- type: SlotBlock
|
||||||
|
slots: [ears, eyes, mask]
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
layers:
|
layers:
|
||||||
- state: icon
|
- state: icon
|
||||||
|
|||||||
@@ -105,6 +105,8 @@
|
|||||||
id: ClothingOuterHardsuitBase
|
id: ClothingOuterHardsuitBase
|
||||||
name: base hardsuit
|
name: base hardsuit
|
||||||
components:
|
components:
|
||||||
|
- type: SlotBlock
|
||||||
|
slots: [innerclothing, feet]
|
||||||
- type: PressureProtection
|
- type: PressureProtection
|
||||||
highPressureMultiplier: 0.3
|
highPressureMultiplier: 0.3
|
||||||
lowPressureMultiplier: 1000
|
lowPressureMultiplier: 1000
|
||||||
@@ -149,6 +151,8 @@
|
|||||||
id: ClothingOuterEVASuitBase
|
id: ClothingOuterEVASuitBase
|
||||||
name: base EVA Suit
|
name: base EVA Suit
|
||||||
components:
|
components:
|
||||||
|
- type: SlotBlock
|
||||||
|
slots: [innerclothing, feet]
|
||||||
- type: PressureProtection
|
- type: PressureProtection
|
||||||
highPressureMultiplier: 0.6
|
highPressureMultiplier: 0.6
|
||||||
lowPressureMultiplier: 1000
|
lowPressureMultiplier: 1000
|
||||||
|
|||||||
Reference in New Issue
Block a user