Prevent shoe buffs while crawling (#39648)
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
95b0df9a89
commit
47dd036ef2
@@ -15,6 +15,13 @@ public sealed partial class ClothingSpeedModifierComponent : Component
|
|||||||
|
|
||||||
[DataField]
|
[DataField]
|
||||||
public float SprintModifier = 1.0f;
|
public float SprintModifier = 1.0f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An optional required standing state.
|
||||||
|
/// Set to true if you need to be standing, false if you need to not be standing, null if you don't care.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public bool? Standing;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Content.Shared.Inventory;
|
|||||||
using Content.Shared.Item.ItemToggle;
|
using Content.Shared.Item.ItemToggle;
|
||||||
using Content.Shared.Item.ItemToggle.Components;
|
using Content.Shared.Item.ItemToggle.Components;
|
||||||
using Content.Shared.Movement.Systems;
|
using Content.Shared.Movement.Systems;
|
||||||
|
using Content.Shared.Standing;
|
||||||
using Content.Shared.Verbs;
|
using Content.Shared.Verbs;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
@@ -12,10 +13,11 @@ namespace Content.Shared.Clothing;
|
|||||||
|
|
||||||
public sealed class ClothingSpeedModifierSystem : EntitySystem
|
public sealed class ClothingSpeedModifierSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
|
||||||
[Dependency] private readonly ExamineSystemShared _examine = default!;
|
[Dependency] private readonly ExamineSystemShared _examine = default!;
|
||||||
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!;
|
|
||||||
[Dependency] private readonly ItemToggleSystem _toggle = default!;
|
[Dependency] private readonly ItemToggleSystem _toggle = default!;
|
||||||
|
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!;
|
||||||
|
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||||
|
[Dependency] private readonly StandingStateSystem _standing = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -54,7 +56,12 @@ public sealed class ClothingSpeedModifierSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnRefreshMoveSpeed(EntityUid uid, ClothingSpeedModifierComponent component, InventoryRelayedEvent<RefreshMovementSpeedModifiersEvent> args)
|
private void OnRefreshMoveSpeed(EntityUid uid, ClothingSpeedModifierComponent component, InventoryRelayedEvent<RefreshMovementSpeedModifiersEvent> args)
|
||||||
{
|
{
|
||||||
if (_toggle.IsActivated(uid))
|
if (!_toggle.IsActivated(uid))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (component.Standing != null && !_standing.IsMatchingState(args.Owner, component.Standing.Value))
|
||||||
|
return;
|
||||||
|
|
||||||
args.Args.ModifySpeed(component.WalkModifier, component.SprintModifier);
|
args.Args.ModifySpeed(component.WalkModifier, component.SprintModifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,33 @@
|
|||||||
using Content.Shared.Clothing.Components;
|
using Content.Shared.Clothing.Components;
|
||||||
using Content.Shared.Gravity;
|
using Content.Shared.Gravity;
|
||||||
using Content.Shared.Inventory;
|
using Content.Shared.Inventory;
|
||||||
|
using Content.Shared.Standing;
|
||||||
|
|
||||||
namespace Content.Shared.Clothing.EntitySystems;
|
namespace Content.Shared.Clothing.EntitySystems;
|
||||||
|
|
||||||
|
/// <remarks>
|
||||||
|
/// We check standing state on all clothing because we don't want you to have anti-gravity unless you're standing.
|
||||||
|
/// This is for balance reasons as it prevents you from wearing anti-grav clothing to cheese being stun cuffed, as
|
||||||
|
/// well as other worse things.
|
||||||
|
/// </remarks>
|
||||||
public sealed class AntiGravityClothingSystem : EntitySystem
|
public sealed class AntiGravityClothingSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] SharedGravitySystem _gravity = default!;
|
[Dependency] private readonly StandingStateSystem _standing = default!;
|
||||||
|
[Dependency] private readonly SharedGravitySystem _gravity = default!;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<AntiGravityClothingComponent, InventoryRelayedEvent<IsWeightlessEvent>>(OnIsWeightless);
|
SubscribeLocalEvent<AntiGravityClothingComponent, InventoryRelayedEvent<IsWeightlessEvent>>(OnIsWeightless);
|
||||||
SubscribeLocalEvent<AntiGravityClothingComponent, ClothingGotEquippedEvent>(OnEquipped);
|
SubscribeLocalEvent<AntiGravityClothingComponent, ClothingGotEquippedEvent>(OnEquipped);
|
||||||
SubscribeLocalEvent<AntiGravityClothingComponent, ClothingGotUnequippedEvent>(OnUnequipped);
|
SubscribeLocalEvent<AntiGravityClothingComponent, ClothingGotUnequippedEvent>(OnUnequipped);
|
||||||
|
SubscribeLocalEvent<AntiGravityClothingComponent, InventoryRelayedEvent<DownedEvent>>(OnDowned);
|
||||||
|
SubscribeLocalEvent<AntiGravityClothingComponent, InventoryRelayedEvent<StoodEvent>>(OnStood);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnIsWeightless(Entity<AntiGravityClothingComponent> ent, ref InventoryRelayedEvent<IsWeightlessEvent> args)
|
private void OnIsWeightless(Entity<AntiGravityClothingComponent> ent, ref InventoryRelayedEvent<IsWeightlessEvent> args)
|
||||||
{
|
{
|
||||||
if (args.Args.Handled)
|
if (args.Args.Handled || _standing.IsDown(args.Owner))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
args.Args.Handled = true;
|
args.Args.Handled = true;
|
||||||
@@ -26,11 +36,29 @@ public sealed class AntiGravityClothingSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEquipped(Entity<AntiGravityClothingComponent> entity, ref ClothingGotEquippedEvent args)
|
private void OnEquipped(Entity<AntiGravityClothingComponent> entity, ref ClothingGotEquippedEvent args)
|
||||||
{
|
{
|
||||||
|
// This clothing item does nothing if we're not standing
|
||||||
|
if (_standing.IsDown(args.Wearer))
|
||||||
|
return;
|
||||||
|
|
||||||
_gravity.RefreshWeightless(args.Wearer, true);
|
_gravity.RefreshWeightless(args.Wearer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnUnequipped(Entity<AntiGravityClothingComponent> entity, ref ClothingGotUnequippedEvent args)
|
private void OnUnequipped(Entity<AntiGravityClothingComponent> entity, ref ClothingGotUnequippedEvent args)
|
||||||
{
|
{
|
||||||
|
// This clothing item does nothing if we're not standing
|
||||||
|
if (_standing.IsDown(args.Wearer))
|
||||||
|
return;
|
||||||
|
|
||||||
_gravity.RefreshWeightless(args.Wearer, false);
|
_gravity.RefreshWeightless(args.Wearer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnDowned(Entity<AntiGravityClothingComponent> entity, ref InventoryRelayedEvent<DownedEvent> args)
|
||||||
|
{
|
||||||
|
_gravity.RefreshWeightless(args.Owner, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStood(Entity<AntiGravityClothingComponent> entity, ref InventoryRelayedEvent<StoodEvent> args)
|
||||||
|
{
|
||||||
|
_gravity.RefreshWeightless(args.Owner, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ using Content.Shared.Overlays;
|
|||||||
using Content.Shared.Projectiles;
|
using Content.Shared.Projectiles;
|
||||||
using Content.Shared.Radio;
|
using Content.Shared.Radio;
|
||||||
using Content.Shared.Slippery;
|
using Content.Shared.Slippery;
|
||||||
|
using Content.Shared.Standing;
|
||||||
using Content.Shared.Strip.Components;
|
using Content.Shared.Strip.Components;
|
||||||
using Content.Shared.Temperature;
|
using Content.Shared.Temperature;
|
||||||
using Content.Shared.Verbs;
|
using Content.Shared.Verbs;
|
||||||
@@ -57,6 +58,8 @@ public partial class InventorySystem
|
|||||||
SubscribeLocalEvent<InventoryComponent, IsUnequippingTargetAttemptEvent>(RelayInventoryEvent);
|
SubscribeLocalEvent<InventoryComponent, IsUnequippingTargetAttemptEvent>(RelayInventoryEvent);
|
||||||
SubscribeLocalEvent<InventoryComponent, ChameleonControllerOutfitSelectedEvent>(RelayInventoryEvent);
|
SubscribeLocalEvent<InventoryComponent, ChameleonControllerOutfitSelectedEvent>(RelayInventoryEvent);
|
||||||
SubscribeLocalEvent<InventoryComponent, BeforeEmoteEvent>(RelayInventoryEvent);
|
SubscribeLocalEvent<InventoryComponent, BeforeEmoteEvent>(RelayInventoryEvent);
|
||||||
|
SubscribeLocalEvent<InventoryComponent, StoodEvent>(RelayInventoryEvent);
|
||||||
|
SubscribeLocalEvent<InventoryComponent, DownedEvent>(RelayInventoryEvent);
|
||||||
|
|
||||||
// by-ref events
|
// by-ref events
|
||||||
SubscribeLocalEvent<InventoryComponent, RefreshFrictionModifiersEvent>(RefRelayInventoryEvent);
|
SubscribeLocalEvent<InventoryComponent, RefreshFrictionModifiersEvent>(RefRelayInventoryEvent);
|
||||||
@@ -114,7 +117,7 @@ public partial class InventorySystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// this copies the by-ref event if it is a struct
|
// this copies the by-ref event if it is a struct
|
||||||
var ev = new InventoryRelayedEvent<T>(args);
|
var ev = new InventoryRelayedEvent<T>(args, inventory.Owner);
|
||||||
var enumerator = new InventorySlotEnumerator(inventory, args.TargetSlots);
|
var enumerator = new InventorySlotEnumerator(inventory, args.TargetSlots);
|
||||||
while (enumerator.NextItem(out var item))
|
while (enumerator.NextItem(out var item))
|
||||||
{
|
{
|
||||||
@@ -130,7 +133,7 @@ public partial class InventorySystem
|
|||||||
if (args.TargetSlots == SlotFlags.NONE)
|
if (args.TargetSlots == SlotFlags.NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var ev = new InventoryRelayedEvent<T>(args);
|
var ev = new InventoryRelayedEvent<T>(args, inventory.Owner);
|
||||||
var enumerator = new InventorySlotEnumerator(inventory, args.TargetSlots);
|
var enumerator = new InventorySlotEnumerator(inventory, args.TargetSlots);
|
||||||
while (enumerator.NextItem(out var item))
|
while (enumerator.NextItem(out var item))
|
||||||
{
|
{
|
||||||
@@ -141,7 +144,7 @@ public partial class InventorySystem
|
|||||||
private void OnGetEquipmentVerbs(EntityUid uid, InventoryComponent component, GetVerbsEvent<EquipmentVerb> args)
|
private void OnGetEquipmentVerbs(EntityUid uid, InventoryComponent component, GetVerbsEvent<EquipmentVerb> args)
|
||||||
{
|
{
|
||||||
// Automatically relay stripping related verbs to all equipped clothing.
|
// Automatically relay stripping related verbs to all equipped clothing.
|
||||||
var ev = new InventoryRelayedEvent<GetVerbsEvent<EquipmentVerb>>(args);
|
var ev = new InventoryRelayedEvent<GetVerbsEvent<EquipmentVerb>>(args, uid);
|
||||||
var enumerator = new InventorySlotEnumerator(component);
|
var enumerator = new InventorySlotEnumerator(component);
|
||||||
while (enumerator.NextItem(out var item, out var slotDef))
|
while (enumerator.NextItem(out var item, out var slotDef))
|
||||||
{
|
{
|
||||||
@@ -153,7 +156,7 @@ public partial class InventorySystem
|
|||||||
private void OnGetInnateVerbs(EntityUid uid, InventoryComponent component, GetVerbsEvent<InnateVerb> args)
|
private void OnGetInnateVerbs(EntityUid uid, InventoryComponent component, GetVerbsEvent<InnateVerb> args)
|
||||||
{
|
{
|
||||||
// Automatically relay stripping related verbs to all equipped clothing.
|
// Automatically relay stripping related verbs to all equipped clothing.
|
||||||
var ev = new InventoryRelayedEvent<GetVerbsEvent<InnateVerb>>(args);
|
var ev = new InventoryRelayedEvent<GetVerbsEvent<InnateVerb>>(args, uid);
|
||||||
var enumerator = new InventorySlotEnumerator(component, SlotFlags.WITHOUT_POCKET);
|
var enumerator = new InventorySlotEnumerator(component, SlotFlags.WITHOUT_POCKET);
|
||||||
while (enumerator.NextItem(out var item))
|
while (enumerator.NextItem(out var item))
|
||||||
{
|
{
|
||||||
@@ -176,9 +179,12 @@ public sealed class InventoryRelayedEvent<TEvent> : EntityEventArgs
|
|||||||
{
|
{
|
||||||
public TEvent Args;
|
public TEvent Args;
|
||||||
|
|
||||||
public InventoryRelayedEvent(TEvent args)
|
public EntityUid Owner;
|
||||||
|
|
||||||
|
public InventoryRelayedEvent(TEvent args, EntityUid owner)
|
||||||
{
|
{
|
||||||
Args = args;
|
Args = args;
|
||||||
|
Owner = owner;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public sealed class EntityStorageLayingDownOverrideSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
// Explicitly check for standing state component, as entities without it will return false for IsDown()
|
// Explicitly check for standing state component, as entities without it will return false for IsDown()
|
||||||
// which prevents inserting any kind of non-mobs into this container (which is unintended)
|
// which prevents inserting any kind of non-mobs into this container (which is unintended)
|
||||||
if (TryComp<StandingStateComponent>(ent, out var standingState) && !_standing.IsDown(ent, standingState))
|
if (TryComp<StandingStateComponent>(ent, out var standingState) && !_standing.IsDown((ent, standingState)))
|
||||||
args.Contents.Remove(ent);
|
args.Contents.Remove(ent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Shared.Climbing.Events;
|
using Content.Shared.Climbing.Events;
|
||||||
using Content.Shared.Hands.Components;
|
using Content.Shared.Hands.Components;
|
||||||
|
using Content.Shared.Inventory;
|
||||||
using Content.Shared.Movement.Events;
|
using Content.Shared.Movement.Events;
|
||||||
using Content.Shared.Movement.Systems;
|
using Content.Shared.Movement.Systems;
|
||||||
using Content.Shared.Physics;
|
using Content.Shared.Physics;
|
||||||
@@ -69,12 +70,17 @@ public sealed class StandingStateSystem : EntitySystem
|
|||||||
ChangeLayers(entity);
|
ChangeLayers(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDown(EntityUid uid, StandingStateComponent? standingState = null)
|
public bool IsMatchingState(Entity<StandingStateComponent?> entity, bool standing)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref standingState, false))
|
return standing != IsDown(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsDown(Entity<StandingStateComponent?> entity)
|
||||||
|
{
|
||||||
|
if (!Resolve(entity, ref entity.Comp, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !standingState.Standing;
|
return !entity.Comp.Standing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Down(EntityUid uid,
|
public bool Down(EntityUid uid,
|
||||||
@@ -213,29 +219,27 @@ public record struct DropHandItemsEvent();
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Subscribe if you can potentially block a down attempt.
|
/// Subscribe if you can potentially block a down attempt.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class DownAttemptEvent : CancellableEntityEventArgs
|
public sealed class DownAttemptEvent : CancellableEntityEventArgs;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Subscribe if you can potentially block a stand attempt.
|
/// Subscribe if you can potentially block a stand attempt.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class StandAttemptEvent : CancellableEntityEventArgs
|
public sealed class StandAttemptEvent : CancellableEntityEventArgs;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised when an entity becomes standing
|
/// Raised when an entity becomes standing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class StoodEvent : EntityEventArgs
|
public sealed class StoodEvent : EntityEventArgs, IInventoryRelayEvent
|
||||||
{
|
{
|
||||||
}
|
public SlotFlags TargetSlots { get; } = SlotFlags.FEET;
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised when an entity is not standing
|
/// Raised when an entity is not standing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class DownedEvent : EntityEventArgs
|
public sealed class DownedEvent : EntityEventArgs, IInventoryRelayEvent
|
||||||
{
|
{
|
||||||
|
public SlotFlags TargetSlots { get; } = SlotFlags.FEET;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -501,7 +501,7 @@ public abstract partial class SharedStunSystem
|
|||||||
|
|
||||||
// Targeted moth attack
|
// Targeted moth attack
|
||||||
CancelKnockdownDoAfter((entity, entity.Comp));
|
CancelKnockdownDoAfter((entity, entity.Comp));
|
||||||
RemComp<KnockedDownComponent>(entity);
|
RemCompDeferred<KnockedDownComponent>(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnKnockdownAttempt(Entity<GravityAffectedComponent> entity, ref KnockDownAttemptEvent args)
|
private void OnKnockdownAttempt(Entity<GravityAffectedComponent> entity, ref KnockDownAttemptEvent args)
|
||||||
|
|||||||
@@ -135,6 +135,7 @@
|
|||||||
- type: ClothingSpeedModifier
|
- type: ClothingSpeedModifier
|
||||||
walkModifier: 1.5
|
walkModifier: 1.5
|
||||||
sprintModifier: 1.5
|
sprintModifier: 1.5
|
||||||
|
standing: true
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
- type: GenericVisualizer
|
- type: GenericVisualizer
|
||||||
visuals:
|
visuals:
|
||||||
|
|||||||
Reference in New Issue
Block a user