using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; 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("Knuckles")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Knuckles")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("97A069E8-5AAB-4E2A-BAE4-B6E2E251C03E")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace Knuckles.GhostShip { public class SkellyEventCommand : ConsoleCommand { public override string Name => "skellyevent"; public override string Help => "skellyevent — inicia el evento de invasión"; public override void Run(string[] args) { if (args.Length < 1) { Console instance = Console.instance; if (instance != null) { instance.Print("Uso: skellyevent "); } return; } string name = args[0]; Player val = ((IEnumerable)Player.GetAllPlayers()).FirstOrDefault((Func)((Player p) => p.GetPlayerName().Equals(name, StringComparison.OrdinalIgnoreCase))); if ((Object)(object)val == (Object)null) { Console instance2 = Console.instance; if (instance2 != null) { instance2.Print("Jugador '" + name + "' no encontrado."); } ManualLogSource log = SpawnGhostLongshipAndSkels.Log; if (log != null) { log.LogWarning((object)("skellyevent: '" + name + "' no encontrado.")); } } else { Console instance3 = Console.instance; if (instance3 != null) { instance3.Print("Iniciando invasión en " + val.GetPlayerName() + "..."); } SpawnGhostLongshipAndSkels.StartEventForTarget(val); } } } [BepInPlugin("nazhi.spawnlongshipghostandskels", "Spawn Ghost Longship + Waves", "2.6.0")] public class SpawnGhostLongshipAndSkels : BaseUnityPlugin { private class BoatGodMode : MonoBehaviour { private WearNTear _wt; private void Awake() { _wt = ((Component)this).GetComponentInChildren(); if ((Object)(object)_wt == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"BoatGodMode: WearNTear no encontrado en el Longship."); } } } private void LateUpdate() { if ((Object)(object)_wt == (Object)null) { return; } try { _wt.Repair(); } catch (Exception arg) { ManualLogSource log = Log; if (log != null) { log.LogError((object)$"BoatGodMode: error en Repair(): {arg}"); } } } } [HarmonyPatch(typeof(ZNet), "Awake")] private static class ZNetPatch { [CompilerGenerated] private sealed class d__1 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private float 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = 0f; break; case 1: <>1__state = -1; 5__1 += 0.1f; break; } if (ZRoutedRpc.instance == null && 5__1 < 10f) { <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 1; return true; } if (ZRoutedRpc.instance != null) { Log.LogInfo((object)$"ZRoutedRpc encontrado tras {5__1:F1}s — registrando RPCs."); RegisterAllRpcs(); } else { Log.LogError((object)"ZRoutedRpc nunca se inicializó tras 10s."); } 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(); } } [HarmonyPostfix] private static void Postfix() { if ((Object)(object)Instance != (Object)null) { ((MonoBehaviour)Instance).StartCoroutine(WaitAndRegister()); } } [IteratorStateMachine(typeof(d__1))] private static IEnumerator WaitAndRegister() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(0); } } internal struct InvasionContext { public Vector3 ShorePoint; public Vector3 WaterPoint; public Vector3 ShoreDir; public float WaterLevel; public Vector3 BoatPos; public Quaternion BoatRot; } private class WaveSkeleton : MonoBehaviour { private void OnDestroy() { if (_currentWaveAlive > 0) { _currentWaveAlive--; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"WaveSkeleton destruido. Restantes en wave: {_currentWaveAlive}"); } } } } private class GhostEnforcer : MonoBehaviour { private float _nextTime; private const float Interval = 0.5f; private void Update() { if ((Object)(object)this == (Object)null || (Object)(object)((Component)this).gameObject == (Object)null || Time.time < _nextTime) { return; } _nextTime = Time.time + 0.5f; try { ApplyGhostMaterial(((Component)this).gameObject); } catch (Exception arg) { ManualLogSource log = Log; if (log != null) { log.LogError((object)$"GhostEnforcer error en {((Object)((Component)this).gameObject).name}: {arg}"); } } } } [CompilerGenerated] private sealed class d__18 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Vector3 shoreDir; public SpawnGhostLongshipAndSkels <>4__this; private GameObject 5__1; private Vector3 5__2; private Quaternion 5__3; private Quaternion 5__4; private float 5__5; private ZNetView 5__6; private ZDO 5__7; private ZDO 5__8; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 5__6 = null; 5__7 = null; 5__8 = null; <>1__state = -2; } private bool MoveNext() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) ManualLogSource log2; Vector3 val; switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = FindBoatInScene(); if ((Object)(object)5__1 == (Object)null) { <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; } goto IL_007f; case 1: <>1__state = -1; 5__1 = FindBoatInScene(); goto IL_007f; case 2: <>1__state = -1; goto IL_01d0; case 3: { <>1__state = -1; break; } IL_007f: if ((Object)(object)5__1 == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"RetreatCoroutine: barco no encontrado."); } return false; } log2 = Log; if (log2 != null) { log2.LogInfo((object)("RetreatCoroutine: moviendo '" + ((Object)5__1).name + "'.")); } val = new Vector3(shoreDir.x, 0f, shoreDir.z); 5__2 = -((Vector3)(ref val)).normalized; if (((Vector3)(ref 5__2)).sqrMagnitude < 0.001f) { 5__2 = -5__1.transform.forward; } 5__3 = 5__1.transform.rotation; 5__4 = Quaternion.LookRotation(5__2, Vector3.up); 5__5 = 0f; goto IL_01d0; IL_01d0: if (5__5 < 5f && (Object)(object)5__1 != (Object)null) { 5__5 += Time.deltaTime; 5__1.transform.rotation = Quaternion.Slerp(5__3, 5__4, Mathf.Clamp01(5__5 / 5f)); <>2__current = null; <>1__state = 2; return true; } if ((Object)(object)5__1 == (Object)null) { return false; } 5__5 = 0f; break; } if (5__5 < 8f && (Object)(object)5__1 != (Object)null) { 5__5 += Time.deltaTime; Transform transform = 5__1.transform; transform.position += 5__1.transform.forward * 3f * Time.deltaTime; <>2__current = null; <>1__state = 3; return true; } if ((Object)(object)5__1 == (Object)null) { return false; } 5__6 = 5__1.GetComponent(); if ((Object)(object)5__6 != (Object)null && 5__6.IsOwner()) { 5__7 = 5__6.GetZDO(); if (5__7 != null && ZDOMan.instance != null) { ZDOMan.instance.DestroyZDO(5__7); } 5__7 = null; } else if ((Object)(object)5__6 != (Object)null) { 5__6.ClaimOwnership(); 5__8 = 5__6.GetZDO(); if (5__8 != null && ZDOMan.instance != null) { ZDOMan.instance.DestroyZDO(5__8); } 5__8 = null; } else { Object.Destroy((Object)(object)5__1); } ManualLogSource log3 = Log; if (log3 != null) { log3.LogInfo((object)"RetreatCoroutine: barco destruido."); } 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(); } } [CompilerGenerated] private sealed class d__22 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public InvasionContext ctx; public int waveIndex; public int skeletonCount; public int ghostCount; public bool includeRancid; public SpawnGhostLongshipAndSkels <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; _currentWaveAlive = 0; BroadcastHud(showTimer: true, <>4__this._eventTimeRemaining, showTitle: true, (waveIndex == 1) ? "Los enemigos desembarcan cerca..." : "Más enemigos se acercan"); <>4__this.SpawnSkeletonWave(ctx, skeletonCount, ghostCount, includeRancid, waveIndex); if (_currentWaveAlive <= 0) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)$"Wave {waveIndex}: no se spawneó ningún enemigo."); } return false; } break; case 1: <>1__state = -1; <>4__this._eventTimeRemaining -= 1f; BroadcastHud(<>4__this._eventTimeRemaining > 0f, <>4__this._eventTimeRemaining, showTitle: true); break; } if (<>4__this._eventTimeRemaining > 0f && _currentWaveAlive > 0) { <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)$"Wave {waveIndex}: finalizada."); } 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(); } } [CompilerGenerated] private sealed class d__20 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public InvasionContext ctx; public SpawnGhostLongshipAndSkels <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = <>4__this.RunSingleWave(ctx, 1, 2, 1, includeRancid: false); <>1__state = 1; return true; case 1: <>1__state = -1; if (<>4__this._eventTimeRemaining <= 0f) { return false; } <>2__current = <>4__this.WaveBreak(); <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = <>4__this.RunSingleWave(ctx, 2, 4, 0, includeRancid: false); <>1__state = 3; return true; case 3: <>1__state = -1; if (<>4__this._eventTimeRemaining <= 0f) { return false; } <>2__current = <>4__this.WaveBreak(); <>1__state = 4; return true; case 4: <>1__state = -1; <>2__current = <>4__this.RunSingleWave(ctx, 3, 5, 2, includeRancid: false); <>1__state = 5; return true; case 5: <>1__state = -1; if (<>4__this._eventTimeRemaining <= 0f) { return false; } <>2__current = <>4__this.WaveBreak(); <>1__state = 6; return true; case 6: <>1__state = -1; <>2__current = <>4__this.RunSingleWave(ctx, 4, 6, 0, includeRancid: false); <>1__state = 7; return true; case 7: <>1__state = -1; if (<>4__this._eventTimeRemaining <= 0f) { return false; } <>2__current = <>4__this.WaveBreak(); <>1__state = 8; return true; case 8: <>1__state = -1; <>2__current = <>4__this.RunSingleWave(ctx, 5, 6, 2, includeRancid: true); <>1__state = 9; return true; case 9: <>1__state = -1; 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(); } } [CompilerGenerated] private sealed class d__16 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Player targetPlayer; public SpawnGhostLongshipAndSkels <>4__this; private InvasionContext 5__1; private GameObject 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this._eventRunning = true; BroadcastHud(showTimer: false, 0f, showTitle: true, "El enemigo ha encontrado tu base"); <>2__current = (object)new WaitForSeconds(10f); <>1__state = 1; return true; case 1: <>1__state = -1; BroadcastHud(showTimer: false, 0f, showTitle: true, "Los enemigos desembarcan cerca tuyo"); <>2__current = (object)new WaitForSeconds(1.5f); <>1__state = 2; return true; case 2: <>1__state = -1; if (!<>4__this.PrepareInvasionContext(targetPlayer, out 5__1)) { BroadcastHud(showTimer: false, 0f, showTitle: false, "No se pudo encontrar una orilla cercana."); <>4__this._eventRunning = false; return false; } 5__2 = <>4__this.SpawnBoat(5__1); <>4__this._currentBoat = 5__2; if ((Object)(object)5__2 == (Object)null) { BroadcastHud(showTimer: false, 0f, showTitle: false, "Falló el spawn del Longship."); <>4__this._eventRunning = false; return false; } <>4__this._eventTimeRemaining = 150f; <>4__this._showTimer = true; BroadcastHud(showTimer: true, <>4__this._eventTimeRemaining, showTitle: true); <>2__current = <>4__this.RunWaves(5__1); <>1__state = 3; return true; case 3: { <>1__state = -1; <>4__this._showTimer = false; BroadcastHud(showTimer: false, 0f, showTitle: true); ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "Nazhi_RPC_StartRetreat", new object[1] { 5__1.ShoreDir }); } <>2__current = (object)new WaitForSeconds(14f); <>1__state = 4; return true; } case 4: { <>1__state = -1; BroadcastHud(showTimer: false, 0f, showTitle: false); <>4__this._eventRunning = false; <>4__this._currentBoat = null; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"Evento finalizado."); } 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(); } } [CompilerGenerated] private sealed class d__60 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public SpawnGhostLongshipAndSkels <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__60(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.2f); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.CheckAllWaveSkeletonGhosts("[GhostFix-0.2]"); <>2__current = (object)new WaitForSeconds(0.8f); <>1__state = 2; return true; case 2: <>1__state = -1; <>4__this.CheckAllWaveSkeletonGhosts("[GhostFix-1.0]"); 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(); } } [CompilerGenerated] private sealed class d__21 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public SpawnGhostLongshipAndSkels <>4__this; private float 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__21(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = 3f; break; case 1: <>1__state = -1; 5__1 -= 1f; <>4__this._eventTimeRemaining -= 1f; BroadcastHud(showTimer: true, <>4__this._eventTimeRemaining, showTitle: true); break; } if (5__1 > 0f && <>4__this._eventTimeRemaining > 0f) { <>2__current = (object)new WaitForSeconds(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(); } } internal const string BoatPrefab = "VikingShip"; internal const string SkelPrefab = "Skeleton"; internal const string RancidPrefab = "Skeleton_Poison"; internal const int TotalWaves = 5; internal const int FirstWaveSkels = 3; internal const int SkelsPerWaveIncrement = 2; internal const float TotalEventDurationSeconds = 150f; internal const float BreakBetweenWaves = 3f; private bool _eventRunning = false; internal static int _currentWaveAlive; internal float _eventTimeRemaining = 0f; internal bool _showTimer = false; internal GameObject _currentBoat; internal const string RpcStartRetreat = "Nazhi_RPC_StartRetreat"; internal static Material GhostMaterial; internal static bool _hudShowTimer; internal static float _hudTimeRemaining; internal static bool _hudShowTitle; private static GUIStyle _timerStyle; private static GUIStyle _titleStyle; private static GUIStyle _titleShadow; internal const string RpcEventHud = "Nazhi_RPC_EventHud"; internal static ManualLogSource Log; internal static SpawnGhostLongshipAndSkels Instance; internal const string RpcApplyGhost = "Nazhi_RPC_ApplyGhost"; internal const string ZdoGhostKey = "nazhi_ghost"; private Harmony _harmony; public static void StartEventForTarget(Player target) { if ((Object)(object)target == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"StartEventForTarget: target es null."); } } else if ((Object)(object)Instance == (Object)null) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogError((object)"StartEventForTarget: Instance es null (plugin no inicializado)."); } } else { Instance.StartEventForTargetInternal(target); } } private void StartEventForTargetInternal(Player target) { if ((Object)(object)target == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"StartEventForTargetInternal: target es null."); } return; } if (_eventRunning) { MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)2, "La invasión ya está en curso...", 0, (Sprite)null, false); } return; } ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)("Iniciando evento de invasión para: " + target.GetPlayerName())); } ((MonoBehaviour)this).StartCoroutine(TriggerEventFlow(target)); } [IteratorStateMachine(typeof(d__16))] private IEnumerator TriggerEventFlow(Player targetPlayer) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__16(0) { <>4__this = this, targetPlayer = targetPlayer }; } internal static void OnRpcStartRetreat(long sender, Vector3 shoreDir) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Instance == (Object)null)) { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"OnRpcStartRetreat: iniciando retirada local."); } ((MonoBehaviour)Instance).StartCoroutine(Instance.RetreatCoroutine(shoreDir)); } } [IteratorStateMachine(typeof(d__18))] private IEnumerator RetreatCoroutine(Vector3 shoreDir) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__18(0) { <>4__this = this, shoreDir = shoreDir }; } private static GameObject FindBoatInScene() { if ((Object)(object)Instance?._currentBoat != (Object)null) { return Instance._currentBoat; } GameObject[] array = Object.FindObjectsOfType(); ZNetView val2 = default(ZNetView); foreach (GameObject val in array) { if ((Object)(object)val == (Object)null) { continue; } string name = ((Object)val).name; if ((name.IndexOf("VikingShip", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Longship", StringComparison.OrdinalIgnoreCase) >= 0) && val.TryGetComponent(ref val2)) { ZDO zDO = val2.GetZDO(); if (zDO != null && zDO.GetBool("nazhi_ghost", false)) { return val; } } } return null; } [IteratorStateMachine(typeof(d__20))] private IEnumerator RunWaves(InvasionContext ctx) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__20(0) { <>4__this = this, ctx = ctx }; } [IteratorStateMachine(typeof(d__21))] private IEnumerator WaveBreak() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__21(0) { <>4__this = this }; } [IteratorStateMachine(typeof(d__22))] private IEnumerator RunSingleWave(InvasionContext ctx, int waveIndex, int skeletonCount, int ghostCount, bool includeRancid) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__22(0) { <>4__this = this, ctx = ctx, waveIndex = waveIndex, skeletonCount = skeletonCount, ghostCount = ghostCount, includeRancid = includeRancid }; } internal static void TryCacheGhostMaterial() { if ((Object)(object)GhostMaterial != (Object)null) { return; } ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null) { return; } GameObject prefab = instance.GetPrefab("Ghost"); if (!Object.op_Implicit((Object)(object)prefab)) { return; } SkinnedMeshRenderer componentInChildren = prefab.GetComponentInChildren(); if (Object.op_Implicit((Object)(object)componentInChildren)) { GhostMaterial = ((Renderer)componentInChildren).material; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"GhostMaterial cacheado."); } } } private void OnGUI() { if (_hudShowTitle) { DrawEventTitle(); } if (_hudShowTimer && _hudTimeRemaining > 0f) { DrawTimer(); } } private static void DrawEventTitle() { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (_titleStyle == null) { _titleStyle = new GUIStyle(GUI.skin.label) { fontSize = 20, fontStyle = (FontStyle)1, alignment = (TextAnchor)1 }; _titleStyle.normal.textColor = new Color(0.55f, 0.85f, 1f); _titleShadow = new GUIStyle(_titleStyle); _titleShadow.normal.textColor = new Color(0f, 0f, 0f, 0.55f); } float num = ((float)Screen.width - 340f) * 0.5f; GUI.Label(new Rect(num + 2f, 22f, 340f, 32f), "Invasión Espectral", _titleShadow); GUI.Label(new Rect(num, 20f, 340f, 32f), "Invasión Espectral", _titleStyle); } private static void DrawTimer() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) if (_timerStyle == null) { _timerStyle = new GUIStyle(GUI.skin.label) { fontSize = 24, fontStyle = (FontStyle)1, alignment = (TextAnchor)1 }; _timerStyle.normal.textColor = new Color(1f, 0.84f, 0f); } float num = ((float)Screen.width - 200f) * 0.5f; float num2 = (_hudShowTitle ? 54f : 20f); GUI.Label(new Rect(num, num2, 200f, 40f), FormatTime(_hudTimeRemaining), _timerStyle); } private static string FormatTime(float seconds) { if (seconds < 0f) { seconds = 0f; } int num = Mathf.RoundToInt(seconds); return $"{num / 60:00}:{num % 60:00}"; } internal static void BroadcastHud(bool showTimer, float timeRemaining, bool showTitle, string centerMsg = "") { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "Nazhi_RPC_EventHud", new object[4] { showTimer ? 1 : 0, timeRemaining, showTitle ? 1 : 0, centerMsg ?? "" }); } } internal static void OnRpcEventHud(long sender, int showTimerI, float timeRemaining, int showTitleI, string centerMsg) { _hudShowTimer = showTimerI != 0; _hudTimeRemaining = timeRemaining; _hudShowTitle = showTitleI != 0; if (!string.IsNullOrEmpty(centerMsg)) { MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)2, centerMsg, 0, (Sprite)null, false); } } } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; ((Component)this).gameObject.AddComponent(); Log.LogInfo((object)"Knuckles GhostShip cargado (Main.cs)"); } private static void OnRpcApplyGhost(long sender, ZDOID zdoid) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNetScene.instance == (Object)null) { return; } ZDOMan instance = ZDOMan.instance; ZDO val = ((instance != null) ? instance.GetZDO(zdoid) : null); if (val == null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)$"RPC_ApplyGhost: no se encontró ZDO para ZDOID={zdoid}"); } return; } ZNetView val2 = ZNetScene.instance.FindInstance(val); if ((Object)(object)val2 == (Object)null) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)$"RPC_ApplyGhost: no se encontró ZNetView para ZDOID={zdoid}"); } return; } GameObject gameObject = ((Component)val2).gameObject; if (!((Object)(object)gameObject == (Object)null)) { TryCacheGhostMaterial(); if (((Object)gameObject).name.IndexOf("VikingShip", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)gameObject).name.IndexOf("Longship", StringComparison.OrdinalIgnoreCase) >= 0) { DisableWaterEffects(gameObject); ApplyGhostMaterial_Filtered(gameObject); } else { ApplyGhostMaterial(gameObject); } ManualLogSource log3 = Log; if (log3 != null) { log3.LogInfo((object)$"RPC_ApplyGhost: ghost aplicado a {((Object)gameObject).name} (ZDOID={zdoid})"); } } } internal static void SendGhostRpc(GameObject go) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) ZNetView val = default(ZNetView); if ((Object)(object)go == (Object)null || !go.TryGetComponent(ref val)) { return; } ZDO zDO = val.GetZDO(); if (zDO != null) { ZDOID uid = zDO.m_uid; ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "Nazhi_RPC_ApplyGhost", new object[1] { uid }); } ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"SendGhostRpc enviado para {((Object)go).name} (ZDOID={uid})"); } } } internal static GameObject InstantiateNet(string prefabName, Vector3 pos, Quaternion rot, bool markAsGhost = false) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null) { return null; } GameObject prefab = instance.GetPrefab(prefabName); if ((Object)(object)prefab == (Object)null) { return null; } GameObject val = Object.Instantiate(prefab, pos, rot); ZNetView val2 = default(ZNetView); if (val.TryGetComponent(ref val2)) { ZDO zDO = val2.GetZDO(); if (zDO != null) { zDO.SetPosition(pos); zDO.SetRotation(rot); if (markAsGhost) { zDO.Set("nazhi_ghost", true); } } } return val; } private void Start() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown RegisterConsoleCommand(); CacheGhostMaterialStartup(); _harmony = new Harmony("nazhi.ghostship"); _harmony.PatchAll(typeof(ZNetPatch)); Log.LogInfo((object)"Harmony patch aplicado."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void RegisterConsoleCommand() { try { CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new SkellyEventCommand()); Log.LogInfo((object)"Comando 'skellyevent' registrado."); } catch (Exception arg) { Log.LogError((object)$"Error registrando comando 'skellyevent': {arg}"); } } private void CacheGhostMaterialStartup() { try { TryCacheGhostMaterial(); Log.LogInfo((object)"GhostMaterial cacheado en Startup."); } catch (Exception arg) { Log.LogError((object)$"Error cacheando GhostMaterial: {arg}"); } } internal static void RegisterAllRpcs() { if (ZRoutedRpc.instance == null) { Log.LogWarning((object)"RegisterAllRpcs: ZRoutedRpc.instance sigue null."); return; } try { ZRoutedRpc.instance.Register("Nazhi_RPC_ApplyGhost", (Action)OnRpcApplyGhost); } catch { } try { ZRoutedRpc.instance.Register("Nazhi_RPC_EventHud", (Method)OnRpcEventHud); } catch { } try { ZRoutedRpc.instance.Register("Nazhi_RPC_StartRetreat", (Action)OnRpcStartRetreat); } catch { } Log.LogInfo((object)"RPCs registrados correctamente."); } private bool PrepareInvasionContext(Player target, out InvasionContext ctx) { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) ctx = default(InvasionContext); ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogError((object)"PrepareInvasionContext: ZNetScene.instance es null."); } return false; } if ((Object)(object)instance.GetPrefab("VikingShip") == (Object)null || (Object)(object)instance.GetPrefab("Skeleton") == (Object)null) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogError((object)"PrepareInvasionContext: prefabs no encontrados Boat=VikingShip, Skel=Skeleton"); } return false; } if ((Object)(object)target == (Object)null) { ManualLogSource log3 = Log; if (log3 != null) { log3.LogError((object)"PrepareInvasionContext: target es null."); } return false; } Vector3 position = ((Component)target).transform.position; if (!FindNearestShore(position, 80f, out var shorePoint, out var waterPoint, out var shoreDir)) { ManualLogSource log4 = Log; if (log4 != null) { log4.LogWarning((object)("PrepareInvasionContext: no se encontró orilla (<= 80m) para " + target.GetPlayerName() + ".")); } return false; } float waterLevel = GetWaterLevel(); Vector3 val = -((Vector3)(ref shoreDir)).normalized; Vector3 start = waterPoint + val * 8f; Vector3 val2 = PushToDeeperWater(start, shoreDir, 3f, 15f, 1.5f); Vector3 boatPos = val2; boatPos.y = waterLevel + 0.25f; Vector3 val3 = new Vector3(shoreDir.x, 0f, shoreDir.z); Vector3 val4 = ((Vector3)(ref val3)).normalized; if (((Vector3)(ref val4)).sqrMagnitude < 0.001f) { val4 = Vector3.forward; } Quaternion boatRot = Quaternion.LookRotation(val4, Vector3.up); ctx = new InvasionContext { ShorePoint = shorePoint, WaterPoint = waterPoint, ShoreDir = shoreDir, WaterLevel = waterLevel, BoatPos = boatPos, BoatRot = boatRot }; ManualLogSource log5 = Log; if (log5 != null) { log5.LogInfo((object)$"PrepareInvasionContext OK para {target.GetPlayerName()} en {position}."); } return true; } private GameObject SpawnBoat(InvasionContext ctx) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) GameObject val = InstantiateNet("VikingShip", ctx.BoatPos, ctx.BoatRot, markAsGhost: true); if ((Object)(object)val == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogError((object)"SpawnBoat: falló InstantiateNet del Longship."); } return null; } val.AddComponent(); DisableWaterEffects(val); ApplyGhostMaterial_Filtered(val); SendGhostRpc(val); ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)"SpawnBoat: Longship ghost inmortal spawneado correctamente."); } return val; } private void SpawnSkeletonWave(InvasionContext ctx, int skeletonCount, int ghostCount, bool includeRancid, int waveIndex) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null) { return; } Vector3 normalized = ((Vector3)(ref ctx.ShoreDir)).normalized; Vector3 val = Vector3.Cross(Vector3.up, normalized); Vector3 normalized2 = ((Vector3)(ref val)).normalized; Vector3 val2 = ctx.ShorePoint + normalized * 2.5f; int num = 0; for (int i = 0; i < skeletonCount; i++) { float num2 = (float)i - (float)(skeletonCount - 1) * 0.5f; Vector3 xz = val2 + normalized2 * (num2 * 3f); if (!PlaceOnGround(xz, out var placed)) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)$"Wave {waveIndex}: no se encontró suelo para un skeleton."); } continue; } Quaternion rot = Quaternion.LookRotation(-ctx.ShoreDir, Vector3.up); GameObject val3 = InstantiateNet("Skeleton", placed, rot, markAsGhost: true); if ((Object)(object)val3 != (Object)null) { Character component = val3.GetComponent(); if (component != null) { component.m_level = Mathf.Max(1, waveIndex); } ApplyGhostMaterial(val3); val3.AddComponent(); AggroNearestPlayer(val3); val3.AddComponent(); SendGhostRpc(val3); _currentWaveAlive++; num++; } } for (int j = 0; j < ghostCount; j++) { float num3 = (float)j - (float)(ghostCount - 1) * 0.5f; Vector3 xz2 = val2 + normalized2 * (num3 * 3f * 0.7f); if (!PlaceOnGround(xz2, out var placed2)) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)$"Wave {waveIndex}: no se encontró suelo para un Ghost."); } continue; } Quaternion rot2 = Quaternion.LookRotation(-ctx.ShoreDir, Vector3.up); GameObject val4 = InstantiateNet("Ghost", placed2, rot2); if ((Object)(object)val4 != (Object)null) { Character component2 = val4.GetComponent(); if (component2 != null) { component2.m_level = Mathf.Max(1, waveIndex); } AggroNearestPlayer(val4); val4.AddComponent(); _currentWaveAlive++; num++; } } if (includeRancid) { GameObject prefab = instance.GetPrefab("Skeleton_Poison"); if ((Object)(object)prefab != (Object)null) { Vector3 xz3 = val2; if (PlaceOnGround(xz3, out var placed3)) { Quaternion rot3 = Quaternion.LookRotation(-ctx.ShoreDir, Vector3.up); GameObject val5 = InstantiateNet("Skeleton_Poison", placed3, rot3, markAsGhost: true); if ((Object)(object)val5 != (Object)null) { Character component3 = val5.GetComponent(); if (component3 != null) { component3.m_level = Mathf.Max(1, waveIndex + 1); } ApplyGhostMaterial(val5); val5.AddComponent(); AggroNearestPlayer(val5); val5.AddComponent(); SendGhostRpc(val5); _currentWaveAlive++; num++; ManualLogSource log3 = Log; if (log3 != null) { log3.LogInfo((object)"Wave final: Rancid Remains añadido."); } } } } else { ManualLogSource log4 = Log; if (log4 != null) { log4.LogWarning((object)"SpawnSkeletonWave: prefab RancidPrefab no encontrado."); } } } ManualLogSource log5 = Log; if (log5 != null) { log5.LogInfo((object)$"Wave {waveIndex}: {num} enemigos generados."); } ((MonoBehaviour)this).StartCoroutine(VerifyWaveGhostMaterials()); } [IteratorStateMachine(typeof(d__60))] private IEnumerator VerifyWaveGhostMaterials() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__60(0) { <>4__this = this }; } private void CheckAllWaveSkeletonGhosts(string tag) { WaveSkeleton[] array = Object.FindObjectsOfType(); WaveSkeleton[] array2 = array; foreach (WaveSkeleton waveSkeleton in array2) { GameObject gameObject = ((Component)waveSkeleton).gameObject; if (!((Object)(object)gameObject == (Object)null) && ((Object)gameObject).name.IndexOf("Ghost", StringComparison.OrdinalIgnoreCase) < 0) { ApplyGhostMaterial(gameObject); ManualLogSource log = Log; if (log != null) { log.LogWarning((object)(tag + " Enemy forzado a ghost. Obj=" + ((Object)gameObject).name)); } } } } private static bool FindNearestShore(Vector3 origin, float maxRadius, out Vector3 shorePoint, out Vector3 waterPoint, out Vector3 shoreDir) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (shoreDir = Vector3.zero); val = (shorePoint = (waterPoint = val)); float waterLevel = GetWaterLevel(); float num = waterLevel - 0.3f; float num2 = float.MaxValue; bool result = false; Vector3 val2 = default(Vector3); for (int i = 0; i < 36; i++) { float num3 = (float)Math.PI * 2f * ((float)i / 36f); ((Vector3)(ref val2))..ctor(Mathf.Cos(num3), 0f, Mathf.Sin(num3)); bool flag = false; bool flag2 = false; Vector3 val3 = origin; for (float num4 = 1f; num4 <= maxRadius; num4 += 1f) { Vector3 val4 = origin + val2 * num4; if (!TryGetGroundHeight(val4, out var height)) { continue; } bool flag3 = height >= num; if (!flag2) { flag2 = true; flag = flag3; val3 = val4; continue; } if (flag3 != flag) { Vector3 val5 = val3; Vector3 val6 = val4; for (int j = 0; j < 10; j++) { Vector3 val7 = (val5 + val6) * 0.5f; TryGetGroundHeight(val7, out var height2); bool flag4 = height2 >= num; if (flag4 == flag) { val5 = val7; } else { val6 = val7; } } Vector3 val8 = (flag ? val5 : val6); Vector3 val9 = (flag ? val6 : val5); float num5 = Vector3.Distance(origin, val8); if (num5 < num2) { num2 = num5; shorePoint = val8; waterPoint = val9; val = val8 - val9; shoreDir = ((Vector3)(ref val)).normalized; result = true; } break; } flag = flag3; val3 = val4; } } return result; } private static bool TryGetGroundHeight(Vector3 pos, out float height) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) height = 0f; if ((Object)(object)ZoneSystem.instance != (Object)null) { try { float num = default(float); if (ZoneSystem.instance.GetSolidHeight(pos, ref num, 1000)) { height = num; return true; } } catch { } } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(pos.x, 2000f, pos.z); RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(val, Vector3.down, ref val2, 5000f, -1, (QueryTriggerInteraction)1)) { height = ((RaycastHit)(ref val2)).point.y; return true; } return false; } private static float GetHeightSafe(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) float height; return TryGetGroundHeight(pos, out height) ? height : GetWaterLevel(); } private static float GetWaterLevel() { return ((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.m_waterLevel : 30f; } private static float GetDepthAt(Vector3 pos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) float waterLevel = GetWaterLevel(); float heightSafe = GetHeightSafe(pos); return waterLevel - heightSafe; } private static Vector3 PushToDeeperWater(Vector3 start, Vector3 shoreDir, float minDepth, float maxPush, float step) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) Vector3 val = -((Vector3)(ref shoreDir)).normalized; Vector3 val2 = start; for (float num = 0f; num <= maxPush; num += step) { if (GetDepthAt(val2) >= minDepth) { return val2; } val2 += val * step; } return start; } private static bool PlaceOnGround(Vector3 xz, out Vector3 placed) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) placed = xz; if (TryGetGroundHeight(xz, out var height)) { placed.y = height; return true; } return false; } internal static void ApplyGhostMaterial(GameObject go) { if ((Object)(object)GhostMaterial == (Object)null) { TryCacheGhostMaterial(); if ((Object)(object)GhostMaterial == (Object)null) { return; } } Renderer[] componentsInChildren = go.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { val.material = GhostMaterial; } } internal static void ApplyGhostOverlay(GameObject go) { if ((Object)(object)GhostMaterial == (Object)null) { TryCacheGhostMaterial(); if ((Object)(object)GhostMaterial == (Object)null) { return; } } Renderer[] componentsInChildren = go.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { Material[] materials = val.materials; Material[] array = (Material[])(object)new Material[materials.Length + 1]; for (int j = 0; j < materials.Length; j++) { array[j] = materials[j]; } array[materials.Length] = GhostMaterial; val.materials = array; } } internal static void ApplyGhostMaterial_Filtered(GameObject go) { if ((Object)(object)GhostMaterial == (Object)null) { TryCacheGhostMaterial(); if ((Object)(object)GhostMaterial == (Object)null) { return; } } Renderer[] componentsInChildren = go.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { string text = ((Object)((Component)val).gameObject).name.ToLowerInvariant(); if (!text.Contains("watereffects") && !text.Contains("watermask")) { val.material = GhostMaterial; } } ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"Ghost aplicado al Longship (filtrado)."); } } internal static void DisableWaterEffects(GameObject boat) { try { Transform val = FindChildRecursiveByNameContains(boat.transform, "watereffects"); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(false); ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"watereffects desactivados en el Longship."); } } else { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)"watereffects no encontrados en el Longship."); } } } catch (Exception arg) { ManualLogSource log3 = Log; if (log3 != null) { log3.LogError((object)$"DisableWaterEffects error: {arg}"); } } } private static Transform FindChildRecursiveByNameContains(Transform root, string substring) { if ((Object)(object)root == (Object)null || substring == null) { return null; } string value = substring.ToLowerInvariant(); if (((Object)root).name != null && ((Object)root).name.ToLowerInvariant().Contains(value)) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindChildRecursiveByNameContains(root.GetChild(i), substring); if ((Object)(object)val != (Object)null) { return val; } } return null; } internal static void AggroNearestPlayer(GameObject skel) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) try { Character component = skel.GetComponent(); if ((Object)(object)component == (Object)null) { return; } Player closestPlayer = Player.GetClosestPlayer(skel.transform.position, 60f); if ((Object)(object)closestPlayer == (Object)null) { return; } MonsterAI component2 = skel.GetComponent(); if ((Object)(object)component2 != (Object)null) { ((BaseAI)component2).m_alerted = true; ((BaseAI)component2).SetHuntPlayer(true); component2.SetTarget((Character)(object)closestPlayer); ((BaseAI)component2).SetAggravated(true, (AggravatedReason)0); ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("Aggro → " + closestPlayer.GetPlayerName() + " (MonsterAI)")); } return; } BaseAI component3 = skel.GetComponent(); if ((Object)(object)component3 != (Object)null) { component3.m_alerted = true; component3.SetHuntPlayer(true); component3.SetAggravated(true, (AggravatedReason)0); component3.Alert(); ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)("Aggro → " + closestPlayer.GetPlayerName() + " (BaseAI fallback)")); } } } catch (Exception arg) { ManualLogSource log3 = Log; if (log3 != null) { log3.LogError((object)$"AggroNearestPlayer error: {arg}"); } } } } public class GhostSyncMonitor : MonoBehaviour { [CompilerGenerated] private sealed class d__3 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public GhostSyncMonitor <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; if (!((Object)(object)ZNetScene.instance == (Object)null)) { SpawnGhostLongshipAndSkels.TryCacheGhostMaterial(); if (!((Object)(object)SpawnGhostLongshipAndSkels.GhostMaterial == (Object)null)) { <>4__this.ScanAllNetViews(); } } break; } <>2__current = (object)new WaitForSeconds(1.5f); <>1__state = 1; return true; } 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 const float ScanInterval = 1.5f; private readonly HashSet _processed = new HashSet(); private void Start() { ((MonoBehaviour)this).StartCoroutine(ScanLoop()); } [IteratorStateMachine(typeof(d__3))] private IEnumerator ScanLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__3(0) { <>4__this = this }; } private void ScanAllNetViews() { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) ZNetView[] array = Object.FindObjectsOfType(); foreach (ZNetView val in array) { if ((Object)(object)val == (Object)null) { continue; } ZDO zDO = val.GetZDO(); if (zDO == null || !zDO.GetBool("nazhi_ghost", false)) { continue; } GameObject gameObject = ((Component)val).gameObject; if ((Object)(object)gameObject == (Object)null) { continue; } if (((Object)gameObject).name.IndexOf("VikingShip", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)gameObject).name.IndexOf("Longship", StringComparison.OrdinalIgnoreCase) >= 0) { SpawnGhostLongshipAndSkels.DisableWaterEffects(gameObject); SpawnGhostLongshipAndSkels.ApplyGhostMaterial_Filtered(gameObject); } else { SpawnGhostLongshipAndSkels.ApplyGhostMaterial(gameObject); } ZDOID uid = zDO.m_uid; if (_processed.Add(uid)) { ManualLogSource log = SpawnGhostLongshipAndSkels.Log; if (log != null) { log.LogInfo((object)$"GhostSyncMonitor: ghost aplicado a {((Object)gameObject).name} (ZDOID={uid})"); } } } } } }