123 lines
3.8 KiB
C#
123 lines
3.8 KiB
C#
// Copyright (c) 2023 bradson
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// 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.Prepatching;
|
|
|
|
namespace PerformanceFish;
|
|
|
|
public sealed class MapPrepatches : ClassWithFishPrepatches
|
|
{
|
|
public sealed class FinalizeLoadingPatch : FishPrepatch
|
|
{
|
|
public override string? Description { get; }
|
|
= "An attempt at logging and fixing possible causes for the common FMOD error spam. None of "
|
|
+ "Performance Fish's other patches interact with this in any way.";
|
|
|
|
public override MethodBase TargetMethodBase { get; }
|
|
= AccessTools.DeclaredMethod(typeof(Map), nameof(Map.FinalizeLoading));
|
|
|
|
public static void Postfix(Map __instance)
|
|
{
|
|
var listerThings = __instance.listerThings;
|
|
|
|
var musicalInstruments = listerThings.ThingsInGroup(ThingRequestGroup.MusicalInstrument);
|
|
for (var i = musicalInstruments.Count; i-- > 0;)
|
|
{
|
|
var thing = musicalInstruments[i];
|
|
if (thing is Building_MusicalInstrument)
|
|
continue;
|
|
|
|
Log.Error($"Map '{__instance}' contains thing that is not of type 'Building_MusicalInstrument' "
|
|
+ $"in ThingsInGroup for ThingRequestGroup.MusicalInstrument: '{
|
|
thing}' at cell '{thing.Position}'. Removing now to prevent further issues.");
|
|
|
|
if (!RefundOrRemoveIfUnassignable(__instance, thing))
|
|
listerThings.RemoveFromGroup(thing, ThingRequestGroup.MusicalInstrument);
|
|
}
|
|
|
|
var musicSources = listerThings.ThingsInGroup(ThingRequestGroup.MusicSource);
|
|
for (var i = musicSources.Count; i-- > 0;)
|
|
{
|
|
var thing = musicSources[i];
|
|
if (thing.TryGetComp<CompPlaysMusic>() != null)
|
|
continue;
|
|
|
|
Log.Error($"Map '{__instance}' contains thing without comp of type 'CompPlaysMusic' in "
|
|
+ $"ThingsInGroup for ThingRequestGroup.MusicSource: '{
|
|
thing}' at cell '{thing.Position}'. Removing now to prevent further issues.");
|
|
|
|
if (!RefundOrRemoveIfUnassignable(__instance, thing))
|
|
listerThings.RemoveFromGroup(thing, ThingRequestGroup.MusicSource);
|
|
}
|
|
|
|
var allThings = listerThings.AllThings;
|
|
for (var i = allThings.Count; i-- > 0;)
|
|
{
|
|
var thing = allThings[i];
|
|
var thingDef = thing.def;
|
|
|
|
if (thingDef is null)
|
|
{
|
|
Log.Error($"Map '{__instance}' contains thing '{thing}' with null def at cell '{
|
|
thing.Position}'. This will likely cause issues. Removing now.");
|
|
|
|
listerThings.Remove(thing);
|
|
// continue;
|
|
}
|
|
// else if (thing.GetType().IsAssignableTo(thingDef.thingClass))
|
|
// {
|
|
// Log.Error($"Map '{__instance}' contains thing '{thing}' of incorrect type '{
|
|
// thing.GetType()}' at cell '{thing.Position}'. This should be '{
|
|
// thingDef.thingClass}' instead and will likely cause issues. Destroying and refunding now.");
|
|
// }
|
|
// else
|
|
// {
|
|
// continue;
|
|
// }
|
|
//
|
|
// if (!TryRefundOrRemove(__instance, thing))
|
|
// listerThings.Remove(thing);
|
|
}
|
|
}
|
|
|
|
private static bool RefundOrRemoveIfUnassignable(Map map, Thing thing)
|
|
{
|
|
if (thing.def != null && thing.GetType().IsAssignableTo(thing.def.thingClass))
|
|
return false;
|
|
|
|
return TryRefundOrRemove(map, thing);
|
|
}
|
|
|
|
private static bool TryRefundOrRemove(Map map, Thing thing)
|
|
{
|
|
var previousAllowDestroy = Thing.allowDestroyNonDestroyable;
|
|
Thing.allowDestroyNonDestroyable = true;
|
|
|
|
try
|
|
{
|
|
GenSpawn.Refund(thing, map, CellRect.Empty);
|
|
}
|
|
catch (Exception refundException)
|
|
{
|
|
Log.Error($"Failed to refund thing '{thing}'. Destroying.\n{refundException}");
|
|
try
|
|
{
|
|
thing.Destroy();
|
|
}
|
|
catch (Exception destroyException)
|
|
{
|
|
Log.Error($"Failed to destroy thing '{thing}'.\n{destroyException}");
|
|
return false;
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
Thing.allowDestroyNonDestroyable = previousAllowDestroy;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
} |