using Cthangover.Core.Bootstrap;
using Cthangover.Core.Characters;
using Cthangover.Core.Factories;
using Cthangover.Core.Factories.Impls;
using Cthangover.Core.Mods;
using Cthangover.Core.Settings;
using Cthangover.Core.Utils;
namespace Cthangover.Mods.Characters
{
///
/// Engine-mod initializer for the characters subsystem. Publishes the
/// factories living in this assembly to the kernel contracts
/// (,
/// , )
/// as soon as the assembly is registered, so core-side consumers —
/// CharacterData, inventory and skills UI, dialog avatar lookups —
/// resolve templates without referencing a runtime-compiled mod assembly.
///
/// Registration happens in (the earliest and
/// most frequent initializer callback) rather than on resources-ready:
/// CharacterData.AddCharacterToParty is called from other mods'
/// OnModResourcesReady (starter party), and initializer callbacks
/// are delivered per mod registration, so being first here removes any
/// ordering dependency between mods. The factories themselves only
/// collect entity data lazily on the first Get, after the mod
/// registry is finalized. Registration is guarded and idempotent because
/// ModManager.Reload() re-runs OnModLoaded for every mod.
///
public class CharactersModInitializer : IModInitializer
{
private static bool registered;
/// Publishes this mod's factories to the kernel registries; safe to call again after a mod reload.
public void OnModLoaded(string modId)
{
if (registered)
return;
registered = true;
CharacterTemplateRegistry.Provider = CharacterFactory.Instance;
ActionTemplateRegistry.Provider = ActionCharacterFactory.Instance;
AvatarProviderRegistry.Provider = AvatarFactory.Instance;
GameLogger.Log("MODS", "CharactersModInitializer: template providers registered (character, action, avatar)");
}
///
/// Registers the new-game roster reset owner with AppServices
/// (idempotent — duplicates by Id are ignored). Template collection
/// stays lazy on first lookup. Persistence needs no setup here:
/// is an IModSaveable
/// discovered by ModSaveableRegistry automatically.
///
public void OnModResourcesReady()
{
AppServices.Current.RegisterResettable(new CharactersResettable());
}
}
///
/// New-game state owner of the characters mod: clears the party roster
/// and battle set. Today the roster dies implicitly with
/// GameData.ResetRuntime (it lives inside RuntimeData),
/// which runs before the reset loop, so this reset is a no-op in the
/// normal pipeline; it stays correct if the roster ever moves to
/// mod-owned static storage (the recruiting path) or if the reset loop
/// runs standalone, and makes the characters mod an explicit new-game
/// state owner like quests and recruiting. Registered from
/// ;
/// deduplicates by .
///
internal sealed class CharactersResettable : IResettable
{
/// Resettable key under which AppServices deduplicates registration.
public string Id => "characters";
/// Clears the party roster and battle set on "New Game".
public void ResetForNewGame()
{
var characterData = GameData.Instance.Runtime.CharacterData;
characterData.Characters.Clear();
characterData.BattleSet.Clear();
}
}
}