using Unity.Entities;
using Unity.Mathematics;
using Unity.NetCode;
namespace ProjectM.Simulation
{
///
/// Structure type ids (a byte, not an enum, per the cross-assembly enum-in-Burst hazard). Turret is the
/// first concrete structure; Harvester/Fabricator/Conveyor are RESERVED now (free) for the M7 automation
/// pillar (production chains) so adding them later is purely additive.
///
public static class StructureType
{
public const byte None = 0;
public const byte Turret = 1;
// Reserved for M7 automation — do not reuse these codes:
public const byte Harvester = 2;
public const byte Fabricator = 3;
public const byte Conveyor = 4;
// World-pass structural/cosmetic build-out (additive; these byte values keep PlacedStructure.Type's
// [GhostField] serializer identical — no re-bake of existing ghosts). Do NOT reuse 2-4 (M7 automation).
public const byte Wall = 5;
public const byte Pylon = 6;
}
///
/// A built base structure occupying one grid cell. An ownerless INTERPOLATED ghost (RegionTag{Base},
/// world-owned, runtime-spawned by BuildPlaceSystem). is the only replicated field
/// (a cheap byte for client visual branching); is server-only (clients derive it from
/// the replicated LocalTransform via , so it stays off the wire).
/// / are server-only raw NetworkTick values
/// (-guarded; 0 = inactive): the Turret reuses as its
/// fire cooldown NOW (not dead weight), and M7 production reuses both as the next-production-tick +
/// deterministic offline catch-up linchpin (produced = floor((now - LastProcessedTick)/period)). These two
/// tick fields are the IDENTITY/TIMING that cannot be reconstructed retroactively, so they are baked now.
///
public struct PlacedStructure : IComponentData
{
/// Structure type (see ); the only replicated field.
[GhostField] public byte Type;
/// Occupied grid cell (server-only; clients derive it from LocalTransform).
public int2 Cell;
/// Next action tick (server-only; turret cooldown now / next production tick in M7). 0 = inactive.
public uint NextTick;
/// Last tick this structure was processed (server-only; M7 offline-catch-up baseline). Stamped at spawn.
public uint LastProcessedTick;
}
///
/// A buildable defense turret (the first structure). Hitscan: TurretFireSystem applies a direct
/// DamageEvent to the nearest in-range living Husk on cooldown (reusing
/// ) — reuses HealthApplyDamageSystem, no projectile/friendly-fire.
///
public struct Turret : IComponentData
{
public float Range;
public int CooldownTicks;
public float Damage;
}
///
/// One row of the build catalog: cost + prefab per structure type. Modeled on AbilityPrefabElement
/// (prefab baked via GetEntity, NEVER inside a blob — blobs don't remap entity refs). M7 adds a recipe
/// column to this element additively (the catalog is baked, not replicated → no format break).
///
public struct StructureCatalogEntry : IBufferElementData
{
public byte Type;
public Entity Prefab;
public byte CostResourceId;
public int CostAmount;
}
/// Tag on the baked singleton carrying the buffer (the build cost/prefab table).
public struct StructureCatalog : IComponentData { }
}