fix(chargen): Campaign CC gate round 1 Batch B — authored selection states, label state, zoom/swatch feedback
GF-1/GF-8: UiButton now recognizes retail's custom Unselected/Selected radio-pair (0x10000016/0x10000017), bypassing the standard Normal/ Highlight machine that never admitted those state names — .Selected now lights the heritage/template/gender/Face-Clothes rows it was always a no-op for. AP-222/GF-11b: per-state label color/outline (dat 0x1B/0x21) now applies off the REQUESTED retail state id, not the art-gated committed ActiveState — resolves the Appearance spins' current-part highlight (text recolors even though no Highlight art exists on either client) and the Town caption's Normal-to-white swap. GF-11c: UiButton.LabelBox lets a lifted caption with its own authored rect draw there instead of the face-relative offset that's only correct when the label is authored directly on the button (heritage/template family, unchanged). GF-9: wires the real nine companion overlay elements (SetColor's SetVisible mechanism) that swatch clicks were always meant to drive, retiring AP-215 item 1 (the swatch.Selected substitution was a permanent no-op — swatches author no Highlight media at all). GF-10: zoom buttons now set the retail-mirrored mutual-exclusive Highlight/Normal pair on click; InitializePage carries no initial SetState for either button, so both stay at "Normal" until first click. Register: AP-222 retired (mechanism identified and ported), AP-215 narrowed (item 1 retired, item 2 unrelated and unchanged), row count recount corrected 164 (was already one high before this batch). App suite 5282/3 (was 5266/3), Runtime 1735/0 unchanged. Fixture + live- DAT tests only — no graphical client launch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
1d9de5e095
commit
7d09821fdc
11 changed files with 1043 additions and 42 deletions
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using AcDream.App.UI;
|
||||
|
||||
|
|
@ -673,4 +674,65 @@ public static class ElementReader
|
|||
})
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AP-222 / GF-11b (Campaign CC gate round 1 Batch B): resolves a color
|
||||
/// property (0x1B FontColor's Array-tolerant shape, same unwrap as
|
||||
/// <see cref="ReadEffectiveColorPalette"/>) for EVERY state <paramref
|
||||
/// name="info"/> itself authors, keyed by retail numeric state id.
|
||||
/// Returns null unless at least two states resolve to GENUINELY
|
||||
/// DIFFERENT colors — the overwhelming majority of elements author one
|
||||
/// color for every state (or none at all), and for those this returns
|
||||
/// null so the caller keeps its existing single-default-color behavior
|
||||
/// untouched. Only elements that really do recolor per state (the
|
||||
/// Appearance spins' Highlight brightening, the Town buttons' Normal-
|
||||
/// to-white caption swap) get a non-null map.
|
||||
/// </summary>
|
||||
internal static IReadOnlyDictionary<uint, Vector4>? BuildPerStateColorMap(
|
||||
ElementInfo info, uint propertyId)
|
||||
{
|
||||
Dictionary<uint, Vector4>? map = null;
|
||||
foreach (uint stateId in info.States.Keys)
|
||||
{
|
||||
if (!info.TryGetEffectiveProperty(propertyId, out UiPropertyValue value, stateId))
|
||||
continue;
|
||||
|
||||
UiPropertyValue? colorValue = value.Kind == UiPropertyKind.Color
|
||||
? value
|
||||
: value.Kind == UiPropertyKind.Array
|
||||
&& value.ArrayValue.Count > 0
|
||||
&& value.ArrayValue[0].Kind == UiPropertyKind.Color
|
||||
? value.ArrayValue[0]
|
||||
: null;
|
||||
if (colorValue is null)
|
||||
continue;
|
||||
|
||||
UiColorValue c = colorValue.ColorValue;
|
||||
float alpha = c.Alpha == 0 ? 1f : c.Alpha / 255f;
|
||||
(map ??= new Dictionary<uint, Vector4>())[stateId] =
|
||||
new Vector4(c.Red / 255f, c.Green / 255f, c.Blue / 255f, alpha);
|
||||
}
|
||||
|
||||
return map is { Count: > 1 } && map.Values.Distinct().Count() > 1 ? map : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AP-222 counterpart of <see cref="BuildPerStateColorMap"/> for a bool
|
||||
/// property (0x21 Outline) — same "null unless genuinely per-state"
|
||||
/// gating.
|
||||
/// </summary>
|
||||
internal static IReadOnlyDictionary<uint, bool>? BuildPerStateBoolMap(
|
||||
ElementInfo info, uint propertyId)
|
||||
{
|
||||
Dictionary<uint, bool>? map = null;
|
||||
foreach (uint stateId in info.States.Keys)
|
||||
{
|
||||
if (!info.TryGetEffectiveProperty(propertyId, out UiPropertyValue value, stateId)
|
||||
|| value.Kind != UiPropertyKind.Bool)
|
||||
continue;
|
||||
(map ??= new Dictionary<uint, bool>())[stateId] = value.BoolValue;
|
||||
}
|
||||
|
||||
return map is { Count: > 1 } && map.Values.Distinct().Count() > 1 ? map : null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue