From 645c2494ec68b71c20627dc65d69b782b4d614c3 Mon Sep 17 00:00:00 2001 From: Ilya246 <57039557+Ilya246@users.noreply.github.com> Date: Sun, 28 Dec 2025 11:16:07 +0400 Subject: [PATCH] optimise shuttle collision entity throwing (#40984) * optimise * reconstruct * fix * very mild change --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- .../Shuttles/Systems/ShuttleSystem.Impact.cs | 49 ++++++++++++++----- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/Content.Server/Shuttles/Systems/ShuttleSystem.Impact.cs b/Content.Server/Shuttles/Systems/ShuttleSystem.Impact.cs index 6126234451..d50eea53ee 100644 --- a/Content.Server/Shuttles/Systems/ShuttleSystem.Impact.cs +++ b/Content.Server/Shuttles/Systems/ShuttleSystem.Impact.cs @@ -231,35 +231,58 @@ public sealed partial class ShuttleSystem var knockdownTime = TimeSpan.FromSeconds(5); var minsq = _minThrowVelocity * _minThrowVelocity; - // iterate all entities on the grid - // TODO: only iterate non-static entities - var childEnumerator = xform.ChildEnumerator; - while (childEnumerator.MoveNext(out var uid)) - { - // don't throw static bodies - if (!_physicsQuery.TryGetComponent(uid, out var physics) || (physics.BodyType & BodyType.Static) != 0) - continue; + // iterate all dynamic entities on the grid + if (!TryComp(gridUid, out var lookup) || !_gridQuery.TryComp(gridUid, out var gridComp)) + return; + + var gridBox = gridComp.LocalAABB; + List> list = new(); + HashSet processed = new(); + var state = (list, processed, _physicsQuery); + lookup.DynamicTree.QueryAabb(ref state, GridQueryCallback, gridBox, true); + lookup.SundriesTree.QueryAabb(ref state, GridQueryCallback, gridBox, true); + + foreach (var ent in list) + { // don't throw if buckled - if (_buckle.IsBuckled(uid, _buckleQuery.CompOrNull(uid))) + if (_buckle.IsBuckled(ent, _buckleQuery.CompOrNull(ent))) continue; // don't throw them if they have magboots - if (movedByPressureQuery.TryComp(uid, out var moved) && !moved.Enabled) + if (movedByPressureQuery.TryComp(ent, out var moved) && !moved.Enabled) continue; if (direction.LengthSquared() > minsq) { - _stuns.TryCrawling(uid, knockdownTime); - _throwing.TryThrow(uid, direction, physics, Transform(uid), _projQuery, direction.Length(), playSound: false); + _stuns.TryCrawling(ent.Owner, knockdownTime); + _throwing.TryThrow(ent, direction, ent.Comp, Transform(ent), _projQuery, direction.Length(), playSound: false); } else { - _physics.ApplyLinearImpulse(uid, direction * physics.Mass, body: physics); + _physics.ApplyLinearImpulse(ent, direction * ent.Comp.Mass, body: ent.Comp); } } } + private static bool GridQueryCallback( + ref (List> List, HashSet Processed, EntityQuery PhysicsQuery) state, + in EntityUid uid) + { + if (state.Processed.Add(uid) && state.PhysicsQuery.TryComp(uid, out var body)) + state.List.Add((uid, body)); + + return true; + } + + private static bool GridQueryCallback( + ref (List> List, HashSet Processed, EntityQuery PhysicsQuery) state, + in FixtureProxy proxy) + { + var owner = proxy.Entity; + return GridQueryCallback(ref state, in owner); + } + /// /// Structure to hold impact tile processing data for batch processing /// -- 2.52.0