using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("SkrekFix")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SkrekFix")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("b6bdfc0b-a51f-4d52-8a20-7770b3e3e9e8")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace SkrekFixMod; [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("midnight.skrekfix", "SkrekFix", "1.0.0")] public class ShrekPatch : BaseUnityPlugin { internal static ManualLogSource ModLogger; private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) ModLogger = ((BaseUnityPlugin)this).Logger; ((BaseUnityPlugin)this).Logger.LogInfo((object)"SkrekFix loaded!"); new Harmony("midnight.skrekfix").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"SkrekFix patches applied!"); } } [HarmonyPatch] public static class SpawnSpawnModPatch { [CompilerGenerated] private sealed class d__2 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private int 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = 0; break; case 1: <>1__state = -1; ShrekEnemyReplacer.ReplaceDifficulty3Enemy($"Delayed replacement attempt {5__1 + 1}"); 5__1++; break; } if (5__1 < 10) { <>2__current = (object)new WaitForSecondsRealtime(1f); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static MethodBase TargetMethod() { return AccessTools.Method("Animaciones.SpawnSpawnMod:Awake", (Type[])null, (Type[])null); } private static bool Prefix(object __instance) { MonoBehaviour val = (MonoBehaviour)((__instance is MonoBehaviour) ? __instance : null); if (val != null) { val.StartCoroutine(ReplaceEnemyWhenReady()); } return false; } [IteratorStateMachine(typeof(d__2))] private static IEnumerator ReplaceEnemyWhenReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__2(0); } } [HarmonyPatch(typeof(EnemyDirector), "AmountSetup")] public static class EnemyDirectorAmountSetupPatch { private static void Prefix(EnemyDirector __instance) { ShrekEnemyReplacer.ReplaceDifficulty3Enemy("AmountSetup patch", __instance); } } [HarmonyPatch(typeof(EnemyDirector), "PickEnemies")] public static class EnemyDirectorPickEnemiesPatch { private static void Prefix(EnemyDirector __instance) { ShrekEnemyReplacer.ReplaceDifficulty3Enemy("PickEnemies patch", __instance); } } [HarmonyPatch(typeof(MusicEnemyNear), "Logic")] public static class MusicEnemyNearLogicPatch { private static void Prefix(MusicEnemyNear __instance) { if (!((Object)(object)__instance == (Object)null)) { if ((Object)(object)Camera.main != (Object)null) { AccessTools.Field(typeof(MusicEnemyNear), "Camera")?.SetValue(__instance, Camera.main); } FixAllEnemyCenterTransforms(); } } private static void Finalizer(Exception __exception) { if (__exception != null) { ShrekPatch.ModLogger.LogError((object)("MusicEnemyNear.Logic error blocked: " + __exception.Message)); } } private static void FixAllEnemyCenterTransforms() { if ((Object)(object)EnemyDirector.instance == (Object)null || EnemyDirector.instance.enemiesSpawned == null) { return; } foreach (EnemyParent item in EnemyDirector.instance.enemiesSpawned) { if ((Object)(object)item == (Object)null) { continue; } Enemy val = ((Component)item).GetComponentInChildren(true); if ((Object)(object)val == (Object)null) { val = ((Component)item).GetComponent(); } if (!((Object)(object)val == (Object)null) && !((Object)(object)val.CenterTransform != (Object)null)) { Transform val2 = ((Component)val).transform.Find("Vision"); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)val).transform.Find("Animation System"); } if ((Object)(object)val2 == (Object)null) { val2 = ((Component)val).transform; } val.CenterTransform = val2; ShrekPatch.ModLogger.LogInfo((object)("Fixed CenterTransform for " + ((Object)item).name + ": " + ((Object)val2).name)); } } } } [HarmonyPatch(typeof(EnemyHeadAnimationSystem), "Update")] public static class ShrekChaseLoopActivePatch { private static bool loggedOnce; private static readonly Dictionary forcedSources = new Dictionary(); private static void Postfix(EnemyHeadAnimationSystem __instance) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.Enemy == (Object)null) { return; } if (!(__instance.ChaseLoopActive = (int)__instance.Enemy.CurrentState == 4 || (int)__instance.Enemy.CurrentState == 5)) { StopForcedSource(__instance); return; } FixChaseSound(__instance, __instance.ChaseLoop, "ChaseLoop"); if (!loggedOnce) { DebugSound(__instance.ChaseLoop, "ChaseLoop"); DebugSound(__instance.ChaseLoop2, "ChaseLoop2"); loggedOnce = true; } } private static void FixChaseSound(EnemyHeadAnimationSystem owner, Sound sound, string label) { if (!((Object)(object)owner == (Object)null) && sound != null && !((Object)(object)sound.Source == (Object)null) && !((Object)(object)sound.Source.clip == (Object)null) && !((Object)(object)Camera.main == (Object)null)) { if (!forcedSources.TryGetValue(owner, out var value) || (Object)(object)value == (Object)null) { value = ((Component)Camera.main).gameObject.AddComponent(); value.loop = true; value.playOnAwake = false; value.spatialBlend = 0f; value.volume = 0.35f; value.mute = false; value.ignoreListenerVolume = true; value.ignoreListenerPause = true; forcedSources[owner] = value; ShrekPatch.ModLogger.LogInfo((object)("Created per-enemy forced camera source for " + label + ".")); } if ((Object)(object)value.clip != (Object)(object)sound.Source.clip) { ShrekPatch.ModLogger.LogInfo((object)(label + ": Clip changed from " + (((Object)(object)value.clip == (Object)null) ? "NULL" : ((Object)value.clip).name) + " to " + ((Object)sound.Source.clip).name)); value.Stop(); value.clip = sound.Source.clip; value.time = 0f; } value.volume = 0.35f; value.mute = false; if (!value.isPlaying) { value.Play(); } } } private static void StopForcedSource(EnemyHeadAnimationSystem owner) { if (!((Object)(object)owner == (Object)null) && forcedSources.TryGetValue(owner, out var value) && (Object)(object)value != (Object)null && value.isPlaying) { value.Stop(); } } private static void DebugSound(Sound sound, string label) { if (sound == null) { ShrekPatch.ModLogger.LogError((object)(label + ": Sound is NULL")); return; } ShrekPatch.ModLogger.LogInfo((object)(label + ": Source = " + (((Object)(object)sound.Source == (Object)null) ? "NULL" : ((Object)sound.Source).name))); ManualLogSource modLogger = ShrekPatch.ModLogger; AudioSource source = sound.Source; modLogger.LogInfo((object)(label + ": Source clip = " + (((Object)(object)((source != null) ? source.clip : null) == (Object)null) ? "NULL" : ((Object)sound.Source.clip).name))); ShrekPatch.ModLogger.LogInfo((object)$"{label}: Source isPlaying = {!((Object)(object)sound.Source == (Object)null) && sound.Source.isPlaying}"); ShrekPatch.ModLogger.LogInfo((object)$"{label}: Source volume = {(((Object)(object)sound.Source == (Object)null) ? (-1f) : sound.Source.volume)}"); } } public static class ShrekEnemyReplacer { private static bool loggedSpawnObjectFields; public static void ReplaceDifficulty3Enemy(string source, EnemyDirector director = null) { EnemySetup val = Resources.Load("EnemySetups/Enemy - Shrek"); if ((Object)(object)val == (Object)null) { Type type = AccessTools.TypeByName("Animaciones.MiMod"); if (type != null) { FieldInfo fieldInfo = AccessTools.Field(type, "enemySetupMod"); if (fieldInfo != null) { if (fieldInfo.IsStatic) { object? value = fieldInfo.GetValue(null); val = (EnemySetup)((value is EnemySetup) ? value : null); } else { object obj = AccessTools.Field(type, "instance")?.GetValue(null); val = (EnemySetup)((obj == null) ? null : /*isinst with value type is only supported in some contexts*/); } } } } if ((Object)(object)val == (Object)null) { ShrekPatch.ModLogger.LogError((object)(source + ": EnemySetup is null.")); return; } FixShrekSpawnObjectPath(val, source); LogSpawnObjectFields(val, source); if ((Object)(object)director == (Object)null) { director = EnemyDirector.instance; } if ((Object)(object)director == (Object)null) { director = Object.FindAnyObjectByType(); } if (!((Object)(object)director == (Object)null) && director.enemiesDifficulty3 != null) { if (director.enemiesDifficulty3.Count == 0) { director.enemiesDifficulty3.Add(val); } else { director.enemiesDifficulty3[0] = val; } ShrekPatch.ModLogger.LogInfo((object)(source + ": Replaced enemiesDifficulty3[0] with test enemy.")); } } private static void FixShrekSpawnObjectPath(EnemySetup shrekEnemy, string source) { if (shrekEnemy.spawnObjects != null && shrekEnemy.spawnObjects.Count != 0) { PrefabRef val = shrekEnemy.spawnObjects[0]; FieldInfo fieldInfo = AccessTools.Field(((object)val).GetType(), "resourcePath"); if (fieldInfo != null) { fieldInfo.SetValue(val, "AssetBundles/skrek/Assets/Resources/enemies/Enemy - Shrek.prefab"); ShrekPatch.ModLogger.LogInfo((object)(source + ": resourcePath fixed.")); } } } private static void LogSpawnObjectFields(EnemySetup shrekEnemy, string source) { if (loggedSpawnObjectFields || shrekEnemy.spawnObjects == null || shrekEnemy.spawnObjects.Count == 0) { return; } foreach (PrefabRef spawnObject in shrekEnemy.spawnObjects) { ShrekPatch.ModLogger.LogInfo((object)(source + ": SpawnObject type = " + ((object)spawnObject).GetType().FullName)); } loggedSpawnObjectFields = true; } }