diff --git a/Nickel/Framework/Content/ContentManager.cs b/Nickel/Framework/Content/ContentManager.cs index 383ef734..d60fe414 100644 --- a/Nickel/Framework/Content/ContentManager.cs +++ b/Nickel/Framework/Content/ContentManager.cs @@ -63,7 +63,7 @@ IModDataHandler modDataHandler var cards = new CardManager(currentModLoadPhaseProvider, loggerProvider, vanillaModManifest); var artifacts = new ArtifactManager(currentModLoadPhaseProvider, loggerProvider, vanillaModManifest); var characters = new CharacterManager(currentModLoadPhaseProvider, loggerProvider, eventManager, sprites, audio, decks, statuses, cards, vanillaModManifest, modLoaderModManifest); - var parts = new PartManager(enumCasePool, currentModLoadPhaseProvider); + var parts = new PartManager(enumCasePool, currentModLoadPhaseProvider, vanillaModManifest); var ships = new ShipManager(currentModLoadPhaseProvider, vanillaModManifest); var cardTraits = new CardTraitManager(loggerProvider, vanillaModManifest, modLoaderModManifest, modDataHandler); var enemies = new EnemyManager(currentModLoadPhaseProvider, loggerProvider, vanillaModManifest); @@ -90,6 +90,7 @@ internal void InjectLocalizations(string locale, Dictionary loca this.Cards.InjectLocalizations(locale, localizations); this.Artifacts.InjectLocalizations(locale, localizations); this.Characters.InjectLocalizations(locale, localizations); + this.Parts.InjectLocalizations(locale, localizations); this.Ships.InjectLocalizations(locale, localizations); this.Enemies.InjectLocalizations(locale, localizations); } diff --git a/Nickel/Framework/Content/PartManager.cs b/Nickel/Framework/Content/PartManager.cs index 5066ba5f..d81dfd51 100644 --- a/Nickel/Framework/Content/PartManager.cs +++ b/Nickel/Framework/Content/PartManager.cs @@ -1,24 +1,29 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; namespace Nickel; internal sealed class PartManager { + private readonly IModManifest VanillaModManifest; private readonly AfterDbInitManager PartTypeManager; private readonly AfterDbInitManager PartInstanceManager; private readonly EnumCasePool EnumCasePool; private readonly Dictionary UniqueNameToPartTypeEntry = []; private readonly Dictionary UniqueNameToPartInstanceEntry = []; + private readonly Dictionary VanillaPartTypes; - public PartManager(EnumCasePool enumCasePool, Func currentModLoadPhaseProvider) + public PartManager(EnumCasePool enumCasePool, Func currentModLoadPhaseProvider, IModManifest vanillaModManifest) { + this.VanillaModManifest = vanillaModManifest; this.PartTypeManager = new(currentModLoadPhaseProvider, Inject); this.PartInstanceManager = new(currentModLoadPhaseProvider, Inject); this.EnumCasePool = enumCasePool; + ArtifactRewardPatches.OnGetBlockedArtifacts += this.OnGetBlockedArtifacts; + + this.VanillaPartTypes = Enum.GetValues().ToDictionary(v => Enum.GetName(v)!, v => v); } private void OnGetBlockedArtifacts(object? _, ArtifactRewardPatches.GetBlockedArtifactsEventArgs e) @@ -33,7 +38,10 @@ private void OnGetBlockedArtifacts(object? _, ArtifactRewardPatches.GetBlockedAr } internal void InjectQueuedEntries() - => this.PartInstanceManager.InjectQueuedEntries(); + { + this.PartInstanceManager.InjectQueuedEntries(); + this.PartTypeManager.InjectQueuedEntries(); + } public IPartTypeEntry RegisterPartType(IModManifest owner, string name, PartTypeConfiguration configuration) { @@ -59,20 +67,42 @@ public IPartEntry RegisterPart(IModManifest owner, string name, PartConfiguratio return entry; } - public bool TryGetPartTypeByUniqueName(string uniqueName, [MaybeNullWhen(false)] out IPartTypeEntry entry) + public IPartTypeEntry? LookupPartTypeByUniqueName(string uniqueName) { - entry = null; - return this.UniqueNameToPartTypeEntry.TryGetValue(uniqueName, out var typedEntry); + if (this.UniqueNameToPartTypeEntry.TryGetValue(uniqueName, out var entry)) + return entry; + + if (this.VanillaPartTypes.TryGetValue(uniqueName, out var partType)) + { + entry = new PartTypeEntry(this.VanillaModManifest, uniqueName, partType, new() + { + Name = _ => Loc.T($"part.{uniqueName}.name"), + Description = _ => Loc.T($"part.{uniqueName}.desc"), + }); + + this.UniqueNameToPartTypeEntry[uniqueName] = entry; + return entry; + } + + return null; } - public bool TryGetPartByUniqueName(string uniqueName, [MaybeNullWhen(false)] out IPartEntry entry) + internal void InjectLocalizations(string locale, Dictionary localizations) { - entry = null; - return this.UniqueNameToPartInstanceEntry.TryGetValue(uniqueName, out var typedEntry); + foreach (var entry in this.UniqueNameToPartTypeEntry.Values) + InjectLocalization(locale, localizations, entry); } private static void Inject(PartTypeEntry entry) - { + => InjectLocalization(DB.currentLocale.locale, DB.currentLocale.strings, entry); + + private static void InjectLocalization(string locale, Dictionary localizations, PartTypeEntry entry) + { + var key = entry.PartType.Key(); + if (entry.Configuration.Name.Localize(locale) is { } name) + localizations[$"part.{key}.name"] = name; + if (entry.Configuration.Description.Localize(locale) is { } description) + localizations[$"part.{key}.desc"] = description; } private static void Inject(PartEntry entry) diff --git a/Nickel/Framework/Implementations/Content/ModShips.cs b/Nickel/Framework/Implementations/Content/ModShips.cs index 5f1cfc08..e8142ec2 100644 --- a/Nickel/Framework/Implementations/Content/ModShips.cs +++ b/Nickel/Framework/Implementations/Content/ModShips.cs @@ -25,6 +25,9 @@ public IReadOnlyDictionary RegisteredParts public IShipEntry? LookupByUniqueName(string uniqueName) => shipManagerProvider().LookupByUniqueName(uniqueName); + public IPartTypeEntry? LookupPartTypeByUniqueName(string uniqueName) + => partManagerProvider().LookupPartTypeByUniqueName(uniqueName); + public IShipEntry RegisterShip(string name, ShipConfiguration configuration) { var entry = shipManagerProvider().RegisterShip(modManifest, name, configuration); diff --git a/Nickel/Interfaces/Content/IModShips.cs b/Nickel/Interfaces/Content/IModShips.cs index 966beb73..450eb387 100644 --- a/Nickel/Interfaces/Content/IModShips.cs +++ b/Nickel/Interfaces/Content/IModShips.cs @@ -30,6 +30,13 @@ public interface IModShips /// An entry, or null if the unique name does not match any known ships. IShipEntry? LookupByUniqueName(string uniqueName); + /// + /// Lookup a ship part type () entry by its full . + /// + /// The unique name to retrieve an entry for. + /// An entry, or null if the unique name does not match any known part types. + IPartTypeEntry? LookupPartTypeByUniqueName(string uniqueName); + /// /// Register a new . /// diff --git a/Nickel/Models/Content/PartTypeConfiguration.cs b/Nickel/Models/Content/PartTypeConfiguration.cs index 1d71edf3..4f80f6c2 100644 --- a/Nickel/Models/Content/PartTypeConfiguration.cs +++ b/Nickel/Models/Content/PartTypeConfiguration.cs @@ -8,6 +8,12 @@ namespace Nickel; /// public readonly struct PartTypeConfiguration { + /// A localization provider for the name of the . + public SingleLocalizationProvider? Name { get; init; } + + /// A localization provider for the description of the . + public SingleLocalizationProvider? Description { get; init; } + /// The artifact types exclusive to this part type. public IReadOnlySet? ExclusiveArtifactTypes { get; init; } }