From 4967faf00f4372d46ce14e810ff624075fa5dedf Mon Sep 17 00:00:00 2001 From: FluffierThanThou Date: Sat, 14 Aug 2021 19:49:42 +0200 Subject: [PATCH] try to use medicine in inventory first --- .../HealthAIUtility_FindBestMedicine.cs | 41 ++++++++++++++++--- ...WorkGiver_DoBill_GetMedicalCareCategory.cs | 2 +- Source/Pharmacist.csproj | 1 + 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/Source/HarmonyPatches/HealthAIUtility_FindBestMedicine.cs b/Source/HarmonyPatches/HealthAIUtility_FindBestMedicine.cs index 3163aaa..00f2bd7 100644 --- a/Source/HarmonyPatches/HealthAIUtility_FindBestMedicine.cs +++ b/Source/HarmonyPatches/HealthAIUtility_FindBestMedicine.cs @@ -2,6 +2,7 @@ // HealthAIUtility_FindBestMedicine.cs // 2017-02-11 +using System.Linq; using HarmonyLib; using RimWorld; using Verse; @@ -10,15 +11,46 @@ namespace Pharmacist { [HarmonyPatch(typeof(HealthAIUtility), nameof(HealthAIUtility.FindBestMedicine))] public class HealthAIUtility_FindBestMedicine { - public static bool Prefix(Pawn healer, Pawn patient, ref Thing __result) { + public static bool Prefix(Pawn healer, Pawn patient, bool onlyUseInventory, ref Thing __result) { + // get lowest of pawn care settings & pharmacy settings MedicalCareCategory pharmacistAdvice = PharmacistUtility.TendAdvice( patient ); - if (pharmacistAdvice <= MedicalCareCategory.NoMeds) { __result = null; return false; } + // check count required + int countRequired = Medicine.GetMedicineCountToFullyHeal(patient); + if (countRequired <= 0) { + __result = null; + return false; + } + + float potencyGetter(Thing t) { + return t.def.GetStatValueAbstract(StatDefOf.MedicalPotency); + } + bool allowedPredicate(Thing m) { + return !m.IsForbidden(healer) + && m.def.IsMedicine + && pharmacistAdvice.AllowsMedicine(m.def) + && healer.CanReserve(m, 10, 1); + } + + // check pockets first + // note: vanilla actually selects the medicine with the _lowest_ potency, + // I have to assume that that is not intentional. + // + // thanks to KennethSammael for adding this check in the unofficial 1.3 update, + // this code is adapted from his changes. + __result = healer.inventory.innerContainer + .Where(allowedPredicate) + .MaxBy(potencyGetter); + if (__result is not null || onlyUseInventory) { + return false; + } + + // search for best meds __result = GenClosest.ClosestThing_Global_Reachable( patient.Position, patient.Map, @@ -26,9 +58,8 @@ public static bool Prefix(Pawn healer, Pawn patient, ref Thing __result) { PathEndMode.ClosestTouch, TraverseParms.For(healer), 9999f, - (m) => !m.IsForbidden(healer) && pharmacistAdvice.AllowsMedicine(m.def) && healer.CanReserve(m, 1), - (m) => m.def.GetStatValueAbstract(StatDefOf.MedicalPotency)); - + allowedPredicate, + potencyGetter); return false; } } diff --git a/Source/HarmonyPatches/WorkGiver_DoBill_GetMedicalCareCategory.cs b/Source/HarmonyPatches/WorkGiver_DoBill_GetMedicalCareCategory.cs index 063e226..2b60944 100644 --- a/Source/HarmonyPatches/WorkGiver_DoBill_GetMedicalCareCategory.cs +++ b/Source/HarmonyPatches/WorkGiver_DoBill_GetMedicalCareCategory.cs @@ -9,7 +9,7 @@ namespace Pharmacist.Properties { [HarmonyPatch(typeof(WorkGiver_DoBill), "GetMedicalCareCategory")] public static class WorkGiver_DoBill_GetMedicalCareCategory { public static bool Prefix(Thing billGiver, ref MedicalCareCategory __result) { - if (!(billGiver is Pawn pawn)) { + if (billGiver is not Pawn pawn) { // because this is the fallback vanilla uses... __result = MedicalCareCategory.Best; } else { diff --git a/Source/Pharmacist.csproj b/Source/Pharmacist.csproj index 9ef67b4..af26639 100644 --- a/Source/Pharmacist.csproj +++ b/Source/Pharmacist.csproj @@ -8,6 +8,7 @@ ..\Assemblies\ portable mod update + 9