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
|
|
@ -108,3 +108,87 @@ public interface IRuntimeSocialView
|
|||
|
||||
bool TryGetFriend(uint characterId, out RuntimeFriendSnapshot friend);
|
||||
}
|
||||
|
||||
// ── Fellowship / Allegiance (Campaign FA slice FA2, 2026-08-12) ────────────
|
||||
// D2: two sibling J-owners, session-scoped Fellowship vs reconnect-surviving
|
||||
// Allegiance (docs/research/2026-08-11-fa-acdream-seams.md §1.3). Consumers
|
||||
// poll Snapshot.Revision — no IRuntimeEventObserver member is added (would
|
||||
// break all 5 bot policies + the trace recorder, per the same doc §1.3).
|
||||
|
||||
public readonly record struct RuntimeFellowMemberSnapshot(
|
||||
uint Guid,
|
||||
string Name,
|
||||
uint Level,
|
||||
uint MaxHealth,
|
||||
uint MaxStamina,
|
||||
uint MaxMana,
|
||||
uint CurrentHealth,
|
||||
uint CurrentStamina,
|
||||
uint CurrentMana,
|
||||
bool ShareLoot);
|
||||
|
||||
public readonly record struct RuntimeFellowshipSnapshot(
|
||||
long Revision,
|
||||
bool IsInFellowship,
|
||||
string Name,
|
||||
uint LeaderGuid,
|
||||
bool ShareXp,
|
||||
bool EvenXpSplit,
|
||||
bool IsOpen,
|
||||
bool Locked,
|
||||
int MemberCount);
|
||||
|
||||
public interface IRuntimeFellowshipView
|
||||
{
|
||||
RuntimeFellowshipSnapshot Snapshot { get; }
|
||||
|
||||
bool TryGetMember(uint guid, out RuntimeFellowMemberSnapshot member);
|
||||
}
|
||||
|
||||
public readonly record struct RuntimeAllegianceMemberSnapshot(
|
||||
uint CharacterId,
|
||||
uint ParentGuid,
|
||||
bool IsLoggedIn,
|
||||
string Name,
|
||||
ushort Rank,
|
||||
uint Level,
|
||||
ushort Loyalty,
|
||||
ushort Leadership,
|
||||
uint CpCached,
|
||||
uint CpTithed,
|
||||
byte Gender,
|
||||
byte HeritageGroup,
|
||||
bool MayPassupExperience);
|
||||
|
||||
public readonly record struct RuntimeAllegianceSnapshot(
|
||||
long Revision,
|
||||
bool HasServerSeed,
|
||||
bool HasProfile,
|
||||
uint Rank,
|
||||
uint TotalMembers,
|
||||
uint TotalVassals,
|
||||
string AllegianceName,
|
||||
uint MonarchGuid,
|
||||
int RecordCount)
|
||||
{
|
||||
public bool HasMonarch => MonarchGuid != 0u;
|
||||
}
|
||||
|
||||
public interface IRuntimeAllegianceView
|
||||
{
|
||||
RuntimeAllegianceSnapshot Snapshot { get; }
|
||||
|
||||
bool TryGetMonarch(out RuntimeAllegianceMemberSnapshot monarch);
|
||||
|
||||
bool TryGetMember(uint guid, out RuntimeAllegianceMemberSnapshot member);
|
||||
|
||||
bool TryGetPatron(uint guid, out RuntimeAllegianceMemberSnapshot patron);
|
||||
|
||||
/// <summary>
|
||||
/// Port of retail's <c>GetFirstVassal</c>/<c>GetNextVassal</c> walk —
|
||||
/// reverse wire order, exactly like <c>AllegianceProfileLookups.
|
||||
/// FindVassals</c> (lane C §4.4 point 3;
|
||||
/// <c>ClientCommandResponses.cs:280-294</c>).
|
||||
/// </summary>
|
||||
IEnumerable<RuntimeAllegianceMemberSnapshot> GetVassals(uint guid);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue