Remove most IEntity usages from explosions (#5240)
* Remove most IEntity usages from Destructible and Explosions * Perform a minute amount of cleanup * Fix build
This commit is contained in:
committed by
GitHub
parent
3a4186f6f6
commit
42aaba9a5d
@@ -2,12 +2,12 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.AME.Components;
|
using Content.Server.AME.Components;
|
||||||
using Content.Server.Explosion;
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Server.NodeContainer.NodeGroups;
|
using Content.Server.NodeContainer.NodeGroups;
|
||||||
using Content.Server.NodeContainer.Nodes;
|
using Content.Server.NodeContainer.Nodes;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ namespace Content.Server.AME
|
|||||||
|
|
||||||
intensity = Math.Min(intensity, 8);
|
intensity = Math.Min(intensity, 8);
|
||||||
|
|
||||||
epicenter.Owner.SpawnExplosion(intensity / 2, intensity, intensity * 2, intensity * 3);
|
EntitySystem.Get<ExplosionSystem>().SpawnExplosion(epicenter.Owner.Uid, intensity / 2, intensity, intensity * 2, intensity * 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using Content.Server.Chemistry.EntitySystems;
|
|||||||
using Content.Server.Configurable;
|
using Content.Server.Configurable;
|
||||||
using Content.Server.Disposal.Tube.Components;
|
using Content.Server.Disposal.Tube.Components;
|
||||||
using Content.Server.EUI;
|
using Content.Server.EUI;
|
||||||
using Content.Server.Explosion;
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Server.Ghost.Roles;
|
using Content.Server.Ghost.Roles;
|
||||||
using Content.Server.Inventory.Components;
|
using Content.Server.Inventory.Components;
|
||||||
using Content.Server.Mind.Commands;
|
using Content.Server.Mind.Commands;
|
||||||
@@ -40,6 +40,7 @@ namespace Content.Server.Administration
|
|||||||
[Dependency] private readonly IAdminManager _adminManager = default!;
|
[Dependency] private readonly IAdminManager _adminManager = default!;
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
[Dependency] private readonly EuiManager _euiManager = default!;
|
[Dependency] private readonly EuiManager _euiManager = default!;
|
||||||
|
[Dependency] private readonly ExplosionSystem _explosions = default!;
|
||||||
[Dependency] private readonly GhostRoleSystem _ghostRoleSystem = default!;
|
[Dependency] private readonly GhostRoleSystem _ghostRoleSystem = default!;
|
||||||
|
|
||||||
private readonly Dictionary<IPlayerSession, EditSolutionsEui> _openSolutionUis = new();
|
private readonly Dictionary<IPlayerSession, EditSolutionsEui> _openSolutionUis = new();
|
||||||
@@ -118,7 +119,7 @@ namespace Content.Server.Administration
|
|||||||
verb.Act = () =>
|
verb.Act = () =>
|
||||||
{
|
{
|
||||||
var coords = args.Target.Transform.Coordinates;
|
var coords = args.Target.Transform.Coordinates;
|
||||||
Timer.Spawn(_gameTiming.TickPeriod, () => ExplosionHelper.SpawnExplosion(coords, 0, 1, 2, 1), CancellationToken.None);
|
Timer.Spawn(_gameTiming.TickPeriod, () => _explosions.SpawnExplosion(coords, 0, 1, 2, 1), CancellationToken.None);
|
||||||
if (args.Target.TryGetComponent(out SharedBodyComponent? body))
|
if (args.Target.TryGetComponent(out SharedBodyComponent? body))
|
||||||
{
|
{
|
||||||
body.Gib();
|
body.Gib();
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using Content.Server.Explosion;
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
using Robust.Server.Player;
|
using Robust.Server.Player;
|
||||||
using Robust.Shared.Console;
|
using Robust.Shared.Console;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
|
||||||
|
|
||||||
namespace Content.Server.Administration.Commands
|
namespace Content.Server.Administration.Commands
|
||||||
{
|
{
|
||||||
[AdminCommand(AdminFlags.Fun)]
|
[AdminCommand(AdminFlags.Fun)]
|
||||||
@@ -35,7 +35,7 @@ namespace Content.Server.Administration.Commands
|
|||||||
var mapTransform = player.AttachedEntity.Transform.GetMapTransform();
|
var mapTransform = player.AttachedEntity.Transform.GetMapTransform();
|
||||||
var coords = new EntityCoordinates(mapTransform.Owner.Uid, x, y);
|
var coords = new EntityCoordinates(mapTransform.Owner.Uid, x, y);
|
||||||
|
|
||||||
ExplosionHelper.SpawnExplosion(coords, dev, hvy, lgh, fla);
|
EntitySystem.Get<ExplosionSystem>().SpawnExplosion(coords, dev, hvy, lgh, fla);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Server.Atmos.EntitySystems;
|
using Content.Server.Atmos.EntitySystems;
|
||||||
using Content.Server.Body.Respiratory;
|
using Content.Server.Body.Respiratory;
|
||||||
using Content.Server.Explosion;
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Server.NodeContainer;
|
|
||||||
using Content.Server.NodeContainer.Nodes;
|
|
||||||
using Content.Server.UserInterface;
|
using Content.Server.UserInterface;
|
||||||
using Content.Shared.ActionBlocker;
|
using Content.Shared.ActionBlocker;
|
||||||
using Content.Shared.Actions;
|
using Content.Shared.Actions;
|
||||||
@@ -12,7 +10,6 @@ using Content.Shared.Actions.Components;
|
|||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
using Content.Shared.Atmos.Components;
|
using Content.Shared.Atmos.Components;
|
||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.DragDrop;
|
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Sound;
|
using Content.Shared.Sound;
|
||||||
@@ -271,7 +268,7 @@ namespace Content.Server.Atmos.Components
|
|||||||
range = MaxExplosionRange;
|
range = MaxExplosionRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
Owner.SpawnExplosion((int) (range * 0.25f), (int) (range * 0.5f), (int) (range * 1.5f), 1);
|
EntitySystem.Get<ExplosionSystem>().SpawnExplosion(OwnerUid, (int) (range * 0.25f), (int) (range * 0.5f), (int) (range * 1.5f), 1);
|
||||||
|
|
||||||
Owner.QueueDelete();
|
Owner.QueueDelete();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Server.Chemistry.Components;
|
|
||||||
using Content.Server.Chemistry.Components.SolutionManager;
|
using Content.Server.Chemistry.Components.SolutionManager;
|
||||||
using Content.Server.Explosion;
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Shared.Chemistry.Components;
|
using Content.Shared.Chemistry.Components;
|
||||||
using Content.Shared.Chemistry.Reaction;
|
using Content.Shared.Chemistry.Reaction;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -50,7 +49,7 @@ namespace Content.Server.Chemistry.ReactionEffects
|
|||||||
var finalHeavyImpactRange = (int)MathF.Round(_heavyImpactRange * floatIntensity);
|
var finalHeavyImpactRange = (int)MathF.Round(_heavyImpactRange * floatIntensity);
|
||||||
var finalLightImpactRange = (int)MathF.Round(_lightImpactRange * floatIntensity);
|
var finalLightImpactRange = (int)MathF.Round(_lightImpactRange * floatIntensity);
|
||||||
var finalFlashRange = (int)MathF.Round(_flashRange * floatIntensity);
|
var finalFlashRange = (int)MathF.Round(_flashRange * floatIntensity);
|
||||||
solutionEntity.SpawnExplosion(finalDevastationRange,
|
EntitySystem.Get<ExplosionSystem>().SpawnExplosion(solutionEntity, finalDevastationRange,
|
||||||
finalHeavyImpactRange, finalLightImpactRange, finalFlashRange);
|
finalHeavyImpactRange, finalLightImpactRange, finalFlashRange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
using Content.Server.Construction;
|
||||||
using Content.Server.Destructible.Thresholds;
|
using Content.Server.Destructible.Thresholds;
|
||||||
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Shared.Acts;
|
using Content.Shared.Acts;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
@@ -13,8 +15,12 @@ namespace Content.Server.Destructible
|
|||||||
public class DestructibleSystem : EntitySystem
|
public class DestructibleSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] public readonly IRobustRandom Random = default!;
|
[Dependency] public readonly IRobustRandom Random = default!;
|
||||||
[Dependency] public readonly AudioSystem AudioSystem = default!;
|
public new IEntityManager EntityManager => base.EntityManager;
|
||||||
|
|
||||||
[Dependency] public readonly ActSystem ActSystem = default!;
|
[Dependency] public readonly ActSystem ActSystem = default!;
|
||||||
|
[Dependency] public readonly AudioSystem AudioSystem = default!;
|
||||||
|
[Dependency] public readonly ConstructionSystem ConstructionSystem = default!;
|
||||||
|
[Dependency] public readonly ExplosionSystem ExplosionSystem = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Server.Construction;
|
|
||||||
using Content.Server.Construction.Components;
|
using Content.Server.Construction.Components;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
@@ -13,12 +12,12 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
[DataField("node")]
|
[DataField("node")]
|
||||||
public string Node { get; private set; } = string.Empty;
|
public string Node { get; private set; } = string.Empty;
|
||||||
|
|
||||||
public void Execute(EntityUid owner, DestructibleSystem system, IEntityManager entityManager)
|
public void Execute(EntityUid owner, DestructibleSystem system)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(Node) || !entityManager.TryGetComponent(owner, out ConstructionComponent? construction))
|
if (string.IsNullOrEmpty(Node) || !system.EntityManager.TryGetComponent(owner, out ConstructionComponent? construction))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EntitySystem.Get<ConstructionSystem>().ChangeNode(owner, null, Node, true, construction);
|
system.ConstructionSystem.ChangeNode(owner, null, Node, true, construction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
return (Acts & act) != 0;
|
return (Acts & act) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(EntityUid owner, DestructibleSystem system, IEntityManager entityManager)
|
public void Execute(EntityUid owner, DestructibleSystem system)
|
||||||
{
|
{
|
||||||
if (HasAct(ThresholdActs.Breakage))
|
if (HasAct(ThresholdActs.Breakage))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Server.Atmos.Piping.Unary.Components;
|
|
||||||
using Content.Server.Atmos.Piping.Unary.EntitySystems;
|
using Content.Server.Atmos.Piping.Unary.EntitySystems;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
@@ -10,11 +9,9 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
[DataDefinition]
|
[DataDefinition]
|
||||||
public class DumpCanisterBehavior : IThresholdBehavior
|
public class DumpCanisterBehavior : IThresholdBehavior
|
||||||
{
|
{
|
||||||
public void Execute(EntityUid owner, DestructibleSystem system, IEntityManager entityManager)
|
public void Execute(EntityUid owner, DestructibleSystem system)
|
||||||
{
|
{
|
||||||
var gasCanisterSystem = entityManager.EntitySysManager.GetEntitySystem<GasCanisterSystem>();
|
system.EntityManager.EntitySysManager.GetEntitySystem<GasCanisterSystem>().PurgeContents(owner);
|
||||||
|
|
||||||
gasCanisterSystem.PurgeContents(owner);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
[DataDefinition]
|
[DataDefinition]
|
||||||
public class EmptyAllContainersBehaviour : IThresholdBehavior
|
public class EmptyAllContainersBehaviour : IThresholdBehavior
|
||||||
{
|
{
|
||||||
public void Execute(EntityUid owner, DestructibleSystem system, IEntityManager entityManager)
|
public void Execute(EntityUid owner, DestructibleSystem system)
|
||||||
{
|
{
|
||||||
if (!entityManager.TryGetComponent<ContainerManagerComponent>(owner, out var containerManager))
|
if (!system.EntityManager.TryGetComponent<ContainerManagerComponent>(owner, out var containerManager))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var container in containerManager.GetAllContainers())
|
foreach (var container in containerManager.GetAllContainers())
|
||||||
{
|
{
|
||||||
container.EmptyContainer(true, entityManager.GetComponent<TransformComponent>(owner).Coordinates);
|
container.EmptyContainer(true, system.EntityManager.GetComponent<TransformComponent>(owner).Coordinates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Content.Server.Explosion;
|
|
||||||
using Content.Server.Explosion.Components;
|
using Content.Server.Explosion.Components;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -13,9 +12,9 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
[DataDefinition]
|
[DataDefinition]
|
||||||
public class ExplodeBehavior : IThresholdBehavior
|
public class ExplodeBehavior : IThresholdBehavior
|
||||||
{
|
{
|
||||||
public void Execute(EntityUid owner, DestructibleSystem system, IEntityManager entityManager)
|
public void Execute(EntityUid owner, DestructibleSystem system)
|
||||||
{
|
{
|
||||||
owner.SpawnExplosion(entityManager:entityManager);
|
system.ExplosionSystem.SpawnExplosion(owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
{
|
{
|
||||||
[DataField("recursive")] private bool _recursive = true;
|
[DataField("recursive")] private bool _recursive = true;
|
||||||
|
|
||||||
public void Execute(EntityUid owner, DestructibleSystem system, IEntityManager entityManager)
|
public void Execute(EntityUid owner, DestructibleSystem system)
|
||||||
{
|
{
|
||||||
if (entityManager.TryGetComponent(owner, out SharedBodyComponent? body))
|
if (system.EntityManager.TryGetComponent(owner, out SharedBodyComponent? body))
|
||||||
{
|
{
|
||||||
body.Gib(_recursive);
|
body.Gib(_recursive);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
/// An instance of <see cref="DestructibleSystem"/> to pull dependencies
|
/// An instance of <see cref="DestructibleSystem"/> to pull dependencies
|
||||||
/// and other systems from.
|
/// and other systems from.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="entityManager"></param>
|
void Execute(EntityUid owner, DestructibleSystem system);
|
||||||
void Execute(EntityUid owner, DestructibleSystem system, IEntityManager entityManager);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("sound", required: true)] public SoundSpecifier Sound { get; set; } = default!;
|
[DataField("sound", required: true)] public SoundSpecifier Sound { get; set; } = default!;
|
||||||
|
|
||||||
public void Execute(EntityUid owner, DestructibleSystem system, IEntityManager entityManager)
|
public void Execute(EntityUid owner, DestructibleSystem system)
|
||||||
{
|
{
|
||||||
var pos = entityManager.GetComponent<TransformComponent>(owner).Coordinates;
|
var pos = system.EntityManager.GetComponent<TransformComponent>(owner).Coordinates;
|
||||||
SoundSystem.Play(Filter.Pvs(pos), Sound.GetSound(), pos, AudioHelpers.WithVariation(0.125f));
|
SoundSystem.Play(Filter.Pvs(pos), Sound.GetSound(), pos, AudioHelpers.WithVariation(0.125f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using Content.Server.Stack;
|
using Content.Server.Stack;
|
||||||
using Content.Shared.Prototypes;
|
using Content.Shared.Prototypes;
|
||||||
using Content.Shared.Random.Helpers;
|
using Content.Shared.Random.Helpers;
|
||||||
using Content.Shared.Stacks;
|
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
|
|
||||||
@@ -19,9 +18,9 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
[DataField("spawn")]
|
[DataField("spawn")]
|
||||||
public Dictionary<string, MinMax> Spawn { get; set; } = new();
|
public Dictionary<string, MinMax> Spawn { get; set; } = new();
|
||||||
|
|
||||||
public void Execute(EntityUid owner, DestructibleSystem system, IEntityManager entityManager)
|
public void Execute(EntityUid owner, DestructibleSystem system)
|
||||||
{
|
{
|
||||||
var position = entityManager.GetComponent<TransformComponent>(owner).MapPosition;
|
var position = system.EntityManager.GetComponent<TransformComponent>(owner).MapPosition;
|
||||||
|
|
||||||
foreach (var (entityId, minMax) in Spawn)
|
foreach (var (entityId, minMax) in Spawn)
|
||||||
{
|
{
|
||||||
@@ -33,7 +32,7 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
|
|
||||||
if (EntityPrototypeHelpers.HasComponent<StackComponent>(entityId))
|
if (EntityPrototypeHelpers.HasComponent<StackComponent>(entityId))
|
||||||
{
|
{
|
||||||
var spawned = entityManager.SpawnEntity(entityId, position);
|
var spawned = system.EntityManager.SpawnEntity(entityId, position);
|
||||||
var stack = spawned.GetComponent<StackComponent>();
|
var stack = spawned.GetComponent<StackComponent>();
|
||||||
EntitySystem.Get<StackSystem>().SetCount(spawned.Uid, count, stack);
|
EntitySystem.Get<StackSystem>().SetCount(spawned.Uid, count, stack);
|
||||||
spawned.RandomOffset(0.5f);
|
spawned.RandomOffset(0.5f);
|
||||||
@@ -42,7 +41,7 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
{
|
{
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var spawned = entityManager.SpawnEntity(entityId, position);
|
var spawned = system.EntityManager.SpawnEntity(entityId, position);
|
||||||
spawned.RandomOffset(0.5f);
|
spawned.RandomOffset(0.5f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
/// <param name="owner">Entity on which behavior is executed</param>
|
/// <param name="owner">Entity on which behavior is executed</param>
|
||||||
/// <param name="system">system calling the behavior</param>
|
/// <param name="system">system calling the behavior</param>
|
||||||
/// <param name="entityManager"></param>
|
/// <param name="entityManager"></param>
|
||||||
public void Execute(EntityUid owner, DestructibleSystem system, IEntityManager entityManager)
|
public void Execute(EntityUid owner, DestructibleSystem system)
|
||||||
{
|
{
|
||||||
var solutionContainerSystem = EntitySystem.Get<SolutionContainerSystem>();
|
var solutionContainerSystem = EntitySystem.Get<SolutionContainerSystem>();
|
||||||
|
|
||||||
var coordinates = entityManager.GetComponent<TransformComponent>(owner).Coordinates;
|
var coordinates = system.EntityManager.GetComponent<TransformComponent>(owner).Coordinates;
|
||||||
|
|
||||||
if (entityManager.TryGetComponent(owner, out SpillableComponent? spillableComponent) &&
|
if (system.EntityManager.TryGetComponent(owner, out SpillableComponent? spillableComponent) &&
|
||||||
solutionContainerSystem.TryGetSolution(owner, spillableComponent.SolutionName,
|
solutionContainerSystem.TryGetSolution(owner, spillableComponent.SolutionName,
|
||||||
out var compSolution))
|
out var compSolution))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ namespace Content.Server.Destructible.Thresholds
|
|||||||
if (!entityManager.EntityExists(owner))
|
if (!entityManager.EntityExists(owner))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
behavior.Execute(owner, system, entityManager);
|
behavior.Execute(owner, system);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Server.Flash.Components;
|
using Content.Server.Flash.Components;
|
||||||
using Content.Server.Throwing;
|
using Content.Server.Throwing;
|
||||||
using Content.Shared.Explosion;
|
using Content.Shared.Explosion;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
namespace Content.Server.Explosion.Components
|
namespace Content.Server.Explosion.Components
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Content.Server.Explosion.Components
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var sourceLocation = eventArgs.Source;
|
var sourceLocation = eventArgs.Source;
|
||||||
var targetLocation = eventArgs.Target.Transform.Coordinates;
|
var targetLocation = Owner.EntityManager.GetComponent<TransformComponent>(eventArgs.Target).Coordinates;
|
||||||
|
|
||||||
if (sourceLocation.Equals(targetLocation)) return;
|
if (sourceLocation.Equals(targetLocation)) return;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Trigger;
|
using Content.Shared.Trigger;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Shared.Sound;
|
using Content.Shared.Sound;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Camera;
|
using Content.Server.Camera;
|
||||||
@@ -21,9 +21,9 @@ using Robust.Shared.Player;
|
|||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
namespace Content.Server.Explosion
|
namespace Content.Server.Explosion.EntitySystems
|
||||||
{
|
{
|
||||||
public static class ExplosionHelper
|
public class ExplosionSystem : EntitySystem
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Distance used for camera shake when distance from explosion is (0.0, 0.0).
|
/// Distance used for camera shake when distance from explosion is (0.0, 0.0).
|
||||||
@@ -34,19 +34,35 @@ namespace Content.Server.Explosion
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Chance of a tile breaking if the severity is Light and Heavy
|
/// Chance of a tile breaking if the severity is Light and Heavy
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static readonly float LightBreakChance = 0.3f;
|
private const float LightBreakChance = 0.3f;
|
||||||
private static readonly float HeavyBreakChance = 0.8f;
|
private const float HeavyBreakChance = 0.8f;
|
||||||
private static SoundSpecifier _explosionSound = new SoundCollectionSpecifier("explosion");
|
|
||||||
|
|
||||||
private static bool IgnoreExplosivePassable(IEntity e) => e.HasTag("ExplosivePassable");
|
// TODO move this to the component
|
||||||
|
private static readonly SoundSpecifier ExplosionSound = new SoundCollectionSpecifier("explosion");
|
||||||
|
|
||||||
private static ExplosionSeverity CalculateSeverity(float distance, float devastationRange, float heaveyRange)
|
[Dependency] private readonly IEntityLookup _entityLookup = default!;
|
||||||
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
|
[Dependency] private readonly IMapManager _maps = default!;
|
||||||
|
[Dependency] private readonly IPlayerManager _players = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
[Dependency] private readonly ITileDefinitionManager _tiles = default!;
|
||||||
|
|
||||||
|
[Dependency] private readonly ActSystem _acts = default!;
|
||||||
|
[Dependency] private readonly EffectSystem _effects = default!;
|
||||||
|
[Dependency] private readonly TriggerSystem _triggers = default!;
|
||||||
|
|
||||||
|
private bool IgnoreExplosivePassable(IEntity e)
|
||||||
|
{
|
||||||
|
return e.HasTag("ExplosivePassable");
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExplosionSeverity CalculateSeverity(float distance, float devastationRange, float heavyRange)
|
||||||
{
|
{
|
||||||
if (distance < devastationRange)
|
if (distance < devastationRange)
|
||||||
{
|
{
|
||||||
return ExplosionSeverity.Destruction;
|
return ExplosionSeverity.Destruction;
|
||||||
}
|
}
|
||||||
else if (distance < heaveyRange)
|
else if (distance < heavyRange)
|
||||||
{
|
{
|
||||||
return ExplosionSeverity.Heavy;
|
return ExplosionSeverity.Heavy;
|
||||||
}
|
}
|
||||||
@@ -56,174 +72,10 @@ namespace Content.Server.Explosion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private void CameraShakeInRange(EntityCoordinates epicenter, float maxRange)
|
||||||
/// Damage entities inside the range. The damage depends on a discrete
|
|
||||||
/// damage bracket [light, heavy, devastation] and the distance from the epicenter
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// A dictionary of coordinates relative to the parents of every grid of entities that survived the explosion,
|
|
||||||
/// have an airtight component and are currently blocking air. Like a wall.
|
|
||||||
/// </returns>
|
|
||||||
private static void DamageEntitiesInRange(EntityCoordinates epicenter, Box2 boundingBox,
|
|
||||||
float devastationRange,
|
|
||||||
float heaveyRange,
|
|
||||||
float maxRange,
|
|
||||||
MapId mapId)
|
|
||||||
{
|
{
|
||||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
var players = _players.GetPlayersInRange(epicenter, (int) Math.Ceiling(maxRange));
|
||||||
|
|
||||||
var exAct = EntitySystem.Get<ActSystem>();
|
|
||||||
|
|
||||||
var entitiesInRange = IoCManager.Resolve<IEntityLookup>().GetEntitiesInRange(mapId, boundingBox, 0).ToList();
|
|
||||||
|
|
||||||
var impassableEntities = new List<Tuple<IEntity, float>>();
|
|
||||||
var nonImpassableEntities = new List<Tuple<IEntity, float>>();
|
|
||||||
// TODO: Given this seems to rely on physics it should just query directly like everything else.
|
|
||||||
|
|
||||||
// The entities are paired with their distance to the epicenter
|
|
||||||
// and splitted into two lists based on if they are Impassable or not
|
|
||||||
foreach (var entity in entitiesInRange)
|
|
||||||
{
|
|
||||||
if (entity.Deleted || entity.IsInContainer())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!entity.Transform.Coordinates.TryDistance(entityManager, epicenter, out var distance) || distance > maxRange)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!entity.TryGetComponent(out PhysicsComponent? body) || body.Fixtures.Count < 1)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((body.CollisionLayer & (int) CollisionGroup.Impassable) != 0)
|
|
||||||
{
|
|
||||||
impassableEntities.Add(Tuple.Create(entity, distance));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nonImpassableEntities.Add(Tuple.Create(entity, distance));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Impassable entities are sorted in descending order
|
|
||||||
// Entities closer to the epicenter are first
|
|
||||||
impassableEntities.Sort((x, y) => x.Item2.CompareTo(y.Item2));
|
|
||||||
|
|
||||||
// Impassable entities are handled first. If they are damaged enough, they are destroyed and they may
|
|
||||||
// be able to spawn a new entity. I.e Wall -> Girder.
|
|
||||||
// Girder has a tag ExplosivePassable, and the predicate make it so the entities with this tag are ignored
|
|
||||||
var epicenterMapPos = epicenter.ToMap(entityManager);
|
|
||||||
foreach (var (entity, distance) in impassableEntities)
|
|
||||||
{
|
|
||||||
if (!entity.InRangeUnobstructed(epicenterMapPos, maxRange, ignoreInsideBlocker: true, predicate: IgnoreExplosivePassable))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
exAct.HandleExplosion(epicenter, entity, CalculateSeverity(distance, devastationRange, heaveyRange));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Impassable entities were handled first so NonImpassable entities have a bigger chance to get hit. As now
|
|
||||||
// there are probably more ExplosivePassable entities around
|
|
||||||
foreach (var (entity, distance) in nonImpassableEntities)
|
|
||||||
{
|
|
||||||
if (!entity.InRangeUnobstructed(epicenterMapPos, maxRange, ignoreInsideBlocker: true, predicate: IgnoreExplosivePassable))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
exAct.HandleExplosion(epicenter, entity, CalculateSeverity(distance, devastationRange, heaveyRange));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Damage tiles inside the range. The type of tile can change depending on a discrete
|
|
||||||
/// damage bracket [light, heavy, devastation], the distance from the epicenter and
|
|
||||||
/// a probabilty bracket [<see cref="LightBreakChance"/>, <see cref="HeavyBreakChance"/>, 1.0].
|
|
||||||
/// </summary>
|
|
||||||
///
|
|
||||||
private static void DamageTilesInRange(EntityCoordinates epicenter,
|
|
||||||
GridId gridId,
|
|
||||||
Box2 boundingBox,
|
|
||||||
float devastationRange,
|
|
||||||
float heaveyRange,
|
|
||||||
float maxRange)
|
|
||||||
{
|
|
||||||
var mapManager = IoCManager.Resolve<IMapManager>();
|
|
||||||
if (!mapManager.TryGetGrid(gridId, out var mapGrid))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
|
||||||
if (!entityManager.TryGetEntity(mapGrid.GridEntityId, out var grid))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var robustRandom = IoCManager.Resolve<IRobustRandom>();
|
|
||||||
var tileDefinitionManager = IoCManager.Resolve<ITileDefinitionManager>();
|
|
||||||
|
|
||||||
var tilesInGridAndCircle = mapGrid.GetTilesIntersecting(boundingBox);
|
|
||||||
|
|
||||||
var epicenterMapPos = epicenter.ToMap(entityManager);
|
|
||||||
foreach (var tile in tilesInGridAndCircle)
|
|
||||||
{
|
|
||||||
var tileLoc = mapGrid.GridTileToLocal(tile.GridIndices);
|
|
||||||
if (!tileLoc.TryDistance(entityManager, epicenter, out var distance) || distance > maxRange)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tile.IsBlockedTurf(false))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tileLoc.ToMap(entityManager).InRangeUnobstructed(epicenterMapPos, maxRange, ignoreInsideBlocker: false, predicate: IgnoreExplosivePassable))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tileDef = (ContentTileDefinition) tileDefinitionManager[tile.Tile.TypeId];
|
|
||||||
var baseTurfs = tileDef.BaseTurfs;
|
|
||||||
if (baseTurfs.Count == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var zeroTile = new Robust.Shared.Map.Tile(tileDefinitionManager[baseTurfs[0]].TileId);
|
|
||||||
var previousTile = new Robust.Shared.Map.Tile(tileDefinitionManager[baseTurfs[^1]].TileId);
|
|
||||||
|
|
||||||
var severity = CalculateSeverity(distance, devastationRange, heaveyRange);
|
|
||||||
|
|
||||||
switch (severity)
|
|
||||||
{
|
|
||||||
case ExplosionSeverity.Light:
|
|
||||||
if (!previousTile.IsEmpty && robustRandom.Prob(LightBreakChance))
|
|
||||||
{
|
|
||||||
mapGrid.SetTile(tileLoc, previousTile);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ExplosionSeverity.Heavy:
|
|
||||||
if (!previousTile.IsEmpty && robustRandom.Prob(HeavyBreakChance))
|
|
||||||
{
|
|
||||||
mapGrid.SetTile(tileLoc, previousTile);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ExplosionSeverity.Destruction:
|
|
||||||
mapGrid.SetTile(tileLoc, zeroTile);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CameraShakeInRange(EntityCoordinates epicenter, float maxRange)
|
|
||||||
{
|
|
||||||
var playerManager = IoCManager.Resolve<IPlayerManager>();
|
|
||||||
var players = playerManager.GetPlayersInRange(epicenter, (int) Math.Ceiling(maxRange));
|
|
||||||
foreach (var player in players)
|
foreach (var player in players)
|
||||||
{
|
{
|
||||||
if (player.AttachedEntity == null || !player.AttachedEntity.TryGetComponent(out CameraRecoilComponent? recoil))
|
if (player.AttachedEntity == null || !player.AttachedEntity.TryGetComponent(out CameraRecoilComponent? recoil))
|
||||||
@@ -231,10 +83,8 @@ namespace Content.Server.Explosion
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
|
||||||
|
|
||||||
var playerPos = player.AttachedEntity.Transform.WorldPosition;
|
var playerPos = player.AttachedEntity.Transform.WorldPosition;
|
||||||
var delta = epicenter.ToMapPos(entityManager) - playerPos;
|
var delta = epicenter.ToMapPos(EntityManager) - playerPos;
|
||||||
|
|
||||||
//Change if zero. Will result in a NaN later breaking camera shake if not changed
|
//Change if zero. Will result in a NaN later breaking camera shake if not changed
|
||||||
if (delta.EqualsApprox((0.0f, 0.0f)))
|
if (delta.EqualsApprox((0.0f, 0.0f)))
|
||||||
@@ -250,83 +100,250 @@ namespace Content.Server.Explosion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void FlashInRange(EntityCoordinates epicenter, float flashrange)
|
/// <summary>
|
||||||
|
/// Damage entities inside the range. The damage depends on a discrete
|
||||||
|
/// damage bracket [light, heavy, devastation] and the distance from the epicenter
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// A dictionary of coordinates relative to the parents of every grid of entities that survived the explosion,
|
||||||
|
/// have an airtight component and are currently blocking air. Like a wall.
|
||||||
|
/// </returns>
|
||||||
|
private void DamageEntitiesInRange(
|
||||||
|
EntityCoordinates epicenter,
|
||||||
|
Box2 boundingBox,
|
||||||
|
float devastationRange,
|
||||||
|
float heavyRange,
|
||||||
|
float maxRange,
|
||||||
|
MapId mapId)
|
||||||
{
|
{
|
||||||
if (flashrange > 0)
|
var entitiesInRange = _entityLookup.GetEntitiesInRange(mapId, boundingBox, 0).ToList();
|
||||||
|
|
||||||
|
var impassableEntities = new List<(IEntity, float)>();
|
||||||
|
var nonImpassableEntities = new List<(IEntity, float)>();
|
||||||
|
// TODO: Given this seems to rely on physics it should just query directly like everything else.
|
||||||
|
|
||||||
|
// The entities are paired with their distance to the epicenter
|
||||||
|
// and splitted into two lists based on if they are Impassable or not
|
||||||
|
foreach (var entity in entitiesInRange)
|
||||||
{
|
{
|
||||||
var entitySystemManager = IoCManager.Resolve<IEntitySystemManager>();
|
if (entity.Deleted || entity.IsInContainer())
|
||||||
var time = IoCManager.Resolve<IGameTiming>().CurTime;
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!entity.Transform.Coordinates.TryDistance(EntityManager, epicenter, out var distance) ||
|
||||||
|
distance > maxRange)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!entity.TryGetComponent(out PhysicsComponent? body) || body.Fixtures.Count < 1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((body.CollisionLayer & (int) CollisionGroup.Impassable) != 0)
|
||||||
|
{
|
||||||
|
impassableEntities.Add((entity, distance));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nonImpassableEntities.Add((entity, distance));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Impassable entities are sorted in descending order
|
||||||
|
// Entities closer to the epicenter are first
|
||||||
|
impassableEntities.Sort((x, y) => x.Item2.CompareTo(y.Item2));
|
||||||
|
|
||||||
|
// Impassable entities are handled first. If they are damaged enough, they are destroyed and they may
|
||||||
|
// be able to spawn a new entity. I.e Wall -> Girder.
|
||||||
|
// Girder has a tag ExplosivePassable, and the predicate make it so the entities with this tag are ignored
|
||||||
|
var epicenterMapPos = epicenter.ToMap(EntityManager);
|
||||||
|
foreach (var (entity, distance) in impassableEntities)
|
||||||
|
{
|
||||||
|
if (!entity.InRangeUnobstructed(epicenterMapPos, maxRange, ignoreInsideBlocker: true, predicate: IgnoreExplosivePassable))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_acts.HandleExplosion(epicenter, entity.Uid, CalculateSeverity(distance, devastationRange, heavyRange));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Impassable entities were handled first so NonImpassable entities have a bigger chance to get hit. As now
|
||||||
|
// there are probably more ExplosivePassable entities around
|
||||||
|
foreach (var (entity, distance) in nonImpassableEntities)
|
||||||
|
{
|
||||||
|
if (!entity.InRangeUnobstructed(epicenterMapPos, maxRange, ignoreInsideBlocker: true, predicate: IgnoreExplosivePassable))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_acts.HandleExplosion(epicenter, entity.Uid, CalculateSeverity(distance, devastationRange, heavyRange));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Damage tiles inside the range. The type of tile can change depending on a discrete
|
||||||
|
/// damage bracket [light, heavy, devastation], the distance from the epicenter and
|
||||||
|
/// a probability bracket [<see cref="LightBreakChance"/>, <see cref="HeavyBreakChance"/>, 1.0].
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
private void DamageTilesInRange(EntityCoordinates epicenter,
|
||||||
|
GridId gridId,
|
||||||
|
Box2 boundingBox,
|
||||||
|
float devastationRange,
|
||||||
|
float heaveyRange,
|
||||||
|
float maxRange)
|
||||||
|
{
|
||||||
|
if (!_maps.TryGetGrid(gridId, out var mapGrid))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EntityManager.EntityExists(mapGrid.GridEntityId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tilesInGridAndCircle = mapGrid.GetTilesIntersecting(boundingBox);
|
||||||
|
var epicenterMapPos = epicenter.ToMap(EntityManager);
|
||||||
|
|
||||||
|
foreach (var tile in tilesInGridAndCircle)
|
||||||
|
{
|
||||||
|
var tileLoc = mapGrid.GridTileToLocal(tile.GridIndices);
|
||||||
|
if (!tileLoc.TryDistance(EntityManager, epicenter, out var distance) ||
|
||||||
|
distance > maxRange)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tile.IsBlockedTurf(false))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tileLoc.ToMap(EntityManager).InRangeUnobstructed(epicenterMapPos, maxRange, ignoreInsideBlocker: false, predicate: IgnoreExplosivePassable))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tileDef = (ContentTileDefinition) _tiles[tile.Tile.TypeId];
|
||||||
|
var baseTurfs = tileDef.BaseTurfs;
|
||||||
|
if (baseTurfs.Count == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var zeroTile = new Tile(_tiles[baseTurfs[0]].TileId);
|
||||||
|
var previousTile = new Tile(_tiles[baseTurfs[^1]].TileId);
|
||||||
|
|
||||||
|
var severity = CalculateSeverity(distance, devastationRange, heaveyRange);
|
||||||
|
|
||||||
|
switch (severity)
|
||||||
|
{
|
||||||
|
case ExplosionSeverity.Light:
|
||||||
|
if (!previousTile.IsEmpty && _random.Prob(LightBreakChance))
|
||||||
|
{
|
||||||
|
mapGrid.SetTile(tileLoc, previousTile);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ExplosionSeverity.Heavy:
|
||||||
|
if (!previousTile.IsEmpty && _random.Prob(HeavyBreakChance))
|
||||||
|
{
|
||||||
|
mapGrid.SetTile(tileLoc, previousTile);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ExplosionSeverity.Destruction:
|
||||||
|
mapGrid.SetTile(tileLoc, zeroTile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FlashInRange(EntityCoordinates epicenter, float flashRange)
|
||||||
|
{
|
||||||
|
if (flashRange > 0)
|
||||||
|
{
|
||||||
|
var time = _timing.CurTime;
|
||||||
var message = new EffectSystemMessage
|
var message = new EffectSystemMessage
|
||||||
{
|
{
|
||||||
EffectSprite = "Effects/explosion.rsi",
|
EffectSprite = "Effects/explosion.rsi",
|
||||||
RsiState = "explosionfast",
|
RsiState = "explosionfast",
|
||||||
Born = time,
|
Born = time,
|
||||||
DeathTime = time + TimeSpan.FromSeconds(5),
|
DeathTime = time + TimeSpan.FromSeconds(5),
|
||||||
Size = new Vector2(flashrange / 2, flashrange / 2),
|
Size = new Vector2(flashRange / 2, flashRange / 2),
|
||||||
Coordinates = epicenter,
|
Coordinates = epicenter,
|
||||||
Rotation = 0f,
|
Rotation = 0f,
|
||||||
ColorDelta = new Vector4(0, 0, 0, -1500f),
|
ColorDelta = new Vector4(0, 0, 0, -1500f),
|
||||||
Color = Vector4.Multiply(new Vector4(255, 255, 255, 750), 0.5f),
|
Color = Vector4.Multiply(new Vector4(255, 255, 255, 750), 0.5f),
|
||||||
Shaded = false
|
Shaded = false
|
||||||
};
|
};
|
||||||
entitySystemManager.GetEntitySystem<EffectSystem>().CreateParticle(message);
|
|
||||||
|
_effects.CreateParticle(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove this shit
|
public void SpawnExplosion(
|
||||||
public static void SpawnExplosion(this EntityUid uid, int devastationRange = 0, int heavyImpactRange = 0,
|
EntityUid entity,
|
||||||
int lightImpactRange = 0, int flashRange = 0, IEntityManager? entityManager = null)
|
int devastationRange = 0,
|
||||||
|
int heavyImpactRange = 0,
|
||||||
|
int lightImpactRange = 0,
|
||||||
|
int flashRange = 0,
|
||||||
|
ExplosiveComponent? explosive = null,
|
||||||
|
TransformComponent? transform = null)
|
||||||
{
|
{
|
||||||
entityManager ??= IoCManager.Resolve<IEntityManager>();
|
if (!Resolve(entity, ref transform))
|
||||||
|
{
|
||||||
SpawnExplosion(entityManager.GetEntity(uid), devastationRange, heavyImpactRange, lightImpactRange, flashRange);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SpawnExplosion(this IEntity entity, int devastationRange = 0, int heavyImpactRange = 0,
|
Resolve(entity, ref explosive, false);
|
||||||
int lightImpactRange = 0, int flashRange = 0)
|
|
||||||
{
|
|
||||||
// TODO: Need to refactor this stufferino
|
|
||||||
|
|
||||||
// If you want to directly set off the explosive
|
if (explosive is { Exploding: false })
|
||||||
if (!entity.Deleted && entity.TryGetComponent(out ExplosiveComponent? explosive) && !explosive.Exploding)
|
|
||||||
{
|
{
|
||||||
EntitySystem.Get<TriggerSystem>().Explode(entity.Uid, explosive);
|
_triggers.Explode(entity, explosive);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (entity.TryGetContainer(out var cont))
|
while (EntityManager.TryGetComponent(entity, out ContainerManagerComponent? container))
|
||||||
{
|
{
|
||||||
entity = cont.Owner;
|
entity = container.OwnerUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
var epicenter = entity.Transform.Coordinates;
|
if (!EntityManager.TryGetComponent(entity, out transform))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var epicenter = transform.Coordinates;
|
||||||
|
|
||||||
SpawnExplosion(epicenter, devastationRange, heavyImpactRange, lightImpactRange, flashRange);
|
SpawnExplosion(epicenter, devastationRange, heavyImpactRange, lightImpactRange, flashRange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SpawnExplosion(EntityCoordinates epicenter, int devastationRange = 0,
|
public void SpawnExplosion(
|
||||||
int heavyImpactRange = 0, int lightImpactRange = 0, int flashRange = 0)
|
EntityCoordinates epicenter,
|
||||||
|
int devastationRange = 0,
|
||||||
|
int heavyImpactRange = 0,
|
||||||
|
int lightImpactRange = 0,
|
||||||
|
int flashRange = 0)
|
||||||
{
|
{
|
||||||
var mapId = epicenter.GetMapId(IoCManager.Resolve<IEntityManager>());
|
var mapId = epicenter.GetMapId(EntityManager);
|
||||||
if (mapId == MapId.Nullspace)
|
if (mapId == MapId.Nullspace)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var maxRange = MathHelper.Max(devastationRange, heavyImpactRange, lightImpactRange, 0);
|
var maxRange = MathHelper.Max(devastationRange, heavyImpactRange, lightImpactRange, 0);
|
||||||
|
var epicenterMapPos = epicenter.ToMapPos(EntityManager);
|
||||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
|
||||||
var mapManager = IoCManager.Resolve<IMapManager>();
|
|
||||||
|
|
||||||
var epicenterMapPos = epicenter.ToMapPos(entityManager);
|
|
||||||
var boundingBox = new Box2(epicenterMapPos - new Vector2(maxRange, maxRange),
|
var boundingBox = new Box2(epicenterMapPos - new Vector2(maxRange, maxRange),
|
||||||
epicenterMapPos + new Vector2(maxRange, maxRange));
|
epicenterMapPos + new Vector2(maxRange, maxRange));
|
||||||
|
|
||||||
SoundSystem.Play(Filter.Broadcast(), _explosionSound.GetSound(), epicenter);
|
SoundSystem.Play(Filter.Broadcast(), ExplosionSound.GetSound(), epicenter);
|
||||||
DamageEntitiesInRange(epicenter, boundingBox, devastationRange, heavyImpactRange, maxRange, mapId);
|
DamageEntitiesInRange(epicenter, boundingBox, devastationRange, heavyImpactRange, maxRange, mapId);
|
||||||
|
|
||||||
var mapGridsNear = mapManager.FindGridsIntersecting(mapId, boundingBox);
|
var mapGridsNear = _maps.FindGridsIntersecting(mapId, boundingBox);
|
||||||
|
|
||||||
foreach (var gridId in mapGridsNear)
|
foreach (var gridId in mapGridsNear)
|
||||||
{
|
{
|
||||||
@@ -3,7 +3,6 @@ using Content.Server.Doors.Components;
|
|||||||
using Content.Server.Explosion.Components;
|
using Content.Server.Explosion.Components;
|
||||||
using Content.Server.Flash;
|
using Content.Server.Flash;
|
||||||
using Content.Server.Flash.Components;
|
using Content.Server.Flash.Components;
|
||||||
using Content.Shared.Acts;
|
|
||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.Doors;
|
using Content.Shared.Doors;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
@@ -14,7 +13,7 @@ using Robust.Shared.Physics.Dynamics;
|
|||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
namespace Content.Server.Explosion
|
namespace Content.Server.Explosion.EntitySystems
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised whenever something is Triggered on the entity.
|
/// Raised whenever something is Triggered on the entity.
|
||||||
@@ -34,6 +33,7 @@ namespace Content.Server.Explosion
|
|||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public sealed class TriggerSystem : EntitySystem
|
public sealed class TriggerSystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly ExplosionSystem _explosions = default!;
|
||||||
[Dependency] private readonly FlashSystem _flashSystem = default!;
|
[Dependency] private readonly FlashSystem _flashSystem = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
@@ -65,7 +65,7 @@ namespace Content.Server.Explosion
|
|||||||
}
|
}
|
||||||
|
|
||||||
component.Exploding = true;
|
component.Exploding = true;
|
||||||
component.Owner.SpawnExplosion(component.DevastationRange, component.HeavyImpactRange, component.LightImpactRange, component.FlashRange);
|
_explosions.SpawnExplosion(uid, component.DevastationRange, component.HeavyImpactRange, component.LightImpactRange, component.FlashRange);
|
||||||
EntityManager.QueueDeleteEntity(uid);
|
EntityManager.QueueDeleteEntity(uid);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using Content.Server.Explosion;
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Server.MachineLinking.Components;
|
using Content.Server.MachineLinking.Components;
|
||||||
using Content.Server.MachineLinking.Events;
|
using Content.Server.MachineLinking.Events;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Explosion;
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Server.Pointing.Components;
|
using Content.Server.Pointing.Components;
|
||||||
using Content.Shared.MobState.Components;
|
using Content.Shared.MobState.Components;
|
||||||
using Content.Shared.Pointing.Components;
|
using Content.Shared.Pointing.Components;
|
||||||
@@ -22,6 +22,8 @@ namespace Content.Server.Pointing.EntitySystems
|
|||||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
|
||||||
|
[Dependency] private readonly ExplosionSystem _explosions = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
@@ -106,7 +108,7 @@ namespace Content.Server.Pointing.EntitySystems
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
component.Owner.SpawnExplosion(0, 2, 1, 1);
|
_explosions.SpawnExplosion(uid, 0, 2, 1, 1);
|
||||||
SoundSystem.Play(Filter.Pvs(uid, entityManager: EntityManager), component.ExplosionSound.GetSound(), uid);
|
SoundSystem.Play(Filter.Pvs(uid, entityManager: EntityManager), component.ExplosionSound.GetSound(), uid);
|
||||||
|
|
||||||
EntityManager.QueueDeleteEntity(uid);
|
EntityManager.QueueDeleteEntity(uid);
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Server.Chemistry.Components;
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Server.Explosion;
|
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Shared.Chemistry;
|
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.PowerCell;
|
using Content.Shared.PowerCell;
|
||||||
using Content.Shared.Rounding;
|
using Content.Shared.Rounding;
|
||||||
@@ -75,7 +73,7 @@ namespace Content.Server.PowerCell.Components
|
|||||||
var light = (int) Math.Ceiling(Math.Sqrt(CurrentCharge) / 30);
|
var light = (int) Math.Ceiling(Math.Sqrt(CurrentCharge) / 30);
|
||||||
|
|
||||||
CurrentCharge = 0;
|
CurrentCharge = 0;
|
||||||
Owner.SpawnExplosion(0, heavy, light, light*2);
|
EntitySystem.Get<ExplosionSystem>().SpawnExplosion(OwnerUid, 0, heavy, light, light*2);
|
||||||
Owner.Delete();
|
Owner.Delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace Content.Shared.Acts
|
|||||||
public class ExplosionEventArgs : EventArgs
|
public class ExplosionEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public EntityCoordinates Source { get; set; }
|
public EntityCoordinates Source { get; set; }
|
||||||
public IEntity Target { get; set; } = default!;
|
public EntityUid Target { get; set; }
|
||||||
public ExplosionSeverity Severity { get; set; }
|
public ExplosionSeverity Severity { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ namespace Content.Shared.Acts
|
|||||||
EntityManager.QueueDeleteEntity(owner);
|
EntityManager.QueueDeleteEntity(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleExplosion(EntityCoordinates source, IEntity target, ExplosionSeverity severity)
|
public void HandleExplosion(EntityCoordinates source, EntityUid target, ExplosionSeverity severity)
|
||||||
{
|
{
|
||||||
var eventArgs = new ExplosionEventArgs
|
var eventArgs = new ExplosionEventArgs
|
||||||
{
|
{
|
||||||
@@ -78,7 +78,7 @@ namespace Content.Shared.Acts
|
|||||||
Target = target,
|
Target = target,
|
||||||
Severity = severity
|
Severity = severity
|
||||||
};
|
};
|
||||||
var exActs = target.GetAllComponents<IExAct>().ToList();
|
var exActs = EntityManager.GetComponents<IExAct>(target).ToList();
|
||||||
|
|
||||||
foreach (var exAct in exActs)
|
foreach (var exAct in exActs)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user