Reduce knocked down players tile friction (#11035)

This commit is contained in:
metalgearsloth
2022-09-11 16:49:10 +10:00
committed by GitHub
parent 47dd0ff2e8
commit 12e1a961d6
12 changed files with 80 additions and 124 deletions

View File

@@ -1,15 +0,0 @@
using Content.Client.Physics.Controllers;
using Content.Shared.Friction;
using Robust.Shared.GameObjects;
namespace Content.Client.Friction
{
public sealed class TileFrictionController : SharedTileFrictionController
{
public override void Initialize()
{
base.Initialize();
Mover = Get<MoverController>();
}
}
}

View File

@@ -1,9 +0,0 @@
using Content.Shared.Slippery;
namespace Content.Client.Slippery
{
internal sealed class SlipperySystem : SharedSlipperySystem
{
protected override void PlaySound(SlipperyComponent component) {}
}
}

View File

@@ -36,6 +36,7 @@ namespace Content.Server.Chemistry.TileReactions
var slippery = entityManager.EnsureComponent<SlipperyComponent>(puddle.Owner); var slippery = entityManager.EnsureComponent<SlipperyComponent>(puddle.Owner);
slippery.LaunchForwardsMultiplier = _launchForwardsMultiplier; slippery.LaunchForwardsMultiplier = _launchForwardsMultiplier;
slippery.ParalyzeTime = _paralyzeTime; slippery.ParalyzeTime = _paralyzeTime;
entityManager.Dirty(slippery);
var step = entityManager.EnsureComponent<StepTriggerComponent>(puddle.Owner); var step = entityManager.EnsureComponent<StepTriggerComponent>(puddle.Owner);
entityManager.EntitySysManager.GetEntitySystem<StepTriggerSystem>().SetRequiredTriggerSpeed(puddle.Owner, _requiredSlipSpeed, step); entityManager.EntitySysManager.GetEntitySystem<StepTriggerSystem>().SetRequiredTriggerSpeed(puddle.Owner, _requiredSlipSpeed, step);

View File

@@ -1,14 +0,0 @@
using Content.Server.Physics.Controllers;
using Content.Shared.Friction;
namespace Content.Server.Friction
{
public sealed class TileFrictionController : SharedTileFrictionController
{
public override void Initialize()
{
base.Initialize();
Mover = Get<MoverController>();
}
}
}

View File

@@ -1,15 +0,0 @@
using Content.Shared.Audio;
using Content.Shared.Slippery;
using Robust.Shared.Audio;
using Robust.Shared.Player;
namespace Content.Server.Slippery
{
internal sealed class SlipperySystem : SharedSlipperySystem
{
protected override void PlaySound(SlipperyComponent component)
{
SoundSystem.Play(component.SlipSound.GetSound(), Filter.Pvs(component.Owner), component.Owner, AudioHelpers.WithVariation(0.2f));
}
}
}

View File

@@ -1,7 +1,6 @@
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Content.Shared.Gravity; using Content.Shared.Gravity;
using Content.Shared.Movement; using Content.Shared.Movement.Events;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Systems; using Content.Shared.Movement.Systems;
using Content.Shared.Pulling.Components; using Content.Shared.Pulling.Components;
using JetBrains.Annotations; using JetBrains.Annotations;
@@ -16,13 +15,13 @@ using Robust.Shared.Utility;
namespace Content.Shared.Friction namespace Content.Shared.Friction
{ {
public abstract class SharedTileFrictionController : VirtualController public sealed class TileFrictionController : VirtualController
{ {
[Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!;
[Dependency] private readonly SharedGravitySystem _gravity = default!; [Dependency] private readonly SharedGravitySystem _gravity = default!;
[Dependency] private readonly SharedMoverController _mover = default!;
protected SharedMoverController Mover = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!;
private float _stopSpeed; private float _stopSpeed;
private float _frictionModifier; private float _frictionModifier;
@@ -79,7 +78,10 @@ namespace Content.Shared.Friction
// Only apply friction when it's not a mob (or the mob doesn't have control) // Only apply friction when it's not a mob (or the mob doesn't have control)
if (prediction && !body.Predict || if (prediction && !body.Predict ||
body.BodyStatus == BodyStatus.InAir || body.BodyStatus == BodyStatus.InAir ||
Mover.UseMobMovement(body.Owner)) continue; _mover.UseMobMovement(body.Owner))
{
continue;
}
if (body.LinearVelocity.Equals(Vector2.Zero) && body.AngularVelocity.Equals(0f)) continue; if (body.LinearVelocity.Equals(Vector2.Zero) && body.AngularVelocity.Equals(0f)) continue;
@@ -99,6 +101,11 @@ namespace Content.Shared.Friction
bodyModifier = frictionComp.Modifier; bodyModifier = frictionComp.Modifier;
} }
var ev = new TileFrictionEvent(bodyModifier);
RaiseLocalEvent(body.Owner, ref ev);
bodyModifier = ev.Modifier;
// If we're sandwiched between 2 pullers reduce friction // If we're sandwiched between 2 pullers reduce friction
// Might be better to make this dynamic and check how many are in the pull chain? // Might be better to make this dynamic and check how many are in the pull chain?
// Either way should be much faster for now. // Either way should be much faster for now.
@@ -143,7 +150,7 @@ namespace Content.Shared.Friction
var newSpeed = MathF.Max(0.0f, speed - drop); var newSpeed = MathF.Max(0.0f, speed - drop);
newSpeed /= speed; newSpeed /= speed;
body.LinearVelocity *= newSpeed; _physics.SetLinearVelocity(body, body.LinearVelocity * newSpeed);
} }
private void ReduceAngularVelocity(bool prediction, PhysicsComponent body, float friction, float frameTime) private void ReduceAngularVelocity(bool prediction, PhysicsComponent body, float friction, float frameTime)
@@ -174,7 +181,7 @@ namespace Content.Shared.Friction
var newSpeed = MathF.Max(0.0f, speed - drop); var newSpeed = MathF.Max(0.0f, speed - drop);
newSpeed /= speed; newSpeed /= speed;
body.AngularVelocity *= newSpeed; _physics.SetAngularVelocity(body, body.AngularVelocity * newSpeed);
} }
[Pure] [Pure]

View File

@@ -1,7 +1,7 @@
namespace Content.Shared.Friction namespace Content.Shared.Friction
{ {
[RegisterComponent] [RegisterComponent]
[Access(typeof(SharedTileFrictionController))] [Access(typeof(TileFrictionController))]
public sealed class TileFrictionModifierComponent : Component public sealed class TileFrictionModifierComponent : Component
{ {
/// <summary> /// <summary>

View File

@@ -0,0 +1,15 @@
namespace Content.Shared.Movement.Events;
/// <summary>
/// Raised to try and get any tile friction modifiers for a particular body.
/// </summary>
[ByRefEvent]
public struct TileFrictionEvent
{
public float Modifier;
public TileFrictionEvent(float modifier)
{
Modifier = modifier;
}
}

View File

@@ -69,7 +69,7 @@ namespace Content.Shared.Movement.Systems
InitializeRelay(); InitializeRelay();
_configManager.OnValueChanged(CCVars.RelativeMovement, SetRelativeMovement, true); _configManager.OnValueChanged(CCVars.RelativeMovement, SetRelativeMovement, true);
_configManager.OnValueChanged(CCVars.StopSpeed, SetStopSpeed, true); _configManager.OnValueChanged(CCVars.StopSpeed, SetStopSpeed, true);
UpdatesBefore.Add(typeof(SharedTileFrictionController)); UpdatesBefore.Add(typeof(TileFrictionController));
} }
private void SetRelativeMovement(bool value) => _relativeMovement = value; private void SetRelativeMovement(bool value) => _relativeMovement = value;

View File

@@ -15,75 +15,29 @@ namespace Content.Shared.Slippery
[NetworkedComponent] [NetworkedComponent]
public sealed class SlipperyComponent : Component public sealed class SlipperyComponent : Component
{ {
private float _paralyzeTime = 3f;
private float _launchForwardsMultiplier = 1f;
private SoundSpecifier _slipSound = new SoundPathSpecifier("/Audio/Effects/slip.ogg");
/// <summary> /// <summary>
/// Path to the sound to be played when a mob slips. /// Path to the sound to be played when a mob slips.
/// </summary> /// </summary>
[ViewVariables] [ViewVariables]
[DataField("slipSound")] [DataField("slipSound")]
public SoundSpecifier SlipSound [Access(Other = AccessPermissions.ReadWriteExecute)]
{ public SoundSpecifier SlipSound = new SoundPathSpecifier("/Audio/Effects/slip.ogg");
get => _slipSound;
set
{
if (value == _slipSound)
return;
_slipSound = value;
Dirty();
}
}
/// <summary> /// <summary>
/// How many seconds the mob will be paralyzed for. /// How many seconds the mob will be paralyzed for.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("paralyzeTime")] [DataField("paralyzeTime")]
public float ParalyzeTime [Access(Other = AccessPermissions.ReadWrite)]
{ public float ParalyzeTime = 3f;
get => _paralyzeTime;
set
{
if (MathHelper.CloseToPercent(_paralyzeTime, value)) return;
_paralyzeTime = value;
Dirty();
}
}
/// <summary> /// <summary>
/// The entity's speed will be multiplied by this to slip it forwards. /// The entity's speed will be multiplied by this to slip it forwards.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("launchForwardsMultiplier")] [DataField("launchForwardsMultiplier")]
public float LaunchForwardsMultiplier [Access(Other = AccessPermissions.ReadWrite)]
{ public float LaunchForwardsMultiplier = 1f;
get => _launchForwardsMultiplier;
set
{
if (MathHelper.CloseToPercent(_launchForwardsMultiplier, value)) return;
_launchForwardsMultiplier = value;
Dirty();
}
}
public override ComponentState GetComponentState()
{
return new SlipperyComponentState(ParalyzeTime, LaunchForwardsMultiplier, SlipSound.GetSound());
}
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
{
if (curState is not SlipperyComponentState state) return;
_paralyzeTime = state.ParalyzeTime;
_launchForwardsMultiplier = state.LaunchForwardsMultiplier;
_slipSound = new SoundPathSpecifier(state.SlipSound);
}
} }
[Serializable, NetSerializable] [Serializable, NetSerializable]

View File

@@ -5,14 +5,17 @@ using Content.Shared.StatusEffect;
using Content.Shared.StepTrigger.Systems; using Content.Shared.StepTrigger.Systems;
using Content.Shared.Stunnable; using Content.Shared.Stunnable;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Audio;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameStates;
namespace Content.Shared.Slippery namespace Content.Shared.Slippery
{ {
[UsedImplicitly] [UsedImplicitly]
public abstract class SharedSlipperySystem : EntitySystem public sealed class SlipperySystem : EntitySystem
{ {
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedStunSystem _stunSystem = default!; [Dependency] private readonly SharedStunSystem _stunSystem = default!;
[Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!; [Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!;
[Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly SharedContainerSystem _container = default!;
@@ -24,6 +27,22 @@ namespace Content.Shared.Slippery
SubscribeLocalEvent<SlipperyComponent, StepTriggerAttemptEvent>(HandleAttemptCollide); SubscribeLocalEvent<SlipperyComponent, StepTriggerAttemptEvent>(HandleAttemptCollide);
SubscribeLocalEvent<SlipperyComponent, StepTriggeredEvent>(HandleStepTrigger); SubscribeLocalEvent<SlipperyComponent, StepTriggeredEvent>(HandleStepTrigger);
SubscribeLocalEvent<NoSlipComponent, SlipAttemptEvent>(OnNoSlipAttempt); SubscribeLocalEvent<NoSlipComponent, SlipAttemptEvent>(OnNoSlipAttempt);
SubscribeLocalEvent<SlipperyComponent, ComponentGetState>(OnSlipperyGetState);
SubscribeLocalEvent<SlipperyComponent, ComponentHandleState>(OnSlipperyHandleState);
}
private void OnSlipperyHandleState(EntityUid uid, SlipperyComponent component, ref ComponentHandleState args)
{
if (args.Current is not SlipperyComponentState state) return;
component.ParalyzeTime = state.ParalyzeTime;
component.LaunchForwardsMultiplier = state.LaunchForwardsMultiplier;
component.SlipSound = new SoundPathSpecifier(state.SlipSound);
}
private void OnSlipperyGetState(EntityUid uid, SlipperyComponent component, ref ComponentGetState args)
{
args.State = new SlipperyComponentState(component.ParalyzeTime, component.LaunchForwardsMultiplier, component.SlipSound.GetSound());
} }
private void HandleStepTrigger(EntityUid uid, SlipperyComponent component, ref StepTriggeredEvent args) private void HandleStepTrigger(EntityUid uid, SlipperyComponent component, ref StepTriggeredEvent args)
@@ -69,14 +88,13 @@ namespace Content.Shared.Slippery
// Preventing from playing the slip sound when you are already knocked down. // Preventing from playing the slip sound when you are already knocked down.
if (playSound) if (playSound)
PlaySound(component); {
_audio.PlayPredicted(component.SlipSound, other, other);
}
_adminLogger.Add(LogType.Slip, LogImpact.Low, _adminLogger.Add(LogType.Slip, LogImpact.Low,
$"{ToPrettyString(other):mob} slipped on collision with {ToPrettyString(component.Owner):entity}"); $"{ToPrettyString(other):mob} slipped on collision with {ToPrettyString(component.Owner):entity}");
} }
// Until we get predicted slip sounds TM?
protected abstract void PlaySound(SlipperyComponent component);
} }
/// <summary> /// <summary>

View File

@@ -26,6 +26,12 @@ namespace Content.Shared.Stunnable
[Dependency] private readonly StatusEffectsSystem _statusEffectSystem = default!; [Dependency] private readonly StatusEffectsSystem _statusEffectSystem = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!; [Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
/// <summary>
/// Friction modifier for knocked down players.
/// Doesn't make them faster but makes them slow down... slower.
/// </summary>
public const float KnockDownModifier = 0.4f;
public override void Initialize() public override void Initialize()
{ {
SubscribeLocalEvent<KnockedDownComponent, ComponentInit>(OnKnockInit); SubscribeLocalEvent<KnockedDownComponent, ComponentInit>(OnKnockInit);
@@ -48,6 +54,8 @@ namespace Content.Shared.Stunnable
SubscribeLocalEvent<KnockedDownComponent, InteractHandEvent>(OnInteractHand); SubscribeLocalEvent<KnockedDownComponent, InteractHandEvent>(OnInteractHand);
SubscribeLocalEvent<SlowedDownComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed); SubscribeLocalEvent<SlowedDownComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed);
SubscribeLocalEvent<KnockedDownComponent, TileFrictionEvent>(OnKnockedTileFriction);
// Attempt event subscriptions. // Attempt event subscriptions.
SubscribeLocalEvent<StunnedComponent, UpdateCanMoveEvent>(OnMoveAttempt); SubscribeLocalEvent<StunnedComponent, UpdateCanMoveEvent>(OnMoveAttempt);
SubscribeLocalEvent<StunnedComponent, InteractionAttemptEvent>(OnInteractAttempt); SubscribeLocalEvent<StunnedComponent, InteractionAttemptEvent>(OnInteractAttempt);
@@ -205,6 +213,7 @@ namespace Content.Shared.Stunnable
if (args.Handled || knocked.HelpTimer > 0f) if (args.Handled || knocked.HelpTimer > 0f)
return; return;
// TODO: This should be an event.
if (HasComp<SleepingComponent>(uid)) if (HasComp<SleepingComponent>(uid))
return; return;
@@ -215,11 +224,16 @@ namespace Content.Shared.Stunnable
SoundSystem.Play(knocked.StunAttemptSound.GetSound(), Filter.Pvs(uid), uid, AudioHelpers.WithVariation(0.05f)); SoundSystem.Play(knocked.StunAttemptSound.GetSound(), Filter.Pvs(uid), uid, AudioHelpers.WithVariation(0.05f));
knocked.Dirty(); Dirty(knocked);
args.Handled = true; args.Handled = true;
} }
private void OnKnockedTileFriction(EntityUid uid, KnockedDownComponent component, ref TileFrictionEvent args)
{
args.Modifier *= KnockDownModifier;
}
#region Attempt Event Handling #region Attempt Event Handling
private void OnMoveAttempt(EntityUid uid, StunnedComponent stunned, UpdateCanMoveEvent args) private void OnMoveAttempt(EntityUid uid, StunnedComponent stunned, UpdateCanMoveEvent args)