Fixed rare TryFindBestBetterStoreCellFor errors, added better exception handling for drawing errors thrown by other mods

Those log messages now include things and the position where drawing fails
Plant printing was slightly improved further too, correctly handling theoretical hydroponics of sizes above 20 now
This commit is contained in:
bbradson
2024-04-30 20:37:18 +02:00
parent 1ca55fc7b8
commit 79e8b5f70d
16 changed files with 183 additions and 75 deletions
@@ -11,16 +11,15 @@ public record struct HaulDestinationManagerCache()
public event Action<HaulDestinationManager>? PriorityChanged;
public int[] GroupCountByPriority = new int[StoragePriorityCount];
public readonly int[] GroupCountByPriority = new int[StoragePriorityCount];
[MethodImpl(MethodImplOptions.NoInlining)]
public void OnPriorityChanged(HaulDestinationManager manager)
{
var slotGroupsByPriority = manager.AllGroupsListInPriorityOrder;
Array.Clear(GroupCountByPriority, 0, GroupCountByPriority.Length);
for (var i = slotGroupsByPriority.Count; i-- > 0;)
GroupCountByPriority[(int)slotGroupsByPriority[i].Settings.Priority]++;
GroupCountByPriority.Clear();
manager.AllGroupsListInPriorityOrder.UnwrapArray(out var slotGroupsByPriority, out var slotGroupCount);
for (var i = slotGroupCount; --i >= 0;)
GroupCountByPriority[(int)slotGroupsByPriority.UnsafeLoad(i).Settings.Priority]++;
PriorityChanged?.Invoke(manager);
}
@@ -17,6 +17,8 @@ public sealed class HaulDestinationManagerPatches : ClassWithFishPrepatches
= AccessTools.DeclaredMethod(typeof(HaulDestinationManager),
nameof(HaulDestinationManager.Notify_HaulDestinationChangedPriority));
public static void Prefix(HaulDestinationManager __instance) => __instance.RecalculateStorageGroupMemberCount();
public static void Postfix(HaulDestinationManager __instance)
=> __instance.Cache().OnPriorityChanged(__instance);
}
@@ -29,6 +31,12 @@ public sealed class HaulDestinationManagerPatches : ClassWithFishPrepatches
= AccessTools.DeclaredMethod(typeof(HaulDestinationManager),
nameof(HaulDestinationManager.AddHaulDestination));
public static void Prefix(HaulDestinationManager __instance, IHaulDestination haulDestination)
{
if (haulDestination is IStorageGroupMember { Group: { } group })
group.SpawnedMemberCount()++;
}
public static void Postfix(HaulDestinationManager __instance, IHaulDestination haulDestination)
{
if (haulDestination is not ISlotGroupParent slotGroupParent)
@@ -47,6 +55,12 @@ public sealed class HaulDestinationManagerPatches : ClassWithFishPrepatches
= AccessTools.DeclaredMethod(typeof(HaulDestinationManager),
nameof(HaulDestinationManager.RemoveHaulDestination));
public static void Prefix(HaulDestinationManager __instance, IHaulDestination haulDestination)
{
if (haulDestination is IStorageGroupMember { Group: { } group })
group.SpawnedMemberCount()--;
}
public static void Postfix(HaulDestinationManager __instance, IHaulDestination haulDestination)
{
if (haulDestination is not ISlotGroupParent slotGroupParent)
@@ -76,8 +90,8 @@ public sealed class HaulDestinationManagerPatches : ClassWithFishPrepatches
if (__result != 0)
return __result;
var storageSettingsGroupA = a.TryGetStorageGroup();
var storageSettingsGroupB = b.TryGetStorageGroup();
var storageSettingsGroupA = a.StorageGroup;
var storageSettingsGroupB = b.StorageGroup;
return storageSettingsGroupA == null
? storageSettingsGroupB == null
@@ -91,7 +105,7 @@ public sealed class HaulDestinationManagerPatches : ClassWithFishPrepatches
[MethodImpl(MethodImplOptions.NoInlining)]
public static int CompareStorageSettingsGroups(StorageGroup a, StorageGroup b)
{
var result = b.MemberCount.CompareTo(a.MemberCount);
var result = b.SpawnedMemberCount().CompareTo(a.SpawnedMemberCount());
return result != 0 ? result : a.loadID.CompareTo(b.loadID);
}
}
@@ -36,6 +36,21 @@ public static class StorageExtensions
=> slotGroup.parent is Building storage
? storage.TrueItemsPerCell() * cellCount
: cellCount;
public static void RecalculateStorageGroupMemberCount(this HaulDestinationManager haulDestinationManager)
{
haulDestinationManager.map.storageGroups.groups.UnwrapArray(out var storageGroups, out var storageGroupCount);
for (var i = storageGroupCount; --i >= 0;)
storageGroups.UnsafeLoad(i).SpawnedMemberCount() = 0;
haulDestinationManager.AllGroupsListInPriorityOrder.UnwrapArray(out var slotGroupsByPriority,
out var slotGroupCount);
for (var i = slotGroupCount; --i >= 0;)
{
if (slotGroupsByPriority.UnsafeLoad(i).StorageGroup is { } storageGroup)
storageGroup.SpawnedMemberCount()++;
}
}
static StorageExtensions()
{
@@ -254,7 +254,7 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
#if STORAGE_GROUP_DEBUG
if (!Debug.LoggedOnce && !(Current.Game?.tickManager?.Paused ?? true))
Debug.LogStuff(listInPriorityOrder);
Debug.LogStuff(haulDestinationManager);
#endif
var foundPriority = currentPriority;
@@ -287,10 +287,10 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
var slotGroup = listInPriorityOrder[i++];
int otherGroupMembers;
var storageGroup = slotGroup.TryGetStorageGroup();
var storageGroup = slotGroup.StorageGroup;
if (storageGroup != null)
{
otherGroupMembers = storageGroup.MemberCount - 1;
otherGroupMembers = storageGroup.SpawnedMemberCount() - 1;
Debug.VerifyStorageGroup(otherGroupMembers, listInPriorityOrder, i, storageGroup);
groupsOfPriorityCount -= otherGroupMembers;
@@ -334,19 +334,18 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
return true;
FixCache:
if (hadToFixCache)
if (!hadToFixCache)
{
hadToFixCache = true;
UpdateCache(haulDestinationManager);
goto StartOfLoop;
}
else
{
LogErrorForFailedTryFindBestBetterStoreCellForAttempt(t, carrier, map, currentPriority, faction,
closestSlot);
goto Result;
}
else
{
hadToFixCache = true;
}
UpdateCache(haulDestinationManager);
goto StartOfLoop;
}
[MethodImpl(MethodImplOptions.NoInlining)]
@@ -357,11 +356,29 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
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)}");
Debug.GetStorageGroupInfo(map?.haulDestinationManager)}");
[MethodImpl(MethodImplOptions.NoInlining)]
public static void UpdateCache(HaulDestinationManager haulDestinationManager)
{
var storageGroups = haulDestinationManager.map.storageGroups.groups;
for (var i = storageGroups.Count; i-- > 0;)
{
var group = storageGroups[i];
var members = group.members;
for (var j = members.Count; j-- > 0;)
{
var member = members[j];
if (member.Group != group)
members.RemoveAt(j);
}
if (members.Count == 0)
storageGroups.RemoveAt(i);
}
haulDestinationManager.RecalculateStorageGroupMemberCount();
haulDestinationManager.AllGroupsListInPriorityOrder.InsertionSort(HaulDestinationManager
.CompareSlotGroupPrioritiesDescending);
haulDestinationManager.Cache().OnPriorityChanged(haulDestinationManager);
@@ -404,36 +421,36 @@ public sealed class StoreUtilityPrepatches : ClassWithFishPrepatches
for (var b = otherGroupMembers; b-- > 0;)
{
var otherSlotGroup = listInPriorityOrder[i + b];
if (otherSlotGroup.TryGetStorageGroup() == storageGroup)
if (otherSlotGroup.StorageGroup == storageGroup)
continue;
Log.Error($"Incorrect haul destination order! Storage '{
otherSlotGroup.parent}' was expected to have Storage group '{storageGroup}', but had '{
otherSlotGroup.TryGetStorageGroup().ToStringSafe()}' instead");
otherSlotGroup.StorageGroup.ToStringSafe()}' instead");
}
}
[Conditional("STORAGE_GROUP_DEBUG")]
public static void LogStuff(List<SlotGroup> listInPriorityOrder)
public static void LogStuff(HaulDestinationManager haulDestinationManager)
{
LoggedOnce = true;
Log.Message(GetStorageGroupInfo(listInPriorityOrder));
Log.Message(GetStorageGroupInfo(haulDestinationManager));
}
public static string GetStorageGroupInfo(List<SlotGroup>? slotGroupsInPriorityOrder)
public static string GetStorageGroupInfo(HaulDestinationManager? haulDestinationManager)
{
var slotGroupsInPriorityOrder = haulDestinationManager?.AllGroupsListInPriorityOrder;
if (slotGroupsInPriorityOrder is null)
return string.Empty;
var storageGroups = slotGroupsInPriorityOrder.Select(static slotGroup => slotGroup.TryGetStorageGroup())
.Where(Is.NotNull).Distinct().ToList();
var storageGroups = haulDestinationManager!.map.storageGroups.groups;
return StringHelper.Resolve($"SlotGroup count: {
slotGroupsInPriorityOrder.Count}, StorageGroup count: {
storageGroups.Count}, slotGroups in storage groups: {storageGroups
.Select(static group => group!.MemberCount)
.Select(static group => group!.SpawnedMemberCount())
.Sum()}, outside of storage groups: {slotGroupsInPriorityOrder
.Select(static slotGroup => slotGroup.TryGetStorageGroup())
.Select(static slotGroup => slotGroup.StorageGroup)
.Where(Is.Null).Count()}");
}