From 440af750157639b4b016994d15082d73c2265187 Mon Sep 17 00:00:00 2001 From: Alex Tearse-Doyle Date: Wed, 15 Sep 2021 23:28:28 -0700 Subject: [PATCH] 1.3 updates. Used bool onlyUseInventory which is true when drafted-ordered-to-tend apparently playerSettings can be null, so... hopefully other things aren't broken but don't check for null. Deleting old transpiler inside MakeNewToils didn't apply and seemingly didn't matter --- Source/GetPawnMedicalCareCategory.cs | 1 - Source/MedicineGrabbing.cs | 123 +++++++-------------------- 2 files changed, 31 insertions(+), 93 deletions(-) diff --git a/Source/GetPawnMedicalCareCategory.cs b/Source/GetPawnMedicalCareCategory.cs index 311d18f..b778390 100644 --- a/Source/GetPawnMedicalCareCategory.cs +++ b/Source/GetPawnMedicalCareCategory.cs @@ -34,7 +34,6 @@ public static MedicalCareCategory GetCare(this Pawn pawn) else { care = pawn.playerSettings?.medCare ?? MedicalCareCategory.NoCare; - Log.Message($"Care for {pawn} is {care}"); } return care; } diff --git a/Source/MedicineGrabbing.cs b/Source/MedicineGrabbing.cs index 3639850..d910790 100644 --- a/Source/MedicineGrabbing.cs +++ b/Source/MedicineGrabbing.cs @@ -251,70 +251,6 @@ public static IEnumerable Transpiler(IEnumerable check = m => m.Name.Contains("MakeNewToils"); - - harmony.PatchGeneratedMethod(typeof(JobDriver_TendPatient), check, transpiler: transpiler); - } - public static IEnumerable Transpiler(IEnumerable instructions) - { - MethodInfo FindBestMedicineInfo = AccessTools.Method(typeof(HealthAIUtility), nameof(HealthAIUtility.FindBestMedicine)); - MethodInfo FindInfo = AccessTools.Method(typeof(FindBestMedicine), nameof(FindBestMedicine.Find)); - - - //MethodInfo FirstOrDefaultInfo = AccessTools.Method(typeof(Enumerable), "FirstOrDefault", new Type[] { typeof(IEnumerable) }, new Type[] { typeof(IEnumerable) }); - //MethodInfo FirstOrDefaultInfo = AccessTools.FirstMethod(typeof(Enumerable), mi => mi.Name == "FirstOrDefault" && mi.GetParameters().Count() == 1); - //FirstOrDefaultInfo = FirstOrDefaultInfo.MakeGenericMethod(new Type[] { typeof(IEnumerable) }); - //MethodInfo ThingCountThingInfo = AccessTools.Property(typeof(ThingCount), "Thing").GetGetMethod(); - - // - MethodInfo GetTheBloodyThingInfo = AccessTools.Method(typeof(MakeNewToils_Patch), "GetTheBloodyThing"); - - FieldInfo jobFieldInfo = AccessTools.Field( - typeof(JobDriver), nameof(JobDriver.job)); - FieldInfo jobCountInfo = AccessTools.Field( - typeof(Job), nameof(Job.count)); - List iList = instructions.ToList(); - List jobInstructions = new List(); - for (int i = 0; i < iList.Count(); i++) - { - if (iList[i].LoadsField(jobFieldInfo)) - { - jobInstructions.AddRange(iList.GetRange(i - 3, 4)); - break; - } - } - - foreach (CodeInstruction i in instructions) - { - if (i.Calls(FindBestMedicineInfo)) - { - foreach (CodeInstruction jobI in jobInstructions) - yield return jobI; - yield return new CodeInstruction(OpCodes.Ldflda, jobCountInfo); - yield return new CodeInstruction(OpCodes.Call, FindInfo); - yield return new CodeInstruction(OpCodes.Call, GetTheBloodyThingInfo); - //yield return new CodeInstruction(OpCodes.Call, FirstOrDefaultInfo); - //yield return new CodeInstruction(OpCodes.Call, ThingCountThingInfo); - } - else yield return i; - } - } - public static Thing GetTheBloodyThing(List x) - { - return x.FirstOrDefault().Thing; - } - } - - [HarmonyPatch(typeof(HealthAIUtility))] [HarmonyPatch("FindBestMedicine")] [HarmonyBefore(new string[] { "fluffy.rimworld.pharmacist" })] @@ -378,17 +314,17 @@ static FindBestMedicine() } //FindBestMedicine Replacement - private static bool Prefix(Pawn healer, Pawn patient, ref Thing __result) + private static bool Prefix(Pawn healer, Pawn patient, ref Thing __result, bool onlyUseInventory = false) { if (patient.GetCare() <= MedicalCareCategory.NoMeds || Medicine.GetMedicineCountToFullyHeal(patient) <= 0) return true; - __result = Find(healer, patient, out int dummy).FirstOrDefault().Thing; + __result = Find(healer, patient, out int dummy, onlyUseInventory).FirstOrDefault().Thing; return false; } //public static Thing FindBestMedicine(Pawn healer, Pawn patient) - public static List Find(Pawn healer, Pawn patient, out int totalCount) + public static List Find(Pawn healer, Pawn patient, out int totalCount, bool onlyUseInventory = false) { totalCount = 0; Log.Message($"{healer} is tending to {patient}"); @@ -418,7 +354,7 @@ public static List Find(Pawn healer, Pawn patient, out int totalCoun finalCare = toUse > finalCare ? toUse : finalCare; } - Log.Message($"defaultCare = {defaultCare}, care = {finalCare}"); + Log.Message($"Care for {patient} is {defaultCare}, Custom care = {finalCare}"); //Android Droid support; Predicate validatorDroid = t => true; @@ -429,17 +365,35 @@ public static List Find(Pawn healer, Pawn patient, out int totalCoun validatorDroid = t => t.def.modExtensions?.Any(e => extRepair.IsAssignableFrom(e.GetType())) ?? false; } - //Med - Predicate validatorMed = t => finalCare.AllowsMedicine(t.def) && validatorDroid(t); + //Find valid Meds: + List allMeds = new List(); - //Ground + Predicate validatorMed = t => finalCare.AllowsMedicine(t.def) && validatorDroid(t); Map map = patient.Map; TraverseParms traverseParams = TraverseParms.For(healer, Danger.Deadly, TraverseMode.ByPawn, false); - Predicate validator = (Thing t) => validatorMed(t) - && map.reachability.CanReach(patient.Position, t, PathEndMode.ClosestTouch, traverseParams) - && !t.IsForbidden(healer) && healer.CanReserve(t, FindBestMedicine.maxPawns, 1);//can reserve at least 1 - Func priorityGetter = (Thing t) => MedicineRating(t, sufficientQuality); - List groundMedicines = patient.Map.listerThings.ThingsInGroup(isDroid?ThingRequestGroup.HaulableEver:ThingRequestGroup.Medicine).FindAll(t => validator(t)); + + //Ground + if (!onlyUseInventory) + { + Predicate validator = (Thing t) => validatorMed(t) + && map.reachability.CanReach(patient.Position, t, PathEndMode.ClosestTouch, traverseParams) + && !t.IsForbidden(healer) && healer.CanReserve(t, FindBestMedicine.maxPawns, 1);//can reserve at least 1 + Func priorityGetter = (Thing t) => MedicineRating(t, sufficientQuality); + List groundMedicines = map.listerThings.ThingsInGroup(isDroid ? ThingRequestGroup.HaulableEver : ThingRequestGroup.Medicine).FindAll(t => validator(t)); + + //Add each ground + foreach (Thing t in groundMedicines) + allMeds.Add(new MedicineEvaluator() + { + thing = t, + pawn = null, + rating = MedicineRating(t, sufficientQuality), + distance = DistanceTo(t, healer, patient) + }); + } + + //Ground-only medicines: + List groundEvaluators = allMeds.ListFullCopy(); //Pawns Predicate validatorHolder = (Pawn p) => @@ -463,21 +417,6 @@ public static List Find(Pawn healer, Pawn patient, out int totalCoun pawns.RemoveAll(p => !validatorHolder(p)); - //Evaluate them all - List allMeds = new List(); - - //Add each ground - foreach (Thing t in groundMedicines) - allMeds.Add(new MedicineEvaluator() - { - thing = t, - pawn = null, - rating = MedicineRating(t, sufficientQuality), - distance = DistanceTo(t, healer, patient) - }); - - List groundEvaluators = allMeds.ListFullCopy(); - //Add best from each pawn foreach (Pawn p in pawns) { @@ -574,7 +513,7 @@ public static List HediffsToTend(Pawn patient) private static Thing FindBestMedicineInInventory(Pawn pawn, Pawn patient, Predicate validatorMed, float sufficientQuality, bool isHealer) { - if (pawn == null || pawn.inventory == null || patient == null || patient.playerSettings == null) + if (pawn == null || pawn.inventory == null || patient == null) return null; List items = new List(pawn.inventory.innerContainer.InnerListForReading);