using Unity.Collections; using Unity.Entities; namespace ProjectM.Simulation { /// Ability KIND for the AbilityFireSystem dispatch (MC-4 spike for MC-6). Backed by byte so the /// baked blob stores a byte (the Burst cross-assembly enum rule); the runtime switch compares the byte value. public enum AbilityArchetype : byte { Projectile = 0, // today's path: spawn a projectile ghost Hitscan = 1, // MC-6 Cone = 2, // MC-6 (melee-style cone via the ability system) Aoe = 3, // MC-6 } /// One authored ability definition, baked immutable into the AbilityDatabase blob. public struct AbilityDefBlob { public byte Id; // AbilityId public byte Archetype; // AbilityArchetype (0 = Projectile); read at dispatch in AbilityFireSystem (MC-6 spike) public float Damage; public float ProjectileSpeed; public float Range; public float AutoTargetRange; public float AutoTargetConeRadians; public int CooldownTicks; public FixedString64Bytes Name; } /// One authored character-stats definition, baked immutable into the AbilityDatabase blob. public struct CharacterStatsBlob { public byte Id; // CharacterId public float MoveSpeed; public float TurnRateRadiansPerSec; public float MaxHealth; public FixedString64Bytes Name; } /// /// Immutable designer-authored definition database, baked from ScriptableObjects to a blob asset and /// shared by every entity (Burst-fast, zero per-instance cost). Looked up by stable id. Entity/prefab /// references are NOT stored here (blobs don't remap entity refs) - see AbilityPrefabElement. /// /// NOTE: the lookups are intentionally NOT 'readonly' methods. A readonly struct method forces a /// defensive copy of a field when calling a non-readonly member on it; copying a BlobArray breaks its /// relative-offset pointer, so the array would read as empty. Plain (non-readonly) methods access the /// BlobArray in place. Always reach these through 'ref blob.Value'. /// public struct AbilityDatabaseBlob { public BlobArray Abilities; public BlobArray Characters; /// Linear lookup by ability id (the array is tiny). Returns false if not present. public bool TryGetAbility(byte id, out AbilityDefBlob def) { for (int i = 0; i < Abilities.Length; i++) { if (Abilities[i].Id == id) { def = Abilities[i]; return true; } } def = default; return false; } /// Linear lookup by character id (the array is tiny). Returns false if not present. public bool TryGetCharacter(byte id, out CharacterStatsBlob def) { for (int i = 0; i < Characters.Length; i++) { if (Characters[i].Id == id) { def = Characters[i]; return true; } } def = default; return false; } } }