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