fix(journal): the location readout is a FIELD, refresh at the click, and Abandon works
Three fixes from the first connected round. The location readout is authored EDITABLE (0x16), so it builds as a UiField — not the UiText its "00.0S, 00.0W" placeholder suggests. The controller resolved it as text, got null, and threw every write away in silence: Record reached the model and reached the FILE, and never reached the screen. That is exactly what was reported, and it is a whole class of bug, so the sweep that found it is now a test over every element all three controllers bind. The handlers mutated the model and left redrawing to the next frame's Tick. Retail's ListenToElementMessage @0x004968D0 ends every one of them in Update() instead — at the moment of the click. The deferred version happened to work in the client and made the behaviour untestable and a frame late; the notes-page tests I had not written until now fail against it. Abandon is wired. "Retail's abandon path is a contract-registry command we have not ported" was wrong — it is game action 0x0316 with a single contract id, and ACE replies with the 0x0315 delete QT3 already handles. Nothing is removed locally, so a refusal leaves the quest visibly intact rather than vanishing it optimistically and having it reappear on the next full table. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
0b27c5d0fe
commit
e35d9386e4
12 changed files with 556 additions and 16 deletions
|
|
@ -485,6 +485,55 @@ public sealed class JournalContractsPageControllerTests
|
|||
Assert.NotEqual(unselected.DefaultColor, selected.DefaultColor);
|
||||
}
|
||||
|
||||
// ── Abandon (game action 0x0316) ────────────────────────────────────
|
||||
|
||||
[Fact]
|
||||
public void AbandonSendsTheSelectedContractAndRemovesNothingLocally()
|
||||
{
|
||||
// The row disappears when the SERVER answers with its own 0x0315
|
||||
// delete. Removing it optimistically would vanish a quest the server
|
||||
// refused to drop, and it would reappear on the next full table.
|
||||
(UiElement page, _) = BuildPage();
|
||||
using var state = new RuntimeContractState();
|
||||
Track(state, 0x10u, stage: 2u);
|
||||
var abandoned = new List<uint>();
|
||||
|
||||
var controller = new JournalContractsPageController(
|
||||
page,
|
||||
new JournalContractsPageController.Bindings(
|
||||
Contracts: state.View,
|
||||
Catalog: () => Catalog(Entry(0x10u, "First")),
|
||||
Now: () => Now,
|
||||
TemplateResolver: RowTemplate,
|
||||
Abandon: abandoned.Add));
|
||||
|
||||
controller.AbandonSelected();
|
||||
|
||||
Assert.Equal(new[] { 0x10u }, abandoned.ToArray());
|
||||
Assert.Equal(1, state.View.Snapshot.ContractCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AbandonWithNothingSelectedSendsNothing()
|
||||
{
|
||||
(UiElement page, _) = BuildPage();
|
||||
using var state = new RuntimeContractState();
|
||||
var abandoned = new List<uint>();
|
||||
|
||||
var controller = new JournalContractsPageController(
|
||||
page,
|
||||
new JournalContractsPageController.Bindings(
|
||||
Contracts: state.View,
|
||||
Catalog: () => ContractCatalog.Empty,
|
||||
Now: () => Now,
|
||||
TemplateResolver: RowTemplate,
|
||||
Abandon: abandoned.Add));
|
||||
|
||||
controller.AbandonSelected();
|
||||
|
||||
Assert.Empty(abandoned);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AProgressCounterRendersThroughTheAuthoredFormat()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue