Rework climbing (#7706)

This commit is contained in:
Jacob Tong
2022-05-10 01:08:52 -07:00
committed by GitHub
parent 7198173ff4
commit 0e945b42b2
11 changed files with 516 additions and 634 deletions

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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; }
}
}