From dd12edf90193f002ea17236d3b1291aa0308f0b0 Mon Sep 17 00:00:00 2001 From: edbmods Date: Thu, 9 May 2024 23:49:15 -0700 Subject: [PATCH 1/7] Fixed mutation implants loading from presets and added them as implant options --- Source/DialogManageImplants.cs | 54 ++++++++++++++++++--------------- Source/Implant.cs | 10 +++++- Source/ProviderHealthOptions.cs | 9 ++++++ 3 files changed, 48 insertions(+), 25 deletions(-) diff --git a/Source/DialogManageImplants.cs b/Source/DialogManageImplants.cs index 52e5434..67c27b2 100644 --- a/Source/DialogManageImplants.cs +++ b/Source/DialogManageImplants.cs @@ -211,10 +211,13 @@ protected void ResetDisabledState() { if (part == null) { continue; } + // If there's already an implant on that body part record, skip it. Otherwise add it + // to the list of first pass valid implants if (firstPassReplacedParts.ContainsKey(part.Record)) { continue; } firstPassValidImplants.Add(implant); + // Also keep track of whether we've replaced a body part with an implant if (implant.ReplacesPart) { firstPassReplacedParts.Add(implant.BodyPartRecord, implant); } @@ -224,6 +227,7 @@ protected void ResetDisabledState() { // that don't replace parts but whose target part has been removed. Dictionary secondPassReplacedParts = new Dictionary(); List secondPassValidImplants = new List(); + // Iterate all of the implants that we marked as valid in the first pass foreach (var implant in firstPassValidImplants) { UniqueBodyPart part = health.FindBodyPartsForRecord(implant.BodyPartRecord); if (part == null) { @@ -260,19 +264,19 @@ protected void ResetDisabledState() { validImplants.Add(implant); } - //Logger.Debug("Valid implants"); - //foreach (var i in validImplants) { - // Logger.Debug(" " + i.recipe.LabelCap + ", " + i.PartName + (i.ReplacesPart ? ", replaces part" : "")); - //} + Logger.Debug("Valid implants:"); + foreach (var i in validImplants) { + Logger.Debug(" " + i.Label + ", " + i.BodyPartRecord?.def?.defName + (i.ReplacesPart ? ", replaces part" : "")); + } - // Iterate each body part option for each recipe to determine if that body part is missing, + // Iterate each body part option for each option to determine if that body part is missing, // based on the whether or not it or one of its ancestors has been replaced. Only evaluate each - // body part once. The result will be used to determine if recipes and part options should be + // body part once. The result will be used to determine if options and part options should be // disabled. HashSet evaluatedParts = new HashSet(); Dictionary blockedParts = new Dictionary(); - foreach (var recipe in options) { - foreach (var part in recipe.Parts) { + foreach (var option in options) { + foreach (var part in option.Parts) { if (evaluatedParts.Contains(part.Part)) { continue; } @@ -290,7 +294,7 @@ protected void ResetDisabledState() { } } - // Go through each recipe and recipe part, marking the parts as disabled if + // Go through each option and option part, marking the parts as disabled if // they are missing and marking the recipes as disabled if all of its parts // are disabled. foreach (var option in options) { @@ -318,19 +322,19 @@ protected void ResetDisabledState() { } } - // Evaluate each recipe's selected state. - foreach (var recipe in options) { - recipe.PartiallySelected = false; - if (recipe.Selected) { + // Evaluate each option's selected state. + foreach (var option in options) { + option.PartiallySelected = false; + if (option.Selected) { int selectedCount = 0; - foreach (var part in recipe.Parts) { + foreach (var part in option.Parts) { if (part.Selected && !part.Disabled) { selectedCount++; break; } } if (selectedCount == 0) { - recipe.PartiallySelected = true; + option.PartiallySelected = true; } } } @@ -340,8 +344,8 @@ protected void ResetDisabledState() { protected void ResetCachedBlockedSelectionAlert() { bool showAlert = false; - foreach (var recipe in options) { - foreach (var part in recipe.Parts) { + foreach (var option in options) { + foreach (var part in option.Parts) { if (part.Disabled && part.Implant != null) { showAlert = true; break; @@ -356,17 +360,19 @@ protected void ResetCachedBlockedSelectionAlert() { return; } List blockedSelections = new List(); - foreach (var recipe in options) { - int partCount = recipe.Parts.Count; - foreach (var part in recipe.Parts) { - if (part.Disabled && part.Implant != null) { - blockedSelections.Add(part.Implant); + foreach (var option in options) { + int partCount = option.Parts?.Count ?? 0; + if (option.Parts != null) { + foreach (var part in option.Parts) { + if (part.Disabled && part.Implant != null) { + blockedSelections.Add(part.Implant); + } } } } string listItems = ""; foreach (var item in blockedSelections) { - listItems += "\n" + "EdB.PC.Dialog.Implant.Alert.Item".Translate(item.Recipe.LabelCap, item.BodyPartRecord.def.label); + listItems += "\n" + "EdB.PC.Dialog.Implant.Alert.Item".Translate(item.Label, item.BodyPartRecord?.def?.label); } cachedBlockedSelectionAlert = "EdB.PC.Dialog.Implant.Alert".Translate(listItems); } @@ -769,7 +775,7 @@ protected void Resize() { ClickPartAction(option, part); } if (part.BlockingImplant != null) { - TooltipHandler.TipRegion(labelRect, "EdB.PC.Dialog.Implant.Conflict".Translate(part.BlockingImplant.Recipe.LabelCap, part.BlockingImplant.BodyPartRecord.Label)); + TooltipHandler.TipRegion(labelRect, "EdB.PC.Dialog.Implant.Conflict".Translate(part.BlockingImplant.Label, part.BlockingImplant.BodyPartRecord.Label)); } } cursor += labelRect.height; diff --git a/Source/Implant.cs b/Source/Implant.cs index 2aee0d1..73e7836 100644 --- a/Source/Implant.cs +++ b/Source/Implant.cs @@ -26,7 +26,12 @@ public Implant(BodyPartRecord bodyPartRecord, RecipeDef recipe) { public string Label { get { - return Recipe?.addsHediff?.LabelCap ?? ""; + if (Recipe != null) { + return Recipe?.addsHediff?.LabelCap ?? ""; + } + else { + return "EdB.PC.Dialog.Implant.InstallImplantLabel".Translate(Option?.HediffDef?.label); + } } } @@ -37,6 +42,9 @@ public bool ReplacesPart { || typeof(Hediff_MissingPart).IsAssignableFrom(Recipe.addsHediff.hediffClass))) { return true; } + else if (Option?.HediffDef?.organicAddedBodypart ?? false) { + return true; + } return false; } } diff --git a/Source/ProviderHealthOptions.cs b/Source/ProviderHealthOptions.cs index 46a920c..3a5ceb5 100644 --- a/Source/ProviderHealthOptions.cs +++ b/Source/ProviderHealthOptions.cs @@ -171,6 +171,15 @@ protected void InitializeImplantRecipes(OptionsHealth options, ThingDef pawnThin foreach (var value in implantOptionLookup.Values) { options.AddImplantOption(value); } + + // Add options for mutations + foreach (var def in DefDatabase.AllDefs.Where(d => d.organicAddedBodypart && d.defaultInstallPart != null)) { + ImplantOption option = new ImplantOption() { + HediffDef = def, + BodyPartDefs = new HashSet() { def.defaultInstallPart }, + }; + options.AddImplantOption(option); + } } protected bool InitializeHediffGivenByUseEffect(OptionsHealth options, CompProperties_UseEffectInstallImplant useEffect) { From e67bc75df758c54a59e38f0d42b469b5863f7354 Mon Sep 17 00:00:00 2001 From: edbmods Date: Thu, 9 May 2024 23:49:59 -0700 Subject: [PATCH 2/7] Now clearing out the Prepare Carefully singleton after the game is initialized --- Source/HarmonyPatches.cs | 1 + Source/Mod.cs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/HarmonyPatches.cs b/Source/HarmonyPatches.cs index c5a90d6..4c4bc18 100644 --- a/Source/HarmonyPatches.cs +++ b/Source/HarmonyPatches.cs @@ -77,6 +77,7 @@ static void Postfix() { // After we've initialized the new game, swap in the original scenario parts so that the game save // doesn't include any Prepare Carefully-specific scene parts. Mod.Instance.RestoreScenarioParts(); + Mod.ClearInstance(); } } } diff --git a/Source/Mod.cs b/Source/Mod.cs index b0c4516..399891c 100644 --- a/Source/Mod.cs +++ b/Source/Mod.cs @@ -8,7 +8,7 @@ namespace EdB.PrepareCarefully { public class Mod { - public static readonly Version MinimumGameVersion = new Version(1, 3, 3102); + public static readonly Version MinimumGameVersion = new Version(1, 5, 0); private static Mod instance = new Mod(); public static Mod Instance { get { @@ -19,6 +19,9 @@ public static Mod Instance { } } + public static void ClearInstance() { + instance = null; + } public ModState State { get; set; } public void Clear() { From 19f9bc5cae1d9d8b4d6597c4fa1a3df7ab1af707 Mon Sep 17 00:00:00 2001 From: edbmods Date: Fri, 10 May 2024 19:18:05 -0700 Subject: [PATCH 3/7] Added mutation implants. Removing mutant-specific or -restricted implants for pawns that don't match --- Source/DialogManageImplants.cs | 6 +-- Source/Implant.cs | 2 - Source/MapperPawnToCustomizations.cs | 12 +++--- Source/OptionsHealth.cs | 7 ---- Source/PawnCustomizer.cs | 2 +- Source/PawnLoaderV3.cs | 1 - Source/PawnLoaderV5.cs | 21 ++++------ Source/ProviderHealthOptions.cs | 58 +++++++++++++++++++--------- 8 files changed, 57 insertions(+), 52 deletions(-) diff --git a/Source/DialogManageImplants.cs b/Source/DialogManageImplants.cs index 67c27b2..2ae8d0a 100644 --- a/Source/DialogManageImplants.cs +++ b/Source/DialogManageImplants.cs @@ -484,17 +484,17 @@ public bool NeedsDependencies(ref HashSet missingDependencies) { if (missingDependencies == null) { missingDependencies = new HashSet(); } - HashSet selected = new HashSet(implantList.Select(i => i.Option.HediffDef)); + HashSet selected = new HashSet(implantList.Select(i => i.Option?.HediffDef).Where(h => h != null)); Logger.Debug(" Selected implants: " + string.Join(", ", selected.Select(d => d.defName))); foreach (var implant in implantList) { - if (implant.Option.Dependency != null && !selected.Contains(implant.Option.Dependency)) { + if (implant.Option?.Dependency != null && !selected.Contains(implant.Option.Dependency)) { var optionToAdd = FindDialogOptionForHediff(implant.Option.Dependency); if (optionToAdd != null) { missingDependencies.Add(optionToAdd); } } } - Logger.Debug(" Needs dependencies: " + string.Join(", ", missingDependencies.Select(o => o.ImplantOption.HediffDef.defName))); + Logger.Debug(" Needs dependencies: " + string.Join(", ", missingDependencies.Select(o => o.ImplantOption?.HediffDef?.defName))); return missingDependencies.Count > 0; } diff --git a/Source/Implant.cs b/Source/Implant.cs index 73e7836..17f53f5 100644 --- a/Source/Implant.cs +++ b/Source/Implant.cs @@ -8,8 +8,6 @@ namespace EdB.PrepareCarefully { public class Implant : CustomizedHediff { - public string label = ""; - public Implant() { } diff --git a/Source/MapperPawnToCustomizations.cs b/Source/MapperPawnToCustomizations.cs index 0257828..e2a244c 100644 --- a/Source/MapperPawnToCustomizations.cs +++ b/Source/MapperPawnToCustomizations.cs @@ -262,13 +262,15 @@ public void MapInjuriesAndImplants(Pawn pawn, CustomizationsPawn customizations) else { //Logger.Debug("Did not find injury option for {" + hediff.def.defName + "} for part {" + hediff.Part?.LabelCap + "}"); ImplantOption implantOption = healthOptions.FindImplantOptionsThatAddHediff(hediff).RandomElementWithFallback(null); - if (implantOption != null) { + HediffDef hediffDef = hediff?.def; + BodyPartRecord bodyPartRecord = hediff.Part; + if (hediffDef != null) { var implant = new Implant() { Option = implantOption, - Recipe = implantOption.RecipeDef, - BodyPartRecord = hediff.Part, + Recipe = implantOption?.RecipeDef, + BodyPartRecord = bodyPartRecord, Hediff = hediff, - HediffDef = hediff?.def, + HediffDef = hediffDef, }; if (hediff is Hediff_Level level) { //Logger.Debug("Mapping implant " + implantOption.HediffDef.defName + " with severity " + level.level); @@ -279,7 +281,7 @@ public void MapInjuriesAndImplants(Pawn pawn, CustomizationsPawn customizations) implants.Add(implant); } else { - Logger.Warning("Could not add hediff {" + hediff.def.defName + "} to the pawn because found no matching implant option for the body part {" + (hediff.Part?.def?.defName ?? "WholeBody") + "}"); + Logger.Debug("Could not find implant option for hediff {" + hediff.def?.defName + "} and body part {" + (hediff.Part?.def?.defName ?? "WholeBody") + "}"); } } } diff --git a/Source/OptionsHealth.cs b/Source/OptionsHealth.cs index d6b7cd7..d311533 100644 --- a/Source/OptionsHealth.cs +++ b/Source/OptionsHealth.cs @@ -261,13 +261,6 @@ public void AddImplantRecipe(RecipeDef recipe, List parts) { public void AddImplantOption(ImplantOption option) { ImplantOptions.Add(option); } - public void AddImplantHediffDef(HediffDef hediffDef, BodyPartRecord bodyPartRecord = null) { - ImplantOptions.Add(new ImplantOption() { - RecipeDef = null, - HediffDef = hediffDef, - BodyPartRecord = bodyPartRecord, - }); - } public IEnumerable FindBodyPartsForImplantRecipe(RecipeDef recipeDef) { if (recipeDef == null) { diff --git a/Source/PawnCustomizer.cs b/Source/PawnCustomizer.cs index ade0087..1e4e0af 100644 --- a/Source/PawnCustomizer.cs +++ b/Source/PawnCustomizer.cs @@ -400,7 +400,7 @@ public void ApplyInjuryAndImplantCustomizationsToPawn(Pawn pawn, CustomizationsP ApplyImplantToPawn(pawn, implant); } catch (Exception e) { - Logger.Warning("Failed to add implant {" + implant.label + "} to part {" + implant.BodyPartRecord?.def?.defName + "}", e); + Logger.Warning("Failed to add implant {" + implant.Label + "} to part {" + implant.BodyPartRecord?.def?.defName + "}", e); implantsToRemove.Add(implant); } } diff --git a/Source/PawnLoaderV3.cs b/Source/PawnLoaderV3.cs index 7d0af94..84d41ea 100644 --- a/Source/PawnLoaderV3.cs +++ b/Source/PawnLoaderV3.cs @@ -358,7 +358,6 @@ public PawnLoaderResult ConvertSaveRecordToCustomizedPawn(SaveRecordPawnV3 recor BodyPartRecord = bodyPart, HediffDef = recipeDef.addsHediff, }; - implant.label = implant.Label; customizations.Implants.Add(implant); } else { diff --git a/Source/PawnLoaderV5.cs b/Source/PawnLoaderV5.cs index 828c237..85ccd3a 100644 --- a/Source/PawnLoaderV5.cs +++ b/Source/PawnLoaderV5.cs @@ -624,8 +624,6 @@ public PawnLoaderResult ConvertSaveRecordToCustomizedPawn(SaveRecordPawnV5 recor Recipe = recipeDef, HediffDef = recipeDef.addsHediff, }; - // TODO: This looks weird; something to do with caching the label. Should rework it. - implant.label = implant.Label; customizations.Implants.Add(implant); Logger.Debug("Added implant customizations " + recipeDef?.defName); } @@ -637,18 +635,13 @@ public PawnLoaderResult ConvertSaveRecordToCustomizedPawn(SaveRecordPawnV5 recor HediffDef hediffDef = DefDatabase.GetNamedSilentFail(implantRecord.hediffDef); if (hediffDef != null) { ImplantOption implantOption = healthOptions.FindImplantOptionThatAddsHediffDefToBodyPart(hediffDef, bodyPart?.def); - if (implantOption == null) { - result.AddWarning("Could not add implant to pawn because no matching option was found for specified HediffDef {" + implantRecord.hediffDef + "} and BodyPartDef {" + bodyPart?.def?.defName + "}"); - } - else { - Implant implant = new Implant(); - implant.Option = implantOption; - implant.BodyPartRecord = bodyPart; - implant.label = implant.Label; - implant.HediffDef = hediffDef; - implant.Severity = implantRecord.severity; - customizations.Implants.Add(implant); - } + Implant implant = new Implant() { + Option = implantOption, + BodyPartRecord = bodyPart, + HediffDef = hediffDef, + Severity = implantRecord.severity, + }; + customizations.Implants.Add(implant); } else { result.AddWarning("Could not add implant to pawn because the specified HediffDef {" + implantRecord.hediffDef + "} for the implant was not found"); diff --git a/Source/ProviderHealthOptions.cs b/Source/ProviderHealthOptions.cs index 3a5ceb5..d927f69 100644 --- a/Source/ProviderHealthOptions.cs +++ b/Source/ProviderHealthOptions.cs @@ -12,36 +12,39 @@ namespace EdB.PrepareCarefully { public class ProviderHealthOptions { - protected Dictionary optionsLookup = new Dictionary(); + protected Dictionary, OptionsHealth> optionsLookup = new Dictionary, OptionsHealth>(); protected HashSet excludedOptions = new HashSet() { "VatLearning", "VatGrowing", "Pregnant", "PsychicBond", "PsychicBondTorn", "ResearchCommand", "Animal_Flu", "Stillborn", "Animal_Plague" }; public OptionsHealth GetOptions(CustomizedPawn customizedPawn) { - if (!optionsLookup.TryGetValue(customizedPawn.Pawn.def, out var result)) { - result = InitializeHealthOptions(customizedPawn.Pawn.def); - optionsLookup.Add(customizedPawn.Pawn.def, result); + var cacheKey = Tuple.Create(customizedPawn.Pawn.def, customizedPawn.Pawn.mutant?.Def); + if (!optionsLookup.TryGetValue(cacheKey, out var result)) { + result = InitializeHealthOptions(customizedPawn.Pawn.def, customizedPawn.Pawn.mutant?.Def); + optionsLookup.Add(cacheKey, result); } return result; } public OptionsHealth GetOptions(Pawn pawn) { - if (!optionsLookup.TryGetValue(pawn.def, out var result)) { - result = InitializeHealthOptions(pawn.def); - optionsLookup.Add(pawn.def, result); + var cacheKey = Tuple.Create(pawn.def, pawn.mutant?.Def); + if (!optionsLookup.TryGetValue(cacheKey, out var result)) { + result = InitializeHealthOptions(pawn.def, pawn.mutant?.Def); + optionsLookup.Add(cacheKey, result); } return result; } public OptionsHealth GetOptions(ThingDef def) { - if (!optionsLookup.TryGetValue(def, out var result)) { - result = InitializeHealthOptions(def); - optionsLookup.Add(def, result); + var cacheKey = Tuple.Create(def, (MutantDef)null); + if (!optionsLookup.TryGetValue(cacheKey, out var result)) { + result = InitializeHealthOptions(def, null); + optionsLookup.Add(cacheKey, result); } return result; } - protected OptionsHealth InitializeHealthOptions(ThingDef pawnThingDef) { + protected OptionsHealth InitializeHealthOptions(ThingDef pawnThingDef, MutantDef mutantDef) { OptionsHealth result = new OptionsHealth(); BodyDef bodyDef = pawnThingDef.race.body; result.BodyDef = bodyDef; @@ -49,7 +52,10 @@ protected OptionsHealth InitializeHealthOptions(ThingDef pawnThingDef) { HashSet ancestors = new HashSet(); ProcessBodyPart(result, bodyDef.corePart, 1, ancestors); - InitializeImplantRecipes(result, pawnThingDef); + List implantOptions = InitializeImplantRecipes(result, pawnThingDef, mutantDef); + foreach (var implantOption in implantOptions) { + result.AddImplantOption(implantOption); + } InitializeInjuryOptions(result, pawnThingDef); result.Sort(); @@ -77,10 +83,11 @@ protected int ProcessBodyPart(OptionsHealth options, BodyPartRecord record, int return index; } - protected void InitializeImplantRecipes(OptionsHealth options, ThingDef pawnThingDef) { + protected List InitializeImplantRecipes(OptionsHealth options, ThingDef pawnThingDef, MutantDef mutantDef) { + List result = new List(); // Find all recipes that replace a body part. List recipes = new List(); - recipes.AddRange(DefDatabase.AllDefs.Where((RecipeDef def) => { + IEnumerable startingRecipes = DefDatabase.AllDefs.Where((RecipeDef def) => { if (def.addsHediff != null && ((def.appliedOnFixedBodyParts != null && def.appliedOnFixedBodyParts.Count > 0) || (def.appliedOnFixedBodyPartGroups != null && def.appliedOnFixedBodyPartGroups.Count > 0)) && (def.recipeUsers.NullOrEmpty() || def.recipeUsers.Contains(pawnThingDef))) { @@ -91,9 +98,20 @@ protected void InitializeImplantRecipes(OptionsHealth options, ThingDef pawnThin //Logger.Debug("Excluding implant recipe: " + def.defName); return false; } - })); - - + }).Where(r => { + if (mutantDef != null && r.mutantBlacklist.CountAllowNull() > 0 && r.mutantBlacklist.Contains(mutantDef)) { + Logger.Debug("removing recipe because mutant pawn is not allowed: " + r.LabelCap + ", mutant = " + mutantDef.LabelCap + ", exclusion list = " + string.Join(",", r.mutantBlacklist)); + return false; + } + else if (r.mutantPrerequisite.CountAllowNull() > 0 && !r.mutantPrerequisite.Contains(mutantDef)) { + Logger.Debug("removing recipe because pawn is not an allowed kind of mutant: " + r.LabelCap + ", required = " + string.Join(",", r.mutantPrerequisite)); + return false; + } + else { + return true; + } + }); + recipes.AddRange(startingRecipes); // Remove duplicates: recipes that apply the same hediff on the same body parts. HashSet recipeHashes = new HashSet(); @@ -169,7 +187,7 @@ protected void InitializeImplantRecipes(OptionsHealth options, ThingDef pawnThin } } foreach (var value in implantOptionLookup.Values) { - options.AddImplantOption(value); + result.Add(value); } // Add options for mutations @@ -178,8 +196,10 @@ protected void InitializeImplantRecipes(OptionsHealth options, ThingDef pawnThin HediffDef = def, BodyPartDefs = new HashSet() { def.defaultInstallPart }, }; - options.AddImplantOption(option); + result.Add(option); } + + return result; } protected bool InitializeHediffGivenByUseEffect(OptionsHealth options, CompProperties_UseEffectInstallImplant useEffect) { From 0e117fd059d399869424778a3728492897ef3f27 Mon Sep 17 00:00:00 2001 From: edbmods Date: Fri, 10 May 2024 19:22:01 -0700 Subject: [PATCH 4/7] Updated change log and version numbers --- Properties/AssemblyInfo.cs | 2 +- Resources/About/About.xml | 2 +- Resources/About/Manifest.xml | 2 +- Resources/CHANGELOG.txt | 9 +++++++++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index c576b8a..bc6abb2 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -14,4 +14,4 @@ [assembly: AssemblyVersion("1.1.1")] // Increment for each new release -[assembly: AssemblyFileVersion("1.5.10")] +[assembly: AssemblyFileVersion("1.5.11")] diff --git a/Resources/About/About.xml b/Resources/About/About.xml index 31d691c..b55159a 100644 --- a/Resources/About/About.xml +++ b/Resources/About/About.xml @@ -25,7 +25,7 @@ If you get a set of starting colonists that you like, save them as a preset so that you can start your game the same way next time. -[Version 1.5.10] +[Version 1.5.11]
  • net.pardeike.rimworld.mod.harmony
  • diff --git a/Resources/About/Manifest.xml b/Resources/About/Manifest.xml index 3d3e5d0..1e2058f 100644 --- a/Resources/About/Manifest.xml +++ b/Resources/About/Manifest.xml @@ -1,7 +1,7 @@ EdB.PrepareCarefully - 1.5.10 + 1.5.11 false https://github.com/edbmods/EdBPrepareCarefully/raw/master/Resources/About/Manifest.xml https://github.com/edbmods/EdBPrepareCarefully/releases/latest diff --git a/Resources/CHANGELOG.txt b/Resources/CHANGELOG.txt index e7ad721..1bfcce8 100644 --- a/Resources/CHANGELOG.txt +++ b/Resources/CHANGELOG.txt @@ -1,3 +1,12 @@ + _____________________________________________________________________________ + + Version 1.5.11 + _____________________________________________________________________________ + + - Added missing implants (tentacles, etc.) + - Pawns can no longer add implants that are mutant-specific or restricted + if their mutant type does not match + _____________________________________________________________________________ Version 1.5.10 From 390d1a0cd0df2cc3d66be3d2417e0f663dc797be Mon Sep 17 00:00:00 2001 From: edbmods Date: Fri, 10 May 2024 21:07:19 -0700 Subject: [PATCH 5/7] Changed OptionsHealth.FindBodyPartsForRecord() to return an IEnumerable to avoid some null pointer issues with mods --- Source/OptionsHealth.cs | 6 +++--- Source/ProviderHealthOptions.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/OptionsHealth.cs b/Source/OptionsHealth.cs index d311533..6fbf916 100644 --- a/Source/OptionsHealth.cs +++ b/Source/OptionsHealth.cs @@ -121,12 +121,12 @@ public UniqueBodyPart FindBodyPartsForRecord(BodyPartRecord record) { return null; } } - public List FindBodyPartsForDef(BodyPartDef def) { + public IEnumerable FindBodyPartsForDef(BodyPartDef def) { if (bodyPartDefLookup.TryGetValue(def, out List result)) { return result; } else { - return null; + return Enumerable.Empty(); } } public IEnumerable FindImplantRecipesThatAddHediff(Hediff hediff) { @@ -322,7 +322,7 @@ public IEnumerable BodyPartsForInjury(InjuryOption option) { else { List records = new List(); foreach (var part in option.ValidParts) { - records.AddRange(FindBodyPartsForDef(part).ConvertAll(p => p.Record)); + records.AddRange(FindBodyPartsForDef(part).Select(p => p.Record)); } return records; } diff --git a/Source/ProviderHealthOptions.cs b/Source/ProviderHealthOptions.cs index d927f69..5d23ee4 100644 --- a/Source/ProviderHealthOptions.cs +++ b/Source/ProviderHealthOptions.cs @@ -132,7 +132,7 @@ protected List InitializeImplantRecipes(OptionsHealth options, Th foreach (var r in recipes) { // Add all of the body parts for that recipe to the list. foreach (var bodyPartDef in r.appliedOnFixedBodyParts) { - List fixedParts = options.FindBodyPartsForDef(bodyPartDef); + List fixedParts = options.FindBodyPartsForDef(bodyPartDef).ToList(); if (fixedParts != null && fixedParts.Count > 0) { //Logger.Debug("Adding recipe for " + r.defName + " for fixed parts " + String.Join(", ", fixedParts.ConvertAll(p => p.Record.LabelCap))); options.AddImplantRecipe(r, fixedParts); @@ -216,7 +216,7 @@ protected bool InitializeHediffGivenByUseEffect(OptionsHealth options, CompPrope } if (useEffect.bodyPart != null) { List validParts = new List() { useEffect.bodyPart }; - List parts = options.FindBodyPartsForDef(useEffect.bodyPart); + List parts = options.FindBodyPartsForDef(useEffect.bodyPart).ToList(); if (parts == null || parts.Count == 0) { //Logger.Debug("Found no valid body parts for hediff use effect: " + hediffDef.defName + ", " + useEffect.bodyPart.defName); return false; @@ -250,7 +250,7 @@ protected void InitializeHediffGiverInjuries(OptionsHealth options, HediffGiver if (giver.partsToAffect != null && !giver.canAffectAnyLivePart) { List validParts = new List(); foreach (var def in giver.partsToAffect) { - List parts = options.FindBodyPartsForDef(def); + List parts = options.FindBodyPartsForDef(def).ToList(); if (parts != null) { validParts.Add(def); } From 1023eceee43cdef79dfa4f1d4cc1686d0677bc86 Mon Sep 17 00:00:00 2001 From: edbmods Date: Fri, 10 May 2024 21:22:20 -0700 Subject: [PATCH 6/7] Don't show the implant level slider if the max level is one --- Source/DialogManageImplants.cs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/Source/DialogManageImplants.cs b/Source/DialogManageImplants.cs index 2ae8d0a..6d84f04 100644 --- a/Source/DialogManageImplants.cs +++ b/Source/DialogManageImplants.cs @@ -445,6 +445,9 @@ public void SelectOption(DialogOption option) { return; } option.Selected = true; + if (option.ImplantOption?.MaxSeverity == 1) { + UpdateSeverity(option, 1); + } if (option.Parts.Count == 1) { if (!option.Parts[0].Selected) { option.Parts[0].Selected = true; @@ -480,12 +483,12 @@ public void AddMissingDependencies() { } public bool NeedsDependencies(ref HashSet missingDependencies) { - Logger.Debug("NeedsDependencies()"); + //Logger.Debug("NeedsDependencies()"); if (missingDependencies == null) { missingDependencies = new HashSet(); } HashSet selected = new HashSet(implantList.Select(i => i.Option?.HediffDef).Where(h => h != null)); - Logger.Debug(" Selected implants: " + string.Join(", ", selected.Select(d => d.defName))); + //Logger.Debug(" Selected implants: " + string.Join(", ", selected.Select(d => d.defName))); foreach (var implant in implantList) { if (implant.Option?.Dependency != null && !selected.Contains(implant.Option.Dependency)) { var optionToAdd = FindDialogOptionForHediff(implant.Option.Dependency); @@ -494,7 +497,7 @@ public bool NeedsDependencies(ref HashSet missingDependencies) { } } } - Logger.Debug(" Needs dependencies: " + string.Join(", ", missingDependencies.Select(o => o.ImplantOption?.HediffDef?.defName))); + //Logger.Debug(" Needs dependencies: " + string.Join(", ", missingDependencies.Select(o => o.ImplantOption?.HediffDef?.defName))); return missingDependencies.Count > 0; } @@ -523,7 +526,7 @@ public bool HasUnneededDependencies(ref HashSet unneededDependenci unneededDependencies.Add(option); } } - Logger.Debug("Unneeded dependencies: " + string.Join(", ", unneededDependencies.Select(o => o.ImplantOption?.HediffDef?.defName ?? "null"))); + //Logger.Debug("Unneeded dependencies: " + string.Join(", ", unneededDependencies.Select(o => o.ImplantOption?.HediffDef?.defName ?? "null"))); return unneededDependencies.Count > 0; } @@ -537,7 +540,7 @@ public void DeselectOption(DialogOption option) { option.Selected = false; option.SelectedDependency = false; if (option.Parts != null) { - Logger.Debug(" option.Parts = " + string.Join(", ", option.Parts.Select(p => p.UniquePart.Record.def.defName))); + //Logger.Debug(" option.Parts = " + string.Join(", ", option.Parts.Select(p => p.UniquePart.Record.def.defName))); } foreach (var part in option.Parts) { if (part.Selected) { @@ -556,10 +559,10 @@ public void UpdateSeverity(DialogOption option, float severity) { Implant implant = implantList.FirstOrDefault(i => i.Option == option.ImplantOption); if (implant != null) { implant.Severity = option.Severity; - Logger.Debug("Updated implant severity"); + //Logger.Debug("Updated implant severity"); } else { - Logger.Debug("Didn't find implant to update"); + //Logger.Debug("Didn't find implant to update"); } } protected void AddImplant(DialogOption option, ImplantBodyPart part) { @@ -722,7 +725,7 @@ protected void Resize() { if (option.Selected || option.SelectedDependency) { float inset = 32; float cursor = labelRect.yMax; - if (option.ImplantOption.MaxSeverity > 0) { + if (option.ImplantOption.MaxSeverity > 1) { float rowWidth = rect.width - inset * 2; float sliderWidth = rowWidth - LevelLabelSize.x - LevelValueSize.x - 12; float sliderHeight = 12; @@ -789,7 +792,7 @@ protected void Resize() { if (option.Selected && option.Parts.Count > 1) { height += LineHeight * option.Parts.Count; } - if (option.Selected && option.ImplantOption.MaxSeverity > 0) { + if (option.Selected && option.ImplantOption.MaxSeverity > 1) { height += LineHeight; } return height; From e9df7736cb9ab3c9b42407ae651757ebfadf0e06 Mon Sep 17 00:00:00 2001 From: edbmods Date: Fri, 10 May 2024 21:41:13 -0700 Subject: [PATCH 7/7] Changelog tweaks --- Resources/CHANGELOG.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Resources/CHANGELOG.txt b/Resources/CHANGELOG.txt index 1bfcce8..eb37680 100644 --- a/Resources/CHANGELOG.txt +++ b/Resources/CHANGELOG.txt @@ -3,9 +3,13 @@ Version 1.5.11 _____________________________________________________________________________ - - Added missing implants (tentacles, etc.) - - Pawns can no longer add implants that are mutant-specific or restricted - if their mutant type does not match + - Added some missing implants (tentacles, etc.) + - Bug fixes: + - Pawns can no longer add implants that are mutant-specific or restricted + if their mutant type does not match + - Fixed some errors when trying to open the Bionics and Implants dialog + when using some mods + - Removed the implant level slider when the implant only has one level _____________________________________________________________________________