Climbing system (#1750)
* Initial commit * Climbing uses its own controller now * Missed a check * Get rid of hands check * Cleanup * Get rid of speciescomponent stuff * Remove unneeded check, add separate case for moving other players. * Add DoAfter * IClientDraggable added to ClimbingComponent * Added some basic integration tests. Renamed ClimbMode to Climbing. * oops * Minor fixes * ffff * Table fix * Revamped system so its more predicted, uses proper logic for de-climbing. Get hype!!! * Flag check fix * Distance check and reset numticksblocked * get rid
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Movement
|
||||
{
|
||||
public interface IClimbable { };
|
||||
|
||||
public class SharedClimbableComponent : Component, IClimbable
|
||||
{
|
||||
public sealed override string Name => "Climbable";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Physics;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Serialization;
|
||||
using System;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Movement
|
||||
{
|
||||
public abstract class SharedClimbingComponent : Component, IActionBlocker, ICollideSpecial
|
||||
{
|
||||
public sealed override string Name => "Climbing";
|
||||
public sealed override uint? NetID => ContentNetIDs.CLIMBING;
|
||||
|
||||
protected ICollidableComponent Body;
|
||||
protected bool IsOnClimbableThisFrame = false;
|
||||
|
||||
protected bool OwnerIsTransitioning
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Body.TryGetController<ClimbController>(out var controller))
|
||||
{
|
||||
return controller.IsActive;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract bool IsClimbing { get; set; }
|
||||
|
||||
bool IActionBlocker.CanMove() => !OwnerIsTransitioning;
|
||||
bool IActionBlocker.CanChangeDirection() => !OwnerIsTransitioning;
|
||||
|
||||
bool ICollideSpecial.PreventCollide(IPhysBody collided)
|
||||
{
|
||||
if (((CollisionGroup)collided.CollisionLayer).HasFlag(CollisionGroup.VaultImpassable) && collided.Entity.HasComponent<IClimbable>())
|
||||
{
|
||||
IsOnClimbableThisFrame = true;
|
||||
return IsClimbing;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
Owner.TryGetComponent(out Body);
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
protected sealed class ClimbModeComponentState : ComponentState
|
||||
{
|
||||
public ClimbModeComponentState(bool climbing) : base(ContentNetIDs.CLIMBING)
|
||||
{
|
||||
Climbing = climbing;
|
||||
}
|
||||
|
||||
public bool Climbing { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,6 @@
|
||||
public const uint STUNNABLE = 1048;
|
||||
public const uint HUNGER = 1049;
|
||||
public const uint THIRST = 1050;
|
||||
|
||||
public const uint FLASHABLE = 1051;
|
||||
public const uint BUCKLE = 1052;
|
||||
public const uint PROJECTILE = 1053;
|
||||
@@ -65,6 +64,7 @@
|
||||
public const uint DO_AFTER = 1058;
|
||||
public const uint RADIATION_PULSE = 1059;
|
||||
public const uint BODY_MANAGER = 1060;
|
||||
public const uint CLIMBING = 1061;
|
||||
|
||||
// Net IDs for integration tests.
|
||||
public const uint PREDICTION_TEST = 10001;
|
||||
|
||||
@@ -10,21 +10,13 @@ namespace Content.Shared.GameObjects.EntitySystems
|
||||
public interface IActionBlocker
|
||||
{
|
||||
bool CanMove() => true;
|
||||
|
||||
bool CanInteract() => true;
|
||||
|
||||
bool CanUse() => true;
|
||||
|
||||
bool CanThrow() => true;
|
||||
|
||||
bool CanSpeak() => true;
|
||||
|
||||
bool CanDrop() => true;
|
||||
|
||||
bool CanPickup() => true;
|
||||
|
||||
bool CanEmote() => true;
|
||||
|
||||
bool CanAttack() => true;
|
||||
|
||||
bool CanEquip() => true;
|
||||
|
||||
87
Content.Shared/Physics/ClimbController.cs
Normal file
87
Content.Shared/Physics/ClimbController.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
#nullable enable
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
|
||||
namespace Content.Shared.Physics
|
||||
{
|
||||
/// <summary>
|
||||
/// Movement controller used by the climb system. Lerps the player from A to B.
|
||||
/// Also does checks to make sure the player isn't blocked.
|
||||
/// </summary>
|
||||
public class ClimbController : VirtualController
|
||||
{
|
||||
private Vector2? _movingTo = null;
|
||||
private Vector2 _lastKnownPosition = default;
|
||||
private int _numTicksBlocked = 0;
|
||||
|
||||
/// <summary>
|
||||
/// If 5 ticks have passed and our position has not changed then something is blocking us.
|
||||
/// </summary>
|
||||
public bool IsBlocked => _numTicksBlocked > 5 || _isMovingWrongDirection;
|
||||
|
||||
/// <summary>
|
||||
/// If the controller is currently moving the player somewhere, it is considered active.
|
||||
/// </summary>
|
||||
public bool IsActive => _movingTo.HasValue;
|
||||
|
||||
private float _initialDist = default;
|
||||
private bool _isMovingWrongDirection = false;
|
||||
|
||||
public void TryMoveTo(Vector2 from, Vector2 to)
|
||||
{
|
||||
if (ControlledComponent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_initialDist = (from - to).Length;
|
||||
_numTicksBlocked = 0;
|
||||
_lastKnownPosition = from;
|
||||
_movingTo = to;
|
||||
_isMovingWrongDirection = false;
|
||||
}
|
||||
|
||||
public override void UpdateAfterProcessing()
|
||||
{
|
||||
base.UpdateAfterProcessing();
|
||||
|
||||
if (ControlledComponent == null || _movingTo == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ControlledComponent.Owner.Transform.WorldPosition - _lastKnownPosition).Length <= 0.05f)
|
||||
{
|
||||
_numTicksBlocked++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_numTicksBlocked = 0;
|
||||
}
|
||||
|
||||
_lastKnownPosition = ControlledComponent.Owner.Transform.WorldPosition;
|
||||
|
||||
if ((ControlledComponent.Owner.Transform.WorldPosition - _movingTo.Value).Length <= 0.05f)
|
||||
{
|
||||
_movingTo = null;
|
||||
}
|
||||
|
||||
if (_movingTo.HasValue)
|
||||
{
|
||||
var dist = (_lastKnownPosition - _movingTo.Value).Length;
|
||||
|
||||
if (dist > _initialDist)
|
||||
{
|
||||
_isMovingWrongDirection = true;
|
||||
}
|
||||
|
||||
var diff = _movingTo.Value - ControlledComponent.Owner.Transform.WorldPosition;
|
||||
LinearVelocity = diff.Normalized * 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
LinearVelocity = Vector2.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user