using Unity.Entities;
namespace ProjectM.Simulation
{
///
/// The ONE in-place frame-swap effect, shared by the editor dev tool (DebugOp.SetClass) and the player-facing
/// frame select. Re-seeds the frame's stat band via ; the caller then writes
/// FrameId/PlayerClass, re-seeds the socket loadout, and calls (a static can't resolve
/// singletons or SystemAPI.SetComponent, so the caller passes the resolved pieces). Server-authoritative +
/// prediction-correct (StatRecomputeSystem refolds EffectiveCharacterStats next tick).
///
/// HISTORY (2026-08-07 audit purge): this also used to strip and replay a PERMANENT-META band
/// (MetaUpgradeCatalog + MetaTierState) so an Aether-bought upgrade followed the frame across a swap. The meta
/// shop belonged to the superseded base/expedition direction and was deleted; only the frame band remains.
///
public static class ClassSwapUtil
{
/// Re-seed the frame stat band for on .
/// Returns the normalized frame id (the caller writes FrameId/PlayerClass + re-seeds the socket
/// loadout).
public static void Apply(byte rawClass, DynamicBuffer mods, out byte newClass)
{
newClass = ClassTraits.Normalize(rawClass);
ClassTraits.Reapply(newClass, mods);
}
/// Heal/down-clamp a LIVING player's Current to the new class's full max (blob base folded with the
/// just-reseeded , like StatRecomputeSystem). Doubles as the down-clamp when the new
/// class's max is lower (Bathynaut +30 HP vs Harpooner -15%). No-op on a corpse (Current<=0) — respawn refills.
public static void HealClamp(ref Health health, float baseMaxHealth, DynamicBuffer mods)
{
if (health.Current > 0f)
health.Current = StatMath.Apply(baseMaxHealth, StatTarget.MaxHealth, mods);
}
}
}