diff --git a/Content.Client/GameObjects/Components/Movement/ClimbingComponent.cs b/Content.Client/GameObjects/Components/Movement/ClimbingComponent.cs index dc47a7bacc..92a76edd1f 100644 --- a/Content.Client/GameObjects/Components/Movement/ClimbingComponent.cs +++ b/Content.Client/GameObjects/Components/Movement/ClimbingComponent.cs @@ -11,13 +11,14 @@ namespace Content.Client.GameObjects.Components.Movement { base.HandleComponentState(curState, nextState); - if (curState is not ClimbModeComponentState climbModeState) + if (curState is not ClimbModeComponentState climbModeState || Body == null) { return; } IsClimbing = climbModeState.Climbing; - OwnerIsTransitioning = climbModeState.IsTransitioning; } + + public override bool IsClimbing { get; set; } } } diff --git a/Content.Client/GameObjects/Components/Movement/PlayerInputMoverComponent.cs b/Content.Client/GameObjects/Components/Movement/PlayerInputMoverComponent.cs new file mode 100644 index 0000000000..84af66d532 --- /dev/null +++ b/Content.Client/GameObjects/Components/Movement/PlayerInputMoverComponent.cs @@ -0,0 +1,15 @@ +#nullable enable +using Content.Shared.GameObjects.Components.Movement; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; + +namespace Content.Client.GameObjects.Components.Movement +{ + [RegisterComponent] + [ComponentReference(typeof(IMoverComponent))] + public class PlayerInputMoverComponent : SharedPlayerInputMoverComponent + { + public override EntityCoordinates LastPosition { get; set; } + public override float StepSoundDistance { get; set; } + } +} diff --git a/Content.Client/GameObjects/Components/Projectiles/ThrownItemComponent.cs b/Content.Client/GameObjects/Components/Projectiles/ThrownItemComponent.cs new file mode 100644 index 0000000000..6f43d63505 --- /dev/null +++ b/Content.Client/GameObjects/Components/Projectiles/ThrownItemComponent.cs @@ -0,0 +1,12 @@ +using Content.Shared.GameObjects; +using Robust.Shared.GameObjects; + +namespace Content.Client.GameObjects.Components.Projectiles +{ + [RegisterComponent] + public class ThrownItemComponent : ProjectileComponent + { + public override string Name => "ThrownItem"; + public override uint? NetID => ContentNetIDs.THROWN_ITEM; + } +} diff --git a/Content.Client/GameObjects/Components/Suspicion/TraitorOverlay.cs b/Content.Client/GameObjects/Components/Suspicion/TraitorOverlay.cs index be5c76a84d..27e60e6853 100644 --- a/Content.Client/GameObjects/Components/Suspicion/TraitorOverlay.cs +++ b/Content.Client/GameObjects/Components/Suspicion/TraitorOverlay.cs @@ -6,7 +6,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Maths; -using Robust.Shared.Physics; namespace Content.Client.GameObjects.Components.Suspicion { @@ -63,7 +62,7 @@ namespace Content.Client.GameObjects.Components.Suspicion continue; } - if (!ally.TryGetComponent(out IPhysBody physics)) + if (!ally.TryGetComponent(out IPhysicsComponent physics)) { continue; } @@ -83,7 +82,7 @@ namespace Content.Client.GameObjects.Components.Suspicion continue; } - var worldBox = physics.GetWorldAABB(); + var worldBox = physics.WorldAABB; // if not on screen, or too small, continue if (!worldBox.Intersects(in viewport) || worldBox.IsEmpty()) @@ -91,7 +90,7 @@ namespace Content.Client.GameObjects.Components.Suspicion continue; } - var screenCoordinates = _eyeManager.WorldToScreen(physics.GetWorldAABB().TopLeft + (0, 0.5f)); + var screenCoordinates = _eyeManager.WorldToScreen(physics.WorldAABB.TopLeft + (0, 0.5f)); DrawString(screen, _font, screenCoordinates, _traitorText, Color.OrangeRed); } } diff --git a/Content.Client/GameObjects/EntitySystems/MoverSystem.cs b/Content.Client/GameObjects/EntitySystems/MoverSystem.cs new file mode 100644 index 0000000000..ca426d8cbc --- /dev/null +++ b/Content.Client/GameObjects/EntitySystems/MoverSystem.cs @@ -0,0 +1,43 @@ +#nullable enable +using Content.Shared.GameObjects.Components.Movement; +using Content.Shared.GameObjects.EntitySystems; +using JetBrains.Annotations; +using Robust.Client.Physics; +using Robust.Client.Player; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; + +namespace Content.Client.GameObjects.EntitySystems +{ + [UsedImplicitly] + public class MoverSystem : SharedMoverSystem + { + [Dependency] private readonly IPlayerManager _playerManager = default!; + + public override void Initialize() + { + base.Initialize(); + + UpdatesBefore.Add(typeof(PhysicsSystem)); + } + + public override void FrameUpdate(float frameTime) + { + var playerEnt = _playerManager.LocalPlayer?.ControlledEntity; + + if (playerEnt == null || !playerEnt.TryGetComponent(out IMoverComponent? mover) || !playerEnt.TryGetComponent(out IPhysicsComponent? physics)) + { + return; + } + + physics.Predict = true; + + UpdateKinematics(playerEnt.Transform, mover, physics); + } + + public override void Update(float frameTime) + { + FrameUpdate(frameTime); + } + } +} diff --git a/Content.Client/GameObjects/EntitySystems/SubFloorHideSystem.cs b/Content.Client/GameObjects/EntitySystems/SubFloorHideSystem.cs index eb090c024a..beda5c0fca 100644 --- a/Content.Client/GameObjects/EntitySystems/SubFloorHideSystem.cs +++ b/Content.Client/GameObjects/EntitySystems/SubFloorHideSystem.cs @@ -85,22 +85,13 @@ namespace Content.Client.GameObjects.EntitySystems foreach (var snapGridComponent in grid.GetSnapGridCell(position, SnapGridOffset.Center)) { var entity = snapGridComponent.Owner; - if (!entity.TryGetComponent(out SubFloorHideComponent subFloorComponent)) + if (!entity.TryGetComponent(out SubFloorHideComponent subFloorComponent) || + !entity.TryGetComponent(out ISpriteComponent spriteComponent)) { continue; } - var enabled = EnableAll || !subFloorComponent.Running || tileDef.IsSubFloor; - - if (entity.TryGetComponent(out ISpriteComponent spriteComponent)) - { - spriteComponent.Visible = enabled; - } - - if (entity.TryGetComponent(out PhysicsComponent physicsComponent)) - { - physicsComponent.CanCollide = enabled; - } + spriteComponent.Visible = EnableAll || !subFloorComponent.Running || tileDef.IsSubFloor; } } } diff --git a/Content.Client/Physics/Controllers/MoverController.cs b/Content.Client/Physics/Controllers/MoverController.cs deleted file mode 100644 index 797b34f1ac..0000000000 --- a/Content.Client/Physics/Controllers/MoverController.cs +++ /dev/null @@ -1,36 +0,0 @@ -#nullable enable -using Content.Shared.GameObjects.Components.Movement; -using Content.Shared.Physics.Controllers; -using Robust.Client.Player; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Physics.Dynamics; - -namespace Content.Client.Physics.Controllers -{ - public sealed class MoverController : SharedMoverController - { - [Dependency] private readonly IPlayerManager _playerManager = default!; - - public override void UpdateBeforeSolve(bool prediction, float frameTime) - { - base.UpdateBeforeSolve(prediction, frameTime); - - var player = _playerManager.LocalPlayer?.ControlledEntity; - if (player == null || - !player.TryGetComponent(out IMoverComponent? mover) || - !player.TryGetComponent(out PhysicsComponent? body)) return; - - body.Predict = true; // TODO: equal prediction instead of true? - - // Server-side should just be handled on its own so we'll just do this shizznit - if (player.TryGetComponent(out IMobMoverComponent? mobMover)) - { - HandleMobMovement(mover, body, mobMover); - return; - } - - HandleKinematicMovement(mover, body); - } - } -} diff --git a/Content.IntegrationTests/Tests/Doors/AirlockTest.cs b/Content.IntegrationTests/Tests/Doors/AirlockTest.cs index 0bb982f8d7..624f257233 100644 --- a/Content.IntegrationTests/Tests/Doors/AirlockTest.cs +++ b/Content.IntegrationTests/Tests/Doors/AirlockTest.cs @@ -20,10 +20,9 @@ namespace Content.IntegrationTests.Tests.Doors components: - type: Physics anchored: false - fixtures: - - shape: - !type:PhysShapeAabb - bounds: ""-0.49,-0.49,0.49,0.49"" + shapes: + - !type:PhysShapeAabb + bounds: ""-0.49,-0.49,0.49,0.49"" layer: - Impassable @@ -34,10 +33,9 @@ namespace Content.IntegrationTests.Tests.Doors - type: Door - type: Airlock - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: ""-0.49,-0.49,0.49,0.49"" + shapes: + - !type:PhysShapeAabb + bounds: ""-0.49,-0.49,0.49,0.49"" mask: - Impassable "; @@ -113,9 +111,9 @@ namespace Content.IntegrationTests.Tests.Doors var mapManager = server.ResolveDependency(); var entityManager = server.ResolveDependency(); - IPhysBody physBody = null; IEntity physicsDummy = null; IEntity airlock = null; + TestController controller = null; ServerDoorComponent doorComponent = null; var physicsDummyStartingX = -1; @@ -130,7 +128,9 @@ namespace Content.IntegrationTests.Tests.Doors airlock = entityManager.SpawnEntity("AirlockDummy", new MapCoordinates((0, 0), mapId)); - Assert.True(physicsDummy.TryGetComponent(out physBody)); + Assert.True(physicsDummy.TryGetComponent(out IPhysicsComponent physics)); + + controller = physics.EnsureController(); Assert.True(airlock.TryGetComponent(out doorComponent)); Assert.That(doorComponent.State, Is.EqualTo(SharedDoorComponent.DoorState.Closed)); @@ -139,13 +139,12 @@ namespace Content.IntegrationTests.Tests.Doors await server.WaitIdleAsync(); // Push the human towards the airlock - Assert.That(physBody != null); - physBody.LinearVelocity = (0.5f, 0); + controller.LinearVelocity = (0.5f, 0); for (var i = 0; i < 240; i += 10) { // Keep the airlock awake so they collide - airlock.GetComponent().WakeBody(); + airlock.GetComponent().WakeBody(); // Ensure that it is still closed Assert.That(doorComponent.State, Is.EqualTo(SharedDoorComponent.DoorState.Closed)); @@ -160,5 +159,7 @@ namespace Content.IntegrationTests.Tests.Doors // Blocked by the airlock Assert.That(physicsDummy.Transform.MapPosition.X, Is.Negative.Or.Zero); } + + private class TestController : VirtualController { } } } diff --git a/Content.IntegrationTests/Tests/GameObjects/Components/Movement/ClimbUnitTest.cs b/Content.IntegrationTests/Tests/GameObjects/Components/Movement/ClimbUnitTest.cs index 3dfe930761..e4db6d3aba 100644 --- a/Content.IntegrationTests/Tests/GameObjects/Components/Movement/ClimbUnitTest.cs +++ b/Content.IntegrationTests/Tests/GameObjects/Components/Movement/ClimbUnitTest.cs @@ -7,7 +7,6 @@ using NUnit.Framework; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; -using Robust.Shared.Physics; namespace Content.IntegrationTests.Tests.GameObjects.Components.Movement { @@ -60,12 +59,15 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.Movement // Now let's make the player enter a climbing transitioning state. climbing.IsClimbing = true; climbing.TryMoveTo(human.Transform.WorldPosition, table.Transform.WorldPosition); - var body = human.GetComponent(); - // TODO: Check it's climbing + var body = human.GetComponent(); + + Assert.That(body.HasController(), "Player has no ClimbController"); // Force the player out of climb state. It should immediately remove the ClimbController. climbing.IsClimbing = false; + Assert.That(!body.HasController(), "Player wrongly has a ClimbController"); + }); await server.WaitIdleAsync(); diff --git a/Content.IntegrationTests/Tests/Pulling/PullTest.cs b/Content.IntegrationTests/Tests/Pulling/PullTest.cs new file mode 100644 index 0000000000..e1f9954e5e --- /dev/null +++ b/Content.IntegrationTests/Tests/Pulling/PullTest.cs @@ -0,0 +1,79 @@ +using System.Threading.Tasks; +using Content.Server.GameObjects.Components.Pulling; +using Content.Shared.GameObjects.Components.Pulling; +using Content.Shared.Physics.Pull; +using NUnit.Framework; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; + +namespace Content.IntegrationTests.Tests.Pulling +{ + [TestFixture] + [TestOf(typeof(SharedPullableComponent))] + [TestOf(typeof(SharedPullerComponent))] + [TestOf(typeof(PullController))] + public class PullTest : ContentIntegrationTest + { + private const string Prototypes = @" +- type: entity + name: PullTestPullerDummy + id: PullTestPullerDummy + components: + - type: Puller + - type: Physics + +- type: entity + name: PullTestPullableDummy + id: PullTestPullableDummy + components: + - type: Pullable + - type: Physics +"; + + [Test] + public async Task AnchoredNoPullTest() + { + var options = new ServerContentIntegrationOption {ExtraPrototypes = Prototypes}; + var server = StartServerDummyTicker(options); + + await server.WaitIdleAsync(); + + var mapManager = server.ResolveDependency(); + var entityManager = server.ResolveDependency(); + + await server.WaitAssertion(() => + { + mapManager.CreateNewMapEntity(MapId.Nullspace); + + var pullerEntity = entityManager.SpawnEntity("PullTestPullerDummy", MapCoordinates.Nullspace); + var pullableEntity = entityManager.SpawnEntity("PullTestPullableDummy", MapCoordinates.Nullspace); + + var puller = pullerEntity.GetComponent(); + var pullable = pullableEntity.GetComponent(); + var pullablePhysics = pullableEntity.GetComponent(); + + pullablePhysics.Anchored = false; + + Assert.That(pullable.TryStartPull(puller.Owner)); + Assert.That(pullable.Puller, Is.EqualTo(puller.Owner)); + Assert.That(pullable.BeingPulled); + + Assert.That(puller.Pulling, Is.EqualTo(pullable.Owner)); + + Assert.That(pullable.TryStopPull); + Assert.That(pullable.Puller, Is.Null); + Assert.That(pullable.BeingPulled, Is.False); + + Assert.That(puller.Pulling, Is.Null); + + pullablePhysics.Anchored = true; + + Assert.That(pullable.TryStartPull(puller.Owner), Is.False); + Assert.That(pullable.Puller, Is.Null); + Assert.That(pullable.BeingPulled, Is.False); + + Assert.That(puller.Pulling, Is.Null); + }); + } + } +} diff --git a/Content.IntegrationTests/Tests/Utility/EntitySystemExtensionsTest.cs b/Content.IntegrationTests/Tests/Utility/EntitySystemExtensionsTest.cs index 60b376b00b..060c0efc29 100644 --- a/Content.IntegrationTests/Tests/Utility/EntitySystemExtensionsTest.cs +++ b/Content.IntegrationTests/Tests/Utility/EntitySystemExtensionsTest.cs @@ -5,7 +5,6 @@ using Content.Shared.Utility; using NUnit.Framework; using Robust.Shared.GameObjects; using Robust.Shared.Map; -using Robust.Shared.Physics.Broadphase; namespace Content.IntegrationTests.Tests.Utility { @@ -21,10 +20,9 @@ namespace Content.IntegrationTests.Tests.Utility name: {BlockerDummyId} components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: ""-0.49,-0.49,0.49,0.49"" + shapes: + - !type:PhysShapeAabb + bounds: ""-0.49,-0.49,0.49,0.49"" mask: - Impassable "; @@ -39,7 +37,6 @@ namespace Content.IntegrationTests.Tests.Utility var sMapManager = server.ResolveDependency(); var sEntityManager = server.ResolveDependency(); - var broady = server.ResolveDependency().GetEntitySystem(); await server.WaitAssertion(() => { @@ -61,7 +58,6 @@ namespace Content.IntegrationTests.Tests.Utility // Spawn a blocker with an Impassable mask sEntityManager.SpawnEntity(BlockerDummyId, entityCoordinates); - broady.Update(0.016f); // Cannot spawn something with an Impassable layer Assert.Null(sEntityManager.SpawnIfUnobstructed(null, entityCoordinates, CollisionGroup.Impassable)); diff --git a/Content.Server/AI/Utils/Visibility.cs b/Content.Server/AI/Utils/Visibility.cs index 1130ac09a9..238d6b90c7 100644 --- a/Content.Server/AI/Utils/Visibility.cs +++ b/Content.Server/AI/Utils/Visibility.cs @@ -8,7 +8,6 @@ using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Physics; -using Robust.Shared.Physics.Broadphase; namespace Content.Server.AI.Utils { @@ -41,7 +40,7 @@ namespace Content.Server.AI.Utils angle.ToVec(), (int)(CollisionGroup.Opaque | CollisionGroup.Impassable | CollisionGroup.MobImpassable)); - var rayCastResults = EntitySystem.Get().IntersectRay(owner.Transform.MapID, ray, range, owner).ToList(); + var rayCastResults = IoCManager.Resolve().IntersectRay(owner.Transform.MapID, ray, range, owner).ToList(); return rayCastResults.Count > 0 && rayCastResults[0].HitEntity == target; } diff --git a/Content.Server/Administration/Commands/WarpCommand.cs b/Content.Server/Administration/Commands/WarpCommand.cs index 5c3ce5dadf..f46f7c2fca 100644 --- a/Content.Server/Administration/Commands/WarpCommand.cs +++ b/Content.Server/Administration/Commands/WarpCommand.cs @@ -8,8 +8,6 @@ using Robust.Shared.Enums; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; -using Robust.Shared.Maths; -using Robust.Shared.Physics; namespace Content.Server.Administration.Commands { @@ -115,9 +113,9 @@ namespace Content.Server.Administration.Commands if (found.GetGridId(entityManager) != GridId.Invalid) { player.AttachedEntity.Transform.Coordinates = found; - if (player.AttachedEntity.TryGetComponent(out IPhysBody physics)) + if (player.AttachedEntity.TryGetComponent(out IPhysicsComponent physics)) { - physics.LinearVelocity = Vector2.Zero; + physics.Stop(); } } else diff --git a/Content.Server/Atmos/HighPressureMovementController.cs b/Content.Server/Atmos/HighPressureMovementController.cs new file mode 100644 index 0000000000..e2e47c0663 --- /dev/null +++ b/Content.Server/Atmos/HighPressureMovementController.cs @@ -0,0 +1,70 @@ +#nullable enable +using System; +using Content.Server.GameObjects.Components.Atmos; +using Content.Shared.Atmos; +using Content.Shared.Physics; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using Robust.Shared.Maths; +using Robust.Shared.Random; + +namespace Content.Server.Atmos +{ + public class HighPressureMovementController : FrictionController + { + [Dependency] private readonly IRobustRandom _robustRandom = default!; + public override IPhysicsComponent? ControlledComponent { protected get; set; } + + private const float MoveForcePushRatio = 1f; + private const float MoveForceForcePushRatio = 1f; + private const float ProbabilityOffset = 25f; + private const float ProbabilityBasePercent = 10f; + private const float ThrowForce = 100f; + + public void ExperiencePressureDifference(int cycle, float pressureDifference, AtmosDirection direction, + float pressureResistanceProbDelta, EntityCoordinates throwTarget) + { + if (ControlledComponent == null) + return; + + // TODO ATMOS stuns? + + var transform = ControlledComponent.Owner.Transform; + var pressureComponent = ControlledComponent.Owner.GetComponent(); + var maxForce = MathF.Sqrt(pressureDifference) * 2.25f; + var moveProb = 100f; + + if (pressureComponent.PressureResistance > 0) + moveProb = MathF.Abs((pressureDifference / pressureComponent.PressureResistance * ProbabilityBasePercent) - + ProbabilityOffset); + + if (moveProb > ProbabilityOffset && _robustRandom.Prob(MathF.Min(moveProb / 100f, 1f)) + && !float.IsPositiveInfinity(pressureComponent.MoveResist) + && (!ControlledComponent.Anchored + && (maxForce >= (pressureComponent.MoveResist * MoveForcePushRatio))) + || (ControlledComponent.Anchored && (maxForce >= (pressureComponent.MoveResist * MoveForceForcePushRatio)))) + { + + + if (maxForce > ThrowForce) + { + if (throwTarget != EntityCoordinates.Invalid) + { + var moveForce = maxForce * MathHelper.Clamp(moveProb, 0, 100) / 150f; + var pos = ((throwTarget.Position - transform.Coordinates.Position).Normalized + direction.ToDirection().ToVec()).Normalized; + LinearVelocity = pos * moveForce; + } + + else + { + var moveForce = MathF.Min(maxForce * MathHelper.Clamp(moveProb, 0, 100) / 2500f, 20f); + LinearVelocity = direction.ToDirection().ToVec() * moveForce; + } + + pressureComponent.LastHighPressureMovementAirCycle = cycle; + } + } + } + } +} diff --git a/Content.Server/Atmos/TileAtmosphere.cs b/Content.Server/Atmos/TileAtmosphere.cs index a409408254..274a31cced 100644 --- a/Content.Server/Atmos/TileAtmosphere.cs +++ b/Content.Server/Atmos/TileAtmosphere.cs @@ -17,7 +17,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Random; using Robust.Shared.ViewVariables; @@ -194,12 +193,14 @@ namespace Content.Server.Atmos foreach (var entity in _gridTileLookupSystem.GetEntitiesIntersecting(GridIndex, GridIndices)) { - if (!entity.TryGetComponent(out IPhysBody physics) + if (!entity.TryGetComponent(out IPhysicsComponent physics) || !entity.IsMovedByPressure(out var pressure) || entity.IsInContainer()) continue; - var pressureMovements = physics.Entity.EnsureComponent(); + physics.WakeBody(); + + var pressureMovements = physics.EnsureController(); if (pressure.LastHighPressureMovementAirCycle < _gridAtmosphereComponent.UpdateCounter) { pressureMovements.ExperiencePressureDifference(_gridAtmosphereComponent.UpdateCounter, PressureDifference, _pressureDirection, 0, PressureSpecificTarget?.GridIndices.ToEntityCoordinates(GridIndex, _mapManager) ?? EntityCoordinates.Invalid); diff --git a/Content.Server/Commands/MakeSentientCommand.cs b/Content.Server/Commands/MakeSentientCommand.cs index b8fb7e356d..115369baf3 100644 --- a/Content.Server/Commands/MakeSentientCommand.cs +++ b/Content.Server/Commands/MakeSentientCommand.cs @@ -5,7 +5,6 @@ using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Movement; using Content.Shared.Administration; using Content.Shared.GameObjects.Components.Mobs.Speech; -using Content.Shared.GameObjects.Components.Movement; using Robust.Shared.Console; using Robust.Shared.GameObjects; using Robust.Shared.IoC; @@ -56,8 +55,7 @@ namespace Content.Server.Commands Timer.Spawn(100, () => { entity.EnsureComponent(); - entity.EnsureComponent(); - entity.EnsureComponent(); + entity.EnsureComponent(); entity.EnsureComponent(); entity.EnsureComponent(); }); diff --git a/Content.Server/Commands/Physics/TestbedCommand.cs b/Content.Server/Commands/Physics/TestbedCommand.cs deleted file mode 100644 index aaeb6f2912..0000000000 --- a/Content.Server/Commands/Physics/TestbedCommand.cs +++ /dev/null @@ -1,234 +0,0 @@ -// MIT License - -// Copyright (c) 2019 Erin Catto - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - - -using Content.Server.Administration; -using Content.Shared.Administration; -using Content.Shared.Physics; -using Robust.Server.Player; -using Robust.Shared.Console; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Map; -using Robust.Shared.Maths; -using Robust.Shared.Physics; -using Robust.Shared.Physics.Dynamics; -using Robust.Shared.Physics.Dynamics.Shapes; -using Robust.Shared.Timing; - -#nullable enable - -namespace Content.Server.Commands.Physics -{ - /* - * I didn't use blueprints because this is way easier to iterate upon as I can shit out testbed upon testbed on new maps - * and never have to leave my debugger. - */ - - /// - /// Copies of Box2D's physics testbed for debugging. - /// - [AdminCommand(AdminFlags.Mapping)] - public class TestbedCommand : IConsoleCommand - { - public string Command => "testbed"; - public string Description => "Loads a physics testbed and teleports your player there"; - public string Help => $"{Command} "; - public void Execute(IConsoleShell shell, string argStr, string[] args) - { - if (args.Length != 2) - { - shell.WriteLine("Require 2 args for testbed!"); - return; - } - - var mapManager = IoCManager.Resolve(); - - if (!int.TryParse(args[0], out var mapInt)) - { - shell.WriteLine($"Unable to parse map {args[0]}"); - return; - } - - var mapId = new MapId(mapInt); - if (!mapManager.MapExists(mapId)) - { - shell.WriteLine("Unable to find map {mapId}"); - return; - } - - if (shell.Player == null) - { - shell.WriteLine("No player found"); - return; - } - - var player = (IPlayerSession) shell.Player; - - switch (args[1]) - { - case "boxstack": - SetupPlayer(mapId, shell, player, mapManager); - CreateBoxStack(mapId); - break; - case "circlestack": - SetupPlayer(mapId, shell, player, mapManager); - CreateCircleStack(mapId); - break; - default: - shell.WriteLine($"testbed {args[0]} not found!"); - return; - } - - shell.WriteLine($"Testbed on map {mapId}"); - } - - private void SetupPlayer(MapId mapId, IConsoleShell shell, IPlayerSession? player, IMapManager mapManager) - { - var pauseManager = IoCManager.Resolve(); - pauseManager.SetMapPaused(mapId, false); - var map = EntitySystem.Get().Maps[mapId].Gravity = new Vector2(0, -4.9f); - - return; - } - - private void CreateBoxStack(MapId mapId) - { - var entityManager = IoCManager.Resolve(); - - var ground = entityManager.SpawnEntity("BlankEntity", new MapCoordinates(0, 0, mapId)).AddComponent(); - - var horizontal = new EdgeShape(new Vector2(-20, 0), new Vector2(20, 0)); - var horizontalFixture = new Fixture(ground, horizontal) - { - CollisionLayer = (int) CollisionGroup.Impassable, - CollisionMask = (int) CollisionGroup.Impassable, - Hard = true - }; - ground.AddFixture(horizontalFixture); - - var vertical = new EdgeShape(new Vector2(10, 0), new Vector2(10, 10)); - var verticalFixture = new Fixture(ground, vertical) - { - CollisionLayer = (int) CollisionGroup.Impassable, - CollisionMask = (int) CollisionGroup.Impassable, - Hard = true - }; - ground.AddFixture(verticalFixture); - - var xs = new[] - { - 0.0f, -10.0f, -5.0f, 5.0f, 10.0f - }; - - var columnCount = 1; - var rowCount = 15; - PolygonShape shape; - - for (var j = 0; j < columnCount; j++) - { - for (var i = 0; i < rowCount; i++) - { - var x = 0.0f; - - var box = entityManager.SpawnEntity("BlankEntity", - new MapCoordinates(new Vector2(xs[j] + x, 0.55f + 2.1f * i), mapId)).AddComponent(); - - box.BodyType = BodyType.Dynamic; - box.SleepingAllowed = false; - shape = new PolygonShape(); - shape.SetAsBox(0.5f, 0.5f); - box.FixedRotation = false; - // TODO: Need to detect shape and work out if we need to use fixedrotation - - var fixture = new Fixture(box, shape) - { - CollisionMask = (int) CollisionGroup.Impassable, - CollisionLayer = (int) CollisionGroup.Impassable, - Hard = true, - }; - box.AddFixture(fixture); - } - } - } - - private void CreateCircleStack(MapId mapId) - { - var entityManager = IoCManager.Resolve(); - - // TODO: Need a blank entity we can spawn for testbed. - var ground = entityManager.SpawnEntity("BlankEntity", new MapCoordinates(0, 0, mapId)).AddComponent(); - - var horizontal = new EdgeShape(new Vector2(-20, 0), new Vector2(20, 0)); - var horizontalFixture = new Fixture(ground, horizontal) - { - CollisionLayer = (int) CollisionGroup.Impassable, - CollisionMask = (int) CollisionGroup.Impassable, - Hard = true - }; - ground.AddFixture(horizontalFixture); - - var vertical = new EdgeShape(new Vector2(10, 0), new Vector2(10, 10)); - var verticalFixture = new Fixture(ground, vertical) - { - CollisionLayer = (int) CollisionGroup.Impassable, - CollisionMask = (int) CollisionGroup.Impassable, - Hard = true - }; - ground.AddFixture(verticalFixture); - - var xs = new[] - { - 0.0f, -10.0f, -5.0f, 5.0f, 10.0f - }; - - var columnCount = 1; - var rowCount = 15; - PhysShapeCircle shape; - - for (var j = 0; j < columnCount; j++) - { - for (var i = 0; i < rowCount; i++) - { - var x = 0.0f; - - var box = entityManager.SpawnEntity("BlankEntity", - new MapCoordinates(new Vector2(xs[j] + x, 0.55f + 2.1f * i), mapId)).AddComponent(); - - box.BodyType = BodyType.Dynamic; - box.SleepingAllowed = false; - shape = new PhysShapeCircle {Radius = 0.5f}; - box.FixedRotation = false; - // TODO: Need to detect shape and work out if we need to use fixedrotation - - var fixture = new Fixture(box, shape) - { - CollisionMask = (int) CollisionGroup.Impassable, - CollisionLayer = (int) CollisionGroup.Impassable, - Hard = true, - }; - box.AddFixture(fixture); - } - } - } - } -} diff --git a/Content.Server/Construction/Completions/SetAnchor.cs b/Content.Server/Construction/Completions/SetAnchor.cs index 680d021237..69037b8b79 100644 --- a/Content.Server/Construction/Completions/SetAnchor.cs +++ b/Content.Server/Construction/Completions/SetAnchor.cs @@ -3,7 +3,6 @@ using System.Threading.Tasks; using Content.Shared.Construction; using JetBrains.Annotations; using Robust.Shared.GameObjects; -using Robust.Shared.Physics; using Robust.Shared.Serialization; namespace Content.Server.Construction.Completions @@ -20,9 +19,9 @@ namespace Content.Server.Construction.Completions public async Task PerformAction(IEntity entity, IEntity? user) { - if (!entity.TryGetComponent(out IPhysBody? physics)) return; + if (!entity.TryGetComponent(out IPhysicsComponent? physics)) return; - physics.BodyType = Value ? BodyType.Static : BodyType.Dynamic; + physics.Anchored = Value; } } } diff --git a/Content.Server/Construction/Conditions/EntityAnchored.cs b/Content.Server/Construction/Conditions/EntityAnchored.cs index b7cf287597..8dcb5bfc76 100644 --- a/Content.Server/Construction/Conditions/EntityAnchored.cs +++ b/Content.Server/Construction/Conditions/EntityAnchored.cs @@ -2,7 +2,6 @@ using Content.Shared.Construction; using JetBrains.Annotations; using Robust.Shared.GameObjects; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.Utility; @@ -20,21 +19,21 @@ namespace Content.Server.Construction.Conditions public async Task Condition(IEntity entity) { - if (!entity.TryGetComponent(out IPhysBody physics)) return false; + if (!entity.TryGetComponent(out IPhysicsComponent physics)) return false; - return (physics.BodyType == BodyType.Static && Anchored) || (physics.BodyType != BodyType.Static && !Anchored); + return physics.Anchored == Anchored; } public bool DoExamine(IEntity entity, FormattedMessage message, bool inDetailsRange) { - if (!entity.TryGetComponent(out IPhysBody physics)) return false; + if (!entity.TryGetComponent(out IPhysicsComponent physics)) return false; switch (Anchored) { - case true when physics.BodyType == BodyType.Static: + case true when !physics.Anchored: message.AddMarkup("First, anchor it.\n"); return true; - case false when physics.BodyType == BodyType.Static: + case false when physics.Anchored: message.AddMarkup("First, unanchor it.\n"); return true; } diff --git a/Content.Server/Explosions/ExplosionHelper.cs b/Content.Server/Explosions/ExplosionHelper.cs index b03beebb2a..759d3c1269 100644 --- a/Content.Server/Explosions/ExplosionHelper.cs +++ b/Content.Server/Explosions/ExplosionHelper.cs @@ -77,7 +77,6 @@ namespace Content.Server.Explosions var impassableEntities = new List>(); var nonImpassableEntities = new List>(); - // TODO: Given this seems to rely on physics it should just query directly like everything else. // The entities are paired with their distance to the epicenter // and splitted into two lists based on if they are Impassable or not @@ -93,7 +92,7 @@ namespace Content.Server.Explosions continue; } - if (!entity.TryGetComponent(out PhysicsComponent? body) || body.Fixtures.Count < 1) + if (!entity.TryGetComponent(out IPhysicsComponent? body) || body.PhysicsShapes.Count < 1) { continue; } diff --git a/Content.Server/GameObjects/Components/AnchorableComponent.cs b/Content.Server/GameObjects/Components/AnchorableComponent.cs index b01bc7cfb2..d6ed4b447e 100644 --- a/Content.Server/GameObjects/Components/AnchorableComponent.cs +++ b/Content.Server/GameObjects/Components/AnchorableComponent.cs @@ -7,7 +7,6 @@ using Content.Server.Utility; using Content.Shared.GameObjects.Components.Interactable; using Content.Shared.Interfaces.GameObjects.Components; using Robust.Shared.GameObjects; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -43,7 +42,7 @@ namespace Content.Server.GameObjects.Components /// true if it is valid, false otherwise private async Task Valid(IEntity user, IEntity? utilizing, [NotNullWhen(true)] bool force = false) { - if (!Owner.HasComponent()) + if (!Owner.HasComponent()) { return false; } @@ -75,8 +74,8 @@ namespace Content.Server.GameObjects.Components return false; } - var physics = Owner.GetComponent(); - physics.BodyType = BodyType.Static; + var physics = Owner.GetComponent(); + physics.Anchored = true; if (Owner.TryGetComponent(out PullableComponent? pullableComponent)) { @@ -106,8 +105,8 @@ namespace Content.Server.GameObjects.Components return false; } - var physics = Owner.GetComponent(); - physics.BodyType = BodyType.Dynamic; + var physics = Owner.GetComponent(); + physics.Anchored = false; return true; } @@ -121,12 +120,12 @@ namespace Content.Server.GameObjects.Components /// true if toggled, false otherwise private async Task TryToggleAnchor(IEntity user, IEntity? utilizing = null, bool force = false) { - if (!Owner.TryGetComponent(out IPhysBody? physics)) + if (!Owner.TryGetComponent(out IPhysicsComponent? physics)) { return false; } - return physics.BodyType == BodyType.Static ? + return physics.Anchored ? await TryUnAnchor(user, utilizing, force) : await TryAnchor(user, utilizing, force); } diff --git a/Content.Server/GameObjects/Components/Atmos/FlammableComponent.cs b/Content.Server/GameObjects/Components/Atmos/FlammableComponent.cs index c0ae761594..26777a5488 100644 --- a/Content.Server/GameObjects/Components/Atmos/FlammableComponent.cs +++ b/Content.Server/GameObjects/Components/Atmos/FlammableComponent.cs @@ -15,7 +15,6 @@ using Content.Shared.Interfaces.GameObjects.Components; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.Localization; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -135,19 +134,19 @@ namespace Content.Server.GameObjects.Components.Atmos } var entity = Owner.EntityManager.GetEntity(uid); - var physics = Owner.GetComponent(); - var otherPhysics = entity.GetComponent(); + var physics = Owner.GetComponent(); + var otherPhysics = entity.GetComponent(); - if (!physics.GetWorldAABB().Intersects(otherPhysics.GetWorldAABB())) + if (!physics.WorldAABB.Intersects(otherPhysics.WorldAABB)) { _collided.Remove(uid); } } } - public void CollideWith(IPhysBody ourBody, IPhysBody otherBody) + public void CollideWith(IEntity collidedWith) { - if (!otherBody.Entity.TryGetComponent(out FlammableComponent otherFlammable)) + if (!collidedWith.TryGetComponent(out FlammableComponent otherFlammable)) return; if (!FireSpread || !otherFlammable.FireSpread) diff --git a/Content.Server/GameObjects/Components/Atmos/GasCanisterComponent.cs b/Content.Server/GameObjects/Components/Atmos/GasCanisterComponent.cs index 5a2273b22c..9c1d0f329b 100644 --- a/Content.Server/GameObjects/Components/Atmos/GasCanisterComponent.cs +++ b/Content.Server/GameObjects/Components/Atmos/GasCanisterComponent.cs @@ -13,7 +13,6 @@ using Content.Shared.Interfaces.GameObjects.Components; using Content.Shared.Atmos; using Content.Shared.GameObjects.EntitySystems.ActionBlocker; using Robust.Server.GameObjects; -using Robust.Shared.Physics; namespace Content.Server.GameObjects.Components.Atmos { @@ -41,7 +40,7 @@ namespace Content.Server.GameObjects.Components.Atmos public GasMixture Air { get; set; } = default!; [ViewVariables] - public bool Anchored => !Owner.TryGetComponent(out var physics) || physics.BodyType == BodyType.Static; + public bool Anchored => !Owner.TryGetComponent(out var physics) || physics.Anchored; /// /// The floor connector port that the canister is attached to. @@ -78,7 +77,7 @@ namespace Content.Server.GameObjects.Components.Atmos public override void Initialize() { base.Initialize(); - if (Owner.TryGetComponent(out var physics)) + if (Owner.TryGetComponent(out var physics)) { AnchorUpdate(); } diff --git a/Content.Server/GameObjects/Components/Atmos/MovedByPressureComponent.cs b/Content.Server/GameObjects/Components/Atmos/MovedByPressureComponent.cs index cd06b21f5a..36a5bae151 100644 --- a/Content.Server/GameObjects/Components/Atmos/MovedByPressureComponent.cs +++ b/Content.Server/GameObjects/Components/Atmos/MovedByPressureComponent.cs @@ -1,14 +1,6 @@ #nullable enable -using System; using System.Diagnostics.CodeAnalysis; -using Content.Shared.Atmos; -using Content.Shared.GameObjects.Components.Mobs.State; -using Content.Shared.Physics; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Map; -using Robust.Shared.Maths; -using Robust.Shared.Random; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -17,16 +9,8 @@ namespace Content.Server.GameObjects.Components.Atmos [RegisterComponent] public class MovedByPressureComponent : Component { - [Dependency] private readonly IRobustRandom _robustRandom = default!; - public override string Name => "MovedByPressure"; - private const float MoveForcePushRatio = 1f; - private const float MoveForceForcePushRatio = 1f; - private const float ProbabilityOffset = 25f; - private const float ProbabilityBasePercent = 10f; - private const float ThrowForce = 100f; - [ViewVariables(VVAccess.ReadWrite)] public bool Enabled { get; set; } = true; [ViewVariables(VVAccess.ReadWrite)] @@ -43,77 +27,6 @@ namespace Content.Server.GameObjects.Components.Atmos serializer.DataField(this, x => PressureResistance, "pressureResistance", 1f); serializer.DataField(this, x => MoveResist, "moveResist", 100f); } - - public void ExperiencePressureDifference(int cycle, float pressureDifference, AtmosDirection direction, - float pressureResistanceProbDelta, EntityCoordinates throwTarget) - { - if (!Owner.TryGetComponent(out PhysicsComponent? physics)) - return; - - physics.WakeBody(); - // TODO ATMOS stuns? - - var transform = physics.Owner.Transform; - var maxForce = MathF.Sqrt(pressureDifference) * 2.25f; - var moveProb = 100f; - - if (PressureResistance > 0) - moveProb = MathF.Abs((pressureDifference / PressureResistance * ProbabilityBasePercent) - - ProbabilityOffset); - - if (moveProb > ProbabilityOffset && _robustRandom.Prob(MathF.Min(moveProb / 100f, 1f)) - && !float.IsPositiveInfinity(MoveResist) - && (!physics.Anchored - && (maxForce >= (MoveResist * MoveForcePushRatio))) - || (physics.Anchored && (maxForce >= (MoveResist * MoveForceForcePushRatio)))) - { - - if (physics.Owner.HasComponent()) - { - physics.BodyStatus = BodyStatus.InAir; - - foreach (var fixture in physics.Fixtures) - { - fixture.CollisionMask &= ~(int) CollisionGroup.VaultImpassable; - } - - Owner.SpawnTimer(2000, () => - { - if (Deleted || !Owner.TryGetComponent(out PhysicsComponent? physicsComponent)) return; - - // Uhh if you get race conditions good luck buddy. - if (physicsComponent.Owner.HasComponent()) - { - physicsComponent.BodyStatus = BodyStatus.OnGround; - } - - foreach (var fixture in physics.Fixtures) - { - fixture.CollisionMask |= (int) CollisionGroup.VaultImpassable; - } - }); - } - - if (maxForce > ThrowForce) - { - // Vera please fix ;-; - if (throwTarget != EntityCoordinates.Invalid) - { - var moveForce = maxForce * MathHelper.Clamp(moveProb, 0, 100) / 15f; - var pos = ((throwTarget.Position - transform.Coordinates.Position).Normalized + direction.ToDirection().ToVec()).Normalized; - physics.ApplyLinearImpulse(pos * moveForce); - } - - else - { - var moveForce = MathF.Min(maxForce * MathHelper.Clamp(moveProb, 0, 100) / 2500f, 20f); - physics.ApplyLinearImpulse(direction.ToDirection().ToVec() * moveForce); - } - - LastHighPressureMovementAirCycle = cycle; - } - } - } } public static class MovedByPressureExtensions diff --git a/Content.Server/GameObjects/Components/Chemistry/VaporComponent.cs b/Content.Server/GameObjects/Components/Chemistry/VaporComponent.cs index e1ee21c68d..040bf9eb92 100644 --- a/Content.Server/GameObjects/Components/Chemistry/VaporComponent.cs +++ b/Content.Server/GameObjects/Components/Chemistry/VaporComponent.cs @@ -7,7 +7,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -30,6 +29,8 @@ namespace Content.Server.GameObjects.Components.Chemistry private float _timer; private EntityCoordinates _target; private bool _running; + private Vector2 _direction; + private float _velocity; private float _aliveTime; public override void Initialize() @@ -39,16 +40,18 @@ namespace Content.Server.GameObjects.Components.Chemistry Owner.EnsureComponentWarn(out SolutionContainerComponent _); } - public void Start(Vector2 dir, float speed, EntityCoordinates target, float aliveTime) + public void Start(Vector2 dir, float velocity, EntityCoordinates target, float aliveTime) { _running = true; _target = target; + _direction = dir; + _velocity = velocity; _aliveTime = aliveTime; // Set Move - if (Owner.TryGetComponent(out PhysicsComponent physics)) + if (Owner.TryGetComponent(out IPhysicsComponent physics)) { - physics.BodyStatus = BodyStatus.InAir; - physics.ApplyLinearImpulse(dir * speed); + var controller = physics.EnsureController(); + controller.Move(_direction, _velocity); } } @@ -69,7 +72,7 @@ namespace Content.Server.GameObjects.Components.Chemistry _timer += frameTime; _reactTimer += frameTime; - if (_reactTimer >= ReactTime) + if (_reactTimer >= ReactTime && Owner.TryGetComponent(out IPhysicsComponent physics)) { _reactTimer = 0; var mapGrid = _mapManager.GetGrid(Owner.Transform.GridID); @@ -87,6 +90,12 @@ namespace Content.Server.GameObjects.Components.Chemistry if(!_reached && _target.TryDistance(Owner.EntityManager, Owner.Transform.Coordinates, out var distance) && distance <= 0.5f) { _reached = true; + + if (Owner.TryGetComponent(out IPhysicsComponent coll)) + { + var controller = coll.EnsureController(); + controller.Stop(); + } } if (contents.CurrentVolume == 0 || _timer > _aliveTime) @@ -118,17 +127,26 @@ namespace Content.Server.GameObjects.Components.Chemistry return true; } - void ICollideBehavior.CollideWith(IPhysBody ourBody, IPhysBody otherBody) + void ICollideBehavior.CollideWith(IEntity collidedWith) { if (!Owner.TryGetComponent(out SolutionContainerComponent contents)) return; - contents.Solution.DoEntityReaction(otherBody.Entity, ReactionMethod.Touch); + contents.Solution.DoEntityReaction(collidedWith, ReactionMethod.Touch); // Check for collision with a impassable object (e.g. wall) and stop - if ((otherBody.CollisionLayer & (int) CollisionGroup.Impassable) != 0 && otherBody.Hard) + if (collidedWith.TryGetComponent(out IPhysicsComponent physics)) { - Owner.Delete(); + if ((physics.CollisionLayer & (int) CollisionGroup.Impassable) != 0 && physics.Hard) + { + if (Owner.TryGetComponent(out IPhysicsComponent coll)) + { + var controller = coll.EnsureController(); + controller.Stop(); + } + + Owner.Delete(); + } } } } diff --git a/Content.Server/GameObjects/Components/Construction/ConstructionComponent.cs b/Content.Server/GameObjects/Components/Construction/ConstructionComponent.cs index caa538f242..d0f562f4b8 100644 --- a/Content.Server/GameObjects/Components/Construction/ConstructionComponent.cs +++ b/Content.Server/GameObjects/Components/Construction/ConstructionComponent.cs @@ -16,7 +16,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Log; -using Robust.Shared.Physics; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Utility; @@ -437,10 +436,10 @@ namespace Content.Server.GameObjects.Components.Construction } } - if (Owner.TryGetComponent(out IPhysBody? physics) && - entity.TryGetComponent(out IPhysBody? otherPhysics)) + if (Owner.TryGetComponent(out IPhysicsComponent? physics) && + entity.TryGetComponent(out IPhysicsComponent? otherPhysics)) { - otherPhysics.BodyType = physics.BodyType; + otherPhysics.Anchored = physics.Anchored; } Owner.Delete(); diff --git a/Content.Server/GameObjects/Components/Conveyor/ConveyorComponent.cs b/Content.Server/GameObjects/Components/Conveyor/ConveyorComponent.cs index 3482c7b849..363e935724 100644 --- a/Content.Server/GameObjects/Components/Conveyor/ConveyorComponent.cs +++ b/Content.Server/GameObjects/Components/Conveyor/ConveyorComponent.cs @@ -4,13 +4,11 @@ using Content.Server.GameObjects.Components.MachineLinking; using Content.Server.GameObjects.Components.Power.ApcNetComponents; using Content.Shared.GameObjects.Components.Conveyor; using Content.Shared.GameObjects.Components.MachineLinking; -using Content.Shared.GameObjects.Components.Movement; using Content.Shared.Physics; using Robust.Server.GameObjects; using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -29,8 +27,6 @@ namespace Content.Server.GameObjects.Components.Conveyor [ViewVariables(VVAccess.ReadWrite)] private Angle _angle; - public float Speed => _speed; - /// /// The amount of units to move the entity by per second. /// @@ -90,7 +86,7 @@ namespace Content.Server.GameObjects.Components.Conveyor /// /// The angle when taking into account if the conveyor is reversed /// - public Angle GetAngle() + private Angle GetAngle() { var adjustment = _state == ConveyorState.Reversed ? MathHelper.Pi : 0; var radians = MathHelper.DegreesToRadians(_angle); @@ -98,7 +94,7 @@ namespace Content.Server.GameObjects.Components.Conveyor return new Angle(Owner.Transform.LocalRotation.Theta + radians + adjustment); } - public bool CanRun() + private bool CanRun() { if (State == ConveyorState.Off) { @@ -119,16 +115,15 @@ namespace Content.Server.GameObjects.Components.Conveyor return true; } - public bool CanMove(IEntity entity) + private bool CanMove(IEntity entity) { - // TODO We should only check status InAir or Static or MapGrid or /mayber/ container if (entity == Owner) { return false; } - if (!entity.TryGetComponent(out IPhysBody? physics) || - physics.BodyType == BodyType.Static) + if (!entity.TryGetComponent(out IPhysicsComponent? physics) || + physics.Anchored) { return false; } @@ -151,6 +146,31 @@ namespace Content.Server.GameObjects.Components.Conveyor return true; } + public void Update(float frameTime) + { + if (!CanRun()) + { + return; + } + + var intersecting = Owner.EntityManager.GetEntitiesIntersecting(Owner, true); + var direction = GetAngle().ToVec(); + + foreach (var entity in intersecting) + { + if (!CanMove(entity)) + { + continue; + } + + if (entity.TryGetComponent(out IPhysicsComponent? physics)) + { + var controller = physics.EnsureController(); + controller.Move(direction, _speed, entity.Transform.WorldPosition - Owner.Transform.WorldPosition); + } + } + } + public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); diff --git a/Content.Server/GameObjects/Components/Damage/DamageOnHighSpeedImpactComponent.cs b/Content.Server/GameObjects/Components/Damage/DamageOnHighSpeedImpactComponent.cs index 682bbcdac4..5d98dd7bc0 100644 --- a/Content.Server/GameObjects/Components/Damage/DamageOnHighSpeedImpactComponent.cs +++ b/Content.Server/GameObjects/Components/Damage/DamageOnHighSpeedImpactComponent.cs @@ -6,7 +6,6 @@ using Content.Shared.GameObjects.Components.Damage; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.IoC; -using Robust.Shared.Physics; using Robust.Shared.Random; using Robust.Shared.Serialization; using Robust.Shared.Timing; @@ -47,16 +46,16 @@ namespace Content.Server.GameObjects.Components.Damage serializer.DataField(this, x => x.StunMinimumDamage, "stunMinimumDamage", 10); } - public void CollideWith(IPhysBody ourBody, IPhysBody otherBody) + public void CollideWith(IEntity collidedWith) { - if (!Owner.TryGetComponent(out IDamageableComponent damageable)) return; + if (!Owner.TryGetComponent(out IPhysicsComponent physics) || !Owner.TryGetComponent(out IDamageableComponent damageable)) return; - var speed = ourBody.LinearVelocity.Length; + var speed = physics.LinearVelocity.Length; if (speed < MinimumSpeed) return; if(!string.IsNullOrEmpty(SoundHit)) - EntitySystem.Get().PlayFromEntity(SoundHit, otherBody.Entity, AudioHelpers.WithVariation(0.125f).WithVolume(-0.125f)); + EntitySystem.Get().PlayFromEntity(SoundHit, collidedWith, AudioHelpers.WithVariation(0.125f).WithVolume(-0.125f)); if ((_gameTiming.CurTime - _lastHit).TotalSeconds < DamageCooldown) return; @@ -68,7 +67,7 @@ namespace Content.Server.GameObjects.Components.Damage if (Owner.TryGetComponent(out StunnableComponent stun) && _robustRandom.Prob(StunChance)) stun.Stun(StunSeconds); - damageable.ChangeDamage(Damage, damage, false, otherBody.Entity); + damageable.ChangeDamage(Damage, damage, false, collidedWith); } } } diff --git a/Content.Server/GameObjects/Components/Disposal/DisposalHolderComponent.cs b/Content.Server/GameObjects/Components/Disposal/DisposalHolderComponent.cs index b97bf89f9a..e71444b706 100644 --- a/Content.Server/GameObjects/Components/Disposal/DisposalHolderComponent.cs +++ b/Content.Server/GameObjects/Components/Disposal/DisposalHolderComponent.cs @@ -10,7 +10,6 @@ using Robust.Server.GameObjects; using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -81,7 +80,7 @@ namespace Content.Server.GameObjects.Components.Disposal return false; } - if (!entity.TryGetComponent(out IPhysBody? physics) || + if (!entity.TryGetComponent(out IPhysicsComponent? physics) || !physics.CanCollide) { return false; @@ -98,7 +97,7 @@ namespace Content.Server.GameObjects.Components.Disposal return false; } - if (entity.TryGetComponent(out IPhysBody? physics)) + if (entity.TryGetComponent(out IPhysicsComponent? physics)) { physics.CanCollide = false; } @@ -130,7 +129,7 @@ namespace Content.Server.GameObjects.Components.Disposal foreach (var entity in _contents.ContainedEntities.ToArray()) { - if (entity.TryGetComponent(out IPhysBody? physics)) + if (entity.TryGetComponent(out IPhysicsComponent? physics)) { physics.CanCollide = true; } diff --git a/Content.Server/GameObjects/Components/Disposal/DisposalMailingUnitComponent.cs b/Content.Server/GameObjects/Components/Disposal/DisposalMailingUnitComponent.cs index 9d67c6b238..d9ee7f7177 100644 --- a/Content.Server/GameObjects/Components/Disposal/DisposalMailingUnitComponent.cs +++ b/Content.Server/GameObjects/Components/Disposal/DisposalMailingUnitComponent.cs @@ -26,7 +26,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Log; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.Timing; using Robust.Shared.ViewVariables; @@ -143,7 +142,7 @@ namespace Content.Server.GameObjects.Components.Disposal return false; } - if (!entity.TryGetComponent(out IPhysBody? physics) || + if (!entity.TryGetComponent(out IPhysicsComponent? physics) || !physics.CanCollide) { return false; diff --git a/Content.Server/GameObjects/Components/Disposal/DisposalRouterComponent.cs b/Content.Server/GameObjects/Components/Disposal/DisposalRouterComponent.cs index 3b5ddd0470..d4d9f1519e 100644 --- a/Content.Server/GameObjects/Components/Disposal/DisposalRouterComponent.cs +++ b/Content.Server/GameObjects/Components/Disposal/DisposalRouterComponent.cs @@ -16,7 +16,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.ViewVariables; using static Content.Shared.GameObjects.Components.Disposal.SharedDisposalRouterComponent; @@ -34,8 +33,8 @@ namespace Content.Server.GameObjects.Components.Disposal [ViewVariables] public bool Anchored => - !Owner.TryGetComponent(out IPhysBody? physics) || - physics.BodyType == BodyType.Static; + !Owner.TryGetComponent(out IPhysicsComponent? physics) || + physics.Anchored; [ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(DisposalRouterUiKey.Key); diff --git a/Content.Server/GameObjects/Components/Disposal/DisposalUnitComponent.cs b/Content.Server/GameObjects/Components/Disposal/DisposalUnitComponent.cs index 20a7432038..769a8ad613 100644 --- a/Content.Server/GameObjects/Components/Disposal/DisposalUnitComponent.cs +++ b/Content.Server/GameObjects/Components/Disposal/DisposalUnitComponent.cs @@ -28,7 +28,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Log; -using Robust.Shared.Physics; using Robust.Shared.Random; using Robust.Shared.Serialization; using Robust.Shared.Timing; @@ -140,7 +139,7 @@ namespace Content.Server.GameObjects.Components.Disposal if (!base.CanInsert(entity)) return false; - if (!entity.TryGetComponent(out IPhysBody? physics) || + if (!entity.TryGetComponent(out IPhysicsComponent? physics) || !physics.CanCollide) { if (entity.TryGetComponent(out IMobStateComponent? state) && state.IsDead()) diff --git a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs index d3434bf33e..b75158b618 100644 --- a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs +++ b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs @@ -1,4 +1,4 @@ -#nullable enable +#nullable enable using System; using System.Linq; using System.Threading; @@ -25,7 +25,6 @@ using Robust.Shared.Log; using Robust.Shared.Maths; using Robust.Shared.Physics; using Robust.Shared.Players; -using Robust.Shared.Physics.Broadphase; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; using Timer = Robust.Shared.Timing.Timer; @@ -39,7 +38,7 @@ namespace Content.Server.GameObjects.Components.Doors { [ComponentDependency] private readonly IDoorCheck? _doorCheck = null; - + public override DoorState State { get => base.State; @@ -203,7 +202,7 @@ namespace Content.Server.GameObjects.Components.Doors } } - void ICollideBehavior.CollideWith(IPhysBody ourBody, IPhysBody otherBody) + void ICollideBehavior.CollideWith(IEntity entity) { if (State != DoorState.Closed) { @@ -217,9 +216,9 @@ namespace Content.Server.GameObjects.Components.Doors // Disabled because it makes it suck hard to walk through double doors. - if (otherBody.Entity.HasComponent()) + if (entity.HasComponent()) { - if (!otherBody.Entity.TryGetComponent(out var mover)) return; + if (!entity.TryGetComponent(out var mover)) return; /* // TODO: temporary hack to fix the physics system raising collision events akwardly. @@ -232,7 +231,7 @@ namespace Content.Server.GameObjects.Components.Doors TryOpen(entity); */ - TryOpen(otherBody.Entity); + TryOpen(entity); } } @@ -309,7 +308,7 @@ namespace Content.Server.GameObjects.Components.Doors { return _doorCheck.OpenCheck(); } - + return true; } @@ -413,14 +412,18 @@ namespace Content.Server.GameObjects.Components.Doors { var safety = SafetyCheck(); - if (safety && Owner.TryGetComponent(out PhysicsComponent? physicsComponent)) + if (safety && PhysicsComponent != null) { - var broadPhaseSystem = EntitySystem.Get(); + var physics = IoCManager.Resolve(); - // Use this version so we can ignore the CanCollide being false - foreach(var e in broadPhaseSystem.GetCollidingEntities(physicsComponent.Entity.Transform.MapID, physicsComponent.GetWorldAABB())) + foreach(var e in physics.GetCollidingEntities(Owner.Transform.MapID, PhysicsComponent.WorldAABB)) { - if ((physicsComponent.CollisionMask & e.CollisionLayer) != 0 && broadPhaseSystem.IntersectionPercent(physicsComponent, e) > 0.01f) return true; + if (e.CanCollide && + ((PhysicsComponent.CollisionMask & e.CollisionLayer) != 0x0 || + (PhysicsComponent.CollisionLayer & e.CollisionMask) != 0x0)) + { + return true; + } } } return false; @@ -449,7 +452,7 @@ namespace Content.Server.GameObjects.Components.Doors OnPartialClose(); await Timer.Delay(CloseTimeTwo, _stateChangeCancelTokenSource.Token); - + if (Occludes && Owner.TryGetComponent(out OccluderComponent? occluder)) { occluder.Enabled = true; @@ -492,25 +495,26 @@ namespace Content.Server.GameObjects.Components.Doors return false; } - var doorAABB = PhysicsComponent.GetWorldAABB(); + var doorAABB = PhysicsComponent.WorldAABB; var hitsomebody = false; // Crush foreach (var e in collidingentities) { - if (!e.Entity.TryGetComponent(out StunnableComponent? stun) - || !e.Entity.TryGetComponent(out IDamageableComponent? damage)) + if (!e.TryGetComponent(out StunnableComponent? stun) + || !e.TryGetComponent(out IDamageableComponent? damage) + || !e.TryGetComponent(out IPhysicsComponent? otherBody)) { continue; } - var percentage = e.GetWorldAABB().IntersectPercentage(doorAABB); + var percentage = otherBody.WorldAABB.IntersectPercentage(doorAABB); if (percentage < 0.1f) continue; hitsomebody = true; - CurrentlyCrushing.Add(e.Entity.Uid); + CurrentlyCrushing.Add(e.Uid); damage.ChangeDamage(DamageType.Blunt, DoorCrushDamage, false, Owner); stun.Paralyze(DoorStunTime); diff --git a/Content.Server/GameObjects/Components/Explosion/ClusterFlashComponent.cs b/Content.Server/GameObjects/Components/Explosion/ClusterFlashComponent.cs index d0d9d4dfdf..5b20361569 100644 --- a/Content.Server/GameObjects/Components/Explosion/ClusterFlashComponent.cs +++ b/Content.Server/GameObjects/Components/Explosion/ClusterFlashComponent.cs @@ -1,21 +1,22 @@ #nullable enable +using Content.Shared.Interfaces.GameObjects.Components; +using Content.Server.GameObjects.Components.Explosion; +using Robust.Shared.GameObjects; +using System.Threading.Tasks; +using Robust.Shared.Serialization; using System; using System.Diagnostics.CodeAnalysis; -using System.Threading.Tasks; -using Content.Server.GameObjects.Components.Items; using Content.Server.GameObjects.Components.Trigger.TimerTrigger; -using Content.Shared.GameObjects.Components.Explosion; -using Content.Shared.Interfaces.GameObjects.Components; +using Content.Server.Throw; using Robust.Server.GameObjects; -using Robust.Shared.GameObjects; +using Content.Shared.GameObjects.Components.Explosion; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Random; -using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; -namespace Content.Server.GameObjects.Components.Explosion +namespace Content.Server.GameObjects.Components.Explosives { [RegisterComponent] public sealed class ClusterFlashComponent : Component, IInteractUsing, IUse @@ -116,13 +117,10 @@ namespace Content.Server.GameObjects.Components.Explosion var angleMin = segmentAngle * thrownCount; var angleMax = segmentAngle * (thrownCount + 1); var angle = Angle.FromDegrees(random.Next(angleMin, angleMax)); - // var distance = random.NextFloat() * _throwDistance; + var distance = (float)random.NextFloat() * _throwDistance; + var target = new EntityCoordinates(Owner.Uid, angle.ToVec().Normalized * distance); - delay += random.Next(550, 900); - thrownCount++; - - // TODO: Suss out throw strength - grenade.TryThrow(angle.ToVec().Normalized * 50); + grenade.Throw(0.5f, target, grenade.Transform.Coordinates); grenade.SpawnTimer(delay, () => { @@ -134,6 +132,9 @@ namespace Content.Server.GameObjects.Components.Explosion useTimer.Trigger(eventArgs.User); } }); + + delay += random.Next(550, 900); + thrownCount++; } Owner.Delete(); @@ -148,7 +149,7 @@ namespace Content.Server.GameObjects.Components.Explosion if (_unspawnedCount > 0) { _unspawnedCount--; - grenade = Owner.EntityManager.SpawnEntity(_fillPrototype, Owner.Transform.MapPosition); + grenade = Owner.EntityManager.SpawnEntity(_fillPrototype, Owner.Transform.Coordinates); return true; } diff --git a/Content.Server/GameObjects/Components/Fluids/PuddleComponent.cs b/Content.Server/GameObjects/Components/Fluids/PuddleComponent.cs index 80ba9e6899..90104dde43 100644 --- a/Content.Server/GameObjects/Components/Fluids/PuddleComponent.cs +++ b/Content.Server/GameObjects/Components/Fluids/PuddleComponent.cs @@ -15,7 +15,6 @@ using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Map; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Random; using Robust.Shared.Serialization; using Robust.Shared.Utility; @@ -373,7 +372,7 @@ namespace Content.Server.GameObjects.Components.Fluids foreach (var entity in _snapGrid.GetInDir(direction)) { - if (entity.TryGetComponent(out IPhysBody physics) && + if (entity.TryGetComponent(out IPhysicsComponent physics) && (physics.CollisionLayer & (int) CollisionGroup.Impassable) != 0) { puddle = default; diff --git a/Content.Server/GameObjects/Components/GUI/HandsComponent.cs b/Content.Server/GameObjects/Components/GUI/HandsComponent.cs index 249f1c8057..0902075b57 100644 --- a/Content.Server/GameObjects/Components/GUI/HandsComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/HandsComponent.cs @@ -27,9 +27,6 @@ using Robust.Shared.Maths; using Robust.Shared.Network; using Robust.Shared.Players; using Robust.Shared.ViewVariables; -using Robust.Shared.Map; -using Robust.Shared.Network; -using Robust.Shared.Physics; namespace Content.Server.GameObjects.Components.GUI { @@ -720,13 +717,13 @@ namespace Content.Server.GameObjects.Components.GUI Dirty(); - if (!message.Entity.TryGetComponent(out IPhysBody? physics)) + if (!message.Entity.TryGetComponent(out IPhysicsComponent? physics)) { return; } // set velocity to zero - physics.LinearVelocity = Vector2.Zero; + physics.Stop(); return; } } diff --git a/Content.Server/GameObjects/Components/Items/Storage/EntityStorageComponent.cs b/Content.Server/GameObjects/Components/Items/Storage/EntityStorageComponent.cs index 070517efad..4ea38ef3da 100644 --- a/Content.Server/GameObjects/Components/Items/Storage/EntityStorageComponent.cs +++ b/Content.Server/GameObjects/Components/Items/Storage/EntityStorageComponent.cs @@ -17,7 +17,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.Timing; using Robust.Shared.ViewVariables; @@ -227,7 +226,7 @@ namespace Content.Server.GameObjects.Components.Items.Storage private void ModifyComponents() { - if (!_isCollidableWhenOpen && Owner.TryGetComponent(out var physics)) + if (!_isCollidableWhenOpen && Owner.TryGetComponent(out var physics)) { if (Open) { @@ -253,10 +252,10 @@ namespace Content.Server.GameObjects.Components.Items.Storage protected virtual bool AddToContents(IEntity entity) { if (entity == Owner) return false; - if (entity.TryGetComponent(out IPhysBody? entityPhysicsComponent)) + if (entity.TryGetComponent(out IPhysicsComponent? entityPhysicsComponent)) { - if(MaxSize < entityPhysicsComponent.GetWorldAABB().Size.X - || MaxSize < entityPhysicsComponent.GetWorldAABB().Size.Y) + if(MaxSize < entityPhysicsComponent.WorldAABB.Size.X + || MaxSize < entityPhysicsComponent.WorldAABB.Size.Y) { return false; } @@ -286,7 +285,7 @@ namespace Content.Server.GameObjects.Components.Items.Storage if(Contents.Remove(contained)) { contained.Transform.WorldPosition = ContentsDumpPosition(); - if (contained.TryGetComponent(out var physics)) + if (contained.TryGetComponent(out var physics)) { physics.CanCollide = true; } diff --git a/Content.Server/GameObjects/Components/Items/Storage/ItemComponent.cs b/Content.Server/GameObjects/Components/Items/Storage/ItemComponent.cs index 603410cb48..da37b1240b 100644 --- a/Content.Server/GameObjects/Components/Items/Storage/ItemComponent.cs +++ b/Content.Server/GameObjects/Components/Items/Storage/ItemComponent.cs @@ -1,5 +1,6 @@ using Content.Server.GameObjects.Components.GUI; using Content.Server.Interfaces.GameObjects.Components.Items; +using Content.Server.Throw; using Content.Shared.GameObjects; using Content.Shared.GameObjects.Components.Items; using Content.Shared.GameObjects.Components.Storage; @@ -13,7 +14,6 @@ using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.Localization; using Robust.Shared.Players; -using Robust.Shared.Physics; using Robust.Shared.Serialization; namespace Content.Server.GameObjects.Components.Items.Storage @@ -87,8 +87,8 @@ namespace Content.Server.GameObjects.Components.Items.Storage return false; } - if (Owner.TryGetComponent(out IPhysBody physics) && - physics.BodyType == BodyType.Static) + if (Owner.TryGetComponent(out IPhysicsComponent physics) && + physics.Anchored) { return false; } @@ -141,22 +141,22 @@ namespace Content.Server.GameObjects.Components.Items.Storage var targetLocation = eventArgs.Target.Transform.Coordinates; var dirVec = (targetLocation.ToMapPos(Owner.EntityManager) - sourceLocation.ToMapPos(Owner.EntityManager)).Normalized; - float throwForce; + var throwForce = 1.0f; switch (eventArgs.Severity) { case ExplosionSeverity.Destruction: - throwForce = 30.0f; + throwForce = 3.0f; break; case ExplosionSeverity.Heavy: - throwForce = 20.0f; + throwForce = 2.0f; break; - default: - throwForce = 10.0f; + case ExplosionSeverity.Light: + throwForce = 1.0f; break; } - Owner.TryThrow(dirVec * throwForce); + Owner.Throw(throwForce, targetLocation, sourceLocation, true); } } } diff --git a/Content.Server/GameObjects/Components/Items/ThrowHelper.cs b/Content.Server/GameObjects/Components/Items/ThrowHelper.cs deleted file mode 100644 index d3751529af..0000000000 --- a/Content.Server/GameObjects/Components/Items/ThrowHelper.cs +++ /dev/null @@ -1,49 +0,0 @@ -#nullable enable -using Content.Server.GameObjects.Components.Items.Storage; -using Content.Server.GameObjects.EntitySystems.Click; -using Content.Shared.GameObjects.Components.Mobs.State; -using Robust.Shared.GameObjects; -using Robust.Shared.Log; -using Robust.Shared.Maths; -using Robust.Shared.Physics; - -namespace Content.Server.GameObjects.Components.Items -{ - internal static class ThrowHelper - { - /// - /// Tries to throw the entity if it has a physics component, otherwise does nothing. - /// - /// - /// Will use the vector's magnitude as the strength of the impulse - internal static void TryThrow(this IEntity entity, Vector2 direction, IEntity? user = null) - { - if (direction == Vector2.Zero || !entity.TryGetComponent(out PhysicsComponent? physicsComponent)) - { - return; - } - - if (physicsComponent.BodyType == BodyType.Static) - { - Logger.Warning("Tried to throw entity {entity} but can't throw static bodies!"); - return; - } - - if (entity.HasComponent()) - { - Logger.Warning("Throwing not supported for mobs!"); - return; - } - - if (entity.HasComponent()) - { - entity.EnsureComponent().Thrower = user; - - if (user != null) - EntitySystem.Get().ThrownInteraction(user, entity); - } - - physicsComponent.ApplyLinearImpulse(direction); - } - } -} diff --git a/Content.Server/GameObjects/Components/Items/ThrownItemComponent.cs b/Content.Server/GameObjects/Components/Items/ThrownItemComponent.cs deleted file mode 100644 index d0b78f25c4..0000000000 --- a/Content.Server/GameObjects/Components/Items/ThrownItemComponent.cs +++ /dev/null @@ -1,33 +0,0 @@ -#nullable enable -using Content.Server.GameObjects.EntitySystems.Click; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Physics; - -namespace Content.Server.GameObjects.Components.Items -{ - [RegisterComponent] - public class ThrownItemComponent : Component, ICollideBehavior - { - public override string Name => "ThrownItem"; - - public IEntity? Thrower { get; set; } - - public override void HandleMessage(ComponentMessage message, IComponent? component) - { - base.HandleMessage(message, component); - switch (message) - { - case PhysicsSleepCompMessage: - EntitySystem.Get().LandInteraction(Thrower, Owner, Owner.Transform.Coordinates); - IoCManager.Resolve().RemoveComponent(Owner.Uid, this); - break; - } - } - - public void CollideWith(IPhysBody ourBody, IPhysBody otherBody) - { - EntitySystem.Get().ThrowCollideInteraction(Thrower, ourBody, otherBody); - } - } -} diff --git a/Content.Server/GameObjects/Components/Mobs/State/DeadMobState.cs b/Content.Server/GameObjects/Components/Mobs/State/DeadMobState.cs index 723f861982..27e4dee466 100644 --- a/Content.Server/GameObjects/Components/Mobs/State/DeadMobState.cs +++ b/Content.Server/GameObjects/Components/Mobs/State/DeadMobState.cs @@ -4,7 +4,6 @@ using Content.Shared.GameObjects.Components.Mobs; using Content.Shared.GameObjects.Components.Mobs.State; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; -using Robust.Shared.Physics; namespace Content.Server.GameObjects.Components.Mobs.State { @@ -31,7 +30,7 @@ namespace Content.Server.GameObjects.Components.Mobs.State EntitySystem.Get().Down(entity); - if (entity.TryGetComponent(out IPhysBody physics)) + if (entity.TryGetComponent(out IPhysicsComponent physics)) { physics.CanCollide = false; } @@ -41,7 +40,7 @@ namespace Content.Server.GameObjects.Components.Mobs.State { base.ExitState(entity); - if (entity.TryGetComponent(out IPhysBody physics)) + if (entity.TryGetComponent(out IPhysicsComponent physics)) { physics.CanCollide = true; } diff --git a/Content.Server/GameObjects/Components/Movement/AiControllerComponent.cs b/Content.Server/GameObjects/Components/Movement/AiControllerComponent.cs index 20fc06f32d..e846046e46 100644 --- a/Content.Server/GameObjects/Components/Movement/AiControllerComponent.cs +++ b/Content.Server/GameObjects/Components/Movement/AiControllerComponent.cs @@ -14,9 +14,8 @@ using Robust.Shared.ViewVariables; namespace Content.Server.GameObjects.Components.Movement { - [RegisterComponent] - [ComponentReference(typeof(IMobMoverComponent))] - public class AiControllerComponent : Component, IMobMoverComponent, IMoverComponent + [RegisterComponent, ComponentReference(typeof(IMoverComponent))] + public class AiControllerComponent : Component, IMoverComponent { private float _visionRadius; @@ -108,7 +107,8 @@ namespace Content.Server.GameObjects.Components.Movement /// [ViewVariables] - public float GrabRange { get; set; } = 0.2f; + public float GrabRange => 0.2f; + /// /// Is the entity Sprinting (running)? diff --git a/Content.Server/GameObjects/Components/Movement/ClimbableComponent.cs b/Content.Server/GameObjects/Components/Movement/ClimbableComponent.cs index e13096dda4..bc85f07eb5 100644 --- a/Content.Server/GameObjects/Components/Movement/ClimbableComponent.cs +++ b/Content.Server/GameObjects/Components/Movement/ClimbableComponent.cs @@ -13,7 +13,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.Localization; using Robust.Shared.Log; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -165,11 +164,9 @@ namespace Content.Server.GameObjects.Components.Movement var result = await EntitySystem.Get().DoAfter(doAfterEventArgs); - if (result != DoAfterStatus.Cancelled && entityToMove.TryGetComponent(out PhysicsComponent body) && body.Fixtures.Count >= 1) + if (result != DoAfterStatus.Cancelled && entityToMove.TryGetComponent(out IPhysicsComponent body) && body.PhysicsShapes.Count >= 1) { - var entityPos = entityToMove.Transform.WorldPosition; - - var direction = (Owner.Transform.WorldPosition - entityPos).Normalized; + var direction = (Owner.Transform.WorldPosition - entityToMove.Transform.WorldPosition).Normalized; var endPoint = Owner.Transform.WorldPosition; var climbMode = entityToMove.GetComponent(); @@ -177,14 +174,14 @@ namespace Content.Server.GameObjects.Components.Movement if (MathF.Abs(direction.X) < 0.6f) // user climbed mostly vertically so lets make it a clean straight line { - endPoint = new Vector2(entityPos.X, endPoint.Y); + endPoint = new Vector2(entityToMove.Transform.WorldPosition.X, endPoint.Y); } else if (MathF.Abs(direction.Y) < 0.6f) // user climbed mostly horizontally so lets make it a clean straight line { - endPoint = new Vector2(endPoint.X, entityPos.Y); + endPoint = new Vector2(endPoint.X, entityToMove.Transform.WorldPosition.Y); } - climbMode.TryMoveTo(entityPos, endPoint); + climbMode.TryMoveTo(entityToMove.Transform.WorldPosition, endPoint); // 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 @@ -212,12 +209,9 @@ namespace Content.Server.GameObjects.Components.Movement var result = await EntitySystem.Get().DoAfter(doAfterEventArgs); - if (result != DoAfterStatus.Cancelled && user.TryGetComponent(out PhysicsComponent body) && body.Fixtures.Count >= 1) + if (result != DoAfterStatus.Cancelled && user.TryGetComponent(out IPhysicsComponent body) && body.PhysicsShapes.Count >= 1) { - // TODO: Remove the copy-paste code - var userPos = user.Transform.WorldPosition; - - var direction = (Owner.Transform.WorldPosition - userPos).Normalized; + var direction = (Owner.Transform.WorldPosition - user.Transform.WorldPosition).Normalized; var endPoint = Owner.Transform.WorldPosition; var climbMode = user.GetComponent(); @@ -232,7 +226,7 @@ namespace Content.Server.GameObjects.Components.Movement endPoint = new Vector2(endPoint.X, user.Transform.WorldPosition.Y); } - climbMode.TryMoveTo(userPos, endPoint); + climbMode.TryMoveTo(user.Transform.WorldPosition, endPoint); var othersMessage = Loc.GetString("{0:theName} jumps onto {1:theName}!", user, Owner); user.PopupMessageOtherClients(othersMessage); diff --git a/Content.Server/GameObjects/Components/Movement/ClimbingComponent.cs b/Content.Server/GameObjects/Components/Movement/ClimbingComponent.cs index b7b0e5377b..c67aabec71 100644 --- a/Content.Server/GameObjects/Components/Movement/ClimbingComponent.cs +++ b/Content.Server/GameObjects/Components/Movement/ClimbingComponent.cs @@ -1,13 +1,10 @@ #nullable enable -using System; -using Content.Server.GameObjects.EntitySystems; using Content.Shared.GameObjects.Components.Buckle; using Content.Shared.GameObjects.Components.Movement; +using Content.Shared.Physics; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; using Robust.Shared.Maths; using Robust.Shared.Players; -using Robust.Shared.Timing; namespace Content.Server.GameObjects.Components.Movement { @@ -15,41 +12,23 @@ namespace Content.Server.GameObjects.Components.Movement [ComponentReference(typeof(SharedClimbingComponent))] public class ClimbingComponent : SharedClimbingComponent { - [Dependency] private readonly IGameTiming _gameTiming = default!; + private bool _isClimbing; + private ClimbController? _climbController; public override bool IsClimbing { - get => base.IsClimbing; + get => _isClimbing; set { if (_isClimbing == value) return; - base.IsClimbing = value; - - if (value) + if (!value) { - StartClimbTime = IoCManager.Resolve().CurTime; - EntitySystem.Get().AddActiveClimber(this); - OwnerIsTransitioning = true; - } - else - { - EntitySystem.Get().RemoveActiveClimber(this); - OwnerIsTransitioning = false; + Body?.TryRemoveController(); } - Dirty(); - } - } - - protected override bool OwnerIsTransitioning - { - get => base.OwnerIsTransitioning; - set - { - if (value == base.OwnerIsTransitioning) return; - base.OwnerIsTransitioning = value; + _isClimbing = value; Dirty(); } } @@ -72,36 +51,38 @@ namespace Content.Server.GameObjects.Components.Movement /// public void TryMoveTo(Vector2 from, Vector2 to) { - if (Body == null) return; + if (Body == null) + return; - var velocity = (to - from).Length; - - if (velocity <= 0.0f) return; - - Body.ApplyLinearImpulse((to - from).Normalized * velocity * 400); - OwnerIsTransitioning = true; - - Owner.SpawnTimer((int) (BufferTime * 1000), () => - { - if (Deleted) return; - OwnerIsTransitioning = false; - }); + _climbController = Body.EnsureController(); + _climbController.TryMoveTo(from, to); } public void Update() { - if (!IsClimbing || _gameTiming.CurTime < TimeSpan.FromSeconds(BufferTime) + StartClimbTime) - { + if (!IsClimbing || Body == null) return; + + if (_climbController != null && (_climbController.IsBlocked || !_climbController.IsActive)) + { + if (Body.TryRemoveController()) + { + _climbController = null; + } } - if (!IsOnClimbableThisFrame && IsClimbing) + if (IsClimbing) + Body.WakeBody(); + + if (!IsOnClimbableThisFrame && IsClimbing && _climbController == null) IsClimbing = false; + + IsOnClimbableThisFrame = false; } public override ComponentState GetComponentState(ICommonSession player) { - return new ClimbModeComponentState(_isClimbing, OwnerIsTransitioning); + return new ClimbModeComponentState(_isClimbing); } } } diff --git a/Content.Server/GameObjects/Components/Movement/PlayerInputMoverComponent.cs b/Content.Server/GameObjects/Components/Movement/PlayerInputMoverComponent.cs new file mode 100644 index 0000000000..b5637c5eb2 --- /dev/null +++ b/Content.Server/GameObjects/Components/Movement/PlayerInputMoverComponent.cs @@ -0,0 +1,19 @@ +#nullable enable +using Content.Shared.GameObjects.Components.Movement; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; + +namespace Content.Server.GameObjects.Components.Movement +{ + /// + /// Moves the entity based on input from a KeyBindingInputComponent. + /// + [RegisterComponent] + [ComponentReference(typeof(IMoverComponent))] + public class PlayerInputMoverComponent : SharedPlayerInputMoverComponent + { + public override EntityCoordinates LastPosition { get; set; } + + public override float StepSoundDistance { get; set; } + } +} diff --git a/Content.Server/GameObjects/Components/Movement/ShuttleControllerComponent.cs b/Content.Server/GameObjects/Components/Movement/ShuttleControllerComponent.cs index ac65dc456e..5cdadde4cd 100644 --- a/Content.Server/GameObjects/Components/Movement/ShuttleControllerComponent.cs +++ b/Content.Server/GameObjects/Components/Movement/ShuttleControllerComponent.cs @@ -10,8 +10,6 @@ using Robust.Shared.IoC; using Robust.Shared.Log; using Robust.Shared.Map; using Robust.Shared.Maths; -using Robust.Shared.Physics; -using Robust.Shared.Physics.Dynamics; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -21,6 +19,8 @@ namespace Content.Server.GameObjects.Components.Movement [ComponentReference(typeof(IMoverComponent))] internal class ShuttleControllerComponent : Component, IMoverComponent { + [Dependency] private readonly IMapManager _mapManager = default!; + private bool _movingUp; private bool _movingDown; private bool _movingLeft; @@ -39,19 +39,43 @@ namespace Content.Server.GameObjects.Components.Movement public override string Name => "ShuttleController"; - public bool IgnorePaused => false; - [ViewVariables(VVAccess.ReadWrite)] public float CurrentWalkSpeed { get; } = 8; public float CurrentSprintSpeed => 0; + /// + [ViewVariables] + public float CurrentPushSpeed => 0.0f; + + /// + [ViewVariables] + public float GrabRange => 0.0f; + public bool Sprinting => false; - public (Vector2 walking, Vector2 sprinting) VelocityDir { get; set; } = (Vector2.Zero, Vector2.Zero); + public (Vector2 walking, Vector2 sprinting) VelocityDir { get; } = (Vector2.Zero, Vector2.Zero); + public EntityCoordinates LastPosition { get; set; } + public float StepSoundDistance { get; set; } public void SetVelocityDirection(Direction direction, ushort subTick, bool enabled) { - VelocityDir = (CalcNewVelocity(direction, enabled), Vector2.Zero); + var gridId = Owner.Transform.GridID; + + if (_mapManager.TryGetGrid(gridId, out var grid) && + Owner.EntityManager.TryGetEntity(grid.GridEntityId, out var gridEntity)) + { + //TODO: Switch to shuttle component + if (!gridEntity.TryGetComponent(out IPhysicsComponent? physics)) + { + physics = gridEntity.AddComponent(); + physics.Mass = 1; + physics.CanCollide = true; + physics.PhysicsShapes.Add(new PhysShapeGrid(grid)); + } + + var controller = physics.EnsureController(); + controller.Push(CalcNewVelocity(direction, enabled), CurrentWalkSpeed); + } } public void SetSprinting(ushort subTick, bool walking) diff --git a/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs b/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs index 5701ec4e9d..73bb4f0cb1 100644 --- a/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs +++ b/Content.Server/GameObjects/Components/NodeContainer/Nodes/Node.cs @@ -5,7 +5,6 @@ using System.Linq; using Content.Server.GameObjects.Components.NodeContainer.NodeGroups; using Robust.Shared.GameObjects; using Robust.Shared.IoC; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -39,7 +38,7 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes /// public bool Connectable => !_deleting && Anchored; - private bool Anchored => !Owner.TryGetComponent(out var physics) || physics.BodyType == BodyType.Static; + private bool Anchored => !Owner.TryGetComponent(out var physics) || physics.Anchored; /// /// Prevents a node from being used by other nodes while midway through removal. diff --git a/Content.Server/GameObjects/Components/PA/ParticleProjectileComponent.cs b/Content.Server/GameObjects/Components/PA/ParticleProjectileComponent.cs index bc389c0a80..2fb3bc8bdf 100644 --- a/Content.Server/GameObjects/Components/PA/ParticleProjectileComponent.cs +++ b/Content.Server/GameObjects/Components/PA/ParticleProjectileComponent.cs @@ -6,7 +6,6 @@ using Robust.Server.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.Log; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Timing; namespace Content.Server.GameObjects.Components.PA @@ -16,9 +15,9 @@ namespace Content.Server.GameObjects.Components.PA { public override string Name => "ParticleProjectile"; private ParticleAcceleratorPowerState _state; - public void CollideWith(IPhysBody ourBody, IPhysBody otherBody) + public void CollideWith(IEntity collidedWith) { - if (otherBody.Entity.TryGetComponent(out var singularityComponent)) + if (collidedWith.TryGetComponent(out var singularityComponent)) { var multiplier = _state switch { @@ -31,8 +30,8 @@ namespace Content.Server.GameObjects.Components.PA }; singularityComponent.Energy += 10 * multiplier; Owner.Delete(); - } - else if (otherBody.Entity.TryGetComponent(out var singularityGeneratorComponent)) + }else if (collidedWith.TryGetComponent(out var singularityGeneratorComponent) + ) { singularityGeneratorComponent.Power += _state switch { @@ -56,7 +55,7 @@ namespace Content.Server.GameObjects.Components.PA Logger.Error("ParticleProjectile tried firing, but it was spawned without a CollidableComponent"); return; } - physicsComponent.BodyStatus = BodyStatus.InAir; + physicsComponent.Status = BodyStatus.InAir; if (!Owner.TryGetComponent(out var projectileComponent)) { @@ -82,6 +81,7 @@ namespace Content.Server.GameObjects.Components.PA spriteComponent.LayerSetState(0, $"particle{suffix}"); physicsComponent + .EnsureController() .LinearVelocity = angle.ToVec() * 20f; Owner.Transform.LocalRotation = new Angle(angle + Angle.FromDegrees(180)); diff --git a/Content.Server/GameObjects/Components/Portal/PortalComponent.cs b/Content.Server/GameObjects/Components/Portal/PortalComponent.cs index 4c9b9678bd..96bc5314e9 100644 --- a/Content.Server/GameObjects/Components/Portal/PortalComponent.cs +++ b/Content.Server/GameObjects/Components/Portal/PortalComponent.cs @@ -5,7 +5,6 @@ using Content.Shared.GameObjects.Components.Portal; using Content.Shared.GameObjects.Components.Tag; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -169,11 +168,11 @@ namespace Content.Server.GameObjects.Components.Portal StartCooldown(); } - public void CollideWith(IPhysBody ourBody, IPhysBody otherBody) + public void CollideWith(IEntity collidedWith) { if (_onCooldown == false) { - TryPortalEntity(otherBody.Entity); + TryPortalEntity(collidedWith); } } } diff --git a/Content.Server/GameObjects/Components/Portal/TeleporterComponent.cs b/Content.Server/GameObjects/Components/Portal/TeleporterComponent.cs index d620b30c53..3b5f33bc3a 100644 --- a/Content.Server/GameObjects/Components/Portal/TeleporterComponent.cs +++ b/Content.Server/GameObjects/Components/Portal/TeleporterComponent.cs @@ -9,7 +9,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Random; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -105,7 +104,7 @@ namespace Content.Server.GameObjects.Components.Portal { // Added this component to avoid stacking portals and causing shenanigans // TODO: Doesn't do a great job of stopping stacking portals for directed - if (entity.HasComponent() || entity.HasComponent()) + if (entity.HasComponent() || entity.HasComponent()) { return; } @@ -149,7 +148,7 @@ namespace Content.Server.GameObjects.Components.Portal // TODO: Check the user's spot? Upside is no stacking TPs but downside is they can't unstuck themselves from walls. foreach (var entity in _serverEntityManager.GetEntitiesIntersecting(user.Transform.MapID, target)) { - if (entity.HasComponent() || entity.HasComponent()) + if (entity.HasComponent() || entity.HasComponent()) { return false; } diff --git a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverComponent.cs b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverComponent.cs index b38a64cfbe..a933be6cb6 100644 --- a/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverComponent.cs +++ b/Content.Server/GameObjects/Components/Power/ApcNetComponents/PowerReceiverComponent.cs @@ -7,7 +7,6 @@ using Robust.Server.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.Utility; using Robust.Shared.ViewVariables; @@ -22,7 +21,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents { [Dependency] private readonly IServerEntityManager _serverEntityManager = default!; - [ViewVariables] [ComponentDependency] private readonly IPhysBody? _physicsComponent = null; + [ViewVariables] [ComponentDependency] private readonly IPhysicsComponent? _physicsComponent = null; public override string Name => "PowerReceiver"; @@ -51,7 +50,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents /// public bool Connectable => Anchored; - private bool Anchored => _physicsComponent == null || _physicsComponent.BodyType == BodyType.Static; + private bool Anchored => _physicsComponent == null || _physicsComponent.Anchored; [ViewVariables] public bool NeedsProvider { get; private set; } = true; @@ -99,7 +98,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents } } - public override void OnRemove() + public override void OnRemove() { _provider.RemoveReceiver(this); base.OnRemove(); diff --git a/Content.Server/GameObjects/Components/Projectiles/ChemicalInjectionProjectileComponent.cs b/Content.Server/GameObjects/Components/Projectiles/ChemicalInjectionProjectileComponent.cs index 9c83c1a1db..f5e0fd90a5 100644 --- a/Content.Server/GameObjects/Components/Projectiles/ChemicalInjectionProjectileComponent.cs +++ b/Content.Server/GameObjects/Components/Projectiles/ChemicalInjectionProjectileComponent.cs @@ -5,7 +5,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; using System; -using Robust.Shared.Physics; namespace Content.Server.GameObjects.Components.Projectiles { @@ -37,9 +36,9 @@ namespace Content.Server.GameObjects.Components.Projectiles _solutionContainer = Owner.EnsureComponent(); } - void ICollideBehavior.CollideWith(IPhysBody ourBody, IPhysBody otherBody) + void ICollideBehavior.CollideWith(IEntity entity) { - if (!otherBody.Entity.TryGetComponent(out var bloodstream)) + if (!entity.TryGetComponent(out var bloodstream)) return; var solution = _solutionContainer.Solution; diff --git a/Content.Server/GameObjects/Components/Projectiles/ExplosiveProjectileComponent.cs b/Content.Server/GameObjects/Components/Projectiles/ExplosiveProjectileComponent.cs index 2f8e58fe0d..5a76b11d28 100644 --- a/Content.Server/GameObjects/Components/Projectiles/ExplosiveProjectileComponent.cs +++ b/Content.Server/GameObjects/Components/Projectiles/ExplosiveProjectileComponent.cs @@ -1,6 +1,5 @@ using Content.Server.GameObjects.Components.Explosion; using Robust.Shared.GameObjects; -using Robust.Shared.Physics; namespace Content.Server.GameObjects.Components.Projectiles { @@ -16,12 +15,18 @@ namespace Content.Server.GameObjects.Components.Projectiles Owner.EnsureComponent(); } - void ICollideBehavior.CollideWith(IPhysBody ourBody, IPhysBody otherBody) + void ICollideBehavior.CollideWith(IEntity entity) { if (Owner.TryGetComponent(out ExplosiveComponent explosive)) { explosive.Explosion(); } } + + // Projectile should handle the deleting + void ICollideBehavior.PostCollide(int collisionCount) + { + return; + } } } diff --git a/Content.Server/GameObjects/Components/Projectiles/FlashProjectileComponent.cs b/Content.Server/GameObjects/Components/Projectiles/FlashProjectileComponent.cs index f878ba8d38..84475b77f5 100644 --- a/Content.Server/GameObjects/Components/Projectiles/FlashProjectileComponent.cs +++ b/Content.Server/GameObjects/Components/Projectiles/FlashProjectileComponent.cs @@ -1,6 +1,5 @@ using Content.Server.GameObjects.Components.Weapon; using Robust.Shared.GameObjects; -using Robust.Shared.Physics; using Robust.Shared.Serialization; namespace Content.Server.GameObjects.Components.Projectiles @@ -32,15 +31,20 @@ namespace Content.Server.GameObjects.Components.Projectiles Owner.EnsureComponent(); } - void ICollideBehavior.CollideWith(IPhysBody ourBody, IPhysBody otherBody) + void ICollideBehavior.CollideWith(IEntity entity) { if (_flashed) { return; } - FlashableComponent.FlashAreaHelper(Owner, _range, _duration); _flashed = true; } + + // Projectile should handle the deleting + void ICollideBehavior.PostCollide(int collisionCount) + { + return; + } } } diff --git a/Content.Server/GameObjects/Components/Projectiles/HitscanComponent.cs b/Content.Server/GameObjects/Components/Projectiles/HitscanComponent.cs index e58e6a8dc5..28ee924f96 100644 --- a/Content.Server/GameObjects/Components/Projectiles/HitscanComponent.cs +++ b/Content.Server/GameObjects/Components/Projectiles/HitscanComponent.cs @@ -7,7 +7,6 @@ using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Physics; -using Robust.Shared.Physics.Dynamics; using Robust.Shared.Serialization; using Robust.Shared.Timing; diff --git a/Content.Server/GameObjects/Components/Projectiles/ProjectileComponent.cs b/Content.Server/GameObjects/Components/Projectiles/ProjectileComponent.cs index 033cebe455..daa721cc10 100644 --- a/Content.Server/GameObjects/Components/Projectiles/ProjectileComponent.cs +++ b/Content.Server/GameObjects/Components/Projectiles/ProjectileComponent.cs @@ -5,7 +5,6 @@ using Content.Shared.GameObjects.Components.Damage; using Content.Shared.GameObjects.Components.Projectiles; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; -using Robust.Shared.Physics; using Robust.Shared.Players; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -13,7 +12,7 @@ using Robust.Shared.ViewVariables; namespace Content.Server.GameObjects.Components.Projectiles { [RegisterComponent] - public class ProjectileComponent : SharedProjectileComponent, ICollideBehavior, IPostCollide + public class ProjectileComponent : SharedProjectileComponent, ICollideBehavior { protected override EntityUid Shooter => _shooter; @@ -28,14 +27,15 @@ namespace Content.Server.GameObjects.Components.Projectiles set => _damages = value; } - private bool _damagedEntity = false; - + public bool DeleteOnCollide => _deleteOnCollide; private bool _deleteOnCollide; // Get that juicy FPS hit sound private string _soundHit; private string _soundHitSpecies; + private bool _damagedEntity; + public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); @@ -58,27 +58,39 @@ namespace Content.Server.GameObjects.Components.Projectiles Dirty(); } + private bool _internalDeleteOnCollide; + /// - /// Applies the damage when our projectile collides with its victim + /// Applies the damage when our projectile collides with its victim /// - void ICollideBehavior.CollideWith(IPhysBody ourBody, IPhysBody otherBody) + /// + void ICollideBehavior.CollideWith(IEntity entity) { - // This is so entities that shouldn't get a collision are ignored. - if (!otherBody.Hard || _damagedEntity) + if (_damagedEntity) { return; } - if (otherBody.Entity.TryGetComponent(out IDamageableComponent damage) && _soundHitSpecies != null) + // This is so entities that shouldn't get a collision are ignored. + if (entity.TryGetComponent(out IPhysicsComponent otherPhysics) && otherPhysics.Hard == false) { - EntitySystem.Get().PlayAtCoords(_soundHitSpecies, otherBody.Entity.Transform.Coordinates); + _internalDeleteOnCollide = false; + return; } - else if (_soundHit != null) + else { - EntitySystem.Get().PlayAtCoords(_soundHit, otherBody.Entity.Transform.Coordinates); + _internalDeleteOnCollide = true; } - if (damage != null) + if (_soundHitSpecies != null && entity.HasComponent()) + { + EntitySystem.Get().PlayAtCoords(_soundHitSpecies, entity.Transform.Coordinates); + } else if (_soundHit != null) + { + EntitySystem.Get().PlayAtCoords(_soundHit, entity.Transform.Coordinates); + } + + if (entity.TryGetComponent(out IDamageableComponent damage)) { Owner.EntityManager.TryGetEntity(_shooter, out var shooter); @@ -90,17 +102,17 @@ namespace Content.Server.GameObjects.Components.Projectiles _damagedEntity = true; } - // Damaging it can delete it - if (!otherBody.Entity.Deleted && otherBody.Entity.TryGetComponent(out CameraRecoilComponent recoilComponent)) + if (!entity.Deleted && entity.TryGetComponent(out CameraRecoilComponent recoilComponent) + && Owner.TryGetComponent(out IPhysicsComponent ownPhysics)) { - var direction = ourBody.LinearVelocity.Normalized; + var direction = ownPhysics.LinearVelocity.Normalized; recoilComponent.Kick(direction); } } - void IPostCollide.PostCollide(IPhysBody ourBody, IPhysBody otherBody) + void ICollideBehavior.PostCollide(int collideCount) { - if (_damagedEntity) Owner.Delete(); + if (collideCount > 0 && DeleteOnCollide && _internalDeleteOnCollide) Owner.Delete(); } public override ComponentState GetComponentState(ICommonSession player) diff --git a/Content.Server/GameObjects/Components/Projectiles/StunnableProjectileComponent.cs b/Content.Server/GameObjects/Components/Projectiles/StunnableProjectileComponent.cs index f13d3d41ed..d8ce946c24 100644 --- a/Content.Server/GameObjects/Components/Projectiles/StunnableProjectileComponent.cs +++ b/Content.Server/GameObjects/Components/Projectiles/StunnableProjectileComponent.cs @@ -1,6 +1,5 @@ using Content.Server.GameObjects.Components.Mobs; using Robust.Shared.GameObjects; -using Robust.Shared.Physics; using Robust.Shared.Serialization; namespace Content.Server.GameObjects.Components.Projectiles @@ -33,14 +32,16 @@ namespace Content.Server.GameObjects.Components.Projectiles Owner.EnsureComponentWarn(out ProjectileComponent _); } - void ICollideBehavior.CollideWith(IPhysBody ourBody, IPhysBody otherBody) + void ICollideBehavior.CollideWith(IEntity entity) { - if (otherBody.Entity.TryGetComponent(out StunnableComponent stunnableComponent)) + if (entity.TryGetComponent(out StunnableComponent stunnableComponent)) { stunnableComponent.Stun(_stunAmount); stunnableComponent.Knockdown(_knockdownAmount); stunnableComponent.Slowdown(_slowdownAmount); } } + + void ICollideBehavior.PostCollide(int collidedCount) {} } } diff --git a/Content.Server/GameObjects/Components/Projectiles/ThrownItemComponent.cs b/Content.Server/GameObjects/Components/Projectiles/ThrownItemComponent.cs new file mode 100644 index 0000000000..31899d5fed --- /dev/null +++ b/Content.Server/GameObjects/Components/Projectiles/ThrownItemComponent.cs @@ -0,0 +1,118 @@ +using Content.Server.GameObjects.EntitySystems.Click; +using Content.Shared.GameObjects; +using Content.Shared.Physics; +using Robust.Server.GameObjects; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Maths; +using Robust.Shared.Physics; + +namespace Content.Server.GameObjects.Components.Projectiles +{ + [RegisterComponent] + internal class ThrownItemComponent : ProjectileComponent, ICollideBehavior + { + public const float DefaultThrowTime = 0.25f; + + private bool _shouldCollide = true; + private bool _shouldStop = false; + + public override string Name => "ThrownItem"; + public override uint? NetID => ContentNetIDs.THROWN_ITEM; + + /// + /// User who threw the item. + /// + public IEntity User { get; set; } + + void ICollideBehavior.CollideWith(IEntity entity) + { + if (!_shouldCollide || entity.Deleted) return; + if (entity.TryGetComponent(out PhysicsComponent collid)) + { + if (!collid.Hard) // ignore non hard + return; + + _shouldStop = true; // hit something hard => stop after this collision + + // Raise an event. + EntitySystem.Get().ThrowCollideInteraction(User, Owner, entity, Owner.Transform.Coordinates); + } + + // Stop colliding with mobs, this mimics not having enough velocity to do damage + // after impacting the first object. + // For realism this should actually be changed when the velocity of the object is less than a threshold. + // This would allow ricochets off walls, and weird gravity effects from slowing the object. + if (!Owner.Deleted && Owner.TryGetComponent(out IPhysicsComponent body) && body.PhysicsShapes.Count >= 1) + { + _shouldCollide = false; + } + } + + private void StopThrow() + { + if (Deleted) + { + return; + } + + if (Owner.TryGetComponent(out IPhysicsComponent body) && body.PhysicsShapes.Count >= 1) + { + body.PhysicsShapes[0].CollisionMask &= (int) ~CollisionGroup.ThrownItem; + + if (body.TryGetController(out ThrownController controller)) + { + controller.LinearVelocity = Vector2.Zero; + } + + body.Status = BodyStatus.OnGround; + + Owner.RemoveComponent(); + EntitySystem.Get().LandInteraction(User, Owner, Owner.Transform.Coordinates); + } + } + + void ICollideBehavior.PostCollide(int collideCount) + { + if (_shouldStop && collideCount > 0) + { + StopThrow(); + } + } + + public void StartThrow(Vector2 direction, float speed) + { + var comp = Owner.GetComponent(); + comp.Status = BodyStatus.InAir; + + var controller = comp.EnsureController(); + controller.Push(direction, speed); + + EntitySystem.Get() + .PlayFromEntity("/Audio/Effects/toss.ogg", Owner); + + StartStopTimer(); + } + + private void StartStopTimer() + { + Owner.SpawnTimer((int) (DefaultThrowTime * 1000), MaybeStopThrow); + } + + private void MaybeStopThrow() + { + if (Deleted) + { + return; + } + + if (IoCManager.Resolve().IsWeightless(Owner.Transform.Coordinates)) + { + StartStopTimer(); + return; + } + + StopThrow(); + } + } +} diff --git a/Content.Server/GameObjects/Components/Pulling/PullableComponent.cs b/Content.Server/GameObjects/Components/Pulling/PullableComponent.cs index 9c55176d5d..53a1c9b059 100644 --- a/Content.Server/GameObjects/Components/Pulling/PullableComponent.cs +++ b/Content.Server/GameObjects/Components/Pulling/PullableComponent.cs @@ -5,7 +5,6 @@ using Content.Shared.GameObjects.EntitySystems; using Content.Shared.GameObjects.Verbs; using Robust.Shared.GameObjects; using Robust.Shared.Localization; -using Robust.Shared.Physics; namespace Content.Server.GameObjects.Components.Pulling { @@ -32,15 +31,15 @@ namespace Content.Server.GameObjects.Components.Pulling } if (!user.HasComponent() || - !user.TryGetComponent(out IPhysBody? userPhysics) || - !component.Owner.TryGetComponent(out IPhysBody? targetPhysics) || - targetPhysics.BodyType == BodyType.Static) + !user.TryGetComponent(out IPhysicsComponent? userPhysics) || + !component.Owner.TryGetComponent(out IPhysicsComponent? targetPhysics) || + targetPhysics.Anchored) { return; } data.Visibility = VerbVisibility.Visible; - data.Text = component.Puller == userPhysics.Entity + data.Text = component.Puller == userPhysics ? Loc.GetString("Stop pulling") : Loc.GetString("Pull"); } diff --git a/Content.Server/GameObjects/Components/Recycling/RecyclerComponent.cs b/Content.Server/GameObjects/Components/Recycling/RecyclerComponent.cs index f8fc9d3bc4..3b34e50b79 100644 --- a/Content.Server/GameObjects/Components/Recycling/RecyclerComponent.cs +++ b/Content.Server/GameObjects/Components/Recycling/RecyclerComponent.cs @@ -19,7 +19,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -31,7 +30,7 @@ namespace Content.Server.GameObjects.Components.Recycling { public override string Name => "Recycler"; - public List Intersecting { get; set; } = new(); + private readonly List _intersecting = new(); /// /// Whether or not sentient beings will be recycled @@ -73,9 +72,9 @@ namespace Content.Server.GameObjects.Components.Recycling private void Recycle(IEntity entity) { - if (!Intersecting.Contains(entity)) + if (!_intersecting.Contains(entity)) { - Intersecting.Add(entity); + _intersecting.Add(entity); } // TODO: Prevent collision with recycled items @@ -94,7 +93,7 @@ namespace Content.Server.GameObjects.Components.Recycling recyclable.Recycle(_efficiency); } - public bool CanRun() + private bool CanRun() { if (Owner.TryGetComponent(out PowerReceiverComponent? receiver) && !receiver.Powered) @@ -110,15 +109,15 @@ namespace Content.Server.GameObjects.Components.Recycling return true; } - public bool CanMove(IEntity entity) + private bool CanMove(IEntity entity) { if (entity == Owner) { return false; } - if (!entity.TryGetComponent(out IPhysBody? physics) || - physics.BodyType == BodyType.Static) + if (!entity.TryGetComponent(out IPhysicsComponent? physics) || + physics.Anchored) { return false; } @@ -141,6 +140,34 @@ namespace Content.Server.GameObjects.Components.Recycling return true; } + public void Update(float frameTime) + { + if (!CanRun()) + { + _intersecting.Clear(); + return; + } + + var direction = Vector2.UnitX; + + for (var i = _intersecting.Count - 1; i >= 0; i--) + { + var entity = _intersecting[i]; + + if (entity.Deleted || !CanMove(entity) || !Owner.EntityManager.IsIntersecting(Owner, entity)) + { + _intersecting.RemoveAt(i); + continue; + } + + if (entity.TryGetComponent(out IPhysicsComponent? physics)) + { + var controller = physics.EnsureController(); + controller.Move(direction, frameTime, entity.Transform.WorldPosition - Owner.Transform.WorldPosition); + } + } + } + public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); @@ -149,9 +176,9 @@ namespace Content.Server.GameObjects.Components.Recycling serializer.DataField(ref _efficiency, "efficiency", 0.25f); } - void ICollideBehavior.CollideWith(IPhysBody ourBody, IPhysBody otherBody) + void ICollideBehavior.CollideWith(IEntity collidedWith) { - Recycle(otherBody.Entity); + Recycle(collidedWith); } SuicideKind ISuicideAct.Suicide(IEntity victim, IChatManager chat) diff --git a/Content.Server/GameObjects/Components/Rotatable/FlippableComponent.cs b/Content.Server/GameObjects/Components/Rotatable/FlippableComponent.cs index fa1050f619..0ff258fd57 100644 --- a/Content.Server/GameObjects/Components/Rotatable/FlippableComponent.cs +++ b/Content.Server/GameObjects/Components/Rotatable/FlippableComponent.cs @@ -4,7 +4,6 @@ using Content.Shared.GameObjects.Verbs; using Content.Shared.Interfaces; using Robust.Shared.GameObjects; using Robust.Shared.Localization; -using Robust.Shared.Physics; using Robust.Shared.Serialization; namespace Content.Server.GameObjects.Components.Rotatable @@ -18,8 +17,8 @@ namespace Content.Server.GameObjects.Components.Rotatable private void TryFlip(IEntity user) { - if (Owner.TryGetComponent(out IPhysBody? physics) && - physics.BodyType == BodyType.Static) + if (Owner.TryGetComponent(out IPhysicsComponent? physics) && + physics.Anchored) { Owner.PopupMessage(user, Loc.GetString("It's stuck.")); return; diff --git a/Content.Server/GameObjects/Components/Rotatable/RotatableComponent.cs b/Content.Server/GameObjects/Components/Rotatable/RotatableComponent.cs index 2a458e209c..877c8bdbc5 100644 --- a/Content.Server/GameObjects/Components/Rotatable/RotatableComponent.cs +++ b/Content.Server/GameObjects/Components/Rotatable/RotatableComponent.cs @@ -4,7 +4,6 @@ using Content.Shared.Interfaces; using Robust.Shared.GameObjects; using Robust.Shared.Localization; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -29,9 +28,9 @@ namespace Content.Server.GameObjects.Components.Rotatable private void TryRotate(IEntity user, Angle angle) { - if (!RotateWhileAnchored && Owner.TryGetComponent(out IPhysBody physics)) + if (!RotateWhileAnchored && Owner.TryGetComponent(out IPhysicsComponent physics)) { - if (physics.BodyType == BodyType.Static) + if (physics.Anchored) { Owner.PopupMessage(user, Loc.GetString("It's stuck.")); return; @@ -46,7 +45,7 @@ namespace Content.Server.GameObjects.Components.Rotatable { protected override void GetData(IEntity user, RotatableComponent component, VerbData data) { - if (!ActionBlockerSystem.CanInteract(user) || (!component.RotateWhileAnchored && component.Owner.TryGetComponent(out IPhysBody physics) && physics.BodyType == BodyType.Static)) + if (!ActionBlockerSystem.CanInteract(user) || (!component.RotateWhileAnchored && component.Owner.TryGetComponent(out IPhysicsComponent physics) && physics.Anchored)) { data.Visibility = VerbVisibility.Invisible; return; @@ -68,7 +67,7 @@ namespace Content.Server.GameObjects.Components.Rotatable { protected override void GetData(IEntity user, RotatableComponent component, VerbData data) { - if (!ActionBlockerSystem.CanInteract(user) || (!component.RotateWhileAnchored && component.Owner.TryGetComponent(out IPhysBody physics) && physics.BodyType == BodyType.Static)) + if (!ActionBlockerSystem.CanInteract(user) || (!component.RotateWhileAnchored && component.Owner.TryGetComponent(out IPhysicsComponent physics) && physics.Anchored)) { data.Visibility = VerbVisibility.Invisible; return; diff --git a/Content.Server/GameObjects/Components/Singularity/ContainmentFieldComponent.cs b/Content.Server/GameObjects/Components/Singularity/ContainmentFieldComponent.cs index aa01024901..14702fa091 100644 --- a/Content.Server/GameObjects/Components/Singularity/ContainmentFieldComponent.cs +++ b/Content.Server/GameObjects/Components/Singularity/ContainmentFieldComponent.cs @@ -1,6 +1,5 @@ #nullable enable using Robust.Shared.GameObjects; -using Robust.Shared.Physics; namespace Content.Server.GameObjects.Components.Singularity { @@ -10,7 +9,7 @@ namespace Content.Server.GameObjects.Components.Singularity public override string Name => "ContainmentField"; public ContainmentFieldConnection? Parent; - public void CollideWith(IPhysBody ourBody, IPhysBody otherBody) + public void CollideWith(IEntity collidedWith) { if (Parent == null) { @@ -18,7 +17,7 @@ namespace Content.Server.GameObjects.Components.Singularity return; } - Parent.TryRepell(Owner, otherBody.Entity); + Parent.TryRepell(Owner, collidedWith); } } } diff --git a/Content.Server/GameObjects/Components/Singularity/ContainmentFieldConnection.cs b/Content.Server/GameObjects/Components/Singularity/ContainmentFieldConnection.cs index a127bfa5bb..7ad9ec1d53 100644 --- a/Content.Server/GameObjects/Components/Singularity/ContainmentFieldConnection.cs +++ b/Content.Server/GameObjects/Components/Singularity/ContainmentFieldConnection.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; using System.Threading; +using Content.Shared.Physics; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Log; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Timer = Robust.Shared.Timing.Timer; namespace Content.Server.GameObjects.Components.Singularity @@ -90,12 +90,10 @@ namespace Content.Server.GameObjects.Components.Singularity /// Entity to repell. public void TryRepell(IEntity repellFrom, IEntity toRepell) { - // TODO: Fix this also it's fucking repel - if (!_fields.Contains(repellFrom) || !toRepell.TryGetComponent(out var collidableComponent)) return; + if (!_fields.Contains(repellFrom) || !toRepell.TryGetComponent(out var collidableComponent)) return; - return; var speed = 5; - //var containmentFieldRepellController = collidableComponent.EnsureController(); + var containmentFieldRepellController = collidableComponent.EnsureController(); if (!CanRepell(toRepell)) { @@ -108,22 +106,22 @@ namespace Content.Server.GameObjects.Components.Singularity { if (repellFrom.Transform.WorldPosition.X.CompareTo(toRepell.Transform.WorldPosition.X) > 0) { - //containmentFieldRepellController.Repell(Direction.West, speed); + containmentFieldRepellController.Repell(Direction.West, speed); } else { - //containmentFieldRepellController.Repell(Direction.East, speed); + containmentFieldRepellController.Repell(Direction.East, speed); } } else { if (repellFrom.Transform.WorldPosition.Y.CompareTo(toRepell.Transform.WorldPosition.Y) > 0) { - //containmentFieldRepellController.Repell(Direction.South, speed); + containmentFieldRepellController.Repell(Direction.South, speed); } else { - //containmentFieldRepellController.Repell(Direction.North, speed); + containmentFieldRepellController.Repell(Direction.North, speed); } } diff --git a/Content.Server/GameObjects/Components/Singularity/ContainmentFieldGeneratorComponent.cs b/Content.Server/GameObjects/Components/Singularity/ContainmentFieldGeneratorComponent.cs index 21dfdc75f6..7dc05478bf 100644 --- a/Content.Server/GameObjects/Components/Singularity/ContainmentFieldGeneratorComponent.cs +++ b/Content.Server/GameObjects/Components/Singularity/ContainmentFieldGeneratorComponent.cs @@ -10,7 +10,6 @@ using Robust.Shared.IoC; using Robust.Shared.Log; using Robust.Shared.Maths; using Robust.Shared.Physics; -using Robust.Shared.Physics.Broadphase; using Robust.Shared.ViewVariables; using Robust.Server.GameObjects; @@ -118,7 +117,7 @@ namespace Content.Server.GameObjects.Components.Singularity var dirVec = direction.ToVec(); var ray = new CollisionRay(Owner.Transform.WorldPosition, dirVec, (int) CollisionGroup.MobMask); - var rawRayCastResults = EntitySystem.Get().IntersectRay(Owner.Transform.MapID, ray, 4.5f, Owner, false); + var rawRayCastResults = _physicsManager.IntersectRay(Owner.Transform.MapID, ray, 4.5f, Owner, false); var rayCastResults = rawRayCastResults as RayCastResults[] ?? rawRayCastResults.ToArray(); if(!rayCastResults.Any()) continue; @@ -183,9 +182,9 @@ namespace Content.Server.GameObjects.Components.Singularity } } - public void CollideWith(IPhysBody ourBody, IPhysBody otherBody) + public void CollideWith(IEntity collidedWith) { - if (otherBody.Entity.HasComponent()) + if(collidedWith.HasComponent()) { ReceivePower(4); } diff --git a/Content.Server/GameObjects/Components/Singularity/EmitterComponent.cs b/Content.Server/GameObjects/Components/Singularity/EmitterComponent.cs index 8b46a78468..d86662d49b 100644 --- a/Content.Server/GameObjects/Components/Singularity/EmitterComponent.cs +++ b/Content.Server/GameObjects/Components/Singularity/EmitterComponent.cs @@ -254,7 +254,7 @@ namespace Content.Server.GameObjects.Components.Singularity return; } - physicsComponent.BodyStatus = BodyStatus.InAir; + physicsComponent.Status = BodyStatus.InAir; if (!projectile.TryGetComponent(out var projectileComponent)) { @@ -265,6 +265,7 @@ namespace Content.Server.GameObjects.Components.Singularity projectileComponent.IgnoreEntity(Owner); physicsComponent + .EnsureController() .LinearVelocity = Owner.Transform.WorldRotation.ToVec() * 20f; projectile.Transform.LocalRotation = Owner.Transform.WorldRotation; diff --git a/Content.Server/GameObjects/Components/Singularity/SingularityComponent.cs b/Content.Server/GameObjects/Components/Singularity/SingularityComponent.cs index dc72c4e00c..d8c32dc2e3 100644 --- a/Content.Server/GameObjects/Components/Singularity/SingularityComponent.cs +++ b/Content.Server/GameObjects/Components/Singularity/SingularityComponent.cs @@ -14,7 +14,6 @@ using Robust.Shared.Log; using Robust.Shared.Maths; using Robust.Shared.Map; using Robust.Shared.Physics; -using Robust.Shared.Physics.Dynamics.Shapes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -39,6 +38,7 @@ namespace Content.Server.GameObjects.Components.Singularity _energy = value; if (_energy <= 0) { + if(_singularityController != null) _singularityController.LinearVelocity = Vector2.Zero; _spriteComponent?.LayerSetVisible(0, false); Owner.Delete(); @@ -75,7 +75,7 @@ namespace Content.Server.GameObjects.Components.Singularity _spriteComponent?.LayerSetRSI(0, "Effects/Singularity/singularity_" + _level + ".rsi"); _spriteComponent?.LayerSetState(0, "singularity_" + _level); - if(_collidableComponent != null && _collidableComponent.Fixtures.Any() && _collidableComponent.Fixtures[0].Shape is PhysShapeCircle circle) + if(_collidableComponent != null && _collidableComponent.PhysicsShapes.Any() && _collidableComponent.PhysicsShapes[0] is PhysShapeCircle circle) { circle.Radius = _level - 0.5f; } @@ -95,6 +95,7 @@ namespace Content.Server.GameObjects.Components.Singularity _ => 0 }; + private SingularityController? _singularityController; private PhysicsComponent? _collidableComponent; private SpriteComponent? _spriteComponent; private RadiationPulseComponent? _radiationPulseComponent; @@ -128,6 +129,9 @@ namespace Content.Server.GameObjects.Components.Singularity Logger.Error("SingularityComponent was spawned without SpriteComponent"); } + _singularityController = _collidableComponent?.EnsureController(); + if(_singularityController!=null)_singularityController.ControlledComponent = _collidableComponent; + if (!Owner.TryGetComponent(out _radiationPulseComponent)) { Logger.Error("SingularityComponent was spawned without RadiationPulseComponent"); @@ -136,18 +140,60 @@ namespace Content.Server.GameObjects.Components.Singularity Level = 1; } - public void Update(int seconds) + public void Update() { - Energy -= EnergyDrain * seconds; + Energy -= EnergyDrain; + + if(Level == 1) return; + //pushing + var pushVector = new Vector2((_random.Next(-10, 10)), _random.Next(-10, 10)); + while (pushVector.X == 0 && pushVector.Y == 0) + { + pushVector = new Vector2((_random.Next(-10, 10)), _random.Next(-10, 10)); + } + _singularityController?.Push(pushVector.Normalized, 2); } - void ICollideBehavior.CollideWith(IPhysBody ourBody, IPhysBody otherBody) + private readonly List _previousPulledEntities = new(); + public void CleanupPulledEntities() { - var otherEntity = otherBody.Entity; - - if (otherEntity.TryGetComponent(out var mapGridComponent)) + foreach (var previousPulledEntity in _previousPulledEntities) { - foreach (var tile in mapGridComponent.Grid.GetTilesIntersecting(ourBody.GetWorldAABB())) + if(previousPulledEntity.Deleted) continue; + if (!previousPulledEntity.TryGetComponent(out var collidableComponent)) continue; + var controller = collidableComponent.EnsureController(); + controller.StopPull(); + } + _previousPulledEntities.Clear(); + } + + public void PullUpdate() + { + CleanupPulledEntities(); + var entitiesToPull = Owner.EntityManager.GetEntitiesInRange(Owner.Transform.Coordinates, Level * 10); + foreach (var entity in entitiesToPull) + { + if (!entity.TryGetComponent(out var collidableComponent)) continue; + if (entity.HasComponent()) continue; + var controller = collidableComponent.EnsureController(); + if(Owner.Transform.Coordinates.EntityId != entity.Transform.Coordinates.EntityId) continue; + var vec = (Owner.Transform.Coordinates - entity.Transform.Coordinates).Position; + if (vec == Vector2.Zero) continue; + + var speed = 10 / vec.Length * Level; + + controller.Pull(vec.Normalized, speed); + _previousPulledEntities.Add(entity); + } + } + + void ICollideBehavior.CollideWith(IEntity entity) + { + if (_collidableComponent == null) return; //how did it even collide then? :D + + if (entity.TryGetComponent(out var mapGridComponent)) + { + foreach (var tile in mapGridComponent.Grid.GetTilesIntersecting(((IPhysBody) _collidableComponent).WorldAABB)) { mapGridComponent.Grid.SetTile(tile.GridIndices, Tile.Empty); Energy++; @@ -155,14 +201,14 @@ namespace Content.Server.GameObjects.Components.Singularity return; } - if (otherEntity.HasComponent() || (otherEntity.TryGetComponent(out var component) && component.CanRepell(Owner))) + if (entity.HasComponent() || (entity.TryGetComponent(out var component) && component.CanRepell(Owner))) { return; } - if (otherEntity.IsInContainer()) return; + if (entity.IsInContainer()) return; - otherEntity.Delete(); + entity.Delete(); Energy++; } @@ -170,6 +216,7 @@ namespace Content.Server.GameObjects.Components.Singularity { _playingSound?.Stop(); _audioSystem.PlayAtCoords("/Audio/Effects/singularity_collapse.ogg", Owner.Transform.Coordinates); + CleanupPulledEntities(); base.OnRemove(); } } diff --git a/Content.Server/GameObjects/Components/Temperature/TemperatureComponent.cs b/Content.Server/GameObjects/Components/Temperature/TemperatureComponent.cs index 92cdc41ba4..4536d0625c 100644 --- a/Content.Server/GameObjects/Components/Temperature/TemperatureComponent.cs +++ b/Content.Server/GameObjects/Components/Temperature/TemperatureComponent.cs @@ -5,7 +5,6 @@ using Content.Shared.Atmos; using Content.Shared.Damage; using Content.Shared.GameObjects.Components.Damage; using Robust.Shared.GameObjects; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -30,7 +29,7 @@ namespace Content.Server.GameObjects.Components.Temperature [ViewVariables] public float HeatCapacity { get { - if (Owner.TryGetComponent(out var physics)) + if (Owner.TryGetComponent(out var physics)) { return SpecificHeat * physics.Mass; } diff --git a/Content.Server/GameObjects/Components/Weapon/FlashableComponent.cs b/Content.Server/GameObjects/Components/Weapon/FlashableComponent.cs index e919a9350f..5dfbf79023 100644 --- a/Content.Server/GameObjects/Components/Weapon/FlashableComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/FlashableComponent.cs @@ -1,6 +1,5 @@ using System; using Content.Shared.GameObjects.Components.Weapons; -using Content.Shared.Physics; using Content.Shared.Utility; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; @@ -32,17 +31,18 @@ namespace Content.Server.GameObjects.Components.Weapon public static void FlashAreaHelper(IEntity source, float range, float duration, string sound = null) { - foreach (var entity in source.EntityManager.GetEntitiesInRange(source.Transform.Coordinates, range)) + foreach (var entity in IoCManager.Resolve().GetEntitiesInRange(source.Transform.Coordinates, range)) { - if (!entity.TryGetComponent(out FlashableComponent flashable) || - !source.InRangeUnobstructed(entity, range, CollisionGroup.Opaque)) continue; + if (!source.InRangeUnobstructed(entity, range, popup: true)) + continue; - flashable.Flash(duration); + if(entity.TryGetComponent(out FlashableComponent flashable)) + flashable.Flash(duration); } if (!string.IsNullOrEmpty(sound)) { - EntitySystem.Get().PlayAtCoords(sound, source.Transform.Coordinates); + IoCManager.Resolve().GetEntitySystem().PlayAtCoords(sound, source.Transform.Coordinates); } } } diff --git a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs index e1af68da6c..3feb2f9703 100644 --- a/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Melee/MeleeWeaponComponent.cs @@ -12,7 +12,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Maths; using Robust.Shared.Physics; -using Robust.Shared.Physics.Broadphase; using Robust.Shared.Serialization; using Robust.Shared.Timing; using Robust.Shared.ViewVariables; @@ -197,13 +196,10 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee for (var i = 0; i < increments; i++) { var castAngle = new Angle(baseAngle + increment * i); - var res = EntitySystem.Get().IntersectRay(mapId, - new CollisionRay(position, castAngle.ToVec(), - (int) (CollisionGroup.Impassable | CollisionGroup.MobImpassable)), Range, ignore).ToList(); - - if (res.Count != 0) + var res = _physicsManager.IntersectRay(mapId, new CollisionRay(position, castAngle.ToWorldVec(), (int) (CollisionGroup.Impassable|CollisionGroup.MobImpassable)), Range, ignore).FirstOrDefault(); + if (res.HitEntity != null) { - resSet.Add(res[0].HitEntity); + resSet.Add(res.HitEntity); } } diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs index 604bdfeb12..af66bc9ccc 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerRangedBarrelComponent.cs @@ -20,7 +20,6 @@ using Robust.Shared.Log; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Physics; -using Robust.Shared.Physics.Broadphase; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Serialization; @@ -384,14 +383,15 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels projectileAngle = angle; } - var physics = projectile.GetComponent(); - physics.BodyStatus = BodyStatus.InAir; + var physics = projectile.GetComponent(); + physics.Status = BodyStatus.InAir; var projectileComponent = projectile.GetComponent(); projectileComponent.IgnoreEntity(shooter); projectile - .GetComponent() + .GetComponent() + .EnsureController() .LinearVelocity = projectileAngle.ToVec() * velocity; projectile.Transform.LocalRotation = projectileAngle + MathHelper.PiOver2; @@ -421,7 +421,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels private void FireHitscan(IEntity shooter, HitscanComponent hitscan, Angle angle) { var ray = new CollisionRay(Owner.Transform.Coordinates.ToMapPos(Owner.EntityManager), angle.ToVec(), (int) hitscan.CollisionMask); - var physicsManager = EntitySystem.Get(); + var physicsManager = IoCManager.Resolve(); var rayCastResults = physicsManager.IntersectRay(Owner.Transform.MapID, ray, hitscan.MaxLength, shooter, false).ToList(); if (rayCastResults.Count >= 1) diff --git a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/AiReachableSystem.cs b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/AiReachableSystem.cs index 0c0f838d5f..77fc851348 100644 --- a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/AiReachableSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/AiReachableSystem.cs @@ -10,7 +10,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -155,7 +154,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible var targetNode = _pathfindingSystem.GetNode(targetTile); var collisionMask = 0; - if (entity.TryGetComponent(out IPhysBody physics)) + if (entity.TryGetComponent(out IPhysicsComponent physics)) { collisionMask = physics.CollisionMask; } diff --git a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/ReachableArgs.cs b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/ReachableArgs.cs index 8d16f59d5f..6cedbf3176 100644 --- a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/ReachableArgs.cs +++ b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/ReachableArgs.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using Content.Server.GameObjects.Components.Access; using Content.Server.GameObjects.Components.Movement; using Robust.Shared.GameObjects; -using Robust.Shared.Physics; namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible { @@ -28,7 +27,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible public static ReachableArgs GetArgs(IEntity entity) { var collisionMask = 0; - if (entity.TryGetComponent(out IPhysBody? physics)) + if (entity.TryGetComponent(out IPhysicsComponent? physics)) { collisionMask = physics.CollisionMask; } diff --git a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingNode.cs b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingNode.cs index 9b80c2da6b..ca371983c0 100644 --- a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingNode.cs +++ b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingNode.cs @@ -6,7 +6,6 @@ using Content.Server.GameObjects.Components.Doors; using Robust.Shared.GameObjects; using Robust.Shared.Map; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Utility; namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding @@ -41,7 +40,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding GenerateMask(); } - public static bool IsRelevant(IEntity entity, IPhysBody physicsComponent) + public static bool IsRelevant(IEntity entity, IPhysicsComponent physicsComponent) { if (entity.Transform.GridID == GridId.Invalid || (PathfindingSystem.TrackedCollisionLayers & physicsComponent.CollisionLayer) == 0) @@ -257,7 +256,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding /// /// TODO: These 2 methods currently don't account for a bunch of changes (e.g. airlock unpowered, wrenching, etc.) /// TODO: Could probably optimise this slightly more. - public void AddEntity(IEntity entity, IPhysBody physicsComponent) + public void AddEntity(IEntity entity, IPhysicsComponent physicsComponent) { // If we're a door if (entity.HasComponent() || entity.HasComponent()) @@ -276,7 +275,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding DebugTools.Assert((PathfindingSystem.TrackedCollisionLayers & physicsComponent.CollisionLayer) != 0); - if (physicsComponent.BodyType == BodyType.Static) + if (!physicsComponent.Anchored) { _physicsLayers.Add(entity, physicsComponent.CollisionLayer); } diff --git a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingSystem.cs b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingSystem.cs index 1077ed4fe6..20f70c30e5 100644 --- a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingSystem.cs @@ -11,7 +11,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Utility; namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding @@ -30,7 +29,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding { [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!; - + public IReadOnlyDictionary> Graph => _graph; private readonly Dictionary> _graph = new(); @@ -82,8 +81,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding foreach (var update in _collidableUpdateQueue) { - if (!EntityManager.TryGetEntity(update.Owner, out var entity)) continue; - + var entity = EntityManager.GetEntity(update.Owner); if (update.CanCollide) { HandleEntityAdd(entity); @@ -264,7 +262,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding { if (entity.Deleted || _lastKnownPositions.ContainsKey(entity) || - !entity.TryGetComponent(out IPhysBody physics) || + !entity.TryGetComponent(out IPhysicsComponent physics) || !PathfindingNode.IsRelevant(entity, physics)) { return; @@ -303,7 +301,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding { // If we've moved to space or the likes then remove us. if (moveEvent.Sender.Deleted || - !moveEvent.Sender.TryGetComponent(out IPhysBody physics) || + !moveEvent.Sender.TryGetComponent(out IPhysicsComponent physics) || !PathfindingNode.IsRelevant(moveEvent.Sender, physics) || moveEvent.NewPosition.GetGridId(EntityManager) == GridId.Invalid) { @@ -368,7 +366,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding public bool CanTraverse(IEntity entity, PathfindingNode node) { - if (entity.TryGetComponent(out IPhysBody physics) && + if (entity.TryGetComponent(out IPhysicsComponent physics) && (physics.CollisionMask & node.BlockedCollisionMask) != 0) { return false; diff --git a/Content.Server/GameObjects/EntitySystems/AI/Steering/AiSteeringSystem.cs b/Content.Server/GameObjects/EntitySystems/AI/Steering/AiSteeringSystem.cs index 1bc1f50131..d2de9d5fff 100644 --- a/Content.Server/GameObjects/EntitySystems/AI/Steering/AiSteeringSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/AI/Steering/AiSteeringSystem.cs @@ -13,7 +13,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Timing; using Robust.Shared.Utility; using Robust.Shared.ViewVariables; @@ -414,7 +413,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering var startTile = gridManager.GetTileRef(entity.Transform.Coordinates); var endTile = gridManager.GetTileRef(steeringRequest.TargetGrid); var collisionMask = 0; - if (entity.TryGetComponent(out IPhysBody physics)) + if (entity.TryGetComponent(out IPhysicsComponent physics)) { collisionMask = physics.CollisionMask; } @@ -600,7 +599,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering return Vector2.Zero; } - if (target.TryGetComponent(out IPhysBody physics)) + if (target.TryGetComponent(out IPhysicsComponent physics)) { var targetDistance = (targetPos.Position - entityPos.Position); targetPos = targetPos.Offset(physics.LinearVelocity * targetDistance); @@ -618,7 +617,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering /// private Vector2 CollisionAvoidance(IEntity entity, Vector2 direction, ICollection ignoredTargets) { - if (direction == Vector2.Zero || !entity.TryGetComponent(out IPhysBody physics)) + if (direction == Vector2.Zero || !entity.TryGetComponent(out IPhysicsComponent physics)) { return Vector2.Zero; } @@ -659,7 +658,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering // if we're moving in the same direction then ignore // So if 2 entities are moving towards each other and both detect a collision they'll both move in the same direction // i.e. towards the right - if (physicsEntity.TryGetComponent(out IPhysBody otherPhysics) && + if (physicsEntity.TryGetComponent(out IPhysicsComponent otherPhysics) && Vector2.Dot(otherPhysics.LinearVelocity, direction) > 0) { continue; diff --git a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs index 45c4db54ee..79c21d5900 100644 --- a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Content.Server.GameObjects.Components.Items.Storage; @@ -26,7 +25,6 @@ using Robust.Shared.IoC; using Robust.Shared.Log; using Robust.Shared.Map; using Robust.Shared.Maths; -using Robust.Shared.Physics; using Robust.Shared.Players; namespace Content.Server.GameObjects.EntitySystems.Click @@ -39,8 +37,6 @@ namespace Content.Server.GameObjects.EntitySystems.Click { [Dependency] private readonly IEntityManager _entityManager = default!; - private List _throwCollide = new(); - public override void Initialize() { SubscribeNetworkEvent(HandleDragDropMessage); @@ -606,43 +602,28 @@ namespace Content.Server.GameObjects.EntitySystems.Click /// Calls ThrowCollide on all components that implement the IThrowCollide interface /// on a thrown entity and the target entity it hit. /// - public void ThrowCollideInteraction(IEntity user, IPhysBody thrown, IPhysBody target) + public void ThrowCollideInteraction(IEntity user, IEntity thrown, IEntity target, EntityCoordinates location) { - // TODO: Just pass in the bodies directly - var collideMsg = new ThrowCollideMessage(user, thrown.Entity, target.Entity); + var collideMsg = new ThrowCollideMessage(user, thrown, target, location); RaiseLocalEvent(collideMsg); if (collideMsg.Handled) { return; } - var eventArgs = new ThrowCollideEventArgs(user, thrown.Entity, target.Entity); + var eventArgs = new ThrowCollideEventArgs(user, thrown, target, location); - foreach (var comp in thrown.Entity.GetAllComponents()) + foreach (var comp in thrown.GetAllComponents().ToArray()) { - _throwCollide.Add(comp); + if (thrown.Deleted) break; + comp.DoHit(eventArgs); } - foreach (var collide in _throwCollide) + foreach (var comp in target.GetAllComponents().ToArray()) { - if (thrown.Entity.Deleted) break; - collide.DoHit(eventArgs); + if (target.Deleted) break; + comp.HitBy(eventArgs); } - - _throwCollide.Clear(); - - foreach (var comp in target.Entity.GetAllComponents()) - { - _throwCollide.Add(comp); - } - - foreach (var collide in _throwCollide) - { - if (target.Entity.Deleted) break; - collide.HitBy(eventArgs); - } - - _throwCollide.Clear(); } /// diff --git a/Content.Server/GameObjects/EntitySystems/ClimbSystem.cs b/Content.Server/GameObjects/EntitySystems/ClimbSystem.cs index 69bbc1b033..7036b5acae 100644 --- a/Content.Server/GameObjects/EntitySystems/ClimbSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/ClimbSystem.cs @@ -1,39 +1,18 @@ -using System.Collections.Generic; -using System.Linq; -using Content.Server.GameObjects.Components.Movement; -using Content.Shared.GameObjects.Components.Movement; -using Content.Shared.GameTicking; +using Content.Server.GameObjects.Components.Movement; using JetBrains.Annotations; using Robust.Shared.GameObjects; namespace Content.Server.GameObjects.EntitySystems { [UsedImplicitly] - internal sealed class ClimbSystem : EntitySystem, IResettingEntitySystem + internal sealed class ClimbSystem : EntitySystem { - private readonly HashSet _activeClimbers = new(); - - public void AddActiveClimber(ClimbingComponent climbingComponent) - { - _activeClimbers.Add(climbingComponent); - } - - public void RemoveActiveClimber(ClimbingComponent climbingComponent) - { - _activeClimbers.Remove(climbingComponent); - } - public override void Update(float frameTime) { - foreach (var climber in _activeClimbers.ToArray()) + foreach (var comp in ComponentManager.EntityQuery(true)) { - climber.Update(); + comp.Update(); } } - - public void Reset() - { - _activeClimbers.Clear(); - } } } diff --git a/Content.Server/GameObjects/EntitySystems/ConveyorSystem.cs b/Content.Server/GameObjects/EntitySystems/ConveyorSystem.cs new file mode 100644 index 0000000000..265606c1e0 --- /dev/null +++ b/Content.Server/GameObjects/EntitySystems/ConveyorSystem.cs @@ -0,0 +1,18 @@ +using Content.Server.GameObjects.Components.Conveyor; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; + +namespace Content.Server.GameObjects.EntitySystems +{ + [UsedImplicitly] + internal sealed class ConveyorSystem : EntitySystem + { + public override void Update(float frameTime) + { + foreach (var comp in ComponentManager.EntityQuery(true)) + { + comp.Update(frameTime); + } + } + } +} diff --git a/Content.Server/GameObjects/EntitySystems/HandsSystem.cs b/Content.Server/GameObjects/EntitySystems/HandsSystem.cs index b664c78547..8ee5925390 100644 --- a/Content.Server/GameObjects/EntitySystems/HandsSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/HandsSystem.cs @@ -1,11 +1,11 @@ using System; using System.Linq; using Content.Server.GameObjects.Components.GUI; -using Content.Server.GameObjects.Components.Items; using Content.Server.GameObjects.Components.Items.Storage; using Content.Server.GameObjects.Components.Stack; using Content.Server.GameObjects.EntitySystems.Click; using Content.Server.Interfaces.GameObjects.Components.Items; +using Content.Server.Throw; using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Input; using Content.Shared.Interfaces; @@ -144,12 +144,12 @@ namespace Content.Server.GameObjects.EntitySystems private bool HandleThrowItem(ICommonSession session, EntityCoordinates coords, EntityUid uid) { - var playerEnt = ((IPlayerSession)session).AttachedEntity; + var plyEnt = ((IPlayerSession)session).AttachedEntity; - if (playerEnt == null || !playerEnt.IsValid()) + if (plyEnt == null || !plyEnt.IsValid()) return false; - if (!playerEnt.TryGetComponent(out HandsComponent handsComp)) + if (!plyEnt.TryGetComponent(out HandsComponent handsComp)) return false; if (!handsComp.CanDrop(handsComp.ActiveHand)) @@ -168,19 +168,14 @@ namespace Content.Server.GameObjects.EntitySystems else { stackComp.Use(1); - throwEnt = throwEnt.EntityManager.SpawnEntity(throwEnt.Prototype.ID, playerEnt.Transform.Coordinates); + throwEnt = throwEnt.EntityManager.SpawnEntity(throwEnt.Prototype.ID, plyEnt.Transform.Coordinates); // can only throw one item at a time, regardless of what the prototype stack size is. if (throwEnt.TryGetComponent(out var newStackComp)) newStackComp.Count = 1; } - var direction = coords.ToMapPos(EntityManager) - playerEnt.Transform.WorldPosition; - if (direction == Vector2.Zero) return true; - - direction = direction.Normalized * MathF.Min(direction.Length, 8.0f); - - throwEnt.TryThrow(direction * ThrowForce * 15); + throwEnt.ThrowTo(ThrowForce, coords, plyEnt.Transform.Coordinates, false, plyEnt); return true; } diff --git a/Content.Server/Physics/Controllers/MoverController.cs b/Content.Server/GameObjects/EntitySystems/MoverSystem.cs similarity index 57% rename from Content.Server/Physics/Controllers/MoverController.cs rename to Content.Server/GameObjects/EntitySystems/MoverSystem.cs index 429d617959..5e9097f039 100644 --- a/Content.Server/Physics/Controllers/MoverController.cs +++ b/Content.Server/GameObjects/EntitySystems/MoverSystem.cs @@ -1,17 +1,15 @@ #nullable enable -using System.Collections.Generic; using Content.Server.GameObjects.Components.GUI; using Content.Server.GameObjects.Components.Items.Storage; using Content.Server.GameObjects.Components.Mobs; -using Content.Server.GameObjects.Components.Movement; using Content.Server.GameObjects.Components.Sound; using Content.Shared.Audio; using Content.Shared.GameObjects.Components.Inventory; using Content.Shared.GameObjects.Components.Movement; using Content.Shared.GameObjects.Components.Tag; +using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Maps; using Content.Shared.Physics; -using Content.Shared.Physics.Controllers; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Audio; @@ -19,15 +17,13 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Log; using Robust.Shared.Map; -using Robust.Shared.Maths; -using Robust.Shared.Physics; -using Robust.Shared.Physics.Dynamics; using Robust.Shared.Prototypes; using Robust.Shared.Random; -namespace Content.Server.Physics.Controllers +namespace Content.Server.GameObjects.EntitySystems { - public class MoverController : SharedMoverController + [UsedImplicitly] + internal class MoverSystem : SharedMoverSystem { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; @@ -39,83 +35,54 @@ namespace Content.Server.Physics.Controllers private const float StepSoundMoveDistanceRunning = 2; private const float StepSoundMoveDistanceWalking = 1.5f; - private HashSet _excludedMobs = new(); - + /// public override void Initialize() { base.Initialize(); - _audioSystem = EntitySystem.Get(); + SubscribeLocalEvent(PlayerDetached); + + _audioSystem = EntitySystemManager.GetEntitySystem(); + + UpdatesBefore.Add(typeof(PhysicsSystem)); } - public override void UpdateBeforeSolve(bool prediction, float frameTime) + public override void Update(float frameTime) { - base.UpdateBeforeSolve(prediction, frameTime); - _excludedMobs.Clear(); - - foreach (var (mobMover, mover, physics) in ComponentManager.EntityQuery()) + foreach (var (moverComponent, collidableComponent) in EntityManager.ComponentManager + .EntityQuery(false)) { - _excludedMobs.Add(mover.Owner.Uid); - HandleMobMovement(mover, physics, mobMover); - } - - foreach (var mover in ComponentManager.EntityQuery()) - { - _excludedMobs.Add(mover.Owner.Uid); - HandleShuttleMovement(mover); - } - - foreach (var (mover, physics) in ComponentManager.EntityQuery(true)) - { - if (_excludedMobs.Contains(mover.Owner.Uid)) continue; - - HandleKinematicMovement(mover, physics); + var entity = moverComponent.Owner; + UpdateKinematics(entity.Transform, moverComponent, collidableComponent); } } - /* - * Some thoughts: - * Unreal actually doesn't predict vehicle movement at all, it's purely server-side which I thought was interesting - * The reason for this is that vehicles change direction very slowly compared to players so you don't really have the requirement for quick movement anyway - * As such could probably just look at applying a force / impulse to the shuttle server-side only so it controls like the titanic. - */ - private void HandleShuttleMovement(ShuttleControllerComponent mover) + private void PlayerDetached(PlayerDetachedSystemMessage ev) { - var gridId = mover.Owner.Transform.GridID; - - if (!_mapManager.TryGetGrid(gridId, out var grid) || !EntityManager.TryGetEntity(grid.GridEntityId, out var gridEntity)) return; - - //TODO: Switch to shuttle component - if (!gridEntity.TryGetComponent(out PhysicsComponent? physics)) + if (ev.Entity.TryGetComponent(out IPhysicsComponent? physics) && + physics.TryGetController(out MoverController controller) && + !ev.Entity.IsWeightless()) { - physics = gridEntity.AddComponent(); - physics.BodyStatus = BodyStatus.InAir; - physics.Mass = 1; - physics.CanCollide = true; - physics.AddFixture(new Fixture(physics, new PhysShapeGrid(grid))); + controller.StopMoving(); } - - // TODO: Uhh this probably doesn't work but I still need to rip out the entity tree and make RenderingTreeSystem use grids so I'm not overly concerned about breaking shuttles. - physics.ApplyForce(mover.VelocityDir.walking + mover.VelocityDir.sprinting); - mover.VelocityDir = (Vector2.Zero, Vector2.Zero); } - protected override void HandleFootsteps(IMoverComponent mover, IMobMoverComponent mobMover) + protected override void HandleFootsteps(IMoverComponent mover) { var transform = mover.Owner.Transform; // Handle footsteps. - if (_mapManager.GridExists(mobMover.LastPosition.GetGridId(EntityManager))) + if (_mapManager.GridExists(mover.LastPosition.GetGridId(EntityManager))) { // Can happen when teleporting between grids. - if (!transform.Coordinates.TryDistance(EntityManager, mobMover.LastPosition, out var distance)) + if (!transform.Coordinates.TryDistance(EntityManager, mover.LastPosition, out var distance)) { - mobMover.LastPosition = transform.Coordinates; + mover.LastPosition = transform.Coordinates; return; } - mobMover.StepSoundDistance += distance; + mover.StepSoundDistance += distance; } - mobMover.LastPosition = transform.Coordinates; + mover.LastPosition = transform.Coordinates; float distanceNeeded; if (mover.Sprinting) { @@ -126,11 +93,11 @@ namespace Content.Server.Physics.Controllers distanceNeeded = StepSoundMoveDistanceWalking; } - if (mobMover.StepSoundDistance > distanceNeeded) + if (mover.StepSoundDistance > distanceNeeded) { - mobMover.StepSoundDistance = 0; + mover.StepSoundDistance = 0; - if (!mover.Owner.HasTag("FootstepSound") || mover.Owner.Transform.GridID == GridId.Invalid) + if (!mover.Owner.HasTag("FootstepSound")) { return; } @@ -192,6 +159,5 @@ namespace Content.Server.Physics.Controllers Logger.ErrorS("sound", $"Unable to find sound collection for {soundCollectionName}"); } } - } } diff --git a/Content.Server/GameObjects/EntitySystems/Power/PowerSolarSystem.cs b/Content.Server/GameObjects/EntitySystems/Power/PowerSolarSystem.cs index 862e9466af..fee28a0de7 100644 --- a/Content.Server/GameObjects/EntitySystems/Power/PowerSolarSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Power/PowerSolarSystem.cs @@ -8,7 +8,6 @@ using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Maths; using Robust.Shared.Physics; -using Robust.Shared.Physics.Broadphase; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -138,7 +137,7 @@ namespace Content.Server.GameObjects.EntitySystems // Determine if the solar panel is occluded, and zero out coverage if so. // FIXME: The "Opaque" collision group doesn't seem to work right now. var ray = new CollisionRay(entity.Transform.WorldPosition, TowardsSun.ToVec(), (int) CollisionGroup.Opaque); - var rayCastResults = EntitySystem.Get().IntersectRay(entity.Transform.MapID, ray, SunOcclusionCheckDistance, entity); + var rayCastResults = IoCManager.Resolve().IntersectRay(entity.Transform.MapID, ray, SunOcclusionCheckDistance, entity); if (rayCastResults.Any()) coverage = 0; } diff --git a/Content.Server/GameObjects/EntitySystems/RecyclerSystem.cs b/Content.Server/GameObjects/EntitySystems/RecyclerSystem.cs new file mode 100644 index 0000000000..22e5eb4c17 --- /dev/null +++ b/Content.Server/GameObjects/EntitySystems/RecyclerSystem.cs @@ -0,0 +1,18 @@ +using Content.Server.GameObjects.Components.Recycling; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; + +namespace Content.Server.GameObjects.EntitySystems +{ + [UsedImplicitly] + internal sealed class RecyclerSystem : EntitySystem + { + public override void Update(float frameTime) + { + foreach (var component in ComponentManager.EntityQuery(true)) + { + component.Update(frameTime); + } + } + } +} diff --git a/Content.Server/GameObjects/EntitySystems/SingularitySystem.cs b/Content.Server/GameObjects/EntitySystems/SingularitySystem.cs index bd29f6deff..d0983f55aa 100644 --- a/Content.Server/GameObjects/EntitySystems/SingularitySystem.cs +++ b/Content.Server/GameObjects/EntitySystems/SingularitySystem.cs @@ -7,21 +7,36 @@ namespace Content.Server.GameObjects.EntitySystems [UsedImplicitly] public class SingularitySystem : EntitySystem { - private float _accumulator; + private float curTimeSingulo; + private float curTimePull; public override void Update(float frameTime) { base.Update(frameTime); - _accumulator += frameTime; + curTimeSingulo += frameTime; + curTimePull += frameTime; - while (_accumulator > 1.0f) + var shouldUpdate = curTimeSingulo >= 1f; + var shouldPull = curTimePull >= 0.2f; + if (!shouldUpdate && !shouldPull) return; + var singulos = ComponentManager.EntityQuery(true); + + if (curTimeSingulo >= 1f) { - _accumulator -= 1.0f; - - foreach (var singularity in ComponentManager.EntityQuery()) + curTimeSingulo -= 1f; + foreach (var singulo in singulos) { - singularity.Update(1); + singulo.Update(); + } + } + + if (curTimePull >= 0.5f) + { + curTimePull -= 0.5f; + foreach (var singulo in singulos) + { + singulo.PullUpdate(); } } } diff --git a/Content.Server/Physics/Controllers/ConveyorController.cs b/Content.Server/Physics/Controllers/ConveyorController.cs deleted file mode 100644 index 88a53b6f18..0000000000 --- a/Content.Server/Physics/Controllers/ConveyorController.cs +++ /dev/null @@ -1,118 +0,0 @@ -#nullable enable -using System; -using System.Collections.Generic; -using Content.Server.GameObjects.Components.Conveyor; -using Content.Server.GameObjects.Components.Recycling; -using Content.Shared.GameObjects.Components.Movement; -using Robust.Shared.GameObjects; -using Robust.Shared.Maths; -using Robust.Shared.Physics; -using Robust.Shared.Physics.Controllers; - -namespace Content.Server.Physics.Controllers -{ - internal sealed class ConveyorController : VirtualController - { - public override List UpdatesAfter => new() {typeof(MoverController)}; - - public override void UpdateBeforeSolve(bool prediction, float frameTime) - { - base.UpdateBeforeSolve(prediction, frameTime); - foreach (var comp in ComponentManager.EntityQuery()) - { - Convey(comp, frameTime); - } - - // TODO: Uhh you can probably wrap the recycler's conveying properties into... conveyor - foreach (var comp in ComponentManager.EntityQuery()) - { - ConveyRecycler(comp, frameTime); - } - } - - private void Convey(ConveyorComponent comp, float frameTime) - { - // TODO: Use ICollideBehavior and cache intersecting - // Use an event for conveyors to know what needs to run - if (!comp.CanRun()) - { - return; - } - - var intersecting = EntityManager.GetEntitiesIntersecting(comp.Owner, true); - var direction = comp.GetAngle().ToVec(); - Vector2? ownerPos = null; - - foreach (var entity in intersecting) - { - if (!comp.CanMove(entity)) continue; - - if (!entity.TryGetComponent(out IPhysBody? physics) || physics.BodyStatus == BodyStatus.InAir || - entity.IsWeightless()) continue; - - ownerPos ??= comp.Owner.Transform.WorldPosition; - var itemRelativeToConveyor = entity.Transform.WorldPosition - ownerPos.Value; - - physics.LinearVelocity += Convey(direction * comp.Speed, frameTime, itemRelativeToConveyor); - } - } - - // TODO Uhhh I did a shit job plz fix smug - private Vector2 Convey(Vector2 velocityDirection, float frameTime, Vector2 itemRelativeToConveyor) - { - //gravitating item towards center - //http://csharphelper.com/blog/2016/09/find-the-shortest-distance-between-a-point-and-a-line-segment-in-c/ - Vector2 centerPoint; - - var t = 0f; - if (velocityDirection.Length > 0) // if velocitydirection is 0, this calculation will divide by 0 - { - t = Vector2.Dot(itemRelativeToConveyor, velocityDirection) / - Vector2.Dot(velocityDirection, velocityDirection); - } - - if (t < 0) - { - centerPoint = new Vector2(); - } - else if (t > 1) - { - centerPoint = velocityDirection; - } - else - { - centerPoint = velocityDirection * t; - } - - var delta = centerPoint - itemRelativeToConveyor; - return delta * (400 * delta.Length) * frameTime; - } - - private void ConveyRecycler(RecyclerComponent comp, float frameTime) - { - if (!comp.CanRun()) - { - comp.Intersecting.Clear(); - return; - } - - var direction = Vector2.UnitX; - Vector2? ownerPos = null; - - for (var i = comp.Intersecting.Count - 1; i >= 0; i--) - { - var entity = comp.Intersecting[i]; - - if (entity.Deleted || !comp.CanMove(entity) || !EntityManager.IsIntersecting(comp.Owner, entity)) - { - comp.Intersecting.RemoveAt(i); - continue; - } - - if (!entity.TryGetComponent(out IPhysBody? physics)) continue; - ownerPos ??= comp.Owner.Transform.WorldPosition; - physics.LinearVelocity += Convey(direction, frameTime, entity.Transform.WorldPosition - ownerPos.Value); - } - } - } -} diff --git a/Content.Server/Physics/Controllers/SingularityController.cs b/Content.Server/Physics/Controllers/SingularityController.cs deleted file mode 100644 index 9a0a6a1b86..0000000000 --- a/Content.Server/Physics/Controllers/SingularityController.cs +++ /dev/null @@ -1,106 +0,0 @@ -#nullable enable -using Content.Server.GameObjects.Components.Observer; -using Content.Server.GameObjects.Components.Singularity; -using Robust.Server.GameObjects; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Map; -using Robust.Shared.Maths; -using Robust.Shared.Physics; -using Robust.Shared.Physics.Broadphase; -using Robust.Shared.Physics.Controllers; -using Robust.Shared.Random; - -namespace Content.Server.Physics.Controllers -{ - internal sealed class SingularityController : VirtualController - { - [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly IRobustRandom _robustRandom = default!; - - private float _pullAccumulator; - private float _moveAccumulator; - - public override void UpdateBeforeSolve(bool prediction, float frameTime) - { - base.UpdateBeforeSolve(prediction, frameTime); - - _moveAccumulator += frameTime; - _pullAccumulator += frameTime; - - while (_pullAccumulator > 0.5f) - { - _pullAccumulator -= 0.5f; - - foreach (var singularity in ComponentManager.EntityQuery()) - { - // TODO: Use colliders instead probably yada yada - PullEntities(singularity); - // Yeah look the collision with station wasn't working and I'm 15k lines in and not debugging this shit - DestroyTiles(singularity); - } - } - - while (_moveAccumulator > 1.0f) - { - _moveAccumulator -= 1.0f; - - foreach (var (singularity, physics) in ComponentManager.EntityQuery()) - { - if (singularity.Owner.HasComponent()) continue; - - // TODO: Need to essentially use a push vector in a random direction for us PLUS - // Any entity colliding with our larger circlebox needs to have an impulse applied to itself. - physics.BodyStatus = BodyStatus.InAir; - MoveSingulo(singularity, physics); - } - } - } - - private void MoveSingulo(SingularityComponent singularity, PhysicsComponent physics) - { - if (singularity.Level <= 1) return; - // TODO: Could try gradual changes instead but for now just try to replicate - - var pushVector = new Vector2(_robustRandom.Next(-10, 10), _robustRandom.Next(-10, 10)); - - if (pushVector == Vector2.Zero) return; - - physics.LinearVelocity = Vector2.Zero; - physics.LinearVelocity = pushVector.Normalized * 2; - } - - private void PullEntities(SingularityComponent component) - { - var singularityCoords = component.Owner.Transform.Coordinates; - // TODO: Maybe if we have named fixtures needs to pull out the outer circle collider (inner will be for deleting). - var entitiesToPull = EntityManager.GetEntitiesInRange(singularityCoords, component.Level * 10); - foreach (var entity in entitiesToPull) - { - if (!entity.TryGetComponent(out var collidableComponent) || collidableComponent.BodyType == BodyType.Static) continue; - if (entity.HasComponent()) continue; - if (singularityCoords.EntityId != entity.Transform.Coordinates.EntityId) continue; - var vec = (singularityCoords - entity.Transform.Coordinates).Position; - if (vec == Vector2.Zero) continue; - - var speed = 10 / vec.Length * component.Level; - - collidableComponent.ApplyLinearImpulse(vec.Normalized * speed); - } - } - - private void DestroyTiles(SingularityComponent component) - { - if (!component.Owner.TryGetComponent(out PhysicsComponent? physicsComponent)) return; - var worldBox = physicsComponent.GetWorldAABB(); - - foreach (var grid in _mapManager.FindGridsIntersecting(component.Owner.Transform.MapID, worldBox)) - { - foreach (var tile in grid.GetTilesIntersecting(worldBox)) - { - grid.SetTile(tile.GridIndices, Tile.Empty); - } - } - } - } -} diff --git a/Content.Server/Throw/ThrowHelper.cs b/Content.Server/Throw/ThrowHelper.cs new file mode 100644 index 0000000000..ede0856ef6 --- /dev/null +++ b/Content.Server/Throw/ThrowHelper.cs @@ -0,0 +1,156 @@ +using System; +using Content.Server.GameObjects.Components.Projectiles; +using Content.Shared.GameObjects.Components.Movement; +using Content.Shared.GameObjects.EntitySystems.ActionBlocker; +using Content.Shared.Physics; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using Robust.Shared.Maths; +using Robust.Shared.Physics; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Server.Throw +{ + public static class ThrowHelper + { + /// + /// Throw an entity in the direction of from . + /// + /// The entity to throw. + /// + /// The force to throw the entity with. + /// Total impulse applied is equal to this force applied for one second. + /// + /// + /// The target location to throw at. + /// This is only used to calculate a direction, + /// actual distance is purely determined by . + /// + /// + /// The position to start the throw from. + /// + /// + /// If true, slightly spread the actual throw angle. + /// + /// + /// The entity that did the throwing. An opposite impulse will be applied to this entity if passed in. + /// + public static void Throw(this IEntity thrownEnt, float throwForce, EntityCoordinates targetLoc, EntityCoordinates sourceLoc, bool spread = false, IEntity throwSourceEnt = null) + { + if (thrownEnt.Deleted) + { + return; + } + + if (!thrownEnt.TryGetComponent(out IPhysicsComponent colComp)) + return; + + var entityManager = IoCManager.Resolve(); + var direction_vector = targetLoc.ToMapPos(entityManager) - sourceLoc.ToMapPos(entityManager); + + if (direction_vector.Length == 0) + { + return; + } + + colComp.CanCollide = true; + // I can now collide with player, so that i can do damage. + + if (!thrownEnt.TryGetComponent(out ThrownItemComponent projComp)) + { + projComp = thrownEnt.AddComponent(); + + if (colComp.PhysicsShapes.Count == 0) + colComp.PhysicsShapes.Add(new PhysShapeAabb()); + + colComp.PhysicsShapes[0].CollisionMask |= (int) CollisionGroup.ThrownItem; + colComp.Status = BodyStatus.InAir; + } + + var angle = new Angle(direction_vector); + if (spread) + { + var spreadRandom = IoCManager.Resolve(); + angle += Angle.FromDegrees(spreadRandom.NextGaussian(0, 3)); + } + + if (throwSourceEnt != null) + { + projComp.User = throwSourceEnt; + projComp.IgnoreEntity(throwSourceEnt); + + if (ActionBlockerSystem.CanChangeDirection(throwSourceEnt)) + { + throwSourceEnt.Transform.LocalRotation = (angle + MathHelper.PiOver2).GetCardinalDir().ToAngle(); + } + } + + // scaling is handled elsewhere, this is just multiplying by 60 independent of timing as a fix until elsewhere values are updated + var spd = throwForce * 60; + + projComp.StartThrow(angle.ToVec(), spd); + + if (throwSourceEnt != null && + throwSourceEnt.TryGetComponent(out var physics)) + { + if (throwSourceEnt.IsWeightless()) + { + // We don't check for surrounding entities, + // so you'll still get knocked around if you're hugging the station wall in zero g. + // I got kinda lazy is the reason why. Also it makes a bit of sense. + // If somebody wants they can come along and make it so magboots completely hold you still. + // Would be a cool incentive to use them. + const float throwFactor = 0.2f; // Break Newton's Third Law for better gameplay + var mover = physics.EnsureController(); + mover.Push(-angle.ToVec(), spd * throwFactor); + } + } + } + + /// + /// Throw an entity at the position of from , + /// without overshooting. + /// cl + /// The entity to throw. + /// + /// The MAXIMUM force to throw the entity with. + /// Throw force increases with distance to target, this is the maximum force allowed. + /// + /// + /// The target location to throw at. + /// This function will try to land at this exact spot, + /// if is large enough to allow for it to be reached. + /// + /// + /// The position to start the throw from. + /// + /// + /// If true, slightly spread the actual throw angle. + /// + /// + /// The entity that did the throwing. An opposite impulse will be applied to this entity if passed in. + /// + public static void ThrowTo(this IEntity thrownEnt, float throwForceMax, EntityCoordinates targetLoc, + EntityCoordinates sourceLoc, bool spread = false, IEntity throwSourceEnt = null) + { + var entityManager = IoCManager.Resolve(); + var timing = IoCManager.Resolve(); + + // Calculate the force necessary to land a throw based on throw duration, mass and distance. + if (!targetLoc.TryDistance(entityManager, sourceLoc, out var distance)) + { + return; + } + + var throwDuration = ThrownItemComponent.DefaultThrowTime; + // TODO: Mass isn't even used on the system side yet for controllers so do that someday + var velocityNecessary = distance / throwDuration; + var forceNecessary = velocityNecessary / timing.TickRate; + + // Then clamp it to the max force allowed and call Throw(). + thrownEnt.Throw(MathF.Min(forceNecessary, throwForceMax), targetLoc, sourceLoc, spread, throwSourceEnt); + } + } +} diff --git a/Content.Shared/CCVars.cs b/Content.Shared/CCVars.cs index be32a4f6d4..4ba36ccc3c 100644 --- a/Content.Shared/CCVars.cs +++ b/Content.Shared/CCVars.cs @@ -166,15 +166,6 @@ namespace Content.Shared public static readonly CVarDef ParallaxDebug = CVarDef.Create("parallax.debug", false, CVar.CLIENTONLY); - /* - * Physics - */ - - public static readonly CVarDef TileFrictionModifier = - CVarDef.Create("physics.tilefriction", 15.0f); - - public static readonly CVarDef StopSpeed = - CVarDef.Create("physics.stopspeed", 0.1f); /* * Ambience diff --git a/Content.Shared/Construction/ConstructionConditions/WallmountCondition.cs b/Content.Shared/Construction/ConstructionConditions/WallmountCondition.cs index 4fb163e149..80afe9976c 100644 --- a/Content.Shared/Construction/ConstructionConditions/WallmountCondition.cs +++ b/Content.Shared/Construction/ConstructionConditions/WallmountCondition.cs @@ -9,7 +9,6 @@ using Robust.Shared.Serialization; using System.Linq; using Robust.Shared.GameObjects; using Robust.Shared.Physics; -using Robust.Shared.Physics.Broadphase; namespace Content.Shared.Construction.ConstructionConditions { @@ -35,7 +34,7 @@ namespace Content.Shared.Construction.ConstructionConditions return false; // now we need to check that user actually tries to build wallmount on a wall - var physics = EntitySystem.Get(); + var physics = IoCManager.Resolve(); var rUserToObj = new CollisionRay(userWorldPosition, userToObject.Normalized, (int) CollisionGroup.Impassable); var length = userToObject.Length; var userToObjRaycastResults = physics.IntersectRayWithPredicate(user.Transform.MapID, rUserToObj, maxLength: length, diff --git a/Content.Shared/GameObjects/Components/Buckle/SharedBuckleComponent.cs b/Content.Shared/GameObjects/Components/Buckle/SharedBuckleComponent.cs index 3c5dc5ed36..8d84a62345 100644 --- a/Content.Shared/GameObjects/Components/Buckle/SharedBuckleComponent.cs +++ b/Content.Shared/GameObjects/Components/Buckle/SharedBuckleComponent.cs @@ -18,7 +18,7 @@ namespace Content.Shared.GameObjects.Components.Buckle public sealed override uint? NetID => ContentNetIDs.BUCKLE; - [ComponentDependency] protected readonly IPhysBody? Physics; + [ComponentDependency] protected readonly IPhysicsComponent? Physics; /// /// The range from which this entity can buckle to a . diff --git a/Content.Shared/GameObjects/Components/Disposal/SharedDisposalUnitComponent.cs b/Content.Shared/GameObjects/Components/Disposal/SharedDisposalUnitComponent.cs index 2b655beae6..e4899fe1b0 100644 --- a/Content.Shared/GameObjects/Components/Disposal/SharedDisposalUnitComponent.cs +++ b/Content.Shared/GameObjects/Components/Disposal/SharedDisposalUnitComponent.cs @@ -20,8 +20,8 @@ namespace Content.Shared.GameObjects.Components.Disposal [ViewVariables] public bool Anchored => - !Owner.TryGetComponent(out IPhysBody? physics) || - physics.BodyType == BodyType.Static; + !Owner.TryGetComponent(out IPhysicsComponent? physics) || + physics.Anchored; [Serializable, NetSerializable] public enum Visuals @@ -166,7 +166,7 @@ namespace Content.Shared.GameObjects.Components.Disposal if (!Anchored) return false; - if (!entity.TryGetComponent(out IPhysBody? physics) || + if (!entity.TryGetComponent(out IPhysicsComponent? physics) || !physics.CanCollide) { if (!(entity.TryGetComponent(out IMobStateComponent? damageState) && damageState.IsDead())) { diff --git a/Content.Shared/GameObjects/Components/Doors/SharedDoorComponent.cs b/Content.Shared/GameObjects/Components/Doors/SharedDoorComponent.cs index b9ddd6c6d4..bdfc58a0d3 100644 --- a/Content.Shared/GameObjects/Components/Doors/SharedDoorComponent.cs +++ b/Content.Shared/GameObjects/Components/Doors/SharedDoorComponent.cs @@ -19,7 +19,7 @@ namespace Content.Shared.GameObjects.Components.Doors protected readonly SharedAppearanceComponent? AppearanceComponent = null; [ComponentDependency] - protected readonly IPhysBody? PhysicsComponent = null; + protected readonly IPhysicsComponent? PhysicsComponent = null; [ViewVariables] private DoorState _state = DoorState.Closed; diff --git a/Content.Shared/GameObjects/Components/Mobs/SharedCombatModeComponent.cs b/Content.Shared/GameObjects/Components/Mobs/SharedCombatModeComponent.cs index 5d4988f92d..a40b5f315b 100644 --- a/Content.Shared/GameObjects/Components/Mobs/SharedCombatModeComponent.cs +++ b/Content.Shared/GameObjects/Components/Mobs/SharedCombatModeComponent.cs @@ -21,22 +21,8 @@ namespace Content.Shared.GameObjects.Components.Mobs get => _isInCombatMode; set { - if (_isInCombatMode == value) return; _isInCombatMode = value; Dirty(); - - // Regenerate physics contacts -> Can probably just selectively check - /* Still a bit jank so left disabled for now. - if (Owner.TryGetComponent(out PhysicsComponent? physicsComponent)) - { - if (value) - { - physicsComponent.WakeBody(); - } - - physicsComponent.RegenerateContacts(); - } - */ } } @@ -46,7 +32,6 @@ namespace Content.Shared.GameObjects.Components.Mobs get => _activeZone; set { - if (_activeZone == value) return; _activeZone = value; Dirty(); } diff --git a/Content.Shared/GameObjects/Components/Movement/IMobMoverComponent.cs b/Content.Shared/GameObjects/Components/Movement/IMobMoverComponent.cs deleted file mode 100644 index 378b4813f2..0000000000 --- a/Content.Shared/GameObjects/Components/Movement/IMobMoverComponent.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Robust.Shared.GameObjects; -using Robust.Shared.Map; - - -namespace Content.Shared.GameObjects.Components.Movement -{ - public interface IMobMoverComponent : IComponent - { - EntityCoordinates LastPosition { get; set; } - - public float StepSoundDistance { get; set; } - - float GrabRange { get; set; } - } -} diff --git a/Content.Shared/GameObjects/Components/Movement/IMoverComponent.cs b/Content.Shared/GameObjects/Components/Movement/IMoverComponent.cs index c0ecc99c9b..620a176899 100644 --- a/Content.Shared/GameObjects/Components/Movement/IMoverComponent.cs +++ b/Content.Shared/GameObjects/Components/Movement/IMoverComponent.cs @@ -19,6 +19,17 @@ namespace Content.Shared.GameObjects.Components.Movement /// float CurrentSprintSpeed { get; } + + /// + /// The movement speed (m/s) of the entity when it pushes off of a solid object in zero gravity. + /// + float CurrentPushSpeed { get; } + + /// + /// How far an entity can reach (in meters) to grab hold of a solid object in zero gravity. + /// + float GrabRange { get; } + /// /// Is the entity Sprinting (running)? /// @@ -29,6 +40,10 @@ namespace Content.Shared.GameObjects.Components.Movement /// (Vector2 walking, Vector2 sprinting) VelocityDir { get; } + EntityCoordinates LastPosition { get; set; } + + float StepSoundDistance { get; set; } + /// /// Toggles one of the four cardinal directions. Each of the four directions are /// composed into a single direction vector, . Enabling @@ -40,5 +55,6 @@ namespace Content.Shared.GameObjects.Components.Movement void SetVelocityDirection(Direction direction, ushort subTick, bool enabled); void SetSprinting(ushort subTick, bool walking); + } } diff --git a/Content.Shared/GameObjects/Components/Movement/SharedClimbingComponent.cs b/Content.Shared/GameObjects/Components/Movement/SharedClimbingComponent.cs index 96d4e3d1c3..626449b0ec 100644 --- a/Content.Shared/GameObjects/Components/Movement/SharedClimbingComponent.cs +++ b/Content.Shared/GameObjects/Components/Movement/SharedClimbingComponent.cs @@ -3,89 +3,64 @@ using System; using Content.Shared.GameObjects.EntitySystems.ActionBlocker; using Content.Shared.Physics; using Robust.Shared.GameObjects; +using Robust.Shared.Physics; using Robust.Shared.Serialization; -using Robust.Shared.ViewVariables; namespace Content.Shared.GameObjects.Components.Movement { - public abstract class SharedClimbingComponent : Component, IActionBlocker + public abstract class SharedClimbingComponent : Component, IActionBlocker, ICollideSpecial { public sealed override string Name => "Climbing"; public sealed override uint? NetID => ContentNetIDs.CLIMBING; - protected bool IsOnClimbableThisFrame + protected IPhysicsComponent? Body; + protected bool IsOnClimbableThisFrame; + + protected bool OwnerIsTransitioning { get { - if (Body == null) return false; - - foreach (var entity in Body.GetBodiesIntersecting()) + if (Body != null && Body.TryGetController(out var controller)) { - if ((entity.CollisionLayer & (int) CollisionGroup.VaultImpassable) != 0) return true; + return controller.IsActive; } return false; } } + public abstract bool IsClimbing { get; set; } + bool IActionBlocker.CanMove() => !OwnerIsTransitioning; + bool IActionBlocker.CanChangeDirection() => !OwnerIsTransitioning; - [ViewVariables] - protected virtual bool OwnerIsTransitioning { get; set; } - - [ComponentDependency] protected PhysicsComponent? Body; - - 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. - /// - protected const float BufferTime = 0.3f; - - public virtual bool IsClimbing + bool ICollideSpecial.PreventCollide(IPhysBody collided) { - get => _isClimbing; - set + if (((CollisionGroup)collided.CollisionLayer).HasFlag(CollisionGroup.VaultImpassable) && collided.Entity.HasComponent()) { - if (_isClimbing == value) return; - _isClimbing = value; - - ToggleVaultPassable(value); + IsOnClimbableThisFrame = true; + return IsClimbing; } + + return false; } - protected bool _isClimbing; - - // TODO: Layers need a re-work - private void ToggleVaultPassable(bool value) + public override void Initialize() { - // Hope the mob has one fixture - if (Body == null || Body.Deleted) return; + base.Initialize(); - foreach (var fixture in Body.Fixtures) - { - if (value) - { - fixture.CollisionMask &= ~(int) CollisionGroup.VaultImpassable; - } - else - { - fixture.CollisionMask |= (int) CollisionGroup.VaultImpassable; - } - } + Owner.TryGetComponent(out Body); } [Serializable, NetSerializable] protected sealed class ClimbModeComponentState : ComponentState { - public ClimbModeComponentState(bool climbing, bool isTransitioning) : base(ContentNetIDs.CLIMBING) + public ClimbModeComponentState(bool climbing) : base(ContentNetIDs.CLIMBING) { Climbing = climbing; - IsTransitioning = isTransitioning; } public bool Climbing { get; } - public bool IsTransitioning { get; } } } } diff --git a/Content.Shared/GameObjects/Components/Movement/SharedDummyInputMoverComponent.cs b/Content.Shared/GameObjects/Components/Movement/SharedDummyInputMoverComponent.cs index 45f377b322..91e82a958d 100644 --- a/Content.Shared/GameObjects/Components/Movement/SharedDummyInputMoverComponent.cs +++ b/Content.Shared/GameObjects/Components/Movement/SharedDummyInputMoverComponent.cs @@ -10,12 +10,14 @@ namespace Content.Shared.GameObjects.Components.Movement public class SharedDummyInputMoverComponent : Component, IMoverComponent { public override string Name => "DummyInputMover"; - public bool IgnorePaused => false; public float CurrentWalkSpeed => 0f; public float CurrentSprintSpeed => 0f; - + public float CurrentPushSpeed => 0f; + public float GrabRange => 0f; public bool Sprinting => false; public (Vector2 walking, Vector2 sprinting) VelocityDir => (Vector2.Zero, Vector2.Zero); + public EntityCoordinates LastPosition { get; set; } + public float StepSoundDistance { get; set; } public void SetVelocityDirection(Direction direction, ushort subTick, bool enabled) { diff --git a/Content.Shared/GameObjects/Components/Movement/SharedPlayerInputMoverComponent.cs b/Content.Shared/GameObjects/Components/Movement/SharedPlayerInputMoverComponent.cs index 7cbdcd77d0..4a6fa3a52d 100644 --- a/Content.Shared/GameObjects/Components/Movement/SharedPlayerInputMoverComponent.cs +++ b/Content.Shared/GameObjects/Components/Movement/SharedPlayerInputMoverComponent.cs @@ -5,6 +5,7 @@ using Robust.Shared.Configuration; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Log; +using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Physics; using Robust.Shared.Players; @@ -14,9 +15,7 @@ using Robust.Shared.ViewVariables; namespace Content.Shared.GameObjects.Components.Movement { - [RegisterComponent] - [ComponentReference(typeof(IMoverComponent))] - public class SharedPlayerInputMoverComponent : Component, IMoverComponent + public abstract class SharedPlayerInputMoverComponent : Component, IMoverComponent, ICollideSpecial { // This class has to be able to handle server TPS being lower than client FPS. // While still having perfectly responsive movement client side. @@ -40,10 +39,8 @@ namespace Content.Shared.GameObjects.Components.Movement [Dependency] private readonly IConfigurationManager _configurationManager = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; - [ComponentDependency] private readonly MovementSpeedModifierComponent? _movementSpeed = default!; - - public override string Name => "PlayerInputMover"; - public override uint? NetID => ContentNetIDs.PLAYER_INPUT_MOVER; + public sealed override string Name => "PlayerInputMover"; + public sealed override uint? NetID => ContentNetIDs.PLAYER_INPUT_MOVER; private GameTick _lastInputTick; private ushort _lastInputSubTick; @@ -52,19 +49,36 @@ namespace Content.Shared.GameObjects.Components.Movement private MoveButtons _heldMoveButtons = MoveButtons.None; - // Don't serialize because it probably shouldn't change and it's a waste. - public bool IgnorePaused + public float CurrentWalkSpeed { - get => _ignorePaused; - set => _ignorePaused = value; + get + { + if (Owner.TryGetComponent(out MovementSpeedModifierComponent? component)) + { + return component.CurrentWalkSpeed; + } + + return MovementSpeedModifierComponent.DefaultBaseWalkSpeed; + } } - private bool _ignorePaused; + public float CurrentSprintSpeed + { + get + { + if (Owner.TryGetComponent(out MovementSpeedModifierComponent? component)) + { + return component.CurrentSprintSpeed; + } - public float CurrentWalkSpeed => _movementSpeed?.CurrentWalkSpeed ?? MovementSpeedModifierComponent.DefaultBaseWalkSpeed; - - public float CurrentSprintSpeed => _movementSpeed?.CurrentSprintSpeed ?? MovementSpeedModifierComponent.DefaultBaseSprintSpeed; + return MovementSpeedModifierComponent.DefaultBaseSprintSpeed; + } + } + [ViewVariables(VVAccess.ReadWrite)] + public float CurrentPushSpeed => 5; + [ViewVariables(VVAccess.ReadWrite)] + public float GrabRange => 0.2f; public bool Sprinting => !HasFlag(_heldMoveButtons, MoveButtons.Walk); /// @@ -117,24 +131,27 @@ namespace Content.Shared.GameObjects.Components.Movement } } + public abstract EntityCoordinates LastPosition { get; set; } + public abstract float StepSoundDistance { get; set; } + /// /// Whether or not the player can move diagonally. /// [ViewVariables] public bool DiagonalMovementEnabled => _configurationManager.GetCVar(CCVars.GameDiagonalMovement); - public override void ExposeData(ObjectSerializer serializer) + /// + public override void OnAdd() { - base.ExposeData(serializer); - serializer.DataField(ref _ignorePaused, "ignorePaused", false); + // This component requires that the entity has a IPhysicsComponent. + if (!Owner.HasComponent()) + Logger.Error( + $"[ECS] {Owner.Prototype?.Name} - {nameof(SharedPlayerInputMoverComponent)} requires" + + $" {nameof(IPhysicsComponent)}. "); + + base.OnAdd(); } - /// - public override void Initialize() - { - base.Initialize(); - Owner.EnsureComponentWarn(); - } /// /// Toggles one of the four cardinal directions. Each of the four directions are @@ -249,6 +266,12 @@ namespace Content.Shared.GameObjects.Components.Movement return vec; } + bool ICollideSpecial.PreventCollide(IPhysBody collidedWith) + { + // Don't collide with other mobs + return collidedWith.Entity.HasComponent(); + } + [Serializable, NetSerializable] private sealed class MoverComponentState : ComponentState { diff --git a/Content.Shared/GameObjects/Components/Movement/SharedPlayerMobMoverComponent.cs b/Content.Shared/GameObjects/Components/Movement/SharedPlayerMobMoverComponent.cs deleted file mode 100644 index 6bb688a9ab..0000000000 --- a/Content.Shared/GameObjects/Components/Movement/SharedPlayerMobMoverComponent.cs +++ /dev/null @@ -1,100 +0,0 @@ -#nullable enable -using System; -using Content.Shared.GameObjects.Components.Body; -using Content.Shared.GameObjects.Components.Mobs; -using Robust.Shared.GameObjects; -using Robust.Shared.Map; -using Robust.Shared.Maths; -using Robust.Shared.Physics; -using Robust.Shared.Players; -using Robust.Shared.Serialization; -using Robust.Shared.ViewVariables; - -namespace Content.Shared.GameObjects.Components.Movement -{ - /// - /// The basic player mover with footsteps and grabbing - /// - [RegisterComponent] - [ComponentReference(typeof(IMobMoverComponent))] - public class SharedPlayerMobMoverComponent : Component, IMobMoverComponent, ICollideSpecial - { - public override string Name => "PlayerMobMover"; - public override uint? NetID => ContentNetIDs.PLAYER_MOB_MOVER; - - private float _stepSoundDistance; - private float _grabRange; - - [ViewVariables(VVAccess.ReadWrite)] - public EntityCoordinates LastPosition { get; set; } - - [ViewVariables(VVAccess.ReadWrite)] - public float StepSoundDistance - { - get => _stepSoundDistance; - set - { - if (MathHelper.CloseTo(_stepSoundDistance, value)) return; - _stepSoundDistance = value; - Dirty(); - } - } - - [ViewVariables(VVAccess.ReadWrite)] - public float GrabRange - { - get => _grabRange; - set - { - if (MathHelper.CloseTo(_grabRange, value)) return; - _grabRange = value; - Dirty(); - } - } - - public override void Initialize() - { - base.Initialize(); - if (!Owner.HasComponent()) - { - Owner.EnsureComponentWarn(); - } - } - - public override ComponentState GetComponentState(ICommonSession session) - { - return new PlayerMobMoverComponentState(StepSoundDistance, GrabRange); - } - - public override void HandleComponentState(ComponentState? curState, ComponentState? nextState) - { - base.HandleComponentState(curState, nextState); - if (curState is not PlayerMobMoverComponentState playerMoverState) return; - StepSoundDistance = playerMoverState.StepSoundDistance; - GrabRange = playerMoverState.GrabRange; - } - - bool ICollideSpecial.PreventCollide(IPhysBody collidedWith) - { - // Don't collide with other mobs - // unless they have combat mode on - return collidedWith.Entity.HasComponent(); /* && - (!Owner.TryGetComponent(out SharedCombatModeComponent? ownerCombat) || !ownerCombat.IsInCombatMode) && - (!collidedWith.Entity.TryGetComponent(out SharedCombatModeComponent? otherCombat) || !otherCombat.IsInCombatMode); - */ - } - - [Serializable, NetSerializable] - private sealed class PlayerMobMoverComponentState : ComponentState - { - public float StepSoundDistance; - public float GrabRange; - - public PlayerMobMoverComponentState(float stepSoundDistance, float grabRange) : base(ContentNetIDs.PLAYER_MOB_MOVER) - { - StepSoundDistance = stepSoundDistance; - GrabRange = grabRange; - } - } - } -} diff --git a/Content.Shared/GameObjects/Components/Movement/SharedSlipperyComponent.cs b/Content.Shared/GameObjects/Components/Movement/SharedSlipperyComponent.cs index bac177ac89..d8faed5fa3 100644 --- a/Content.Shared/GameObjects/Components/Movement/SharedSlipperyComponent.cs +++ b/Content.Shared/GameObjects/Components/Movement/SharedSlipperyComponent.cs @@ -3,12 +3,10 @@ using System; using System.Collections.Generic; using System.Linq; using Content.Shared.GameObjects.Components.Mobs; -using Content.Shared.GameObjects.EntitySystems.ActionBlocker; using Content.Shared.GameObjects.EntitySystems.EffectBlocker; using Content.Shared.Physics; using Robust.Shared.Containers; using Robust.Shared.GameObjects; -using Robust.Shared.Physics; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -55,12 +53,14 @@ namespace Content.Shared.GameObjects.Components.Movement [ViewVariables(VVAccess.ReadWrite)] public virtual bool Slippery { get; set; } - private bool TrySlip(IPhysBody ourBody, IPhysBody otherBody) + private bool TrySlip(IEntity entity) { if (!Slippery || Owner.IsInContainer() - || _slipped.Contains(otherBody.Entity.Uid) - || !otherBody.Entity.TryGetComponent(out SharedStunnableComponent? stun)) + || _slipped.Contains(entity.Uid) + || !entity.TryGetComponent(out SharedStunnableComponent? stun) + || !entity.TryGetComponent(out IPhysicsComponent? otherBody) + || !Owner.TryGetComponent(out IPhysicsComponent? body)) { return false; } @@ -70,22 +70,26 @@ namespace Content.Shared.GameObjects.Components.Movement return false; } - var percentage = otherBody.GetWorldAABB().IntersectPercentage(ourBody.GetWorldAABB()); + var percentage = otherBody.WorldAABB.IntersectPercentage(body.WorldAABB); if (percentage < IntersectPercentage) { return false; } - if (!EffectBlockerSystem.CanSlip(otherBody.Entity)) + if (!EffectBlockerSystem.CanSlip(entity)) { return false; } - otherBody.LinearVelocity *= LaunchForwardsMultiplier; + if (entity.TryGetComponent(out IPhysicsComponent? physics)) + { + var controller = physics.EnsureController(); + controller.LinearVelocity = physics.LinearVelocity * LaunchForwardsMultiplier; + } stun.Paralyze(5); - _slipped.Add(otherBody.Entity.Uid); + _slipped.Add(entity.Uid); OnSlip(); @@ -94,9 +98,9 @@ namespace Content.Shared.GameObjects.Components.Movement protected virtual void OnSlip() { } - public void CollideWith(IPhysBody ourBody, IPhysBody otherBody) + public void CollideWith(IEntity collidedWith) { - TrySlip(ourBody, otherBody); + TrySlip(collidedWith); } public void Update() @@ -110,10 +114,10 @@ namespace Content.Shared.GameObjects.Components.Movement } var entity = Owner.EntityManager.GetEntity(uid); - var physics = Owner.GetComponent(); - var otherPhysics = entity.GetComponent(); + var physics = Owner.GetComponent(); + var otherPhysics = entity.GetComponent(); - if (!physics.GetWorldAABB().Intersects(otherPhysics.GetWorldAABB())) + if (!physics.WorldAABB.Intersects(otherPhysics.WorldAABB)) { _slipped.Remove(uid); } @@ -128,12 +132,12 @@ namespace Content.Shared.GameObjects.Components.Movement physics.Hard = false; - var fixtures = physics.Fixtures.FirstOrDefault(); + var shape = physics.PhysicsShapes.FirstOrDefault(); - if (fixtures != null) + if (shape != null) { - fixtures.CollisionLayer |= (int) CollisionGroup.SmallImpassable; - fixtures.CollisionMask = (int) CollisionGroup.None; + shape.CollisionLayer |= (int) CollisionGroup.SmallImpassable; + shape.CollisionMask = (int) CollisionGroup.None; } } diff --git a/Content.Shared/GameObjects/Components/Movement/TileFrictionModifier.cs b/Content.Shared/GameObjects/Components/Movement/TileFrictionModifier.cs deleted file mode 100644 index a8249f3638..0000000000 --- a/Content.Shared/GameObjects/Components/Movement/TileFrictionModifier.cs +++ /dev/null @@ -1,62 +0,0 @@ -#nullable enable -using System; -using Robust.Shared.GameObjects; -using Robust.Shared.Maths; -using Robust.Shared.Players; -using Robust.Shared.Serialization; -using Robust.Shared.ViewVariables; - -namespace Content.Shared.GameObjects.Components.Movement -{ - [RegisterComponent] - public class SharedTileFrictionModifier : Component - { - public override string Name => "TileFrictionModifier"; - - /// - /// Multiply the tilefriction cvar by this to get the body's actual tilefriction. - /// - [ViewVariables(VVAccess.ReadWrite)] - public float Modifier - { - get => _modifier; - set - { - if (MathHelper.CloseTo(_modifier, value)) return; - - _modifier = value; - } - } - - private float _modifier; - - public override void ExposeData(ObjectSerializer serializer) - { - base.ExposeData(serializer); - serializer.DataField(this, x => x.Modifier, "modifier", 1.0f); - } - - public override ComponentState GetComponentState(ICommonSession session) - { - return new TileFrictionComponentState(_modifier); - } - - public override void HandleComponentState(ComponentState? curState, ComponentState? nextState) - { - base.HandleComponentState(curState, nextState); - if (curState is not TileFrictionComponentState tileState) return; - _modifier = tileState.Modifier; - } - - [NetSerializable, Serializable] - protected class TileFrictionComponentState : ComponentState - { - public float Modifier; - - public TileFrictionComponentState(float modifier) : base(ContentNetIDs.TILE_FRICTION) - { - Modifier = modifier; - } - } - } -} diff --git a/Content.Shared/GameObjects/Components/Portal/SharedPortalComponent.cs b/Content.Shared/GameObjects/Components/Portal/SharedPortalComponent.cs index bd6ae67bd6..720fef70a4 100644 --- a/Content.Shared/GameObjects/Components/Portal/SharedPortalComponent.cs +++ b/Content.Shared/GameObjects/Components/Portal/SharedPortalComponent.cs @@ -1,7 +1,6 @@ #nullable enable using System; using Robust.Shared.GameObjects; -using Robust.Shared.Physics; using Robust.Shared.Serialization; namespace Content.Shared.GameObjects.Components.Portal @@ -14,7 +13,7 @@ namespace Content.Shared.GameObjects.Components.Portal { base.OnAdd(); - if (Owner.TryGetComponent(out var physics)) + if (Owner.TryGetComponent(out var physics)) { physics.Hard = false; } diff --git a/Content.Shared/GameObjects/Components/Projectiles/SharedProjectileComponent.cs b/Content.Shared/GameObjects/Components/Projectiles/SharedProjectileComponent.cs index 82ecff0ff7..6804f756b6 100644 --- a/Content.Shared/GameObjects/Components/Projectiles/SharedProjectileComponent.cs +++ b/Content.Shared/GameObjects/Components/Projectiles/SharedProjectileComponent.cs @@ -19,8 +19,6 @@ namespace Content.Shared.GameObjects.Components.Projectiles get => _ignoreShooter; set { - if (_ignoreShooter == value) return; - _ignoreShooter = value; Dirty(); } diff --git a/Content.Shared/GameObjects/Components/Pulling/SharedPullableComponent.cs b/Content.Shared/GameObjects/Components/Pulling/SharedPullableComponent.cs index e428894684..2574cea788 100644 --- a/Content.Shared/GameObjects/Components/Pulling/SharedPullableComponent.cs +++ b/Content.Shared/GameObjects/Components/Pulling/SharedPullableComponent.cs @@ -11,7 +11,6 @@ using Robust.Shared.Log; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Players; -using Robust.Shared.Physics.Dynamics.Joints; using Robust.Shared.Serialization; namespace Content.Shared.GameObjects.Components.Pulling @@ -21,16 +20,14 @@ namespace Content.Shared.GameObjects.Components.Pulling public override string Name => "Pullable"; public override uint? NetID => ContentNetIDs.PULLABLE; - [ComponentDependency] private readonly PhysicsComponent? _physics = default!; + [ComponentDependency] private readonly IPhysicsComponent? _physics = default!; /// /// Only set in Puller->set! Only set in unison with _pullerPhysics! /// private IEntity? _puller; - private IPhysBody? _pullerPhysics; - public IPhysBody? PullerPhysics => _pullerPhysics; - - private DistanceJoint? _pullJoint = null; + private IPhysicsComponent? _pullerPhysics; + public IPhysicsComponent? PullerPhysics => _pullerPhysics; /// /// The current entity pulling this component. @@ -65,6 +62,7 @@ namespace Content.Shared.GameObjects.Components.Pulling oldPuller.EntityManager.EventBus.RaiseEvent(EventSource.Local, message); _physics.WakeBody(); + _physics.TryRemoveController(); } // else-branch warning is handled below } @@ -72,7 +70,7 @@ namespace Content.Shared.GameObjects.Components.Pulling // Now that is settled, prepare to be pulled by a new object. if (_physics == null) { - Logger.WarningS("c.go.c.pulling", "Well now you've done it, haven't you? SharedPullableComponent on {0} didn't have an IPhysBody.", Owner); + Logger.WarningS("c.go.c.pulling", "Well now you've done it, haven't you? SharedPullableComponent on {0} didn't have an IPhysicsComponent.", Owner); return; } @@ -85,7 +83,7 @@ namespace Content.Shared.GameObjects.Components.Pulling return; } - if (!value.TryGetComponent(out var pullerPhysics)) + if (!value.TryGetComponent(out var valuePhysics)) { return; } @@ -115,7 +113,7 @@ namespace Content.Shared.GameObjects.Components.Pulling // Continue with pulling process. - var pullAttempt = new PullAttemptMessage(pullerPhysics, _physics); + var pullAttempt = new PullAttemptMessage(valuePhysics, _physics); value.SendMessage(null, pullAttempt); @@ -135,8 +133,9 @@ namespace Content.Shared.GameObjects.Components.Pulling _puller = value; Dirty(); - _pullerPhysics = pullerPhysics; + _pullerPhysics = valuePhysics; + _physics.EnsureController().Manager = this; var message = new PullStartedMessage(_pullerPhysics, _physics); _puller.SendMessage(null, message); @@ -144,13 +143,7 @@ namespace Content.Shared.GameObjects.Components.Pulling _puller.EntityManager.EventBus.RaiseEvent(EventSource.Local, message); - _physics.WakeBody(); - _pullJoint = pullerPhysics.CreateDistanceJoint(_physics); - // _physics.BodyType = BodyType.Kinematic; // TODO: Need to consider their original bodytype - _pullJoint.CollideConnected = true; - _pullJoint.Length = 1.4f; - _pullJoint.MaxLength = 2.0f; // TODO hacky, we should consider ours and their bb } // Code here will not run if pulling a new object was attempted and failed because of the returns from the refactor. } @@ -219,12 +212,6 @@ namespace Content.Shared.GameObjects.Components.Pulling return false; } - if (_physics != null && _pullJoint != null) - { - _physics.RemoveJoint(_pullJoint); - } - - _pullJoint = null; Puller = null; return true; } @@ -259,16 +246,12 @@ namespace Content.Shared.GameObjects.Components.Pulling return false; } - /* if (!_physics.TryGetController(out PullController controller)) { return false; } - */ - return true; - - //return controller.TryMoveTo(Puller.Transform.Coordinates, to); + return controller.TryMoveTo(Puller.Transform.Coordinates, to); } public override ComponentState GetComponentState(ICommonSession player) diff --git a/Content.Shared/GameObjects/ContentNetIDs.cs b/Content.Shared/GameObjects/ContentNetIDs.cs index 4094687206..122f688364 100644 --- a/Content.Shared/GameObjects/ContentNetIDs.cs +++ b/Content.Shared/GameObjects/ContentNetIDs.cs @@ -14,8 +14,8 @@ namespace Content.Shared.GameObjects public const uint STORAGE = 1005; public const uint INVENTORY = 1006; public const uint POWER_DEBUG_TOOL = 1007; - public const uint PLAYER_MOB_MOVER = 1008; - public const uint TILE_FRICTION = 1009; + // 1008 + // 1009 public const uint RANGED_WEAPON = 1010; public const uint CAMERA_RECOIL = 1011; public const uint SOUND = 1012; @@ -60,7 +60,7 @@ namespace Content.Shared.GameObjects public const uint FLASHABLE = 1051; public const uint BUCKLE = 1052; public const uint PROJECTILE = 1053; - // 1054 + public const uint THROWN_ITEM = 1054; public const uint STRAP = 1055; public const uint DISPOSABLE = 1056; public const uint GAS_ANALYZER = 1057; diff --git a/Content.Shared/GameObjects/EntitySystems/SharedInteractionSystem.cs b/Content.Shared/GameObjects/EntitySystems/SharedInteractionSystem.cs index 6773cb51b3..5c7fe3c85f 100644 --- a/Content.Shared/GameObjects/EntitySystems/SharedInteractionSystem.cs +++ b/Content.Shared/GameObjects/EntitySystems/SharedInteractionSystem.cs @@ -9,7 +9,6 @@ using Robust.Shared.Localization; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Physics; -using Robust.Shared.Physics.Broadphase; namespace Content.Shared.GameObjects.EntitySystems { @@ -19,6 +18,8 @@ namespace Content.Shared.GameObjects.EntitySystems [UsedImplicitly] public class SharedInteractionSystem : EntitySystem { + [Dependency] private readonly IPhysicsManager _physicsManager = default!; + public const float InteractionRange = 2; public const float InteractionRangeSquared = InteractionRange * InteractionRange; @@ -48,7 +49,7 @@ namespace Content.Shared.GameObjects.EntitySystems predicate ??= _ => false; var ray = new CollisionRay(origin.Position, dir.Normalized, collisionMask); - var rayResults = Get().IntersectRayWithPredicate(origin.MapId, ray, dir.Length, predicate.Invoke, false).ToList(); + var rayResults = _physicsManager.IntersectRayWithPredicate(origin.MapId, ray, dir.Length, predicate.Invoke, false).ToList(); if (rayResults.Count == 0) return dir.Length; return (rayResults[0].HitPos - origin.Position).Length; @@ -124,7 +125,7 @@ namespace Content.Shared.GameObjects.EntitySystems predicate ??= _ => false; var ray = new CollisionRay(origin.Position, dir.Normalized, (int) collisionMask); - var rayResults = Get().IntersectRayWithPredicate(origin.MapId, ray, dir.Length, predicate.Invoke, false).ToList(); + var rayResults = _physicsManager.IntersectRayWithPredicate(origin.MapId, ray, dir.Length, predicate.Invoke, false).ToList(); if (rayResults.Count == 0) return true; @@ -132,12 +133,12 @@ namespace Content.Shared.GameObjects.EntitySystems foreach (var result in rayResults) { - if (!result.HitEntity.TryGetComponent(out IPhysBody p)) + if (!result.HitEntity.TryGetComponent(out IPhysicsComponent p)) { continue; } - var bBox = p.GetWorldAABB(); + var bBox = p.WorldAABB; if (bBox.Contains(origin.Position) || bBox.Contains(other.Position)) { diff --git a/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs b/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs index 8b82552545..4bb523b0a1 100644 --- a/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs +++ b/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs @@ -1,11 +1,10 @@ #nullable enable using System.Diagnostics.CodeAnalysis; -using Content.Shared.GameObjects.Components.Mobs.State; +using Content.Shared.GameObjects.Components.Items; using Content.Shared.GameObjects.Components.Movement; using Content.Shared.GameObjects.EntitySystems.ActionBlocker; using Content.Shared.Physics; using Content.Shared.Physics.Pull; -using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.Input; using Robust.Shared.Input.Binding; @@ -16,11 +15,11 @@ using Robust.Shared.Players; namespace Content.Shared.GameObjects.EntitySystems { - /// - /// Handles converting inputs into movement. - /// - public sealed class SharedMoverSystem : EntitySystem + public abstract class SharedMoverSystem : EntitySystem { + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] protected readonly IPhysicsManager PhysicsManager = default!; + public override void Initialize() { base.Initialize(); @@ -46,9 +45,109 @@ namespace Content.Shared.GameObjects.EntitySystems base.Shutdown(); } + //TODO: reorganize this to make more logical sense + protected void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, IPhysicsComponent physics) + { + physics.EnsureController(); + + var weightless = transform.Owner.IsWeightless(); + + if (weightless) + { + // No gravity: is our entity touching anything? + var touching = IsAroundCollider(transform, mover, physics); + + if (!touching) + { + transform.LocalRotation = physics.LinearVelocity.GetDir().ToAngle(); + return; + } + } + + // TODO: movement check. + var (walkDir, sprintDir) = mover.VelocityDir; + var combined = walkDir + sprintDir; + if (combined.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner) && !weightless) + { + if (physics.TryGetController(out MoverController controller)) + { + controller.StopMoving(); + } + } + else if (ActionBlockerSystem.CanMove(mover.Owner)) + { + if (weightless) + { + if (physics.TryGetController(out MoverController controller)) + { + controller.Push(combined, mover.CurrentPushSpeed); + } + + transform.LocalRotation = physics.LinearVelocity.GetDir().ToAngle(); + return; + } + + var total = walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed; + + { + if (physics.TryGetController(out MoverController controller)) + { + controller.Move(total, 1); + } + } + + transform.LocalRotation = total.GetDir().ToAngle(); + + HandleFootsteps(mover); + } + } + + protected virtual void HandleFootsteps(IMoverComponent mover) + { + + } + + private bool IsAroundCollider(ITransformComponent transform, IMoverComponent mover, + IPhysicsComponent collider) + { + foreach (var entity in _entityManager.GetEntitiesInRange(transform.Owner, mover.GrabRange, true)) + { + if (entity == transform.Owner) + { + continue; // Don't try to push off of yourself! + } + + if (!entity.TryGetComponent(out var otherCollider) || + !otherCollider.CanCollide || + (collider.CollisionMask & otherCollider.CollisionLayer) == 0) + { + continue; + } + + // Don't count pulled entities + if (otherCollider.HasController()) + { + continue; + } + + // TODO: Item check. + var touching = ((collider.CollisionMask & otherCollider.CollisionLayer) != 0x0 + || (otherCollider.CollisionMask & collider.CollisionLayer) != 0x0) // Ensure collision + && !entity.HasComponent(); // This can't be an item + + if (touching) + { + return true; + } + } + + return false; + } + + private static void HandleDirChange(ICommonSession? session, Direction dir, ushort subTick, bool state) { - if (!TryGetAttachedComponent(session, out var moverComp)) + if (!TryGetAttachedComponent(session, out var moverComp)) return; var owner = session?.AttachedEntity; @@ -59,15 +158,6 @@ namespace Content.Shared.GameObjects.EntitySystems { comp.MoveInputPressed(session); } - - // For stuff like "Moving out of locker" or the likes - if (owner.IsInContainer() && - (!owner.TryGetComponent(out IMobStateComponent? mobState) || - mobState.IsAlive())) - { - var relayEntityMoveMessage = new RelayMovementEntityMessage(owner); - owner.Transform.Parent!.Owner.SendMessage(owner.Transform, relayEntityMoveMessage); - } } moverComp.SetVelocityDirection(dir, subTick, state); diff --git a/Content.Shared/GameObjects/EntitySystems/SharedPullingSystem.cs b/Content.Shared/GameObjects/EntitySystems/SharedPullingSystem.cs index f7212935ce..a692b51edb 100644 --- a/Content.Shared/GameObjects/EntitySystems/SharedPullingSystem.cs +++ b/Content.Shared/GameObjects/EntitySystems/SharedPullingSystem.cs @@ -8,7 +8,6 @@ using JetBrains.Annotations; using Robust.Shared.GameObjects; using Robust.Shared.Input.Binding; using Robust.Shared.Map; -using Robust.Shared.Physics; using Robust.Shared.Players; namespace Content.Shared.GameObjects.EntitySystems @@ -59,7 +58,7 @@ namespace Content.Shared.GameObjects.EntitySystems return; } - if (!pulled.TryGetComponent(out IPhysBody? physics)) + if (!pulled.TryGetComponent(out IPhysicsComponent? physics)) { return; } diff --git a/Content.Shared/Interfaces/GameObjects/Components/Interaction/IThrowCollide.cs b/Content.Shared/Interfaces/GameObjects/Components/Interaction/IThrowCollide.cs index da811afe2d..d2392384e6 100644 --- a/Content.Shared/Interfaces/GameObjects/Components/Interaction/IThrowCollide.cs +++ b/Content.Shared/Interfaces/GameObjects/Components/Interaction/IThrowCollide.cs @@ -18,7 +18,7 @@ namespace Content.Shared.Interfaces.GameObjects.Components /// /// The entity that threw and hit . /// - public IEntity? User { get; } + public IEntity User { get; } /// /// The entity thrown by that hit @@ -29,12 +29,14 @@ namespace Content.Shared.Interfaces.GameObjects.Components /// The entity hit with by /// public IEntity Target { get; } + public EntityCoordinates Location { get; } - public ThrowCollideEventArgs(IEntity? user, IEntity thrown, IEntity target) + public ThrowCollideEventArgs(IEntity user, IEntity thrown, IEntity target, EntityCoordinates location) { User = user; Thrown = thrown; Target = target; + Location = location; } } @@ -48,7 +50,7 @@ namespace Content.Shared.Interfaces.GameObjects.Components /// /// The entity that threw . /// - public IEntity? User { get; } + public IEntity User { get; } /// /// The entity thrown by that hit @@ -59,12 +61,14 @@ namespace Content.Shared.Interfaces.GameObjects.Components /// The entity hit with by /// public IEntity Target { get; } + public EntityCoordinates Location { get; } - public ThrowCollideMessage(IEntity? user, IEntity thrown, IEntity target) + public ThrowCollideMessage(IEntity user, IEntity thrown, IEntity target, EntityCoordinates location) { User = user; Thrown = thrown; Target = target; + Location = location; } } } diff --git a/Content.Shared/Maps/TurfHelpers.cs b/Content.Shared/Maps/TurfHelpers.cs index 6451324b7d..379bfc2deb 100644 --- a/Content.Shared/Maps/TurfHelpers.cs +++ b/Content.Shared/Maps/TurfHelpers.cs @@ -10,7 +10,6 @@ using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Physics; -using Robust.Shared.Physics.Broadphase; namespace Content.Shared.Maps { @@ -182,7 +181,7 @@ namespace Content.Shared.Maps /// public static bool IsBlockedTurf(this TileRef turf, bool filterMobs) { - var physics = EntitySystem.Get(); + var physics = IoCManager.Resolve(); var worldBox = GetWorldTileBox(turf); diff --git a/Content.Shared/Physics/BulletController.cs b/Content.Shared/Physics/BulletController.cs new file mode 100644 index 0000000000..c54fc53553 --- /dev/null +++ b/Content.Shared/Physics/BulletController.cs @@ -0,0 +1,17 @@ +#nullable enable +using Robust.Shared.GameObjects; +using Robust.Shared.Maths; +using Robust.Shared.Physics; + +namespace Content.Shared.Physics +{ + public class BulletController : VirtualController + { + public override IPhysicsComponent? ControlledComponent { protected get; set; } + + public void Push(Vector2 velocityDirection, float speed) + { + LinearVelocity = velocityDirection * speed; + } + } +} diff --git a/Content.Shared/Physics/ClimbController.cs b/Content.Shared/Physics/ClimbController.cs new file mode 100644 index 0000000000..a61be77317 --- /dev/null +++ b/Content.Shared/Physics/ClimbController.cs @@ -0,0 +1,89 @@ +#nullable enable +using Robust.Shared.Maths; +using Robust.Shared.Physics; + +namespace Content.Shared.Physics +{ + /// + /// 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. + /// + public class ClimbController : VirtualController + { + private Vector2? _movingTo = null; + private Vector2 _lastKnownPosition = default; + private int _numTicksBlocked = 0; + + /// + /// If 5 ticks have passed and our position has not changed then something is blocking us. + /// + public bool IsBlocked => _numTicksBlocked > 5 || _isMovingWrongDirection; + + /// + /// If the controller is currently moving the player somewhere, it is considered active. + /// + 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; + } + + ControlledComponent.WakeBody(); + + 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.1f) + { + _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; + } + } + } +} diff --git a/Content.Shared/Physics/CollisionGroup.cs b/Content.Shared/Physics/CollisionGroup.cs index 03be6c1fe9..1916e72dea 100644 --- a/Content.Shared/Physics/CollisionGroup.cs +++ b/Content.Shared/Physics/CollisionGroup.cs @@ -2,7 +2,6 @@ using System; using JetBrains.Annotations; using Robust.Shared.Map; -using Robust.Shared.Physics.Dynamics; using Robust.Shared.Serialization; using RobustPhysics = Robust.Shared.Physics; @@ -12,7 +11,7 @@ namespace Content.Shared.Physics /// Defined collision groups for the physics system. /// [Flags, PublicAPI] - [FlagsFor(typeof(CollisionLayer)), FlagsFor(typeof(CollisionMask))] + [FlagsFor(typeof(RobustPhysics.CollisionLayer)), FlagsFor(typeof(RobustPhysics.CollisionMask))] public enum CollisionGroup { None = 0, diff --git a/Content.Shared/Physics/ContainmentFieldCollisionController.cs b/Content.Shared/Physics/ContainmentFieldCollisionController.cs new file mode 100644 index 0000000000..a9de254beb --- /dev/null +++ b/Content.Shared/Physics/ContainmentFieldCollisionController.cs @@ -0,0 +1,10 @@ +#nullable enable +using Robust.Shared.Physics; + +namespace Content.Shared.Physics +{ + public class ContainmentFieldCollisionController : VirtualController + { + + } +} diff --git a/Content.Shared/Physics/ContainmentFieldRepellController.cs b/Content.Shared/Physics/ContainmentFieldRepellController.cs new file mode 100644 index 0000000000..c878bf6f53 --- /dev/null +++ b/Content.Shared/Physics/ContainmentFieldRepellController.cs @@ -0,0 +1,13 @@ +#nullable enable +using Robust.Shared.Maths; + +namespace Content.Shared.Physics +{ + public class ContainmentFieldRepellController : FrictionController + { + public void Repell(Direction dir, float speed) + { + LinearVelocity = dir.ToVec() * speed; + } + } +} diff --git a/Content.Shared/Physics/Controllers/SharedMoverController.cs b/Content.Shared/Physics/Controllers/SharedMoverController.cs deleted file mode 100644 index 17eb9e8f58..0000000000 --- a/Content.Shared/Physics/Controllers/SharedMoverController.cs +++ /dev/null @@ -1,142 +0,0 @@ -#nullable enable -using Content.Shared.GameObjects.Components.Mobs.State; -using Content.Shared.GameObjects.Components.Movement; -using Content.Shared.GameObjects.Components.Pulling; -using Content.Shared.GameObjects.EntitySystems.ActionBlocker; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Maths; -using Robust.Shared.Physics; -using Robust.Shared.Physics.Broadphase; -using Robust.Shared.Physics.Controllers; - -namespace Content.Shared.Physics.Controllers -{ - /// - /// Handles player and NPC mob movement. - /// NPCs are handled server-side only. - /// - public abstract class SharedMoverController : VirtualController - { - [Dependency] private readonly IPhysicsManager _physicsManager = default!; - - private SharedBroadPhaseSystem _broadPhaseSystem = default!; - - public override void Initialize() - { - base.Initialize(); - _broadPhaseSystem = EntitySystem.Get(); - } - - /// - /// A generic kinematic mover for entities. - /// - protected void HandleKinematicMovement(IMoverComponent mover, PhysicsComponent physicsComponent) - { - var (walkDir, sprintDir) = mover.VelocityDir; - - // Regular movement. - // Target velocity. - var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed); - - if (total != Vector2.Zero) - { - mover.Owner.Transform.LocalRotation = total.GetDir().ToAngle(); - } - - physicsComponent.LinearVelocity = total; - } - - /// - /// Movement while considering actionblockers, weightlessness, etc. - /// - /// - /// - /// - protected void HandleMobMovement(IMoverComponent mover, PhysicsComponent physicsComponent, IMobMoverComponent mobMover) - { - // TODO: Look at https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/CharacterControllers.html?highlight=controller as it has some adviceo n kinematic controllersx - if (!UseMobMovement(_broadPhaseSystem, physicsComponent, _physicsManager)) - { - return; - } - - var transform = mover.Owner.Transform; - var (walkDir, sprintDir) = mover.VelocityDir; - - var weightless = transform.Owner.IsWeightless(_physicsManager); - - // Handle wall-pushes. - if (weightless) - { - // No gravity: is our entity touching anything? - var touching = IsAroundCollider(_broadPhaseSystem, transform, mobMover, physicsComponent); - - if (!touching) - { - transform.LocalRotation = physicsComponent.LinearVelocity.GetDir().ToAngle(); - return; - } - } - - // Regular movement. - // Target velocity. - var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed); - - if (total != Vector2.Zero) - { - // This should have its event run during island solver soooo - transform.DeferUpdates = true; - transform.LocalRotation = total.GetDir().ToAngle(); - HandleFootsteps(mover, mobMover); - } - - physicsComponent.LinearVelocity = total; - } - - public static bool UseMobMovement(SharedBroadPhaseSystem broadPhaseSystem, PhysicsComponent body, IPhysicsManager? physicsManager = null) - { - return (body.BodyStatus == BodyStatus.OnGround) & - body.Owner.HasComponent() && - ActionBlockerSystem.CanMove(body.Owner) && - (!body.Owner.IsWeightless(physicsManager) || - body.Owner.TryGetComponent(out SharedPlayerMobMoverComponent? mover) && - IsAroundCollider(broadPhaseSystem, body.Owner.Transform, mover, body)); - } - - /// - /// Used for weightlessness to determine if we are near a wall. - /// - /// - /// - /// - /// - /// - public static bool IsAroundCollider(SharedBroadPhaseSystem broadPhaseSystem, ITransformComponent transform, IMobMoverComponent mover, IPhysBody collider) - { - var enlargedAABB = collider.GetWorldAABB().Enlarged(mover.GrabRange); - - foreach (var otherCollider in broadPhaseSystem.GetCollidingEntities(transform.MapID, enlargedAABB)) - { - if (otherCollider == collider) continue; // Don't try to push off of yourself! - - // Only allow pushing off of anchored things that have collision. - if (otherCollider.BodyType != BodyType.Static || - !otherCollider.CanCollide || - ((collider.CollisionMask & otherCollider.CollisionLayer) == 0 && - (otherCollider.CollisionMask & collider.CollisionLayer) == 0) || - (otherCollider.Entity.TryGetComponent(out SharedPullableComponent? pullable) && pullable.BeingPulled)) - { - continue; - } - - return true; - } - - return false; - } - - // TODO: Need a predicted client version that only plays for our own entity and then have server-side ignore our session (for that entity only) - protected virtual void HandleFootsteps(IMoverComponent mover, IMobMoverComponent mobMover) {} - } -} diff --git a/Content.Shared/Physics/Controllers/SharedTileFrictionController.cs b/Content.Shared/Physics/Controllers/SharedTileFrictionController.cs deleted file mode 100644 index a26cc4ffb5..0000000000 --- a/Content.Shared/Physics/Controllers/SharedTileFrictionController.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using Content.Shared.GameObjects.Components.Mobs.State; -using Content.Shared.GameObjects.Components.Movement; -using Content.Shared.GameObjects.EntitySystems.ActionBlocker; -using JetBrains.Annotations; -using Robust.Shared; -using Robust.Shared.Configuration; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Map; -using Robust.Shared.Physics; -using Robust.Shared.Physics.Broadphase; -using Robust.Shared.Physics.Controllers; -using Robust.Shared.Physics.Dynamics; - -#nullable enable - -namespace Content.Shared.Physics.Controllers -{ - public sealed class SharedTileFrictionController : VirtualController - { - [Dependency] private readonly IConfigurationManager _configManager = default!; - [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly IPhysicsManager _physicsManager = default!; - [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; - - private SharedBroadPhaseSystem _broadPhaseSystem = default!; - - private float _stopSpeed; - - private float _frictionModifier; - - public override void Initialize() - { - base.Initialize(); - _broadPhaseSystem = EntitySystem.Get(); - - _frictionModifier = _configManager.GetCVar(CCVars.TileFrictionModifier); - _configManager.OnValueChanged(CCVars.TileFrictionModifier, value => _frictionModifier = value); - - _stopSpeed = _configManager.GetCVar(CCVars.StopSpeed); - _configManager.OnValueChanged(CCVars.StopSpeed, value => _stopSpeed = value); - } - - public override void UpdateBeforeMapSolve(bool prediction, PhysicsMap map, float frameTime) - { - base.UpdateBeforeMapSolve(prediction, map, frameTime); - - foreach (var body in map.AwakeBodies) - { - var speed = body.LinearVelocity.Length; - - if (speed <= 0.0f || body.BodyStatus == BodyStatus.InAir) continue; - - // This is the *actual* amount that speed will drop by, we just do some multiplication around it to be easier. - var drop = 0.0f; - float control; - - // Only apply friction when it's not a mob (or the mob doesn't have control). - if (SharedMoverController.UseMobMovement(_broadPhaseSystem, body, _physicsManager)) continue; - - var surfaceFriction = GetTileFriction(body); - var bodyModifier = body.Owner.GetComponentOrNull()?.Modifier ?? 1.0f; - var friction = _frictionModifier * surfaceFriction * bodyModifier; - - if (friction > 0.0f) - { - // TBH I can't really tell if this makes a difference, player movement is fucking hard. - if (!prediction) - { - control = speed < _stopSpeed ? _stopSpeed : speed; - } - else - { - control = speed; - } - - drop += control * friction * frameTime; - } - - var newSpeed = MathF.Max(0.0f, speed - drop); - - newSpeed /= speed; - body.LinearVelocity *= newSpeed; - } - } - - [Pure] - private float GetTileFriction(IPhysBody body) - { - if (body.BodyStatus == BodyStatus.InAir || body.Entity.Transform.GridID == GridId.Invalid) - return 0.0f; - - var transform = body.Owner.Transform; - var coords = transform.Coordinates; - - var grid = _mapManager.GetGrid(coords.GetGridId(body.Owner.EntityManager)); - var tile = grid.GetTileRef(coords); - var tileDef = _tileDefinitionManager[tile.Tile.TypeId]; - return tileDef.Friction; - } - } -} diff --git a/Content.Shared/Physics/ConveyedController.cs b/Content.Shared/Physics/ConveyedController.cs new file mode 100644 index 0000000000..226b5335a3 --- /dev/null +++ b/Content.Shared/Physics/ConveyedController.cs @@ -0,0 +1,62 @@ +#nullable enable +using Content.Shared.GameObjects.Components.Movement; +using Robust.Shared.GameObjects; +using Robust.Shared.Maths; +using Robust.Shared.Physics; + +namespace Content.Shared.Physics +{ + public class ConveyedController : VirtualController + { + public override IPhysicsComponent? ControlledComponent { protected get; set; } + + public void Move(Vector2 velocityDirection, float speed, Vector2 itemRelativeToConveyor) + { + if (ControlledComponent?.Owner.IsWeightless() ?? false) + { + return; + } + + if (ControlledComponent?.Status == BodyStatus.InAir) + { + return; + } + + LinearVelocity = velocityDirection * speed; + + //gravitating item towards center + //http://csharphelper.com/blog/2016/09/find-the-shortest-distance-between-a-point-and-a-line-segment-in-c/ + Vector2 centerPoint; + + var t = 0f; + if (velocityDirection.Length > 0) //if velocitydirection is 0, this calculation will divide by 0 + { + t = Vector2.Dot(itemRelativeToConveyor, velocityDirection) / + Vector2.Dot(velocityDirection, velocityDirection); + } + + if (t < 0) + { + centerPoint = new Vector2(); + } + else if(t > 1) + { + centerPoint = velocityDirection; + } + else + { + centerPoint = velocityDirection * t; + } + + var delta = centerPoint - itemRelativeToConveyor; + LinearVelocity += delta * (4 * delta.Length); + } + + public override void UpdateAfterProcessing() + { + base.UpdateAfterProcessing(); + + LinearVelocity = Vector2.Zero; + } + } +} diff --git a/Content.Shared/Physics/FrictionController.cs b/Content.Shared/Physics/FrictionController.cs new file mode 100644 index 0000000000..f4fd3c2964 --- /dev/null +++ b/Content.Shared/Physics/FrictionController.cs @@ -0,0 +1,24 @@ +#nullable enable +using System; +using Robust.Shared.IoC; +using Robust.Shared.Physics; + +namespace Content.Shared.Physics +{ + public abstract class FrictionController : VirtualController + { + [Dependency] private readonly IPhysicsManager _physicsManager = default!; + + public override void UpdateAfterProcessing() + { + base.UpdateAfterProcessing(); + + if (ControlledComponent != null && !_physicsManager.IsWeightless(ControlledComponent.Owner.Transform.Coordinates)) + { + LinearVelocity *= 0.85f; + if (MathF.Abs(LinearVelocity.Length) < 1f) + Stop(); + } + } + } +} diff --git a/Content.Shared/Physics/MoverController.cs b/Content.Shared/Physics/MoverController.cs new file mode 100644 index 0000000000..1124806330 --- /dev/null +++ b/Content.Shared/Physics/MoverController.cs @@ -0,0 +1,33 @@ +#nullable enable +using Content.Shared.GameObjects.Components.Movement; +using Robust.Shared.GameObjects; +using Robust.Shared.Maths; +using Robust.Shared.Physics; + +namespace Content.Shared.Physics +{ + public class MoverController : VirtualController + { + public override IPhysicsComponent? ControlledComponent { protected get; set; } + + public void Move(Vector2 velocityDirection, float speed) + { + if (ControlledComponent?.Owner.IsWeightless() ?? false) + { + return; + } + + Push(velocityDirection, speed); + } + + public void Push(Vector2 velocityDirection, float speed) + { + LinearVelocity = velocityDirection * speed; + } + + public void StopMoving() + { + LinearVelocity = Vector2.Zero; + } + } +} diff --git a/Content.Shared/Physics/Pull/PullAttemptMessage.cs b/Content.Shared/Physics/Pull/PullAttemptMessage.cs index 945d58f678..bc8870044f 100644 --- a/Content.Shared/Physics/Pull/PullAttemptMessage.cs +++ b/Content.Shared/Physics/Pull/PullAttemptMessage.cs @@ -1,11 +1,11 @@ #nullable enable -using Robust.Shared.Physics; +using Robust.Shared.GameObjects; namespace Content.Shared.Physics.Pull { public class PullAttemptMessage : PullMessage { - public PullAttemptMessage(IPhysBody puller, IPhysBody pulled) : base(puller, pulled) { } + public PullAttemptMessage(IPhysicsComponent puller, IPhysicsComponent pulled) : base(puller, pulled) { } public bool Cancelled { get; set; } } diff --git a/Content.Shared/Physics/Pull/PullController.cs b/Content.Shared/Physics/Pull/PullController.cs new file mode 100644 index 0000000000..b29643116d --- /dev/null +++ b/Content.Shared/Physics/Pull/PullController.cs @@ -0,0 +1,190 @@ +#nullable enable +using System; +using System.Linq; +using Robust.Shared.Containers; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using Robust.Shared.Maths; +using Robust.Shared.Physics; +using Content.Shared.GameObjects.Components.Pulling; +using static Content.Shared.GameObjects.EntitySystems.SharedInteractionSystem; + +namespace Content.Shared.Physics.Pull +{ + /// + /// This is applied upon a Pullable object when that object is being pulled. + /// It lives only to serve that Pullable object. + /// + public class PullController : VirtualController + { + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IPhysicsManager _physicsManager = default!; + + private const float DistBeforeStopPull = InteractionRange; + + private const float StopMoveThreshold = 0.25f; + + /// + /// The managing SharedPullableComponent of this PullController. + /// MUST BE SET! If you go attaching PullControllers yourself, YOU ARE DOING IT WRONG. + /// If you get a crash based on such, then, well, see previous note. + /// This is set by the SharedPullableComponent attaching the PullController. + /// + public SharedPullableComponent Manager = default!; + + private EntityCoordinates? _movingTo; + + public EntityCoordinates? MovingTo + { + get => _movingTo; + set + { + if (_movingTo == value || ControlledComponent == null) + { + return; + } + + _movingTo = value; + ControlledComponent.WakeBody(); + } + } + + private bool PullerMovingTowardsPulled() + { + var _puller = Manager.PullerPhysics; + if (_puller == null) + { + return false; + } + + if (ControlledComponent == null) + { + return false; + } + + if (_puller.LinearVelocity.EqualsApprox(Vector2.Zero)) + { + return false; + } + + var pullerTransform = _puller.Owner.Transform; + var origin = pullerTransform.Coordinates.Position; + var velocity = _puller.LinearVelocity.Normalized; + var mapId = pullerTransform.MapPosition.MapId; + var ray = new CollisionRay(origin, velocity, (int) CollisionGroup.AllMask); + bool Predicate(IEntity e) => e != ControlledComponent.Owner; + var rayResults = + _physicsManager.IntersectRayWithPredicate(mapId, ray, DistBeforeStopPull, Predicate); + + return rayResults.Any(); + } + + public bool TryMoveTo(EntityCoordinates from, EntityCoordinates to) + { + var _puller = Manager.PullerPhysics; + if (_puller == null || ControlledComponent == null) + { + return false; + } + + if (!_puller.Owner.Transform.Coordinates.InRange(_entityManager, from, InteractionRange)) + { + return false; + } + + if (!_puller.Owner.Transform.Coordinates.InRange(_entityManager, to, InteractionRange)) + { + return false; + } + + if (!from.InRange(_entityManager, to, InteractionRange)) + { + return false; + } + + if (from.Position.EqualsApprox(to.Position)) + { + return false; + } + + if (!_puller.Owner.Transform.Coordinates.TryDistance(_entityManager, to, out var distance) || + Math.Sqrt(distance) > DistBeforeStopPull || + Math.Sqrt(distance) < StopMoveThreshold) + { + return false; + } + + MovingTo = to; + return true; + } + + public override void UpdateBeforeProcessing() + { + var _puller = Manager.PullerPhysics; + if (_puller == null || ControlledComponent == null) + { + return; + } + + if (!_puller.Owner.IsInSameOrNoContainer(ControlledComponent.Owner)) + { + Manager.Puller = null; + return; + } + + var distance = _puller.Owner.Transform.WorldPosition - ControlledComponent.Owner.Transform.WorldPosition; + + if (distance.Length > DistBeforeStopPull) + { + Manager.Puller = null; + } + else if (MovingTo.HasValue) + { + var diff = MovingTo.Value.Position - ControlledComponent.Owner.Transform.Coordinates.Position; + LinearVelocity = diff.Normalized * 5; + } + else + { + if (PullerMovingTowardsPulled()) + { + LinearVelocity = Vector2.Zero; + return; + } + + var distanceAbs = Vector2.Abs(distance); + var totalAabb = _puller.AABB.Size + ControlledComponent.AABB.Size / 2; + if (distanceAbs.X < totalAabb.X && distanceAbs.Y < totalAabb.Y) + { + LinearVelocity = Vector2.Zero; + return; + } + + LinearVelocity = distance.Normalized * _puller.LinearVelocity.Length * 1.5f; + } + } + + public override void UpdateAfterProcessing() + { + base.UpdateAfterProcessing(); + + if (ControlledComponent == null) + { + MovingTo = null; + return; + } + + if (MovingTo != null && + ControlledComponent.Owner.Transform.Coordinates.Position.EqualsApprox(MovingTo.Value.Position, 0.01)) + { + MovingTo = null; + } + + if (LinearVelocity != Vector2.Zero) + { + var angle = LinearVelocity.ToAngle(); + ControlledComponent.Owner.Transform.LocalRotation = angle; + } + } + } +} diff --git a/Content.Shared/Physics/Pull/PullMessage.cs b/Content.Shared/Physics/Pull/PullMessage.cs index d72e15d642..a65957bc84 100644 --- a/Content.Shared/Physics/Pull/PullMessage.cs +++ b/Content.Shared/Physics/Pull/PullMessage.cs @@ -1,15 +1,14 @@ #nullable enable using Robust.Shared.GameObjects; -using Robust.Shared.Physics; namespace Content.Shared.Physics.Pull { public class PullMessage : ComponentMessage { - public readonly IPhysBody Puller; - public readonly IPhysBody Pulled; + public readonly IPhysicsComponent Puller; + public readonly IPhysicsComponent Pulled; - protected PullMessage(IPhysBody puller, IPhysBody pulled) + protected PullMessage(IPhysicsComponent puller, IPhysicsComponent pulled) { Puller = puller; Pulled = pulled; diff --git a/Content.Shared/Physics/Pull/PullStartedMessage.cs b/Content.Shared/Physics/Pull/PullStartedMessage.cs index 0f138cf12c..2dd84a84fd 100644 --- a/Content.Shared/Physics/Pull/PullStartedMessage.cs +++ b/Content.Shared/Physics/Pull/PullStartedMessage.cs @@ -1,11 +1,11 @@ #nullable enable -using Robust.Shared.Physics; +using Robust.Shared.GameObjects; namespace Content.Shared.Physics.Pull { public class PullStartedMessage : PullMessage { - public PullStartedMessage(IPhysBody puller, IPhysBody pulled) : + public PullStartedMessage(IPhysicsComponent puller, IPhysicsComponent pulled) : base(puller, pulled) { } diff --git a/Content.Shared/Physics/Pull/PullStoppedMessage.cs b/Content.Shared/Physics/Pull/PullStoppedMessage.cs index 0b91a38d83..215dae4aee 100644 --- a/Content.Shared/Physics/Pull/PullStoppedMessage.cs +++ b/Content.Shared/Physics/Pull/PullStoppedMessage.cs @@ -1,11 +1,11 @@ #nullable enable -using Robust.Shared.Physics; +using Robust.Shared.GameObjects; namespace Content.Shared.Physics.Pull { public class PullStoppedMessage : PullMessage { - public PullStoppedMessage(IPhysBody puller, IPhysBody pulled) : base(puller, pulled) + public PullStoppedMessage(IPhysicsComponent puller, IPhysicsComponent pulled) : base(puller, pulled) { } } diff --git a/Content.Shared/Physics/ShuttleController.cs b/Content.Shared/Physics/ShuttleController.cs new file mode 100644 index 0000000000..ed986d1e5e --- /dev/null +++ b/Content.Shared/Physics/ShuttleController.cs @@ -0,0 +1,17 @@ +#nullable enable +using Robust.Shared.GameObjects; +using Robust.Shared.Maths; +using Robust.Shared.Physics; + +namespace Content.Shared.Physics +{ + public class ShuttleController : VirtualController + { + public override IPhysicsComponent? ControlledComponent { protected get; set; } + + public void Push(Vector2 velocityDirection, float speed) + { + LinearVelocity = velocityDirection * speed; + } + } +} diff --git a/Content.Shared/Physics/SingularityController.cs b/Content.Shared/Physics/SingularityController.cs new file mode 100644 index 0000000000..c9dd44b1d2 --- /dev/null +++ b/Content.Shared/Physics/SingularityController.cs @@ -0,0 +1,18 @@ +#nullable enable +using Robust.Shared.GameObjects; +using Robust.Shared.Maths; +using Robust.Shared.Physics; + +namespace Content.Shared.Physics +{ + public class SingularityController : VirtualController + { + public override IPhysicsComponent? ControlledComponent { protected get; set; } + + + public void Push(Vector2 velocityDirection, float speed) + { + LinearVelocity = velocityDirection * speed; + } + } +} diff --git a/Content.Shared/Physics/SingularityPullController.cs b/Content.Shared/Physics/SingularityPullController.cs new file mode 100644 index 0000000000..66f4fa0c90 --- /dev/null +++ b/Content.Shared/Physics/SingularityPullController.cs @@ -0,0 +1,22 @@ +#nullable enable +using Robust.Shared.GameObjects; +using Robust.Shared.Maths; +using Robust.Shared.Physics; + +namespace Content.Server.GameObjects.Components.Singularity +{ + public class SingularityPullController : VirtualController + { + public override IPhysicsComponent? ControlledComponent { protected get; set; } + + public void StopPull() + { + LinearVelocity = Vector2.Zero; + } + + public void Pull(Vector2 velocityDirection, float speed) + { + LinearVelocity = velocityDirection * speed; + } + } +} diff --git a/Content.Shared/Physics/SlipController.cs b/Content.Shared/Physics/SlipController.cs new file mode 100644 index 0000000000..bc64449a09 --- /dev/null +++ b/Content.Shared/Physics/SlipController.cs @@ -0,0 +1,44 @@ +#nullable enable +using Robust.Shared.IoC; +using Robust.Shared.Maths; +using Robust.Shared.Physics; + +namespace Content.Shared.Physics +{ + public class SlipController : VirtualController + { + [Dependency] private readonly IPhysicsManager _physicsManager = default!; + + public SlipController() + { + IoCManager.InjectDependencies(this); + } + + private float Decay { get; set; } = 0.95f; + + public override void UpdateAfterProcessing() + { + if (ControlledComponent == null) + { + return; + } + + if (_physicsManager.IsWeightless(ControlledComponent.Owner.Transform.Coordinates)) + { + if (ControlledComponent.IsColliding(Vector2.Zero, false)) + { + Stop(); + } + + return; + } + + LinearVelocity *= Decay; + + if (LinearVelocity.Length < 0.001) + { + Stop(); + } + } + } +} diff --git a/Content.Shared/Physics/ThrowKnockbackController.cs b/Content.Shared/Physics/ThrowKnockbackController.cs new file mode 100644 index 0000000000..6a7dc2ecb1 --- /dev/null +++ b/Content.Shared/Physics/ThrowKnockbackController.cs @@ -0,0 +1,50 @@ +#nullable enable +using Content.Shared.GameObjects.Components.Movement; +using Content.Shared.GameObjects.EntitySystems.ActionBlocker; +using Robust.Shared.IoC; +using Robust.Shared.Maths; +using Robust.Shared.Physics; + +namespace Content.Shared.Physics +{ + public class ThrowKnockbackController : VirtualController + { + public ThrowKnockbackController() + { + IoCManager.InjectDependencies(this); + } + + public void Push(Vector2 velocityDirection, float speed) + { + LinearVelocity = velocityDirection * speed; + } + + private float Decay { get; set; } = 0.95f; + + public override void UpdateAfterProcessing() + { + if (ControlledComponent == null) + { + return; + } + + if (ControlledComponent.Owner.IsWeightless()) + { + if (ActionBlockerSystem.CanMove(ControlledComponent.Owner) + && ControlledComponent.IsColliding(Vector2.Zero, false)) + { + Stop(); + } + + return; + } + + LinearVelocity *= Decay; + + if (LinearVelocity.Length < 0.001) + { + Stop(); + } + } + } +} diff --git a/Content.Shared/Physics/ThrownController.cs b/Content.Shared/Physics/ThrownController.cs new file mode 100644 index 0000000000..8b836b969b --- /dev/null +++ b/Content.Shared/Physics/ThrownController.cs @@ -0,0 +1,17 @@ +#nullable enable +using Robust.Shared.GameObjects; +using Robust.Shared.Maths; +using Robust.Shared.Physics; + +namespace Content.Shared.Physics +{ + public class ThrownController : VirtualController + { + public override IPhysicsComponent? ControlledComponent { protected get; set; } + + public void Push(Vector2 velocityDirection, float speed) + { + LinearVelocity = velocityDirection * speed; + } + } +} diff --git a/Content.Shared/Physics/VaporController.cs b/Content.Shared/Physics/VaporController.cs new file mode 100644 index 0000000000..b2cfa5c774 --- /dev/null +++ b/Content.Shared/Physics/VaporController.cs @@ -0,0 +1,14 @@ +#nullable enable +using Robust.Shared.Maths; +using Robust.Shared.Physics; + +namespace Content.Shared.Physics +{ + public class VaporController : VirtualController + { + public void Move(Vector2 velocityDirection, float speed) + { + LinearVelocity = velocityDirection * speed; + } + } +} diff --git a/Content.Shared/Utility/EntitySystemExtensions.cs b/Content.Shared/Utility/EntitySystemExtensions.cs index 6757021388..b06d595583 100644 --- a/Content.Shared/Utility/EntitySystemExtensions.cs +++ b/Content.Shared/Utility/EntitySystemExtensions.cs @@ -6,7 +6,6 @@ using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Physics; -using Robust.Shared.Physics.Broadphase; namespace Content.Shared.Utility { @@ -18,9 +17,9 @@ namespace Content.Shared.Utility EntityCoordinates coordinates, CollisionGroup collisionLayer, in Box2? box = null, - SharedBroadPhaseSystem? physicsManager = null) + IPhysicsManager? physicsManager = null) { - physicsManager ??= EntitySystem.Get(); + physicsManager ??= IoCManager.Resolve(); var mapCoordinates = coordinates.ToMap(entityManager); return entityManager.SpawnIfUnobstructed(prototypeName, mapCoordinates, collisionLayer, box, physicsManager); @@ -32,19 +31,18 @@ namespace Content.Shared.Utility MapCoordinates coordinates, CollisionGroup collisionLayer, in Box2? box = null, - SharedBroadPhaseSystem? collision = null) + IPhysicsManager? physicsManager = null) { var boxOrDefault = box.GetValueOrDefault(Box2.UnitCentered); - collision ??= EntitySystem.Get(); + physicsManager ??= IoCManager.Resolve(); - foreach (var body in collision.GetCollidingEntities(coordinates.MapId, in boxOrDefault)) + foreach (var body in physicsManager.GetCollidingEntities(coordinates.MapId, in boxOrDefault)) { if (!body.Hard) { continue; } - // TODO: wtf fix this if (collisionLayer == 0 || (body.CollisionMask & (int) collisionLayer) == 0) { continue; @@ -63,7 +61,7 @@ namespace Content.Shared.Utility CollisionGroup collisionLayer, [NotNullWhen(true)] out IEntity? entity, Box2? box = null, - SharedBroadPhaseSystem? physicsManager = null) + IPhysicsManager? physicsManager = null) { entity = entityManager.SpawnIfUnobstructed(prototypeName, coordinates, collisionLayer, box, physicsManager); @@ -77,7 +75,7 @@ namespace Content.Shared.Utility CollisionGroup collisionLayer, [NotNullWhen(true)] out IEntity? entity, in Box2? box = null, - SharedBroadPhaseSystem? physicsManager = null) + IPhysicsManager? physicsManager = null) { entity = entityManager.SpawnIfUnobstructed(prototypeName, coordinates, collisionLayer, box, physicsManager); diff --git a/Resources/Maps/Test/Breathing/3by3-20oxy-80nit.yml b/Resources/Maps/Test/Breathing/3by3-20oxy-80nit.yml index a84d8fd881..a47f06d7ff 100644 --- a/Resources/Maps/Test/Breathing/3by3-20oxy-80nit.yml +++ b/Resources/Maps/Test/Breathing/3by3-20oxy-80nit.yml @@ -52,10 +52,9 @@ entities: type: Transform - index: 0 type: MapGrid - - fixtures: - - shape: - !type:PhysShapeGrid - grid: 0 + - shapes: + - !type:PhysShapeGrid + grid: 0 type: Physics - uniqueMixes: - volume: 2500 diff --git a/Resources/Maps/Test/singularity.yml b/Resources/Maps/Test/singularity.yml index 9303ba8953..c7e0ba4932 100644 --- a/Resources/Maps/Test/singularity.yml +++ b/Resources/Maps/Test/singularity.yml @@ -77,10 +77,9 @@ entities: type: Transform - index: 0 type: MapGrid - - fixtures: - - shape: - !type:PhysShapeGrid - grid: 0 + - shapes: + - !type:PhysShapeGrid + grid: 0 type: Physics - uniqueMixes: - volume: 2500 diff --git a/Resources/Maps/saltern.yml b/Resources/Maps/saltern.yml index c8b8b5e72b..1b99c88f7d 100644 --- a/Resources/Maps/saltern.yml +++ b/Resources/Maps/saltern.yml @@ -8308,10 +8308,9 @@ entities: type: Transform - index: 0 type: MapGrid - - fixtures: - - shape: - !type:PhysShapeGrid - grid: 0 + - shapes: + - !type:PhysShapeGrid + grid: 0 type: Physics - uniqueMixes: - volume: 2500 diff --git a/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml b/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml index e7f8e5877a..aed87f266b 100644 --- a/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml +++ b/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml @@ -24,10 +24,9 @@ - state: panel_open map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.49,-0.49,0.49,0.49" # don't want this colliding with walls or they won't close + shapes: + - !type:PhysShapeAabb + bounds: "-0.49,-0.49,0.49,0.49" # don't want this colliding with walls or they won't close mask: - MobImpassable layer: diff --git a/Resources/Prototypes/Entities/Constructible/Doors/firelock.yml b/Resources/Prototypes/Entities/Constructible/Doors/firelock.yml index 7e28d6c220..4100d6dc85 100644 --- a/Resources/Prototypes/Entities/Constructible/Doors/firelock.yml +++ b/Resources/Prototypes/Entities/Constructible/Doors/firelock.yml @@ -35,10 +35,9 @@ - type: Physics on: false - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.49,-0.49,0.49,0.49" # don't want this colliding with walls or they won't close + shapes: + - !type:PhysShapeAabb + bounds: "-0.49,-0.49,0.49,0.49" # don't want this colliding with walls or they won't close mask: - MobImpassable layer: @@ -111,9 +110,8 @@ airBlockedDirection: - East - type: Physics - fixtures: - - shape: - !type:PhysShapeRect {} + shapes: + - !type:PhysShapeRect bounds: "0.49,-0.49,-0.49,-0.2" # don't want this colliding with walls or they won't close mask: - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Doors/firelock_frame.yml b/Resources/Prototypes/Entities/Constructible/Doors/firelock_frame.yml index 0ab2d1acbe..113b927d18 100644 --- a/Resources/Prototypes/Entities/Constructible/Doors/firelock_frame.yml +++ b/Resources/Prototypes/Entities/Constructible/Doors/firelock_frame.yml @@ -22,10 +22,9 @@ - !type:DoActsBehavior acts: ["Destruction"] - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.49,-0.49,0.49,0.49" + shapes: + - !type:PhysShapeAabb + bounds: "-0.49,-0.49,0.49,0.49" mask: - Impassable layer: diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/beds.yml b/Resources/Prototypes/Entities/Constructible/Furniture/beds.yml index 169c31e145..7e0420ad04 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/beds.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/beds.yml @@ -8,10 +8,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.45, -0.45, 0.05, 0.45" + shapes: + - !type:PhysShapeAabb + bounds: "-0.45, -0.45, 0.05, 0.45" mask: - Impassable - VaultImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/bookshelf.yml b/Resources/Prototypes/Entities/Constructible/Furniture/bookshelf.yml index b0ad5bff2b..658e652990 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/bookshelf.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/bookshelf.yml @@ -11,9 +11,8 @@ - type: Sprite sprite: Constructible/Misc/bookshelf.rsi - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/carpets.yml b/Resources/Prototypes/Entities/Constructible/Furniture/carpets.yml index 0a1921b789..82800af63e 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/carpets.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/carpets.yml @@ -16,10 +16,9 @@ key: full base: carpet_ - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" layer: [ Passable ] - type: Damageable - type: Destructible diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/instruments.yml b/Resources/Prototypes/Entities/Constructible/Furniture/instruments.yml index 596fce5fdd..bfa5aff82b 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/instruments.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/instruments.yml @@ -11,9 +11,8 @@ - type: InteractionOutline - type: Anchorable - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb layer: [MobMask] mask: - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/potted_plants.yml b/Resources/Prototypes/Entities/Constructible/Furniture/potted_plants.yml index 333affc6df..8272e0e572 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/potted_plants.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/potted_plants.yml @@ -7,10 +7,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.2, 0.5, 0.2" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.2, 0.5, 0.2" mask: - Impassable - MobImpassable @@ -59,10 +58,9 @@ - type: Sprite state: plant-25 - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.47,-0.25,0.05,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.47,-0.25,0.05,0.25" layer: [ Passable ] - type: entity diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml b/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml index 9665071a3e..f9f4a0bf2d 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml @@ -10,10 +10,9 @@ - type: InteractionOutline - type: Physics anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.25" mask: - Impassable - VaultImpassable @@ -45,10 +44,9 @@ state: chair color: "#8e9799" - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.45, -0.45, 0.05, 0.45" + shapes: + - !type:PhysShapeAabb + bounds: "-0.45, -0.45, 0.05, 0.45" mask: - Impassable - VaultImpassable @@ -64,10 +62,9 @@ state: stool_base color: "#8e9799" - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.25, 0.05, 0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.25, 0.05, 0.25" mask: - Impassable - VaultImpassable @@ -82,10 +79,9 @@ state: bar_stool color: "white" - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.2, 0.2, 0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.2, 0.2, 0.25" mask: - Impassable - VaultImpassable @@ -101,10 +97,9 @@ - type: Sprite state: officechair_white - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.49, -0.25, 0.37, 0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.49, -0.25, 0.37, 0.25" mask: - Impassable - VaultImpassable @@ -127,10 +122,9 @@ - type: Sprite state: comfychair_preview - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.45, -0.3, 0.35, 0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.45, -0.3, 0.35, 0.3" mask: - Impassable - VaultImpassable @@ -145,10 +139,9 @@ state: wooden_chair color: "white" - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.37, -0.25, 0.49, 0.24" + shapes: + - !type:PhysShapeAabb + bounds: "-0.37, -0.25, 0.49, 0.24" mask: - Impassable - VaultImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/storage.yml b/Resources/Prototypes/Entities/Constructible/Furniture/storage.yml index 0f85babc84..58a8b3aa35 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/storage.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/storage.yml @@ -13,10 +13,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.4,0.4,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.4,0.4,0.4" layer: - Opaque - Impassable @@ -62,10 +61,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.4,0.4,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.4,0.4,0.4" layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/tables.yml b/Resources/Prototypes/Entities/Constructible/Furniture/tables.yml index 1ad9f0516a..5f9721f36d 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/tables.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/tables.yml @@ -17,9 +17,8 @@ key: state base: state_ - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb layer: - VaultImpassable - type: SnapGrid diff --git a/Resources/Prototypes/Entities/Constructible/Ground/catwalk.yml b/Resources/Prototypes/Entities/Constructible/Ground/catwalk.yml index ee28c18787..382d6addaa 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/catwalk.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/catwalk.yml @@ -8,10 +8,9 @@ - type: Clickable - type: InteractionOutline - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" layer: [ Passable ] - type: Sprite netsync: false diff --git a/Resources/Prototypes/Entities/Constructible/Ground/kitchen.yml b/Resources/Prototypes/Entities/Constructible/Ground/kitchen.yml index 67c3ae246c..e9d7cbd46a 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/kitchen.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/kitchen.yml @@ -8,9 +8,8 @@ - type: Clickable - type: InteractionOutline - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb mask: - Impassable layer: diff --git a/Resources/Prototypes/Entities/Constructible/Piping/gascanisters.yml b/Resources/Prototypes/Entities/Constructible/Piping/gascanisters.yml index 8365033e14..fbb0c2e5c3 100644 --- a/Resources/Prototypes/Entities/Constructible/Piping/gascanisters.yml +++ b/Resources/Prototypes/Entities/Constructible/Piping/gascanisters.yml @@ -50,10 +50,9 @@ - type: Physics mass: 25 anchored: false - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.25" mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Power/computers.yml b/Resources/Prototypes/Entities/Constructible/Power/computers.yml index 282bcba4c3..2acb426263 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/computers.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/computers.yml @@ -8,10 +8,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.25" layer: - Impassable - MobImpassable @@ -41,10 +40,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.25" layer: - Impassable - MobImpassable @@ -80,10 +78,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.25" layer: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Power/debug_power.yml b/Resources/Prototypes/Entities/Constructible/Power/debug_power.yml index b53810c169..11e60743c0 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/debug_power.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/debug_power.yml @@ -12,10 +12,9 @@ - type: Clickable - type: InteractionOutline - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" layer: [MobMask, Opaque] - type: SnapGrid offset: Center @@ -49,10 +48,9 @@ - type: Clickable - type: InteractionOutline - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" layer: [MobMask, Opaque] - type: SnapGrid offset: Center @@ -77,10 +75,9 @@ - type: Clickable - type: InteractionOutline - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" layer: [MobMask, Opaque] - type: SnapGrid offset: Center @@ -120,10 +117,9 @@ - type: Clickable - type: InteractionOutline - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" layer: [MobMask, Opaque] - type: SnapGrid offset: Center diff --git a/Resources/Prototypes/Entities/Constructible/Power/lathe.yml b/Resources/Prototypes/Entities/Constructible/Power/lathe.yml index 9b79f71a74..ff1f14657a 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/lathe.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/lathe.yml @@ -10,10 +10,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.4,0.4,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.4,0.4,0.4" mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Power/machine_frame.yml b/Resources/Prototypes/Entities/Constructible/Power/machine_frame.yml index ae0005419b..e700bf2e8f 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/machine_frame.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/machine_frame.yml @@ -9,10 +9,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.25" layer: - Impassable - MobImpassable @@ -56,10 +55,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.25" layer: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Power/particleAccelerator.yml b/Resources/Prototypes/Entities/Constructible/Power/particleAccelerator.yml index d26c88e865..3398afd385 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/particleAccelerator.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/particleAccelerator.yml @@ -9,10 +9,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.49,-0.49,0.49,0.49" + shapes: + - !type:PhysShapeAabb + bounds: "-0.49,-0.49,0.49,0.49" layer: - Opaque - Impassable @@ -40,11 +39,10 @@ damages: Radiation: 10 - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.48,-0.48,0.48,0.48" - hard: false + hard: false + shapes: + - !type:PhysShapeAabb + bounds: "-0.48,-0.48,0.48,0.48" layer: [None] mask: - MobMask diff --git a/Resources/Prototypes/Entities/Constructible/Power/power_base.yml b/Resources/Prototypes/Entities/Constructible/Power/power_base.yml index f1b079b1bb..083cac2119 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/power_base.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/power_base.yml @@ -11,10 +11,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.4, 0.3, 0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.4, 0.3, 0.4" mask: - Impassable - MobImpassable @@ -56,9 +55,8 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb mask: - Impassable - MobImpassable @@ -115,9 +113,8 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb mask: - Impassable - MobImpassable @@ -175,10 +172,9 @@ access: [["Engineering"]] - type: InteractionOutline - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.25, -0.25, 0.25, 0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.25, -0.25, 0.25, 0.3" layer: [ Passable ] - type: SnapGrid offset: Center @@ -232,9 +228,8 @@ - type: Physics mass: 25 anchored: false - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Power/seed_extractor.yml b/Resources/Prototypes/Entities/Constructible/Power/seed_extractor.yml index dadc63b0ce..3397231958 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/seed_extractor.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/seed_extractor.yml @@ -13,10 +13,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.25,0.4,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.25,0.4,0.25" layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml b/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml index e42413ef79..c378ff584d 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml @@ -13,10 +13,9 @@ netsync: false - type: Physics anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.25" mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Power/wires.yml b/Resources/Prototypes/Entities/Constructible/Power/wires.yml index 3af952771a..85f4647af5 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/wires.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/wires.yml @@ -6,12 +6,10 @@ components: - type: Clickable - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" - layer: - - Underplating + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" + layer: [ Underplating ] - type: InteractionOutline - type: SnapGrid offset: Center diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Conveyor/conveyor.yml b/Resources/Prototypes/Entities/Constructible/Specific/Conveyor/conveyor.yml index 16f3244d5a..b2d43c0061 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Conveyor/conveyor.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Conveyor/conveyor.yml @@ -8,11 +8,10 @@ - type: Clickable - type: InteractionOutline - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.49,-0.49,0.49,0.49" - hard: false + hard: false + shapes: + - !type:PhysShapeAabb + bounds: "-0.49,-0.49,0.49,0.49" layer: [Passable] mask: - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Cooking/microwave.yml b/Resources/Prototypes/Entities/Constructible/Specific/Cooking/microwave.yml index 9feef45338..ac4fa5ceb4 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Cooking/microwave.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Cooking/microwave.yml @@ -22,10 +22,9 @@ - key: enum.MicrowaveUiKey.Key type: MicrowaveBoundUserInterface - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.16,-0.3,0.16,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.16,-0.3,0.16,0.3" layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Cooking/reagent_grinder.yml b/Resources/Prototypes/Entities/Constructible/Specific/Cooking/reagent_grinder.yml index 26c18fe7be..2ffab8f32d 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Cooking/reagent_grinder.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Cooking/reagent_grinder.yml @@ -21,10 +21,9 @@ - type: PowerReceiver - type: LoopingSound - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.35,-0.08,0.25,0.15" + shapes: + - !type:PhysShapeAabb + bounds: "-0.35,-0.08,0.25,0.15" layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Dispensers/reagent_dispenser_base.yml b/Resources/Prototypes/Entities/Constructible/Specific/Dispensers/reagent_dispenser_base.yml index bfe5746018..0ee63db22b 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Dispensers/reagent_dispenser_base.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Dispensers/reagent_dispenser_base.yml @@ -9,10 +9,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.3,-0.4,0.3,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.3,-0.4,0.3,0.4" mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/controller.yml b/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/controller.yml index 817af3334d..30d45968ce 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/controller.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/controller.yml @@ -13,9 +13,8 @@ - type: Physics # Mass of 1? Unmovable. Mass of 25? Fine. What on earth is going on? mass: 25 - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/shielding.yml b/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/shielding.yml index 69bfe9c33b..dd8c060024 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/shielding.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/shielding.yml @@ -12,9 +12,8 @@ sprite: Constructible/Power/ame_shielding.rsi state: shield_0 - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Engines/Singularity/emitter.yml b/Resources/Prototypes/Entities/Constructible/Specific/Engines/Singularity/emitter.yml index 2503eae49b..fa21ea3ee4 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Engines/Singularity/emitter.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Engines/Singularity/emitter.yml @@ -10,10 +10,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" layer: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Medical/cloning_machine.yml b/Resources/Prototypes/Entities/Constructible/Specific/Medical/cloning_machine.yml index ff9c013bad..3f07f2d0dc 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Medical/cloning_machine.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Medical/cloning_machine.yml @@ -18,10 +18,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.25" layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Medical/medical_scanner.yml b/Resources/Prototypes/Entities/Constructible/Specific/Medical/medical_scanner.yml index 1fcf944340..01bcd003ff 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Medical/medical_scanner.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Medical/medical_scanner.yml @@ -20,12 +20,12 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb {} - layer: - - Impassable - - VaultImpassable + shapes: + - !type:PhysShapeAabb + mask: + - Impassable + - VaultImpassable + - SmallImpassable - type: SnapGrid offset: Center - type: Anchorable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Research/research.yml b/Resources/Prototypes/Entities/Constructible/Specific/Research/research.yml index 39891cd37f..be404b783f 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Research/research.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Research/research.yml @@ -13,10 +13,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4, -0.45, 0.45, 0.45" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4, -0.45, 0.45, 0.45" mask: - Impassable - MobImpassable @@ -56,9 +55,8 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml b/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml index aba811ac56..111511aa4f 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml @@ -10,10 +10,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.45, -0.45, 0.00, 0.45" + shapes: + - !type:PhysShapeAabb + bounds: "-0.45, -0.45, 0.00, 0.45" layer: [ Passable ] - type: Sprite sprite: Constructible/Power/cargo_teleporter.rsi diff --git a/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml b/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml index d5a3ab9c46..858cbeed69 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml @@ -22,10 +22,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.25,0.4,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.25,0.4,0.25" layer: - Opaque - Impassable @@ -74,10 +73,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.25,0.4,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.25,0.4,0.25" layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/disposal.yml b/Resources/Prototypes/Entities/Constructible/Specific/disposal.yml index e122b19cf6..4248ef7196 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/disposal.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/disposal.yml @@ -51,10 +51,9 @@ state_anchored: pipe-s state_broken: pipe-b - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.25" layer: [ Underplating ] - type: entity @@ -79,10 +78,9 @@ - key: enum.DisposalTaggerUiKey.Key type: DisposalTaggerBoundUserInterface - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.25" layer: [ Underplating ] - type: entity @@ -103,10 +101,9 @@ state_anchored: pipe-t state_broken: pipe-b - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.4,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.4,0.25" layer: [ Underplating ] - type: entity @@ -135,10 +132,9 @@ - type: InteractionOutline - type: Physics anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.3,-0.35,0.3,0.35" + shapes: + - !type:PhysShapeAabb + bounds: "-0.3,-0.35,0.3,0.35" mask: - Impassable - MobImpassable @@ -210,10 +206,9 @@ - key: enum.DisposalRouterUiKey.Key type: DisposalRouterBoundUserInterface - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.25" layer: [ Underplating ] - type: entity @@ -239,11 +234,10 @@ - type: Flippable entity: DisposalRouter - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.5" - layer: [ Underplating ] + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.5" + layer: [ Underplating ] - type: entity id: DisposalJunction @@ -269,11 +263,10 @@ - type: Flippable entity: DisposalJunctionFlipped - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.25" - layer: [ Underplating ] + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.25" + layer: [ Underplating ] - type: entity id: DisposalJunctionFlipped @@ -298,11 +291,10 @@ - type: Flippable entity: DisposalJunction - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.5" - layer: [ Underplating ] + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.5" + layer: [ Underplating ] - type: entity id: DisposalYJunction @@ -326,11 +318,10 @@ state_anchored: pipe-y state_broken: pipe-b - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.25,0.5" - layer: [ Underplating ] + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.25,0.5" + layer: [ Underplating ] - type: entity id: DisposalBend @@ -350,11 +341,10 @@ state_anchored: pipe-c state_broken: pipe-b - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.25,0.25" - layer: [ Underplating ] + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.25,0.25" + layer: [ Underplating ] - type: entity id: DisposalMailingUnit @@ -385,10 +375,9 @@ - type: InteractionOutline - type: Physics anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.35,-0.3,0.35,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.35,-0.3,0.35,0.3" mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml b/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml index f1dca4c97c..ab834372f2 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml @@ -18,15 +18,14 @@ - type: PowerReceiver powerLoad: 500 - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-1.5,-1.5,1.5,1.5" - layer: - - Opaque - - Impassable - - MobImpassable - - VaultImpassable + shapes: + - !type:PhysShapeAabb + bounds: "-1.5,-1.5,1.5,1.5" + layer: + - Opaque + - Impassable + - MobImpassable + - VaultImpassable - type: Clickable - type: InteractionOutline - type: Damageable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml b/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml index 6affcd1840..0bbd53ae00 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml @@ -9,11 +9,10 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.1, 0.5" - hard: false + hard: false + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.1, 0.5" mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/recycler.yml b/Resources/Prototypes/Entities/Constructible/Specific/recycler.yml index 83ce876c87..497cbcfd6a 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/recycler.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/recycler.yml @@ -8,11 +8,10 @@ - type: Clickable - type: InteractionOutline - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.49,-0.49,0.49,0.49" - hard: false + hard: false + shapes: + - !type:PhysShapeAabb + bounds: "-0.49,-0.49,0.49,0.49" layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Storage/Closets/closet.yml b/Resources/Prototypes/Entities/Constructible/Storage/Closets/closet.yml index 761e2e8eed..9cd07d8e32 100644 --- a/Resources/Prototypes/Entities/Constructible/Storage/Closets/closet.yml +++ b/Resources/Prototypes/Entities/Constructible/Storage/Closets/closet.yml @@ -21,12 +21,11 @@ soundHit: /Audio/Effects/bang.ogg - type: InteractionOutline - type: Physics - mass: 50 + mass: 25 anchored: false - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.25,0.5,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.25,0.5,0.25" mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Storage/Crates/crate_base.yml b/Resources/Prototypes/Entities/Constructible/Storage/Crates/crate_base.yml index 2ce86c8235..61c50e31d0 100644 --- a/Resources/Prototypes/Entities/Constructible/Storage/Crates/crate_base.yml +++ b/Resources/Prototypes/Entities/Constructible/Storage/Crates/crate_base.yml @@ -19,10 +19,9 @@ - type: Physics mass: 25 anchored: false - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4, -0.4, 0.29, 0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4, -0.4, 0.29, 0.4" mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Storage/StorageTanks/base_tank.yml b/Resources/Prototypes/Entities/Constructible/Storage/StorageTanks/base_tank.yml index 0c60fb356a..f66eba078d 100644 --- a/Resources/Prototypes/Entities/Constructible/Storage/StorageTanks/base_tank.yml +++ b/Resources/Prototypes/Entities/Constructible/Storage/StorageTanks/base_tank.yml @@ -7,12 +7,11 @@ - type: Clickable - type: InteractionOutline - type: Physics - mass: 100 + mass: 15 anchored: false - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Walls/asteroid.yml b/Resources/Prototypes/Entities/Constructible/Walls/asteroid.yml index c2a204db4d..d4b61d585e 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/asteroid.yml @@ -11,9 +11,8 @@ state: 0 - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb layer: [MobMask] - type: Damageable resistances: metallicResistances diff --git a/Resources/Prototypes/Entities/Constructible/Walls/atmos_plaque.yml b/Resources/Prototypes/Entities/Constructible/Walls/atmos_plaque.yml index 0b14d5319a..cca5f22640 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/atmos_plaque.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/atmos_plaque.yml @@ -4,10 +4,9 @@ name: Atmos Plaque components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.3,-0.3,0.3,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.3,-0.3,0.3,0.3" layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Walls/bar_sign.yml b/Resources/Prototypes/Entities/Constructible/Walls/bar_sign.yml index ff9466f2c5..99f1d83ffe 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/bar_sign.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/bar_sign.yml @@ -5,11 +5,10 @@ - type: Clickable - type: InteractionOutline - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.45, -0.95, 0.45, 1" - layer: [ Passable ] + shapes: + - !type:PhysShapeAabb + bounds: "-0.45, -0.95, 0.45, 1" + layer: [ Passable ] - type: Sprite drawdepth: WallTops sprite: Constructible/Misc/barsign.rsi diff --git a/Resources/Prototypes/Entities/Constructible/Walls/girder.yml b/Resources/Prototypes/Entities/Constructible/Walls/girder.yml index 2dda7e09e4..23949e8a83 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/girder.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/girder.yml @@ -16,9 +16,8 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml b/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml index 92ee1b8072..9bd69a5ab2 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml @@ -9,10 +9,9 @@ graph: lightFixture node: tubeLight - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.45, -0.15, 0.45, 0.35" + shapes: + - !type:PhysShapeAabb + bounds: "-0.45, -0.15, 0.45, 0.35" layer: [ Passable ] - type: LoopingSound - type: Sprite @@ -123,11 +122,10 @@ enabled: false offset: "0, -0.5" - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "0, 0, 0.25, 0.1" - layer: [ Passable ] + shapes: + - !type:PhysShapeAabb + bounds: "0, 0.1, 0.25, 0.1" + layer: [ Passable ] - type: PoweredLight bulb: Bulb - type: PowerReceiver diff --git a/Resources/Prototypes/Entities/Constructible/Walls/low_wall.yml b/Resources/Prototypes/Entities/Constructible/Walls/low_wall.yml index d429038da5..0830167dc2 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/low_wall.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/low_wall.yml @@ -20,9 +20,8 @@ sprite: Constructible/Structures/Walls/low_wall.rsi state: metal - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb layer: - VaultImpassable - SmallImpassable diff --git a/Resources/Prototypes/Entities/Constructible/Walls/mirror.yml b/Resources/Prototypes/Entities/Constructible/Walls/mirror.yml index c75982e644..d51a0b5add 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/mirror.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/mirror.yml @@ -9,9 +9,8 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb layer: [Clickable] - type: Clickable - type: InteractionOutline diff --git a/Resources/Prototypes/Entities/Constructible/Walls/signs.yml b/Resources/Prototypes/Entities/Constructible/Walls/signs.yml index 280ad330bb..d24fb79480 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/signs.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/signs.yml @@ -6,9 +6,8 @@ - type: Clickable - type: InteractionOutline - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb - type: Damageable resistances: metallicResistances - type: Destructible @@ -35,10 +34,9 @@ description: Return to monky. components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.1,-0.4,0.1,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.1,-0.4,0.1,0.4" layer: - Opaque - Impassable @@ -59,10 +57,9 @@ components: - type: Rotatable - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.1,-0.4,0.1,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.1,-0.4,0.1,0.4" layer: - Opaque - Impassable @@ -81,10 +78,9 @@ components: - type: Rotatable - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.1,-0.4,0.1,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.1,-0.4,0.1,0.4" layer: - Opaque - Impassable @@ -104,10 +100,9 @@ components: - type: Rotatable - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.1,-0.4,0.1,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.1,-0.4,0.1,0.4" layer: - Opaque - Impassable @@ -127,10 +122,9 @@ components: - type: Rotatable - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.1,-0.4,0.1,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.1,-0.4,0.1,0.4" layer: - Opaque - Impassable @@ -150,10 +144,9 @@ components: - type: Rotatable - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.1,-0.4,0.1,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.1,-0.4,0.1,0.4" layer: - Opaque - Impassable @@ -172,10 +165,9 @@ components: - type: Rotatable - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.1,-0.4,0.1,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.1,-0.4,0.1,0.4" layer: - Opaque - Impassable @@ -194,10 +186,9 @@ components: - type: Rotatable - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.1,-0.4,0.1,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.1,-0.4,0.1,0.4" layer: - Opaque - Impassable @@ -217,10 +208,9 @@ name: armory sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -238,10 +228,9 @@ name: tool storage sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -259,10 +248,9 @@ name: anomaly lab sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -280,10 +268,9 @@ name: atmos sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -301,10 +288,9 @@ name: bar sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -322,10 +308,9 @@ name: library sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -343,10 +328,9 @@ name: chapel sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -364,10 +348,9 @@ name: head sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -385,10 +368,9 @@ name: conference room sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -406,10 +388,9 @@ name: drones sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -427,10 +408,9 @@ name: engine sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -448,10 +428,9 @@ name: cloning sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -469,10 +448,9 @@ name: interrogation sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -490,10 +468,9 @@ name: surgery sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -511,10 +488,9 @@ name: telecomms sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -532,10 +508,9 @@ name: cargo sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -553,10 +528,9 @@ name: cargo dock sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -574,10 +548,9 @@ name: chemistry sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -595,10 +568,9 @@ name: docking sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -616,10 +588,9 @@ name: engineering sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -637,10 +608,9 @@ name: EVA sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -658,10 +628,9 @@ name: gravity sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -679,10 +648,9 @@ name: medbay sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -700,10 +668,9 @@ name: morgue sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -721,10 +688,9 @@ name: prison sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -742,10 +708,9 @@ name: research and development sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -763,10 +728,9 @@ name: science sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -784,10 +748,9 @@ name: toxins sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -805,10 +768,9 @@ name: bridge sign components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -829,10 +791,9 @@ description: WARNING! Air flow tube. Ensure the flow is disengaged before working. components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.2,-0.3,0.2,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.2,-0.3,0.2,0.3" layer: - Opaque - Impassable @@ -851,10 +812,9 @@ description: WARNING! CO2 flow tube. Ensure the flow is disengaged before working. components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.2,-0.3,0.2,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.2,-0.3,0.2,0.3" layer: - Opaque - Impassable @@ -873,10 +833,9 @@ description: WARNING! N2 flow tube. Ensure the flow is disengaged before working. components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.2,-0.3,0.2,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.2,-0.3,0.2,0.3" layer: - Opaque - Impassable @@ -895,10 +854,9 @@ description: WARNING! N2O flow tube. Ensure the flow is disengaged before working. components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.2,-0.3,0.2,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.2,-0.3,0.2,0.3" layer: - Opaque - Impassable @@ -917,10 +875,9 @@ description: WARNING! O2 flow tube. Ensure the flow is disengaged before working. components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.2,-0.3,0.2,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.2,-0.3,0.2,0.3" layer: - Opaque - Impassable @@ -939,10 +896,9 @@ description: WARNING! Plasma flow tube. Ensure the flow is disengaged before working. components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.2,-0.3,0.2,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.2,-0.3,0.2,0.3" layer: - Opaque - Impassable @@ -961,10 +917,9 @@ description: WARNING! Waste flow tube. Ensure the flow is disengaged before working. components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.2,-0.3,0.2,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.2,-0.3,0.2,0.3" layer: - Opaque - Impassable @@ -983,10 +938,9 @@ description: A warning sign which reads 'NO SMOKING' components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -1005,10 +959,9 @@ description: Technical information of some sort, shame its too worn-out to read. components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable @@ -1027,10 +980,9 @@ description: Looks like a planet crashing by some station above it. Its kinda scary. components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.3,0.4,0.3" + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.3,0.4,0.3" layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Walls/walls.yml b/Resources/Prototypes/Entities/Constructible/Walls/walls.yml index 2def6a2cc3..7d03b952c1 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/walls.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/walls.yml @@ -20,11 +20,8 @@ - type: Icon state: full - type: Physics - bodyType: Static - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Constructible/Walls/windows.yml b/Resources/Prototypes/Entities/Constructible/Walls/windows.yml index cd7a56bfd0..3df6bbd30f 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/windows.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/windows.yml @@ -19,10 +19,8 @@ sprite: Constructible/Structures/Windows/window.rsi state: full - type: Physics - bodyType: Static - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb layer: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 8b7a9b2102..a0bdefb634 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -16,10 +16,9 @@ - type: Physics anchored: false mass: 50 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.30,-0.25,0.40,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.30,-0.25,0.40,0.25" mask: - Impassable - VaultImpassable @@ -50,10 +49,9 @@ - type: Physics anchored: false mass: 90 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.90,-0.50,0.05,0.50" + shapes: + - !type:PhysShapeAabb + bounds: "-0.90,-0.50,0.05,0.50" mask: - Impassable - VaultImpassable @@ -81,10 +79,9 @@ - type: Physics anchored: false mass: 20 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.45,-0.20,0.10,0.20" + shapes: + - !type:PhysShapeAabb + bounds: "-0.45,-0.20,0.10,0.20" mask: - Impassable - VaultImpassable @@ -115,10 +112,9 @@ - type: Physics anchored: false mass: 5 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.20,-0.20,0.20,0.20" + shapes: + - !type:PhysShapeAabb + bounds: "-0.20,-0.20,0.20,0.20" mask: - Impassable - VaultImpassable @@ -159,10 +155,9 @@ - type: Physics anchored: false mass: 5 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.20,-0.20,0.20,0.20" + shapes: + - !type:PhysShapeAabb + bounds: "-0.20,-0.20,0.20,0.20" mask: - Impassable - VaultImpassable @@ -194,10 +189,9 @@ - type: Physics anchored: false mass: 5 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.10,-0.10,0.10,0.10" + shapes: + - !type:PhysShapeAabb + bounds: "-0.10,-0.10,0.10,0.10" mask: - Impassable - VaultImpassable @@ -225,10 +219,9 @@ - type: Physics anchored: false mass: 20 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.60,-0.50,0.05,0.50" + shapes: + - !type:PhysShapeAabb + bounds: "-0.60,-0.50,0.05,0.50" mask: - Impassable - VaultImpassable @@ -257,10 +250,9 @@ - type: Physics anchored: false mass: 20 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.45,-0.35,0.45,0.35" + shapes: + - !type:PhysShapeAabb + bounds: "-0.45,-0.35,0.45,0.35" mask: - Impassable - VaultImpassable @@ -292,10 +284,9 @@ - type: Physics anchored: false mass: 20 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.30,-0.35,0.35,0.35" + shapes: + - !type:PhysShapeAabb + bounds: "-0.30,-0.35,0.35,0.35" mask: - Impassable - VaultImpassable @@ -323,10 +314,9 @@ - type: Physics anchored: false mass: 10 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.30,-0.30,0.25,0.30" + shapes: + - !type:PhysShapeAabb + bounds: "-0.30,-0.30,0.25,0.30" mask: - Impassable - VaultImpassable @@ -357,10 +347,9 @@ - type: Physics anchored: false mass: 10 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.30,-0.40,0.45,0.40" + shapes: + - !type:PhysShapeAabb + bounds: "-0.30,-0.40,0.45,0.40" mask: - Impassable - VaultImpassable @@ -388,10 +377,9 @@ - type: Physics anchored: false mass: 10 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.40,-0.35,0.20,0.35" + shapes: + - !type:PhysShapeAabb + bounds: "-0.40,-0.35,0.20,0.35" mask: - Impassable - VaultImpassable @@ -419,10 +407,9 @@ - type: Physics anchored: false mass: 10 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.50,-0.30,0.35,0.30" + shapes: + - !type:PhysShapeAabb + bounds: "-0.50,-0.30,0.35,0.30" mask: - Impassable - VaultImpassable diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml index c7cec774da..a326dce431 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml @@ -20,10 +20,9 @@ - type: Physics anchored: false mass: 50 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.35,-0.35,0.35,0.35" + shapes: + - !type:PhysShapeAabb + bounds: "-0.35,-0.35,0.35,0.35" mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml b/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml index fd29584ba4..7d602aeccd 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml @@ -24,10 +24,9 @@ - type: Physics anchored: false mass: 85 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.35,-0.35,0.35,0.35" + shapes: + - !type:PhysShapeAabb + bounds: "-0.35,-0.35,0.35,0.35" mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml index 99b904fd54..310f55ce1e 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml @@ -15,10 +15,9 @@ state: corgi - type: Physics mass: 10 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.50,-0.25,0.30,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.50,-0.25,0.30,0.25" mask: - Impassable - VaultImpassable @@ -63,10 +62,9 @@ state: cat - type: Physics mass: 10 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.45,-0.20,0.30,0.20" + shapes: + - !type:PhysShapeAabb + bounds: "-0.45,-0.20,0.30,0.20" mask: - Impassable - VaultImpassable @@ -114,10 +112,9 @@ state: sloth - type: Physics mass: 10 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.45,-0.35,0.15,0.35" + shapes: + - !type:PhysShapeAabb + bounds: "-0.45,-0.35,0.15,0.35" mask: - Impassable - VaultImpassable diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml index db8d44b526..88422cd83e 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml @@ -32,9 +32,8 @@ - type: Physics anchored: false mass: 50 - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb mask: - Impassable # - MobImpassable Turns these off for now since humans don't have collisions either. diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index 57d4ffcf3b..cca996bacc 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -22,10 +22,9 @@ - type: Physics anchored: false mass: 85 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-1,-0.4,-0.2,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-1,-0.4,-0.2,0.4" mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml index 26377a68a1..f559eaab3d 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml @@ -4,6 +4,3 @@ id: AdminObserver name: admin observer abstract: true - components: - - type: PlayerInputMover - ignorePaused: true diff --git a/Resources/Prototypes/Entities/Mobs/Player/human.yml b/Resources/Prototypes/Entities/Mobs/Player/human.yml index 3a199a6d52..6f9e3adc25 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/human.yml @@ -10,8 +10,6 @@ showExamineInfo: true - type: Input context: "human" - - type: PlayerMobMover - - type: PlayerInputMover - type: Alerts - type: Actions innateActions: diff --git a/Resources/Prototypes/Entities/Mobs/Player/observer.yml b/Resources/Prototypes/Entities/Mobs/Player/observer.yml index ff0ac0dcf9..c8ff82560a 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/observer.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/observer.yml @@ -11,10 +11,9 @@ - type: Physics anchored: false mass: 5 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.35,-0.35,0.35,0.35" + shapes: + - !type:PhysShapeAabb + bounds: "-0.35,-0.35,0.35,0.35" mask: - GhostImpassable status: InAir diff --git a/Resources/Prototypes/Entities/Mobs/Species/human.yml b/Resources/Prototypes/Entities/Mobs/Species/human.yml index 9c18c3b5c7..b012d0ec83 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/human.yml @@ -117,14 +117,11 @@ - map: [ "enum.Slots.MASK" ] - map: [ "enum.Slots.HEAD" ] - type: Physics - bodyType: Kinematic anchored: false - mass: 70 - fixtures: - - shape: - !type:PhysShapeCircle - radius: 0.35 - restitution: 0.0 + mass: 85 + shapes: + - !type:PhysShapeAabb + bounds: "-0.35,-0.35,0.35,0.35" mask: - Impassable - MobImpassable @@ -132,6 +129,7 @@ layer: - Opaque - MobImpassable + - type: PlayerInputMover - type: AtmosExposed - type: Flammable fireSpread: true @@ -303,10 +301,9 @@ - type: Physics anchored: false mass: 85 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.35,-0.35,0.35,0.35" + shapes: + - !type:PhysShapeAabb + bounds: "-0.35,-0.35,0.35,0.35" mask: - Impassable - MobImpassable diff --git a/Resources/Prototypes/Entities/Objects/Consumable/trash.yml b/Resources/Prototypes/Entities/Objects/Consumable/trash.yml index 218bf91b77..deabc3b5df 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/trash.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/trash.yml @@ -183,9 +183,8 @@ - type: Slippery intersectPercentage: 0.2 - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.2,-0.2,0.2,0.2" + shapes: + - !type:PhysShapeAabb + bounds: "-0.2,-0.2,0.2,0.2" layer: - MobImpassable diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index 7b06ab0acd..925fa649a3 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -86,10 +86,9 @@ - type: Slippery paralyzeTime: 4 - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.25,0.25,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.25,-0.25,0.25,0.25" layer: - MobImpassable diff --git a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml index 0069a1c5b5..77c85606d3 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml @@ -48,15 +48,14 @@ - state: extinguish map: [ "enum.VaporVisualLayers.Base" ] - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.25,0.25,0.25" - hard: false - mask: - - Impassable - - MobImpassable - - SmallImpassable + hard: false + shapes: + - !type:PhysShapeAabb + bounds: "-0.25,-0.25,0.25,0.25" + mask: + - Impassable + - MobImpassable + - SmallImpassable - type: Appearance visuals: - type: VaporVisualizer diff --git a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml index 81b3b2c0c5..cf65ad75aa 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml @@ -87,9 +87,8 @@ shader: unshaded visible: false - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb layer: - Opaque - Impassable @@ -150,9 +149,8 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb layer: - Opaque - Impassable diff --git a/Resources/Prototypes/Entities/Objects/Misc/teleporters.yml b/Resources/Prototypes/Entities/Objects/Misc/teleporters.yml index f53b0053bc..c6b42d9d33 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/teleporters.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/teleporters.yml @@ -49,9 +49,8 @@ description: "Portal to another location." components: - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb {} + shapes: + - !type:PhysShapeAabb mask: [Impassable, MobImpassable] - type: Portal - type: Sprite diff --git a/Resources/Prototypes/Entities/Objects/Power/powercells.yml b/Resources/Prototypes/Entities/Objects/Power/powercells.yml index cb55931f31..ca78abb98f 100644 --- a/Resources/Prototypes/Entities/Objects/Power/powercells.yml +++ b/Resources/Prototypes/Entities/Objects/Power/powercells.yml @@ -8,10 +8,9 @@ components: - type: Physics anchored: false - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.15,-0.3,0.2,0.3" # TODO: these are placeholder values + shapes: + - !type:PhysShapeAabb + bounds: "-0.15,-0.3,0.2,0.3" # TODO: these are placeholder values layer: - Clickable - type: PowerCell @@ -323,10 +322,9 @@ - type: InteractionOutline - type: Physics mass: 5 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.25,0.25,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.25,-0.25,0.25,0.25" mask: [Impassable] layer: [Clickable] @@ -352,10 +350,9 @@ - type: InteractionOutline - type: Physics mass: 5 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.25,0.25,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.25,-0.25,0.25,0.25" mask: [Impassable] layer: [Clickable] @@ -380,9 +377,8 @@ - type: InteractionOutline - type: Physics mass: 5 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.25,0.25,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.25,-0.25,0.25,0.25" mask: [Impassable] layer: [Clickable] diff --git a/Resources/Prototypes/Entities/Objects/Specific/janitor.yml b/Resources/Prototypes/Entities/Objects/Specific/janitor.yml index 10151fbc20..22e348823b 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/janitor.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/janitor.yml @@ -41,10 +41,9 @@ - type: Physics mass: 5 anchored: false - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.40,-0.25,0.25,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.40,-0.25,0.25,0.25" mask: - Impassable - Opaque @@ -72,10 +71,9 @@ - type: Physics mass: 5 anchored: false - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.25,0.25,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.25,-0.25,0.25,0.25" mask: - Impassable - type: Spillable @@ -106,10 +104,9 @@ - type: Slippery paralyzeTime: 2.5 - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.3,-0.4,0.3,0.4" + shapes: + - !type:PhysShapeAabb + bounds: "-0.3,-0.4,0.3,0.4" layer: - MobImpassable @@ -182,15 +179,14 @@ map: [ "enum.VaporVisualLayers.Base" ] - type: Physics anchored: false - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.25,0.25,0.25" - hard: false - mask: - - Impassable - - MobImpassable - - SmallImpassable + hard: false + shapes: + - !type:PhysShapeAabb + bounds: "-0.25,-0.25,0.25,0.25" + mask: + - Impassable + - MobImpassable + - SmallImpassable - type: Appearance visuals: - type: VaporVisualizer diff --git a/Resources/Prototypes/Entities/Objects/Specific/morgue.yml b/Resources/Prototypes/Entities/Objects/Specific/morgue.yml index 323ba4c005..efbd62ae2c 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/morgue.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/morgue.yml @@ -21,10 +21,9 @@ - type: Physics mass: 5 anchored: false - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.45,-0.5,0.1,0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.45,-0.5,0.1,0.5" layer: - Clickable - type: BodyBagEntityStorage @@ -39,7 +38,7 @@ state_closed: bag - type: BodyBagVisualizer - type: Pullable - + - type: entity id: BodyBag_Item name: body bag @@ -54,8 +53,8 @@ # - type: Placeable # prototype: someId # snap: Center - - + + - type: entity id: Morgue name: morgue @@ -76,10 +75,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" mask: - Impassable - MobImpassable @@ -107,7 +105,7 @@ light_soul: morgue_soul_light - type: SnapGrid offset: Center - + - type: entity id: MorgueTray name: morgue tray @@ -122,10 +120,9 @@ - type: Physics mass: 15 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" layer: - Clickable - type: MorgueTray @@ -151,10 +148,9 @@ - type: Physics mass: 25 anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" mask: - Impassable - MobImpassable @@ -183,7 +179,7 @@ light_burning: crema_active_light - type: SnapGrid offset: Center - + - type: entity id: CrematoriumTray name: crematorium tray @@ -203,4 +199,4 @@ - type: Sprite netsync: false sprite: Objects/Consumable/Trash/ash.rsi - state: icon + state: icon \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml index 2a70ec8a0d..bd3d175dea 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml @@ -14,11 +14,10 @@ - type: Physics anchored: false edgeslide: false - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.1,-0.1,0.1,0.1" - hard: false + hard: false + shapes: + - !type:PhysShapeAabb + bounds: "-0.1,-0.1,0.1,0.1" layer: [Clickable] mask: - Impassable @@ -100,11 +99,10 @@ - type: Physics anchored: false edgeslide: false - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.2,-0.2,0.2,0.2" - hard: false + hard: false + shapes: + - !type:PhysShapeAabb + bounds: "-0.2,-0.2,0.2,0.2" layer: 32 mask: 30 diff --git a/Resources/Prototypes/Entities/base_item.yml b/Resources/Prototypes/Entities/base_item.yml index 34799209a1..4425aebf80 100644 --- a/Resources/Prototypes/Entities/base_item.yml +++ b/Resources/Prototypes/Entities/base_item.yml @@ -9,23 +9,14 @@ - type: InteractionOutline - type: MovedByPressure - type: DamageOnHighSpeedImpact - - type: CollisionWake - - type: TileFrictionModifier - modifier: 0.5 - type: Physics anchored: false mass: 5 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.25,0.25,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.25,-0.25,0.25,0.25" layer: - Clickable - mask: - - Impassable - - SmallImpassable - restitution: 0.8 # We want them items B O U N C Y - friction: 0.2 - type: Sprite drawdepth: Items - type: Pullable diff --git a/Resources/Prototypes/Entities/puddle.yml b/Resources/Prototypes/Entities/puddle.yml index e6df04d03b..1cb3ec9b43 100644 --- a/Resources/Prototypes/Entities/puddle.yml +++ b/Resources/Prototypes/Entities/puddle.yml @@ -16,13 +16,12 @@ - type: Clickable - type: Slippery - type: Physics - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.4,0.4,0.4" - hard: false + shapes: + - !type:PhysShapeAabb + bounds: "-0.4,-0.4,0.4,0.4" layer: - MobImpassable + hard: false - type: entity name: puddle diff --git a/Resources/Prototypes/Entities/singularity.yml b/Resources/Prototypes/Entities/singularity.yml index 5be8d5b486..e1576249ed 100644 --- a/Resources/Prototypes/Entities/singularity.yml +++ b/Resources/Prototypes/Entities/singularity.yml @@ -6,13 +6,10 @@ - type: Clickable - type: Physics anchored: false - fixtures: - - shape: - !type:PhysShapeCircle - radius: 0.5 - hard: false - layer: - - MapGrid + shapes: + - !type:PhysShapeCircle + radius: 0.5 + layer: [Impassable] mask: - AllMask mass: 5 @@ -39,10 +36,9 @@ - type: InteractionOutline - type: Physics anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" layer: [MobMask, Opaque] - type: SnapGrid offset: Center @@ -74,10 +70,9 @@ - type: Clickable - type: Physics anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" layer: [MobMask, Opaque] - type: SnapGrid offset: Center @@ -108,10 +103,9 @@ - type: Clickable - type: Physics anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" layer: [MobMask, Opaque] - type: SnapGrid offset: Center @@ -136,10 +130,9 @@ - type: Clickable - type: Physics anchored: true - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.5, -0.5, 0.5, 0.5" + shapes: + - !type:PhysShapeAabb + bounds: "-0.5, -0.5, 0.5, 0.5" layer: [ MobMask ] - type: SnapGrid offset: Center diff --git a/Resources/Prototypes/Entities/traitordm.yml b/Resources/Prototypes/Entities/traitordm.yml index a0c34e96aa..bdd92fe792 100644 --- a/Resources/Prototypes/Entities/traitordm.yml +++ b/Resources/Prototypes/Entities/traitordm.yml @@ -15,10 +15,9 @@ - type: Physics anchored: true mass: 1 - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.25,0.25,0.25" + shapes: + - !type:PhysShapeAabb + bounds: "-0.25,-0.25,0.25,0.25" layer: - Clickable - type: TraitorDeathMatchRedemption