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

View File

@@ -35,7 +35,7 @@ public sealed class ClimbSystem : SharedClimbSystem
[Dependency] private readonly StunSystem _stunSystem = default!; [Dependency] private readonly StunSystem _stunSystem = default!;
private const string ClimbingFixtureName = "climb"; 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(); private readonly Dictionary<EntityUid, List<Fixture>> _fixtureRemoveQueue = new();
@@ -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) Climb(uid, args.User, args.Climbable, climbing: climbing);
|| !TryComp<FixturesComponent>(uid, out var fixturesComp)) }
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; return;
if (!ReplaceFixtures(climbingComp, physicsComp, fixturesComp)) if (!ReplaceFixtures(climbing, physics, fixtures))
return; 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 // 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 // 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(uid, new StartClimbEvent(climbable), false);
RaiseLocalEvent(args.Climbable, new ClimbedOnEvent(uid), 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), var othersMessage = Loc.GetString("comp-climbable-user-climbs-other", ("user", uid),
("climbable", args.Climbable)); ("climbable", climbable));
uid.PopupMessageOtherClients(othersMessage); 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); uid.PopupMessage(selfMessage);
} }
else else
{ {
var othersMessage = Loc.GetString("comp-climbable-user-climbs-force-other", ("user", args.User), var othersMessage = Loc.GetString("comp-climbable-user-climbs-force-other", ("user", user),
("moved-user", uid), ("climbable", args.Climbable)); ("moved-user", uid), ("climbable", climbable));
args.User.PopupMessageOtherClients(othersMessage); user.PopupMessageOtherClients(othersMessage);
var selfMessage = Loc.GetString("comp-climbable-user-climbs-force", ("moved-user", uid), var selfMessage = Loc.GetString("comp-climbable-user-climbs-force", ("moved-user", uid),
("climbable", args.Climbable)); ("climbable", climbable));
args.User.PopupMessage(selfMessage); user.PopupMessage(selfMessage);
} }
} }
@@ -179,10 +186,7 @@ public sealed class ClimbSystem : SharedClimbSystem
{ {
if (args.OurFixture.ID != ClimbingFixtureName if (args.OurFixture.ID != ClimbingFixtureName
|| !component.IsClimbing || !component.IsClimbing
|| component.OwnerIsTransitioning || component.OwnerIsTransitioning)
|| !TryComp<TransformComponent>(uid, out var transformComp)
|| !TryComp<PhysicsComponent>(uid, out var physicsComp)
|| !TryComp<FixturesComponent>(uid, out var fixturesComp))
return; return;
foreach (var fixture in args.OurFixture.Contacts.Keys) foreach (var fixture in args.OurFixture.Contacts.Keys)
@@ -194,13 +198,21 @@ public sealed class ClimbSystem : SharedClimbSystem
return; return;
} }
foreach (var (name, fixtureMask) in component.DisabledFixtureMasks) StopClimb(uid, component);
}
private void StopClimb(EntityUid uid, ClimbingComponent? climbing = null, FixturesComponent? fixtures = null)
{ {
if (!fixturesComp.Fixtures.TryGetValue(name, out var fixture)) if (!Resolve(uid, ref climbing, ref fixtures, false))
return;
foreach (var (name, fixtureMask) in climbing.DisabledFixtureMasks)
{
if (!fixtures.Fixtures.TryGetValue(name, out var fixture))
continue; continue;
fixture.CollisionMask |= fixtureMask; fixture.CollisionMask |= fixtureMask;
} }
component.DisabledFixtureMasks.Clear(); climbing.DisabledFixtureMasks.Clear();
if (!_fixtureRemoveQueue.TryGetValue(uid, out var removeQueue)) if (!_fixtureRemoveQueue.TryGetValue(uid, out var removeQueue))
{ {
@@ -208,10 +220,11 @@ public sealed class ClimbSystem : SharedClimbSystem
_fixtureRemoveQueue.Add(uid, removeQueue); _fixtureRemoveQueue.Add(uid, removeQueue);
} }
if (fixturesComp.Fixtures.TryGetValue(ClimbingFixtureName, out var climbingFixture)) if (fixtures.Fixtures.TryGetValue(ClimbingFixtureName, out var climbingFixture))
removeQueue.Add(climbingFixture); removeQueue.Add(climbingFixture);
component.IsClimbing = false; climbing.IsClimbing = false;
climbing.OwnerIsTransitioning = false;
} }
/// <summary> /// <summary>
@@ -286,19 +299,16 @@ public sealed class ClimbSystem : SharedClimbSystem
return true; 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)) Climb(uid, uid, climbable, true, component);
return;
component.IsClimbing = true;
} }
private static void OnBuckleChange(EntityUid uid, ClimbingComponent component, BuckleChangeEvent args) private void OnBuckleChange(EntityUid uid, ClimbingComponent component, BuckleChangeEvent args)
{ {
if (!args.Buckling) if (!args.Buckling)
return; return;
component.IsClimbing = false; StopClimb(uid, component);
component.OwnerIsTransitioning = false;
} }
private static void OnClimbingGetState(EntityUid uid, ClimbingComponent component, ref ComponentGetState args) private static void OnClimbingGetState(EntityUid uid, ClimbingComponent component, ref ComponentGetState args)

View File

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

View File

@@ -186,7 +186,7 @@ namespace Content.Server.Cloning.Components
CapturedMind = null; CapturedMind = null;
CloningProgress = 0f; CloningProgress = 0f;
UpdateStatus(CloningPodStatus.Idle); UpdateStatus(CloningPodStatus.Idle);
EntitySystem.Get<ClimbSystem>().ForciblySetClimbing(entity); EntitySystem.Get<ClimbSystem>().ForciblySetClimbing(entity, Owner);
} }
public void UpdateStatus(CloningPodStatus status) 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; if (scannerComponent.BodyContainer.ContainedEntity is not {Valid: true} contained) return;
scannerComponent.BodyContainer.Remove(contained); scannerComponent.BodyContainer.Remove(contained);
_climbSystem.ForciblySetClimbing(contained); _climbSystem.ForciblySetClimbing(contained, uid);
UpdateUserInterface(uid, scannerComponent); UpdateUserInterface(uid, scannerComponent);
UpdateAppearance(scannerComponent.Owner, scannerComponent); UpdateAppearance(scannerComponent.Owner, scannerComponent);
} }

View File

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