using System; using Content.Shared.ActionBlocker; using Content.Shared.Physics; using Robust.Shared.GameObjects; using Robust.Shared.GameStates; using Robust.Shared.IoC; using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; namespace Content.Shared.Climbing { [NetworkedComponent()] public abstract class SharedClimbingComponent : Component { [Dependency] private readonly IEntityManager _entMan = default!; protected bool IsOnClimbableThisFrame { get { if (!_entMan.TryGetComponent(Owner, out var physicsComponent)) return false; foreach (var entity in physicsComponent.GetBodiesIntersecting()) { if ((entity.CollisionLayer & (int) CollisionGroup.VaultImpassable) != 0) return true; } return false; } } [ViewVariables] public virtual bool OwnerIsTransitioning { get => _ownerIsTransitioning; set { if (_ownerIsTransitioning == value) return; _ownerIsTransitioning = value; if (!_entMan.TryGetComponent(Owner, out var physicsComponent)) return; if (value) { physicsComponent.BodyType = BodyType.Dynamic; } else { physicsComponent.BodyType = BodyType.KinematicController; } } } private bool _ownerIsTransitioning = false; protected TimeSpan StartClimbTime = TimeSpan.Zero; /// /// We'll launch the mob onto the table and give them at least this amount of time to be on it. /// 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(Owner, out var fixturesComponent) || fixturesComponent.Deleted) return; foreach (var fixture in fixturesComponent.Fixtures.Values) { if (value) { fixture.CollisionMask &= ~(int) CollisionGroup.VaultImpassable; } else { fixture.CollisionMask |= (int) CollisionGroup.VaultImpassable; } } } [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; } } } }