Fix climbing out of CloningPod and MedicalScanner (#8191)

* Fix climbing out of CloningPod and MedicalScanner

* Fix mask

* Fix test
This commit is contained in:
Jacob Tong
2022-05-15 02:57:13 -07:00
committed by GitHub
parent 9255cc97a9
commit cecd1b9ef6
6 changed files with 60 additions and 47 deletions

View File

@@ -58,14 +58,15 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.Movement
Assert.That(entityManager.TryGetComponent(human, out climbing), "Human has no climbing");
Assert.That(entityManager.TryGetComponent(table, out ClimbableComponent? _), "Table has no climbable");
// Now let's make the player enter a climbing transitioning state.
climbing.IsClimbing = true;
EntitySystem.Get<ClimbSystem>().MoveEntityToward(human, table, climbing:climbing);
var body = entityManager.GetComponent<IPhysBody>(human);
// TODO: Check it's climbing
// Force the player out of climb state. It should immediately remove the ClimbController.
climbing.IsClimbing = false;
// TODO ShadowCommander: Implement climbing test
// // Now let's make the player enter a climbing transitioning state.
// climbing.IsClimbing = true;
// EntitySystem.Get<ClimbSystem>().MoveEntityToward(human, table, climbing:climbing);
// var body = entityManager.GetComponent<IPhysBody>(human);
// // TODO: Check it's climbing
//
// // Force the player out of climb state. It should immediately remove the ClimbController.
// climbing.IsClimbing = false;
});
await server.WaitIdleAsync();

View File

@@ -33,10 +33,10 @@ public sealed class ClimbSystem : SharedClimbSystem
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
[Dependency] private readonly StunSystem _stunSystem = default!;
private const string ClimbingFixtureName = "climb";
private const int ClimbingCollisionGroup = (int) CollisionGroup.TableLayer;
private const int ClimbingCollisionGroup = (int) (CollisionGroup.TableLayer | CollisionGroup.LowImpassable);
private readonly Dictionary<EntityUid, List<Fixture>> _fixtureRemoveQueue = new();
public override void Initialize()
@@ -111,42 +111,49 @@ public sealed class ClimbSystem : SharedClimbSystem
});
}
private void OnClimbFinished(EntityUid uid, ClimbingComponent climbingComp, ClimbFinishedEvent args)
private void OnClimbFinished(EntityUid uid, ClimbingComponent climbing, ClimbFinishedEvent args)
{
if (!TryComp<PhysicsComponent>(uid, out var physicsComp)
|| !TryComp<FixturesComponent>(uid, out var fixturesComp))
Climb(uid, args.User, args.Climbable, climbing: climbing);
}
private void Climb(EntityUid uid, EntityUid user, EntityUid climbable, bool silent = false, ClimbingComponent? climbing = null,
PhysicsComponent? physics = null, FixturesComponent? fixtures = null)
{
if (!Resolve(uid, ref climbing, ref physics, ref fixtures, false))
return;
if (!ReplaceFixtures(climbingComp, physicsComp, fixturesComp))
if (!ReplaceFixtures(climbing, physics, fixtures))
return;
climbingComp.IsClimbing = true;
climbing.IsClimbing = true;
MoveEntityToward(uid, args.Climbable, physicsComp, climbingComp);
MoveEntityToward(uid, climbable, physics, climbing);
// we may potentially need additional logic since we're forcing a player onto a climbable
// there's also the cases where the user might collide with the person they are forcing onto the climbable that i haven't accounted for
RaiseLocalEvent(uid, new StartClimbEvent(args.Climbable), false);
RaiseLocalEvent(args.Climbable, new ClimbedOnEvent(uid), false);
RaiseLocalEvent(uid, new StartClimbEvent(climbable), false);
RaiseLocalEvent(climbable, new ClimbedOnEvent(uid), false);
if (args.User == uid)
if (silent)
return;
if (user == uid)
{
var othersMessage = Loc.GetString("comp-climbable-user-climbs-other", ("user", uid),
("climbable", args.Climbable));
("climbable", climbable));
uid.PopupMessageOtherClients(othersMessage);
var selfMessage = Loc.GetString("comp-climbable-user-climbs", ("climbable", args.Climbable));
var selfMessage = Loc.GetString("comp-climbable-user-climbs", ("climbable", climbable));
uid.PopupMessage(selfMessage);
}
else
{
var othersMessage = Loc.GetString("comp-climbable-user-climbs-force-other", ("user", args.User),
("moved-user", uid), ("climbable", args.Climbable));
args.User.PopupMessageOtherClients(othersMessage);
var othersMessage = Loc.GetString("comp-climbable-user-climbs-force-other", ("user", user),
("moved-user", uid), ("climbable", climbable));
user.PopupMessageOtherClients(othersMessage);
var selfMessage = Loc.GetString("comp-climbable-user-climbs-force", ("moved-user", uid),
("climbable", args.Climbable));
args.User.PopupMessage(selfMessage);
("climbable", climbable));
user.PopupMessage(selfMessage);
}
}
@@ -179,10 +186,7 @@ public sealed class ClimbSystem : SharedClimbSystem
{
if (args.OurFixture.ID != ClimbingFixtureName
|| !component.IsClimbing
|| component.OwnerIsTransitioning
|| !TryComp<TransformComponent>(uid, out var transformComp)
|| !TryComp<PhysicsComponent>(uid, out var physicsComp)
|| !TryComp<FixturesComponent>(uid, out var fixturesComp))
|| component.OwnerIsTransitioning)
return;
foreach (var fixture in args.OurFixture.Contacts.Keys)
@@ -194,13 +198,21 @@ public sealed class ClimbSystem : SharedClimbSystem
return;
}
foreach (var (name, fixtureMask) in component.DisabledFixtureMasks)
StopClimb(uid, component);
}
private void StopClimb(EntityUid uid, ClimbingComponent? climbing = null, FixturesComponent? fixtures = null)
{
if (!Resolve(uid, ref climbing, ref fixtures, false))
return;
foreach (var (name, fixtureMask) in climbing.DisabledFixtureMasks)
{
if (!fixturesComp.Fixtures.TryGetValue(name, out var fixture))
if (!fixtures.Fixtures.TryGetValue(name, out var fixture))
continue;
fixture.CollisionMask |= fixtureMask;
}
component.DisabledFixtureMasks.Clear();
climbing.DisabledFixtureMasks.Clear();
if (!_fixtureRemoveQueue.TryGetValue(uid, out var removeQueue))
{
@@ -208,10 +220,11 @@ public sealed class ClimbSystem : SharedClimbSystem
_fixtureRemoveQueue.Add(uid, removeQueue);
}
if (fixturesComp.Fixtures.TryGetValue(ClimbingFixtureName, out var climbingFixture))
if (fixtures.Fixtures.TryGetValue(ClimbingFixtureName, out var climbingFixture))
removeQueue.Add(climbingFixture);
component.IsClimbing = false;
climbing.IsClimbing = false;
climbing.OwnerIsTransitioning = false;
}
/// <summary>
@@ -286,19 +299,16 @@ public sealed class ClimbSystem : SharedClimbSystem
return true;
}
public void ForciblySetClimbing(EntityUid uid, ClimbingComponent? component = null)
public void ForciblySetClimbing(EntityUid uid, EntityUid climbable, ClimbingComponent? component = null)
{
if (!Resolve(uid, ref component, false))
return;
component.IsClimbing = true;
Climb(uid, uid, climbable, true, component);
}
private static void OnBuckleChange(EntityUid uid, ClimbingComponent component, BuckleChangeEvent args)
private void OnBuckleChange(EntityUid uid, ClimbingComponent component, BuckleChangeEvent args)
{
if (!args.Buckling)
return;
component.IsClimbing = false;
component.OwnerIsTransitioning = false;
StopClimb(uid, component);
}
private static void OnClimbingGetState(EntityUid uid, ClimbingComponent component, ref ComponentGetState args)
@@ -310,7 +320,7 @@ public sealed class ClimbSystem : SharedClimbSystem
{
if (TryComp<PhysicsComponent>(args.Climber, out var physics) && physics.Mass <= component.MassLimit)
return;
_damageableSystem.TryChangeDamage(args.Climber, component.ClimberDamage);
_damageableSystem.TryChangeDamage(uid, component.TableDamage);
_stunSystem.TryParalyze(args.Climber, TimeSpan.FromSeconds(component.StunTime), true);
@@ -337,7 +347,7 @@ public sealed class ClimbSystem : SharedClimbSystem
to = new Vector2(from.X, to.Y);
else if (MathF.Abs(y) < 0.6f) // user climbed mostly horizontally so lets make it a clean straight line
to = new Vector2(to.X, from.Y);
var velocity = (to - from).Length;
if (velocity <= 0.0f) return;

View File

@@ -4,6 +4,7 @@ namespace Content.Server.Climbing.Components;
[RegisterComponent]
[ComponentReference(typeof(SharedClimbingComponent))]
[Friend(typeof(ClimbSystem))]
public sealed class ClimbingComponent : SharedClimbingComponent
{
[ViewVariables(VVAccess.ReadWrite)]

View File

@@ -186,7 +186,7 @@ namespace Content.Server.Cloning.Components
CapturedMind = null;
CloningProgress = 0f;
UpdateStatus(CloningPodStatus.Idle);
EntitySystem.Get<ClimbSystem>().ForciblySetClimbing(entity);
EntitySystem.Get<ClimbSystem>().ForciblySetClimbing(entity, Owner);
}
public void UpdateStatus(CloningPodStatus status)

View File

@@ -267,7 +267,7 @@ namespace Content.Server.Medical
if (scannerComponent.BodyContainer.ContainedEntity is not {Valid: true} contained) return;
scannerComponent.BodyContainer.Remove(contained);
_climbSystem.ForciblySetClimbing(contained);
_climbSystem.ForciblySetClimbing(contained, uid);
UpdateUserInterface(uid, scannerComponent);
UpdateAppearance(scannerComponent.Owner, scannerComponent);
}

View File

@@ -59,3 +59,4 @@
interfaces:
- key: enum.CloningPodUIKey.Key
type: CloningPodBoundUserInterface
- type: Climbable