feat(runtime): FA2 -- RuntimeFellowshipState + RuntimeAllegianceState sibling J-owners
Two new sibling Runtime owners under GameRuntime per the Slice-J pattern (D2): RuntimeFellowshipState is session-scoped (a new RuntimeGenerationResetStage.Fellowship clears it at every generation reset, matching the ExternalContainer precedent); RuntimeAllegianceState survives reconnect behind a HasServerSeed-style one-way latch and participates in NO reset stage (its data persists like a real disconnect does not sever allegiance membership). Fellowship: full-update REPLACE, incremental-fellow UPSERT, self-vs- other quit/dismiss removal (self clears the whole snapshot), disband clear, and retail's leader hand-off rule for the Quit button (RequiresLeaderHandoffBeforeQuit -- the current leader quitting WITHOUT disbanding must send 0x0290 AssignNewLeader before 0x00A3, lane B §2.5/§3.6). Allegiance: seeded by AllegianceUpdate (0x0020, always self) and, self-gated on TargetGuid == playerGuid(), by AllegianceInfoResponse (0x027C); wraps the FA1-assembled flat AllegianceMemberRecord list directly (AllegianceTree was deleted at FA1 -- nothing left to wrap). Both apply the full 8-edit J-owner template: construction + fault points + Owner/View properties + CaptureOwnership + a new GameRuntimeTeardownStage pair (FellowshipDisposed/AllegianceDisposed, stage count 11->13) + RuntimeGameplayOwnershipSnapshot inclusion + RuntimeStateCheckpoint/trace fields. IRuntimeFellowshipCommands/ IRuntimeAllegianceCommands added to IGameRuntimeCommands and implemented on DirectGameRuntimeCommandAdapter. No IRuntimeEventObserver member added (D2) -- consumers poll Snapshot.Revision. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
1c40104896
commit
369729f06a
19 changed files with 1949 additions and 35 deletions
|
|
@ -299,6 +299,76 @@ public interface IRuntimeSocialCommands
|
|||
in RuntimeSquelchCommand command);
|
||||
}
|
||||
|
||||
// ── Fellowship / Allegiance (Campaign FA slice FA2, 2026-08-12) ────────────
|
||||
|
||||
/// <summary>
|
||||
/// Generation-gated fellowship outbound actions. <see cref="Quit"/>
|
||||
/// implements retail's leader hand-off rule itself (lane B §2.5/§3.6): the
|
||||
/// current leader quitting WITHOUT disbanding sends <c>0x0290</c> (assign
|
||||
/// a non-leader fellow) BEFORE <c>0x00A3</c> — see
|
||||
/// <c>RuntimeFellowshipState.RequiresLeaderHandoffBeforeQuit</c>.
|
||||
/// <see cref="SetPanelOpen"/> is D4's <c>0x00A6</c> panel-visibility
|
||||
/// declaration, the command the fellowship page's show/hide seam calls
|
||||
/// (FA3+); without it ACE freezes the roster's vitals stream at join.
|
||||
/// </summary>
|
||||
public interface IRuntimeFellowshipCommands
|
||||
{
|
||||
RuntimeCommandResult Create(
|
||||
RuntimeGenerationToken expectedGeneration,
|
||||
string fellowshipName,
|
||||
bool shareXp);
|
||||
|
||||
RuntimeCommandResult Recruit(
|
||||
RuntimeGenerationToken expectedGeneration,
|
||||
uint targetGuid);
|
||||
|
||||
RuntimeCommandResult Dismiss(
|
||||
RuntimeGenerationToken expectedGeneration,
|
||||
uint targetGuid);
|
||||
|
||||
RuntimeCommandResult Quit(
|
||||
RuntimeGenerationToken expectedGeneration,
|
||||
bool disband);
|
||||
|
||||
RuntimeCommandResult AssignLeader(
|
||||
RuntimeGenerationToken expectedGeneration,
|
||||
uint newLeaderGuid);
|
||||
|
||||
RuntimeCommandResult SetOpen(
|
||||
RuntimeGenerationToken expectedGeneration,
|
||||
bool isOpen);
|
||||
|
||||
RuntimeCommandResult SetPanelOpen(
|
||||
RuntimeGenerationToken expectedGeneration,
|
||||
bool panelOpen);
|
||||
}
|
||||
|
||||
/// <summary>Generation-gated allegiance outbound actions.</summary>
|
||||
public interface IRuntimeAllegianceCommands
|
||||
{
|
||||
RuntimeCommandResult Swear(
|
||||
RuntimeGenerationToken expectedGeneration,
|
||||
uint patronGuid);
|
||||
|
||||
RuntimeCommandResult Break(
|
||||
RuntimeGenerationToken expectedGeneration,
|
||||
uint targetGuid);
|
||||
|
||||
RuntimeCommandResult Kick(
|
||||
RuntimeGenerationToken expectedGeneration,
|
||||
uint vassalGuid);
|
||||
|
||||
/// <summary><c>0x027B</c> — empty name queries self.</summary>
|
||||
RuntimeCommandResult RequestInfo(
|
||||
RuntimeGenerationToken expectedGeneration,
|
||||
string playerName);
|
||||
|
||||
/// <summary><c>0x001F</c> — the allegiance panel's subscribe/unsubscribe toggle.</summary>
|
||||
RuntimeCommandResult SetUpdateSubscription(
|
||||
RuntimeGenerationToken expectedGeneration,
|
||||
bool on);
|
||||
}
|
||||
|
||||
public interface IGameRuntimeCommands
|
||||
{
|
||||
IRuntimeSessionCommands Session { get; }
|
||||
|
|
@ -322,4 +392,8 @@ public interface IGameRuntimeCommands
|
|||
IRuntimeCharacterCommands Character { get; }
|
||||
|
||||
IRuntimeSocialCommands Social { get; }
|
||||
|
||||
IRuntimeFellowshipCommands Fellowship { get; }
|
||||
|
||||
IRuntimeAllegianceCommands Allegiance { get; }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue