2021-06-09 22:19:39 +02:00
|
|
|
using Content.Shared.ActionBlocker;
|
2020-08-19 18:13:22 -04:00
|
|
|
using Content.Shared.Physics;
|
2021-07-12 01:32:10 -07:00
|
|
|
using Robust.Shared.GameStates;
|
2021-02-28 18:49:48 +01:00
|
|
|
using Robust.Shared.Physics;
|
2020-08-19 18:13:22 -04:00
|
|
|
using Robust.Shared.Serialization;
|
|
|
|
|
|
2021-06-09 22:19:39 +02:00
|
|
|
namespace Content.Shared.Climbing
|
2020-08-19 18:13:22 -04:00
|
|
|
{
|
2021-07-12 01:32:10 -07:00
|
|
|
[NetworkedComponent()]
|
2021-10-21 13:03:14 +11:00
|
|
|
public abstract class SharedClimbingComponent : Component
|
2020-08-19 18:13:22 -04:00
|
|
|
{
|
2022-01-15 03:26:37 +01:00
|
|
|
[Dependency] private readonly IEntityManager _entMan = default!;
|
2022-04-10 16:48:11 +12:00
|
|
|
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
|
2022-01-15 03:26:37 +01:00
|
|
|
|
2022-04-14 14:31:07 +12:00
|
|
|
/// <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();
|
|
|
|
|
|
2021-03-08 04:09:59 +11:00
|
|
|
protected bool IsOnClimbableThisFrame
|
2020-08-19 18:13:22 -04:00
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2022-01-15 03:26:37 +01:00
|
|
|
if (!_entMan.TryGetComponent<PhysicsComponent>(Owner, out var physicsComponent)) return false;
|
2021-03-08 04:09:59 +11:00
|
|
|
|
2022-01-15 03:26:37 +01:00
|
|
|
foreach (var entity in physicsComponent.GetBodiesIntersecting())
|
2020-08-19 18:13:22 -04:00
|
|
|
{
|
2022-02-21 23:01:58 -06:00
|
|
|
if ((entity.CollisionLayer & (int) CollisionGroup.VaultImpassable) != 0) return true;
|
2020-08-19 18:13:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-08 04:09:59 +11:00
|
|
|
[ViewVariables]
|
2021-08-10 10:34:01 +10:00
|
|
|
public virtual bool OwnerIsTransitioning
|
2020-08-19 18:13:22 -04:00
|
|
|
{
|
2021-03-08 04:09:59 +11:00
|
|
|
get => _ownerIsTransitioning;
|
|
|
|
|
set
|
2020-08-19 18:13:22 -04:00
|
|
|
{
|
2021-03-08 04:09:59 +11:00
|
|
|
if (_ownerIsTransitioning == value) return;
|
|
|
|
|
_ownerIsTransitioning = value;
|
2022-01-15 03:26:37 +01:00
|
|
|
if (!_entMan.TryGetComponent<PhysicsComponent>(Owner, out var physicsComponent)) return;
|
2021-03-08 04:09:59 +11:00
|
|
|
if (value)
|
|
|
|
|
{
|
2022-01-15 03:26:37 +01:00
|
|
|
physicsComponent.BodyType = BodyType.Dynamic;
|
2021-03-08 04:09:59 +11:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-01-15 03:26:37 +01:00
|
|
|
physicsComponent.BodyType = BodyType.KinematicController;
|
2021-03-08 04:09:59 +11:00
|
|
|
}
|
2022-04-10 16:48:11 +12:00
|
|
|
|
|
|
|
|
_sysMan.GetEntitySystem<ActionBlockerSystem>().UpdateCanMove(Owner);
|
2021-03-01 03:11:29 +11:00
|
|
|
}
|
2021-03-08 04:09:59 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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>
|
2021-11-20 01:03:09 +00:00
|
|
|
public const float BufferTime = 0.3f;
|
2020-08-19 18:13:22 -04:00
|
|
|
|
2021-03-08 04:09:59 +11:00
|
|
|
public virtual bool IsClimbing
|
|
|
|
|
{
|
|
|
|
|
get => _isClimbing;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (_isClimbing == value) return;
|
|
|
|
|
_isClimbing = value;
|
|
|
|
|
|
2021-03-26 01:51:26 +00:00
|
|
|
ToggleSmallPassable(value);
|
2021-03-08 04:09:59 +11:00
|
|
|
}
|
2021-02-28 18:49:48 +01:00
|
|
|
}
|
2021-03-01 03:11:29 +11:00
|
|
|
|
2022-01-21 01:38:35 -08:00
|
|
|
private bool _isClimbing;
|
2021-03-08 04:09:59 +11:00
|
|
|
|
|
|
|
|
// TODO: Layers need a re-work
|
2021-03-26 01:51:26 +00:00
|
|
|
private void ToggleSmallPassable(bool value)
|
2020-08-19 18:13:22 -04:00
|
|
|
{
|
2021-03-08 04:09:59 +11:00
|
|
|
// Hope the mob has one fixture
|
2022-01-21 01:38:35 -08:00
|
|
|
if (!_entMan.TryGetComponent<FixturesComponent>(Owner, out var fixturesComponent) || fixturesComponent.Deleted) return;
|
2020-08-19 18:13:22 -04:00
|
|
|
|
2022-04-14 14:31:07 +12:00
|
|
|
if (value)
|
2021-03-08 04:09:59 +11:00
|
|
|
{
|
2022-04-14 14:31:07 +12:00
|
|
|
foreach (var (key, fixture) in fixturesComponent.Fixtures)
|
2021-03-08 04:09:59 +11:00
|
|
|
{
|
2022-04-14 14:31:07 +12:00
|
|
|
if ((fixture.CollisionMask & (int) CollisionGroup.VaultImpassable) == 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
VaultImpassableFixtures.Add(key);
|
2022-02-21 23:01:58 -06:00
|
|
|
fixture.CollisionMask &= ~(int) CollisionGroup.VaultImpassable;
|
2021-03-08 04:09:59 +11:00
|
|
|
}
|
2022-04-14 14:31:07 +12:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var key in VaultImpassableFixtures)
|
|
|
|
|
{
|
|
|
|
|
if (fixturesComponent.Fixtures.TryGetValue(key, out var fixture))
|
2022-02-21 23:01:58 -06:00
|
|
|
fixture.CollisionMask |= (int) CollisionGroup.VaultImpassable;
|
2021-03-08 04:09:59 +11:00
|
|
|
}
|
2022-04-14 14:31:07 +12:00
|
|
|
VaultImpassableFixtures.Clear();
|
2020-08-19 18:13:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Serializable, NetSerializable]
|
|
|
|
|
protected sealed class ClimbModeComponentState : ComponentState
|
|
|
|
|
{
|
2021-07-12 01:32:10 -07:00
|
|
|
public ClimbModeComponentState(bool climbing, bool isTransitioning)
|
2020-08-19 18:13:22 -04:00
|
|
|
{
|
|
|
|
|
Climbing = climbing;
|
2021-03-08 04:09:59 +11:00
|
|
|
IsTransitioning = isTransitioning;
|
2020-08-19 18:13:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Climbing { get; }
|
2021-03-08 04:09:59 +11:00
|
|
|
public bool IsTransitioning { get; }
|
2020-08-19 18:13:22 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|