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:
@@ -11,14 +11,14 @@ using RimWorld.Planet;
|
||||
|
||||
namespace PerformanceFish.Planet;
|
||||
|
||||
public class MothballOptimization : ClassWithFishPrepatches
|
||||
public sealed class MothballOptimization : ClassWithFishPrepatches
|
||||
{
|
||||
public const string BASIC_DESCRIPTION
|
||||
= "Mothballing means to \"take something out of operation but maintain it so that it can be used in the "
|
||||
+ "future.\" RimWorld has this system for world pawns along with a number of conditions which can block it "
|
||||
+ "from taking effect.";
|
||||
|
||||
public class WorldPawnsDefPreventingMothball : FishPrepatch
|
||||
public sealed class WorldPawnsDefPreventingMothball : FishPrepatch
|
||||
{
|
||||
public override string? Description { get; }
|
||||
= BASIC_DESCRIPTION + " This patch essentially serves as a whitelist to allow mothballing a lot more "
|
||||
|
||||
@@ -11,9 +11,9 @@ using RimWorld.Planet;
|
||||
|
||||
namespace PerformanceFish.Planet;
|
||||
|
||||
public class WorldObjectsOptimization : ClassWithFishPrepatches
|
||||
public sealed class WorldObjectsOptimization : ClassWithFishPrepatches
|
||||
{
|
||||
public class WorldObjectsHolderTickPatch : FishPrepatch
|
||||
public sealed class WorldObjectsHolderTickPatch : FishPrepatch
|
||||
{
|
||||
public override string? Description { get; }
|
||||
= "The world objects holder is responsible for ticking every world object. This includes settlements, "
|
||||
@@ -87,24 +87,46 @@ public class WorldObjectsOptimization : ClassWithFishPrepatches
|
||||
CachedWorldObjectsVersion = -2,
|
||||
CachedMapsVersion = -2;
|
||||
|
||||
private static Type[]
|
||||
_whitelistedTickingCompTypes
|
||||
=
|
||||
{
|
||||
typeof(WorldObjectComp),
|
||||
typeof(FormCaravanComp),
|
||||
typeof(TimedDetectionRaids),
|
||||
typeof(EnterCooldownComp)
|
||||
},
|
||||
_whitelistedWorldObjectTypes = { typeof(WorldObject), typeof(MapParent), typeof(Settlement) };
|
||||
private static Type?[]
|
||||
_whitelistedTickingCompTypes =
|
||||
[
|
||||
typeof(WorldObjectComp),
|
||||
typeof(FormCaravanComp),
|
||||
typeof(TimedDetectionRaids),
|
||||
typeof(EnterCooldownComp)
|
||||
],
|
||||
_whitelistedWorldObjectTypes =
|
||||
[
|
||||
typeof(WorldObject),
|
||||
typeof(MapParent),
|
||||
typeof(Settlement),
|
||||
ModCompatibility.Types.RealRuins.POIWorldObject
|
||||
];
|
||||
|
||||
public static void AddCompToWhiteList(Type compType)
|
||||
{
|
||||
_whitelistedTickingCompTypes = _whitelistedTickingCompTypes.Add(compType);
|
||||
SkippableComps = InitializeSkippableComps();
|
||||
}
|
||||
|
||||
public static void AddWorldObjectToWhiteList(Type worldObjectType)
|
||||
{
|
||||
_whitelistedWorldObjectTypes = _whitelistedWorldObjectTypes.Add(worldObjectType);
|
||||
SkippableWorldObjects = InitializeSkippableWorldObjects();
|
||||
}
|
||||
|
||||
public static HashSet<Type>
|
||||
SkippableComps = MakeSubclassHashSet(typeof(WorldObjectComp), nameof(WorldObjectComp.CompTick),
|
||||
_whitelistedTickingCompTypes),
|
||||
SkippableWorldObjects = MakeSubclassHashSet(typeof(WorldObject), nameof(WorldObject.Tick),
|
||||
_whitelistedWorldObjectTypes);
|
||||
SkippableComps = InitializeSkippableComps(),
|
||||
SkippableWorldObjects = InitializeSkippableWorldObjects();
|
||||
|
||||
private static HashSet<Type> MakeSubclassHashSet(Type type, string name, Type[] allowedDeclaringTypes)
|
||||
private static HashSet<Type> InitializeSkippableComps()
|
||||
=> MakeSubclassHashSet(typeof(WorldObjectComp), nameof(WorldObjectComp.CompTick),
|
||||
_whitelistedTickingCompTypes);
|
||||
|
||||
private static HashSet<Type> InitializeSkippableWorldObjects()
|
||||
=> MakeSubclassHashSet(typeof(WorldObject), nameof(WorldObject.Tick), _whitelistedWorldObjectTypes);
|
||||
|
||||
private static HashSet<Type> MakeSubclassHashSet(Type type, string name, Type?[] allowedDeclaringTypes)
|
||||
=> type.SubclassesWithNoMethodOverrideAndSelf(allowedDeclaringTypes, name).ToHashSet();
|
||||
|
||||
public static bool CacheDirty(WorldObjectsHolder instance)
|
||||
@@ -115,4 +137,112 @@ public class WorldObjectsOptimization : ClassWithFishPrepatches
|
||||
|
||||
static WorldObjectsHolderTickPatch() => Cache.Utility.Cleared += SetDirty;
|
||||
}
|
||||
|
||||
public sealed class ExpandingIconCaching : FishPrepatch
|
||||
{
|
||||
public override string? Description { get; }
|
||||
= "Caches icons that get displayed for world objects like settlements on the planet view and adds various "
|
||||
+ "safety checks to better catch and log errors in case of missing icons";
|
||||
|
||||
public override MethodBase TargetMethodBase { get; }
|
||||
= AccessTools.DeclaredPropertyGetter(typeof(WorldObject), nameof(WorldObject.ExpandingIcon));
|
||||
|
||||
public override void Transpiler(ILProcessor ilProcessor, ModuleDefinition module)
|
||||
=> ilProcessor.ReplaceBodyWith(ReplacementBody);
|
||||
|
||||
public static Texture2D ReplacementBody(WorldObject __instance)
|
||||
=> __instance.ExpandingIconCache() ?? InitializeExpandingIcon(__instance);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static Texture2D InitializeExpandingIcon(WorldObject? worldObject)
|
||||
{
|
||||
if (worldObject is null)
|
||||
return BaseContent.BadTex;
|
||||
|
||||
var def = worldObject.def;
|
||||
ref var cache = ref worldObject.ExpandingIconCache();
|
||||
|
||||
try
|
||||
{
|
||||
cache = def?.ExpandingIconTexture;
|
||||
|
||||
if (cache != null)
|
||||
return cache;
|
||||
|
||||
var material = worldObject.Material;
|
||||
if (material != null)
|
||||
cache = material.mainTexture as Texture2D;
|
||||
|
||||
if (cache == null)
|
||||
{
|
||||
cache = BaseContent.BadTex;
|
||||
Log.Error($"No expanding icon found for '{worldObject.ToStringSafe()}' of def '{
|
||||
def?.ToStringSafe()}' from mod '{def?.modContentPack?.Name}'. Assigning default.");
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"Exception while initializing icon for '{worldObject.ToStringSafe()}' of def '{
|
||||
def?.ToStringSafe()}' from mod '{def?.modContentPack?.Name}':\n{ex}");
|
||||
|
||||
return cache = BaseContent.BadTex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ExpandingIconColorCaching : FishPrepatch
|
||||
{
|
||||
public override string? Description { get; }
|
||||
= "Caches colors of icons that get displayed for world objects like settlements on the planet view and "
|
||||
+ "adds various safety checks to better catch and log errors in case of missing data";
|
||||
|
||||
public override MethodBase TargetMethodBase { get; }
|
||||
= AccessTools.DeclaredPropertyGetter(typeof(WorldObject), nameof(WorldObject.ExpandingIconColor));
|
||||
|
||||
public override void Transpiler(ILProcessor ilProcessor, ModuleDefinition module)
|
||||
=> ilProcessor.ReplaceBodyWith(ReplacementBody);
|
||||
|
||||
public static Color ReplacementBody(WorldObject __instance)
|
||||
=> __instance.ExpandingIconColorCache() ?? InitializeExpandingIconColor(__instance);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static Color InitializeExpandingIconColor(WorldObject? worldObject)
|
||||
{
|
||||
if (worldObject is null)
|
||||
return Color.white;
|
||||
|
||||
var def = worldObject.def;
|
||||
ref var cache = ref worldObject.ExpandingIconColorCache();
|
||||
|
||||
try
|
||||
{
|
||||
cache = def?.expandingIconColor;
|
||||
|
||||
if (cache != null)
|
||||
return cache.GetValueOrDefault();
|
||||
|
||||
var material = worldObject.Material;
|
||||
if (material != null)
|
||||
cache = material.color;
|
||||
|
||||
if (cache == null)
|
||||
{
|
||||
cache = Color.white;
|
||||
Log.Error($"No expanding icon color found for '{worldObject.ToStringSafe()}' of def '{
|
||||
def?.ToStringSafe()}' from mod '{def?.modContentPack?.Name}'. Assigning default.");
|
||||
}
|
||||
|
||||
return cache.GetValueOrDefault();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"Exception while initializing icon color for '{worldObject.ToStringSafe()}' of def '{
|
||||
def?.ToStringSafe()}' from mod '{def?.modContentPack?.Name}':\n{ex}");
|
||||
|
||||
return (cache = Color.white).GetValueOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,15 @@
|
||||
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using PerformanceFish.ModCompatibility;
|
||||
using PerformanceFish.Prepatching;
|
||||
using RimWorld.Planet;
|
||||
|
||||
namespace PerformanceFish.Planet;
|
||||
|
||||
public class WorldPawnGCOptimization : ClassWithFishPrepatches
|
||||
public sealed class WorldPawnGCOptimization : ClassWithFishPrepatches
|
||||
{
|
||||
public class AddRelationshipsPatch : FishPrepatch
|
||||
public sealed class AddRelationshipsPatch : FishPrepatch
|
||||
{
|
||||
public override string? Description { get; }
|
||||
= "The world pawn GC is responsible for deleting no longer relevant pawns. AddAllRelationships here tries "
|
||||
@@ -29,8 +30,10 @@ public class WorldPawnGCOptimization : ClassWithFishPrepatches
|
||||
=> AcceptedCriticalPawnReasons.Contains(keptPawns[pawn]);
|
||||
}
|
||||
|
||||
public class WorldPawnGCTickPatch : FishPrepatch
|
||||
public sealed class WorldPawnGCTickPatch : FishPrepatch
|
||||
{
|
||||
public override List<string> IncompatibleModIDs { get; } = [PackageIDs.MULTIPLAYER];
|
||||
|
||||
public override string? Description { get; }
|
||||
= "Normally the world pawn GC processes 1 pawn per tick, and speeds up if it fails to complete its "
|
||||
+ "processing before the game had to add or remove world pawns through other means. This patch changes the "
|
||||
@@ -42,7 +45,7 @@ public class WorldPawnGCOptimization : ClassWithFishPrepatches
|
||||
public static bool Prefix() => TickHelper.MatchesModulo(4);
|
||||
}
|
||||
|
||||
public class CancelGCPassPatch : FishPrepatch
|
||||
public sealed class CancelGCPassPatch : FishPrepatch
|
||||
{
|
||||
public override string? Description { get; }
|
||||
= "When the game determines that it has to speed up its GC process because of world pawn additions or "
|
||||
@@ -67,7 +70,7 @@ public class WorldPawnGCOptimization : ClassWithFishPrepatches
|
||||
}
|
||||
}
|
||||
|
||||
public class GetCriticalPawnReasonPatch : FishPrepatch
|
||||
public sealed class GetCriticalPawnReasonPatch : FishPrepatch
|
||||
{
|
||||
public override string? Description { get; }
|
||||
= "Critical pawns are pawns the game's world pawn GC does not delete. Relationships other than parents of "
|
||||
@@ -102,5 +105,5 @@ public class WorldPawnGCOptimization : ClassWithFishPrepatches
|
||||
}
|
||||
|
||||
public static HashSet<string> AcceptedCriticalPawnReasons
|
||||
= new(new[] { "Colonist", "Generating", "Kidnapped", "CaravanMember", "TransportPod", "Spawned" });
|
||||
= [..new[] { "Colonist", "Generating", "Kidnapped", "CaravanMember", "TransportPod", "Spawned" }];
|
||||
}
|
||||
@@ -10,9 +10,9 @@ using RimWorld.Planet;
|
||||
|
||||
namespace PerformanceFish.Planet;
|
||||
|
||||
public class WorldPawnsOptimization : ClassWithFishPrepatches
|
||||
public sealed class WorldPawnsOptimization : ClassWithFishPrepatches
|
||||
{
|
||||
public class AllPawnsAlivePatch : FishPrepatch
|
||||
public sealed class AllPawnsAlivePatch : FishPrepatch
|
||||
{
|
||||
public override string? Description { get; }
|
||||
= "Minor optimization to reduce the amount of copying happening in the WorldPawns.AllPawnsAlive method";
|
||||
@@ -52,7 +52,7 @@ public class WorldPawnsOptimization : ClassWithFishPrepatches
|
||||
|| instance.pawnsMothballed._version != cache.PawnsMothballedVersion;
|
||||
}
|
||||
|
||||
public class AllPawnsAliveOrDeadPatch : FishPrepatch
|
||||
public sealed class AllPawnsAliveOrDeadPatch : FishPrepatch
|
||||
{
|
||||
public override string? Description { get; }
|
||||
= "Minor optimization to reduce the amount of copying happening in the WorldPawns.AllPawnsAliveOrDead "
|
||||
|
||||
Reference in New Issue
Block a user