From fb9f21876240999347d846c94ca78340f05d6054 Mon Sep 17 00:00:00 2001 From: Terria-K Date: Fri, 26 Dec 2025 01:45:43 +0800 Subject: [PATCH 1/2] Add Name and Description for custom part types --- Nickel/Framework/Content/ContentManager.cs | 1 + Nickel/Framework/Content/PartManager.cs | 23 +++++++++++++++++-- .../Models/Content/PartTypeConfiguration.cs | 6 +++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Nickel/Framework/Content/ContentManager.cs b/Nickel/Framework/Content/ContentManager.cs index 383ef734..cde48705 100644 --- a/Nickel/Framework/Content/ContentManager.cs +++ b/Nickel/Framework/Content/ContentManager.cs @@ -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..e56d1703 100644 --- a/Nickel/Framework/Content/PartManager.cs +++ b/Nickel/Framework/Content/PartManager.cs @@ -33,7 +33,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) { @@ -71,8 +74,24 @@ public bool TryGetPartByUniqueName(string uniqueName, [MaybeNullWhen(false)] out return this.UniqueNameToPartInstanceEntry.TryGetValue(uniqueName, out var typedEntry); } - private static void Inject(PartTypeEntry entry) + internal void InjectLocalizations(string locale, Dictionary localizations) { + foreach (var entry in this.UniqueNameToPartTypeEntry.Values) + this.InjectLocalization(locale, localizations, entry); + } + + private void Inject(PartTypeEntry entry) + { + this.InjectLocalization(DB.currentLocale.locale, DB.currentLocale.strings, entry); + } + + private 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/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; } } From 260340222b794b71d80a09d91284fa3c7e3f1013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dola=C5=9B?= Date: Fri, 2 Jan 2026 14:24:43 +0100 Subject: [PATCH 2/2] Updated PR --- Nickel/Framework/Content/ContentManager.cs | 2 +- Nickel/Framework/Content/PartManager.cs | 45 ++++++++++++------- .../Implementations/Content/ModShips.cs | 3 ++ Nickel/Interfaces/Content/IModShips.cs | 7 +++ 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/Nickel/Framework/Content/ContentManager.cs b/Nickel/Framework/Content/ContentManager.cs index cde48705..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); diff --git a/Nickel/Framework/Content/PartManager.cs b/Nickel/Framework/Content/PartManager.cs index e56d1703..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) @@ -62,30 +67,36 @@ public IPartEntry RegisterPart(IModManifest owner, string name, PartConfiguratio return entry; } - public bool TryGetPartTypeByUniqueName(string uniqueName, [MaybeNullWhen(false)] out IPartTypeEntry entry) - { - entry = null; - return this.UniqueNameToPartTypeEntry.TryGetValue(uniqueName, out var typedEntry); - } - - public bool TryGetPartByUniqueName(string uniqueName, [MaybeNullWhen(false)] out IPartEntry entry) + public IPartTypeEntry? LookupPartTypeByUniqueName(string uniqueName) { - entry = null; - return this.UniqueNameToPartInstanceEntry.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; } internal void InjectLocalizations(string locale, Dictionary localizations) { foreach (var entry in this.UniqueNameToPartTypeEntry.Values) - this.InjectLocalization(locale, localizations, entry); + InjectLocalization(locale, localizations, entry); } - private void Inject(PartTypeEntry entry) - { - this.InjectLocalization(DB.currentLocale.locale, DB.currentLocale.strings, entry); - } + private static void Inject(PartTypeEntry entry) + => InjectLocalization(DB.currentLocale.locale, DB.currentLocale.strings, entry); - private void InjectLocalization(string locale, Dictionary localizations, PartTypeEntry entry) + private static void InjectLocalization(string locale, Dictionary localizations, PartTypeEntry entry) { var key = entry.PartType.Key(); if (entry.Configuration.Name.Localize(locale) is { } name) 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 . ///