TriggerOnPlayerSpawnComplete and ExplosionOnTrigger (#39820)
This commit is contained in:
@@ -63,16 +63,6 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem
|
|||||||
|
|
||||||
public const int MaxExplosionAudioRange = 30;
|
public const int MaxExplosionAudioRange = 30;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The "default" explosion prototype.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// 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.
|
|
||||||
/// </remarks>
|
|
||||||
public static readonly ProtoId<ExplosionPrototype> DefaultExplosionPrototypeId = "Default";
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
@@ -222,10 +212,8 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem
|
|||||||
return r0 * (MathF.Sqrt(12 * totalIntensity / v0 - 3) / 6 + 0.5f);
|
return r0 * (MathF.Sqrt(12 * totalIntensity / v0 - 3) / 6 + 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Queue an explosions, centered on some entity.
|
public override void QueueExplosion(EntityUid uid,
|
||||||
/// </summary>
|
|
||||||
public void QueueExplosion(EntityUid uid,
|
|
||||||
string typeId,
|
string typeId,
|
||||||
float totalIntensity,
|
float totalIntensity,
|
||||||
float slope,
|
float slope,
|
||||||
|
|||||||
@@ -1,14 +1,26 @@
|
|||||||
using Content.Shared.Armor;
|
using Content.Shared.Armor;
|
||||||
using Content.Shared.Explosion.Components;
|
using Content.Shared.Explosion.Components;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Shared.Explosion.EntitySystems;
|
namespace Content.Shared.Explosion.EntitySystems;
|
||||||
|
|
||||||
|
// TODO some sort of struct like DamageSpecifier but for explosions.
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lets code in shared trigger explosions and handles explosion resistance examining.
|
/// Lets code in shared trigger explosions and handles explosion resistance examining.
|
||||||
/// All processing is still done clientside.
|
/// All processing is still done clientside.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class SharedExplosionSystem : EntitySystem
|
public abstract class SharedExplosionSystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The "default" explosion prototype.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 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.
|
||||||
|
/// </remarks>
|
||||||
|
public static readonly ProtoId<ExplosionPrototype> DefaultExplosionPrototypeId = "Default";
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.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)
|
public virtual void TriggerExplosive(EntityUid uid, ExplosiveComponent? explosive = null, bool delete = true, float? totalIntensity = null, float? radius = null, EntityUid? user = null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queue an explosion centered on some entity. Bypasses needing <see cref="ExplosiveComponent"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uid">Where the explosion happens.</param>
|
||||||
|
/// <param name="typeId">A ProtoId of type <see cref="ExplosionPrototype"/>.</param>
|
||||||
|
/// <param name="user">The entity which caused the explosion.</param>
|
||||||
|
/// <param name="addLog">Whether to add an admin log about this explosion. Includes user.</param>
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Shared.Explosion.Components;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
namespace Content.Shared.Trigger.Components.Effects;
|
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.
|
/// TargetUser will only work of the user has ExplosiveComponent as well.
|
||||||
/// The User will be logged in the admin logs.
|
/// The User will be logged in the admin logs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <summary>
|
/// <seealso cref="ExplosionOnTriggerComponent"/>
|
||||||
/// TODO: Allow this to work without an ExplosiveComponent on the user via QueueExplosion.
|
|
||||||
/// </summary>
|
|
||||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
public sealed partial class ExplodeOnTriggerComponent : BaseXOnTriggerComponent;
|
public sealed partial class ExplodeOnTriggerComponent : BaseXOnTriggerComponent;
|
||||||
|
|||||||
@@ -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.
|
||||||
|
/// <summary>
|
||||||
|
/// 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.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="ExplodeOnTriggerComponent"/>
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
|
public sealed partial class ExplosionOnTriggerComponent : BaseXOnTriggerComponent
|
||||||
|
{
|
||||||
|
/// <inheritdoc cref="ExplosiveComponent.ExplosionType"/>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public ProtoId<ExplosionPrototype> ExplosionType = SharedExplosionSystem.DefaultExplosionPrototypeId;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ExplosiveComponent.MaxIntensity"/>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public float MaxTileIntensity = 4;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ExplosiveComponent.IntensitySlope"/>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public float IntensitySlope = 1;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ExplosiveComponent.TotalIntensity"/>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public float TotalIntensity = 10;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ExplosiveComponent.TileBreakScale"/>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public float TileBreakScale = 1f;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ExplosiveComponent.MaxTileBreak"/>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public int MaxTileBreak = int.MaxValue;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ExplosiveComponent.CanCreateVacuum"/>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public bool CanCreateVacuum = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using Content.Shared.GameTicking;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Trigger.Components.Triggers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A trigger which occurs on <see cref="PlayerSpawnCompleteEvent"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>This does not work with <see cref="TraitSystem"/>, as it would add this component while the event is getting raised.</remarks>
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
|
public sealed partial class TriggerOnPlayerSpawnCompleteComponent : BaseTriggerOnXComponent;
|
||||||
@@ -11,10 +11,11 @@ public sealed class ExplodeOnTriggerSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<ExplodeOnTriggerComponent, TriggerEvent>(OnTrigger);
|
SubscribeLocalEvent<ExplodeOnTriggerComponent, TriggerEvent>(OnExplodeTrigger);
|
||||||
|
SubscribeLocalEvent<ExplosionOnTriggerComponent, TriggerEvent>(OnQueueExplosionTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTrigger(Entity<ExplodeOnTriggerComponent> ent, ref TriggerEvent args)
|
private void OnExplodeTrigger(Entity<ExplodeOnTriggerComponent> ent, ref TriggerEvent args)
|
||||||
{
|
{
|
||||||
if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))
|
if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))
|
||||||
return;
|
return;
|
||||||
@@ -27,4 +28,27 @@ public sealed class ExplodeOnTriggerSystem : EntitySystem
|
|||||||
_explosion.TriggerExplosive(target.Value, user: args.User);
|
_explosion.TriggerExplosive(target.Value, user: args.User);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnQueueExplosionTrigger(Entity<ExplosionOnTriggerComponent> 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 Content.Shared.Trigger.Components.Triggers;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
@@ -9,6 +10,7 @@ public sealed partial class TriggerSystem
|
|||||||
private void InitializeSpawn()
|
private void InitializeSpawn()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<TriggerOnSpawnComponent, MapInitEvent>(OnSpawnInit);
|
SubscribeLocalEvent<TriggerOnSpawnComponent, MapInitEvent>(OnSpawnInit);
|
||||||
|
SubscribeLocalEvent<TriggerOnPlayerSpawnCompleteComponent, PlayerSpawnCompleteEvent>(OnPlayerSpawn);
|
||||||
|
|
||||||
SubscribeLocalEvent<SpawnOnTriggerComponent, TriggerEvent>(HandleSpawnOnTrigger);
|
SubscribeLocalEvent<SpawnOnTriggerComponent, TriggerEvent>(HandleSpawnOnTrigger);
|
||||||
SubscribeLocalEvent<SpawnEntityTableOnTriggerComponent, TriggerEvent>(HandleSpawnTableOnTrigger);
|
SubscribeLocalEvent<SpawnEntityTableOnTriggerComponent, TriggerEvent>(HandleSpawnTableOnTrigger);
|
||||||
@@ -20,6 +22,11 @@ public sealed partial class TriggerSystem
|
|||||||
Trigger(ent.Owner, null, ent.Comp.KeyOut);
|
Trigger(ent.Owner, null, ent.Comp.KeyOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnPlayerSpawn(Entity<TriggerOnPlayerSpawnCompleteComponent> ent, ref PlayerSpawnCompleteEvent args)
|
||||||
|
{
|
||||||
|
Trigger(ent.Owner, null, ent.Comp.KeyOut);
|
||||||
|
}
|
||||||
|
|
||||||
private void HandleSpawnOnTrigger(Entity<SpawnOnTriggerComponent> ent, ref TriggerEvent args)
|
private void HandleSpawnOnTrigger(Entity<SpawnOnTriggerComponent> ent, ref TriggerEvent args)
|
||||||
{
|
{
|
||||||
if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))
|
if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))
|
||||||
|
|||||||
Reference in New Issue
Block a user