Slipping tweaks + remove EffectBlocker (#4955)

* Slipping tweaks + remove EffectBlocker

* mfw failed merge conflict resolution

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
mirrorcult
2021-10-24 23:43:49 -07:00
committed by GitHub
parent e016fc9906
commit c0ecdb09af
16 changed files with 69 additions and 112 deletions

View File

@@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Content.Client.Clothing; using Content.Client.Clothing;
using Content.Shared.CharacterAppearance; using Content.Shared.CharacterAppearance;
using Content.Shared.EffectBlocker;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Movement.Components; using Content.Shared.Movement.Components;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
@@ -21,7 +20,7 @@ namespace Content.Client.Inventory
/// </summary> /// </summary>
[RegisterComponent] [RegisterComponent]
[ComponentReference(typeof(SharedInventoryComponent))] [ComponentReference(typeof(SharedInventoryComponent))]
public class ClientInventoryComponent : SharedInventoryComponent, IEffectBlocker public class ClientInventoryComponent : SharedInventoryComponent
{ {
private readonly Dictionary<Slots, IEntity> _slots = new(); private readonly Dictionary<Slots, IEntity> _slots = new();
@@ -284,10 +283,5 @@ namespace Content.Client.Inventory
return false; return false;
} }
bool IEffectBlocker.CanSlip()
{
return !TryGetSlot(Slots.SHOES, out var shoes) || shoes == null || EffectBlockerSystem.CanSlip(shoes);
}
} }
} }

View File

@@ -1,5 +1,8 @@
using Content.Client.HUD; using Content.Client.HUD;
using Content.Client.Items.Components;
using Content.Shared.Input; using Content.Shared.Input;
using Content.Shared.Inventory;
using Content.Shared.Slippery;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -24,6 +27,17 @@ namespace Content.Client.Inventory
SubscribeLocalEvent<ClientInventoryComponent, PlayerAttachedEvent>((_, component, _) => component.PlayerAttached()); SubscribeLocalEvent<ClientInventoryComponent, PlayerAttachedEvent>((_, component, _) => component.PlayerAttached());
SubscribeLocalEvent<ClientInventoryComponent, PlayerDetachedEvent>((_, component, _) => component.PlayerDetached()); SubscribeLocalEvent<ClientInventoryComponent, PlayerDetachedEvent>((_, component, _) => component.PlayerDetached());
SubscribeLocalEvent<ClientInventoryComponent, SlipAttemptEvent>(OnSlipAttemptEvent);
}
// jesus christ, this is duplicated to server/client, should really just be shared..
private void OnSlipAttemptEvent(EntityUid uid, ClientInventoryComponent component, SlipAttemptEvent args)
{
if (component.TryGetSlot(EquipmentSlotDefines.Slots.SHOES, out IEntity? shoes))
{
RaiseLocalEvent(shoes.Uid, args, false);
}
} }
public override void Shutdown() public override void Shutdown()

View File

@@ -8,9 +8,9 @@ using Content.Shared.Body.Components;
using Content.Shared.Body.Part; using Content.Shared.Body.Part;
using Content.Shared.Buckle.Components; using Content.Shared.Buckle.Components;
using Content.Shared.Coordinates; using Content.Shared.Coordinates;
using Content.Shared.EffectBlocker;
using Content.Shared.Interaction.Events; using Content.Shared.Interaction.Events;
using Content.Shared.Movement; using Content.Shared.Movement;
using Content.Shared.Standing;
using NUnit.Framework; using NUnit.Framework;
using Robust.Server.Player; using Robust.Server.Player;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -69,7 +69,9 @@ namespace Content.IntegrationTests.Tests.Buckle
{ {
var mapManager = IoCManager.Resolve<IMapManager>(); var mapManager = IoCManager.Resolve<IMapManager>();
var entityManager = IoCManager.Resolve<IEntityManager>(); var entityManager = IoCManager.Resolve<IEntityManager>();
var actionBlocker = EntitySystem.Get<ActionBlockerSystem>(); var actionBlocker = EntitySystem.Get<ActionBlockerSystem>();
var standingState = EntitySystem.Get<StandingStateSystem>();
var gridId = new GridId(1); var gridId = new GridId(1);
var grid = mapManager.GetGrid(gridId); var grid = mapManager.GetGrid(gridId);
@@ -85,7 +87,8 @@ namespace Content.IntegrationTests.Tests.Buckle
Assert.False(buckle.Buckled); Assert.False(buckle.Buckled);
Assert.True(actionBlocker.CanMove(human)); Assert.True(actionBlocker.CanMove(human));
Assert.True(actionBlocker.CanChangeDirection(human)); Assert.True(actionBlocker.CanChangeDirection(human));
Assert.True(EffectBlockerSystem.CanFall(human)); Assert.True(standingState.Down(human.Uid));
Assert.True(standingState.Stand(human.Uid));
// Default state, no buckled entities, strap // Default state, no buckled entities, strap
Assert.True(chair.TryGetComponent(out strap)); Assert.True(chair.TryGetComponent(out strap));
@@ -102,7 +105,7 @@ namespace Content.IntegrationTests.Tests.Buckle
Assert.True(((BuckleComponentState) buckle.GetComponentState(player)).Buckled); Assert.True(((BuckleComponentState) buckle.GetComponentState(player)).Buckled);
Assert.False(actionBlocker.CanMove(human)); Assert.False(actionBlocker.CanMove(human));
Assert.False(actionBlocker.CanChangeDirection(human)); Assert.False(actionBlocker.CanChangeDirection(human));
Assert.False(EffectBlockerSystem.CanFall(human)); Assert.False(standingState.Down(human.Uid));
Assert.That((human.Transform.WorldPosition - chair.Transform.WorldPosition).Length, Is.LessThanOrEqualTo(buckle.BuckleOffset.Length)); Assert.That((human.Transform.WorldPosition - chair.Transform.WorldPosition).Length, Is.LessThanOrEqualTo(buckle.BuckleOffset.Length));
// Side effects of buckling for the strap // Side effects of buckling for the strap
@@ -125,6 +128,7 @@ namespace Content.IntegrationTests.Tests.Buckle
await server.WaitAssertion(() => await server.WaitAssertion(() =>
{ {
var actionBlocker = EntitySystem.Get<ActionBlockerSystem>(); var actionBlocker = EntitySystem.Get<ActionBlockerSystem>();
var standingState = EntitySystem.Get<StandingStateSystem>();
// Still buckled // Still buckled
Assert.True(buckle.Buckled); Assert.True(buckle.Buckled);
@@ -135,7 +139,7 @@ namespace Content.IntegrationTests.Tests.Buckle
Assert.False(buckle.Buckled); Assert.False(buckle.Buckled);
Assert.True(actionBlocker.CanMove(human)); Assert.True(actionBlocker.CanMove(human));
Assert.True(actionBlocker.CanChangeDirection(human)); Assert.True(actionBlocker.CanChangeDirection(human));
Assert.True(EffectBlockerSystem.CanFall(human)); Assert.True(standingState.Down(human.Uid));
// Unbuckle, strap // Unbuckle, strap
Assert.IsEmpty(strap.BuckledEntities); Assert.IsEmpty(strap.BuckledEntities);
@@ -160,6 +164,7 @@ namespace Content.IntegrationTests.Tests.Buckle
await server.WaitAssertion(() => await server.WaitAssertion(() =>
{ {
var actionBlocker = EntitySystem.Get<ActionBlockerSystem>(); var actionBlocker = EntitySystem.Get<ActionBlockerSystem>();
var standingState = EntitySystem.Get<StandingStateSystem>();
// Still buckled // Still buckled
Assert.True(buckle.Buckled); Assert.True(buckle.Buckled);
@@ -192,7 +197,7 @@ namespace Content.IntegrationTests.Tests.Buckle
Assert.False(buckle.Buckled); Assert.False(buckle.Buckled);
Assert.True(actionBlocker.CanMove(human)); Assert.True(actionBlocker.CanMove(human));
Assert.True(actionBlocker.CanChangeDirection(human)); Assert.True(actionBlocker.CanChangeDirection(human));
Assert.True(EffectBlockerSystem.CanFall(human)); Assert.True(standingState.Down(human.Uid));
// Re-buckle // Re-buckle
Assert.True(buckle.TryBuckle(human, chair)); Assert.True(buckle.TryBuckle(human, chair));

View File

@@ -1,4 +1,5 @@
using Content.Server.Clothing.Components; using Content.Server.Clothing.Components;
using Content.Shared.Slippery;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Localization; using Robust.Shared.Localization;
@@ -12,6 +13,7 @@ namespace Content.Server.Clothing
base.Initialize(); base.Initialize();
SubscribeLocalEvent<MagbootsComponent, GetActivationVerbsEvent>(AddToggleVerb); SubscribeLocalEvent<MagbootsComponent, GetActivationVerbsEvent>(AddToggleVerb);
SubscribeLocalEvent<MagbootsComponent, SlipAttemptEvent>(OnSlipAttempt);
} }
private void AddToggleVerb(EntityUid uid, MagbootsComponent component, GetActivationVerbsEvent args) private void AddToggleVerb(EntityUid uid, MagbootsComponent component, GetActivationVerbsEvent args)
@@ -25,5 +27,13 @@ namespace Content.Server.Clothing
// TODO VERB ICON add toggle icon? maybe a computer on/off symbol? // TODO VERB ICON add toggle icon? maybe a computer on/off symbol?
args.Verbs.Add(verb); args.Verbs.Add(verb);
} }
private void OnSlipAttempt(EntityUid uid, MagbootsComponent component, SlipAttemptEvent args)
{
if (component.On)
{
args.Cancel();
}
}
} }
} }

View File

@@ -10,7 +10,6 @@ using Content.Server.Items;
using Content.Server.Storage.Components; using Content.Server.Storage.Components;
using Content.Shared.ActionBlocker; using Content.Shared.ActionBlocker;
using Content.Shared.Acts; using Content.Shared.Acts;
using Content.Shared.EffectBlocker;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Movement.Components; using Content.Shared.Movement.Components;
using Content.Shared.Popups; using Content.Shared.Popups;
@@ -36,7 +35,7 @@ namespace Content.Server.Inventory.Components
{ {
[RegisterComponent] [RegisterComponent]
[ComponentReference(typeof(SharedInventoryComponent))] [ComponentReference(typeof(SharedInventoryComponent))]
public class InventoryComponent : SharedInventoryComponent, IExAct, IEffectBlocker public class InventoryComponent : SharedInventoryComponent, IExAct
{ {
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!; [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
@@ -101,11 +100,6 @@ namespace Content.Server.Inventory.Components
} }
} }
bool IEffectBlocker.CanSlip()
{
return !TryGetSlotItem(EquipmentSlotDefines.Slots.SHOES, out ItemComponent? shoes) || EffectBlockerSystem.CanSlip(shoes.Owner);
}
protected override void OnRemove() protected override void OnRemove()
{ {
var slots = _slotContainers.Keys.ToList(); var slots = _slotContainers.Keys.ToList();

View File

@@ -1,5 +1,8 @@
using Content.Server.Atmos; using Content.Server.Atmos;
using Content.Server.Inventory.Components; using Content.Server.Inventory.Components;
using Content.Server.Items;
using Content.Shared.Inventory;
using Content.Shared.Slippery;
using Content.Shared.Damage; using Content.Shared.Damage;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -17,6 +20,15 @@ namespace Content.Server.Inventory
SubscribeLocalEvent<InventoryComponent, HighPressureEvent>(OnHighPressureEvent); SubscribeLocalEvent<InventoryComponent, HighPressureEvent>(OnHighPressureEvent);
SubscribeLocalEvent<InventoryComponent, LowPressureEvent>(OnLowPressureEvent); SubscribeLocalEvent<InventoryComponent, LowPressureEvent>(OnLowPressureEvent);
SubscribeLocalEvent<InventoryComponent, DamageModifyEvent>(OnDamageModify); SubscribeLocalEvent<InventoryComponent, DamageModifyEvent>(OnDamageModify);
SubscribeLocalEvent<InventoryComponent, SlipAttemptEvent>(OnSlipAttemptEvent);
}
private void OnSlipAttemptEvent(EntityUid uid, InventoryComponent component, SlipAttemptEvent args)
{
if (component.TryGetSlotItem(EquipmentSlotDefines.Slots.SHOES, out ItemComponent? shoes))
{
RaiseLocalEvent(shoes.Owner.Uid, args, false);
}
} }
private static void HandleInvRemovedFromContainer(EntityUid uid, InventoryComponent component, EntRemovedFromContainerMessage args) private static void HandleInvRemovedFromContainer(EntityUid uid, InventoryComponent component, EntRemovedFromContainerMessage args)

View File

@@ -1,5 +1,4 @@
using Content.Shared.DragDrop; using Content.Shared.DragDrop;
using Content.Shared.EffectBlocker;
using Content.Shared.Emoting; using Content.Shared.Emoting;
using Content.Shared.Interaction.Events; using Content.Shared.Interaction.Events;
using Content.Shared.Inventory.Events; using Content.Shared.Inventory.Events;
@@ -15,7 +14,6 @@ namespace Content.Shared.ActionBlocker
{ {
/// <summary> /// <summary>
/// Utility methods to check if a specific entity is allowed to perform an action. /// Utility methods to check if a specific entity is allowed to perform an action.
/// For effects see <see cref="EffectBlockerSystem"/>
/// </summary> /// </summary>
[UsedImplicitly] [UsedImplicitly]
public class ActionBlockerSystem : EntitySystem public class ActionBlockerSystem : EntitySystem

View File

@@ -1,6 +1,5 @@
using System; using System;
using Content.Shared.DragDrop; using Content.Shared.DragDrop;
using Content.Shared.EffectBlocker;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
@@ -11,7 +10,7 @@ using Robust.Shared.ViewVariables;
namespace Content.Shared.Buckle.Components namespace Content.Shared.Buckle.Components
{ {
[NetworkedComponent()] [NetworkedComponent()]
public abstract class SharedBuckleComponent : Component, IEffectBlocker, IDraggable public abstract class SharedBuckleComponent : Component, IDraggable
{ {
public sealed override string Name => "Buckle"; public sealed override string Name => "Buckle";
@@ -35,8 +34,6 @@ namespace Content.Shared.Buckle.Components
public abstract bool TryBuckle(IEntity? user, IEntity to); public abstract bool TryBuckle(IEntity? user, IEntity to);
bool IEffectBlocker.CanFall() => !Buckled;
bool IDraggable.CanDrop(CanDropEvent args) bool IDraggable.CanDrop(CanDropEvent args)
{ {
return args.Target.HasComponent<SharedStrapComponent>(); return args.Target.HasComponent<SharedStrapComponent>();

View File

@@ -1,17 +0,0 @@
using Robust.Shared.GameObjects;
namespace Content.Shared.EffectBlocker
{
public static class EffectBlockerExtensions
{
public static bool CanFall(this IEntity entity)
{
return EffectBlockerSystem.CanFall(entity);
}
public static bool CanSlip(this IEntity entity)
{
return EffectBlockerSystem.CanSlip(entity);
}
}
}

View File

@@ -1,42 +0,0 @@
using System;
using Content.Shared.ActionBlocker;
using JetBrains.Annotations;
using Robust.Shared.GameObjects;
namespace Content.Shared.EffectBlocker
{
/// <summary>
/// Utility methods to check if an effect is allowed to affect a specific entity.
/// For actions see <see cref="ActionBlockerSystem"/>
/// </summary>
[UsedImplicitly]
public class EffectBlockerSystem : EntitySystem
{
// TODO: Make these methods not static. Maybe move them to their relevant EntitySystems?
// TODO: Add EntityUid overloads.
public static bool CanFall(IEntity entity)
{
var canFall = true;
foreach (var blocker in entity.GetAllComponents<IEffectBlocker>())
{
canFall &= blocker.CanFall(); // Sets var to false if false
}
return canFall;
}
public static bool CanSlip(IEntity entity)
{
var canSlip = true;
foreach (var blocker in entity.GetAllComponents<IEffectBlocker>())
{
canSlip &= blocker.CanSlip(); // Sets var to false if false
}
return canSlip;
}
}
}

View File

@@ -1,14 +0,0 @@
using Content.Shared.ActionBlocker;
namespace Content.Shared.EffectBlocker
{
/// <summary>
/// This interface gives components the ability to block certain effects
/// from affecting the owning entity.
/// </summary>
public interface IEffectBlocker
{
bool CanFall() => true;
bool CanSlip() => true;
}
}

View File

@@ -1,13 +1,10 @@
using Content.Shared.EffectBlocker;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
namespace Content.Shared.Slippery namespace Content.Shared.Slippery
{ {
[RegisterComponent] [RegisterComponent]
public class NoSlipComponent : Component, IEffectBlocker public class NoSlipComponent : Component
{ {
public override string Name => "NoSlip"; public override string Name => "NoSlip";
bool IEffectBlocker.CanSlip() => false;
} }
} }

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Content.Shared.EffectBlocker;
using Content.Shared.StatusEffect; using Content.Shared.StatusEffect;
using Content.Shared.Stunnable; using Content.Shared.Stunnable;
using JetBrains.Annotations; using JetBrains.Annotations;
@@ -26,6 +25,7 @@ namespace Content.Shared.Slippery
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<SlipperyComponent, StartCollideEvent>(HandleCollide); SubscribeLocalEvent<SlipperyComponent, StartCollideEvent>(HandleCollide);
SubscribeLocalEvent<NoSlipComponent, SlipAttemptEvent>(OnNoSlipAttempt);
} }
private void HandleCollide(EntityUid uid, SlipperyComponent component, StartCollideEvent args) private void HandleCollide(EntityUid uid, SlipperyComponent component, StartCollideEvent args)
@@ -40,6 +40,11 @@ namespace Content.Shared.Slippery
component.Colliding.Add(otherUid); component.Colliding.Add(otherUid);
} }
private void OnNoSlipAttempt(EntityUid uid, NoSlipComponent component, SlipAttemptEvent args)
{
args.Cancel();
}
/// <inheritdoc /> /// <inheritdoc />
public override void Update(float frameTime) public override void Update(float frameTime)
{ {
@@ -80,10 +85,10 @@ namespace Content.Shared.Slippery
return false; return false;
} }
if (!EffectBlockerSystem.CanSlip(otherBody.Owner)) var ev = new SlipAttemptEvent();
{ RaiseLocalEvent(otherBody.Owner.Uid, ev, false);
if (ev.Cancelled)
return false; return false;
}
otherBody.LinearVelocity *= component.LaunchForwardsMultiplier; otherBody.LinearVelocity *= component.LaunchForwardsMultiplier;
@@ -136,4 +141,11 @@ namespace Content.Shared.Slippery
return false; return false;
} }
} }
/// <summary>
/// Raised on an entity to determine if it can slip or not.
/// </summary>
public class SlipAttemptEvent : CancellableEntityEventArgs
{
}
} }

View File

@@ -20,7 +20,7 @@ namespace Content.Shared.Slippery
private float _paralyzeTime = 3f; private float _paralyzeTime = 3f;
private float _intersectPercentage = 0.3f; private float _intersectPercentage = 0.3f;
private float _requiredSlipSpeed = 0.1f; private float _requiredSlipSpeed = 5f;
private float _launchForwardsMultiplier = 1f; private float _launchForwardsMultiplier = 1f;
private bool _slippery = true; private bool _slippery = true;
private SoundSpecifier _slipSound = new SoundPathSpecifier("/Audio/Effects/slip.ogg"); private SoundSpecifier _slipSound = new SoundPathSpecifier("/Audio/Effects/slip.ogg");

View File

@@ -1,5 +1,4 @@
using System; using System;
using Content.Shared.EffectBlocker;
using Content.Shared.Sound; using Content.Shared.Sound;
using Robust.Shared.Analyzers; using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -13,7 +12,7 @@ namespace Content.Shared.Standing
{ {
[Friend(typeof(StandingStateSystem))] [Friend(typeof(StandingStateSystem))]
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent]
public sealed class StandingStateComponent : Component, IEffectBlocker public sealed class StandingStateComponent : Component
{ {
public override string Name => "StandingState"; public override string Name => "StandingState";
@@ -25,8 +24,6 @@ namespace Content.Shared.Standing
[DataField("standing")] [DataField("standing")]
public bool Standing { get; set; } = true; public bool Standing { get; set; } = true;
public bool CanFall() => Standing;
public override ComponentState GetComponentState(ICommonSession player) public override ComponentState GetComponentState(ICommonSession player)
{ {
return new StandingComponentState(Standing); return new StandingComponentState(Standing);

View File

@@ -37,7 +37,7 @@
- type: entity - type: entity
parent: ClothingShoesBase parent: ClothingShoesBase
id: ClothingShoesGaloshes id: ClothingShoesGaloshes
name: galoshes shoes name: galoshes
description: Rubber boots. description: Rubber boots.
components: components:
- type: Sprite - type: Sprite