diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs
index fc31a77041..b459f5c70f 100644
--- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs
+++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs
@@ -63,16 +63,6 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem
public const int MaxExplosionAudioRange = 30;
- ///
- /// The "default" explosion prototype.
- ///
- ///
- /// Generally components should specify an explosion prototype via a yaml datafield, so that the yaml-linter can
- /// find errors. However some components, like rogue arrows, or some commands like the admin-smite need to have
- /// a "default" option specified outside of yaml data-fields. Hence this const string.
- ///
- public static readonly ProtoId DefaultExplosionPrototypeId = "Default";
-
public override void Initialize()
{
base.Initialize();
@@ -222,10 +212,8 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem
return r0 * (MathF.Sqrt(12 * totalIntensity / v0 - 3) / 6 + 0.5f);
}
- ///
- /// Queue an explosions, centered on some entity.
- ///
- public void QueueExplosion(EntityUid uid,
+ ///
+ public override void QueueExplosion(EntityUid uid,
string typeId,
float totalIntensity,
float slope,
diff --git a/Content.Shared/Explosion/EntitySystems/SharedExplosionSystem.cs b/Content.Shared/Explosion/EntitySystems/SharedExplosionSystem.cs
index f298255807..d6053c9c3c 100644
--- a/Content.Shared/Explosion/EntitySystems/SharedExplosionSystem.cs
+++ b/Content.Shared/Explosion/EntitySystems/SharedExplosionSystem.cs
@@ -1,14 +1,26 @@
using Content.Shared.Armor;
using Content.Shared.Explosion.Components;
+using Robust.Shared.Prototypes;
namespace Content.Shared.Explosion.EntitySystems;
+// TODO some sort of struct like DamageSpecifier but for explosions.
///
/// Lets code in shared trigger explosions and handles explosion resistance examining.
/// All processing is still done clientside.
///
public abstract class SharedExplosionSystem : EntitySystem
{
+ ///
+ /// The "default" explosion prototype.
+ ///
+ ///
+ /// Generally components should specify an explosion prototype via a yaml datafield, so that the yaml-linter can
+ /// find errors. However some components, like rogue arrows, or some commands like the admin-smite need to have
+ /// a "default" option specified outside of yaml data-fields. Hence this const string.
+ ///
+ public static readonly ProtoId DefaultExplosionPrototypeId = "Default";
+
public override void Initialize()
{
base.Initialize();
@@ -37,4 +49,24 @@ public abstract class SharedExplosionSystem : EntitySystem
public virtual void TriggerExplosive(EntityUid uid, ExplosiveComponent? explosive = null, bool delete = true, float? totalIntensity = null, float? radius = null, EntityUid? user = null)
{
}
+
+ ///
+ /// Queue an explosion centered on some entity. Bypasses needing .
+ ///
+ /// Where the explosion happens.
+ /// A ProtoId of type .
+ /// The entity which caused the explosion.
+ /// Whether to add an admin log about this explosion. Includes user.
+ public virtual void QueueExplosion(EntityUid uid,
+ string typeId,
+ float totalIntensity,
+ float slope,
+ float maxTileIntensity,
+ float tileBreakScale = 1f,
+ int maxTileBreak = int.MaxValue,
+ bool canCreateVacuum = true,
+ EntityUid? user = null,
+ bool addLog = true)
+ {
+ }
}
diff --git a/Content.Shared/Trigger/Components/Effects/ExplodeOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/ExplodeOnTriggerComponent.cs
index 2a1af40a2c..9bb7ce9fa0 100644
--- a/Content.Shared/Trigger/Components/Effects/ExplodeOnTriggerComponent.cs
+++ b/Content.Shared/Trigger/Components/Effects/ExplodeOnTriggerComponent.cs
@@ -1,3 +1,4 @@
+using Content.Shared.Explosion.Components;
using Robust.Shared.GameStates;
namespace Content.Shared.Trigger.Components.Effects;
@@ -7,8 +8,6 @@ namespace Content.Shared.Trigger.Components.Effects;
/// TargetUser will only work of the user has ExplosiveComponent as well.
/// The User will be logged in the admin logs.
///
-///
-/// TODO: Allow this to work without an ExplosiveComponent on the user via QueueExplosion.
-///
+///
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ExplodeOnTriggerComponent : BaseXOnTriggerComponent;
diff --git a/Content.Shared/Trigger/Components/Effects/ExplosionOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/ExplosionOnTriggerComponent.cs
new file mode 100644
index 0000000000..40b59e7a97
--- /dev/null
+++ b/Content.Shared/Trigger/Components/Effects/ExplosionOnTriggerComponent.cs
@@ -0,0 +1,46 @@
+using Content.Shared.Explosion;
+using Content.Shared.Explosion.Components;
+using Content.Shared.Explosion.EntitySystems;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.Trigger.Components.Effects;
+
+// TODO some sort of struct like DamageSpecifier but for explosions.
+///
+/// Will explode the entity using this component's explosion specifications.
+/// If TargetUser is true, they'll explode instead.
+/// The User will be logged in the admin logs.
+///
+///
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class ExplosionOnTriggerComponent : BaseXOnTriggerComponent
+{
+ ///
+ [DataField, AutoNetworkedField]
+ public ProtoId ExplosionType = SharedExplosionSystem.DefaultExplosionPrototypeId;
+
+ ///
+ [DataField, AutoNetworkedField]
+ public float MaxTileIntensity = 4;
+
+ ///
+ [DataField, AutoNetworkedField]
+ public float IntensitySlope = 1;
+
+ ///
+ [DataField, AutoNetworkedField]
+ public float TotalIntensity = 10;
+
+ ///
+ [DataField, AutoNetworkedField]
+ public float TileBreakScale = 1f;
+
+ ///
+ [DataField, AutoNetworkedField]
+ public int MaxTileBreak = int.MaxValue;
+
+ ///
+ [DataField, AutoNetworkedField]
+ public bool CanCreateVacuum = true;
+}
diff --git a/Content.Shared/Trigger/Components/Triggers/TriggerOnPlayerSpawnCompleteComponent.cs b/Content.Shared/Trigger/Components/Triggers/TriggerOnPlayerSpawnCompleteComponent.cs
new file mode 100644
index 0000000000..2151b7edcc
--- /dev/null
+++ b/Content.Shared/Trigger/Components/Triggers/TriggerOnPlayerSpawnCompleteComponent.cs
@@ -0,0 +1,11 @@
+using Content.Shared.GameTicking;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Trigger.Components.Triggers;
+
+///
+/// A trigger which occurs on .
+///
+/// This does not work with , as it would add this component while the event is getting raised.
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class TriggerOnPlayerSpawnCompleteComponent : BaseTriggerOnXComponent;
diff --git a/Content.Shared/Trigger/Systems/ExplodeOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/ExplodeOnTriggerSystem.cs
index 1c773b79a6..120aa23a9d 100644
--- a/Content.Shared/Trigger/Systems/ExplodeOnTriggerSystem.cs
+++ b/Content.Shared/Trigger/Systems/ExplodeOnTriggerSystem.cs
@@ -11,10 +11,11 @@ public sealed class ExplodeOnTriggerSystem : EntitySystem
{
base.Initialize();
- SubscribeLocalEvent(OnTrigger);
+ SubscribeLocalEvent(OnExplodeTrigger);
+ SubscribeLocalEvent(OnQueueExplosionTrigger);
}
- private void OnTrigger(Entity ent, ref TriggerEvent args)
+ private void OnExplodeTrigger(Entity ent, ref TriggerEvent args)
{
if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))
return;
@@ -27,4 +28,27 @@ public sealed class ExplodeOnTriggerSystem : EntitySystem
_explosion.TriggerExplosive(target.Value, user: args.User);
args.Handled = true;
}
+
+ private void OnQueueExplosionTrigger(Entity ent, ref TriggerEvent args)
+ {
+ var (uid, comp) = ent;
+ if (args.Key != null && !comp.KeysIn.Contains(args.Key))
+ return;
+
+ var target = comp.TargetUser ? args.User : uid;
+
+ if (target == null)
+ return;
+
+ _explosion.QueueExplosion(target.Value,
+ comp.ExplosionType,
+ comp.TotalIntensity,
+ comp.IntensitySlope,
+ comp.MaxTileIntensity,
+ comp.TileBreakScale,
+ comp.MaxTileBreak,
+ comp.CanCreateVacuum,
+ args.User);
+ args.Handled = true;
+ }
}
diff --git a/Content.Shared/Trigger/Systems/TriggerSystem.Spawn.cs b/Content.Shared/Trigger/Systems/TriggerSystem.Spawn.cs
index 83457361fd..8750110744 100644
--- a/Content.Shared/Trigger/Systems/TriggerSystem.Spawn.cs
+++ b/Content.Shared/Trigger/Systems/TriggerSystem.Spawn.cs
@@ -1,4 +1,5 @@
-using Content.Shared.Trigger.Components.Effects;
+using Content.Shared.GameTicking;
+using Content.Shared.Trigger.Components.Effects;
using Content.Shared.Trigger.Components.Triggers;
using Robust.Shared.Prototypes;
@@ -9,6 +10,7 @@ public sealed partial class TriggerSystem
private void InitializeSpawn()
{
SubscribeLocalEvent(OnSpawnInit);
+ SubscribeLocalEvent(OnPlayerSpawn);
SubscribeLocalEvent(HandleSpawnOnTrigger);
SubscribeLocalEvent(HandleSpawnTableOnTrigger);
@@ -20,6 +22,11 @@ public sealed partial class TriggerSystem
Trigger(ent.Owner, null, ent.Comp.KeyOut);
}
+ private void OnPlayerSpawn(Entity ent, ref PlayerSpawnCompleteEvent args)
+ {
+ Trigger(ent.Owner, null, ent.Comp.KeyOut);
+ }
+
private void HandleSpawnOnTrigger(Entity ent, ref TriggerEvent args)
{
if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))