Content update for ECS physics (#13291)

This commit is contained in:
metalgearsloth
2023-01-15 15:38:59 +11:00
committed by GitHub
parent 46d24bc36b
commit bf79d76666
61 changed files with 431 additions and 379 deletions

View File

@@ -68,7 +68,8 @@ namespace Content.Client.Suspicion
}
_overlayActive = true;
var overlay = new TraitorOverlay(IoCManager.Resolve<IEntityManager>(), IoCManager.Resolve<IPlayerManager>(), _resourceCache);
var entManager = IoCManager.Resolve<IEntityManager>();
var overlay = new TraitorOverlay(entManager, IoCManager.Resolve<IPlayerManager>(), _resourceCache, entManager.System<EntityLookupSystem>());
_overlayManager.AddOverlay(overlay);
}

View File

@@ -17,6 +17,7 @@ namespace Content.Client.Suspicion
{
private readonly IEntityManager _entityManager;
private readonly IPlayerManager _playerManager;
private readonly EntityLookupSystem _lookup;
public override OverlaySpace Space => OverlaySpace.ScreenSpace;
private readonly Font _font;
@@ -26,11 +27,12 @@ namespace Content.Client.Suspicion
public TraitorOverlay(
IEntityManager entityManager,
IPlayerManager playerManager,
IResourceCache resourceCache)
IResourceCache resourceCache,
EntityLookupSystem lookup)
{
_playerManager = playerManager;
_entityManager = entityManager;
_lookup = lookup;
_font = new VectorFont(resourceCache.GetResource<FontResource>("/Fonts/NotoSans/NotoSans-Regular.ttf"), 10);
}
@@ -77,7 +79,7 @@ namespace Content.Client.Suspicion
var (allyWorldPos, allyWorldRot) = allyXform.GetWorldPositionRotation();
var worldBox = physics.GetWorldAABB(allyWorldPos, allyWorldRot);
var worldBox = _lookup.GetWorldAABB(ally, allyXform);
// if not on screen, or too small, continue
if (!worldBox.Intersects(in viewport) || worldBox.IsEmpty())

View File

@@ -6,8 +6,10 @@ using Content.Shared.Doors.Components;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
namespace Content.IntegrationTests.Tests.Doors
{
@@ -114,6 +116,7 @@ namespace Content.IntegrationTests.Tests.Doors
var mapManager = server.ResolveDependency<IMapManager>();
var entityManager = server.ResolveDependency<IEntityManager>();
var physicsSystem = entityManager.System<SharedPhysicsSystem>();
PhysicsComponent physBody = null;
EntityUid physicsDummy = default;
@@ -140,13 +143,19 @@ namespace Content.IntegrationTests.Tests.Doors
await server.WaitIdleAsync();
// Push the human towards the airlock
await server.WaitAssertion(() => Assert.That(physBody != null));
await server.WaitPost(() => physBody.LinearVelocity = (0.5f, 0));
await server.WaitAssertion(() => Assert.That(physBody, Is.Not.EqualTo(null)));
await server.WaitPost(() =>
{
physicsSystem.SetLinearVelocity(physicsDummy, new Vector2(0.5f, 0f), body: physBody);
});
for (var i = 0; i < 240; i += 10)
{
// Keep the airlock awake so they collide
await server.WaitPost(() => entityManager.GetComponent<PhysicsComponent>(airlock).WakeBody());
await server.WaitPost(() =>
{
physicsSystem.WakeBody(airlock);
});
await server.WaitRunTicks(10);
await server.WaitIdleAsync();

View File

@@ -6,6 +6,7 @@ using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
namespace Content.IntegrationTests.Tests
{
@@ -20,7 +21,8 @@ namespace Content.IntegrationTests.Tests
await server.WaitIdleAsync();
var mapMan = server.ResolveDependency<IMapManager>();
var sEntities = server.ResolveDependency<IEntityManager>();
var entManager = server.ResolveDependency<IEntityManager>();
var physicsSystem = entManager.System<SharedPhysicsSystem>();
EntityUid gridEnt = default;
@@ -30,18 +32,18 @@ namespace Content.IntegrationTests.Tests
var grid = mapMan.CreateGrid(mapId);
gridEnt = grid.Owner;
Assert.That(sEntities.HasComponent<ShuttleComponent>(gridEnt));
Assert.That(sEntities.TryGetComponent<PhysicsComponent>(gridEnt, out var physicsComponent));
Assert.That(entManager.HasComponent<ShuttleComponent>(gridEnt));
Assert.That(entManager.TryGetComponent<PhysicsComponent>(gridEnt, out var physicsComponent));
Assert.That(physicsComponent!.BodyType, Is.EqualTo(BodyType.Dynamic));
Assert.That(sEntities.GetComponent<TransformComponent>(gridEnt).LocalPosition, Is.EqualTo(Vector2.Zero));
physicsComponent.ApplyLinearImpulse(Vector2.One);
Assert.That(entManager.GetComponent<TransformComponent>(gridEnt).LocalPosition, Is.EqualTo(Vector2.Zero));
physicsSystem.ApplyLinearImpulse(gridEnt, Vector2.One, body: physicsComponent);
});
await server.WaitRunTicks(1);
await server.WaitAssertion(() =>
{
Assert.That<Vector2?>(sEntities.GetComponent<TransformComponent>(gridEnt).LocalPosition, Is.Not.EqualTo(Vector2.Zero));
Assert.That(entManager.GetComponent<TransformComponent>(gridEnt).LocalPosition, Is.Not.EqualTo(Vector2.Zero));
});
await pairTracker.CleanReturnAsync();
}

View File

@@ -9,12 +9,15 @@ using Robust.Shared.Enums;
using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
namespace Content.Server.Administration.Commands
{
[AdminCommand(AdminFlags.Admin)]
public sealed class WarpCommand : IConsoleCommand
{
[Dependency] private readonly IEntityManager _entManager = default!;
public string Command => "warp";
public string Description => "Teleports you to predefined areas on the map.";
@@ -37,11 +40,10 @@ namespace Content.Server.Administration.Commands
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
var location = args[0];
if (location == "?")
{
var locations = string.Join(", ", GetWarpPointNames(entMan));
var locations = string.Join(", ", GetWarpPointNames());
shell.WriteLine(locations);
}
@@ -53,20 +55,19 @@ namespace Content.Server.Administration.Commands
return;
}
var mapManager = IoCManager.Resolve<IMapManager>();
var currentMap = entMan.GetComponent<TransformComponent>(playerEntity).MapID;
var currentGrid = entMan.GetComponent<TransformComponent>(playerEntity).GridUid;
var currentMap = _entManager.GetComponent<TransformComponent>(playerEntity).MapID;
var currentGrid = _entManager.GetComponent<TransformComponent>(playerEntity).GridUid;
var found = entMan.EntityQuery<WarpPointComponent>(true)
var found = _entManager.EntityQuery<WarpPointComponent>(true)
.Where(p => p.Location == location)
.Select(p => (entMan.GetComponent<TransformComponent>(p.Owner).Coordinates, p.Follow))
.Select(p => (_entManager.GetComponent<TransformComponent>(p.Owner).Coordinates, p.Follow))
.OrderBy(p => p.Item1, Comparer<EntityCoordinates>.Create((a, b) =>
{
// Sort so that warp points on the same grid/map are first.
// So if you have two maps loaded with the same warp points,
// it will prefer the warp points on the map you're currently on.
var aGrid = a.GetGridUid(entMan);
var bGrid = b.GetGridUid(entMan);
var aGrid = a.GetGridUid(_entManager);
var bGrid = b.GetGridUid(_entManager);
if (aGrid == bGrid)
{
@@ -83,8 +84,8 @@ namespace Content.Server.Administration.Commands
return 1;
}
var mapA = a.GetMapId(entMan);
var mapB = a.GetMapId(entMan);
var mapA = a.GetMapId(_entManager);
var mapB = a.GetMapId(_entManager);
if (mapA == mapB)
{
@@ -113,25 +114,25 @@ namespace Content.Server.Administration.Commands
return;
}
if (follow && entMan.HasComponent<GhostComponent>(playerEntity))
if (follow && _entManager.HasComponent<GhostComponent>(playerEntity))
{
entMan.EntitySysManager.GetEntitySystem<FollowerSystem>().StartFollowingEntity(playerEntity, coords.EntityId);
_entManager.System<FollowerSystem>().StartFollowingEntity(playerEntity, coords.EntityId);
return;
}
var xform = entMan.GetComponent<TransformComponent>(playerEntity);
var xform = _entManager.GetComponent<TransformComponent>(playerEntity);
xform.Coordinates = coords;
xform.AttachToGridOrMap();
if (entMan.TryGetComponent(playerEntity, out PhysicsComponent? physics))
if (_entManager.TryGetComponent(playerEntity, out PhysicsComponent? physics))
{
physics.LinearVelocity = Vector2.Zero;
_entManager.System<SharedPhysicsSystem>().SetLinearVelocity(playerEntity, Vector2.Zero, body: physics);
}
}
}
private static IEnumerable<string> GetWarpPointNames(IEntityManager entMan)
private IEnumerable<string> GetWarpPointNames()
{
return entMan.EntityQuery<WarpPointComponent>(true)
return _entManager.EntityQuery<WarpPointComponent>(true)
.Select(p => p.Location)
.Where(p => p != null)
.OrderBy(p => p)
@@ -142,8 +143,7 @@ namespace Content.Server.Administration.Commands
{
if (args.Length == 1)
{
var ent = IoCManager.Resolve<IEntityManager>();
var options = new[] { "?" }.Concat(GetWarpPointNames(ent));
var options = new[] { "?" }.Concat(GetWarpPointNames());
return CompletionResult.FromHintOptions(options, "<warp point | ?>");
}

View File

@@ -47,6 +47,7 @@ using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Player;
using Robust.Shared.Random;
using Timer = Robust.Shared.Timing.Timer;
@@ -63,18 +64,20 @@ public sealed partial class AdminVerbSystem
[Dependency] private readonly ElectrocutionSystem _electrocutionSystem = default!;
[Dependency] private readonly EntityStorageSystem _entityStorageSystem = default!;
[Dependency] private readonly ExplosionSystem _explosionSystem = default!;
[Dependency] private readonly FixtureSystem _fixtures = default!;
[Dependency] private readonly FlammableSystem _flammableSystem = default!;
[Dependency] private readonly GhostKickManager _ghostKickManager = default!;
[Dependency] private readonly GodmodeSystem _godmodeSystem = default!;
[Dependency] private readonly InventorySystem _inventorySystem = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
[Dependency] private readonly PolymorphableSystem _polymorphableSystem = default!;
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
[Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly TabletopSystem _tabletopSystem = default!;
[Dependency] private readonly VomitSystem _vomitSystem = default!;
[Dependency] private readonly WeldableSystem _weldableSystem = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
// All smite verbs have names so invokeverb works.
private void AddSmiteVerbs(GetVerbsEvent<Verb> args)
@@ -422,20 +425,24 @@ public sealed partial class AdminVerbSystem
var xform = Transform(args.Target);
var fixtures = Comp<FixturesComponent>(args.Target);
xform.Anchored = false; // Just in case.
physics.BodyType = BodyType.Dynamic;
physics.BodyStatus = BodyStatus.InAir;
physics.WakeBody();
foreach (var (_, fixture) in fixtures.Fixtures)
_physics.SetBodyType(args.Target, BodyType.Dynamic, manager: fixtures, body: physics);
_physics.SetBodyStatus(physics, BodyStatus.InAir);
_physics.WakeBody(args.Target, manager: fixtures, body: physics);
foreach (var fixture in fixtures.Fixtures.Values)
{
if (!fixture.Hard)
continue;
fixture.Restitution = 1.1f;
_physics.SetRestitution(args.Target, fixture, 1.1f, false, fixtures);
}
physics.LinearVelocity = _random.NextVector2(1.5f, 1.5f);
physics.AngularVelocity = MathF.PI * 12;
physics.LinearDamping = 0.0f;
physics.AngularDamping = 0.0f;
_fixtures.FixtureUpdate(args.Target, manager: fixtures, body: physics);
_physics.SetLinearVelocity(args.Target, _random.NextVector2(1.5f, 1.5f), manager: fixtures, body: physics);
_physics.SetAngularVelocity(args.Target, MathF.PI * 12, manager: fixtures, body: physics);
_physics.SetLinearDamping(physics, 0f);
_physics.SetAngularDamping(physics, 0f);
},
Impact = LogImpact.Extreme,
Message = Loc.GetString("admin-smite-pinball-description")
@@ -452,18 +459,20 @@ public sealed partial class AdminVerbSystem
var xform = Transform(args.Target);
var fixtures = Comp<FixturesComponent>(args.Target);
xform.Anchored = false; // Just in case.
physics.BodyType = BodyType.Dynamic;
physics.BodyStatus = BodyStatus.InAir;
physics.WakeBody();
foreach (var (_, fixture) in fixtures.Fixtures)
_physics.SetBodyType(args.Target, BodyType.Dynamic, body: physics);
_physics.SetBodyStatus(physics, BodyStatus.InAir);
_physics.WakeBody(args.Target, manager: fixtures, body: physics);
foreach (var fixture in fixtures.Fixtures.Values)
{
fixture.Hard = false;
_physics.SetHard(args.Target, fixture, false, manager: fixtures);
}
physics.LinearVelocity = _random.NextVector2(8.0f, 8.0f);
physics.AngularVelocity = MathF.PI * 12;
physics.LinearDamping = 0.0f;
physics.AngularDamping = 0.0f;
_physics.SetLinearVelocity(args.Target, _random.NextVector2(8.0f, 8.0f), manager: fixtures, body: physics);
_physics.SetAngularVelocity(args.Target, MathF.PI * 12, manager: fixtures, body: physics);
_physics.SetLinearDamping(physics, 0f);
_physics.SetAngularDamping(physics, 0f);
},
Impact = LogImpact.Extreme,
Message = Loc.GetString("admin-smite-yeet-description")

View File

@@ -679,8 +679,8 @@ public sealed partial class AdminVerbSystem
IconTexture = "/Textures/Interface/AdminActions/halt.png",
Act = () =>
{
physics.LinearVelocity = Vector2.Zero;
physics.AngularVelocity = 0.0f;
_physics.SetLinearVelocity(args.Target, Vector2.Zero, body: physics);
_physics.SetAngularVelocity(args.Target, 0f, body: physics);
},
Impact = LogImpact.Medium,
Message = Loc.GetString("admin-trick-halt-movement-description"),

View File

@@ -34,6 +34,6 @@ namespace Content.Server.Atmos.Components
/// Used for the fixture created to handle passing firestacks when two flammable objects collide.
/// </summary>
[DataField("flammableCollisionShape")]
public IPhysShape FlammableCollisionShape = new PhysShapeCircle() { Radius = 0.35f };
public IPhysShape FlammableCollisionShape = new PhysShapeCircle(0.35f);
}
}

View File

@@ -30,15 +30,16 @@ namespace Content.Server.Atmos.EntitySystems
foreach (var comp in _activePressures)
{
var uid = comp.Owner;
MetaDataComponent? metadata = null;
if (Deleted(comp.Owner, metadata))
if (Deleted(uid, metadata))
{
toRemove.Add(comp);
continue;
}
if (Paused(comp.Owner, metadata)) continue;
if (Paused(uid, metadata)) continue;
comp.Accumulator += frameTime;
@@ -48,17 +49,17 @@ namespace Content.Server.Atmos.EntitySystems
comp.Accumulator = 0f;
toRemove.Add(comp);
if (HasComp<MobStateComponent>(comp.Owner) &&
TryComp<PhysicsComponent>(comp.Owner, out var body))
if (HasComp<MobStateComponent>(uid) &&
TryComp<PhysicsComponent>(uid, out var body))
{
body.BodyStatus = BodyStatus.OnGround;
_physics.SetBodyStatus(body, BodyStatus.OnGround);
}
if (TryComp<FixturesComponent>(comp.Owner, out var fixtures))
if (TryComp<FixturesComponent>(uid, out var fixtures))
{
foreach (var (_, fixture) in fixtures.Fixtures)
foreach (var fixture in fixtures.Fixtures.Values)
{
_physics.AddCollisionMask(fixtures, fixture, (int) CollisionGroup.TableLayer);
_physics.AddCollisionMask(uid, fixture, (int) CollisionGroup.TableLayer, manager: fixtures);
}
}
}
@@ -73,11 +74,11 @@ namespace Content.Server.Atmos.EntitySystems
{
if (!TryComp<FixturesComponent>(component.Owner, out var fixtures)) return;
body.BodyStatus = BodyStatus.InAir;
_physics.SetBodyStatus(body, BodyStatus.InAir);
foreach (var fixture in fixtures.Fixtures.Values)
{
_physics.RemoveCollisionMask(fixtures, fixture, (int) CollisionGroup.TableLayer);
_physics.RemoveCollisionMask(body.Owner, fixture, (int) CollisionGroup.TableLayer, manager: fixtures);
}
// TODO: Make them dynamic type? Ehh but they still want movement so uhh make it non-predicted like weightless?
@@ -188,10 +189,12 @@ namespace Content.Server.Atmos.EntitySystems
TransformComponent? xform = null,
PhysicsComponent? physics = null)
{
if (!Resolve(component.Owner, ref physics, false))
var uid = component.Owner;
if (!Resolve(uid, ref physics, false))
return;
if (!Resolve(component.Owner, ref xform)) return;
if (!Resolve(uid, ref xform)) return;
// TODO ATMOS stuns?
@@ -209,7 +212,7 @@ namespace Content.Server.Atmos.EntitySystems
&& (maxForce >= (component.MoveResist * MovedByPressureComponent.MoveForcePushRatio)))
|| (physics.BodyType == BodyType.Static && (maxForce >= (component.MoveResist * MovedByPressureComponent.MoveForceForcePushRatio))))
{
if (HasComp<MobStateComponent>(physics.Owner))
if (HasComp<MobStateComponent>(uid))
{
AddMobMovedByPressure(component, physics);
}
@@ -231,13 +234,12 @@ namespace Content.Server.Atmos.EntitySystems
if (throwTarget != EntityCoordinates.Invalid)
{
var pos = ((throwTarget.ToMap(EntityManager).Position - xform.WorldPosition).Normalized + dirVec).Normalized;
physics.ApplyLinearImpulse(pos * moveForce);
_physics.ApplyLinearImpulse(uid, pos * moveForce, body: physics);
}
else
{
moveForce = MathF.Min(moveForce, SpaceWindMaxPushForce);
physics.ApplyLinearImpulse(dirVec * moveForce);
_physics.ApplyLinearImpulse(uid, dirVec * moveForce, body: physics);
}
component.LastHighPressureMovementAirCycle = cycle;

View File

@@ -484,8 +484,8 @@ namespace Content.Server.Atmos.EntitySystems
var gridPhysics = Comp<PhysicsComponent>(mapGrid.Owner);
// TODO ATMOS: Come up with better values for these.
gridPhysics.ApplyLinearImpulse(direction * totalMolesRemoved * gridPhysics.Mass);
gridPhysics.ApplyAngularImpulse(Vector2.Cross(tile.GridIndices - gridPhysics.LocalCenter, direction) * totalMolesRemoved);
_physics.ApplyLinearImpulse(mapGrid.Owner, direction * totalMolesRemoved * gridPhysics.Mass, body: gridPhysics);
_physics.ApplyAngularImpulse(mapGrid.Owner, Vector2.Cross(tile.GridIndices - gridPhysics.LocalCenter, direction) * totalMolesRemoved, body: gridPhysics);
}
if(tileCount > 10 && (totalMolesRemoved / tileCount) > 20)

View File

@@ -33,6 +33,7 @@ namespace Content.Server.Atmos.EntitySystems
[Dependency] private readonly AlertsSystem _alertsSystem = default!;
[Dependency] private readonly TransformSystem _transformSystem = default!;
[Dependency] private readonly FixtureSystem _fixture = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
public const float MinimumFireStacks = -10f;
@@ -92,12 +93,8 @@ namespace Content.Server.Atmos.EntitySystems
if (!TryComp<PhysicsComponent>(uid, out var body))
return;
_fixture.TryCreateFixture(body, new Fixture(body, component.FlammableCollisionShape)
{
Hard = false,
ID = FlammableFixtureID,
CollisionMask = (int) CollisionGroup.FullTileLayer
});
_fixture.TryCreateFixture(uid, component.FlammableCollisionShape, FlammableFixtureID, hard: false,
collisionMask: (int) CollisionGroup.FullTileLayer, body: body);
}
private void OnInteractUsing(EntityUid uid, FlammableComponent flammable, InteractUsingEvent args)
@@ -274,7 +271,7 @@ namespace Content.Server.Atmos.EntitySystems
_timer -= UpdateTime;
// TODO: This needs cleanup to take off the crust from TemperatureComponent and shit.
foreach (var (flammable, physics, transform) in EntityManager.EntityQuery<FlammableComponent, PhysicsComponent, TransformComponent>())
foreach (var (flammable, transform) in EntityManager.EntityQuery<FlammableComponent, TransformComponent>())
{
var uid = flammable.Owner;
@@ -327,20 +324,21 @@ namespace Content.Server.Atmos.EntitySystems
}
foreach (var otherUid in flammable.Collided.ToArray())
for (var i = flammable.Collided.Count - 1; i >= 0; i--)
{
var otherUid = flammable.Collided[i];
if (!otherUid.IsValid() || !EntityManager.EntityExists(otherUid))
{
flammable.Collided.Remove(otherUid);
flammable.Collided.RemoveAt(i);
continue;
}
var otherPhysics = EntityManager.GetComponent<PhysicsComponent>(uid);
// TODO: Sloth, please save our souls!
if (!physics.GetWorldAABB().Intersects(otherPhysics.GetWorldAABB()))
// no
if (!_lookup.GetWorldAABB(uid, transform).Intersects(_lookup.GetWorldAABB(otherUid)))
{
flammable.Collided.Remove(otherUid);
flammable.Collided.RemoveAt(i);
}
}
}

View File

@@ -81,17 +81,19 @@ public sealed class BeamSystem : SharedBeamSystem
if (TryComp<PhysicsComponent>(ent, out var physics) && TryComp<BeamComponent>(ent, out var beam))
{
var fixture = new Fixture(physics, shape)
{
ID = "BeamBody",
Hard = false,
CollisionMask = (int)CollisionGroup.ItemMask,
CollisionLayer = (int)CollisionGroup.MobLayer
};
FixturesComponent? manager = null;
_fixture.TryCreateFixture(
ent,
shape,
"BeamBody",
hard: false,
collisionMask: (int)CollisionGroup.ItemMask,
collisionLayer: (int)CollisionGroup.MobLayer,
manager: manager,
body: physics);
_fixture.TryCreateFixture(physics, fixture);
_physics.SetBodyType(physics, BodyType.Dynamic);
_physics.SetCanCollide(physics, true);
_physics.SetBodyType(ent, BodyType.Dynamic, manager: manager, body: physics);
_physics.SetCanCollide(ent, true, manager: manager, body: physics);
var beamVisualizerEvent = new BeamVisualizerEvent(ent, distanceLength, userAngle, bodyState, shader);
RaiseNetworkEvent(beamVisualizerEvent);

View File

@@ -13,6 +13,7 @@ using Robust.Shared.Map.Components;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Dynamics;
using Robust.Shared.Physics.Events;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Prototypes;
namespace Content.Server.Chemistry.EntitySystems
@@ -22,6 +23,7 @@ namespace Content.Server.Chemistry.EntitySystems
{
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
[Dependency] private readonly ThrowingSystem _throwing = default!;
@@ -37,7 +39,7 @@ namespace Content.Server.Chemistry.EntitySystems
{
if (!EntityManager.TryGetComponent(uid, out SolutionContainerManagerComponent? contents)) return;
foreach (var (_, value) in contents.Solutions)
foreach (var value in contents.Solutions.Values)
{
value.DoEntityReaction(args.OtherFixture.Body.Owner, ReactionMethod.Touch);
}
@@ -58,8 +60,8 @@ namespace Content.Server.Chemistry.EntitySystems
// Set Move
if (EntityManager.TryGetComponent(vapor.Owner, out PhysicsComponent? physics))
{
physics.LinearDamping = 0f;
physics.AngularDamping = 0f;
_physics.SetLinearDamping(physics, 0f);
_physics.SetAngularDamping(physics, 0f);
_throwing.TryThrow(vapor.Owner, dir * speed, user: user, pushbackRatio: 50f);

View File

@@ -44,6 +44,7 @@ public sealed class ClimbSystem : SharedClimbSystem
[Dependency] private readonly InteractionSystem _interactionSystem = default!;
[Dependency] private readonly StunSystem _stunSystem = default!;
[Dependency] private readonly AudioSystem _audioSystem = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
private const string ClimbingFixtureName = "climb";
private const int ClimbingCollisionGroup = (int) (CollisionGroup.TableLayer | CollisionGroup.LowImpassable);
@@ -162,7 +163,7 @@ public sealed class ClimbSystem : SharedClimbSystem
if (!Resolve(uid, ref climbing, ref physics, ref fixtures, false))
return;
if (!ReplaceFixtures(climbing, physics, fixtures))
if (!ReplaceFixtures(climbing, fixtures))
return;
climbing.IsClimbing = true;
@@ -202,8 +203,10 @@ public sealed class ClimbSystem : SharedClimbSystem
/// Replaces the current fixtures with non-climbing collidable versions so that climb end can be detected
/// </summary>
/// <returns>Returns whether adding the new fixtures was successful</returns>
private bool ReplaceFixtures(ClimbingComponent climbingComp, PhysicsComponent physicsComp, FixturesComponent fixturesComp)
private bool ReplaceFixtures(ClimbingComponent climbingComp, FixturesComponent fixturesComp)
{
var uid = climbingComp.Owner;
// Swap fixtures
foreach (var (name, fixture) in fixturesComp.Fixtures)
{
@@ -213,13 +216,21 @@ public sealed class ClimbSystem : SharedClimbSystem
continue;
climbingComp.DisabledFixtureMasks.Add(fixture.ID, fixture.CollisionMask & ClimbingCollisionGroup);
fixture.CollisionMask &= ~ClimbingCollisionGroup;
_physics.SetCollisionMask(uid, fixture, fixture.CollisionMask & ~ClimbingCollisionGroup, fixturesComp);
}
if (!_fixtureSystem.TryCreateFixture(physicsComp,
new Fixture(new PhysShapeCircle { Radius = 0.35f }, (int) CollisionGroup.None, ClimbingCollisionGroup, false)
{ID = ClimbingFixtureName}, manager: fixturesComp))
if (!_fixtureSystem.TryCreateFixture(
uid,
new PhysShapeCircle(0.35f),
ClimbingFixtureName,
collisionLayer: (int) CollisionGroup.None,
collisionMask: ClimbingCollisionGroup,
hard: false,
manager: fixturesComp))
{
return false;
}
return true;
}
@@ -250,8 +261,11 @@ public sealed class ClimbSystem : SharedClimbSystem
foreach (var (name, fixtureMask) in climbing.DisabledFixtureMasks)
{
if (!fixtures.Fixtures.TryGetValue(name, out var fixture))
{
continue;
fixture.CollisionMask |= fixtureMask;
}
_physics.SetCollisionMask(uid, fixture, fixture.CollisionMask | fixtureMask, fixtures);
}
climbing.DisabledFixtureMasks.Clear();
@@ -397,16 +411,18 @@ public sealed class ClimbSystem : SharedClimbSystem
// Since there are bodies with different masses:
// mass * 10 seems enough to move entity
// instead of launching cats like rockets against the walls with constant impulse value.
physics.ApplyLinearImpulse((to - from).Normalized * velocity * physics.Mass * 10);
physics.BodyType = BodyType.Dynamic;
_physics.ApplyLinearImpulse(uid, (to - from).Normalized * velocity * physics.Mass * 10, body: physics);
_physics.SetBodyType(uid, BodyType.Dynamic, body: physics);
climbing.OwnerIsTransitioning = true;
_actionBlockerSystem.UpdateCanMove(uid);
// Transition back to KinematicController after BufferTime
climbing.Owner.SpawnTimer((int) (ClimbingComponent.BufferTime * 1000), () =>
{
if (climbing.Deleted) return;
physics.BodyType = BodyType.KinematicController;
if (climbing.Deleted)
return;
_physics.SetBodyType(uid, BodyType.KinematicController);
climbing.OwnerIsTransitioning = false;
_actionBlockerSystem.UpdateCanMove(uid);
});
@@ -418,10 +434,13 @@ public sealed class ClimbSystem : SharedClimbSystem
{
if (!TryComp<PhysicsComponent>(uid, out var physicsComp)
|| !TryComp<FixturesComponent>(uid, out var fixturesComp))
{
continue;
}
foreach (var fixture in fixtures)
{
_fixtureSystem.DestroyFixture(physicsComp, fixture, true, fixturesComp);
_fixtureSystem.DestroyFixture(uid, fixture, body: physicsComp, manager: fixturesComp);
}
}

View File

@@ -1,4 +1,3 @@
using System.Text;
using Content.Server.Disposal.Unit.Components;
using Content.Server.UserInterface;
using Robust.Server.GameObjects;

View File

@@ -5,6 +5,7 @@ using Content.Shared.Item;
using Robust.Shared.Containers;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
namespace Content.Server.Disposal.Unit.Components
{
@@ -85,7 +86,7 @@ namespace Content.Server.Disposal.Unit.Components
if (_entMan.TryGetComponent(entity, out PhysicsComponent? physics))
{
physics.CanCollide = false;
_entMan.System<SharedPhysicsSystem>().SetCanCollide(entity, false, body: physics);
}
return true;

View File

@@ -67,7 +67,7 @@ namespace Content.Server.Disposal.Unit.EntitySystems
if (EntityManager.TryGetComponent(entity, out PhysicsComponent? physics))
{
_physicsSystem.WakeBody(entity, physics);
_physicsSystem.WakeBody(entity, body: physics);
}
}

View File

@@ -58,7 +58,9 @@ public sealed class DoorSystem : SharedDoorSystem
args.Handled = true;
}
protected override void SetCollidable(EntityUid uid, bool collidable,
protected override void SetCollidable(
EntityUid uid,
bool collidable,
DoorComponent? door = null,
PhysicsComponent? physics = null,
OccluderComponent? occluder = null)

View File

@@ -14,10 +14,10 @@ namespace Content.Server.Explosion.Components
{
public const string FixtureID = "trigger-on-proximity-fixture";
public HashSet<PhysicsComponent> Colliding = new();
public readonly HashSet<PhysicsComponent> Colliding = new();
[DataField("shape", required: true)]
public IPhysShape Shape { get; set; } = new PhysShapeCircle {Radius = 2};
public IPhysShape Shape { get; set; } = new PhysShapeCircle(2f);
/// <summary>
/// How long the the proximity trigger animation plays for.

View File

@@ -57,13 +57,16 @@ public sealed partial class TriggerSystem
SetProximityAppearance(uid, component);
if (!TryComp<PhysicsComponent>(uid, out var body)) return;
if (!TryComp<PhysicsComponent>(uid, out var body))
return;
_fixtures.TryCreateFixture(body, new Fixture(body, component.Shape)
{
_fixtures.TryCreateFixture(
uid,
component.Shape,
TriggerOnProximityComponent.FixtureID,
hard: false,
// TODO: Should probably have these settable via datafield but I'm lazy and it's a pain
CollisionLayer = (int) (CollisionGroup.MidImpassable | CollisionGroup.LowImpassable | CollisionGroup.HighImpassable), Hard = false, ID = TriggerOnProximityComponent.FixtureID
});
collisionLayer: (int) (CollisionGroup.MidImpassable | CollisionGroup.LowImpassable | CollisionGroup.HighImpassable));
}
private void OnProximityStartCollide(EntityUid uid, TriggerOnProximityComponent component, ref StartCollideEvent args)

View File

@@ -20,6 +20,7 @@ using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Timing;
namespace Content.Server.Ghost
@@ -36,6 +37,7 @@ namespace Content.Server.Ghost
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly FollowerSystem _followerSystem = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
public override void Initialize()
{
@@ -226,7 +228,7 @@ namespace Content.Server.Ghost
xform.Coordinates = Transform(msg.Target).Coordinates;
xform.AttachToGridOrMap();
if (TryComp(attached, out PhysicsComponent? physics))
physics.LinearVelocity = Vector2.Zero;
_physics.SetLinearVelocity(attached, Vector2.Zero, body: physics);
}
private void DeleteEntity(EntityUid uid)

View File

@@ -7,6 +7,7 @@ using Robust.Shared.Audio;
using Robust.Shared.Map;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Player;
using Robust.Shared.Random;
@@ -19,6 +20,7 @@ public sealed class ImmovableRodSystem : EntitySystem
[Dependency] private readonly BodySystem _bodySystem = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
public override void Update(float frameTime)
{
@@ -29,6 +31,7 @@ public sealed class ImmovableRodSystem : EntitySystem
{
if (!rod.DestroyTiles)
continue;
if (!_map.TryGetGrid(trans.GridUid, out var grid))
continue;
@@ -49,9 +52,9 @@ public sealed class ImmovableRodSystem : EntitySystem
{
if (EntityManager.TryGetComponent(uid, out PhysicsComponent? phys))
{
phys.LinearDamping = 0f;
phys.Friction = 0f;
phys.BodyStatus = BodyStatus.InAir;
_physics.SetLinearDamping(phys, 0f);
_physics.SetFriction(phys, 0f);
_physics.SetBodyStatus(phys, BodyStatus.InAir);
if (!component.RandomizeVelocity)
return;
@@ -63,7 +66,7 @@ public sealed class ImmovableRodSystem : EntitySystem
_ => xform.WorldRotation.RotateVec(component.DirectionOverride.ToVec()) * _random.NextFloat(component.MinSpeed, component.MaxSpeed)
};
phys.ApplyLinearImpulse(vel);
_physics.ApplyLinearImpulse(uid, vel, body: phys);
xform.LocalRotation = (vel - xform.WorldPosition).ToWorldAngle() + MathHelper.PiOver2;
}
}

View File

@@ -311,7 +311,8 @@ public sealed class MagicSystem : EntitySystem
var direction = Transform(ev.Target).MapPosition.Position - Transform(ev.Performer).MapPosition.Position;
var impulseVector = direction * 10000;
Comp<PhysicsComponent>(ev.Target).ApplyLinearImpulse(impulseVector);
_physics.ApplyLinearImpulse(ev.Target, impulseVector);
if (!TryComp<BodyComponent>(ev.Target, out var body))
return;

View File

@@ -4,6 +4,7 @@ using Robust.Server.Player;
using Robust.Shared.Players;
using Robust.Shared.Utility;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
namespace Content.Server.Maps;
@@ -11,6 +12,7 @@ namespace Content.Server.Maps;
public sealed class GridDraggingSystem : SharedGridDraggingSystem
{
[Dependency] private readonly IConGroupController _admin = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
private readonly HashSet<ICommonSession> _draggers = new();
@@ -54,8 +56,8 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem
Deleted(ev.Grid)) return;
var gridBody = Comp<PhysicsComponent>(ev.Grid);
gridBody.LinearVelocity = ev.LinearVelocity;
gridBody.AngularVelocity = 0f;
_physics.SetLinearVelocity(ev.Grid, ev.LinearVelocity, body: gridBody);
_physics.SetAngularVelocity(ev.Grid, 0f, body: gridBody);
}
private void OnRequestDrag(GridDragRequestPosition msg, EntitySessionEventArgs args)

View File

@@ -3,6 +3,7 @@ using Content.Server.Singularity.Components;
using Content.Shared.Projectiles;
using Content.Shared.Singularity.Components;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Timing;
namespace Content.Server.ParticleAccelerator.Components
@@ -18,14 +19,16 @@ namespace Content.Server.ParticleAccelerator.Components
{
State = state;
if (!_entMan.TryGetComponent<PhysicsComponent?>(Owner, out var physicsComponent))
if (!_entMan.TryGetComponent<PhysicsComponent>(Owner, out var physicsComponent))
{
Logger.Error("ParticleProjectile tried firing, but it was spawned without a CollidableComponent");
return;
}
physicsComponent.BodyStatus = BodyStatus.InAir;
if (!_entMan.TryGetComponent<ProjectileComponent?>(Owner, out var projectileComponent))
var physics = _entMan.System<SharedPhysicsSystem>();
physics.SetBodyStatus(physicsComponent, BodyStatus.InAir);
if (!_entMan.TryGetComponent<ProjectileComponent>(Owner, out var projectileComponent))
{
Logger.Error("ParticleProjectile tried firing, but it was spawned without a ProjectileComponent");
return;
@@ -33,7 +36,7 @@ namespace Content.Server.ParticleAccelerator.Components
_entMan.EntitySysManager.GetEntitySystem<ProjectileSystem>().SetShooter(projectileComponent, firer);
if (!_entMan.TryGetComponent<SinguloFoodComponent?>(Owner, out var singuloFoodComponent))
if (!_entMan.TryGetComponent<SinguloFoodComponent>(Owner, out var singuloFoodComponent))
{
Logger.Error("ParticleProjectile tried firing, but it was spawned without a SinguloFoodComponent");
return;
@@ -54,7 +57,7 @@ namespace Content.Server.ParticleAccelerator.Components
appearance.SetData(ParticleAcceleratorVisuals.VisualState, state);
}
physicsComponent.LinearVelocity = angle.ToWorldVec() * 20f;
physics.SetLinearVelocity(Owner, angle.ToWorldVec() * 20f, body: physicsComponent);
_entMan.GetComponent<TransformComponent>(Owner).LocalRotation = angle;
Timer.Spawn(3000, () => _entMan.DeleteEntity(Owner));

View File

@@ -77,12 +77,9 @@ namespace Content.Server.Physics.Controllers
var shape = new PolygonShape();
shape.SetAsBox(0.55f, 0.55f);
_fixtures.TryCreateFixture(body, new Fixture(body, shape)
{
ID = ConveyorFixture,
CollisionLayer = (int) (CollisionGroup.LowImpassable | CollisionGroup.MidImpassable | CollisionGroup.Impassable),
Hard = false,
});
_fixtures.TryCreateFixture(uid, shape, ConveyorFixture, hard: false,
collisionLayer: (int) (CollisionGroup.LowImpassable | CollisionGroup.MidImpassable |
CollisionGroup.Impassable), body: body);
}
}
@@ -160,7 +157,7 @@ namespace Content.Server.Physics.Controllers
continue;
if (physics.BodyType != BodyType.Static)
_physics.WakeBody(physics);
_physics.WakeBody(entity, body: physics);
}
}
}
@@ -180,7 +177,7 @@ namespace Content.Server.Physics.Controllers
if (!TryComp<PhysicsComponent>(uid, out var body))
return;
_fixtures.DestroyFixture(body, ConveyorFixture);
_fixtures.DestroyFixture(uid, ConveyorFixture, body: body);
}
public override void UpdateBeforeSolve(bool prediction, float frameTime)
@@ -237,8 +234,9 @@ namespace Content.Server.Physics.Controllers
transform.LocalPosition = localPos;
// Force it awake for collisionwake reasons.
body.Awake = true;
body.SleepTime = 0f;
// TODO: Just use sleepallowed
_physics.SetAwake(entity, body, true);
_physics.SetSleepTime(body, 0f);
}
}

View File

@@ -8,6 +8,7 @@ using Content.Shared.Shuttles.Systems;
using Robust.Server.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Player;
namespace Content.Server.Physics.Controllers
@@ -399,7 +400,7 @@ namespace Content.Server.Physics.Controllers
impulse.Y = MathF.Max(impulse.Y, -shuttleVelocity.Y);
}
PhysicsSystem.SetLinearVelocity(body, body.LinearVelocity + shuttleNorthAngle.RotateVec(impulse));
PhysicsSystem.SetLinearVelocity(shuttle.Owner, body.LinearVelocity + shuttleNorthAngle.RotateVec(impulse), body: body);
}
}
else
@@ -432,7 +433,7 @@ namespace Content.Server.Physics.Controllers
else if (body.AngularVelocity > 0f && body.AngularVelocity + accelSpeed < 0f)
accelSpeed = -body.AngularVelocity;
PhysicsSystem.SetAngularVelocity(body, body.AngularVelocity + accelSpeed);
PhysicsSystem.SetAngularVelocity(shuttle.Owner, body.AngularVelocity + accelSpeed, body: body);
_thruster.SetAngularThrust(shuttle, true);
}
}
@@ -440,19 +441,19 @@ namespace Content.Server.Physics.Controllers
if (linearInput.Length.Equals(0f))
{
body.SleepingAllowed = true;
PhysicsSystem.SetSleepingAllowed(shuttle.Owner, body, true);
if (brakeInput.Equals(0f))
_thruster.DisableLinearThrusters(shuttle);
if (body.LinearVelocity.Length < 0.08)
{
body.LinearVelocity = Vector2.Zero;
PhysicsSystem.SetLinearVelocity(shuttle.Owner, Vector2.Zero, body: body);
}
}
else
{
body.SleepingAllowed = false;
PhysicsSystem.SetSleepingAllowed(shuttle.Owner, body, false);
var angle = linearInput.ToWorldAngle();
var linearDir = angle.GetDir();
var dockFlag = linearDir.AsFlag();
@@ -519,23 +520,23 @@ namespace Content.Server.Physics.Controllers
{
var accelSpeed = totalForce.Length * frameTime;
accelSpeed = MathF.Min(accelSpeed, addSpeed);
body.ApplyLinearImpulse(shuttleNorthAngle.RotateVec(totalForce.Normalized * accelSpeed));
PhysicsSystem.ApplyLinearImpulse(shuttle.Owner, shuttleNorthAngle.RotateVec(totalForce.Normalized * accelSpeed), body: body);
}
}
if (MathHelper.CloseTo(angularInput, 0f))
{
_thruster.SetAngularThrust(shuttle, false);
body.SleepingAllowed = true;
PhysicsSystem.SetSleepingAllowed(shuttle.Owner, body, true);
if (Math.Abs(body.AngularVelocity) < 0.01f)
{
body.AngularVelocity = 0f;
PhysicsSystem.SetAngularVelocity(shuttle.Owner, 0f, body: body);
}
}
else
{
body.SleepingAllowed = false;
PhysicsSystem.SetSleepingAllowed(shuttle.Owner, body, false);
var impulse = shuttle.AngularThrust * -angularInput;
var wishSpeed = MathF.PI;
@@ -554,7 +555,7 @@ namespace Content.Server.Physics.Controllers
else
accelSpeed = MathF.Min(accelSpeed, addSpeed);
PhysicsSystem.SetAngularVelocity(body, body.AngularVelocity + accelSpeed);
PhysicsSystem.SetAngularVelocity(shuttle.Owner, body.AngularVelocity + accelSpeed, body: body);
_thruster.SetAngularThrust(shuttle, true);
}
}

View File

@@ -73,7 +73,7 @@ namespace Content.Server.Physics.Controllers
return;
if (TryComp<PhysicsComponent>(pullable.Owner, out var physics))
physics.WakeBody();
PhysicsSystem.WakeBody(pullable.Owner, body: physics);
_pullableSystem.StopMoveTo(pullable);
}
@@ -164,9 +164,9 @@ namespace Content.Server.Physics.Controllers
var diff = movingPosition - ownerPosition;
var diffLength = diff.Length;
if ((diffLength < MaximumSettleDistance) && (physics.LinearVelocity.Length < MaximumSettleVelocity))
if (diffLength < MaximumSettleDistance && (physics.LinearVelocity.Length < MaximumSettleVelocity))
{
physics.LinearVelocity = Vector2.Zero;
PhysicsSystem.SetLinearVelocity(pullable.Owner, Vector2.Zero, body: physics);
_pullableSystem.StopMoveTo(pullable);
continue;
}
@@ -183,9 +183,11 @@ namespace Content.Server.Physics.Controllers
var scaling = (SettleShutdownDistance - diffLength) / SettleShutdownDistance;
accel -= physics.LinearVelocity * SettleShutdownMultiplier * scaling;
}
physics.WakeBody();
PhysicsSystem.WakeBody(pullable.Owner, body: physics);
var impulse = accel * physics.Mass * frameTime;
physics.ApplyLinearImpulse(impulse);
PhysicsSystem.ApplyLinearImpulse(pullable.Owner, impulse, body: physics);
}
}
}

View File

@@ -69,8 +69,8 @@ internal sealed class RandomWalkController : VirtualController
var pushAngle = _random.NextAngle();
var pushStrength = _random.NextFloat(randomWalk.MinSpeed, randomWalk.MaxSpeed);
_physics.SetLinearVelocity(physics, physics.LinearVelocity * randomWalk.AccumulatorRatio);
_physics.ApplyLinearImpulse(physics, pushAngle.ToVec() * (pushStrength * physics.Mass));
_physics.SetLinearVelocity(uid, physics.LinearVelocity * randomWalk.AccumulatorRatio, body: physics);
_physics.ApplyLinearImpulse(uid, pushAngle.ToVec() * (pushStrength * physics.Mass), body: physics);
}
/// <summary>

View File

@@ -20,12 +20,13 @@ namespace Content.Server.Shuttles.Systems
public sealed partial class DockingSystem : EntitySystem
{
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly FixtureSystem _fixtureSystem = default!;
[Dependency] private readonly SharedJointSystem _jointSystem = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly ShuttleConsoleSystem _console = default!;
[Dependency] private readonly DoorSystem _doorSystem = default!;
[Dependency] private readonly FixtureSystem _fixtureSystem = default!;
[Dependency] private readonly PathfindingSystem _pathfinding = default!;
[Dependency] private readonly ShuttleConsoleSystem _console = default!;
[Dependency] private readonly SharedJointSystem _jointSystem = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
private ISawmill _sawmill = default!;
private const string DockingFixture = "docking";
@@ -70,10 +71,13 @@ namespace Content.Server.Shuttles.Systems
// Assume the docking port itself (and its body) is valid
if (!_mapManager.TryGetGrid(dockingXform.GridUid, out var grid) ||
!HasComp<ShuttleComponent>(grid.Owner)) return null;
!HasComp<ShuttleComponent>(grid.Owner))
{
return null;
}
var transform = body.GetTransform();
var dockingFixture = _fixtureSystem.GetFixtureOrNull(body, DockingFixture);
var transform = _physics.GetPhysicsTransform(body.Owner, dockingXform);
var dockingFixture = _fixtureSystem.GetFixtureOrNull(body.Owner, DockingFixture);
if (dockingFixture == null)
return null;
@@ -99,13 +103,13 @@ namespace Content.Server.Shuttles.Systems
{
if (!TryComp(ent, out DockingComponent? otherDocking) ||
!otherDocking.Enabled ||
!TryComp(ent, out PhysicsComponent? otherBody))
!TryComp(ent, out FixturesComponent? otherBody))
{
continue;
}
var otherTransform = otherBody.GetTransform();
var otherDockingFixture = _fixtureSystem.GetFixtureOrNull(otherBody, DockingFixture);
var otherTransform = _physics.GetPhysicsTransform(ent);
var otherDockingFixture = _fixtureSystem.GetFixtureOrNull(ent, DockingFixture, manager: otherBody);
if (otherDockingFixture == null)
{
@@ -251,7 +255,7 @@ namespace Content.Server.Shuttles.Systems
return;
}
_fixtureSystem.DestroyFixture(physicsComponent, DockingFixture);
_fixtureSystem.DestroyFixture(uid, DockingFixture, body: physicsComponent);
}
private void EnableDocking(EntityUid uid, DockingComponent component)
@@ -264,24 +268,12 @@ namespace Content.Server.Shuttles.Systems
component.Enabled = true;
// TODO: WTF IS THIS GARBAGE
var shape = new PhysShapeCircle
{
// Want half of the unit vector
Position = new Vector2(0f, -0.5f),
Radius = DockingRadius
};
var shape = new PhysShapeCircle(DockingRadius, new Vector2(0f, -0.5f));
// Listen it makes intersection tests easier; you can probably dump this but it requires a bunch more boilerplate
var fixture = new Fixture(physicsComponent, shape)
{
ID = DockingFixture,
Hard = false,
};
// TODO: I want this to ideally be 2 fixtures to force them to have some level of alignment buuuttt
// I also need collisionmanager for that yet again so they get dis.
_fixtureSystem.TryCreateFixture(physicsComponent, fixture);
_fixtureSystem.TryCreateFixture(uid, shape, DockingFixture, hard: false);
}
/// <summary>
@@ -407,16 +399,16 @@ namespace Content.Server.Shuttles.Systems
return false;
}
var fixtureA = _fixtureSystem.GetFixtureOrNull(bodyA, DockingFixture);
var fixtureB = _fixtureSystem.GetFixtureOrNull(bodyB, DockingFixture);
var fixtureA = _fixtureSystem.GetFixtureOrNull(bodyA.Owner, DockingFixture);
var fixtureB = _fixtureSystem.GetFixtureOrNull(bodyB.Owner, DockingFixture);
if (fixtureA == null || fixtureB == null)
{
return false;
}
var transformA = bodyA.GetTransform();
var transformB = bodyB.GetTransform();
var transformA = _physics.GetPhysicsTransform(dockA.Owner);
var transformB = _physics.GetPhysicsTransform(dockB.Owner);
var intersect = false;
for (var i = 0; i < fixtureA.Shape.ChildCount; i++)

View File

@@ -234,10 +234,10 @@ public sealed partial class ShuttleSystem
if (TryComp(comp.Owner, out body))
{
body.LinearVelocity = new Vector2(0f, 20f);
body.AngularVelocity = 0f;
body.LinearDamping = 0f;
body.AngularDamping = 0f;
_physics.SetLinearVelocity(comp.Owner, new Vector2(0f, 20f), body: body);
_physics.SetAngularVelocity(comp.Owner, 0f, body: body);
_physics.SetLinearDamping(body, 0f);
_physics.SetAngularDamping(body, 0f);
}
if (comp.TravelSound != null)
@@ -272,10 +272,10 @@ public sealed partial class ShuttleSystem
if (TryComp(comp.Owner, out body))
{
body.LinearVelocity = Vector2.Zero;
body.AngularVelocity = 0f;
body.LinearDamping = ShuttleLinearDamping;
body.AngularDamping = ShuttleAngularDamping;
_physics.SetLinearVelocity(comp.Owner, Vector2.Zero, body: body);
_physics.SetAngularVelocity(comp.Owner, 0f, body: body);
_physics.SetLinearDamping(body, ShuttleLinearDamping);
_physics.SetAngularDamping(body, ShuttleAngularDamping);
}
TryComp(comp.Owner, out shuttle);
@@ -521,8 +521,8 @@ public sealed partial class ShuttleSystem
if (TryComp<PhysicsComponent>(component.Owner, out var shuttleBody))
{
shuttleBody.LinearVelocity = Vector2.Zero;
shuttleBody.AngularVelocity = 0f;
_physics.SetLinearVelocity(component.Owner, Vector2.Zero, body: shuttleBody);
_physics.SetAngularVelocity(component.Owner, 0f, body: shuttleBody);
}
xform.Coordinates = new EntityCoordinates(targetXform.MapUid.Value, spawnPos);

View File

@@ -85,15 +85,16 @@ namespace Content.Server.Shuttles.Systems
// Look this is jank but it's a placeholder until we design it.
if (args.NewFixtures.Count == 0) return;
var manager = Comp<FixturesComponent>(args.NewFixtures[0].Body.Owner);
var uid = args.NewFixtures[0].Body.Owner;
var manager = Comp<FixturesComponent>(uid);
foreach (var fixture in args.NewFixtures)
{
_physics.SetDensity(fixture, TileMassMultiplier, manager, false);
_fixtures.SetRestitution(fixture, 0.1f, manager, false);
_physics.SetDensity(uid, fixture, TileMassMultiplier, false, manager);
_fixtures.SetRestitution(uid, fixture, 0.1f, false, manager);
}
_fixtures.FixtureUpdate(manager, args.NewFixtures[0].Body);
_fixtures.FixtureUpdate(uid, manager: manager);
}
private void OnGridInit(GridInitializeEvent ev)
@@ -118,11 +119,11 @@ namespace Content.Server.Shuttles.Systems
if (component.Enabled)
{
Enable(physicsComponent);
Enable(uid, physicsComponent);
}
}
public void Toggle(ShuttleComponent component)
public void Toggle(EntityUid uid, ShuttleComponent component)
{
if (!EntityManager.TryGetComponent(component.Owner, out PhysicsComponent? physicsComponent)) return;
@@ -130,28 +131,32 @@ namespace Content.Server.Shuttles.Systems
if (component.Enabled)
{
Enable(physicsComponent);
Enable(uid, physicsComponent);
}
else
{
Disable(physicsComponent);
Disable(uid, physicsComponent);
}
}
private void Enable(PhysicsComponent component)
private void Enable(EntityUid uid, PhysicsComponent component)
{
component.BodyType = BodyType.Dynamic;
component.BodyStatus = BodyStatus.InAir;
component.FixedRotation = false;
component.LinearDamping = ShuttleLinearDamping;
component.AngularDamping = ShuttleAngularDamping;
FixturesComponent? manager = null;
_physics.SetBodyType(uid, BodyType.Dynamic, manager: manager, body: component);
_physics.SetBodyStatus(component, BodyStatus.InAir);
_physics.SetFixedRotation(uid, false, manager: manager, body: component);
_physics.SetLinearDamping(component, ShuttleLinearDamping);
_physics.SetAngularDamping(component, ShuttleAngularDamping);
}
private void Disable(PhysicsComponent component)
private void Disable(EntityUid uid, PhysicsComponent component)
{
component.BodyType = BodyType.Static;
component.BodyStatus = BodyStatus.OnGround;
component.FixedRotation = true;
FixturesComponent? manager = null;
_physics.SetBodyType(uid, BodyType.Static, manager: manager, body: component);
_physics.SetBodyStatus(component, BodyStatus.OnGround);
_physics.SetFixedRotation(uid, true, manager: manager, body: component);
}
private void OnShuttleShutdown(EntityUid uid, ShuttleComponent component, ComponentShutdown args)
@@ -164,7 +169,7 @@ namespace Content.Server.Shuttles.Systems
return;
}
Disable(physicsComponent);
Disable(uid, physicsComponent);
}
}
}

View File

@@ -262,17 +262,8 @@ namespace Content.Server.Shuttles.Systems
component.BurnPoly.Count > 0)
{
var shape = new PolygonShape();
shape.SetVertices(component.BurnPoly);
var fixture = new Fixture(physicsComponent, shape)
{
ID = BurnFixture,
Hard = false,
CollisionLayer = (int) CollisionGroup.FullTileMask
};
_fixtureSystem.TryCreateFixture(physicsComponent, fixture);
_fixtureSystem.TryCreateFixture(uid, shape, BurnFixture, hard: false, collisionLayer: (int) CollisionGroup.FullTileMask);
}
break;
@@ -352,7 +343,7 @@ namespace Content.Server.Shuttles.Systems
if (EntityManager.TryGetComponent(uid, out PhysicsComponent? physicsComponent))
{
_fixtureSystem.DestroyFixture(physicsComponent, BurnFixture);
_fixtureSystem.DestroyFixture(uid, BurnFixture, body: physicsComponent);
}
_activeThrusters.Remove(component);

View File

@@ -183,9 +183,11 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
var minRange2 = MathF.Max(minRange * minRange, MinGravPulseRange); // Cache square value for speed. Also apply a sane minimum value to the minimum value so that div/0s don't happen.
foreach(var entity in _lookup.GetEntitiesInRange(mapPos.MapId, epicenter, maxRange, flags: LookupFlags.Dynamic | LookupFlags.Sundries))
{
if(!TryComp<PhysicsComponent?>(entity, out var physics)
|| physics.BodyType == BodyType.Static)
if (!TryComp<PhysicsComponent>(entity, out var physics)
|| physics.BodyType == BodyType.Static)
{
continue;
}
if(!CanGravPulseAffect(entity))
continue;
@@ -196,7 +198,7 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
continue;
var scaling = (1f / distance2) * physics.Mass; // TODO: Variable falloff gradiants.
_physics.ApplyLinearImpulse(physics, (displacement * baseMatrixDeltaV) * scaling);
_physics.ApplyLinearImpulse(entity, (displacement * baseMatrixDeltaV) * scaling, body: physics);
}
}

View File

@@ -2,11 +2,14 @@ using Content.Server.GameTicking;
using Content.Shared.Spawners.Components;
using Robust.Shared.Map;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
namespace Content.Server.StationEvents.Events
{
public sealed class MeteorSwarm : StationEventSystem
{
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
public override string Prototype => "MeteorSwarm";
private float _cooldown;
@@ -70,12 +73,7 @@ namespace Content.Server.StationEvents.Events
foreach (var grid in MapManager.GetAllMapGrids(mapId))
{
if (!TryComp<PhysicsComponent>(grid.Owner, out var gridBody))
{
continue;
}
var aabb = gridBody.GetWorldAABB();
var aabb = _physics.GetWorldAABB(grid.Owner);
playableArea = playableArea?.Union(aabb) ?? aabb;
}
@@ -97,15 +95,15 @@ namespace Content.Server.StationEvents.Events
var spawnPosition = new MapCoordinates(center + offset, mapId);
var meteor = EntityManager.SpawnEntity("MeteorLarge", spawnPosition);
var physics = EntityManager.GetComponent<PhysicsComponent>(meteor);
physics.BodyStatus = BodyStatus.InAir;
physics.LinearDamping = 0f;
physics.AngularDamping = 0f;
physics.ApplyLinearImpulse(-offset.Normalized * MeteorVelocity * physics.Mass);
physics.ApplyAngularImpulse(
// Get a random angular velocity.
physics.Mass * ((MaxAngularVelocity - MinAngularVelocity) * RobustRandom.NextFloat() +
MinAngularVelocity));
// TODO: God this disgusts me but projectile needs a refactor.
_physics.SetBodyStatus(physics, BodyStatus.InAir);
_physics.SetLinearDamping(physics, 0f);
_physics.SetAngularDamping(physics, 0f);
_physics.ApplyLinearImpulse(meteor, -offset.Normalized * MeteorVelocity * physics.Mass, body: physics);
_physics.ApplyAngularImpulse(
meteor,
physics.Mass * ((MaxAngularVelocity - MinAngularVelocity) * RobustRandom.NextFloat() + MinAngularVelocity),
body: physics);
EnsureComp<TimedDespawnComponent>(meteor).Lifetime = 120f;
}
}

View File

@@ -19,6 +19,7 @@ using Robust.Shared.Containers;
using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Player;
namespace Content.Server.Storage.EntitySystems;
@@ -34,6 +35,7 @@ public sealed class EntityStorageSystem : EntitySystem
[Dependency] private readonly PlaceableSurfaceSystem _placeableSurface = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly AtmosphereSystem _atmos = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly IMapManager _map = default!;
public const string ContainerName = "entity_storage";
@@ -323,7 +325,9 @@ public sealed class EntityStorageSystem : EntitySystem
if (TryComp<PhysicsComponent>(toAdd, out var phys))
{
if (component.MaxSize < phys.GetWorldAABB().Size.X || component.MaxSize < phys.GetWorldAABB().Size.Y)
var aabb = _physics.GetWorldAABB(toAdd, body: phys);
if (component.MaxSize < aabb.Size.X || component.MaxSize < aabb.Size.Y)
return false;
}
@@ -387,11 +391,11 @@ public sealed class EntityStorageSystem : EntitySystem
if (component.Open)
{
component.RemovedMasks = fixture.CollisionLayer & component.MasksToRemove;
fixture.CollisionLayer &= ~component.MasksToRemove;
_physics.SetCollisionLayer(uid, fixture, fixture.CollisionLayer & ~component.MasksToRemove, manager: fixtures);
}
else
{
fixture.CollisionLayer |= component.RemovedMasks;
_physics.SetCollisionLayer(uid, fixture, fixture.CollisionLayer | component.RemovedMasks, manager: fixtures);
component.RemovedMasks = 0;
}
}

View File

@@ -52,7 +52,7 @@ namespace Content.Server.Temperature.Components
{
get
{
if (IoCManager.Resolve<IEntityManager>().TryGetComponent<PhysicsComponent?>(Owner, out var physics) && physics.FixturesMass != 0)
if (IoCManager.Resolve<IEntityManager>().TryGetComponent<PhysicsComponent>(Owner, out var physics) && physics.FixturesMass != 0)
{
return SpecificHeat * physics.FixturesMass;
}

View File

@@ -243,12 +243,12 @@ public sealed partial class GunSystem : SharedGunSystem
public void ShootProjectile(EntityUid uid, Vector2 direction, Vector2 gunVelocity, EntityUid? user = null, float speed = 20f)
{
var physics = EnsureComp<PhysicsComponent>(uid);
physics.BodyStatus = BodyStatus.InAir;
Physics.SetBodyStatus(physics, BodyStatus.InAir);
var targetMapVelocity = gunVelocity + direction.Normalized * speed;
var currentMapVelocity = Physics.GetMapLinearVelocity(uid, physics);
var finalLinear = physics.LinearVelocity + targetMapVelocity - currentMapVelocity;
Physics.SetLinearVelocity(physics, finalLinear);
Physics.SetLinearVelocity(uid, finalLinear, body: physics);
if (user != null)
{

View File

@@ -111,12 +111,12 @@ public sealed class TetherGunSystem : SharedTetherGunSystem
if (TryComp<PhysicsComponent>(msg.Entity, out var body))
{
body.BodyStatus = BodyStatus.InAir;
_physics.SetBodyStatus(body, BodyStatus.InAir);
}
_physics.WakeBody(bodyA);
_physics.WakeBody(bodyB);
var joint = _joints.CreateMouseJoint(bodyA.Owner, bodyB.Owner, id: JointId);
_physics.WakeBody(tether, body: bodyA);
_physics.WakeBody(msg.Entity, body: bodyB);
var joint = _joints.CreateMouseJoint(tether, msg.Entity, id: JointId);
SharedJointSystem.LinearStiffness(5f, 0.7f, bodyA.Mass, bodyB.Mass, out var stiffness, out var damping);
joint.Stiffness = stiffness;
@@ -147,8 +147,9 @@ public sealed class TetherGunSystem : SharedTetherGunSystem
{
Timer.Spawn(1000, () =>
{
if (Deleted(body.Owner)) return;
body.BodyStatus = BodyStatus.OnGround;
if (Deleted(weh.Entity)) return;
_physics.SetBodyStatus(body, BodyStatus.OnGround);
});
}
@@ -186,7 +187,7 @@ public sealed class TetherGunSystem : SharedTetherGunSystem
// Force it awake, always
if (bodyQuery.TryGetComponent(entity.Entity, out var body))
{
_physics.WakeBody(body);
_physics.WakeBody(entity.Entity, body: body);
}
}

View File

@@ -25,12 +25,12 @@ public sealed class PhasingArtifactSystem : EntitySystem
private void OnActivate(EntityUid uid, PhasingArtifactComponent component, ArtifactActivatedEvent args)
{
if (!TryComp<FixturesComponent>(uid, out var fixtures) || !TryComp<PhysicsComponent>(uid, out var phys))
if (!TryComp<FixturesComponent>(uid, out var fixtures))
return;
foreach (var (_, fixture) in fixtures.Fixtures)
foreach (var fixture in fixtures.Fixtures.Values)
{
_physics.SetHard(fixture, false, fixtures);
_physics.SetHard(uid, fixture, false, fixtures);
}
}
}

View File

@@ -186,14 +186,12 @@ public sealed partial class BlockingSystem : EntitySystem
if (TryComp<PhysicsComponent>(user, out var physicsComponent))
{
var fixture = new Fixture(physicsComponent, component.Shape)
{
ID = BlockingComponent.BlockFixtureID,
Hard = true,
CollisionLayer = (int) CollisionGroup.WallLayer
};
_fixtureSystem.TryCreateFixture(physicsComponent, fixture);
_fixtureSystem.TryCreateFixture(user,
component.Shape,
BlockingComponent.BlockFixtureID,
hard: true,
collisionLayer: (int) CollisionGroup.WallLayer,
body: physicsComponent);
}
component.IsBlocking = true;
@@ -243,8 +241,8 @@ public sealed partial class BlockingSystem : EntitySystem
_transformSystem.Unanchor(xform);
_actionsSystem.SetToggled(component.BlockingToggleAction, false);
_fixtureSystem.DestroyFixture(physicsComponent, BlockingComponent.BlockFixtureID);
_physics.SetBodyType(physicsComponent, blockingUserComponent.OriginalBodyType);
_fixtureSystem.DestroyFixture(user, BlockingComponent.BlockFixtureID, body: physicsComponent);
_physics.SetBodyType(user, blockingUserComponent.OriginalBodyType, body: physicsComponent);
_popupSystem.PopupEntity(msgUser, user, user);
_popupSystem.PopupEntity(msgOther, user, Filter.PvsExcept(user), true);
}

View File

@@ -31,9 +31,8 @@ public sealed class BlockingComponent : Component
/// <summary>
/// The shape of the blocking fixture that will be dynamically spawned
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("shape")]
public IPhysShape Shape = new PhysShapeCircle {Radius = 0.5F};
[ViewVariables(VVAccess.ReadWrite)] [DataField("shape")]
public IPhysShape Shape = new PhysShapeCircle(0.5f);
/// <summary>
/// The damage modifer to use while passively blocking

View File

@@ -381,7 +381,10 @@ public abstract class SharedDoorSystem : EntitySystem
#endregion
#region Collisions
protected virtual void SetCollidable(EntityUid uid, bool collidable,
protected virtual void SetCollidable(
EntityUid uid,
bool collidable,
DoorComponent? door = null,
PhysicsComponent? physics = null,
OccluderComponent? occluder = null)
@@ -390,13 +393,13 @@ public abstract class SharedDoorSystem : EntitySystem
return;
if (Resolve(uid, ref physics, false))
PhysicsSystem.SetCanCollide(physics, collidable);
PhysicsSystem.SetCanCollide(uid, collidable, body: physics);
if (!collidable)
door.CurrentlyCrushing.Clear();
if (door.Occludes)
_occluder.SetEnabled(uid, collidable);
_occluder.SetEnabled(uid, collidable, occluder);
}
/// <summary>

View File

@@ -1,5 +1,8 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Explosion;
[NetworkedComponent]
public abstract class SharedTriggerOnProximityComponent : Component
{

View File

@@ -78,6 +78,8 @@ namespace Content.Shared.Friction
foreach (var body in mapComponent.AwakeBodies)
{
var uid = body.Owner;
// Only apply friction when it's not a mob (or the mob doesn't have control)
if (prediction && !body.Predict ||
body.BodyStatus == BodyStatus.InAir ||
@@ -86,46 +88,45 @@ namespace Content.Shared.Friction
continue;
}
if (body.LinearVelocity.Equals(Vector2.Zero) && body.AngularVelocity.Equals(0f)) continue;
if (body.LinearVelocity.Equals(Vector2.Zero) && body.AngularVelocity.Equals(0f))
continue;
DebugTools.Assert(!Deleted(body.Owner));
if (!xformQuery.TryGetComponent(body.Owner, out var xform))
if (!xformQuery.TryGetComponent(uid, out var xform))
{
Logger.ErrorS("physics", $"Unable to get transform for {ToPrettyString(body.Owner)} in tilefrictioncontroller");
continue;
}
var surfaceFriction = GetTileFriction(body, xform);
var surfaceFriction = GetTileFriction(uid, body, xform);
var bodyModifier = 1f;
if (frictionQuery.TryGetComponent(body.Owner, out var frictionComp))
if (frictionQuery.TryGetComponent(uid, out var frictionComp))
{
bodyModifier = frictionComp.Modifier;
}
var ev = new TileFrictionEvent(bodyModifier);
RaiseLocalEvent(body.Owner, ref ev);
RaiseLocalEvent(uid, ref ev);
bodyModifier = ev.Modifier;
// If we're sandwiched between 2 pullers reduce friction
// Might be better to make this dynamic and check how many are in the pull chain?
// Either way should be much faster for now.
if (pullerQuery.TryGetComponent(body.Owner, out var puller) && puller.Pulling != null &&
pullableQuery.TryGetComponent(body.Owner, out var pullable) && pullable.BeingPulled)
if (pullerQuery.TryGetComponent(uid, out var puller) && puller.Pulling != null &&
pullableQuery.TryGetComponent(uid, out var pullable) && pullable.BeingPulled)
{
bodyModifier *= 0.2f;
}
var friction = _frictionModifier * surfaceFriction * bodyModifier;
ReduceLinearVelocity(prediction, body, friction, frameTime);
ReduceAngularVelocity(prediction, body, friction, frameTime);
ReduceLinearVelocity(uid, prediction, body, friction, frameTime);
ReduceAngularVelocity(uid, prediction, body, friction, frameTime);
}
}
private void ReduceLinearVelocity(bool prediction, PhysicsComponent body, float friction, float frameTime)
private void ReduceLinearVelocity(EntityUid uid, bool prediction, PhysicsComponent body, float friction, float frameTime)
{
var speed = body.LinearVelocity.Length;
@@ -153,10 +154,10 @@ namespace Content.Shared.Friction
var newSpeed = MathF.Max(0.0f, speed - drop);
newSpeed /= speed;
_physics.SetLinearVelocity(body, body.LinearVelocity * newSpeed);
_physics.SetLinearVelocity(uid, body.LinearVelocity * newSpeed, body: body);
}
private void ReduceAngularVelocity(bool prediction, PhysicsComponent body, float friction, float frameTime)
private void ReduceAngularVelocity(EntityUid uid, bool prediction, PhysicsComponent body, float friction, float frameTime)
{
var speed = MathF.Abs(body.AngularVelocity);
@@ -184,14 +185,14 @@ namespace Content.Shared.Friction
var newSpeed = MathF.Max(0.0f, speed - drop);
newSpeed /= speed;
_physics.SetAngularVelocity(body, body.AngularVelocity * newSpeed);
_physics.SetAngularVelocity(uid, body.AngularVelocity * newSpeed, body: body);
}
[Pure]
private float GetTileFriction(PhysicsComponent body, TransformComponent xform)
private float GetTileFriction(EntityUid uid, PhysicsComponent body, TransformComponent xform)
{
// TODO: Make IsWeightless event-based; we already have grid traversals tracked so just raise events
if (_gravity.IsWeightless(body.Owner, body, xform))
if (_gravity.IsWeightless(uid, body, xform))
return 0.0f;
if (!xform.Coordinates.IsValid(EntityManager)) return 0.0f;
@@ -201,7 +202,8 @@ namespace Content.Shared.Friction
var tile = grid.GetTileRef(xform.Coordinates);
// If it's a map but on an empty tile then just assume it has gravity.
if (tile.Tile.IsEmpty && HasComp<MapComponent>(xform.GridUid) &&
if (tile.Tile.IsEmpty &&
HasComp<MapComponent>(xform.GridUid) &&
(!TryComp<GravityComponent>(xform.GridUid, out var gravity) || gravity.Enabled))
{
return DefaultFriction;

View File

@@ -42,21 +42,20 @@ public partial class MobStateSystem
private void OnStateExitSubscribers(EntityUid target, MobStateComponent component, MobState state)
{
var uid = component.Owner;
switch (state)
{
case MobState.Alive:
//unused
break;
case MobState.Critical:
_standing.Stand(uid);
_standing.Stand(target);
break;
case MobState.Dead:
RemComp<CollisionWakeComponent>(uid);
_standing.Stand(uid);
if (!_standing.IsDown(uid) && TryComp<PhysicsComponent>(uid, out var physics))
RemComp<CollisionWakeComponent>(target);
_standing.Stand(target);
if (!_standing.IsDown(target) && TryComp<PhysicsComponent>(target, out var physics))
{
_physics.SetCanCollide(physics, true);
_physics.SetCanCollide(target, true, body: physics);
}
break;
@@ -70,28 +69,27 @@ public partial class MobStateSystem
private void OnStateEnteredSubscribers(EntityUid target, MobStateComponent component, MobState state)
{
var uid = component.Owner;
_blocker.UpdateCanMove(uid); //update movement anytime a state changes
_blocker.UpdateCanMove(target); //update movement anytime a state changes
switch (state)
{
case MobState.Alive:
_standing.Stand(uid);
_appearance.SetData(uid, MobStateVisuals.State, MobState.Alive);
_standing.Stand(target);
_appearance.SetData(target, MobStateVisuals.State, MobState.Alive);
break;
case MobState.Critical:
_standing.Down(uid);
_appearance.SetData(uid, MobStateVisuals.State, MobState.Critical);
_standing.Down(target);
_appearance.SetData(target, MobStateVisuals.State, MobState.Critical);
break;
case MobState.Dead:
EnsureComp<CollisionWakeComponent>(uid);
_standing.Down(uid);
EnsureComp<CollisionWakeComponent>(target);
_standing.Down(target);
if (_standing.IsDown(uid) && TryComp<PhysicsComponent>(uid, out var physics))
if (_standing.IsDown(target) && TryComp<PhysicsComponent>(target, out var physics))
{
_physics.SetCanCollide(physics, false);
_physics.SetCanCollide(target, false, body: physics);
}
_appearance.SetData(uid, MobStateVisuals.State, MobState.Dead);
_appearance.SetData(target, MobStateVisuals.State, MobState.Dead);
break;
case MobState.Invalid:
//unused;

View File

@@ -34,6 +34,7 @@ namespace Content.Shared.Movement.Systems
[Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!;
[Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly SharedGravitySystem _gravity = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
@@ -304,10 +305,10 @@ namespace Content.Shared.Movement.Systems
if (!weightless || touching)
Accelerate(ref velocity, in worldTotal, accel, frameTime);
PhysicsSystem.SetLinearVelocity(physicsComponent, velocity);
PhysicsSystem.SetLinearVelocity(physicsComponent.Owner, velocity, body: physicsComponent);
// Ensures that players do not spiiiiiiin
PhysicsSystem.SetAngularVelocity(physicsComponent, 0);
PhysicsSystem.SetAngularVelocity(physicsComponent.Owner, 0, body: physicsComponent);
}
private void Friction(float minimumFrictionSpeed, float frameTime, float friction, ref Vector2 velocity)
@@ -364,7 +365,7 @@ namespace Content.Shared.Movement.Systems
/// </summary>
private bool IsAroundCollider(SharedPhysicsSystem broadPhaseSystem, TransformComponent transform, MobMoverComponent mover, PhysicsComponent collider)
{
var enlargedAABB = collider.GetWorldAABB().Enlarged(mover.GrabRangeVV);
var enlargedAABB = _lookup.GetWorldAABB(collider.Owner, transform).Enlarged(mover.GrabRangeVV);
foreach (var otherCollider in broadPhaseSystem.GetCollidingEntities(transform.MapID, enlargedAABB))
{

View File

@@ -1,5 +1,4 @@
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Components;
namespace Content.Shared.Physics.Pull
{

View File

@@ -146,7 +146,7 @@ namespace Content.Shared.Pulling
if (!_timing.ApplyingState)
{
// Joint startup
var union = _physics.GetHardAABB(pullerPhysics).Union(_physics.GetHardAABB(pullablePhysics));
var union = _physics.GetHardAABB(puller.Owner).Union(_physics.GetHardAABB(pullable.Owner, body: pullablePhysics));
var length = Math.Max(union.Size.X, union.Size.Y) * 0.75f;
var joint = _jointSystem.CreateDistanceJoint(pullablePhysics.Owner, pullerPhysics.Owner, id: pullable.PullJointId);

View File

@@ -11,15 +11,17 @@ using Robust.Shared.Containers;
using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
namespace Content.Shared.Pulling
{
public abstract partial class SharedPullingSystem : EntitySystem
public abstract partial class SharedPullingSystem
{
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[Dependency] private readonly SharedInteractionSystem _interaction = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
public bool CanPull(EntityUid puller, EntityUid pulled)
@@ -102,7 +104,7 @@ namespace Content.Shared.Pulling
if (TryComp<PhysicsComponent>(pullable.Owner, out var pullablePhysics))
{
pullablePhysics.FixedRotation = pullable.PrevFixedRotation;
_physics.SetFixedRotation(pullable.Owner, pullable.PrevFixedRotation, body: pullablePhysics);
}
_pullSm.ForceRelationship(null, pullable);
@@ -198,7 +200,7 @@ namespace Content.Shared.Pulling
_pullSm.ForceRelationship(puller, pullable);
pullable.PrevFixedRotation = pullablePhysics.FixedRotation;
pullablePhysics.FixedRotation = pullable.FixedRotationOnPull;
_physics.SetFixedRotation(pullable.Owner, pullable.FixedRotationOnPull, body: pullablePhysics);
_adminLogger.Add(LogType.Action, LogImpact.Low,
$"{ToPrettyString(puller.Owner):user} started pulling {ToPrettyString(pullable.Owner):target}");
return true;

View File

@@ -40,8 +40,8 @@ public abstract class SharedCorporealSystem : EntitySystem
{
var fixture = fixtures.Fixtures.Values.First();
_physics.SetCollisionMask(fixture, (int) (CollisionGroup.SmallMobMask | CollisionGroup.GhostImpassable));
_physics.SetCollisionLayer(fixture, (int) CollisionGroup.SmallMobLayer);
_physics.SetCollisionMask(uid, fixture, (int) (CollisionGroup.SmallMobMask | CollisionGroup.GhostImpassable), fixtures);
_physics.SetCollisionLayer(uid, fixture, (int) CollisionGroup.SmallMobLayer, fixtures);
}
_movement.RefreshMovementSpeedModifiers(uid);
}
@@ -54,8 +54,8 @@ public abstract class SharedCorporealSystem : EntitySystem
{
var fixture = fixtures.Fixtures.Values.First();
_physics.SetCollisionMask(fixture, (int) CollisionGroup.GhostImpassable);
_physics.SetCollisionLayer(fixture, 0);
_physics.SetCollisionMask(uid, fixture, (int) CollisionGroup.GhostImpassable, fixtures);
_physics.SetCollisionLayer(uid, fixture, 0, fixtures);
}
component.MovementSpeedDebuff = 1; //just so we can avoid annoying code elsewhere
_movement.RefreshMovementSpeedModifiers(uid);

View File

@@ -6,6 +6,7 @@ using Robust.Shared.Physics.Systems;
using Content.Shared.Ghost;
using Content.Shared.Singularity.Components;
using Robust.Shared.Physics;
namespace Content.Shared.Singularity.EntitySystems;
@@ -14,10 +15,11 @@ namespace Content.Shared.Singularity.EntitySystems;
/// </summary>
public abstract class SharedEventHorizonSystem : EntitySystem
{
#region Dependencies
[Dependency] private readonly FixtureSystem _fixtures = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] protected readonly IViewVariablesManager Vvm = default!;
#endregion Dependencies
public override void Initialize()
{
base.Initialize();
@@ -62,7 +64,7 @@ public abstract class SharedEventHorizonSystem : EntitySystem
return;
eventHorizon.Radius = value;
EntityManager.Dirty(eventHorizon);
Dirty(eventHorizon);
if (updateFixture)
UpdateEventHorizonFixture(uid, eventHorizon: eventHorizon);
}
@@ -85,7 +87,7 @@ public abstract class SharedEventHorizonSystem : EntitySystem
return;
eventHorizon.CanBreachContainment = value;
EntityManager.Dirty(eventHorizon);
Dirty(eventHorizon);
if (updateFixture)
UpdateEventHorizonFixture(uid, eventHorizon: eventHorizon);
}
@@ -108,7 +110,7 @@ public abstract class SharedEventHorizonSystem : EntitySystem
return;
eventHorizon.HorizonFixtureId = value;
EntityManager.Dirty(eventHorizon);
Dirty(eventHorizon);
if (updateFixture)
UpdateEventHorizonFixture(uid, eventHorizon: eventHorizon);
}
@@ -117,25 +119,26 @@ public abstract class SharedEventHorizonSystem : EntitySystem
/// Updates the state of the fixture associated with the event horizon.
/// </summary>
/// <param name="eventHorizon">The uid of the event horizon associated with the fixture to update.</param>
/// <param name="fixtures">The physics component containing the fixture to update.</param>
/// <param name="physics">The physics component containing the fixture to update.</param>
/// <param name="eventHorizon">The state of the event horizon associated with the fixture to update.</param>
public void UpdateEventHorizonFixture(EntityUid uid, PhysicsComponent? fixtures = null, EventHorizonComponent? eventHorizon = null)
public void UpdateEventHorizonFixture(EntityUid uid, PhysicsComponent? physics = null, EventHorizonComponent? eventHorizon = null)
{
if(!Resolve(uid, ref eventHorizon))
return;
var fixtureId = eventHorizon.HorizonFixtureId;
if (fixtureId == null || !Resolve(eventHorizon.Owner, ref fixtures, logMissing: false))
FixturesComponent? manager = null;
if (fixtureId == null || !Resolve(uid, ref manager, ref physics, logMissing: false))
return;
var fixture = _fixtures.GetFixtureOrNull(fixtures, fixtureId);
var fixture = _fixtures.GetFixtureOrNull(uid, fixtureId, manager);
if (fixture == null)
return;
var shape = (PhysShapeCircle)fixture.Shape;
shape.Radius = eventHorizon.Radius;
fixture.Hard = !eventHorizon.CanBreachContainment;
EntityManager.Dirty(fixtures);
_physics.SetRadius(uid, fixture, shape, eventHorizon.Radius, manager: manager, body: physics);
_physics.SetHard(uid, fixture, true, manager);
}
#endregion Getters/Setters
@@ -181,8 +184,8 @@ public abstract class SharedEventHorizonSystem : EntitySystem
var otherUid = args.BodyB.Owner;
// For prediction reasons always want the client to ignore these.
if (EntityManager.HasComponent<MapGridComponent>(otherUid) ||
EntityManager.HasComponent<SharedGhostComponent>(otherUid))
if (HasComp<MapGridComponent>(otherUid) ||
HasComp<SharedGhostComponent>(otherUid))
{
args.Cancelled = true;
return true;
@@ -190,8 +193,8 @@ public abstract class SharedEventHorizonSystem : EntitySystem
// If we can, breach containment
// otherwise, check if it's containment and just keep the collision
if (EntityManager.HasComponent<ContainmentFieldComponent>(otherUid) ||
EntityManager.HasComponent<ContainmentFieldGeneratorComponent>(otherUid))
if (HasComp<ContainmentFieldComponent>(otherUid) ||
HasComp<ContainmentFieldGeneratorComponent>(otherUid))
{
if (comp.CanBreachContainment)
args.Cancelled = true;

View File

@@ -355,7 +355,7 @@ public abstract class SharedSingularitySystem : EntitySystem
{
_physics.SetBodyStatus(comp, (args.NewValue > 1) ? BodyStatus.InAir : BodyStatus.OnGround);
if (args.NewValue <= 1 && args.OldValue > 1) // Apparently keeps singularities from getting stuck in the corners of containment fields.
_physics.SetLinearVelocity(comp, Vector2.Zero); // No idea how stopping the singularities movement keeps it from getting stuck though.
_physics.SetLinearVelocity(uid, Vector2.Zero, body: comp); // No idea how stopping the singularities movement keeps it from getting stuck though.
}
/// <summary>

View File

@@ -85,7 +85,7 @@ namespace Content.Shared.Slippery
return;
if (TryComp(other, out PhysicsComponent? physics))
_physics.SetLinearVelocity(physics, physics.LinearVelocity * component.LaunchForwardsMultiplier);
_physics.SetLinearVelocity(other, physics.LinearVelocity * component.LaunchForwardsMultiplier, body: physics);
var playSound = !_statusEffectsSystem.HasStatusEffect(other, "KnockedDown");

View File

@@ -96,7 +96,7 @@ namespace Content.Shared.Standing
continue;
standingState.ChangedFixtures.Add(key);
_physics.SetCollisionMask(fixture, fixture.CollisionMask & ~StandingCollisionLayer);
_physics.SetCollisionMask(uid, fixture, fixture.CollisionMask & ~StandingCollisionLayer, manager: fixtureComponent);
}
}
@@ -148,7 +148,7 @@ namespace Content.Shared.Standing
foreach (var key in standingState.ChangedFixtures)
{
if (fixtureComponent.Fixtures.TryGetValue(key, out var fixture))
_physics.SetCollisionMask(fixture, fixture.CollisionMask | StandingCollisionLayer);
_physics.SetCollisionMask(uid, fixture, fixture.CollisionMask | StandingCollisionLayer, fixtureComponent);
}
}
standingState.ChangedFixtures.Clear();

View File

@@ -60,7 +60,7 @@ public sealed class ThrowingSystem : EntitySystem
comp.Thrower = user;
// Give it a l'il spin.
if (!_tagSystem.HasTag(uid, "NoSpinOnThrow"))
_physics.ApplyAngularImpulse(physics, ThrowAngularImpulse);
_physics.ApplyAngularImpulse(uid, ThrowAngularImpulse, body: physics);
else
{
if (transform == null)
@@ -75,7 +75,7 @@ public sealed class ThrowingSystem : EntitySystem
_interactionSystem.ThrownInteraction(user.Value, uid);
var impulseVector = direction.Normalized * strength * physics.Mass;
_physics.ApplyLinearImpulse(physics, impulseVector);
_physics.ApplyLinearImpulse(uid, impulseVector, body: physics);
// Estimate time to arrival so we can apply OnGround status and slow it much faster.
var time = (direction / strength).Length;
@@ -109,7 +109,7 @@ public sealed class ThrowingSystem : EntitySystem
RaiseLocalEvent(physics.Owner, msg);
if (!msg.Cancelled)
_physics.ApplyLinearImpulse(userPhysics, -impulseVector * pushbackRatio);
_physics.ApplyLinearImpulse(user.Value, -impulseVector * pushbackRatio, body: userPhysics);
}
}
}

View File

@@ -55,19 +55,16 @@ namespace Content.Shared.Throwing
private void ThrowItem(EntityUid uid, ThrownItemComponent component, ThrownEvent args)
{
if (!EntityManager.TryGetComponent(component.Owner, out FixturesComponent? fixturesComponent) ||
fixturesComponent.Fixtures.Count != 1) return;
if (!EntityManager.TryGetComponent(component.Owner, out PhysicsComponent? physicsComponent)) return;
if (fixturesComponent.Fixtures.ContainsKey(ThrowingFixture))
if (!EntityManager.TryGetComponent(uid, out FixturesComponent? fixturesComponent) ||
fixturesComponent.Fixtures.Count != 1 ||
!TryComp<PhysicsComponent>(uid, out var body))
{
Logger.Error($"Found existing throwing fixture on {component.Owner}");
return;
}
var fixture = fixturesComponent.Fixtures.Values.First();
var shape = fixture.Shape;
var throwingFixture = new Fixture(physicsComponent, shape) { CollisionMask = (int) CollisionGroup.ThrownItem, Hard = false, ID = ThrowingFixture };
_fixtures.TryCreateFixture(physicsComponent, throwingFixture, manager: fixturesComponent);
_fixtures.TryCreateFixture(uid, shape, ThrowingFixture, hard: false, collisionMask: (int) CollisionGroup.ThrownItem, manager: fixturesComponent, body: body);
}
private void HandleCollision(EntityUid uid, ThrownItemComponent component, ref StartCollideEvent args)
@@ -104,13 +101,13 @@ namespace Content.Shared.Throwing
private void StopThrow(EntityUid uid, ThrownItemComponent thrownItemComponent)
{
if (EntityManager.TryGetComponent(uid, out PhysicsComponent? physicsComponent))
if (EntityManager.TryGetComponent(uid, out FixturesComponent? manager))
{
var fixture = _fixtures.GetFixtureOrNull(physicsComponent, ThrowingFixture);
var fixture = _fixtures.GetFixtureOrNull(uid, ThrowingFixture, manager: manager);
if (fixture != null)
{
_fixtures.DestroyFixture(physicsComponent, fixture);
_fixtures.DestroyFixture(uid, fixture, manager: manager);
}
}

View File

@@ -28,21 +28,12 @@ public abstract class SharedFlyBySoundSystem : EntitySystem
private void OnStartup(EntityUid uid, FlyBySoundComponent component, ComponentStartup args)
{
if (!TryComp<PhysicsComponent>(uid, out var body)) return;
if (!TryComp<PhysicsComponent>(uid, out var body))
return;
var shape = new PhysShapeCircle()
{
Radius = component.Range,
};
var shape = new PhysShapeCircle(component.Range);
var fixture = new Fixture(body, shape)
{
Hard = false,
ID = FlyByFixture,
CollisionLayer = (int) CollisionGroup.MobMask,
};
_fixtures.TryCreateFixture(body, fixture);
_fixtures.TryCreateFixture(uid, shape, FlyByFixture, collisionLayer: (int) CollisionGroup.MobMask, hard: false, body: body);
}
private void OnShutdown(EntityUid uid, FlyBySoundComponent component, ComponentShutdown args)
@@ -53,7 +44,7 @@ public abstract class SharedFlyBySoundSystem : EntitySystem
return;
}
_fixtures.DestroyFixture(body, FlyByFixture);
_fixtures.DestroyFixture(uid, FlyByFixture, body: body);
}
private void OnHandleState(EntityUid uid, FlyBySoundComponent component, ref ComponentHandleState args)

View File

@@ -383,7 +383,7 @@ public abstract partial class SharedGunSystem : EntitySystem
const float impulseStrength = 85.0f; //The bullet impulse strength, TODO: In the future we might want to make it more projectile dependent
var impulseVector = shotDirection * impulseStrength;
Physics.ApplyLinearImpulse(userPhysics, -impulseVector);
Physics.ApplyLinearImpulse(userPhysics.Owner, -impulseVector, body: userPhysics);
}
protected abstract void CreateEffect(EntityUid uid, MuzzleFlashEvent message, EntityUid? user = null);

View File

@@ -11,7 +11,6 @@
- type: Physics
bodyType: KinematicController
fixedRotation: true
status: OnGround
- type: Fixtures
fixtures:
- shape:

View File

@@ -102,6 +102,7 @@
fixtures:
- shape:
!type:PhysShapeAabb
bounds: "-0.5,-0.5,0.5,0.5"
density: 190
mask:
- FullTileMask