Rework climbing (#7706)
This commit is contained in:
@@ -1,23 +1,28 @@
|
||||
using Content.Shared.DragDrop;
|
||||
using Content.Shared.Movement;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Shared.Climbing
|
||||
namespace Content.Shared.Climbing;
|
||||
|
||||
public abstract class SharedClimbSystem : EntitySystem
|
||||
{
|
||||
public abstract class SharedClimbSystem : EntitySystem
|
||||
public override void Initialize()
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<SharedClimbingComponent, UpdateCanMoveEvent>(HandleMoveAttempt);
|
||||
}
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<SharedClimbingComponent, UpdateCanMoveEvent>(HandleMoveAttempt);
|
||||
SubscribeLocalEvent<SharedClimbableComponent, CanDragDropOnEvent>(OnCanDragDropOn);
|
||||
}
|
||||
|
||||
private void HandleMoveAttempt(EntityUid uid, SharedClimbingComponent component, UpdateCanMoveEvent args)
|
||||
{
|
||||
if (component.LifeStage > ComponentLifeStage.Running)
|
||||
return;
|
||||
private static void HandleMoveAttempt(EntityUid uid, SharedClimbingComponent component, UpdateCanMoveEvent args)
|
||||
{
|
||||
if (component.LifeStage > ComponentLifeStage.Running)
|
||||
return;
|
||||
|
||||
if (component.OwnerIsTransitioning)
|
||||
args.Cancel();
|
||||
}
|
||||
if (component.OwnerIsTransitioning)
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
protected virtual void OnCanDragDropOn(EntityUid uid, SharedClimbableComponent component, CanDragDropOnEvent args)
|
||||
{
|
||||
args.CanDrop = HasComp<SharedClimbingComponent>(args.Dragged);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,13 @@
|
||||
using Content.Shared.DragDrop;
|
||||
using Content.Shared.Interaction;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Shared.Climbing
|
||||
{
|
||||
public interface IClimbable { }
|
||||
|
||||
public abstract class SharedClimbableComponent : Component, IClimbable, IDragDropOn
|
||||
public abstract class SharedClimbableComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The range from which this entity can be climbed.
|
||||
/// </summary>
|
||||
[ViewVariables] [DataField("range")] protected float Range = SharedInteractionSystem.InteractionRange / 1.4f;
|
||||
|
||||
public virtual bool CanDragDropOn(DragDropEvent eventArgs)
|
||||
{
|
||||
return IoCManager.Resolve<IEntityManager>().HasComponent<SharedClimbingComponent>(eventArgs.Dragged);
|
||||
}
|
||||
|
||||
public abstract bool DragDropOn(DragDropEvent eventArgs);
|
||||
[ViewVariables] [DataField("range")] public float Range = SharedInteractionSystem.InteractionRange / 1.4f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,122 +1,38 @@
|
||||
using Content.Shared.ActionBlocker;
|
||||
using Content.Shared.Physics;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Climbing
|
||||
namespace Content.Shared.Climbing;
|
||||
|
||||
[NetworkedComponent]
|
||||
public abstract class SharedClimbingComponent : Component
|
||||
{
|
||||
[NetworkedComponent()]
|
||||
public abstract class SharedClimbingComponent : Component
|
||||
/// <summary>
|
||||
/// Whether the owner is climbing on a climbable entity.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public virtual bool IsClimbing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the owner is being moved onto the climbed entity.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public virtual bool OwnerIsTransitioning { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// We'll launch the mob onto the table and give them at least this amount of time to be on it.
|
||||
/// </summary>
|
||||
public const float BufferTime = 0.3f;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ClimbModeComponentState : ComponentState
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
|
||||
|
||||
/// <summary>
|
||||
/// List of fixtures that had vault-impassable prior to an entity being downed. Required when re-adding the
|
||||
/// collision mask.
|
||||
/// </summary>
|
||||
[DataField("vaultImpassableFixtures")]
|
||||
public List<string> VaultImpassableFixtures = new();
|
||||
|
||||
protected bool IsOnClimbableThisFrame
|
||||
public ClimbModeComponentState(bool climbing, bool isTransitioning)
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_entMan.TryGetComponent<PhysicsComponent>(Owner, out var physicsComponent)) return false;
|
||||
|
||||
foreach (var entity in physicsComponent.GetBodiesIntersecting())
|
||||
{
|
||||
if ((entity.CollisionLayer & (int) CollisionGroup.VaultImpassable) != 0) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
Climbing = climbing;
|
||||
IsTransitioning = isTransitioning;
|
||||
}
|
||||
|
||||
[ViewVariables]
|
||||
public virtual bool OwnerIsTransitioning
|
||||
{
|
||||
get => _ownerIsTransitioning;
|
||||
set
|
||||
{
|
||||
if (_ownerIsTransitioning == value) return;
|
||||
_ownerIsTransitioning = value;
|
||||
if (!_entMan.TryGetComponent<PhysicsComponent>(Owner, out var physicsComponent)) return;
|
||||
if (value)
|
||||
{
|
||||
physicsComponent.BodyType = BodyType.Dynamic;
|
||||
}
|
||||
else
|
||||
{
|
||||
physicsComponent.BodyType = BodyType.KinematicController;
|
||||
}
|
||||
|
||||
_sysMan.GetEntitySystem<ActionBlockerSystem>().UpdateCanMove(Owner);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _ownerIsTransitioning = false;
|
||||
|
||||
protected TimeSpan StartClimbTime = TimeSpan.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// We'll launch the mob onto the table and give them at least this amount of time to be on it.
|
||||
/// </summary>
|
||||
public const float BufferTime = 0.3f;
|
||||
|
||||
public virtual bool IsClimbing
|
||||
{
|
||||
get => _isClimbing;
|
||||
set
|
||||
{
|
||||
if (_isClimbing == value) return;
|
||||
_isClimbing = value;
|
||||
|
||||
ToggleSmallPassable(value);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isClimbing;
|
||||
|
||||
// TODO: Layers need a re-work
|
||||
private void ToggleSmallPassable(bool value)
|
||||
{
|
||||
// Hope the mob has one fixture
|
||||
if (!_entMan.TryGetComponent<FixturesComponent>(Owner, out var fixturesComponent) || fixturesComponent.Deleted) return;
|
||||
|
||||
if (value)
|
||||
{
|
||||
foreach (var (key, fixture) in fixturesComponent.Fixtures)
|
||||
{
|
||||
if ((fixture.CollisionMask & (int) CollisionGroup.VaultImpassable) == 0)
|
||||
continue;
|
||||
|
||||
VaultImpassableFixtures.Add(key);
|
||||
fixture.CollisionMask &= ~(int) CollisionGroup.VaultImpassable;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var key in VaultImpassableFixtures)
|
||||
{
|
||||
if (fixturesComponent.Fixtures.TryGetValue(key, out var fixture))
|
||||
fixture.CollisionMask |= (int) CollisionGroup.VaultImpassable;
|
||||
}
|
||||
VaultImpassableFixtures.Clear();
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
protected sealed class ClimbModeComponentState : ComponentState
|
||||
{
|
||||
public ClimbModeComponentState(bool climbing, bool isTransitioning)
|
||||
{
|
||||
Climbing = climbing;
|
||||
IsTransitioning = isTransitioning;
|
||||
}
|
||||
|
||||
public bool Climbing { get; }
|
||||
public bool IsTransitioning { get; }
|
||||
}
|
||||
public bool Climbing { get; }
|
||||
public bool IsTransitioning { get; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user