Additional safety checks in StoreUtilityPrepatches:TryFindBestBetterStoreCellFor for better mod compatibility
It was reported to be throwing index out of range exceptions, with unknown cause
This commit is contained in:
@@ -257,6 +257,10 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
|
||||
var closestDistSquared = (float)int.MaxValue;
|
||||
var closestSlot = IntVec3.Invalid;
|
||||
|
||||
var hadToFixCache = false;
|
||||
|
||||
StartOfLoop:
|
||||
var listInPriorityOrderCount = listInPriorityOrder.Count;
|
||||
var groupCountByPriority = GetCachedGroupCountByPriority(haulDestinationManager);
|
||||
var i = 0;
|
||||
for (var priorityGroupIndex = groupCountByPriority.Length; priorityGroupIndex-- > 0;)
|
||||
@@ -274,6 +278,9 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
|
||||
|
||||
while (groupsOfPriorityCount-- > 0)
|
||||
{
|
||||
if (i >= listInPriorityOrderCount)
|
||||
goto FixCache;
|
||||
|
||||
var slotGroup = listInPriorityOrder[i++];
|
||||
int otherGroupMembers;
|
||||
var storageGroup = slotGroup.TryGetStorageGroup();
|
||||
@@ -303,12 +310,16 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
|
||||
if (otherGroupMembers <= 0)
|
||||
break;
|
||||
|
||||
if (i >= listInPriorityOrderCount)
|
||||
goto FixCache;
|
||||
|
||||
otherGroupMembers--;
|
||||
slotGroup = listInPriorityOrder[i++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Result:
|
||||
if (!closestSlot.IsValid)
|
||||
{
|
||||
foundCell = IntVec3.Invalid;
|
||||
@@ -317,6 +328,39 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
|
||||
|
||||
foundCell = closestSlot;
|
||||
return true;
|
||||
|
||||
FixCache:
|
||||
if (hadToFixCache)
|
||||
{
|
||||
LogErrorForFailedTryFindBestBetterStoreCellForAttempt(t, carrier, map, currentPriority, faction,
|
||||
closestSlot);
|
||||
goto Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
hadToFixCache = true;
|
||||
}
|
||||
|
||||
UpdateCache(haulDestinationManager);
|
||||
goto StartOfLoop;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static void LogErrorForFailedTryFindBestBetterStoreCellForAttempt(Thing t, Pawn carrier, Map? map,
|
||||
StoragePriority currentPriority, Faction faction, IntVec3 closestSlot)
|
||||
=> Log.Error($"Performance Fish's TryFindBestBetterStoreCellFor patch failed to compute accurate "
|
||||
+ $"results after a recache attempt for thing '{t}', pawn '{carrier}', map '{
|
||||
map}', currentPriority '{currentPriority}', faction '{
|
||||
faction}'. The last found cell was '{
|
||||
closestSlot}'. It is most likely incompatible with something in the mod list.\n{
|
||||
Debug.GetStorageGroupInfo(map?.haulDestinationManager?.AllGroupsListInPriorityOrder)}");
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static void UpdateCache(HaulDestinationManager haulDestinationManager)
|
||||
{
|
||||
haulDestinationManager.AllGroupsListInPriorityOrder.InsertionSort(HaulDestinationManager
|
||||
.CompareSlotGroupPrioritiesDescending);
|
||||
haulDestinationManager.Cache().OnPriorityChanged(haulDestinationManager);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -355,13 +399,24 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
|
||||
public static void LogStuff(List<SlotGroup> listInPriorityOrder)
|
||||
{
|
||||
LoggedOnce = true;
|
||||
var storageGroups = listInPriorityOrder.Select(static slotGroup => slotGroup.TryGetStorageGroup())
|
||||
Log.Message(GetStorageGroupInfo(listInPriorityOrder));
|
||||
}
|
||||
|
||||
public static string GetStorageGroupInfo(List<SlotGroup>? slotGroupsInPriorityOrder)
|
||||
{
|
||||
if (slotGroupsInPriorityOrder is null)
|
||||
return string.Empty;
|
||||
|
||||
var storageGroups = slotGroupsInPriorityOrder.Select(static slotGroup => slotGroup.TryGetStorageGroup())
|
||||
.Where(Is.NotNull).Distinct().ToList();
|
||||
Log.Message($"SlotGroup count: {listInPriorityOrder.Count}, StorageGroup count: {
|
||||
storageGroups.Count}, slotGroups in storage groups: {
|
||||
storageGroups.Select(static group => group!.MemberCount).Sum()}, outside of storage groups: {
|
||||
listInPriorityOrder.Select(static slotGroup => slotGroup.TryGetStorageGroup())
|
||||
.Where(Is.Null).Count()}");
|
||||
|
||||
return StringHelper.Resolve($"SlotGroup count: {
|
||||
slotGroupsInPriorityOrder.Count}, StorageGroup count: {
|
||||
storageGroups.Count}, slotGroups in storage groups: {storageGroups
|
||||
.Select(static group => group!.MemberCount)
|
||||
.Sum()}, outside of storage groups: {slotGroupsInPriorityOrder
|
||||
.Select(static slotGroup => slotGroup.TryGetStorageGroup())
|
||||
.Where(Is.Null).Count()}");
|
||||
}
|
||||
|
||||
public static bool LoggedOnce;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<Configurations>v1.4</Configurations>
|
||||
<Version>0.3.999.91</Version>
|
||||
<Version>0.3.999.92</Version>
|
||||
<NoWarn>
|
||||
1701;1702;IL2121;CS8500;CS9082;CA1000;CA1002;CA1003;CA1707;CA1010;CA1715;CA1716;CA1724;CA1031;CA1033;
|
||||
CA1034;CA1043;CA1051;CA1305;CA1310;CA1710;CA1711;CA1810;CA1812;CA1819;CA1851;CA2002;CA5394;CA1725;CA1062
|
||||
|
||||
Reference in New Issue
Block a user