using Unity.Entities;
namespace ProjectM.Simulation
{
///
/// SERVER-ONLY periodic-AoE state on a player-cast zone ghost (Vortex / LightZone) — the LANTERN Aoe/zone
/// archetype. NOT a [GhostField]: the zone is a server-spawned INTERPOLATED ownerless ghost whose
/// position replicates via the stock LocalTransform variant; only its damage schedule lives here, server-side.
/// ZonePulseSystem borrows the GeyserEruptSystem skeleton (the INVERTED invalid-tick guard so a
/// born-0 tick never storm-fires + the = now + period reschedule) but is ENEMY-ONLY (no friendly fire),
/// stamps = (kills credit the caster,
/// feeding KillRewardSystem — NOT the -1 environment convention), and has NO region gate (a no-world gym).
/// DestroyEntity when elapses.
///
public struct ZoneEffect : IComponentData
{
/// NetworkId of the casting player (damage/kill attribution).
public int CasterNetworkId;
/// Planar (XZ) damage radius, world units.
public float Radius;
/// Damage dealt to each living enemy in radius per pulse.
public float DamagePerPulse;
/// Raw next-pulse tick (NonZero). 0 = unscheduled → lazy-stamped born-correct (GeyserErupt H2 rule, never storm-fires).
public uint NextTick;
/// Raw tick the zone despawns (NonZero). Active while .IsNewerThan(serverTick).
public uint ExpireTick;
/// See . bit0 = Vortex (also pull enemies toward the zone center each pulse).
public byte Flags;
}
/// Bit masks for .
public static class ZoneEffectFlag
{
public const byte Vortex = 1;
}
///
/// SERVER-ONLY decoy-wisp state (the Aoe/spawn Spark) — a server-spawned INTERPOLATED ownerless ghost that
/// draws Husk aggro. EnemyAISystem gathers DecoyTag entities into its target set so Husks path to and
/// strike the decoy (soaking hits via its Health/DamageEvent buffer); it despawns on Health <= 0 or
/// when elapses (both handled where EnemyAISystem already iterates decoys). Position
/// replicates via the stock LocalTransform variant — NOT a [GhostField].
///
public struct DecoyTag : IComponentData
{
/// Raw tick the decoy despawns (NonZero). 0 = no timeout; active while .IsNewerThan(serverTick).
public uint ExpireTick;
}
}