using AcDream.Runtime.Gameplay;
namespace AcDream.Runtime;
public readonly record struct RuntimePendingInventoryRequestSnapshot(
ulong Token,
int Kind,
uint ItemId,
bool Dispatched);
public readonly record struct RuntimeInventoryStateSnapshot(
uint RequestedExternalContainerId,
uint CurrentExternalContainerId,
int BusyCount,
bool CanBeginRequest,
RuntimePendingInventoryRequestSnapshot? PendingRequest,
int ShortcutCount,
long ShortcutRevision,
int ItemManaCount,
long ItemManaRevision);
public readonly record struct RuntimeShortcutSnapshot(
int Index,
uint ObjectId,
uint SpellId);
public interface IRuntimeInventoryStateView
{
RuntimeInventoryStateSnapshot Snapshot { get; }
bool TryGetShortcut(int index, out RuntimeShortcutSnapshot shortcut);
bool TryGetItemMana(uint objectId, out float fraction);
}
public readonly record struct RuntimeCharacterSnapshot(
long CharacterRevision,
long SpellbookRevision,
RuntimeCharacterOptionsSnapshot Options,
RuntimeMovementSkillSnapshot MovementSkills,
int LearnedSpellCount,
int ActiveEnchantmentCount,
int DesiredComponentCount,
int SkillCount,
uint SpellbookFilters);
public readonly record struct RuntimeVitalSnapshot(
int Kind,
uint Ranks,
uint Start,
uint Experience,
uint Current,
uint Maximum);
public readonly record struct RuntimeAttributeSnapshot(
int Kind,
uint Ranks,
uint Start,
uint Experience,
uint Current);
public readonly record struct RuntimeSkillSnapshot(
uint SkillId,
uint Ranks,
uint Status,
uint Experience,
uint Initial,
uint Resistance,
double LastUsed,
uint FormulaBonus,
uint CurrentLevel);
public interface IRuntimeCharacterView
{
RuntimeCharacterSnapshot Snapshot { get; }
bool TryGetVital(int kind, out RuntimeVitalSnapshot vital);
bool TryGetAttribute(int kind, out RuntimeAttributeSnapshot attribute);
bool TryGetSkill(uint skillId, out RuntimeSkillSnapshot skill);
bool KnowsSpell(uint spellId);
bool TryGetFavorite(int tabIndex, int position, out uint spellId);
bool TryGetDesiredComponent(uint componentId, out uint amount);
}
public readonly record struct RuntimeSocialSnapshot(
long FriendsRevision,
int FriendCount,
long SquelchRevision,
int SquelchedAccountCount,
int SquelchedCharacterCount,
int GlobalSquelchTypeCount,
int NegotiatedChatRoomCount);
public readonly record struct RuntimeFriendSnapshot(
uint Id,
string Name,
bool Online,
bool AppearOffline);
public interface IRuntimeSocialView
{
RuntimeSocialSnapshot Snapshot { get; }
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)
{
// FA2 fix-round SHOULD-FIX 6 (blast review): an explicit parameterless
// constructor gives `new()` (used as RuntimeStateCheckpoint's default,
// GameRuntimeViews.cs) a non-null Name instead of `default`'s bitwise
// zero-init (structs never run field initializers or this constructor
// for `default(T)` — only `new S()` invokes it).
public RuntimeFellowshipSnapshot()
: this(0, false, string.Empty, 0u, false, false, false, false, 0)
{
}
}
public interface IRuntimeFellowshipView
{
RuntimeFellowshipSnapshot Snapshot { get; }
bool TryGetMember(uint guid, out RuntimeFellowMemberSnapshot member);
///
/// Campaign FA slice FA4: the complete member roster, for the
/// fellowship page's row-per-fellow list.
/// alone cannot build a roster — it needs the guid first. Order is
/// insertion order (the last 0x02BE FellowshipFullUpdate's
/// wire order, then whatever order incremental 0x02C0 upserts
/// added new members) — retail's own hash-table iteration order is not
/// a stable contract either (lane B §3.9), so no ordering guarantee
/// beyond "stable across repeated calls between mutations" is made.
///
IEnumerable GetMembers();
}
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;
// FA2 fix-round SHOULD-FIX 6 (blast review): see
// RuntimeFellowshipSnapshot's parameterless constructor — same
// non-null-default reasoning, for AllegianceName.
public RuntimeAllegianceSnapshot()
: this(0, false, false, 0u, 0u, 0u, string.Empty, 0u, 0)
{
}
}
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);
///
/// Port of retail's GetFirstVassal/GetNextVassal walk —
/// reverse wire order, exactly like AllegianceProfileLookups.
/// FindVassals (lane C §4.4 point 3;
/// ClientCommandResponses.cs:280-294).
///
IEnumerable GetVassals(uint guid);
}