fix(ui): refresh live skill rows

This commit is contained in:
Erik 2026-07-31 08:22:46 +02:00
parent 461a1fb7b4
commit 1d8371dbe5
3 changed files with 55 additions and 4 deletions

View file

@ -776,12 +776,14 @@ public static class CharacterStatController
foreach (var skill in skills) foreach (var skill in skills)
{ {
int rowIndex = bindings.Count; int rowIndex = bindings.Count;
CharacterSkill LiveSkill() =>
FindSkill(data(), skill.Id) ?? skill;
var row = AddRow(list, datFont, spriteResolve, var row = AddRow(list, datFont, spriteResolve,
left: 0f, top: y, width: listW, height: SkillRowHeight, left: 0f, top: y, width: listW, height: SkillRowHeight,
iconDid: skill.IconDid, iconDid: skill.IconDid,
nameText: skill.Name, nameText: skill.Name,
valueProvider: () => skill.CurrentLevel.ToString(), valueProvider: () => LiveSkill().CurrentLevel.ToString(),
valueColorProvider: () => SkillValueColor(skill), valueColorProvider: () => SkillValueColor(LiveSkill()),
nameColor: Vector4.One); nameColor: Vector4.One);
row.OnClick = () => row.OnClick = () =>
{ {
@ -857,6 +859,18 @@ public static class CharacterStatController
return result; return result;
} }
private static CharacterSkill? FindSkill(CharacterSheet sheet, uint skillId)
{
IReadOnlyList<CharacterSkill> skills = sheet.Skills;
for (int i = 0; i < skills.Count; i++)
{
CharacterSkill skill = skills[i];
if (skill.Id == skillId)
return skill;
}
return null;
}
private static CharacterSkill? SkillAtDisplayIndex(CharacterSheet sheet, int index) private static CharacterSkill? SkillAtDisplayIndex(CharacterSheet sheet, int index)
{ {
if (index < 0) return null; if (index < 0) return null;

View file

@ -209,6 +209,7 @@ public sealed class RetailUiRuntime : IDisposable
private UiShortcutDigitGraphics? _shortcutDigitGraphics; private UiShortcutDigitGraphics? _shortcutDigitGraphics;
private ItemCooldownUiController? _itemCooldownController; private ItemCooldownUiController? _itemCooldownController;
private VividTargetIndicatorController? _vividTargetIndicator; private VividTargetIndicatorController? _vividTargetIndicator;
private IDisposable? _characterSheetSubscription;
private ResourceShutdownTransaction? _shutdown; private ResourceShutdownTransaction? _shutdown;
private bool _disposed; private bool _disposed;
@ -1676,9 +1677,12 @@ public sealed class RetailUiRuntime : IDisposable
return; return;
} }
CharacterSheetProvider provider = _bindings.Character.Provider; CharacterSheetProvider provider = _bindings.Character.Provider;
CharacterSheet currentSheet = provider.BuildSheet();
_characterSheetSubscription = provider.SubscribeChanged(
() => currentSheet = provider.BuildSheet());
CharacterStatController.Bind( CharacterStatController.Bind(
layout, layout,
provider.BuildSheet, () => currentSheet,
_bindings.Assets.DefaultFont, _bindings.Assets.DefaultFont,
_bindings.Assets.ResolveFont(0x40000001u) ?? _bindings.Assets.DefaultFont, _bindings.Assets.ResolveFont(0x40000001u) ?? _bindings.Assets.DefaultFont,
_bindings.Assets.ResolveSprite, _bindings.Assets.ResolveSprite,
@ -1922,7 +1926,11 @@ public sealed class RetailUiRuntime : IDisposable
_shutdown ??= CreateShutdownTransaction( _shutdown ??= CreateShutdownTransaction(
() => _automation?.Dispose(), () => _automation?.Dispose(),
() => _persistence?.Dispose(), () => _persistence?.Dispose(),
() => Host.WindowManager.WindowVisibilityChanged -= OnWindowVisibilityChanged, () =>
{
_characterSheetSubscription?.Dispose();
Host.WindowManager.WindowVisibilityChanged -= OnWindowVisibilityChanged;
},
() => _itemConfirmationController?.Dispose(), () => _itemConfirmationController?.Dispose(),
() => _gameplayConfirmationController?.Dispose(), () => _gameplayConfirmationController?.Dispose(),
() => DialogFactory?.Dispose(), () => DialogFactory?.Dispose(),

View file

@ -1476,6 +1476,35 @@ public class CharacterStatControllerTests
Assert.Equal((" (+50)", buff), (runs[2].Text, runs[2].Color)); Assert.Equal((" (+50)", buff), (runs[2].Text, runs[2].Color));
} }
[Fact]
public void SkillRow_ValueAndColorFollowLiveSheetWithoutTabRebuild()
{
var list = new UiPanel { Width = 300 };
var layout = Fake((CharacterStatController.ListBoxId, list));
CharacterSheet sheet = VitaeSkillSheet(
currentLevel: 300,
baseLevel: 300,
vitaeModifier: 0);
CharacterStatController.Bind(
layout,
() => sheet,
spriteResolve: id => (id, 16, 16));
ClickTab(layout, left: 92f);
UiText value = SkillRows(list)[0].Children.OfType<UiText>().ToList()[2];
Assert.Equal("300", value.LinesProvider()[0].Text);
Assert.Equal(Vector4.One, value.LinesProvider()[0].Color);
sheet = VitaeSkillSheet(
currentLevel: 350,
baseLevel: 300,
vitaeModifier: 0);
Assert.Equal("350", value.LinesProvider()[0].Text);
Assert.Equal(new Vector4(0f, 1f, 0f, 1f), value.LinesProvider()[0].Color);
}
[Fact] [Fact]
public void SkillClick_ZeroDelta_NoParentheticals() public void SkillClick_ZeroDelta_NoParentheticals()
{ {