diff --git a/Content.Server/AI/Pathfinding/PathfindingNode.cs b/Content.Server/AI/Pathfinding/PathfindingNode.cs index d99bdc3511ab..7fc02b76bdb3 100644 --- a/Content.Server/AI/Pathfinding/PathfindingNode.cs +++ b/Content.Server/AI/Pathfinding/PathfindingNode.cs @@ -263,7 +263,8 @@ public void AddEntity(EntityUid entity, IPhysBody physicsComponent, IEntityManag DebugTools.Assert((PathfindingSystem.TrackedCollisionLayers & physicsComponent.CollisionLayer) != 0); - if (physicsComponent.BodyType != BodyType.Static) + if (physicsComponent.BodyType != BodyType.Static || + !physicsComponent.Hard) { _physicsLayers.Add(entity, physicsComponent.CollisionLayer); } @@ -285,18 +286,19 @@ public void RemoveEntity(EntityUid entity) // There's no guarantee that the entity isn't deleted // 90% of updates are probably entities moving around // Entity can't be under multiple categories so just checking each once is fine. - if (_physicsLayers.ContainsKey(entity)) + if (_physicsLayers.Remove(entity)) { - _physicsLayers.Remove(entity); + return; } - else if (_accessReaders.ContainsKey(entity)) + + if (_accessReaders.Remove(entity)) { - _accessReaders.Remove(entity); ParentChunk.Dirty(); + return; } - else if (_blockedCollidables.ContainsKey(entity)) + + if (_blockedCollidables.Remove(entity)) { - _blockedCollidables.Remove(entity); GenerateMask(); ParentChunk.Dirty(); } diff --git a/Content.Server/AI/Pathfinding/PathfindingSystem.Grid.cs b/Content.Server/AI/Pathfinding/PathfindingSystem.Grid.cs index 4c41f4d4a49a..037ac965ed22 100644 --- a/Content.Server/AI/Pathfinding/PathfindingSystem.Grid.cs +++ b/Content.Server/AI/Pathfinding/PathfindingSystem.Grid.cs @@ -7,11 +7,12 @@ namespace Content.Server.AI.Pathfinding; -/// -/// Handles pathfinding while on a grid. -/// public sealed partial class PathfindingSystem { + /* + * Handles pathfinding while on a grid. + */ + [Dependency] private readonly AccessReaderSystem _accessReader = default!; [Dependency] private readonly IMapManager _mapManager = default!; @@ -28,11 +29,23 @@ public override void Initialize() SubscribeLocalEvent(OnAccessChange); SubscribeLocalEvent(OnGridAdd); SubscribeLocalEvent(OnTileChange); + SubscribeLocalEvent(OnBodyTypeChange); // Handle all the base grid changes // Anything that affects traversal (i.e. collision layer) is handled separately. } + private void OnBodyTypeChange(ref PhysicsBodyTypeChangedEvent ev) + { + var xform = Transform(ev.Entity); + + if (!IsRelevant(xform, ev.Component)) return; + + var node = GetNode(xform); + node?.RemoveEntity(ev.Entity); + node?.AddEntity(ev.Entity, ev.Component, EntityManager); + } + private void OnGridAdd(GridAddEvent ev) { EnsureComp(ev.EntityUid); @@ -91,6 +104,8 @@ private PathfindingChunk CreateChunk(GridPathfindingComponent comp, Vector2i ind return newChunk; } + + /// /// Return the corresponding PathfindingNode for this tile /// @@ -149,6 +164,27 @@ private void OnEntityRemove(EntityUid entity, TransformComponent? xform = null) node.RemoveEntity(entity); } + private void OnEntityRemove(EntityUid entity, EntityCoordinates coordinates) + { + var gridId = coordinates.GetGridId(EntityManager); + if (!_mapManager.TryGetGrid(gridId, out var grid)) return; + + var node = GetNode(grid.GetTileRef(coordinates)); + node.RemoveEntity(entity); + } + + private PathfindingNode? GetNode(TransformComponent xform) + { + if (!_mapManager.TryGetGrid(xform.GridID, out var grid)) return null; + return GetNode(grid.GetTileRef(xform.Coordinates)); + } + + private PathfindingNode? GetNode(EntityCoordinates coordinates) + { + if (!_mapManager.TryGetGrid(coordinates.GetGridId(EntityManager), out var grid)) return null; + return GetNode(grid.GetTileRef(coordinates)); + } + /// /// When an entity moves around we'll remove it from its old node and add it to its new node (if applicable) /// @@ -159,27 +195,19 @@ private void OnEntityMove(MoveEvent moveEvent) // If we've moved to space or the likes then remove us. if (!TryComp(moveEvent.Sender, out var physics) || - !IsRelevant(xform, physics) || - moveEvent.NewPosition.GetGridId(EntityManager) == GridId.Invalid) + !IsRelevant(xform, physics)) { - OnEntityRemove(moveEvent.Sender, xform); + OnEntityRemove(moveEvent.Sender, moveEvent.OldPosition); return; } - var oldGridId = moveEvent.OldPosition.GetGridId(EntityManager); - var gridId = moveEvent.NewPosition.GetGridId(EntityManager); + var oldNode = GetNode(moveEvent.OldPosition); + var newNode = GetNode(moveEvent.NewPosition); - if (_mapManager.TryGetGrid(oldGridId, out var oldGrid)) - { - var oldNode = GetNode(oldGrid.GetTileRef(moveEvent.OldPosition)); - oldNode.RemoveEntity(moveEvent.Sender); - } + if (oldNode?.Equals(newNode) == true) return; - if (_mapManager.TryGetGrid(gridId, out var grid)) - { - var newNode = GetNode(grid.GetTileRef(moveEvent.OldPosition)); - newNode.AddEntity(moveEvent.Sender, physics, EntityManager); - } + oldNode?.RemoveEntity(moveEvent.Sender); + newNode?.AddEntity(moveEvent.Sender, physics, EntityManager); } // TODO: Need to rethink the pathfinder utils (traversable etc.). Maybe just chuck them all in PathfindingSystem diff --git a/Content.Server/Disposal/Tube/DisposalTubeSystem.cs b/Content.Server/Disposal/Tube/DisposalTubeSystem.cs index 126de2783f9c..bb9509af1bc6 100644 --- a/Content.Server/Disposal/Tube/DisposalTubeSystem.cs +++ b/Content.Server/Disposal/Tube/DisposalTubeSystem.cs @@ -114,7 +114,7 @@ private void OnOpenTaggerUIAttempt(EntityUid uid, DisposalTaggerComponent router private static void BodyTypeChanged( EntityUid uid, DisposalTubeComponent component, - PhysicsBodyTypeChangedEvent args) + ref PhysicsBodyTypeChangedEvent args) { component.AnchoredChanged(); } diff --git a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs index d087bab9d2be..dcfeff598548 100644 --- a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs +++ b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs @@ -15,7 +15,7 @@ private void InitializePartSystem() private static void BodyTypeChanged( EntityUid uid, ParticleAcceleratorPartComponent component, - PhysicsBodyTypeChangedEvent args) + ref PhysicsBodyTypeChangedEvent args) { component.OnAnchorChanged(); } diff --git a/Content.Server/Singularity/EntitySystems/ContainmentFieldGeneratorSystem.cs b/Content.Server/Singularity/EntitySystems/ContainmentFieldGeneratorSystem.cs index 0e8eba054754..67e92dc16385 100644 --- a/Content.Server/Singularity/EntitySystems/ContainmentFieldGeneratorSystem.cs +++ b/Content.Server/Singularity/EntitySystems/ContainmentFieldGeneratorSystem.cs @@ -57,7 +57,7 @@ private void HandleFieldCollide(EntityUid uid, ContainmentFieldComponent compone private static void BodyTypeChanged( EntityUid uid, ContainmentFieldGeneratorComponent component, - PhysicsBodyTypeChangedEvent args) + ref PhysicsBodyTypeChangedEvent args) { component.OnAnchoredChanged(); } diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml index 0ce3d0d10045..afdfc3448e3c 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml @@ -4,6 +4,9 @@ id: SimpleSpaceMobBase # Mob without barotrauma, freezing and asphyxiation (for space carps!?) suffix: AI components: + - type: Tag + tags: + - DoorBumpOpener - type: Reactive groups: Flammable: [Touch] diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index 8c355b9442e5..916fd6d779c8 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -31,7 +31,7 @@ fixtures: - shape: !type:PhysShapeCircle - radius: 0.35 + radius: 0.25 mass: 120 mask: - MobMask @@ -88,6 +88,8 @@ - type: Tag tags: - CannotSuicide + - DoorBumpOpener + - FootstepSound - type: NoSlip - type: entity