LANTERN purge B6: delete the legacy single-ability path (sockets are THE ability model)
AbilityRef, AbilityCooldown, EffectiveAbilityStats, DefaultAbility deleted. GoInGameServerSystem seeds the per-frame 4-socket Spark loadout UNCONDITIONALLY (was gym-only); ClassSelectReceiveSystem + DebugOp.SetClass swap FrameId + re-seed sockets + zero SocketCooldown; ClassSwapUtil.Apply drops newAbilityId; EquipSystem weapons become stat-sticks (GrantedAbilityId removed from the item blob/authoring); StatRecomputeSystem folds CharacterStatsRef + sockets only; HUD cooldown bar reads socket 0 of SocketCooldown/EffectiveSocketStats; class HUD readers are FrameId-only (ClassForAbility/AbilityFor deleted); DebugModifierInjectionSystem drops CycleAbility. 390 tests green; Play-verified: a non-gym spawn gets frame=2 with Sparks [7,8,6,9] and no console errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -81,9 +81,9 @@ namespace ProjectM.Client
|
||||
// Local class from the replicated AbilityRef (tracks the dev class-switch; PlayerClass is server-only).
|
||||
byte localClass = ClassTraits.WarriorClass;
|
||||
bool haveLocalPlayer = false;
|
||||
foreach (var (fr, ar) in SystemAPI.Query<RefRO<FrameId>, RefRO<AbilityRef>>().WithAll<PlayerTag, GhostOwnerIsLocal>())
|
||||
foreach (var fr in SystemAPI.Query<RefRO<FrameId>>().WithAll<PlayerTag, GhostOwnerIsLocal>())
|
||||
{
|
||||
localClass = fr.ValueRO.Value != 0 ? fr.ValueRO.Value : ClassTraits.ClassForAbility(ar.ValueRO.Id); // FrameId signal, AbilityRef fallback
|
||||
localClass = ClassTraits.Normalize(fr.ValueRO.Value); // FrameId is the sole class signal (legacy AbilityRef deleted)
|
||||
haveLocalPlayer = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -134,8 +134,8 @@ namespace ProjectM.Client
|
||||
// stays correct the day a Health/stats writer is parallelised.
|
||||
EntityManager.CompleteDependencyBeforeRO<Health>();
|
||||
EntityManager.CompleteDependencyBeforeRO<EffectiveCharacterStats>();
|
||||
EntityManager.CompleteDependencyBeforeRO<EffectiveAbilityStats>();
|
||||
EntityManager.CompleteDependencyBeforeRO<AbilityCooldown>();
|
||||
EntityManager.CompleteDependencyBeforeRO<SocketCooldown>();
|
||||
EntityManager.CompleteDependencyBeforeRO<EffectiveSocketStats>();
|
||||
EntityManager.CompleteDependencyBeforeRO<RespawnInvuln>();
|
||||
|
||||
float dt = SystemAPI.Time.DeltaTime; // wall-frame delta — correct in a presentation system
|
||||
@@ -330,9 +330,9 @@ namespace ProjectM.Client
|
||||
float hp = 0f, maxHp = 1f, cdFrac = 1f;
|
||||
bool dead = false, shielded = false;
|
||||
|
||||
foreach (var (health, effChar, effAbility, cd, invuln, entity) in
|
||||
SystemAPI.Query<RefRO<Health>, RefRO<EffectiveCharacterStats>, RefRO<EffectiveAbilityStats>,
|
||||
RefRO<AbilityCooldown>, RefRO<RespawnInvuln>>()
|
||||
foreach (var (health, effChar, cd, invuln, entity) in
|
||||
SystemAPI.Query<RefRO<Health>, RefRO<EffectiveCharacterStats>,
|
||||
RefRO<SocketCooldown>, RefRO<RespawnInvuln>>()
|
||||
.WithAll<GhostOwnerIsLocal, PlayerTag>().WithEntityAccess())
|
||||
{
|
||||
found = true;
|
||||
@@ -340,8 +340,15 @@ namespace ProjectM.Client
|
||||
maxHp = effChar.ValueRO.MaxHealth > 0f ? effChar.ValueRO.MaxHealth : health.ValueRO.Max;
|
||||
dead = SystemAPI.IsComponentEnabled<Dead>(entity);
|
||||
|
||||
uint nextFire = cd.ValueRO.NextFireTick;
|
||||
int cdTicks = effAbility.ValueRO.CooldownTicks;
|
||||
// Cooldown bar = socket 0 (the primary Spark) of the 4-socket kit (the legacy single
|
||||
// AbilityCooldown died — LANTERN purge). EffectiveSocketStats row 0 supplies the duration.
|
||||
uint nextFire = cd.ValueRO.Get(0);
|
||||
int cdTicks = 0;
|
||||
if (SystemAPI.HasBuffer<EffectiveSocketStats>(entity))
|
||||
{
|
||||
var effSockets = SystemAPI.GetBuffer<EffectiveSocketStats>(entity);
|
||||
if (effSockets.Length > 0) cdTicks = effSockets[0].CooldownTicks;
|
||||
}
|
||||
var nextTick = new NetworkTick(nextFire);
|
||||
cdFrac = (haveTick && nextFire != 0 && cdTicks > 0 && nextTick.IsValid && nextTick.IsNewerThan(nt.ServerTick))
|
||||
? Mathf.Clamp01(1f - nextTick.TicksSince(nt.ServerTick) / (float)cdTicks)
|
||||
|
||||
@@ -74,9 +74,9 @@ namespace ProjectM.Client
|
||||
// server-only); tiers from the replicated MetaTierState record on the director ghost.
|
||||
byte localClass = ClassTraits.WarriorClass;
|
||||
bool haveLocalPlayer = false;
|
||||
foreach (var (fr, ar) in SystemAPI.Query<RefRO<FrameId>, RefRO<AbilityRef>>().WithAll<PlayerTag, GhostOwnerIsLocal>())
|
||||
foreach (var fr in SystemAPI.Query<RefRO<FrameId>>().WithAll<PlayerTag, GhostOwnerIsLocal>())
|
||||
{
|
||||
localClass = fr.ValueRO.Value != 0 ? fr.ValueRO.Value : ClassTraits.ClassForAbility(ar.ValueRO.Id); // FrameId signal, AbilityRef fallback
|
||||
localClass = ClassTraits.Normalize(fr.ValueRO.Value); // FrameId is the sole class signal (legacy AbilityRef deleted)
|
||||
haveLocalPlayer = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user