using Unity.Entities;
using Unity.NetCode;
namespace ProjectM.Simulation
{
///
/// MC-4 — predicted, owner-replicated melee combo state on the player (the PRIMARY offense verb). UNLIKE the dash
/// (DashState is non-replicated because a dash is a STATELESS-per-tick decision), the combo is
/// PATH-DEPENDENT — which chain link you are on depends on the sequence + timing of prior presses — and the bounded
/// input command buffer cannot reconstruct it across a reconnect / long rollback (MC-4 review PRED-1 / ROLLBACK-1).
/// So the minimal anchor is replicated as owner-predicted [GhostField]s: a rollback restores the
/// authoritative combo position, then MeleeComboSystem re-simulates forward with ABSOLUTE-WRITE windows (never an
/// in-place prev+1 of a non-restored field — the DashSystem idempotency idiom). The derived chain deadline
/// (LockUntilTick + grace) is NOT stored. All ticks routed through TickUtil.NonZero; compared via
/// only. Baked all-zero (idle). This is the player ghost's only net-new replicated melee
/// state (one re-bake; in-family with DashCooldown/AbilityCooldown).
///
public struct MeleeCombo : IComponentData
{
/// Current/last swing index: 0 = idle, 1..N = chain link. Owner-predicted so a rollback restores the
/// authoritative combo position (the only legitimately path-dependent value).
[GhostField] public byte Step;
/// Raw ServerTick the current swing started (NonZero). Inclusive lower bound of the movement-commit
/// window; also the juice edge signal and the (instant) damage frame.
[GhostField] public uint SwingStartTick;
/// Raw ServerTick the swing's movement-commit / recovery lock ends (NonZero). Gates the next press
/// (locked while now < this) and anchors the chain window [LockUntilTick, LockUntilTick + grace).
[GhostField] public uint LockUntilTick;
/// 07-20 (guidelines G7 input buffer): raw ServerTick of an Attack press that landed during the
/// swing lock's LAST MeleeBufferTicks (NonZero; 0 = empty). Consumed (zeroed) when it starts the chained
/// swing; validity is anchored to the UNLOCK edge, not the press tick, so server tick-batching cannot
/// drop an edge press (design review wf_000bc247 C1). Predicted + rollback-restored like its siblings.
[GhostField] public uint BufferedAttackTick;
}
/// 07-20 (guidelines G2.1 damage-at-contact): SERVER-ONLY scheduled cleave — the AttackWindup
/// schedule-and-consume idiom, entity-local (design review wf_000bc247 C11: no container, no disposal, no
/// staleness window). Stamped when a swing starts (ResolveTick = start + MeleeTiming.ContactTicks), fired on
/// a wrap-safe elapsed compare (tick-batch-proof), CONSUMED by zeroing. A still-armed pending is FLUSHED
/// (fired early) before a chained swing overwrites it, so no knob combination can lose a cleave (C0/C12).
/// Not replicated; the client's contact cues are presentation-side (CombatFeedbackSystem). Baked zeroed.
public struct MeleeCleavePending : IComponentData
{
/// NonZero tick the armed swing's blade lands; 0 = nothing pending.
public uint ResolveTick;
/// Combo step of the ARMED swing (finisher scaling resolved against the live combo length).
public byte Step;
}
}