diff --git a/1.6/Source/DefCache.cs b/1.6/Source/DefCache.cs index cba233d..572c8ca 100644 --- a/1.6/Source/DefCache.cs +++ b/1.6/Source/DefCache.cs @@ -11,7 +11,7 @@ namespace FactionLoadout; /// /// Lazily populated caches of def lists used throughout the editor UI. /// Call once (guarded by a null-check) before accessing any list. -/// that are needed by multiple draw-support classes. +/// Needed for multiple draw-support classes. /// public static class DefCache { @@ -27,6 +27,7 @@ public static class DefCache public static List AllAnimalKindDefs; public static List AllRulePackDefs; public static List AllGeneDefs; + public static Dictionary> DefaultFactionKinds; public static List AllBackstoryCategories; public static List AllChildhoodBackstories; @@ -55,12 +56,26 @@ public static void ScanDefs() HashSet allBodyTypeDefs = new(32); HashSet allGeneDefs = new(1024); + Dictionary> defaultFactionKinds = new(64); + foreach (PawnKindDef def in DefDatabase.AllDefsListForReading) { if (def.RaceProps is { Animal: true, packAnimal: true }) allAnimalKindDefs.Add(def); + + if (def.defaultFactionDef != null) + { + if (!defaultFactionKinds.TryGetValue(def.defaultFactionDef, out List factionKinds)) + { + factionKinds = []; + defaultFactionKinds[def.defaultFactionDef] = factionKinds; + } + factionKinds.Add(def); + } } + DefaultFactionKinds = defaultFactionKinds; + foreach (ThingDef def in DefDatabase.AllDefsListForReading) { if (def.race is { Animal: false }) @@ -215,7 +230,7 @@ private static void PopulateVFEAncientsObjects() } /// - /// Pre-cached blacklists built at apply time: cloned PawnKindDef → blacklisted ThingDefs. + /// Pre-cached blocklists built at apply time: cloned PawnKindDef → blocklisted ThingDefs. /// Includes both global and specific edits merged. Keyed by cloned def for O(1) lookup at generation time. /// public static Dictionary> ApparelBlacklistCache = new(); @@ -225,7 +240,7 @@ private static void PopulateVFEAncientsObjects() /// /// Pre-cached material rules built at apply time: cloned PawnKindDef → (stuff set, isBlocklist). /// Allowlist (isBlocklist false) allows only the set; blocklist bans the set. Specific edit's list - /// (and its mode) wins; otherwise the faction's global edit's. Absent (or empty) key = no restriction. + /// (and its mode) wins; otherwise, the faction's global edit's. Absent (or empty) key = no restriction. /// public static Dictionary defs, bool blocklist)> ApparelMaterialCache = new(); @@ -255,7 +270,7 @@ public static string MaterialCategorySummary(List> materials, b IEnumerable allowed; if (isBlocklist) { - // Blocklist: allowed = every stuff except the banned ones, so we need the set + full scan. + // Blocklist: allowed = every stuff except the banned ones, so we need the set and full scan. HashSet banned = []; if (materials != null) { @@ -321,8 +336,8 @@ public static void BuildBlacklistCaches(PawnKindEdit edit, PawnKindDef def, Pawn } // Material rules: specific edit's list (and its mode) wins, else the faction's global edit's. - // Resolve to currently-present stuff defs; missing-mod entries stay in the saved DefRef list - // but simply don't constrain generation until their mod returns. + // Resolve to currently present stuff defs; missing-mod entries stay in the saved DefRef list + // but don't constrain generation until their mod returns. List> apparelMatList = edit.ApparelMaterials ?? global?.ApparelMaterials; bool apparelMatBlocklist = edit.ApparelMaterials != null ? edit.ApparelMaterialsBlocklist : global?.ApparelMaterialsBlocklist ?? false; HashSet apparelMat = apparelMatList?.Where(r => r.HasValue).Select(r => r.Def).ToHashSet(); diff --git a/1.6/Source/FactionEdit.cs b/1.6/Source/FactionEdit.cs index 783f87e..7d8d5a0 100644 --- a/1.6/Source/FactionEdit.cs +++ b/1.6/Source/FactionEdit.cs @@ -256,6 +256,11 @@ public static IReadOnlyList GetAllPawnKinds(FactionDef def) if (def.fixedLeaderKinds != null) kinds.AddRange(def.fixedLeaderKinds); + if (DefCache.DefaultFactionKinds != null && DefCache.DefaultFactionKinds.TryGetValue(def, out List defaultKinds)) + { + kinds.AddRange(defaultKinds); + } + return kinds.ToArray(); } diff --git a/1.6/Source/Patches/ApparelGenPatch.cs b/1.6/Source/Patches/ApparelGenPatch.cs index 3a81b30..a6f66b0 100644 --- a/1.6/Source/Patches/ApparelGenPatch.cs +++ b/1.6/Source/Patches/ApparelGenPatch.cs @@ -237,7 +237,7 @@ private static Apparel GenerateNewApparel(Pawn pawn, SpecRequirementEdit spec) float healthFactor = pawn.kindDef.gearHealthRange.RandomInRange; if (healthFactor < 1f) { - int hitPoints = Mathf.Max(1, Mathf.RoundToInt(healthFactor * (float)thing.MaxHitPoints)); + int hitPoints = Mathf.Max(1, Mathf.RoundToInt(healthFactor * thing.MaxHitPoints)); thing.HitPoints = hitPoints; } } @@ -312,7 +312,7 @@ private static void HandleApparelPriceLimit(Pawn pawn) // spends it down as it adds items then prunes anything pricier than what's left. // Subtract what was actually spent on the pawn's other apparel and only bail when even the best-case can't cover it. // Prices use the same abstract MarketValue as vanilla's budget math; free warmth/vacuum layers are - // not budget-charged, so spent is a slight over-estimate - hence the clamp. + // not budget-charged, so spent is a slight overestimate - hence the clamp. float spent = pawn.apparel.WornApparel.Sum(a => a.def.GetStatValueAbstract(StatDefOf.MarketValue, a.Stuff)); float budgetLeft = Mathf.Max(0f, pawn.kindDef.apparelMoney.max - spent); if (pair.Price <= budgetLeft) @@ -407,7 +407,7 @@ static void Postfix(ThingStuffPair pair, Pawn pawn, ref bool __result) /// /// Applies the per-kind apparel material rule to vanilla's stuff gate. REQUIRED apparel /// (PawnKindDef.apparelRequired) picks its stuff via CanUseStuff and never touches CanUsePair, -/// so without this a required item could spawn in a disallowed material. +/// so without this, a required item could spawn in a disallowed material. /// [HarmonyPatch(typeof(PawnApparelGenerator), "CanUseStuff")] public static class CanUseStuffMaterialPatch diff --git a/1.6/Source/Util/Extensions.cs b/1.6/Source/Util/Extensions.cs index 7bb1a08..5e0ea44 100644 --- a/1.6/Source/Util/Extensions.cs +++ b/1.6/Source/Util/Extensions.cs @@ -7,13 +7,13 @@ namespace FactionLoadout.Util { public static class Extensions { - private static HashSet tempKinds = new HashSet(); + private static HashSet tempKinds = []; public static Rect GetCentered(this Rect area, float width, float height) => new Rect(area.center.x - width * 0.5f, area.center.y - height * 0.5f, width, height); public static Rect GetCentered(this Rect area, string text) { - var size = Text.CalcSize(text); + Vector2 size = Text.CalcSize(text); return area.GetCentered(size.x, size.y); } @@ -28,7 +28,7 @@ void Register(List list) { if (list == null) return; - foreach (var item in list) + foreach (PawnGenOption item in list) tempKinds.Add(item.kind); } @@ -37,13 +37,13 @@ void RegisterSimple(List list) if (list == null) return; - foreach (var item in list) + foreach (PawnKindDef item in list) tempKinds.Add(item); } if (def.pawnGroupMakers != null) { - foreach (var item in def.pawnGroupMakers) + foreach (PawnGroupMaker item in def.pawnGroupMakers) { Register(item.options); Register(item.traders); @@ -56,6 +56,12 @@ void RegisterSimple(List list) if (def.basicMemberKind != null) tempKinds.Add(def.basicMemberKind); + if (DefCache.DefaultFactionKinds != null && DefCache.DefaultFactionKinds.TryGetValue(def, out List defaultKinds)) + { + foreach (PawnKindDef kind in defaultKinds) + tempKinds.Add(kind); + } + return tempKinds; }