Run Re-Do

This commit is contained in:
2026-07-02 20:41:43 -07:00
parent 86575dd5bc
commit 16e396841e
188 changed files with 8291 additions and 2429 deletions
@@ -187,6 +187,39 @@ namespace ProjectM.Server
ClassTraits.Reapply(newClass, classMods);
SystemAPI.SetComponent(sender, new AbilityRef { Id = ClassTraits.AbilityFor(newClass) });
// Expedition redesign (dev fork, operator-approved): keep the PERMANENT meta channel in
// sync with the swap. Reapply only strips the CLASS-seed band, so the OLD class's meta
// rows would survive — strip the meta band, replay the NEW class's persisted tiers (the
// GoInGame skip/clamp rules), and repoint the server-only PlayerClass anchor so a later
// MetaSpendRequest buys against the right class record. Runs BEFORE the heal below so the
// refill folds the new class's meta MaxHealth too.
TimedModifierUtil.RemoveBySourceIdRange(classMods, Tuning.MetaSourceIdBase,
Tuning.MetaSourceIdBase + Tuning.MetaSourceIdSpan);
if (SystemAPI.TryGetSingleton<MetaUpgradeCatalog>(out var metaCat) && metaCat.Value.IsCreated
&& SystemAPI.TryGetSingletonBuffer<MetaTierState>(out var metaRecord, true))
{
ref var metaPool = ref metaCat.Value.Value;
byte metaBit = BoonMath.MaskFor(newClass);
for (int mi = 0; mi < metaRecord.Length; mi++)
{
if (metaRecord[mi].ClassId != newClass || metaRecord[mi].Tier == 0) continue;
int defIdx = MetaMath.FindDef(ref metaPool, metaRecord[mi].UpgradeId);
if (defIdx < 0) continue;
if ((metaPool.Defs[defIdx].ClassMask & metaBit) == 0) continue;
byte metaTier = metaRecord[mi].Tier < metaPool.Defs[defIdx].MaxTier
? metaRecord[mi].Tier : metaPool.Defs[defIdx].MaxTier;
classMods.Add(new StatModifier
{
Target = metaPool.Defs[defIdx].Target,
Op = metaPool.Defs[defIdx].Op,
Value = metaPool.Defs[defIdx].ValuePerTier * metaTier,
SourceId = Tuning.MetaSourceIdBase + metaRecord[mi].UpgradeId,
});
}
}
if (SystemAPI.HasComponent<PlayerClass>(sender))
SystemAPI.SetComponent(sender, new PlayerClass { ClassId = newClass });
// Let the swapped Fire ability fire immediately (both abilities share one cooldown gate).
if (SystemAPI.HasComponent<AbilityCooldown>(sender))
SystemAPI.SetComponent(sender, new AbilityCooldown { NextFireTick = 0 }); // 0 = ready