Small ExplosionSystem Cleanup (#20817)
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Reflection;
|
||||||
using Content.Server.Explosion.Components;
|
using Content.Server.Explosion.Components;
|
||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
@@ -18,11 +19,12 @@ using Robust.Shared.Physics.Components;
|
|||||||
using Robust.Shared.Physics.Dynamics;
|
using Robust.Shared.Physics.Dynamics;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent;
|
using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent;
|
||||||
|
|
||||||
namespace Content.Server.Explosion.EntitySystems;
|
namespace Content.Server.Explosion.EntitySystems;
|
||||||
|
|
||||||
public sealed partial class ExplosionSystem : EntitySystem
|
public sealed partial class ExplosionSystem
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to limit explosion processing time. See <see cref="MaxProcessingTime"/>.
|
/// Used to limit explosion processing time. See <see cref="MaxProcessingTime"/>.
|
||||||
@@ -176,12 +178,12 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
/// Used for a variation of <see cref="TurfHelpers.IsBlockedTurf()"/> that makes use of the fact that we have
|
/// Used for a variation of <see cref="TurfHelpers.IsBlockedTurf()"/> that makes use of the fact that we have
|
||||||
/// already done an entity lookup on a tile, and don't need to do so again.
|
/// already done an entity lookup on a tile, and don't need to do so again.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public bool IsBlockingTurf(EntityUid uid, EntityQuery<PhysicsComponent> physicsQuery)
|
public bool IsBlockingTurf(EntityUid uid)
|
||||||
{
|
{
|
||||||
if (EntityManager.IsQueuedForDeletion(uid))
|
if (EntityManager.IsQueuedForDeletion(uid))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!physicsQuery.TryGetComponent(uid, out var physics))
|
if (!_physicsQuery.TryGetComponent(uid, out var physics))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return physics.CanCollide && physics.Hard && (physics.CollisionLayer & (int) CollisionGroup.Impassable) != 0;
|
return physics.CanCollide && physics.Hard && (physics.CollisionLayer & (int) CollisionGroup.Impassable) != 0;
|
||||||
@@ -198,19 +200,14 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
DamageSpecifier damage,
|
DamageSpecifier damage,
|
||||||
MapCoordinates epicenter,
|
MapCoordinates epicenter,
|
||||||
HashSet<EntityUid> processed,
|
HashSet<EntityUid> processed,
|
||||||
string id,
|
string id)
|
||||||
EntityQuery<TransformComponent> xformQuery,
|
|
||||||
EntityQuery<DamageableComponent> damageQuery,
|
|
||||||
EntityQuery<PhysicsComponent> physicsQuery,
|
|
||||||
EntityQuery<TagComponent> tagQuery,
|
|
||||||
EntityQuery<ProjectileComponent> projectileQuery)
|
|
||||||
{
|
{
|
||||||
var gridBox = new Box2(tile * grid.TileSize, (tile + 1) * grid.TileSize);
|
var gridBox = new Box2(tile * grid.TileSize, (tile + 1) * grid.TileSize);
|
||||||
|
|
||||||
// get the entities on a tile. Note that we cannot process them directly, or we get
|
// get the entities on a tile. Note that we cannot process them directly, or we get
|
||||||
// enumerator-changed-while-enumerating errors.
|
// enumerator-changed-while-enumerating errors.
|
||||||
List<TransformComponent> list = new();
|
List<(EntityUid, TransformComponent)> list = new();
|
||||||
var state = (list, processed, xformQuery);
|
var state = (list, processed, _transformQuery);
|
||||||
|
|
||||||
// get entities:
|
// get entities:
|
||||||
lookup.DynamicTree.QueryAabb(ref state, GridQueryCallback, gridBox, true);
|
lookup.DynamicTree.QueryAabb(ref state, GridQueryCallback, gridBox, true);
|
||||||
@@ -219,9 +216,9 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
lookup.StaticSundriesTree.QueryAabb(ref state, GridQueryCallback, gridBox, true);
|
lookup.StaticSundriesTree.QueryAabb(ref state, GridQueryCallback, gridBox, true);
|
||||||
|
|
||||||
// process those entities
|
// process those entities
|
||||||
foreach (var xform in list)
|
foreach (var (uid, xform) in list)
|
||||||
{
|
{
|
||||||
ProcessEntity(xform.Owner, epicenter, damage, throwForce, id, xform, damageQuery, physicsQuery, xformQuery, tagQuery, projectileQuery);
|
ProcessEntity(uid, epicenter, damage, throwForce, id, xform);
|
||||||
}
|
}
|
||||||
|
|
||||||
// process anchored entities
|
// process anchored entities
|
||||||
@@ -230,7 +227,7 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
foreach (var entity in anchoredList)
|
foreach (var entity in anchoredList)
|
||||||
{
|
{
|
||||||
processed.Add(entity);
|
processed.Add(entity);
|
||||||
ProcessEntity(entity, epicenter, damage, throwForce, id, null, damageQuery, physicsQuery, xformQuery, tagQuery, projectileQuery);
|
ProcessEntity(entity, epicenter, damage, throwForce, id, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walls and reinforced walls will break into girders. These girders will also be considered turf-blocking for
|
// Walls and reinforced walls will break into girders. These girders will also be considered turf-blocking for
|
||||||
@@ -241,7 +238,7 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
foreach (var entity in grid.GetAnchoredEntities(tile))
|
foreach (var entity in grid.GetAnchoredEntities(tile))
|
||||||
{
|
{
|
||||||
tileBlocked |= IsBlockingTurf(entity, physicsQuery);
|
tileBlocked |= IsBlockingTurf(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,28 +257,28 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
lookup.DynamicTree.QueryAabb(ref state, GridQueryCallback, gridBox, true);
|
lookup.DynamicTree.QueryAabb(ref state, GridQueryCallback, gridBox, true);
|
||||||
lookup.SundriesTree.QueryAabb(ref state, GridQueryCallback, gridBox, true);
|
lookup.SundriesTree.QueryAabb(ref state, GridQueryCallback, gridBox, true);
|
||||||
|
|
||||||
foreach (var xform in list)
|
foreach (var (uid, xform) in list)
|
||||||
{
|
{
|
||||||
// Here we only throw, no dealing damage. Containers n such might drop their entities after being destroyed, but
|
// Here we only throw, no dealing damage. Containers n such might drop their entities after being destroyed, but
|
||||||
// they should handle their own damage pass-through, with their own damage reduction calculation.
|
// they should handle their own damage pass-through, with their own damage reduction calculation.
|
||||||
ProcessEntity(xform.Owner, epicenter, null, throwForce, id, xform, damageQuery, physicsQuery, xformQuery, tagQuery, projectileQuery);
|
ProcessEntity(uid, epicenter, null, throwForce, id, xform);
|
||||||
}
|
}
|
||||||
|
|
||||||
return !tileBlocked;
|
return !tileBlocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool GridQueryCallback(
|
private bool GridQueryCallback(
|
||||||
ref (List<TransformComponent> List, HashSet<EntityUid> Processed, EntityQuery<TransformComponent> XformQuery) state,
|
ref (List<(EntityUid, TransformComponent)> List, HashSet<EntityUid> Processed, EntityQuery<TransformComponent> XformQuery) state,
|
||||||
in EntityUid uid)
|
in EntityUid uid)
|
||||||
{
|
{
|
||||||
if (state.Processed.Add(uid) && state.XformQuery.TryGetComponent(uid, out var xform))
|
if (state.Processed.Add(uid) && state.XformQuery.TryGetComponent(uid, out var xform))
|
||||||
state.List.Add(xform);
|
state.List.Add((uid, xform));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool GridQueryCallback(
|
private bool GridQueryCallback(
|
||||||
ref (List<TransformComponent> List, HashSet<EntityUid> Processed, EntityQuery<TransformComponent> XformQuery) state,
|
ref (List<(EntityUid, TransformComponent)> List, HashSet<EntityUid> Processed, EntityQuery<TransformComponent> XformQuery) state,
|
||||||
in FixtureProxy proxy)
|
in FixtureProxy proxy)
|
||||||
{
|
{
|
||||||
var owner = proxy.Entity;
|
var owner = proxy.Entity;
|
||||||
@@ -299,17 +296,12 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
DamageSpecifier damage,
|
DamageSpecifier damage,
|
||||||
MapCoordinates epicenter,
|
MapCoordinates epicenter,
|
||||||
HashSet<EntityUid> processed,
|
HashSet<EntityUid> processed,
|
||||||
string id,
|
string id)
|
||||||
EntityQuery<TransformComponent> xformQuery,
|
|
||||||
EntityQuery<DamageableComponent> damageQuery,
|
|
||||||
EntityQuery<PhysicsComponent> physicsQuery,
|
|
||||||
EntityQuery<TagComponent> tagQuery,
|
|
||||||
EntityQuery<ProjectileComponent> projectileQuery)
|
|
||||||
{
|
{
|
||||||
var gridBox = Box2.FromDimensions(tile * DefaultTileSize, new Vector2(DefaultTileSize, DefaultTileSize));
|
var gridBox = Box2.FromDimensions(tile * DefaultTileSize, new Vector2(DefaultTileSize, DefaultTileSize));
|
||||||
var worldBox = spaceMatrix.TransformBox(gridBox);
|
var worldBox = spaceMatrix.TransformBox(gridBox);
|
||||||
var list = new List<TransformComponent>();
|
var list = new List<(EntityUid, TransformComponent)>();
|
||||||
var state = (list, processed, invSpaceMatrix, lookup.Owner, xformQuery, gridBox);
|
var state = (list, processed, invSpaceMatrix, lookup.Owner, _transformQuery, gridBox);
|
||||||
|
|
||||||
// get entities:
|
// get entities:
|
||||||
lookup.DynamicTree.QueryAabb(ref state, SpaceQueryCallback, worldBox, true);
|
lookup.DynamicTree.QueryAabb(ref state, SpaceQueryCallback, worldBox, true);
|
||||||
@@ -317,10 +309,10 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
lookup.SundriesTree.QueryAabb(ref state, SpaceQueryCallback, worldBox, true);
|
lookup.SundriesTree.QueryAabb(ref state, SpaceQueryCallback, worldBox, true);
|
||||||
lookup.StaticSundriesTree.QueryAabb(ref state, SpaceQueryCallback, worldBox, true);
|
lookup.StaticSundriesTree.QueryAabb(ref state, SpaceQueryCallback, worldBox, true);
|
||||||
|
|
||||||
foreach (var xform in state.Item1)
|
foreach (var (uid, xform) in state.Item1)
|
||||||
{
|
{
|
||||||
processed.Add(xform.Owner);
|
processed.Add(uid);
|
||||||
ProcessEntity(xform.Owner, epicenter, damage, throwForce, id, xform, damageQuery, physicsQuery, xformQuery, tagQuery, projectileQuery);
|
ProcessEntity(uid, epicenter, damage, throwForce, id, xform);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (throwForce <= 0)
|
if (throwForce <= 0)
|
||||||
@@ -332,14 +324,14 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
lookup.DynamicTree.QueryAabb(ref state, SpaceQueryCallback, worldBox, true);
|
lookup.DynamicTree.QueryAabb(ref state, SpaceQueryCallback, worldBox, true);
|
||||||
lookup.SundriesTree.QueryAabb(ref state, SpaceQueryCallback, worldBox, true);
|
lookup.SundriesTree.QueryAabb(ref state, SpaceQueryCallback, worldBox, true);
|
||||||
|
|
||||||
foreach (var xform in list)
|
foreach (var (uid, xform) in list)
|
||||||
{
|
{
|
||||||
ProcessEntity(xform.Owner, epicenter, null, throwForce, id, xform, damageQuery, physicsQuery, xformQuery, tagQuery, projectileQuery);
|
ProcessEntity(uid, epicenter, null, throwForce, id, xform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SpaceQueryCallback(
|
private bool SpaceQueryCallback(
|
||||||
ref (List<TransformComponent> List, HashSet<EntityUid> Processed, Matrix3 InvSpaceMatrix, EntityUid LookupOwner, EntityQuery<TransformComponent> XformQuery, Box2 GridBox) state,
|
ref (List<(EntityUid, TransformComponent)> List, HashSet<EntityUid> Processed, Matrix3 InvSpaceMatrix, EntityUid LookupOwner, EntityQuery<TransformComponent> XformQuery, Box2 GridBox) state,
|
||||||
in EntityUid uid)
|
in EntityUid uid)
|
||||||
{
|
{
|
||||||
if (state.Processed.Contains(uid))
|
if (state.Processed.Contains(uid))
|
||||||
@@ -351,20 +343,20 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
// parented directly to the map, use local position
|
// parented directly to the map, use local position
|
||||||
if (state.GridBox.Contains(state.InvSpaceMatrix.Transform(xform.LocalPosition)))
|
if (state.GridBox.Contains(state.InvSpaceMatrix.Transform(xform.LocalPosition)))
|
||||||
state.List.Add(xform);
|
state.List.Add((uid, xform));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally check if it intersects our tile
|
// finally check if it intersects our tile
|
||||||
if (state.GridBox.Contains(state.InvSpaceMatrix.Transform(_transformSystem.GetWorldPosition(xform, state.XformQuery))))
|
if (state.GridBox.Contains(state.InvSpaceMatrix.Transform(_transformSystem.GetWorldPosition(xform, state.XformQuery))))
|
||||||
state.List.Add(xform);
|
state.List.Add((uid, xform));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SpaceQueryCallback(
|
private bool SpaceQueryCallback(
|
||||||
ref (List<TransformComponent> List, HashSet<EntityUid> Processed, Matrix3 InvSpaceMatrix, EntityUid LookupOwner, EntityQuery<TransformComponent> XformQuery, Box2 GridBox) state,
|
ref (List<(EntityUid, TransformComponent)> List, HashSet<EntityUid> Processed, Matrix3 InvSpaceMatrix, EntityUid LookupOwner, EntityQuery<TransformComponent> XformQuery, Box2 GridBox) state,
|
||||||
in FixtureProxy proxy)
|
in FixtureProxy proxy)
|
||||||
{
|
{
|
||||||
var uid = proxy.Entity;
|
var uid = proxy.Entity;
|
||||||
@@ -380,44 +372,38 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
DamageSpecifier? damage,
|
DamageSpecifier? damage,
|
||||||
float throwForce,
|
float throwForce,
|
||||||
string id,
|
string id,
|
||||||
TransformComponent? xform,
|
TransformComponent? xform)
|
||||||
EntityQuery<DamageableComponent> damageQuery,
|
|
||||||
EntityQuery<PhysicsComponent> physicsQuery,
|
|
||||||
EntityQuery<TransformComponent> transformQuery,
|
|
||||||
EntityQuery<TagComponent> tagQuery,
|
|
||||||
EntityQuery<ProjectileComponent> projectileQuery)
|
|
||||||
{
|
{
|
||||||
// damage
|
// damage
|
||||||
if (damage != null && damageQuery.TryGetComponent(uid, out var damageable))
|
if (damage != null && _damageQuery.TryGetComponent(uid, out var damageable))
|
||||||
{
|
{
|
||||||
|
// TODO Explosion Performance
|
||||||
|
// Cache this? I.e., instead of raising an event, check for a component?
|
||||||
var ev = new GetExplosionResistanceEvent(id);
|
var ev = new GetExplosionResistanceEvent(id);
|
||||||
RaiseLocalEvent(uid, ref ev, false);
|
RaiseLocalEvent(uid, ref ev);
|
||||||
|
|
||||||
ev.DamageCoefficient = Math.Max(0, ev.DamageCoefficient);
|
ev.DamageCoefficient = Math.Max(0, ev.DamageCoefficient);
|
||||||
|
|
||||||
//todo need a way to track origin of explosion
|
// TODO explosion entity
|
||||||
if (ev.DamageCoefficient == 1)
|
// Move explosion data into the existing explosion visuals entity
|
||||||
|
// Give each explosion a unique name, include in admin logs.
|
||||||
|
|
||||||
|
// TODO Explosion Performance
|
||||||
|
// This creates a new dictionary. Maybe we should just re-use a private local damage specifier and update it.
|
||||||
|
// Though most entities shouldn't have explosion resistance, so maybe its fine.
|
||||||
|
// ReSharper disable once CompareOfFloatsByEqualityOperator
|
||||||
|
if (ev.DamageCoefficient != 1)
|
||||||
|
damage *= ev.DamageCoefficient;
|
||||||
|
|
||||||
|
// Log damage to players. Damage is logged before dealing damage so that the position can be logged before
|
||||||
|
// the entity gets deleted.
|
||||||
|
if (_mindQuery.HasComponent(uid))
|
||||||
{
|
{
|
||||||
// no damage-dict multiplication required.
|
_adminLogger.Add(LogType.Explosion, LogImpact.Medium,
|
||||||
_damageableSystem.TryChangeDamage(uid, damage, ignoreResistances: true, damageable: damageable);
|
$"Explosion caused [{damage.Total}] damage to {ToPrettyString(uid):target} at {xform?.Coordinates}");
|
||||||
if (HasComp<MindContainerComponent>(uid) || HasComp<ExplosiveComponent>(uid))
|
|
||||||
{
|
|
||||||
var damageStr = string.Join(", ", damage.DamageDict.Select(entry => $"{entry.Key}: {entry.Value}"));
|
|
||||||
_adminLogger.Add(LogType.Explosion, LogImpact.Medium,
|
|
||||||
$"Explosion caused [{damageStr}] to {ToPrettyString(uid):target} at {Transform(uid).Coordinates}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var appliedDamage = damage * ev.DamageCoefficient;
|
|
||||||
_damageableSystem.TryChangeDamage(uid, appliedDamage, ignoreResistances: true, damageable: damageable);
|
|
||||||
if (HasComp<MindContainerComponent>(uid) || HasComp<ExplosiveComponent>(uid))
|
|
||||||
{
|
|
||||||
var damageStr = string.Join(", ", appliedDamage.DamageDict.Select(entry => $"{entry.Key}: {entry.Value}"));
|
|
||||||
_adminLogger.Add(LogType.Explosion, LogImpact.Medium,
|
|
||||||
$"Explosion caused [{damageStr}] to {ToPrettyString(uid):target} at {Transform(uid).Coordinates}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_damageableSystem.TryChangeDamage(uid, damage, ignoreResistances: true, damageable: damageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// throw
|
// throw
|
||||||
@@ -425,16 +411,16 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
&& !xform.Anchored
|
&& !xform.Anchored
|
||||||
&& throwForce > 0
|
&& throwForce > 0
|
||||||
&& !EntityManager.IsQueuedForDeletion(uid)
|
&& !EntityManager.IsQueuedForDeletion(uid)
|
||||||
&& physicsQuery.TryGetComponent(uid, out var physics)
|
&& _physicsQuery.TryGetComponent(uid, out var physics)
|
||||||
&& physics.BodyType == BodyType.Dynamic)
|
&& physics.BodyType == BodyType.Dynamic)
|
||||||
{
|
{
|
||||||
var pos = _transformSystem.GetWorldPosition(xform, transformQuery);
|
var pos = _transformSystem.GetWorldPosition(xform);
|
||||||
_throwingSystem.TryThrow(
|
_throwingSystem.TryThrow(
|
||||||
uid,
|
uid,
|
||||||
pos - epicenter.Position,
|
pos - epicenter.Position,
|
||||||
physics,
|
physics,
|
||||||
xform,
|
xform,
|
||||||
projectileQuery,
|
_projectileQuery,
|
||||||
throwForce);
|
throwForce);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,6 +550,9 @@ sealed class Explosion
|
|||||||
|
|
||||||
// Variables used for enumerating over tiles, grids, etc
|
// Variables used for enumerating over tiles, grids, etc
|
||||||
private DamageSpecifier _currentDamage = default!;
|
private DamageSpecifier _currentDamage = default!;
|
||||||
|
#if DEBUG
|
||||||
|
private DamageSpecifier? _expectedDamage;
|
||||||
|
#endif
|
||||||
private BroadphaseComponent _currentLookup = default!;
|
private BroadphaseComponent _currentLookup = default!;
|
||||||
private MapGridComponent? _currentGrid;
|
private MapGridComponent? _currentGrid;
|
||||||
private float _currentIntensity;
|
private float _currentIntensity;
|
||||||
@@ -683,6 +672,16 @@ sealed class Explosion
|
|||||||
while (CurrentIteration < _tileSetIntensity.Count)
|
while (CurrentIteration < _tileSetIntensity.Count)
|
||||||
{
|
{
|
||||||
_currentIntensity = _tileSetIntensity[CurrentIteration];
|
_currentIntensity = _tileSetIntensity[CurrentIteration];
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
if (_expectedDamage != null)
|
||||||
|
{
|
||||||
|
// Check that explosion processing hasn't somehow accidentally mutated the damage set.
|
||||||
|
DebugTools.Assert(_expectedDamage.Equals(_currentDamage));
|
||||||
|
_expectedDamage = ExplosionType.DamagePerIntensity * _currentIntensity;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_currentDamage = ExplosionType.DamagePerIntensity * _currentIntensity;
|
_currentDamage = ExplosionType.DamagePerIntensity * _currentIntensity;
|
||||||
|
|
||||||
// only throw if either the explosion is small, or if this is the outer ring of a large explosion.
|
// only throw if either the explosion is small, or if this is the outer ring of a large explosion.
|
||||||
@@ -780,12 +779,7 @@ sealed class Explosion
|
|||||||
_currentDamage,
|
_currentDamage,
|
||||||
Epicenter,
|
Epicenter,
|
||||||
ProcessedEntities,
|
ProcessedEntities,
|
||||||
ExplosionType.ID,
|
ExplosionType.ID);
|
||||||
_xformQuery,
|
|
||||||
_damageQuery,
|
|
||||||
_physicsQuery,
|
|
||||||
_tagQuery,
|
|
||||||
_projectileQuery);
|
|
||||||
|
|
||||||
// If the floor is not blocked by some dense object, damage the floor tiles.
|
// If the floor is not blocked by some dense object, damage the floor tiles.
|
||||||
if (canDamageFloor)
|
if (canDamageFloor)
|
||||||
@@ -802,12 +796,7 @@ sealed class Explosion
|
|||||||
_currentDamage,
|
_currentDamage,
|
||||||
Epicenter,
|
Epicenter,
|
||||||
ProcessedEntities,
|
ProcessedEntities,
|
||||||
ExplosionType.ID,
|
ExplosionType.ID);
|
||||||
_xformQuery,
|
|
||||||
_damageQuery,
|
|
||||||
_physicsQuery,
|
|
||||||
_tagQuery,
|
|
||||||
_projectileQuery);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MoveNext())
|
if (!MoveNext())
|
||||||
|
|||||||
@@ -14,12 +14,15 @@ using Content.Shared.Database;
|
|||||||
using Content.Shared.Explosion;
|
using Content.Shared.Explosion;
|
||||||
using Content.Shared.GameTicking;
|
using Content.Shared.GameTicking;
|
||||||
using Content.Shared.Inventory;
|
using Content.Shared.Inventory;
|
||||||
|
using Content.Shared.Mind;
|
||||||
|
using Content.Shared.Projectiles;
|
||||||
using Content.Shared.Throwing;
|
using Content.Shared.Throwing;
|
||||||
using Robust.Server.GameStates;
|
using Robust.Server.GameStates;
|
||||||
using Robust.Server.Player;
|
using Robust.Server.Player;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Physics.Components;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
@@ -47,6 +50,12 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
[Dependency] private readonly PvsOverrideSystem _pvsSys = default!;
|
[Dependency] private readonly PvsOverrideSystem _pvsSys = default!;
|
||||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||||
|
|
||||||
|
private EntityQuery<TransformComponent> _transformQuery;
|
||||||
|
private EntityQuery<DamageableComponent> _damageQuery;
|
||||||
|
private EntityQuery<PhysicsComponent> _physicsQuery;
|
||||||
|
private EntityQuery<ProjectileComponent> _projectileQuery;
|
||||||
|
private EntityQuery<MindComponent> _mindQuery;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Tile-size" for space when there are no nearby grids to use as a reference.
|
/// "Tile-size" for space when there are no nearby grids to use as a reference.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -93,6 +102,12 @@ public sealed partial class ExplosionSystem : EntitySystem
|
|||||||
SubscribeCvars();
|
SubscribeCvars();
|
||||||
InitAirtightMap();
|
InitAirtightMap();
|
||||||
InitVisuals();
|
InitVisuals();
|
||||||
|
|
||||||
|
_transformQuery = GetEntityQuery<TransformComponent>();
|
||||||
|
_damageQuery = GetEntityQuery<DamageableComponent>();
|
||||||
|
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
||||||
|
_projectileQuery = GetEntityQuery<ProjectileComponent>();
|
||||||
|
_mindQuery = GetEntityQuery<MindComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnReset(RoundRestartCleanupEvent ev)
|
private void OnReset(RoundRestartCleanupEvent ev)
|
||||||
|
|||||||
Reference in New Issue
Block a user