fix(combat): charge power bar from speed
Read the authored meter direction instead of inferring it from the combat element id, so the bright charge texture grows left-to-right from Speed. Keep the user-approved dark-red middle baseline visible independently and record its exact retail Recklessness visibility edge. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
256c1930bd
commit
707add8539
13 changed files with 50 additions and 49 deletions
|
|
@ -2135,8 +2135,7 @@ public sealed class GameWindow : IDisposable
|
|||
Combat,
|
||||
_combatAttackController,
|
||||
() => _persistedGameplay,
|
||||
SetRetailCombatGameplay,
|
||||
() => LocalPlayer.GetSkill(0x32u)?.Status >= 2u),
|
||||
SetRetailCombatGameplay),
|
||||
Toolbar: new AcDream.App.UI.ToolbarRuntimeBindings(
|
||||
Objects,
|
||||
() => Shortcuts,
|
||||
|
|
|
|||
|
|
@ -105,7 +105,6 @@ public static class FixtureProvider
|
|||
attacks,
|
||||
() => gameplay,
|
||||
value => gameplay = value,
|
||||
() => true,
|
||||
new CombatUiLabels(
|
||||
"Speed", "Power", "Repeat Attacks", "Auto Target", "Keep in View",
|
||||
"High", "Medium", "Low"),
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ public sealed class CombatUiController : IRetainedPanelController
|
|||
CombatAttackController attacks,
|
||||
Func<GameplaySettings> gameplay,
|
||||
Action<GameplaySettings> setGameplay,
|
||||
Func<bool> recklessnessTrained,
|
||||
CombatUiLabels labels,
|
||||
Action<bool> setWindowVisible)
|
||||
{
|
||||
|
|
@ -95,7 +94,6 @@ public sealed class CombatUiController : IRetainedPanelController
|
|||
_powerControl.SetScalarPosition(_attacks.DesiredPower);
|
||||
_powerControl.ScalarChanged = _attacks.SetDesiredPower;
|
||||
_powerControl.ScalarFill = () => _attacks.PowerBarLevel;
|
||||
_powerControl.ScalarRangeVisible = recklessnessTrained;
|
||||
|
||||
BindAttackButton(_high, AttackHeight.High);
|
||||
BindAttackButton(_medium, AttackHeight.Medium);
|
||||
|
|
@ -131,7 +129,6 @@ public sealed class CombatUiController : IRetainedPanelController
|
|||
CombatAttackController attacks,
|
||||
Func<GameplaySettings> gameplay,
|
||||
Action<GameplaySettings> setGameplay,
|
||||
Func<bool> recklessnessTrained,
|
||||
CombatUiLabels labels,
|
||||
Action<bool> setWindowVisible)
|
||||
{
|
||||
|
|
@ -140,7 +137,6 @@ public sealed class CombatUiController : IRetainedPanelController
|
|||
ArgumentNullException.ThrowIfNull(attacks);
|
||||
ArgumentNullException.ThrowIfNull(gameplay);
|
||||
ArgumentNullException.ThrowIfNull(setGameplay);
|
||||
ArgumentNullException.ThrowIfNull(recklessnessTrained);
|
||||
ArgumentNullException.ThrowIfNull(labels);
|
||||
ArgumentNullException.ThrowIfNull(setWindowVisible);
|
||||
|
||||
|
|
@ -158,8 +154,7 @@ public sealed class CombatUiController : IRetainedPanelController
|
|||
return new CombatUiController(
|
||||
layout, basic, advanced, power, high, medium, low,
|
||||
repeatAttacks, autoTarget, keepInView,
|
||||
combat, attacks, gameplay, setGameplay, recklessnessTrained,
|
||||
labels, setWindowVisible);
|
||||
combat, attacks, gameplay, setGameplay, labels, setWindowVisible);
|
||||
}
|
||||
|
||||
public void SyncVisibility() => OnCombatModeChanged(_combat.CurrentMode);
|
||||
|
|
@ -238,7 +233,6 @@ public sealed class CombatUiController : IRetainedPanelController
|
|||
_attacks.StateChanged -= OnAttackStateChanged;
|
||||
_powerControl.ScalarChanged = null;
|
||||
_powerControl.ScalarFill = () => null;
|
||||
_powerControl.ScalarRangeVisible = () => false;
|
||||
_high.OnPressed = null;
|
||||
_high.OnReleased = null;
|
||||
_medium.OnPressed = null;
|
||||
|
|
|
|||
|
|
@ -178,19 +178,22 @@ public static class DatWidgetFactory
|
|||
.FirstOrDefault();
|
||||
bar.ScalarFillSprite = fill is null ? 0u : DefaultImage(fill);
|
||||
|
||||
// gmCombatUI preserves a second authored meter child for the
|
||||
// trained-Recklessness range. The controller owns its visibility,
|
||||
// exactly like gmCombatUI::ListenToElementMessage @ 0x004CC430;
|
||||
// the widget only retains the media because it consumes DAT children.
|
||||
// gmCombatUI preserves a second authored meter child for its dark
|
||||
// red interior range. The widget retains the media because horizontal
|
||||
// scrollbars consume their DAT children.
|
||||
ElementInfo? scalarRange = meter?.Children.FirstOrDefault(
|
||||
child => child.Id == 0x100005EFu);
|
||||
bar.ScalarRangeSprite = scalarRange is null
|
||||
? 0u
|
||||
: DefaultImage(scalarRange);
|
||||
// gmCombatUI meter 0x10000050 grows from the Power end at the
|
||||
// right toward Speed at the left (retail screenshot oracle +
|
||||
// gmCombatUI::RecvNotice_SetPowerbarLevel 0x004CC0E0).
|
||||
bar.ScalarFillFromRight = meter?.Id == 0x10000050u;
|
||||
// UIElement_Meter::UIElement_Meter @ 0x0046F4C0 defaults direction
|
||||
// 1; DrawChildren @ 0x0046FBD0 clips that direction left-to-right.
|
||||
// Direction 3 is the horizontal reverse. Read authored attribute
|
||||
// 0x6F instead of inferring direction from the combat element id.
|
||||
bar.ScalarFillFromRight = meter is not null
|
||||
&& meter.TryGetEffectiveProperty(0x6Fu, out UiPropertyValue direction)
|
||||
&& direction.Kind == UiPropertyKind.Enum
|
||||
&& direction.UnsignedValue == 3u;
|
||||
return bar;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,8 +40,7 @@ public sealed record CombatRuntimeBindings(
|
|||
CombatState State,
|
||||
CombatAttackController Attacks,
|
||||
Func<GameplaySettings> Gameplay,
|
||||
Action<GameplaySettings> SetGameplay,
|
||||
Func<bool> RecklessnessTrained);
|
||||
Action<GameplaySettings> SetGameplay);
|
||||
|
||||
public sealed record ToolbarRuntimeBindings(
|
||||
ClientObjectTable Objects,
|
||||
|
|
@ -481,7 +480,6 @@ public sealed class RetailUiRuntime : IDisposable
|
|||
_bindings.Combat.Attacks,
|
||||
_bindings.Combat.Gameplay,
|
||||
_bindings.Combat.SetGameplay,
|
||||
_bindings.Combat.RecklessnessTrained,
|
||||
labels,
|
||||
visible =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,11 +42,10 @@ public sealed class UiScrollbar : UiElement
|
|||
public Func<float?> ScalarFill { get; set; } = () => null;
|
||||
public uint ScalarFillSprite { get; set; }
|
||||
/// <summary>
|
||||
/// Optional authored texture beneath the live scalar fill. gmCombatUI uses
|
||||
/// element <c>0x100005EF</c> for the trained-Recklessness range.
|
||||
/// Optional authored texture beneath the live scalar fill. gmCombatUI's
|
||||
/// dark-red interior media comes from element <c>0x100005EF</c>.
|
||||
/// </summary>
|
||||
public uint ScalarRangeSprite { get; set; }
|
||||
public Func<bool> ScalarRangeVisible { get; set; } = () => false;
|
||||
public float ScalarRangeLeft { get; set; }
|
||||
public float ScalarRangeWidth { get; set; } = float.PositiveInfinity;
|
||||
/// <summary>
|
||||
|
|
@ -139,7 +138,7 @@ public sealed class UiScrollbar : UiElement
|
|||
{
|
||||
DrawTiled(ctx, resolve, TrackSprite, 0f, 0f, Width, Height);
|
||||
(float rangeLeft, float rangeWidth) = ScalarRangeRect();
|
||||
if (ScalarRangeVisible() && ScalarRangeSprite != 0)
|
||||
if (ScalarRangeSprite != 0)
|
||||
DrawTiled(ctx, resolve, ScalarRangeSprite,
|
||||
rangeLeft, 0f, rangeWidth, Height);
|
||||
if (ScalarFill() is float fill && ScalarFillSprite != 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue