refactor(runtime): own magic and player state
Move the coupled Spellbook and LocalPlayerState into one Runtime-owned character graph, route content, live-session, retained UI, reset, and shutdown through that exact owner, and delete the duplicate desired-component snapshot from inventory state. Preserve synchronous retail update and reset ordering while adding independent-instance and retryable-failure coverage. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
d362172620
commit
d02a12ceac
16 changed files with 418 additions and 96 deletions
|
|
@ -12,6 +12,7 @@ using AcDream.Core.Physics;
|
|||
using AcDream.Core.Rendering;
|
||||
using AcDream.Core.Spells;
|
||||
using AcDream.Core.Vfx;
|
||||
using AcDream.Runtime.Gameplay;
|
||||
using DatReaderWriter;
|
||||
using Silk.NET.Input;
|
||||
using Silk.NET.OpenGL;
|
||||
|
|
@ -48,7 +49,7 @@ internal sealed record ContentEffectsAudioDependencies(
|
|||
ResidencyBudgetOptions ResidencyBudgets,
|
||||
PhysicsDataCache PhysicsDataCache,
|
||||
bool DumpMotionEnabled,
|
||||
Spellbook SpellBook,
|
||||
RuntimeCharacterState Character,
|
||||
AnimationHookRouter HookRouter,
|
||||
EntityEffectPoseRegistry EffectPoses,
|
||||
DeferredEntityEffectAdvanceSource EntityEffectAdvance,
|
||||
|
|
@ -85,7 +86,9 @@ internal interface IContentEffectsAudioCompositionFactory
|
|||
IDatReaderWriter dats,
|
||||
Action<string> diagnostic);
|
||||
MagicCatalog LoadMagicCatalog(IDatReaderWriter dats);
|
||||
void InstallSpellMetadata(Spellbook spellBook, MagicCatalog catalog);
|
||||
void InstallSpellMetadata(
|
||||
RuntimeCharacterState character,
|
||||
MagicCatalog catalog);
|
||||
int GetSpellCount(MagicCatalog catalog);
|
||||
IAnimationLoader CreateAnimationLoader(
|
||||
IDatReaderWriter dats,
|
||||
|
|
@ -143,8 +146,10 @@ internal sealed class RetailContentEffectsAudioCompositionFactory
|
|||
public MagicCatalog LoadMagicCatalog(IDatReaderWriter dats) =>
|
||||
MagicCatalog.Load(dats);
|
||||
|
||||
public void InstallSpellMetadata(Spellbook spellBook, MagicCatalog catalog) =>
|
||||
spellBook.InstallMetadata(catalog.SpellTable);
|
||||
public void InstallSpellMetadata(
|
||||
RuntimeCharacterState character,
|
||||
MagicCatalog catalog) =>
|
||||
character.InstallSpellMetadata(catalog.SpellTable);
|
||||
|
||||
public int GetSpellCount(MagicCatalog catalog) => catalog.SpellTable.Count;
|
||||
|
||||
|
|
@ -326,7 +331,7 @@ internal sealed class ContentEffectsAudioCompositionPhase :
|
|||
MagicCatalog magic = _factory.LoadMagicCatalog(dats);
|
||||
_publication.PublishMagicCatalog(magic);
|
||||
Fault(ContentEffectsAudioCompositionPoint.MagicCatalogPublished);
|
||||
_factory.InstallSpellMetadata(_dependencies.SpellBook, magic);
|
||||
_factory.InstallSpellMetadata(_dependencies.Character, magic);
|
||||
_dependencies.Log(
|
||||
$"spells: loaded {_factory.GetSpellCount(magic)} entries from portal.dat");
|
||||
Fault(ContentEffectsAudioCompositionPoint.SpellMetadataInstalled);
|
||||
|
|
|
|||
|
|
@ -48,9 +48,8 @@ internal sealed record InteractionRetainedUiDependencies(
|
|||
SelectionState Selection,
|
||||
RuntimeInventoryState Inventory,
|
||||
MagicCatalog MagicCatalog,
|
||||
Spellbook Spellbook,
|
||||
RuntimeCharacterState Character,
|
||||
RuntimeCommunicationState Communication,
|
||||
LocalPlayerState LocalPlayer,
|
||||
StackSplitQuantityState StackSplitQuantity,
|
||||
BufferedUiRegistry? UiRegistry,
|
||||
LiveCombatModeCommandSlot CombatModeCommands,
|
||||
|
|
@ -350,7 +349,7 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
try
|
||||
{
|
||||
VitalsVM vitals = d.ExistingVitals
|
||||
?? new VitalsVM(d.Combat, d.LocalPlayer);
|
||||
?? new VitalsVM(d.Combat, d.Character.LocalPlayer);
|
||||
UiHost host = lease.AcquireHost(
|
||||
() => new UiHost(
|
||||
d.Gl,
|
||||
|
|
@ -372,7 +371,7 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
|
||||
var characterSheet = new CharacterSheetProvider(
|
||||
d.Inventory.Objects,
|
||||
d.LocalPlayer,
|
||||
d.Character.LocalPlayer,
|
||||
playerGuid: () => d.PlayerIdentity.ServerGuid,
|
||||
activeToonName: () => d.Settings.ActiveToonKey,
|
||||
fallbackSheet: Studio.SampleData.SampleCharacter,
|
||||
|
|
@ -389,7 +388,7 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
|
||||
MagicRuntime magic = MagicRuntime.Create(
|
||||
d.MagicCatalog,
|
||||
d.Spellbook,
|
||||
d.Character.Spellbook,
|
||||
d.Inventory.Objects,
|
||||
selectedObject: () => d.Selection.SelectedObjectId,
|
||||
localPlayerId: () => d.PlayerIdentity.ServerGuid,
|
||||
|
|
@ -421,7 +420,7 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
|
||||
uint skillId = SkillId(school);
|
||||
if (skillId != 0u)
|
||||
return d.LocalPlayer.GetSkill(skillId)?.CurrentLevel ?? 0u;
|
||||
return d.Character.LocalPlayer.GetSkill(skillId)?.CurrentLevel ?? 0u;
|
||||
|
||||
uint highest = 0u;
|
||||
foreach (MagicSchool candidate in new[]
|
||||
|
|
@ -435,7 +434,8 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
{
|
||||
highest = Math.Max(
|
||||
highest,
|
||||
d.LocalPlayer.GetSkill(SkillId(candidate))?.CurrentLevel ?? 0u);
|
||||
d.Character.LocalPlayer.GetSkill(
|
||||
SkillId(candidate))?.CurrentLevel ?? 0u);
|
||||
}
|
||||
return highest;
|
||||
}
|
||||
|
|
@ -527,7 +527,7 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
() => d.Settings.Gameplay,
|
||||
d.Settings.SetCombatGameplay),
|
||||
Magic: new MagicRuntimeBindings(
|
||||
d.Spellbook,
|
||||
d.Character.Spellbook,
|
||||
magic.Casting,
|
||||
d.Inventory.Objects,
|
||||
() => d.PlayerIdentity.ServerGuid,
|
||||
|
|
@ -569,10 +569,10 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
late.Selection.ResolveVividTargetInfo,
|
||||
late.SelectionCamera.UiSnapshot),
|
||||
Indicators: new IndicatorRuntimeBindings(
|
||||
d.Spellbook,
|
||||
d.Character.Spellbook,
|
||||
d.Inventory.Objects,
|
||||
() => d.PlayerIdentity.ServerGuid,
|
||||
() => d.LocalPlayer.GetAttribute(
|
||||
() => d.Character.LocalPlayer.GetAttribute(
|
||||
LocalPlayerState.AttributeKind.Strength)
|
||||
is { } strength ? (int?)strength.Current : null,
|
||||
() => late.Session.LinkStatus,
|
||||
|
|
@ -614,7 +614,7 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
() => d.PlayerIdentity.ServerGuid,
|
||||
iconComposer.GetIcon,
|
||||
iconComposer.GetDragIcon,
|
||||
() => d.LocalPlayer.GetAttribute(
|
||||
() => d.Character.LocalPlayer.GetAttribute(
|
||||
LocalPlayerState.AttributeKind.Strength)
|
||||
is { } strength ? (int?)strength.Current : null,
|
||||
guid => late.Session.CurrentSession?.SendUse(guid),
|
||||
|
|
|
|||
|
|
@ -85,8 +85,7 @@ internal sealed record SessionPlayerDependencies(
|
|||
CombatState Combat,
|
||||
CombatFeedbackSlot CombatFeedback,
|
||||
RuntimeCommunicationState Communication,
|
||||
LocalPlayerState LocalPlayer,
|
||||
Spellbook Spellbook,
|
||||
RuntimeCharacterState Character,
|
||||
TransferableResourceSlot<PortalTunnelPresentation> PortalTunnelFallback,
|
||||
Action<string> Log);
|
||||
|
||||
|
|
@ -802,8 +801,7 @@ internal sealed class SessionPlayerCompositionPhase
|
|||
d.CharacterOptions),
|
||||
new LiveSessionDomainRuntime(
|
||||
d.EntityObjects,
|
||||
d.LocalPlayer,
|
||||
d.Spellbook,
|
||||
d.Character,
|
||||
d.Combat,
|
||||
d.Inventory,
|
||||
d.Communication),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue