fix(player): apply AttributeFormula to wire-derived Run/Jump skill — root cause of short jumps
Found the underlying cause of the user's persistent "jumps don't reach retail height" complaint. The wire's SkillEntry `init` field is ONLY the InitLevel (training/specialized chargen bonus, per ACE GameEventPlayerDescription.cs:317 "init_level, for training/specialized bonus from character creation"). It does NOT include the AttributeFormula contribution. ACE's CreatureSkill.Current is computed as: AttributeFormula(skill, attrs) + InitLevel + Ranks + augs + multipliers - vitae Pre-fix13 we used `init + ranks` only — dropping the AttributeFormula term, which is the DOMINANT component for movement skills (50-100 points typical). For our character that meant Jump skill 208 instead of the actual ~280-310, giving a 3.11 m peak instead of the retail ~4 m peak. Hence "feels like the upward acceleration is too slow and we don't reach the same height". Fix: - GameWindow caches portal.dat's SkillTable (0x0E000004u) at WireAll time. Each entry has a SkillFormula with attr1/ attr2/multipliers/divisor/additive constants (formula: bonus = (attr1*M1 + attr2*M2)/Div + Additive). - GameEventWiring.WireAll gains a `resolveSkillFormulaBonus(skillId, attrCurrents)` callback. GameWindow plugs in a resolver that looks up SkillTable.Skills[skillId].Formula, applies the formula using the player's current attribute values from PD. - The PD handler builds attrId→current map (ranks+start) from the parsed attributes before iterating skills, then passes it to the resolver for Run (24) and Jump (22). - Total skill = formulaBonus + InitLevel + Ranks. Matches ACE Current minus augs/multipliers/vitae (close enough — those add maybe ±10 % at most). ACDREAM_DUMP_VITALS=1 logs add a per-skill line: "vitals: PD-skill id=22 init=N ranks=N formulaBonus=N total=N" so live testing can confirm the formula is applied. Tests stay 1222 green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4b6fcffa01
commit
a060f4fc98
2 changed files with 83 additions and 11 deletions
|
|
@ -1220,9 +1220,37 @@ public sealed class GameWindow : IDisposable
|
|||
// this one call, server-sent ChannelBroadcast / damage
|
||||
// notifications / spell learns / wield events all update
|
||||
// the corresponding client-side state without further glue.
|
||||
// K-fix13 (2026-04-26): cache portal.dat's SkillTable so the
|
||||
// skill-formula resolver can apply the AttributeFormula
|
||||
// contribution. Without this, our wire-derived "skill"
|
||||
// value was missing the dominant attribute-derived term
|
||||
// and jumps undershot retail by ~30 % at typical
|
||||
// attribute levels.
|
||||
var skillTable = _dats?.Get<DatReaderWriter.DBObjs.SkillTable>(0x0E000004u);
|
||||
|
||||
AcDream.Core.Net.GameEventWiring.WireAll(
|
||||
_liveSession.GameEvents, Items, Combat, SpellBook, Chat, LocalPlayer,
|
||||
TurbineChat,
|
||||
resolveSkillFormulaBonus: (skillId, attrCurrents) =>
|
||||
{
|
||||
// ACE GetFormula (AttributeFormula.cs:55-): when
|
||||
// formula.X (Attribute1Multiplier) is 0, the formula
|
||||
// is "no attribute contribution" and the function
|
||||
// returns 0. Otherwise:
|
||||
// bonus = (attr1 * Mult1 + attr2 * Mult2) / Divisor + Additive
|
||||
if (skillTable?.Skills is null) return 0u;
|
||||
if (!skillTable.Skills.TryGetValue(
|
||||
(DatReaderWriter.Enums.SkillId)skillId, out var skillBase))
|
||||
return 0u;
|
||||
var f = skillBase.Formula;
|
||||
if (f.Attribute1Multiplier == 0 || f.Divisor == 0) return 0u;
|
||||
attrCurrents.TryGetValue((uint)f.Attribute1, out uint a1);
|
||||
attrCurrents.TryGetValue((uint)f.Attribute2, out uint a2);
|
||||
long num = (long)a1 * f.Attribute1Multiplier
|
||||
+ (long)a2 * f.Attribute2Multiplier;
|
||||
long bonus = num / f.Divisor + f.AdditiveBonus;
|
||||
return bonus < 0 ? 0u : (uint)bonus;
|
||||
},
|
||||
onSkillsUpdated: (runSkill, jumpSkill) =>
|
||||
{
|
||||
// K-fix7 (2026-04-26): cache the latest server-sent
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue