Partial kudzu fix (#10854)
This commit is contained in:
@@ -331,7 +331,7 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||||||
{
|
{
|
||||||
if (component.BumpOpen)
|
if (component.BumpOpen)
|
||||||
{
|
{
|
||||||
foreach (var other in PhysicsSystem.GetCollidingEntities(body))
|
foreach (var other in PhysicsSystem.GetContactingEntities(body, approximate: true))
|
||||||
{
|
{
|
||||||
if (Tags.HasTag(other.Owner, "DoorBumpOpener") &&
|
if (Tags.HasTag(other.Owner, "DoorBumpOpener") &&
|
||||||
TryOpen(component.Owner, component, other.Owner, false, quiet: true)) break;
|
TryOpen(component.Owner, component, other.Owner, false, quiet: true)) break;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.Movement.Components;
|
namespace Content.Shared.Movement.Components;
|
||||||
|
|
||||||
@@ -6,8 +7,22 @@ namespace Content.Shared.Movement.Components;
|
|||||||
public sealed class SlowContactsComponent : Component
|
public sealed class SlowContactsComponent : Component
|
||||||
{
|
{
|
||||||
[ViewVariables, DataField("walkSpeedModifier")]
|
[ViewVariables, DataField("walkSpeedModifier")]
|
||||||
public float WalkSpeedModifier { get; private set; } = 1.0f;
|
public float WalkSpeedModifier { get; set; } = 1.0f;
|
||||||
|
|
||||||
[ViewVariables, DataField("sprintSpeedModifier")]
|
[ViewVariables, DataField("sprintSpeedModifier")]
|
||||||
public float SprintSpeedModifier { get; private set; } = 1.0f;
|
public float SprintSpeedModifier { get; set; } = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class SlowContactsComponentState : ComponentState
|
||||||
|
{
|
||||||
|
public readonly float WalkSpeedModifier;
|
||||||
|
|
||||||
|
public readonly float SprintSpeedModifier;
|
||||||
|
|
||||||
|
public SlowContactsComponentState(float walkSpeedModifier, float sprintSpeedModifier)
|
||||||
|
{
|
||||||
|
WalkSpeedModifier = walkSpeedModifier;
|
||||||
|
SprintSpeedModifier = sprintSpeedModifier;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Movement.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Exists just to listen to a single event. What a life.
|
||||||
|
/// </summary>
|
||||||
|
[NetworkedComponent, RegisterComponent] // must be networked to properly predict adding & removal
|
||||||
|
public sealed class SlowedByContactComponent : Component
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using Robust.Shared.GameStates;
|
|
||||||
|
|
||||||
namespace Content.Shared.Movement.Components;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Exists just to listen to a single event. What a life.
|
|
||||||
/// </summary>
|
|
||||||
[NetworkedComponent, RegisterComponent]
|
|
||||||
public sealed class SlowsOnContactComponent : Component
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Shared.Movement.Components;
|
using Content.Shared.Movement.Components;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Physics.Dynamics;
|
using Robust.Shared.Physics.Dynamics;
|
||||||
|
|
||||||
namespace Content.Shared.Movement.Systems;
|
namespace Content.Shared.Movement.Systems;
|
||||||
@@ -8,65 +9,96 @@ public sealed class SlowContactsSystem : EntitySystem
|
|||||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||||
[Dependency] private readonly MovementSpeedModifierSystem _speedModifierSystem = default!;
|
[Dependency] private readonly MovementSpeedModifierSystem _speedModifierSystem = default!;
|
||||||
|
|
||||||
private readonly Dictionary<EntityUid, int> _statusCapableInContact = new();
|
private HashSet<EntityUid> _toUpdate = new();
|
||||||
|
private HashSet<EntityUid> _toRemove = new();
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
SubscribeLocalEvent<SlowContactsComponent, StartCollideEvent>(OnEntityEnter);
|
SubscribeLocalEvent<SlowContactsComponent, StartCollideEvent>(OnEntityEnter);
|
||||||
SubscribeLocalEvent<SlowContactsComponent, EndCollideEvent>(OnEntityExit);
|
SubscribeLocalEvent<SlowContactsComponent, EndCollideEvent>(OnEntityExit);
|
||||||
SubscribeLocalEvent<SlowsOnContactComponent, RefreshMovementSpeedModifiersEvent>(MovementSpeedCheck);
|
SubscribeLocalEvent<SlowedByContactComponent, RefreshMovementSpeedModifiersEvent>(MovementSpeedCheck);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<SlowContactsComponent, ComponentHandleState>(OnHandleState);
|
||||||
|
SubscribeLocalEvent<SlowContactsComponent, ComponentGetState>(OnGetState);
|
||||||
|
|
||||||
|
UpdatesAfter.Add(typeof(SharedPhysicsSystem));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MovementSpeedCheck(EntityUid uid, SlowsOnContactComponent component, RefreshMovementSpeedModifiersEvent args)
|
public override void Update(float frameTime)
|
||||||
{
|
{
|
||||||
if (!_statusCapableInContact.ContainsKey(uid) || _statusCapableInContact[uid] <= 0)
|
base.Update(frameTime);
|
||||||
|
|
||||||
|
_toRemove.Clear();
|
||||||
|
|
||||||
|
foreach (var ent in _toUpdate)
|
||||||
|
{
|
||||||
|
_speedModifierSystem.RefreshMovementSpeedModifiers(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var ent in _toRemove)
|
||||||
|
{
|
||||||
|
RemComp<SlowedByContactComponent>(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
_toUpdate.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGetState(EntityUid uid, SlowContactsComponent component, ref ComponentGetState args)
|
||||||
|
{
|
||||||
|
args.State = new SlowContactsComponentState(component.WalkSpeedModifier, component.SprintSpeedModifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnHandleState(EntityUid uid, SlowContactsComponent component, ref ComponentHandleState args)
|
||||||
|
{
|
||||||
|
if (args.Current is not SlowContactsComponentState state)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
component.WalkSpeedModifier = state.WalkSpeedModifier;
|
||||||
|
component.SprintSpeedModifier = state.SprintSpeedModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MovementSpeedCheck(EntityUid uid, SlowedByContactComponent component, RefreshMovementSpeedModifiersEvent args)
|
||||||
|
{
|
||||||
if (!EntityManager.TryGetComponent<PhysicsComponent>(uid, out var physicsComponent))
|
if (!EntityManager.TryGetComponent<PhysicsComponent>(uid, out var physicsComponent))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var walkSpeed = 1.0f;
|
var walkSpeed = 1.0f;
|
||||||
var sprintSpeed = 1.0f;
|
var sprintSpeed = 1.0f;
|
||||||
|
|
||||||
foreach (var colliding in _physics.GetCollidingEntities(physicsComponent))
|
bool remove = true;
|
||||||
|
foreach (var colliding in _physics.GetContactingEntities(physicsComponent))
|
||||||
{
|
{
|
||||||
var ent = colliding.Owner;
|
var ent = colliding.Owner;
|
||||||
if (!EntityManager.TryGetComponent<SlowContactsComponent>(ent, out var slowContactsComponent))
|
if (!TryComp<SlowContactsComponent>(ent, out var slowContactsComponent))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
walkSpeed = Math.Min(walkSpeed, slowContactsComponent.WalkSpeedModifier);
|
walkSpeed = Math.Min(walkSpeed, slowContactsComponent.WalkSpeedModifier);
|
||||||
sprintSpeed = Math.Min(sprintSpeed, slowContactsComponent.SprintSpeedModifier);
|
sprintSpeed = Math.Min(sprintSpeed, slowContactsComponent.SprintSpeedModifier);
|
||||||
|
remove = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
args.ModifySpeed(walkSpeed, sprintSpeed);
|
args.ModifySpeed(walkSpeed, sprintSpeed);
|
||||||
|
|
||||||
|
// no longer colliding with anything
|
||||||
|
if (remove)
|
||||||
|
_toRemove.Add(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEntityExit(EntityUid uid, SlowContactsComponent component, EndCollideEvent args)
|
private void OnEntityExit(EntityUid uid, SlowContactsComponent component, EndCollideEvent args)
|
||||||
{
|
{
|
||||||
var otherUid = args.OtherFixture.Body.Owner;
|
var otherUid = args.OtherFixture.Body.Owner;
|
||||||
if (!EntityManager.HasComponent<MovementSpeedModifierComponent>(otherUid)
|
if (HasComp<MovementSpeedModifierComponent>(otherUid))
|
||||||
|| !EntityManager.HasComponent<SlowsOnContactComponent>(otherUid))
|
_toUpdate.Add(otherUid);
|
||||||
return;
|
|
||||||
if (!_statusCapableInContact.ContainsKey(otherUid))
|
|
||||||
Logger.ErrorS("slowscontacts", $"The entity {otherUid} left a body ({uid}) it was never in.");
|
|
||||||
_statusCapableInContact[otherUid]--;
|
|
||||||
if (_statusCapableInContact[otherUid] == 0)
|
|
||||||
EntityManager.RemoveComponentDeferred<SlowsOnContactComponent>(otherUid);
|
|
||||||
_speedModifierSystem.RefreshMovementSpeedModifiers(otherUid);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEntityEnter(EntityUid uid, SlowContactsComponent component, StartCollideEvent args)
|
private void OnEntityEnter(EntityUid uid, SlowContactsComponent component, StartCollideEvent args)
|
||||||
{
|
{
|
||||||
var otherUid = args.OtherFixture.Body.Owner;
|
var otherUid = args.OtherFixture.Body.Owner;
|
||||||
if (!EntityManager.HasComponent<MovementSpeedModifierComponent>(otherUid))
|
if (!HasComp<MovementSpeedModifierComponent>(otherUid))
|
||||||
return;
|
return;
|
||||||
if (!_statusCapableInContact.ContainsKey(otherUid))
|
|
||||||
_statusCapableInContact[otherUid] = 0;
|
|
||||||
_statusCapableInContact[otherUid]++;
|
|
||||||
|
|
||||||
EnsureComp<SlowsOnContactComponent>(otherUid);
|
EnsureComp<SlowedByContactComponent>(otherUid);
|
||||||
_speedModifierSystem.RefreshMovementSpeedModifiers(otherUid);
|
_toUpdate.Add(otherUid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user