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]
|
||||
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]
|
||||
|
||||
@@ -3,6 +3,7 @@ using Content.Shared.Inventory;
|
||||
using Content.Shared.Item.ItemToggle;
|
||||
using Content.Shared.Item.ItemToggle.Components;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Standing;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameStates;
|
||||
@@ -12,10 +13,11 @@ namespace Content.Shared.Clothing;
|
||||
|
||||
public sealed class ClothingSpeedModifierSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examine = default!;
|
||||
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = 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()
|
||||
{
|
||||
@@ -54,8 +56,13 @@ public sealed class ClothingSpeedModifierSystem : EntitySystem
|
||||
|
||||
private void OnRefreshMoveSpeed(EntityUid uid, ClothingSpeedModifierComponent component, InventoryRelayedEvent<RefreshMovementSpeedModifiersEvent> args)
|
||||
{
|
||||
if (_toggle.IsActivated(uid))
|
||||
args.Args.ModifySpeed(component.WalkModifier, component.SprintModifier);
|
||||
if (!_toggle.IsActivated(uid))
|
||||
return;
|
||||
|
||||
if (component.Standing != null && !_standing.IsMatchingState(args.Owner, component.Standing.Value))
|
||||
return;
|
||||
|
||||
args.Args.ModifySpeed(component.WalkModifier, component.SprintModifier);
|
||||
}
|
||||
|
||||
private void OnClothingVerbExamine(EntityUid uid, ClothingSpeedModifierComponent component, GetVerbsEvent<ExamineVerb> args)
|
||||
|
||||
@@ -1,23 +1,33 @@
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Content.Shared.Gravity;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Standing;
|
||||
|
||||
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
|
||||
{
|
||||
[Dependency] SharedGravitySystem _gravity = default!;
|
||||
[Dependency] private readonly StandingStateSystem _standing = default!;
|
||||
[Dependency] private readonly SharedGravitySystem _gravity = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<AntiGravityClothingComponent, InventoryRelayedEvent<IsWeightlessEvent>>(OnIsWeightless);
|
||||
SubscribeLocalEvent<AntiGravityClothingComponent, ClothingGotEquippedEvent>(OnEquipped);
|
||||
SubscribeLocalEvent<AntiGravityClothingComponent, ClothingGotUnequippedEvent>(OnUnequipped);
|
||||
SubscribeLocalEvent<AntiGravityClothingComponent, InventoryRelayedEvent<DownedEvent>>(OnDowned);
|
||||
SubscribeLocalEvent<AntiGravityClothingComponent, InventoryRelayedEvent<StoodEvent>>(OnStood);
|
||||
}
|
||||
|
||||
private void OnIsWeightless(Entity<AntiGravityClothingComponent> ent, ref InventoryRelayedEvent<IsWeightlessEvent> args)
|
||||
{
|
||||
if (args.Args.Handled)
|
||||
if (args.Args.Handled || _standing.IsDown(args.Owner))
|
||||
return;
|
||||
|
||||
args.Args.Handled = true;
|
||||
@@ -26,11 +36,29 @@ public sealed class AntiGravityClothingSystem : EntitySystem
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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.Radio;
|
||||
using Content.Shared.Slippery;
|
||||
using Content.Shared.Standing;
|
||||
using Content.Shared.Strip.Components;
|
||||
using Content.Shared.Temperature;
|
||||
using Content.Shared.Verbs;
|
||||
@@ -57,6 +58,8 @@ public partial class InventorySystem
|
||||
SubscribeLocalEvent<InventoryComponent, IsUnequippingTargetAttemptEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, ChameleonControllerOutfitSelectedEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, BeforeEmoteEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, StoodEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, DownedEvent>(RelayInventoryEvent);
|
||||
|
||||
// by-ref events
|
||||
SubscribeLocalEvent<InventoryComponent, RefreshFrictionModifiersEvent>(RefRelayInventoryEvent);
|
||||
@@ -114,7 +117,7 @@ public partial class InventorySystem
|
||||
return;
|
||||
|
||||
// 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);
|
||||
while (enumerator.NextItem(out var item))
|
||||
{
|
||||
@@ -130,7 +133,7 @@ public partial class InventorySystem
|
||||
if (args.TargetSlots == SlotFlags.NONE)
|
||||
return;
|
||||
|
||||
var ev = new InventoryRelayedEvent<T>(args);
|
||||
var ev = new InventoryRelayedEvent<T>(args, inventory.Owner);
|
||||
var enumerator = new InventorySlotEnumerator(inventory, args.TargetSlots);
|
||||
while (enumerator.NextItem(out var item))
|
||||
{
|
||||
@@ -141,7 +144,7 @@ public partial class InventorySystem
|
||||
private void OnGetEquipmentVerbs(EntityUid uid, InventoryComponent component, GetVerbsEvent<EquipmentVerb> args)
|
||||
{
|
||||
// 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);
|
||||
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)
|
||||
{
|
||||
// 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);
|
||||
while (enumerator.NextItem(out var item))
|
||||
{
|
||||
@@ -176,9 +179,12 @@ public sealed class InventoryRelayedEvent<TEvent> : EntityEventArgs
|
||||
{
|
||||
public TEvent Args;
|
||||
|
||||
public InventoryRelayedEvent(TEvent args)
|
||||
public EntityUid Owner;
|
||||
|
||||
public InventoryRelayedEvent(TEvent args, EntityUid owner)
|
||||
{
|
||||
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()
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Shared.Climbing.Events;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Movement.Events;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Physics;
|
||||
@@ -69,12 +70,17 @@ public sealed class StandingStateSystem : EntitySystem
|
||||
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 !standingState.Standing;
|
||||
return !entity.Comp.Standing;
|
||||
}
|
||||
|
||||
public bool Down(EntityUid uid,
|
||||
@@ -213,29 +219,27 @@ public record struct DropHandItemsEvent();
|
||||
/// <summary>
|
||||
/// Subscribe if you can potentially block a down attempt.
|
||||
/// </summary>
|
||||
public sealed class DownAttemptEvent : CancellableEntityEventArgs
|
||||
{
|
||||
}
|
||||
public sealed class DownAttemptEvent : CancellableEntityEventArgs;
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe if you can potentially block a stand attempt.
|
||||
/// </summary>
|
||||
public sealed class StandAttemptEvent : CancellableEntityEventArgs
|
||||
{
|
||||
}
|
||||
public sealed class StandAttemptEvent : CancellableEntityEventArgs;
|
||||
|
||||
/// <summary>
|
||||
/// Raised when an entity becomes standing
|
||||
/// </summary>
|
||||
public sealed class StoodEvent : EntityEventArgs
|
||||
public sealed class StoodEvent : EntityEventArgs, IInventoryRelayEvent
|
||||
{
|
||||
}
|
||||
public SlotFlags TargetSlots { get; } = SlotFlags.FEET;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Raised when an entity is not standing
|
||||
/// </summary>
|
||||
public sealed class DownedEvent : EntityEventArgs
|
||||
public sealed class DownedEvent : EntityEventArgs, IInventoryRelayEvent
|
||||
{
|
||||
public SlotFlags TargetSlots { get; } = SlotFlags.FEET;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -501,7 +501,7 @@ public abstract partial class SharedStunSystem
|
||||
|
||||
// Targeted moth attack
|
||||
CancelKnockdownDoAfter((entity, entity.Comp));
|
||||
RemComp<KnockedDownComponent>(entity);
|
||||
RemCompDeferred<KnockedDownComponent>(entity);
|
||||
}
|
||||
|
||||
private void OnKnockdownAttempt(Entity<GravityAffectedComponent> entity, ref KnockDownAttemptEvent args)
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 1.5
|
||||
sprintModifier: 1.5
|
||||
standing: true
|
||||
- type: Appearance
|
||||
- type: GenericVisualizer
|
||||
visuals:
|
||||
@@ -182,7 +183,7 @@
|
||||
price: 75
|
||||
- type: Tag
|
||||
tags: [ ]
|
||||
|
||||
|
||||
- type: entity
|
||||
parent: ClothingShoesBase
|
||||
id: ClothingShoesBootsJump
|
||||
@@ -200,7 +201,7 @@
|
||||
jumpSound: /Audio/Effects/stealthoff.ogg
|
||||
- type: ActionGrant
|
||||
actions:
|
||||
- ActionGravityJump
|
||||
- ActionGravityJump
|
||||
- type: ItemActionGrant
|
||||
actions:
|
||||
- ActionGravityJump
|
||||
|
||||
Reference in New Issue
Block a user