feat(items): port retail external-container looting
Add the ClientUISystem ground-object lifecycle, authoritative root and nested ViewContents projections, replacement and close semantics, and the DAT-authored gmExternalContainerUI strip for chests and corpses. Route double-click loot and full or partial drag transfers through the shared retail item policy without optimistic external ownership. Remove the incorrect NoLongerViewingContents behavior from owned side packs and retire AP-106/#196. Release build succeeds and all 5,875 tests pass with five intentional skips. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
48a118db91
commit
20ce67b625
27 changed files with 1750 additions and 45 deletions
|
|
@ -141,6 +141,11 @@ public sealed class UiScrollbar : UiElement
|
|||
if (SpriteResolve is not { } resolve) return;
|
||||
if (Horizontal)
|
||||
{
|
||||
if (ScalarChanged is null && Model is { } horizontalModel)
|
||||
{
|
||||
DrawHorizontalModel(ctx, resolve, horizontalModel);
|
||||
return;
|
||||
}
|
||||
DrawTiled(ctx, resolve, TrackSprite, 0f, 0f, Width, Height);
|
||||
(float rangeLeft, float rangeWidth) = ScalarRangeRect();
|
||||
if (ScalarRangeSprite != 0)
|
||||
|
|
@ -196,6 +201,31 @@ public sealed class UiScrollbar : UiElement
|
|||
}
|
||||
}
|
||||
|
||||
private void DrawHorizontalModel(
|
||||
UiRenderContext ctx,
|
||||
Func<uint, (uint tex, int w, int h)> resolve,
|
||||
UiScrollable model)
|
||||
{
|
||||
DrawTiled(ctx, resolve, TrackSprite, 0f, 0f, Width, Height);
|
||||
DrawSprite(ctx, resolve, UpSprite, 0f, 0f, ButtonH, Height);
|
||||
DrawSprite(ctx, resolve, DownSprite, Width - ButtonH, 0f, ButtonH, Height);
|
||||
if (!model.HasOverflow) return;
|
||||
|
||||
float trackLeft = ButtonH;
|
||||
float trackLength = MathF.Max(0f, Width - 2f * ButtonH);
|
||||
var (tx, tw) = ThumbRect(model, trackLeft, trackLength);
|
||||
if (ThumbTopSprite != 0 && ThumbBotSprite != 0 && tw >= 2f * CapH)
|
||||
{
|
||||
DrawSprite(ctx, resolve, ThumbTopSprite, tx, 0f, CapH, Height);
|
||||
DrawTiled(ctx, resolve, ThumbSprite, tx + CapH, 0f, tw - 2f * CapH, Height);
|
||||
DrawSprite(ctx, resolve, ThumbBotSprite, tx + tw - CapH, 0f, CapH, Height);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTiled(ctx, resolve, ThumbSprite, tx, 0f, tw, Height);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Draw a sprite stretched 1:1 to the dest rect.</summary>
|
||||
private void DrawSprite(UiRenderContext ctx, Func<uint, (uint tex, int w, int h)> resolve,
|
||||
uint id, float x, float y, float w, float h)
|
||||
|
|
@ -263,6 +293,9 @@ public sealed class UiScrollbar : UiElement
|
|||
if (Horizontal && ScalarChanged is not null)
|
||||
return OnScalarEvent(e);
|
||||
|
||||
if (Horizontal && Model is not null)
|
||||
return OnHorizontalModelEvent(e);
|
||||
|
||||
if (Model is not { } m) return false;
|
||||
|
||||
switch (e.Type)
|
||||
|
|
@ -318,6 +351,50 @@ public sealed class UiScrollbar : UiElement
|
|||
return false;
|
||||
}
|
||||
|
||||
private bool OnHorizontalModelEvent(in UiEvent e)
|
||||
{
|
||||
UiScrollable m = Model!;
|
||||
switch (e.Type)
|
||||
{
|
||||
case UiEventType.MouseDown:
|
||||
{
|
||||
float x = e.Data1;
|
||||
if (x <= ButtonH) { m.ScrollByLines(-1); return true; }
|
||||
if (x >= Width - ButtonH) { m.ScrollByLines(1); return true; }
|
||||
|
||||
float trackLeft = ButtonH;
|
||||
float trackLength = MathF.Max(0f, Width - 2f * ButtonH);
|
||||
var (tx, tw) = ThumbRect(m, trackLeft, trackLength);
|
||||
if (x >= tx && x <= tx + tw)
|
||||
{
|
||||
_draggingThumb = true;
|
||||
_dragOffsetX = x - tx;
|
||||
}
|
||||
else
|
||||
{
|
||||
m.ScrollByPage(x < tx ? -1 : 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
case UiEventType.MouseMove when _draggingThumb:
|
||||
{
|
||||
float trackLeft = ButtonH;
|
||||
float trackLength = MathF.Max(0f, Width - 2f * ButtonH);
|
||||
float thumbWidth = MathF.Max(MinThumb, trackLength * m.ThumbRatio);
|
||||
float travel = MathF.Max(1f, trackLength - thumbWidth);
|
||||
float ratio = ((float)e.Data1 - _dragOffsetX - trackLeft) / travel;
|
||||
m.SetPositionRatio(ratio);
|
||||
return true;
|
||||
}
|
||||
|
||||
case UiEventType.MouseUp:
|
||||
_draggingThumb = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool OnScalarEvent(in UiEvent e)
|
||||
{
|
||||
switch (e.Type)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue