TriggerOnPlayerSpawnComplete and ExplosionOnTrigger (#39820)
This commit is contained in:
@@ -63,16 +63,6 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem
|
||||
|
||||
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()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -222,10 +212,8 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem
|
||||
return r0 * (MathF.Sqrt(12 * totalIntensity / v0 - 3) / 6 + 0.5f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queue an explosions, centered on some entity.
|
||||
/// </summary>
|
||||
public void QueueExplosion(EntityUid uid,
|
||||
/// <inheritdoc />
|
||||
public override void QueueExplosion(EntityUid uid,
|
||||
string typeId,
|
||||
float totalIntensity,
|
||||
float slope,
|
||||
|
||||
@@ -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.
|
||||
/// <summary>
|
||||
/// Lets code in shared trigger explosions and handles explosion resistance examining.
|
||||
/// All processing is still done clientside.
|
||||
/// </summary>
|
||||
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()
|
||||
{
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
/// <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;
|
||||
|
||||
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.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// TODO: Allow this to work without an ExplosiveComponent on the user via QueueExplosion.
|
||||
/// </summary>
|
||||
/// <seealso cref="ExplosionOnTriggerComponent"/>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
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();
|
||||
|
||||
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))
|
||||
return;
|
||||
@@ -27,4 +28,27 @@ public sealed class ExplodeOnTriggerSystem : EntitySystem
|
||||
_explosion.TriggerExplosive(target.Value, user: args.User);
|
||||
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 Robust.Shared.Prototypes;
|
||||
|
||||
@@ -9,6 +10,7 @@ public sealed partial class TriggerSystem
|
||||
private void InitializeSpawn()
|
||||
{
|
||||
SubscribeLocalEvent<TriggerOnSpawnComponent, MapInitEvent>(OnSpawnInit);
|
||||
SubscribeLocalEvent<TriggerOnPlayerSpawnCompleteComponent, PlayerSpawnCompleteEvent>(OnPlayerSpawn);
|
||||
|
||||
SubscribeLocalEvent<SpawnOnTriggerComponent, TriggerEvent>(HandleSpawnOnTrigger);
|
||||
SubscribeLocalEvent<SpawnEntityTableOnTriggerComponent, TriggerEvent>(HandleSpawnTableOnTrigger);
|
||||
@@ -20,6 +22,11 @@ public sealed partial class TriggerSystem
|
||||
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)
|
||||
{
|
||||
if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))
|
||||
|
||||
Reference in New Issue
Block a user