Files
Project-M/Assets/_Project/Scripts/Simulation/Combat/EnemyComponents.cs
T
kronic e362aaeb43 Import art/VFX asset packs + game-feel systems; normalize texture extensions to lowercase for LFS
Add BefourStudios SciFi environment packs, Gabriel Aguiar VFX, and the
ShaderCrew Toon Shader embedded packages, plus combat/enemy/wave/death
gameplay systems and supporting vault docs/screenshots.

Rename 11 vendor textures from uppercase .PNG/.HDR to lowercase so the
case-sensitive Git LFS filters (*.png/*.hdr) match on case-sensitive
filesystems (Linux CI, case-sensitive macOS), not just locally where
core.ignorecase=true masks the gap. Each .meta moved with its asset so
GUID references are preserved. All ~1000 binaries tracked via LFS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 22:50:43 -07:00

44 lines
1.9 KiB
C#

using Unity.Entities;
namespace ProjectM.Simulation
{
/// <summary>
/// Marks a Husk enemy: a server-simulated, OWNERLESS INTERPOLATED ghost that seeks the nearest player
/// and strikes on contact. Damageable like the training dummy (Health/HitRadius/DamageEvent), but unlike
/// the dummy it IS a replicated ghost, so every client sees it. Movement is server-authoritative — written
/// to LocalTransform in the plain <c>SimulationSystemGroup</c> (interpolated ghosts are NOT predicted) and
/// replicated via the stock LocalTransform default variant (no hand-written <c>[GhostField]</c>). Spawned by
/// the <see cref="WaveDirector"/> (round-robin over Husk variants).
/// </summary>
public struct EnemyTag : IComponentData { }
/// <summary>
/// Baked Husk tunables — identical on both worlds, not replicated (only server systems read them). Different
/// Husk variants (Grunt / Swarmer / Brute) are just different baked values of this component.
/// </summary>
public struct EnemyStats : IComponentData
{
/// <summary>Planar seek speed toward the target, world units/second.</summary>
public float MoveSpeed;
/// <summary>Centre-to-centre distance at which the Husk can strike a player.</summary>
public float AttackRange;
/// <summary>Damage dealt per strike.</summary>
public float AttackDamage;
/// <summary>Simulation ticks between strikes.</summary>
public int AttackCooldownTicks;
}
/// <summary>
/// Server-only per-Husk attack gate. Raw tick value of the earliest tick it may strike again; <c>0</c> =
/// ready. Compared by wrapping into a <see cref="Unity.NetCode.NetworkTick"/> (raw subtraction is unsafe
/// across tick wraparound), mirroring <see cref="AbilityCooldown"/>. Not replicated.
/// </summary>
public struct EnemyAttackCooldown : IComponentData
{
public uint NextAttackTick;
}
}