feat(player): port retail augmentation stat chain

This commit is contained in:
Erik 2026-07-31 08:08:23 +02:00
parent 0cb60d98a0
commit 461a1fb7b4
22 changed files with 953 additions and 138 deletions

View file

@ -140,6 +140,18 @@ public sealed class CharacterSheetProvider
StaminaMax = VitalMax(LocalPlayerState.VitalKind.Stamina),
ManaCurrent = VitalCurrent(LocalPlayerState.VitalKind.Mana),
ManaMax = VitalMax(LocalPlayerState.VitalKind.Mana),
VitalBaseMaxValues =
[
VitalBaseMax(LocalPlayerState.VitalKind.Health),
VitalBaseMax(LocalPlayerState.VitalKind.Stamina),
VitalBaseMax(LocalPlayerState.VitalKind.Mana),
],
VitalVitaeModifiers =
[
_localPlayer.GetVitalVitaeModifier(LocalPlayerState.VitalKind.Health),
_localPlayer.GetVitalVitaeModifier(LocalPlayerState.VitalKind.Stamina),
_localPlayer.GetVitalVitaeModifier(LocalPlayerState.VitalKind.Mana),
],
// Issue #267: the panel's main attribute values are EFFECTIVE
// (post-buff) — retail CACQualities::EnchantAttribute. Base values
@ -176,7 +188,7 @@ public sealed class CharacterSheetProvider
AttrCurrent(LocalPlayerState.AttributeKind.Focus),
AttrCurrent(LocalPlayerState.AttributeKind.Self),
},
Skills = BuildLiveCharacterSkills(),
Skills = BuildLiveCharacterSkills(props),
BurdenCurrent = props.GetInt(5u),
BurdenMax = props.GetInt(96u),
EncumbranceAugmentations = props.GetInt(0xE6u),
@ -344,7 +356,8 @@ public sealed class CharacterSheetProvider
}
}
private IReadOnlyList<CharacterSkill> BuildLiveCharacterSkills()
private IReadOnlyList<CharacterSkill> BuildLiveCharacterSkills(
PropertyBundle properties)
{
var result = new List<CharacterSkill>();
var skillTable = SkillTable;
@ -374,23 +387,26 @@ public sealed class CharacterSheetProvider
// retail CACQualities::EnchantSkill (0x005947b0). VitaeModifier
// isolates vitae's own contribution for the footer's separate
// vitae parenthetical (SkillInfoRegion::GetVitaeModifier 0x004f0fa0).
int effectiveLevel = _localPlayer.GetEffectiveSkill(snapshot.SkillId)
?? checked((int)Math.Min(int.MaxValue, snapshot.CurrentLevel));
int vitaeModifier = _localPlayer.GetSkillVitaeModifier(snapshot.SkillId);
PlayerSkillMath.Value values =
_localPlayer.GetSkillValue(snapshot.SkillId, properties)
?? new PlayerSkillMath.Value(
checked((int)Math.Min(int.MaxValue, snapshot.CurrentLevel)),
checked((int)Math.Min(int.MaxValue, snapshot.CurrentLevel)),
0);
result.Add(new CharacterSkill(
snapshot.SkillId,
name,
icon,
advancement,
checked((int)Math.Min(int.MaxValue, snapshot.BaseLevel)),
effectiveLevel,
values.UnenchantedLevel,
values.EffectiveLevel,
IsUsableUntrained(snapshot.SkillId),
trainedCost,
specializedCost,
raiseCost,
raise10Cost,
vitaeModifier));
values.VitaeModifier));
}
return result;
@ -467,6 +483,11 @@ public sealed class CharacterSheetProvider
private int VitalMax(LocalPlayerState.VitalKind kind) =>
_localPlayer.GetMaxApprox(kind) is { } max ? checked((int)Math.Min(int.MaxValue, max)) : 0;
private int VitalBaseMax(LocalPlayerState.VitalKind kind) =>
_localPlayer.GetBaseMaxApprox(kind) is { } max
? checked((int)Math.Min(int.MaxValue, max))
: 0;
// ── Raise-request flow ─────────────────────────────────────────────────
/// <summary>