Added gas grid optimization, various despawn optimizations, new hauling optimizations utilizing events and regions, bugfixes for old patches and for vanilla functions too, as well as smaller additions. 1.3 files removed.
This commit is contained in:
@@ -3,12 +3,16 @@
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
using PerformanceFish.ModCompatibility;
|
||||
|
||||
namespace PerformanceFish.JobSystem;
|
||||
|
||||
public class DisabledWorkTypesOptimization : ClassWithFishPatches
|
||||
public sealed class DisabledWorkTypesOptimization : ClassWithFishPatches
|
||||
{
|
||||
public class PawnGetDisabledWorkTypes : FishPatch
|
||||
public sealed class PawnGetDisabledWorkTypes : FishPatch
|
||||
{
|
||||
public override List<string> IncompatibleModIDs { get; } = [PackageIDs.MULTIPLAYER];
|
||||
|
||||
public override string? Description { get; }
|
||||
= "Essentially fixes a bug in Pawn.GetDisabledWorkTypes that causes the method to discard its cache and "
|
||||
+ "constantly keep recalculating. With the patch applied it'll return early when a valid cache exists.";
|
||||
|
||||
@@ -9,9 +9,9 @@ using Verse.AI;
|
||||
|
||||
namespace PerformanceFish.JobSystem;
|
||||
|
||||
public class GenClosestPatches : ClassWithFishPatches
|
||||
public sealed class GenClosestPatches : ClassWithFishPatches
|
||||
{
|
||||
public class ClosestThing_Global_Patch : FishPatch
|
||||
public sealed class ClosestThing_Global_Patch : FishPatch
|
||||
{
|
||||
public override string Description { get; } = "Threading for job scanning. Disabled and unstable.";
|
||||
public override bool DefaultState => false;
|
||||
@@ -226,29 +226,4 @@ public class GenClosestPatches : ClassWithFishPatches
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if threadingEnabled
|
||||
public class CanReach_Patch : FishPatch
|
||||
{
|
||||
protected CanReach_Patch() => FishSettings.ThreadingPatches.Add(this);
|
||||
public override bool DefaultState => false;
|
||||
public override string Description { get; }
|
||||
= "Lock for threading. Only needed with threading enabled and off by default";
|
||||
public override Expression<Action> TargetMethod { get; }
|
||||
= static () => default(Reachability)!.CanReach(default, null, default, default);
|
||||
public static void Prefix()
|
||||
{
|
||||
if (FishSettings.ThreadingEnabled)
|
||||
Monitor.Enter(Lock);
|
||||
}
|
||||
|
||||
public static Exception Finalizer(Exception __exception)
|
||||
{
|
||||
if (FishSettings.ThreadingEnabled)
|
||||
Monitor.Exit(Lock);
|
||||
return __exception;
|
||||
}
|
||||
private static object Lock { get; } = new();
|
||||
}
|
||||
#endif
|
||||
//}
|
||||
@@ -7,22 +7,21 @@ using PerformanceFish.ModCompatibility;
|
||||
|
||||
namespace PerformanceFish.JobSystem;
|
||||
|
||||
public class JobGiver_HaulOptimization : ClassWithFishPatches
|
||||
public sealed class JobGiver_HaulOptimization : ClassWithFishPatches
|
||||
{
|
||||
public class PotentialWorkThingsGlobal_Patch : FishPatch
|
||||
public sealed class PotentialWorkThingsGlobal_Patch : FishPatch
|
||||
{
|
||||
public override List<string> IncompatibleModIDs { get; } = [PackageIDs.MULTIPLAYER];
|
||||
|
||||
public override string Description { get; }
|
||||
= "Sorts haulables by distance before running expensive hauling calculations on them to avoid checks on "
|
||||
+ "far away items";
|
||||
+ "far away items";
|
||||
|
||||
public override MethodBase TargetMethodInfo { get; }
|
||||
= AccessTools.Method(typeof(JobGiver_Haul), nameof(JobGiver_Haul.TryGiveJob));
|
||||
|
||||
public static CodeInstructions? Transpiler(CodeInstructions codes, MethodBase method)
|
||||
{
|
||||
if (ActiveMods.Multiplayer) // PUAH has known issues with sorting and multiplayer
|
||||
return codes;
|
||||
|
||||
var pawn_Map_listerHaulables_ThingsPotentiallyNeedingHauling
|
||||
= FishTranspiler.Call(static () => default(ListerHaulables)!.ThingsPotentiallyNeedingHauling());
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@ using static PerformanceFish.TranspilerHelpers;
|
||||
|
||||
namespace PerformanceFish.JobSystem;
|
||||
|
||||
public class JobGiver_WorkPatches : ClassWithFishPatches
|
||||
public sealed class JobGiver_WorkPatches : ClassWithFishPatches
|
||||
{
|
||||
public class TryIssueJobPackage_InnerDelegate_Patch : FishPatch
|
||||
public sealed class TryIssueJobPackage_InnerDelegate_Patch : FishPatch
|
||||
{
|
||||
public override string Description => "Work scanning optimization. Splits the IsForbidden and HasJobOnThing checks into separate loops, then threads the IsForbidden loop, sorts it, caches the result and skips any following duplicate checks";
|
||||
public override MethodBase TargetMethodInfo => AccessTools.FindIncludingInnerTypes(typeof(JobGiver_Work),
|
||||
@@ -44,7 +44,7 @@ public class JobGiver_WorkPatches : ClassWithFishPatches
|
||||
}
|
||||
}
|
||||
|
||||
public class TryIssueJobPackage_Patch : FishPatch
|
||||
public sealed class TryIssueJobPackage_Patch : FishPatch
|
||||
{
|
||||
public override string Description => "Work scanning optimization. Splits the IsForbidden and HasJobOnThing checks into separate loops, then threads the IsForbidden loop, sorts it, caches the result and skips any following duplicate checks";
|
||||
public override MethodBase TargetMethodInfo => AccessTools.Method(typeof(JobGiver_Work), nameof(JobGiver_Work.TryIssueJobPackage));
|
||||
@@ -243,7 +243,7 @@ public class JobGiver_WorkPatches : ClassWithFishPatches
|
||||
public static Dictionary<IEnumerable<Thing>, IEnumerable<Thing>> PrefilteredPotentialWorkThingsGlobal { get; } = new();
|
||||
}
|
||||
|
||||
public class ThingRequest_IsUndefined_Patch : FishPatch
|
||||
public sealed class ThingRequest_IsUndefined_Patch : FishPatch
|
||||
{
|
||||
public override string Description => "Part of the work scanning optimization";
|
||||
public override MethodBase TargetMethodInfo => AccessTools.PropertyGetter(typeof(ThingRequest), nameof(ThingRequest.IsUndefined));
|
||||
@@ -259,7 +259,7 @@ public class JobGiver_WorkPatches : ClassWithFishPatches
|
||||
=> __instance.group == ThingRequestGroup.Undefined && !((FishCache)__instance.singleDef).IsSingleDef;
|
||||
}
|
||||
|
||||
public class ThingRequest_CanBeFoundInRegion_Patch : FirstPriorityFishPatch
|
||||
public sealed class ThingRequest_CanBeFoundInRegion_Patch : FirstPriorityFishPatch
|
||||
{
|
||||
public override string Description => "Part of the work scanning optimization";
|
||||
public override MethodBase TargetMethodInfo => AccessTools.PropertyGetter(typeof(ThingRequest), nameof(ThingRequest.CanBeFoundInRegion));
|
||||
@@ -276,7 +276,7 @@ public class JobGiver_WorkPatches : ClassWithFishPatches
|
||||
|| (__instance.group != ThingRequestGroup.Undefined && (__instance.group == ThingRequestGroup.Nothing || __instance.group.StoreInRegion()));
|
||||
}
|
||||
|
||||
public class ListerThings_ThingsMatching_Patch : FirstPriorityFishPatch
|
||||
public sealed class ListerThings_ThingsMatching_Patch : FirstPriorityFishPatch
|
||||
{
|
||||
public override string Description => "Part of the work scanning optimization";
|
||||
public override Expression<Action> TargetMethod => () => new ListerThings(default).ThingsMatching(default);
|
||||
|
||||
@@ -5,44 +5,55 @@
|
||||
|
||||
using System.Linq;
|
||||
using System.Reflection.Emit;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using PerformanceFish.Prepatching;
|
||||
using Verse.AI;
|
||||
using IngredientCacheList
|
||||
= PerformanceFish.Utility.KeyedList<Verse.IngredientCount, (System.Collections.Generic.List<Verse.ThingDef> Defs,
|
||||
bool Found)>;
|
||||
using OpCodes = System.Reflection.Emit.OpCodes;
|
||||
using RecipeIngredientCache
|
||||
= PerformanceFish.Cache.ByIndex<RimWorld.Bill,
|
||||
PerformanceFish.JobSystem.WorkGiver_DoBillOptimization.RecipeIngredientCacheValue>;
|
||||
|
||||
namespace PerformanceFish.JobSystem;
|
||||
|
||||
public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
public sealed class WorkGiver_DoBillPrepatches : ClassWithFishPrepatches
|
||||
{
|
||||
public static List<Type?> BlackListedModExtensions
|
||||
=> _blackListedModExtensions ??= new() { Reflection.Type("VFEAncients", "VFEAncients.RecipeExtension_Mend") };
|
||||
public static List<Type> BlackListedModExtensions
|
||||
=> _blackListedModExtensions ??= InitializeBlackListedModExtensions();
|
||||
|
||||
private static List<Type?>? _blackListedModExtensions;
|
||||
|
||||
public class TryFindBestIngredientsHelper_InnerDelegate_Patch : FirstPriorityFishPatch
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static List<Type> InitializeBlackListedModExtensions()
|
||||
{
|
||||
var list = new List<Type>();
|
||||
|
||||
if (ModCompatibility.Types.VFEAncients.RecipeExtensionMend is { } VFEAncientsRecipeExtension)
|
||||
list.Add(VFEAncientsRecipeExtension);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static List<Type>? _blackListedModExtensions;
|
||||
|
||||
public sealed class TryFindBestIngredientsHelper_InnerDelegate_Patch : FishPrepatch
|
||||
{
|
||||
public override List<string> IncompatibleModIDs { get; }
|
||||
= [ModCompatibility.PackageIDs.USE_BEST_MATERIALS];
|
||||
|
||||
public override List<Type> LinkedPatches { get; } =
|
||||
[
|
||||
typeof(WorkGiver_DoBillOptimization.TryFindBestIngredientsHelper_Patch),
|
||||
typeof(WorkGiver_DoBillOptimization.TryFindBestIngredientsInSet_NoMixHelper_Patch)
|
||||
];
|
||||
|
||||
public override string Description { get; }
|
||||
= "Optimizes WorkGiver_DoBill to only check things that get accepted by a bill's filter for its "
|
||||
+ "ingredient lookup, instead of looping over everything and then checking filters afterwards. "
|
||||
+ "Also caches these filter acceptances. Large performance impact.";
|
||||
|
||||
public override bool Enabled
|
||||
{
|
||||
set
|
||||
{
|
||||
if (base.Enabled == value)
|
||||
return;
|
||||
|
||||
Get<TryFindBestIngredientsHelper_Patch>().Enabled
|
||||
= Get<TryFindBestIngredientsInSet_NoMixHelper_Patch>().Enabled
|
||||
= base.Enabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override MethodBase TargetMethodInfo { get; }
|
||||
public override MethodBase TargetMethodBase { get; }
|
||||
= AccessTools.FirstMethod(DelegateInstanceType, static m
|
||||
=> m.GetParameters() is { Length: 1 } parameterInfos
|
||||
&& parameterInfos[0].ParameterType == typeof(Region)
|
||||
@@ -52,12 +63,15 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
&& instruction.operand is MethodInfo info
|
||||
&& info == AccessTools.Method(typeof(ListerThings), nameof(ListerThings.ThingsMatching))));
|
||||
|
||||
public static CodeInstructions Transpiler(CodeInstructions codeInstructions, MethodBase method)
|
||||
=> Reflection.MakeReplacementCall(AccessTools.Method(
|
||||
typeof(TryFindBestIngredientsHelper_InnerDelegate_Patch), nameof(Replacement),
|
||||
generics: new[] { DelegateInstanceType }));
|
||||
public override void Transpiler(ILProcessor ilProcessor, ModuleDefinition module)
|
||||
=> ilProcessor.ReplaceBodyWith(ReplacementBody);
|
||||
|
||||
public static bool Replacement<T>(T __instance, Region r) where T : class
|
||||
// public static CodeInstructions Transpiler(CodeInstructions codeInstructions, MethodBase method)
|
||||
// => Reflection.MakeReplacementCall(AccessTools.Method(
|
||||
// typeof(TryFindBestIngredientsHelper_InnerDelegate_Patch), nameof(ReplacementBody),
|
||||
// generics: new[] { DelegateInstanceType }));
|
||||
|
||||
public static bool ReplacementBody(object __instance, Region r)
|
||||
{
|
||||
var instance = _delegateInstance.Get(__instance);
|
||||
var thingValidator = _thingValidatorInstance.Get(instance.ThingValidator.Target);
|
||||
@@ -75,7 +89,7 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
#if V1_4
|
||||
|| bill.billStack?.billGiver is Building_MechGestator
|
||||
#endif
|
||||
|| (BlackListedModExtensions.Exists(static b => b != null)
|
||||
|| (BlackListedModExtensions.Count > 0
|
||||
&& IsBlackListed(bill))) // <-- Fuck these too
|
||||
{
|
||||
list = GetDefaultList(r);
|
||||
@@ -89,7 +103,7 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
cache.Update(bill);
|
||||
}
|
||||
|
||||
list = GetList(r.listerThings.listsByDef, cache.thingDefs);
|
||||
list = GetList(r, cache.thingDefs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,10 +124,9 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
|
||||
instance.FoundAll = true;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private static bool HasNoFilters(Bill bill)
|
||||
public static bool HasNoFilters(Bill bill)
|
||||
=> bill.ingredientFilter is null
|
||||
|| bill.recipe.fixedIngredientFilter is null;
|
||||
|
||||
@@ -135,13 +148,13 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
return false;
|
||||
}*/
|
||||
|
||||
private static bool IsBlackListed(Bill? bill)
|
||||
public static bool IsBlackListed(Bill? bill)
|
||||
=> bill is null
|
||||
|| bill.recipe.modExtensions.ExistsAndNotNull(static e
|
||||
=> BlackListedModExtensions.Contains(e.GetType()));
|
||||
|
||||
private static List<Thing> GetDefaultList(Region r)
|
||||
=> r.ListerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver));
|
||||
public static List<Thing> GetDefaultList(Region r)
|
||||
=> r.listerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver));
|
||||
|
||||
public static void InsertAtCorrectPosition(List<Thing> list, List<Thing> thingsToInsert, Pawn pawn)
|
||||
{
|
||||
@@ -159,7 +172,8 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly ThingPositionComparer _insertAtCorrectPositionComparer = new();
|
||||
private static readonly WorkGiver_DoBillOptimization.ThingPositionComparer _insertAtCorrectPositionComparer
|
||||
= new();
|
||||
|
||||
public static void ActualLoop(List<Thing> list, Region r, Pawn pawn, Predicate<Thing> baseValidator,
|
||||
bool billGiverIsPawn)
|
||||
@@ -182,8 +196,10 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Thing> GetList(Dictionary<ThingDef, List<Thing>> listsByDef, IngredientCacheList cacheList)
|
||||
public static List<Thing> GetList(Region region, IngredientCacheList cacheList)
|
||||
{
|
||||
var listsByDef = region.listerThings.listsByDef;
|
||||
|
||||
var list = _tempListForIngredients;
|
||||
list.Clear();
|
||||
var set = _tempSetForIngredientDefs;
|
||||
@@ -216,7 +232,7 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
{
|
||||
var recipe = bill.recipe;
|
||||
var ingredients = recipe.ingredients;
|
||||
var listsByDef = r.Map.listerThings.listsByDef;
|
||||
var listsByDef = r.GetMap().listerThings.listsByDef;
|
||||
var result = cacheList ?? new(3);
|
||||
|
||||
for (var i = 0; i < ingredients.Count;
|
||||
@@ -229,7 +245,7 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
}
|
||||
else
|
||||
{
|
||||
result[ingredients[i]] = ingredientList = new(new(), false);
|
||||
result[ingredients[i]] = ingredientList = new([], false);
|
||||
}
|
||||
|
||||
var filter = ingredients[i].filter;
|
||||
@@ -291,8 +307,8 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
(mediumFilter, largestFilter) = (largestFilter, mediumFilter);
|
||||
}
|
||||
|
||||
private static readonly List<Thing> _tempListForIngredients = new();
|
||||
private static readonly HashSet<ThingDef> _tempSetForIngredientDefs = new();
|
||||
private static readonly List<Thing> _tempListForIngredients = [];
|
||||
private static readonly HashSet<ThingDef> _tempSetForIngredientDefs = [];
|
||||
}
|
||||
|
||||
private static Type DelegateInstanceType { get; }
|
||||
@@ -308,8 +324,8 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
&& AccessTools.Field(t, "foundAllIngredientsAndChoose") != null
|
||||
&& AccessTools.Field(t, "foundAll") != null
|
||||
&& AccessTools.Field(t, "thingValidator") != null)
|
||||
?? throw new("Performance Fish failed to find the target type for its WorkGiver_DoBill patch. "
|
||||
+ "This means that specific patch won't apply.");
|
||||
?? ThrowHelper.ThrowInvalidOperationException<Type>("Performance Fish failed to find the target type "
|
||||
+ "for its WorkGiver_DoBill patch. This means that specific patch won't apply.");
|
||||
|
||||
private static Type ThingValidatorInstanceType { get; }
|
||||
= AccessTools.FirstInner(typeof(WorkGiver_DoBill), static t
|
||||
@@ -320,20 +336,20 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
//&& AccessTools.Field(t, "chosen") != null
|
||||
//&& AccessTools.Field(t, "billGiver") != null
|
||||
/*&& AccessTools.Field(t, "pawn") != null*/)
|
||||
?? throw new("Performance Fish failed to find the thingValidator type for its WorkGiver_DoBill patch. "
|
||||
+ "This likely flat out breaks the entire patch.");
|
||||
?? ThrowHelper.ThrowInvalidOperationException<Type>("Performance Fish failed to find the thingValidator "
|
||||
+ "type for its WorkGiver_DoBill patch. This likely flat out breaks the entire patch.");
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
private static DelegateInstance _delegateInstance { get; }
|
||||
public static DelegateInstance _delegateInstance { get; }
|
||||
= (DelegateInstance)Activator.CreateInstance(
|
||||
typeof(DelegateInstanceImplementation<>).MakeGenericType(DelegateInstanceType));
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
private static ThingValidatorInstance _thingValidatorInstance { get; }
|
||||
public static ThingValidatorInstance _thingValidatorInstance { get; }
|
||||
= (ThingValidatorInstance)Activator.CreateInstance(
|
||||
typeof(ThingValidatorInstanceImplementation<>).MakeGenericType(ThingValidatorInstanceType));
|
||||
|
||||
private abstract class DelegateInstance
|
||||
public abstract class DelegateInstance
|
||||
{
|
||||
public abstract DelegateInstance Get(object obj);
|
||||
|
||||
@@ -347,7 +363,7 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
public abstract Predicate<Thing> ThingValidator { get; set; }
|
||||
}
|
||||
|
||||
private class DelegateInstanceImplementation<T> : DelegateInstance where T : class
|
||||
private sealed class DelegateInstanceImplementation<T> : DelegateInstance where T : class
|
||||
{
|
||||
#pragma warning disable CS8618
|
||||
private T _instance;
|
||||
@@ -430,7 +446,7 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
= AccessTools.FieldRefAccess<T, Predicate<Thing>>("thingValidator");
|
||||
}
|
||||
|
||||
private abstract class ThingValidatorInstance
|
||||
public abstract class ThingValidatorInstance
|
||||
{
|
||||
public abstract ThingValidatorInstance? Get(object obj);
|
||||
|
||||
@@ -438,7 +454,7 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
//public abstract Thing BillGiver { get; set; }
|
||||
}
|
||||
|
||||
private class ThingValidatorInstanceImplementation<T> : ThingValidatorInstance where T : class
|
||||
private sealed class ThingValidatorInstanceImplementation<T> : ThingValidatorInstance where T : class
|
||||
{
|
||||
#pragma warning disable CS8618
|
||||
private T _instance;
|
||||
@@ -467,27 +483,21 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
private static AccessTools.FieldRef<T, Bill> _bill = AccessTools.FieldRefAccess<T, Bill>("bill");
|
||||
//private static AccessTools.FieldRef<T, Thing> _billGiver = AccessTools.FieldRefAccess<T, Thing>("billGiver");
|
||||
}
|
||||
}
|
||||
|
||||
public class TryFindBestIngredientsHelper_Patch : FishPatch
|
||||
public sealed class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
{
|
||||
public sealed class TryFindBestIngredientsHelper_Patch : FishPatch
|
||||
{
|
||||
public override bool ShowSettings => false;
|
||||
|
||||
public override string Description { get; } = "Part of the DoBill optimization";
|
||||
|
||||
public override bool Enabled
|
||||
{
|
||||
set
|
||||
{
|
||||
if (base.Enabled == value)
|
||||
return;
|
||||
|
||||
Get<TryFindBestIngredientsInSet_NoMixHelper_Patch>().Enabled = base.Enabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override Delegate TargetMethodGroup { get; } = WorkGiver_DoBill.TryFindBestIngredientsHelper;
|
||||
|
||||
public static void Postfix(Predicate<Thing> thingValidator)
|
||||
{
|
||||
var thingValidatorInstance = _thingValidatorInstance.Get(thingValidator.Target);
|
||||
var thingValidatorInstance = WorkGiver_DoBillPrepatches._thingValidatorInstance.Get(thingValidator.Target);
|
||||
if (thingValidatorInstance is null)
|
||||
return;
|
||||
|
||||
@@ -505,8 +515,10 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
}
|
||||
}
|
||||
|
||||
public class TryFindBestIngredientsInSet_NoMixHelper_Patch : FishPatch
|
||||
public sealed class TryFindBestIngredientsInSet_NoMixHelper_Patch : FishPatch
|
||||
{
|
||||
public override List<Type> LinkedPatches { get; } = [typeof(TryFindBestIngredientsHelper_Patch)];
|
||||
|
||||
public override string Description { get; }
|
||||
= "Part of the DoBill optimization. Bills that need multiple ingredients, like for example steel and "
|
||||
+ "components for guns, normally scan their surroundings for all those ingredients and count them, until "
|
||||
@@ -515,17 +527,6 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
+ "case of steel and components that could mean not having to go over 100s of steel stacks at times. "
|
||||
+ "Prevents large spikes from these situations, does nothing for all other bills.";
|
||||
|
||||
public override bool Enabled
|
||||
{
|
||||
set
|
||||
{
|
||||
if (base.Enabled == value)
|
||||
return;
|
||||
|
||||
Get<TryFindBestIngredientsHelper_Patch>().Enabled = base.Enabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override Delegate TargetMethodGroup { get; } = WorkGiver_DoBill.TryFindBestIngredientsInSet_NoMixHelper;
|
||||
|
||||
public static void Prefix(ref bool alreadySorted, Bill? bill)
|
||||
@@ -549,16 +550,15 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
&& codes[i + 1] == FishTranspiler.Constant(1) // i++;
|
||||
&& codes[i + 2] == FishTranspiler.Add
|
||||
&& codes[i + 3] == i_variable.Store(),
|
||||
code
|
||||
=> new[]
|
||||
{
|
||||
code =>
|
||||
[
|
||||
new(OpCodes.Br_S, new_i_label), // else
|
||||
FishTranspiler.FirstLocalVariable(method, typeof(IngredientCount))
|
||||
.WithLabels(code.ExtractLabels()),
|
||||
FishTranspiler.FirstArgument(method, typeof(Bill)),
|
||||
FishTranspiler.Call(MarkIngredientCountAsFound),
|
||||
code.WithLabels(new_i_label)
|
||||
});
|
||||
]);
|
||||
|
||||
// if (!flag)
|
||||
// {
|
||||
@@ -599,7 +599,7 @@ public class WorkGiver_DoBillOptimization : ClassWithFishPatches
|
||||
}
|
||||
}
|
||||
|
||||
public class ThingPositionComparer : IComparer<Thing>
|
||||
public sealed class ThingPositionComparer : IComparer<Thing>
|
||||
{
|
||||
public IntVec3 rootCell;
|
||||
|
||||
|
||||
@@ -7,15 +7,15 @@ using PerformanceFish.ModCompatibility;
|
||||
|
||||
namespace PerformanceFish.JobSystem;
|
||||
|
||||
public class WorkGiver_HaulOptimization : ClassWithFishPatches
|
||||
public sealed class WorkGiver_HaulOptimization : ClassWithFishPatches
|
||||
{
|
||||
public class PotentialWorkThingsGlobal_Patch : FishPatch
|
||||
public sealed class PotentialWorkThingsGlobal_Patch : FishPatch
|
||||
{
|
||||
public override bool Enabled => base.Enabled && !ActiveMods.Multiplayer;
|
||||
|
||||
public override List<string> IncompatibleModIDs { get; } = [PackageIDs.MULTIPLAYER];
|
||||
|
||||
public override string Description { get; }
|
||||
= "Sorts haulables by distance before running expensive hauling calculations on them to avoid checks on "
|
||||
+ "far away items";
|
||||
+ "far away items";
|
||||
|
||||
public override MethodBase TargetMethodInfo { get; }
|
||||
= AccessTools.Method(typeof(WorkGiver_Haul), nameof(WorkGiver_Haul.PotentialWorkThingsGlobal));
|
||||
|
||||
@@ -7,13 +7,13 @@ using Verse.AI;
|
||||
|
||||
namespace PerformanceFish.JobSystem;
|
||||
|
||||
public class WorkGiver_MergeOptimization : ClassWithFishPatches
|
||||
public sealed class WorkGiver_MergeOptimization : ClassWithFishPatches
|
||||
{
|
||||
public class JobOnThing_Patch : FishPatch
|
||||
public sealed class JobOnThing_Patch : FishPatch
|
||||
{
|
||||
public override string Description { get; }
|
||||
= "Removes mergeables from ListerMergeables if they no longer qualify as mergeable when trying to check "
|
||||
+ "for a merging job on them. Vanilla RimWorld just fails and keeps them in";
|
||||
+ "for a merging job on them. Vanilla RimWorld just fails and keeps them in";
|
||||
|
||||
public override MethodBase TargetMethodInfo { get; }
|
||||
= AccessTools.Method(typeof(WorkGiver_Merge), nameof(WorkGiver_Merge.JobOnThing));
|
||||
@@ -23,14 +23,16 @@ public class WorkGiver_MergeOptimization : ClassWithFishPatches
|
||||
if (t.GetSlotGroup() is not null)
|
||||
return true;
|
||||
|
||||
RemoveFromListerMergeables(t);
|
||||
TryRemoveFromListerMergeables(t);
|
||||
__result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void RemoveFromListerMergeables(Thing t)
|
||||
private static void TryRemoveFromListerMergeables(Thing t)
|
||||
{
|
||||
var map = t.MapHeld;
|
||||
if (t.TryGetMapHeld() is not { } map)
|
||||
return;
|
||||
|
||||
map.listerMergeables.TryRemove(t);
|
||||
map.listerHaulables.Check(t);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user