using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using RollingGiant; using RollingGiant.NetcodePatcher; using RollingGiant.Patches; using RollingGiant.Settings; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.Audio; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.Pool; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RollingGiant")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Adds an inventory to the ship, allowing it to store items and retrieve them.")] [assembly: AssemblyFileVersion("0.0.0.0")] [assembly: AssemblyInformationalVersion("0.0.0-alpha.0.37+f0703090c5e6dbe5b0417dc8c477feeda6c6d3e1")] [assembly: AssemblyProduct("RollingGiant")] [assembly: AssemblyTitle("RollingGiant")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] 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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RollingGiant { public class NetworkHandler : NetworkBehaviour { private static readonly List _aiTypes = Enum.GetValues(typeof(RollingGiantAiType)).Cast().Take(Enum.GetValues(typeof(RollingGiantAiType)).Length - 1) .ToList(); private NetworkVariable _aiType = new NetworkVariable(RollingGiantAiType.RandomlyMoveWhileLooking, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private static InputAction _gotoPreviousAiType; private static InputAction _gotoNextAiType; private static InputAction _reloadConfig; private static InputAction _tpAllToEntrance; private static InputAction _tpPlayersToMe; private static InputAction _killAllEnemies; private static InputAction _spawnGiant; public static NetworkHandler Instance { get; private set; } public static RollingGiantAiType AiType => Instance._aiType.Value; public override void OnNetworkSpawn() { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Expected O, but got Unknown //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Expected O, but got Unknown //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Expected O, but got Unknown if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) { if (Object.op_Implicit((Object)(object)Instance)) { ((Component)Instance).gameObject.GetComponent().Despawn(true); } _aiType.Value = CustomConfig.AiType.GetFirst(); } Instance = this; InputAction gotoPreviousAiType = _gotoPreviousAiType; if (gotoPreviousAiType != null) { gotoPreviousAiType.Disable(); } InputAction gotoPreviousAiType2 = _gotoPreviousAiType; if (gotoPreviousAiType2 != null) { gotoPreviousAiType2.Dispose(); } _gotoPreviousAiType = new InputAction("gotoPreviousAiType", (InputActionType)1, CustomConfig.GotoPreviousAiTypeKey.Value, (string)null, (string)null, (string)null); _gotoPreviousAiType.Enable(); InputAction gotoNextAiType = _gotoNextAiType; if (gotoNextAiType != null) { gotoNextAiType.Disable(); } InputAction gotoNextAiType2 = _gotoNextAiType; if (gotoNextAiType2 != null) { gotoNextAiType2.Dispose(); } _gotoNextAiType = new InputAction("gotoNextAiType", (InputActionType)1, CustomConfig.GotoNextAiTypeKey.Value, (string)null, (string)null, (string)null); _gotoNextAiType.Enable(); InputAction reloadConfig = _reloadConfig; if (reloadConfig != null) { reloadConfig.Disable(); } InputAction reloadConfig2 = _reloadConfig; if (reloadConfig2 != null) { reloadConfig2.Dispose(); } _reloadConfig = new InputAction("reloadConfig", (InputActionType)1, CustomConfig.ReloadConfigKey.Value, (string)null, (string)null, (string)null); _reloadConfig.Enable(); InputAction tpAllToEntrance = _tpAllToEntrance; if (tpAllToEntrance != null) { tpAllToEntrance.Disable(); } InputAction tpAllToEntrance2 = _tpAllToEntrance; if (tpAllToEntrance2 != null) { tpAllToEntrance2.Dispose(); } _tpAllToEntrance = new InputAction("tpAllToEntrance", (InputActionType)1, "/numpad1", (string)null, (string)null, (string)null); _tpAllToEntrance.Enable(); InputAction tpPlayersToMe = _tpPlayersToMe; if (tpPlayersToMe != null) { tpPlayersToMe.Disable(); } InputAction tpPlayersToMe2 = _tpPlayersToMe; if (tpPlayersToMe2 != null) { tpPlayersToMe2.Dispose(); } _tpPlayersToMe = new InputAction("tpPlayersToMe", (InputActionType)1, "/numpad2", (string)null, (string)null, (string)null); _tpPlayersToMe.Enable(); InputAction killAllEnemies = _killAllEnemies; if (killAllEnemies != null) { killAllEnemies.Disable(); } InputAction killAllEnemies2 = _killAllEnemies; if (killAllEnemies2 != null) { killAllEnemies2.Dispose(); } _killAllEnemies = new InputAction("killAllEnemies", (InputActionType)1, "/numpad3", (string)null, (string)null, (string)null); _killAllEnemies.Enable(); InputAction spawnGiant = _spawnGiant; if (spawnGiant != null) { spawnGiant.Disable(); } InputAction spawnGiant2 = _spawnGiant; if (spawnGiant2 != null) { spawnGiant2.Dispose(); } _spawnGiant = new InputAction("spawnEnemy", (InputActionType)1, "/numpad5", (string)null, (string)null, (string)null); _spawnGiant.Enable(); ((NetworkBehaviour)this).OnNetworkSpawn(); } public void SetAiType(RollingGiantAiType aiType) { if (((NetworkBehaviour)this).IsServer || ((NetworkBehaviour)this).IsHost) { SetNewAiType(aiType, showTip: false); } } private void Update() { //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028a: 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_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsServer && !((NetworkBehaviour)this).IsHost) { return; } if (_gotoPreviousAiType.WasPressedThisFrame()) { int num = _aiTypes.IndexOf(_aiType.Value) - 1; if (num < 0) { num = _aiTypes.Count - 1; } SetNewAiType(_aiTypes[num]); } else if (_gotoNextAiType.WasPressedThisFrame()) { int num2 = _aiTypes.IndexOf(_aiType.Value) + 1; if (num2 >= _aiTypes.Count) { num2 = 0; } SetNewAiType(_aiTypes[num2]); } else if (_reloadConfig.WasPressedThisFrame()) { Plugin.Config.Reload(); SyncedInstance.Instance.Reload(); _aiType.Value = CustomConfig.AiType.GetFirst(); SetNewAiType(_aiType.Value); HUDManager.Instance.DisplayTip("Config reloaded", $"Ai defaulted to {_aiType.Value}", false, false, "LC_Tip1"); } else if (_spawnGiant.WasPressedThisFrame()) { RoundManager instance = RoundManager.Instance; PlayerControllerB localPlayer = instance.playersManager.localPlayerController; SelectableLevel currentLevel = instance.currentLevel; bool isInsideFactory = localPlayer.isInsideFactory; foreach (SpawnableEnemyWithRarity enemy in currentLevel.Enemies) { if ((Object)(object)enemy.enemyType != (Object)(object)Plugin.EnemyTypeInside) { continue; } if (isInsideFactory) { EnemyVent val = instance.allEnemyVents.OrderBy((EnemyVent x) => Vector3.Distance(x.floorNode.position, ((Component)localPlayer).transform.position)).FirstOrDefault(); Vector3 position = val.floorNode.position; instance.SpawnEnemyOnServer(position, instance.allEnemyVents[0].floorNode.eulerAngles.y, currentLevel.Enemies.IndexOf(enemy)); } else { GameObject[] array = GameObject.FindGameObjectsWithTag("OutsideAINode"); Vector3 position2 = array[Random.Range(0, array.Length - 1)].transform.position; GameObject enemyPrefab = currentLevel.OutsideEnemies[currentLevel.OutsideEnemies.IndexOf(enemy)].enemyType.enemyPrefab; GameObject val2 = Object.Instantiate(enemyPrefab, position2, Quaternion.Euler(Vector3.zero)); val2.gameObject.GetComponentInChildren().Spawn(true); } HUDManager.Instance.DisplayTip("Spawned enemy", $"{((Object)enemy.enemyType).name}\n{_aiType.Value}", false, false, "LC_Tip1"); return; } HUDManager.Instance.DisplayTip("Failed", "No enemy found", true, false, "LC_Tip1"); } else if (_tpAllToEntrance.WasPressedThisFrame()) { Transform[] source = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); Transform val3 = ((IEnumerable)source).FirstOrDefault((Func)((Transform x) => Object.op_Implicit((Object)(object)x) && ((Object)x).name.ToLower().Contains("teleports"))); if (!Object.op_Implicit((Object)(object)val3)) { Plugin.Log.LogInfo((object)"No entrance found"); return; } for (int i = 0; i < val3.childCount; i++) { Transform child = val3.GetChild(i); if (!(((Object)child).name != "EntranceTeleportA")) { TeleportToClientRpc(child.position, RoundManager.Instance.playersManager.localPlayerController.isInsideFactory); RoundManager.Instance.playersManager.localPlayerController.TeleportPlayer(child.position, false, 0f, false, true); } } HUDManager.Instance.DisplayTip("Teleport", "Teleported players to entrance", false, false, "LC_Tip1"); } else if (_tpPlayersToMe.WasPressedThisFrame()) { PlayerControllerB localPlayerController = RoundManager.Instance.playersManager.localPlayerController; TeleportToClientRpc(((Component)localPlayerController).transform.position, localPlayerController.isInsideFactory); HUDManager.Instance.DisplayTip("Teleport", "Teleported players to you", false, false, "LC_Tip1"); } else if (_killAllEnemies.WasPressedThisFrame()) { EnemyAI[] array2 = Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0); EnemyAI[] array3 = array2; foreach (EnemyAI val4 in array3) { val4.KillEnemyOnOwnerClient(false); } HUDManager.Instance.DisplayTip("Kill all enemies", "Killed all enemies", false, false, "LC_Tip1"); } } private void SetNewAiType(RollingGiantAiType aiType, bool showTip = true) { RollingGiantAiType value = _aiType.Value; _aiType.Value = aiType; CustomConfig.SetCurrentAi(); EmitSharedServerSettingsClientRpc(); if (Object.op_Implicit((Object)(object)HUDManager.Instance) && value != aiType && showTip) { HUDManager.Instance.DisplayTip("Rolling Giant AI changed", aiType.ToString(), false, false, "LC_Tip1"); } Plugin.Log.LogMessage((object)$"Rolling Giant AI changed: {aiType}"); } [ClientRpc] private void EmitSharedServerSettingsClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4257552972u, val, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4257552972u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; CustomConfig.RequestSync(); } } } [ClientRpc] private void TeleportToClientRpc(Vector3 position, bool insideFactory) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_0131: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1240235977u, val, (RpcDelivery)0); ((FastBufferWriter)(ref val2)).WriteValueSafe(ref position); ((FastBufferWriter)(ref val2)).WriteValueSafe(ref insideFactory, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1240235977u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost)) { return; } base.__rpc_exec_stage = (__RpcExecStage)0; if (!((NetworkBehaviour)this).IsServer && !((NetworkBehaviour)this).IsHost) { PlayerControllerB localPlayerController = RoundManager.Instance.playersManager.localPlayerController; if (!localPlayerController.isPlayerDead && ((NetworkBehaviour)localPlayerController).IsSpawned) { localPlayerController.TeleportPlayer(position, false, 0f, false, true); localPlayerController.isInsideFactory = insideFactory; } } } protected override void __initializeVariables() { if (_aiType == null) { throw new Exception("NetworkHandler._aiType cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_aiType).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_aiType, "_aiType"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)_aiType); ((NetworkBehaviour)this).__initializeVariables(); } protected override void __initializeRpcs() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown ((NetworkBehaviour)this).__registerRpc(4257552972u, new RpcReceiveHandler(__rpc_handler_4257552972), "EmitSharedServerSettingsClientRpc"); ((NetworkBehaviour)this).__registerRpc(1240235977u, new RpcReceiveHandler(__rpc_handler_1240235977), "TeleportToClientRpc"); ((NetworkBehaviour)this).__initializeRpcs(); } private static void __rpc_handler_4257552972(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((NetworkHandler)(object)target).EmitSharedServerSettingsClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1240235977(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_005c: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { Vector3 position = default(Vector3); ((FastBufferReader)(ref reader)).ReadValueSafe(ref position); bool insideFactory = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref insideFactory, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((NetworkHandler)(object)target).TeleportToClientRpc(position, insideFactory); target.__rpc_exec_stage = (__RpcExecStage)0; } } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "NetworkHandler"; } } [BepInPlugin("nomnomab.rollinggiant", "Rolling Giant", "2.6.2")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "nomnomab.rollinggiant"; public const string PluginName = "Rolling Giant"; public const string PluginVersion = "2.6.2"; private const int SaveFileVersion = 11; public static string PluginDirectory; public static AssetBundle Bundle; public static EnemyType EnemyTypeInside; public static EnemyType EnemyTypeOutside; public static EnemyType EnemyTypeOutsideDaytime; public static TerminalNode EnemyTerminalNode; public static TerminalKeyword EnemyTerminalKeyword; public static AudioClip WalkSound; public static AudioClip[] StopSounds; public static GameObject PlayerRagdoll; public static Item PosterItem; public static Material BlackAndWhiteMaterial; internal static ManualLogSource Log; public static CustomConfig CustomConfig { get; private set; } public static ConfigFile Config { get; private set; } private void Awake() { Config = ((BaseUnityPlugin)this).Config; Log = ((BaseUnityPlugin)this).Logger; PluginDirectory = ((BaseUnityPlugin)this).Info.Location; LoadSettings(); RemoveOldSettings(); LoadAssets(); LoadNetWeaver(); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin nomnomab.rollinggiant is loaded!"); } private void LoadNetWeaver() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); Type[] array = types; foreach (Type type in array) { try { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { methodInfo.Invoke(null, null); } } } catch { Log.LogWarning((object)("NetWeaver is skipping " + type.FullName)); } } } private void LoadSettings() { CustomConfig = new CustomConfig(((BaseUnityPlugin)this).Config); } private void RemoveOldSettings() { int value = ((BaseUnityPlugin)this).Config.Bind("z_Ignore", "__version", 0, "The version of this config file. Do not change this.").Value; if (value != 11) { Log.LogMessage((object)$"Removing old settings... ({value} != {11})"); string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath; string destFileName = configFilePath + ".bak"; File.Copy(configFilePath, destFileName, overwrite: true); File.WriteAllText(configFilePath, ""); ((BaseUnityPlugin)this).Config.Reload(); CustomConfig.Reload(setValues: false); ((BaseUnityPlugin)this).Config.Bind("z_Ignore", "__version", 11, (ConfigDescription)null).Value = 11; CustomConfig.AssignFromSaved(); ((BaseUnityPlugin)this).Config.Save(); } else { Log.LogMessage((object)$"Settings version is up to date ({value} == {11})"); } } private void LoadAssets() { //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: 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_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) try { string directoryName = Path.GetDirectoryName(PluginDirectory); if (directoryName == null) { throw new Exception("Failed to get directory name!"); } Bundle = AssetBundle.LoadFromFile(Path.Combine(directoryName, "rollinggiant")); EnemyTypeInside = Bundle.LoadAsset("Assets/RollingGiant/Data/RollingGiant_EnemyType.asset"); EnemyTypeOutside = Bundle.LoadAsset("Assets/RollingGiant/Data/RollingGiant_EnemyType_Outside.asset"); EnemyTypeOutsideDaytime = Bundle.LoadAsset("Assets/RollingGiant/Data/RollingGiant_EnemyType_Outside_Daytime.asset"); EnemyTypeInside.MaxCount = RollingGiant.Settings.CustomConfig.MaxPerLevel; EnemyTypeOutside.MaxCount = RollingGiant.Settings.CustomConfig.MaxPerLevel; EnemyTypeOutsideDaytime.MaxCount = RollingGiant.Settings.CustomConfig.MaxPerLevel; NetworkPatches.RegisterPrefab(EnemyTypeInside.enemyPrefab); NetworkPatches.RegisterPrefab(EnemyTypeOutside.enemyPrefab); NetworkPatches.RegisterPrefab(EnemyTypeOutsideDaytime.enemyPrefab); EnemyTerminalNode = Bundle.LoadAsset("Assets/RollingGiant/Data/RollingGiant_TerminalNode.asset"); EnemyTerminalKeyword = Bundle.LoadAsset("Assets/RollingGiant/Data/RollingGiant_TerminalKeyword.asset"); } catch (Exception arg) { Log.LogError((object)$"Failed to load asset bundle! {arg}"); } try { WalkSound = Bundle.LoadAsset("Assets/RollingGiant/Audio/MovingLoop.wav"); StopSounds = (AudioClip[])(object)new AudioClip[5]; for (int i = 0; i < 5; i++) { StopSounds[i] = Bundle.LoadAsset($"Assets/RollingGiant/Audio/Stopped{i + 1}.wav"); } PlayerRagdoll = Bundle.LoadAsset("Assets/RollingGiant/PlayerRagdollRollingGiant Variant.prefab"); PlayerRagdoll.AddComponent(); PosterItem = Bundle.LoadAsset("Assets/RollingGiant/Data/RollingGiant_PosterItem.asset"); Item posterItem = PosterItem; posterItem.rotationOffset += new Vector3(45f, 0f, 0f); Item posterItem2 = PosterItem; posterItem2.positionOffset += new Vector3(-0.1f, -0.12f, 0.15f); Object.Destroy((Object)(object)PosterItem.spawnPrefab.GetComponent()); PosterItem.spawnPrefab.AddComponent().Init(); NetworkPatches.RegisterPrefab(PosterItem.spawnPrefab); BlackAndWhiteMaterial = Bundle.LoadAsset("Assets/RollingGiant/Materials/RollingGiant_Gray.mat"); } catch (Exception arg2) { Log.LogError((object)$"Failed to load assets! {arg2}"); } } } [HarmonyPatch] public class DebugEditorPatch { [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] public static void ForceIsEditor(ref bool __result) { __result = true; } } [Flags] public enum RollingGiantAiType { [Description("Coilhead AI")] Coilhead = 1, [Description("Move when player is looking at it")] InverseCoilhead = 2, [Description("Randomly move while the player is looking at it")] RandomlyMoveWhileLooking = 4, [Description("If the player looks at it for too long it doesn't stop chasing")] LookingTooLongKeepsAgro = 8, [Description("Once the player is noticed, the Rolling Giant will follow the player constantly")] FollowOnceAgro = 0x10, [Description("Once the player sees the Rolling Giant, it will chase the player after a timer")] OnceSeenAgroAfterTimer = 0x20, [Description("Will put all AI types into the selection for you")] All = 0x3F } public static class RollingGiantAiTypeExtensions { public static RollingGiantAiType GetFirst(this RollingGiantAiType aiType) { RollingGiantAiType[] array = Enum.GetValues(typeof(RollingGiantAiType)).Cast().ToArray(); for (int i = 0; i < array.Length - 1; i++) { RollingGiantAiType rollingGiantAiType = array[i]; if ((aiType & rollingGiantAiType) == rollingGiantAiType) { return rollingGiantAiType; } } return aiType; } public static RollingGiantAiType GetRandom(this RollingGiantAiType aiType, int seedOffset) { //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) List list = default(List); PooledObject> val = CollectionPool, RollingGiantAiType>.Get(ref list); try { RollingGiantAiType[] array = Enum.GetValues(typeof(RollingGiantAiType)).Cast().ToArray(); for (int i = 0; i < array.Length - 1; i++) { RollingGiantAiType rollingGiantAiType = array[i]; if ((aiType & rollingGiantAiType) == rollingGiantAiType) { list.Add(rollingGiantAiType); } } if (list.Count == 1) { return aiType; } RollingGiantAiType rollingGiantAiType2 = aiType; if (Object.op_Implicit((Object)(object)NetworkHandler.Instance)) { rollingGiantAiType2 = NetworkHandler.AiType; list.Remove(rollingGiantAiType2); } Random random = new Random(StartOfRound.Instance.randomMapSeed + seedOffset); int index = random.Next(0, list.Count); if (list.Count > 1) { rollingGiantAiType2 = list[index]; Plugin.Log.LogInfo((object)$"Selected AI type: {rollingGiantAiType2}"); } else if (list.Count == 0) { rollingGiantAiType2 = array[random.Next(0, array.Length - 1)]; Plugin.Log.LogInfo((object)$"Selected AI type: {rollingGiantAiType2}"); } else { rollingGiantAiType2 = list[0]; Plugin.Log.LogInfo((object)$"Selected initial AI type: {rollingGiantAiType2}"); } return rollingGiantAiType2; } finally { ((IDisposable)val).Dispose(); } } public static int AiTypesCount(this RollingGiantAiType aiType) { int num = 0; RollingGiantAiType[] array = Enum.GetValues(typeof(RollingGiantAiType)).Cast().ToArray(); for (int i = 0; i < array.Length - 1; i++) { RollingGiantAiType rollingGiantAiType = array[i]; if ((aiType & rollingGiantAiType) == rollingGiantAiType) { num++; } } return num; } } public class Poster : PhysicsProp { public void Init() { ((GrabbableObject)this).grabbable = true; ((GrabbableObject)this).itemProperties = Plugin.PosterItem; ((GrabbableObject)this).isInFactory = true; ((GrabbableObject)this).mainObjectRenderer = ((Component)this).GetComponent(); ((GrabbableObject)this).grabbableToEnemies = true; } protected override void __initializeVariables() { ((PhysicsProp)this).__initializeVariables(); } protected override void __initializeRpcs() { ((PhysicsProp)this).__initializeRpcs(); } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "Poster"; } } public class RollingGiantAI : EnemyAI { private const float ROAMING_AUDIO_PERCENT = 0.4f; [SerializeField] private AISearchRoutine _searchForPlayers; [SerializeField] private Collider _mainCollider; [SerializeField] private AudioClip[] _stopNoises; private AudioSource _rollingSFX; private NetworkVariable _velocity = new NetworkVariable(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private NetworkVariable _waitTimer = new NetworkVariable(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private NetworkVariable _moveTimer = new NetworkVariable(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private NetworkVariable _lookTimer = new NetworkVariable(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private NetworkVariable _agroTimer = new NetworkVariable(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private float _timeSinceHittingPlayer; private bool _wantsToChaseThisClient; private bool _hasEnteredChaseState; private bool _wasStopped; private bool _wasFeared; private bool _isAgro; private float _lastSpeed; private bool _tooBig; private static RollingGiantAiType _aiType => NetworkHandler.AiType; private static SharedAiSettings _sharedAiSettings => CustomConfig.SharedAiSettings; private static void LogInfo(object message) { Plugin.Log.LogInfo(message); } private static float NextDouble() { if (!Object.op_Implicit((Object)(object)RoundManager.Instance) || RoundManager.Instance.LevelRandom == null) { return Random.value; } return (float)RoundManager.Instance.LevelRandom.NextDouble(); } public override void Start() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) ((EnemyAI)this).Start(); Init(((Component)this).transform.localScale.x); if (((NetworkBehaviour)this).IsHost || ((NetworkBehaviour)this).IsOwner) { AssignInitData_LocalClient(); } LogInfo($"Rolling giant spawned with ai type: {NetworkHandler.AiType}, owner? {((NetworkBehaviour)this).IsOwner}"); } private void Init(float scale) { base.agent = ((Component)this).gameObject.GetComponentInChildren(); _rollingSFX = ((Component)((Component)this).transform.Find("RollingSFX")).GetComponent(); AudioMixerGroup outputAudioMixerGroup = SoundManager.Instance.diageticMixer.outputAudioMixerGroup; _rollingSFX.outputAudioMixerGroup = outputAudioMixerGroup; base.creatureVoice.outputAudioMixerGroup = outputAudioMixerGroup; base.creatureSFX.outputAudioMixerGroup = outputAudioMixerGroup; _rollingSFX.loop = true; _rollingSFX.clip = Plugin.WalkSound; float time = NextDouble() * Plugin.WalkSound.length; _rollingSFX.time = time; _rollingSFX.pitch = Mathf.Lerp(1.1f, 0.8f, Mathf.InverseLerp(0.9f, 1.2f, scale)); _rollingSFX.volume = 0f; _rollingSFX.Play(); base.isOutside = base.enemyType.isOutsideEnemy || base.enemyType.isDaytimeEnemy; if (base.isOutside) { base.allAINodes = GameObject.FindGameObjectsWithTag("OutsideAINode"); } else { base.allAINodes = GameObject.FindGameObjectsWithTag("AINode"); } } public void ResetValues() { if (((NetworkBehaviour)this).IsHost || ((NetworkBehaviour)this).IsServer) { _waitTimer.Value = 0f; _moveTimer.Value = 0f; _lookTimer.Value = 0f; _agroTimer.Value = 0f; ((EnemyAI)this).SwitchToBehaviourState(0); EndChasingPlayer_ClientRpc(); ResetValues_ClientRpc(); } } [ClientRpc] private void ResetValues_ClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1389605656u, val, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1389605656u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; _isAgro = false; _wasStopped = false; _wasFeared = false; } } } public override void DaytimeEnemyLeave() { ((EnemyAI)this).DaytimeEnemyLeave(); Renderer[] componentsInChildren = ((Component)((Component)this).transform).GetComponentsInChildren(); foreach (Renderer val in componentsInChildren) { if (!(((Object)val).name == "object_3")) { val.sharedMaterial = Plugin.BlackAndWhiteMaterial; } } _mainCollider.isTrigger = true; } public override void DoAIInterval() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: 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_01c6: Unknown result type (might be due to invalid IL or missing references) if (base.daytimeEnemyLeaving) { _mainCollider.isTrigger = true; return; } ((EnemyAI)this).DoAIInterval(); if (StartOfRound.Instance.livingPlayers == 0 || base.isEnemyDead) { return; } switch (base.currentBehaviourStateIndex) { case 0: { if (!((NetworkBehaviour)this).IsServer) { ((EnemyAI)this).ChangeOwnershipOfEnemy(StartOfRound.Instance.allPlayerScripts[0].actualClientId); break; } if (!_searchForPlayers.inProgress) { ((EnemyAI)this).StartSearch(((Component)this).transform.position, _searchForPlayers); LogInfo($"[DoAIInterval::{NetworkHandler.AiType}] StartSearch({((Component)this).transform.position}, _searchForPlayers)"); break; } PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (!val.isPlayerDead && ((NetworkBehaviour)val).IsSpawned && base.isOutside != val.isInsideFactory && (base.isOutside || ((EnemyAI)this).PlayerIsTargetable(val, false, false, true))) { float num = Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position); bool flag = num < (float)(base.isOutside ? 90 : 30); if (!Physics.Linecast(((Component)this).transform.position + Vector3.up * 0.5f, ((Component)val.gameplayCamera).transform.position, StartOfRound.Instance.collidersAndRoomMaskAndDefault) && flag) { ((EnemyAI)this).SwitchToBehaviourState(1); LogInfo($"[DoAIInterval::{NetworkHandler.AiType}] SwitchToBehaviourState(1), found {val?.playerUsername} at distance {num}m"); return; } } } if (!base.isOutside) { break; } PlayerControllerB closestPlayer = ((EnemyAI)this).GetClosestPlayer(false, false, false); if (Object.op_Implicit((Object)(object)closestPlayer) && !Physics.Linecast(((Component)this).transform.position + Vector3.up * 0.5f, ((Component)closestPlayer.gameplayCamera).transform.position, StartOfRound.Instance.collidersAndRoomMaskAndDefault)) { float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)closestPlayer).transform.position); if (num2 < (float)(base.isOutside ? 90 : 30)) { base.targetPlayer = closestPlayer; ((EnemyAI)this).SwitchToBehaviourState(1); LogInfo($"[DoAIInterval::{NetworkHandler.AiType}] ClosestPlayer! SwitchToBehaviourState(1), found {base.targetPlayer?.playerUsername}"); } } break; } case 1: if (!((EnemyAI)this).TargetClosestPlayer(1.5f, false, 70f, false, false, true)) { base.movingTowardsTargetPlayer = false; if (!_searchForPlayers.inProgress) { ((EnemyAI)this).SwitchToBehaviourState(0); LogInfo($"[DoAIInterval::{NetworkHandler.AiType}] lost player; StartSearch({((Component)this).transform.position}, _searchForPlayers)"); } } else if (_searchForPlayers.inProgress) { ((EnemyAI)this).StopSearch(_searchForPlayers, true); base.movingTowardsTargetPlayer = true; LogInfo($"[DoAIInterval::{NetworkHandler.AiType}] StopSearch(_searchForPlayers), found {base.targetPlayer?.playerUsername}"); } break; } } public override void Update() { //IL_0053: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_059b: Unknown result type (might be due to invalid IL or missing references) //IL_05a0: Unknown result type (might be due to invalid IL or missing references) //IL_05a8: Unknown result type (might be due to invalid IL or missing references) //IL_05ad: Unknown result type (might be due to invalid IL or missing references) //IL_05af: Unknown result type (might be due to invalid IL or missing references) //IL_05b1: Unknown result type (might be due to invalid IL or missing references) //IL_05b3: Unknown result type (might be due to invalid IL or missing references) //IL_05b8: Unknown result type (might be due to invalid IL or missing references) //IL_05ce: Unknown result type (might be due to invalid IL or missing references) //IL_05d0: Unknown result type (might be due to invalid IL or missing references) //IL_05d5: Unknown result type (might be due to invalid IL or missing references) //IL_05e3: Unknown result type (might be due to invalid IL or missing references) //IL_05e8: Unknown result type (might be due to invalid IL or missing references) //IL_05fa: Unknown result type (might be due to invalid IL or missing references) if (base.daytimeEnemyLeaving) { _mainCollider.isTrigger = true; _rollingSFX.volume = 0f; return; } Vector3 velocity2; if (((NetworkBehaviour)this).IsHost || ((NetworkBehaviour)this).IsServer) { NetworkVariable velocity = _velocity; velocity2 = base.agent.velocity; velocity.Value = ((Vector3)(ref velocity2)).magnitude; } ((EnemyAI)this).Update(); if (base.isEnemyDead) { return; } velocity2 = base.agent.velocity; _lastSpeed = ((Vector3)(ref velocity2)).magnitude; CalculateAgentSpeed(); _timeSinceHittingPlayer += Time.deltaTime; _mainCollider.isTrigger = _velocity.Value > 0.01f; float value = _velocity.Value; if (value > 0.1f) { _rollingSFX.volume = Mathf.Lerp(0f, Mathf.Clamp01(0.4f * value + 0.05f), value / _sharedAiSettings.moveSpeed); } else { _rollingSFX.volume = Mathf.Lerp(_rollingSFX.volume, 0f, Time.deltaTime); } GameNetworkManager instance = GameNetworkManager.Instance; PlayerControllerB localPlayerController = instance.localPlayerController; if (_wasStopped && !_wasFeared && localPlayerController.HasLineOfSightToPosition(base.eye.position, 70f, 25, -1f, -1)) { _wasFeared = true; float num = Vector3.Distance(((Component)this).transform.position, ((Component)localPlayerController).transform.position); if (num < 4f) { instance.localPlayerController.JumpToFearLevel(0.9f, true); } else if (num < 9f) { instance.localPlayerController.JumpToFearLevel(0.4f, true); } if (_lastSpeed > 1f) { RoundManager.PlayRandomClip(base.creatureVoice, _stopNoises, false, 1f, 0, 1000); } } switch (base.currentBehaviourStateIndex) { case 0: if (_hasEnteredChaseState) { _hasEnteredChaseState = false; _wantsToChaseThisClient = false; _wasStopped = false; _wasFeared = false; base.agent.speed = 0f; if (_aiType != RollingGiantAiType.OnceSeenAgroAfterTimer) { _isAgro = false; if (((NetworkBehaviour)this).IsOwner) { _agroTimer.Value = 0f; } } if (((NetworkBehaviour)this).IsOwner) { _waitTimer.Value = 0f; _moveTimer.Value = 0f; _lookTimer.Value = 0f; } } if (((NetworkBehaviour)this).IsOwner && ((EnemyAI)this).TargetClosestPlayer(1.5f, true, 70f, false, false, true) && !_wantsToChaseThisClient) { _wantsToChaseThisClient = true; BeginChasingPlayer_ServerRpc((int)base.targetPlayer.playerClientId); LogInfo($"[Update::{NetworkHandler.AiType}] began chasing local player {base.targetPlayer?.playerUsername}"); } break; case 1: { if (!_hasEnteredChaseState) { _hasEnteredChaseState = true; _wantsToChaseThisClient = false; _wasStopped = false; _wasFeared = false; if (_aiType != RollingGiantAiType.OnceSeenAgroAfterTimer) { _isAgro = false; if (((NetworkBehaviour)this).IsOwner) { _agroTimer.Value = 0f; } } if (((NetworkBehaviour)this).IsOwner) { _waitTimer.Value = 0f; _moveTimer.Value = 0f; _lookTimer.Value = 0f; } } if (base.stunNormalizedTimer > 0f) { break; } PlayerControllerB targetPlayer = base.targetPlayer; if (((NetworkBehaviour)this).IsOwner) { if (!base.isOutside && !((EnemyAI)this).TargetClosestPlayer(1.5f, false, 70f, false, false, true)) { ((EnemyAI)this).SwitchToBehaviourState(0); EndChasingPlayer_ServerRpc(); LogInfo($"[Update::{NetworkHandler.AiType}] not in range; SwitchToBehaviourState(0)"); break; } if (base.isOutside && !((EnemyAI)this).TargetClosestPlayer(1.5f, false, 70f, false, false, true)) { PlayerControllerB closestPlayer = ((EnemyAI)this).GetClosestPlayer(false, false, false); if (!Object.op_Implicit((Object)(object)closestPlayer)) { ((EnemyAI)this).SwitchToBehaviourState(0); EndChasingPlayer_ServerRpc(); LogInfo($"[Update::{NetworkHandler.AiType}] not in range; SwitchToBehaviourState(0)"); break; } base.targetPlayer = closestPlayer; } if (_wasStopped && _sharedAiSettings.rotateToLookAtPlayer && _lookTimer.Value >= _sharedAiSettings.delayBeforeLookingAtPlayer) { Vector3 position = ((Component)base.targetPlayer).transform.position; Vector3 position2 = ((Component)this).transform.position; Vector3 val = position - position2; val.y = 0f; ((Vector3)(ref val)).Normalize(); Quaternion val2 = Quaternion.LookRotation(val); ((Component)this).transform.rotation = Quaternion.Lerp(((Component)this).transform.rotation, val2, Time.deltaTime / _sharedAiSettings.lookAtPlayerDuration); } } RollingGiantAiType aiType = NetworkHandler.AiType; PlayerControllerB closestPlayer2; switch (aiType) { case RollingGiantAiType.Coilhead: if (AmIBeingLookedAt(out closestPlayer2)) { _wasStopped = true; return; } break; case RollingGiantAiType.InverseCoilhead: if (!AmIBeingLookedAt(out closestPlayer2) && _isAgro && CheckLineOfSightToAnyPlayer()) { _wasStopped = true; return; } break; case RollingGiantAiType.RandomlyMoveWhileLooking: if (AmIBeingLookedAt(out closestPlayer2) && _moveTimer.Value <= 0f) { _wasStopped = true; return; } break; case RollingGiantAiType.LookingTooLongKeepsAgro: if (AmIBeingLookedAt(out closestPlayer2) && _agroTimer.Value < 1f) { _wasStopped = true; return; } break; case RollingGiantAiType.OnceSeenAgroAfterTimer: if (_isAgro && _agroTimer.Value > 0f) { _wasStopped = true; return; } break; default: Plugin.Log.LogWarning((object)$"Unknown ai type: {aiType}"); break; case RollingGiantAiType.FollowOnceAgro: break; } _wasStopped = false; _wasFeared = false; if (((NetworkBehaviour)this).IsOwner && (Object)(object)targetPlayer != (Object)(object)base.targetPlayer) { ((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer); LogInfo($"[Update::{NetworkHandler.AiType}] SetMovingTowardsTargetPlayer, player {base.targetPlayer?.playerUsername}"); } break; } } } private static float SmoothLerp(float a, float b, float t) { return a + t * t * (b - a); } public override void OnCollideWithPlayer(Collider other) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) if (base.daytimeEnemyLeaving) { return; } ((EnemyAI)this).OnCollideWithPlayer(other); if (!(_timeSinceHittingPlayer < 0.6f)) { PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false); if (Object.op_Implicit((Object)(object)val) && (!_tooBig || !val.isInHangarShipRoom)) { _timeSinceHittingPlayer = 0.2f; int num = StartOfRound.Instance.playerRagdolls.IndexOf(Plugin.PlayerRagdoll); val.DamagePlayer(90, true, true, (CauseOfDeath)4, num, false, default(Vector3)); base.agent.speed = 0f; GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(1f, true); } } } private void CalculateAgentSpeed() { if (base.stunNormalizedTimer >= 0f) { base.agent.speed = 0f; base.agent.acceleration = 200f; } else if (base.currentBehaviourStateIndex == 0) { MoveAccelerate(); } else { if (base.currentBehaviourStateIndex != 1) { return; } if (((NetworkBehaviour)this).IsOwner && !IsAgentOnNavMesh(((Component)base.agent).gameObject)) { MoveAccelerate(); LogInfo($"[CalculateAgentSpeed::{NetworkHandler.AiType}] not on navmesh"); return; } PlayerControllerB closestPlayer; bool flag = AmIBeingLookedAt(out closestPlayer); if (((NetworkBehaviour)this).IsOwner) { if (flag) { NetworkVariable lookTimer = _lookTimer; lookTimer.Value += Time.deltaTime; } else { _lookTimer.Value = 0f; } } RollingGiantAiType aiType = NetworkHandler.AiType; switch (aiType) { case RollingGiantAiType.Coilhead: if (flag) { MoveDecelerate(); } else { MoveAccelerate(); } break; case RollingGiantAiType.InverseCoilhead: if (!flag && _isAgro && CheckLineOfSightToAnyPlayer()) { MoveDecelerate(); break; } MoveAccelerate(); _isAgro = true; break; case RollingGiantAiType.RandomlyMoveWhileLooking: if (flag) { if (_waitTimer.Value <= 0f && _moveTimer.Value <= 0f) { GenerateWaitTime(); } if (_waitTimer.Value > 0f && _moveTimer.Value <= 0f) { MoveDecelerate(); if (((NetworkBehaviour)this).IsOwner) { LogInfo($"_waitTimer: {_waitTimer.Value}"); NetworkVariable waitTimer = _waitTimer; waitTimer.Value -= Time.deltaTime; if (_waitTimer.Value <= 0f) { GenerateMoveTime(); } } break; } } MoveAccelerate(); if (_moveTimer.Value > 0f && ((NetworkBehaviour)this).IsOwner) { LogInfo($"_moveTimer: {_moveTimer.Value}"); NetworkVariable moveTimer = _moveTimer; moveTimer.Value -= Time.deltaTime; if (_moveTimer.Value <= 0f) { GenerateWaitTime(); } } break; case RollingGiantAiType.LookingTooLongKeepsAgro: if (!_isAgro) { if (flag) { if (((NetworkBehaviour)this).IsOwner) { NetworkVariable agroTimer2 = _agroTimer; agroTimer2.Value += Time.deltaTime / _sharedAiSettings.lookTimeBeforeAgro; } LogInfo($"[Update::{NetworkHandler.AiType}] _agroTimer: {_agroTimer.Value}"); if (_agroTimer.Value >= 1f) { _isAgro = true; LogInfo($"[Update::{NetworkHandler.AiType}] got agro"); } MoveDecelerate(); } else { if (((NetworkBehaviour)this).IsOwner) { _agroTimer.Value = Mathf.Lerp(_agroTimer.Value, 0f, Time.deltaTime / (_sharedAiSettings.lookTimeBeforeAgro * 1.5f)); LogInfo($"[Update::{NetworkHandler.AiType}] _agroTimer: {_agroTimer.Value}"); } MoveAccelerate(); } } else { MoveAccelerate(); } break; case RollingGiantAiType.FollowOnceAgro: if (!_isAgro && flag) { _isAgro = true; MoveDecelerate(); LogInfo($"[Update::{NetworkHandler.AiType}] got agro"); } else { MoveAccelerate(); } break; case RollingGiantAiType.OnceSeenAgroAfterTimer: if (!_isAgro) { if (flag) { _isAgro = true; LogInfo($"[Update::{NetworkHandler.AiType}] got agro"); if (((NetworkBehaviour)this).IsOwner) { _agroTimer.Value = Mathf.Lerp(_sharedAiSettings.waitTimeMin, _sharedAiSettings.waitTimeMax, NextDouble()); } MoveDecelerate(); break; } } else if (_agroTimer.Value > 0f) { LogInfo($"[Update::{NetworkHandler.AiType}] _agroTimer: {_agroTimer.Value}"); if (((NetworkBehaviour)this).IsOwner) { NetworkVariable agroTimer = _agroTimer; agroTimer.Value -= Time.deltaTime; } if (_agroTimer.Value <= 0f) { LogInfo($"[Update::{NetworkHandler.AiType}] chasing time"); } MoveDecelerate(); break; } MoveAccelerate(); break; default: Plugin.Log.LogWarning((object)$"Unknown ai type: {aiType}"); break; } } } private void MoveAccelerate() { base.agent.speed = ((_sharedAiSettings.moveAcceleration == 0f) ? _sharedAiSettings.moveSpeed : Mathf.Lerp(base.agent.speed, _sharedAiSettings.moveSpeed, Time.deltaTime / _sharedAiSettings.moveAcceleration)); base.agent.acceleration = Mathf.Lerp(base.agent.acceleration, 200f, Time.deltaTime); } private void MoveDecelerate() { base.agent.speed = ((_sharedAiSettings.moveDeceleration == 0f) ? 0f : Mathf.Lerp(base.agent.speed, 0f, Time.deltaTime / _sharedAiSettings.moveDeceleration)); base.agent.acceleration = 200f; } private bool AmIBeingLookedAt(out PlayerControllerB closestPlayer) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; float num = float.MaxValue; closestPlayer = null; PlayerControllerB[] array = allPlayerScripts; foreach (PlayerControllerB val in array) { if ((base.isOutside || ((EnemyAI)this).PlayerIsTargetable(val, false, false, true)) && !val.isPlayerDead && ((NetworkBehaviour)val).IsSpawned && val.HasLineOfSightToPosition(((Component)this).transform.position + Vector3.up * 1.6f, 68f, 60, -1f, -1)) { float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position); if (num2 < num) { num = num2; closestPlayer = val; } } } return Object.op_Implicit((Object)(object)closestPlayer); } private bool CheckLineOfSightTo(PlayerControllerB player) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) return Object.op_Implicit((Object)(object)player) && ((EnemyAI)this).CheckLineOfSightForPosition(((Component)player.gameplayCamera).transform.position, 68f, 60, -1f, (Transform)null); } private bool CheckLineOfSightToAnyPlayer() { PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; PlayerControllerB[] array = allPlayerScripts; foreach (PlayerControllerB val in array) { if (((NetworkBehaviour)val).IsSpawned && !val.isPlayerDead && CheckLineOfSightTo(val)) { return true; } } return false; } private bool IsAgentOnNavMesh(GameObject agentObject) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) Vector3 position = agentObject.transform.position; NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(position, ref val, 3f, -1) && Mathf.Approximately(position.x, ((NavMeshHit)(ref val)).position.x) && Mathf.Approximately(position.z, ((NavMeshHit)(ref val)).position.z)) { return position.y >= ((NavMeshHit)(ref val)).position.y; } return false; } [ServerRpc(RequireOwnership = false)] private void BeginChasingPlayer_ServerRpc(int playerId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(913739805u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, playerId); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 913739805u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; BeginChasingPlayer_ClientRpc(playerId); } } } [ClientRpc] private void BeginChasingPlayer_ClientRpc(int playerId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2111596117u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, playerId); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2111596117u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; ((EnemyAI)this).SwitchToBehaviourStateOnLocalClient(1); PlayerControllerB movingTowardsTargetPlayer = StartOfRound.Instance.allPlayerScripts[playerId]; ((EnemyAI)this).SetMovingTowardsTargetPlayer(movingTowardsTargetPlayer); } } } [ServerRpc(RequireOwnership = false)] private void EndChasingPlayer_ServerRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3771085912u, val, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3771085912u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; EndChasingPlayer_ClientRpc(); } } } [ClientRpc] private void EndChasingPlayer_ClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1947504516u, val, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1947504516u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; base.movingTowardsTargetPlayer = false; ((EnemyAI)this).SwitchToBehaviourStateOnLocalClient(0); } } } private void GenerateWaitTime() { if (((NetworkBehaviour)this).IsOwner) { float value = Mathf.Lerp(_sharedAiSettings.waitTimeMin, _sharedAiSettings.waitTimeMax, NextDouble()); _waitTimer.Value = value; } } private void GenerateAgroTime() { if (((NetworkBehaviour)this).IsOwner) { _agroTimer.Value = _sharedAiSettings.lookTimeBeforeAgro; } } private void GenerateMoveTime() { if (((NetworkBehaviour)this).IsOwner) { float value = Mathf.Lerp(_sharedAiSettings.randomMoveTimeMin, _sharedAiSettings.randomMoveTimeMax, NextDouble()); _moveTimer.Value = value; } } [ServerRpc(RequireOwnership = false)] private void AssignInitData_ServerRpc(float scale) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2584131514u, val, (RpcDelivery)0); ((FastBufferWriter)(ref val2)).WriteValueSafe(ref scale, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2584131514u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; AssignAgentData(scale); ((Component)base.agent).transform.localScale = Vector3.one * scale; AssignInitData_ClientRpc(scale); } } } private void AssignInitData_LocalClient() { //IL_002e: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) CustomConfig instance = SyncedInstance.Instance; Vector2 val = (base.isOutside ? new Vector2(instance.GiantScaleOutsideMin, instance.GiantScaleOutsideMax) : new Vector2(instance.GiantScaleInsideMin, instance.GiantScaleInsideMax)); float num = Mathf.Lerp(val.x, val.y, NextDouble()); AssignAgentData(num); ((Component)base.agent).transform.localScale = Vector3.one * num; AssignInitData_ServerRpc(num); } [ClientRpc] private void AssignInitData_ClientRpc(float scale) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3644677666u, val, (RpcDelivery)0); ((FastBufferWriter)(ref val2)).WriteValueSafe(ref scale, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3644677666u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; base.updatePositionThreshold = float.MaxValue; AssignAgentData(scale); ((Component)base.agent).transform.localScale = Vector3.one * scale; } } } private void AssignAgentData(float scale) { Init(scale); if (scale >= 1.2f) { int areaMask = base.agent.areaMask; areaMask &= ~(1 << NavMesh.GetAreaFromName("SmallSpace")); areaMask &= ~(1 << NavMesh.GetAreaFromName("MediumSpace")); areaMask &= ~(1 << NavMesh.GetAreaFromName("Climb")); areaMask &= ~(1 << NavMesh.GetAreaFromName("PlayerShip")); base.agent.areaMask = areaMask; _tooBig = true; } } protected override void __initializeVariables() { if (_velocity == null) { throw new Exception("RollingGiantAI._velocity cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_velocity).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_velocity, "_velocity"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)_velocity); if (_waitTimer == null) { throw new Exception("RollingGiantAI._waitTimer cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_waitTimer).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_waitTimer, "_waitTimer"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)_waitTimer); if (_moveTimer == null) { throw new Exception("RollingGiantAI._moveTimer cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_moveTimer).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_moveTimer, "_moveTimer"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)_moveTimer); if (_lookTimer == null) { throw new Exception("RollingGiantAI._lookTimer cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_lookTimer).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_lookTimer, "_lookTimer"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)_lookTimer); if (_agroTimer == null) { throw new Exception("RollingGiantAI._agroTimer cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_agroTimer).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_agroTimer, "_agroTimer"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)_agroTimer); ((EnemyAI)this).__initializeVariables(); } protected override void __initializeRpcs() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown ((NetworkBehaviour)this).__registerRpc(1389605656u, new RpcReceiveHandler(__rpc_handler_1389605656), "ResetValues_ClientRpc"); ((NetworkBehaviour)this).__registerRpc(913739805u, new RpcReceiveHandler(__rpc_handler_913739805), "BeginChasingPlayer_ServerRpc"); ((NetworkBehaviour)this).__registerRpc(2111596117u, new RpcReceiveHandler(__rpc_handler_2111596117), "BeginChasingPlayer_ClientRpc"); ((NetworkBehaviour)this).__registerRpc(3771085912u, new RpcReceiveHandler(__rpc_handler_3771085912), "EndChasingPlayer_ServerRpc"); ((NetworkBehaviour)this).__registerRpc(1947504516u, new RpcReceiveHandler(__rpc_handler_1947504516), "EndChasingPlayer_ClientRpc"); ((NetworkBehaviour)this).__registerRpc(2584131514u, new RpcReceiveHandler(__rpc_handler_2584131514), "AssignInitData_ServerRpc"); ((NetworkBehaviour)this).__registerRpc(3644677666u, new RpcReceiveHandler(__rpc_handler_3644677666), "AssignInitData_ClientRpc"); ((EnemyAI)this).__initializeRpcs(); } private static void __rpc_handler_1389605656(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((RollingGiantAI)(object)target).ResetValues_ClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_913739805(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int playerId = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref playerId); target.__rpc_exec_stage = (__RpcExecStage)1; ((RollingGiantAI)(object)target).BeginChasingPlayer_ServerRpc(playerId); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2111596117(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int playerId = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref playerId); target.__rpc_exec_stage = (__RpcExecStage)1; ((RollingGiantAI)(object)target).BeginChasingPlayer_ClientRpc(playerId); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_3771085912(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((RollingGiantAI)(object)target).EndChasingPlayer_ServerRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1947504516(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((RollingGiantAI)(object)target).EndChasingPlayer_ClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2584131514(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002f: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { float scale = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref scale, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((RollingGiantAI)(object)target).AssignInitData_ServerRpc(scale); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_3644677666(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002f: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { float scale = default(float); ((FastBufferReader)(ref reader)).ReadValueSafe(ref scale, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((RollingGiantAI)(object)target).AssignInitData_ClientRpc(scale); target.__rpc_exec_stage = (__RpcExecStage)0; } } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "RollingGiantAI"; } } public class RollingGiantDeadBody : MonoBehaviour { } public static class Utility { public static object InvokeNotOverride(this MethodInfo methodInfo, object targetObject, params object[] arguments) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 0) { if (arguments != null && arguments.Length != 0) { throw new Exception("Arguments cont doesn't match"); } } else if (parameters.Length != arguments.Length) { throw new Exception("Arguments cont doesn't match"); } Type returnType = null; if (methodInfo.ReturnType != typeof(void)) { returnType = methodInfo.ReturnType; } Type type = targetObject.GetType(); DynamicMethod dynamicMethod = new DynamicMethod("", returnType, new Type[2] { type, typeof(object) }, type); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); iLGenerator.Emit(OpCodes.Ldarg_0); for (int i = 0; i < parameters.Length; i++) { ParameterInfo parameterInfo = parameters[i]; iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Ldc_I4_S, i); iLGenerator.Emit(OpCodes.Ldelem_Ref); Type parameterType = parameterInfo.ParameterType; if (parameterType.IsPrimitive) { iLGenerator.Emit(OpCodes.Unbox_Any, parameterType); } else if (!(parameterType == typeof(object))) { iLGenerator.Emit(OpCodes.Castclass, parameterType); } } iLGenerator.Emit(OpCodes.Call, methodInfo); iLGenerator.Emit(OpCodes.Ret); return dynamicMethod.Invoke(null, new object[2] { targetObject, arguments }); } } } namespace RollingGiant.Settings { public struct SharedAiSettings : INetworkSerializable { public float moveSpeed; public float moveAcceleration; public float moveDeceleration; public bool rotateToLookAtPlayer; public float delayBeforeLookingAtPlayer; public float lookAtPlayerDuration; public float waitTimeMin; public float waitTimeMax; public float randomMoveTimeMin; public float randomMoveTimeMax; public float lookTimeBeforeAgro; public unsafe void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0056: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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) ((BufferSerializer*)(&serializer))->SerializeValue(ref moveSpeed, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref moveAcceleration, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref moveDeceleration, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref rotateToLookAtPlayer, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref delayBeforeLookingAtPlayer, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref lookAtPlayerDuration, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref waitTimeMin, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref waitTimeMax, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref randomMoveTimeMin, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref randomMoveTimeMax, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref lookTimeBeforeAgro, default(ForPrimitives)); } public override string ToString() { return $"moveSpeed: {moveSpeed}, moveAcceleration: {moveAcceleration}, moveDeceleration: {moveDeceleration}, rotateToLookAtPlayer: {rotateToLookAtPlayer}, delayBeforeLookingAtPlayer: {delayBeforeLookingAtPlayer}, lookAtPlayerDuration: {lookAtPlayerDuration}, waitTimeMin: {waitTimeMin}, waitTimeMax: {waitTimeMax}, randomMoveTimeMin: {randomMoveTimeMin}, randomMoveTimeMax: {randomMoveTimeMax}, lookTimeBeforeAgro: {lookTimeBeforeAgro}"; } } [Serializable] public class CustomConfig : SyncedInstance { public const string ROLLINGGIANT_ONREQUESTCONFIGSYNC = "RollingGiant_OnRequestConfigSync"; public const string ROLLINGGIANT_ONRECEIVECONFIGSYNC = "RollingGiant_OnReceiveConfigSync"; private static ConfigFile _config; public const string Name1 = "1. General Settings"; public const string Name2 = "2. AI Settings"; public const string AiTypeDescription = "The AI type of the Rolling Giant.\n(Putting multiple will randomly choose between them each time you land on a moon)"; public const string AiTypeChangeOnHourIntervalDescription = "If the AI type should change every X hours. This will affect already spawned Rolling Giants!\nIf set to 0 it will not change.\nWill pick from the values set in AiType."; public const string MoveSpeedDescription = "The speed of the Rolling Giant in m/s²."; public const string MoveAccelerationDescription = "How long it takes the Rolling Giant to get to its movement speed. in seconds"; public const string MoveDecelerationDescription = "How long it takes the Rolling Giant to stop moving in seconds."; public const string RotateToLookAtPlayerDescription = "If the Rolling Giant should rotate to look at the player."; public const string DelayBeforeLookingAtPlayerDescription = "The delay before the Rolling Giant looks at the player in seconds."; public const string LookAtPlayerDurationDescription = "The duration the Rolling Giant looks at the player in seconds."; public static SharedAiSettings SharedAiSettings { get; private set; } public static ConfigEntry GotoPreviousAiTypeKey { get; private set; } public static ConfigEntry GotoNextAiTypeKey { get; private set; } public static ConfigEntry ReloadConfigKey { get; private set; } public static ConfigEntry SpawnInEntry { get; private set; } public static ConfigEntry SpawnInOutsideChanceEntry { get; private set; } public static ConfigEntry SpawnInAnyEntry { get; private set; } public static ConfigEntry SpawnInAnyChanceEntry { get; private set; } public static ConfigEntry SpawnInAnyOutsideChanceEntry { get; private set; } public static ConfigEntry CanSpawnInsideEntry { get; private set; } public static ConfigEntry CanSpawnOutsideEntry { get; private set; } public static ConfigEntry DisableOutsideAtNightEntry { get; private set; } public static ConfigEntry MaxPerLevelEntry { get; private set; } public static ConfigEntry SpawnPosterInEntry { get; private set; } public float GiantScaleInsideMin { get; private set; } public float GiantScaleInsideMax { get; private set; } public float GiantScaleOutsideMin { get; private set; } public float GiantScaleOutsideMax { get; private set; } public static string SpawnIn { get; private set; } public static int SpawnInOutsideChance { get; private set; } public static bool SpawnInAny { get; private set; } public static int SpawnInAnyChance { get; private set; } public static int SpawnInAnyOutsideChance { get; private set; } public static bool CanSpawnInside { get; private set; } public static bool CanSpawnOutside { get; private set; } public static bool DisableOutsideAtNight { get; private set; } public static int MaxPerLevel { get; private set; } public static string SpawnPosterIn { get; private set; } public static RollingGiantAiType AiType { get; internal set; } public static int AiTypeChangeOnHourInterval { get; private set; } public float MoveSpeed { get; private set; } public float MoveAcceleration { get; private set; } public float MoveDeceleration { get; private set; } public bool RotateToLookAtPlayer { get; private set; } public float DelayBeforeLookingAtPlayer { get; private set; } public float LookAtPlayerDuration { get; private set; } public float RandomlyMoveWhenLooking_WaitTimeMin { get; private set; } public float RandomlyMoveWhenLooking_WaitTimeMax { get; private set; } public float RandomlyMoveWhenLooking_RandomMoveTimeMin { get; private set; } public float RandomlyMoveWhenLooking_RandomMoveTimeMax { get; private set; } public float LookingTooLongKeepsAgro_LookTimeBeforeAgro { get; private set; } public float OnceSeenAgroAfterTimer_WaitTimeMin { get; private set; } public float OnceSeenAgroAfterTimer_WaitTimeMax { get; private set; } public static ConfigEntry GiantScaleInsideMinEntry { get; private set; } public static ConfigEntry GiantScaleInsideMaxEntry { get; private set; } public static ConfigEntry GiantScaleOutsideMinEntry { get; private set; } public static ConfigEntry GiantScaleOutsideMaxEntry { get; private set; } public static ConfigEntry AiTypeEntry { get; private set; } public static ConfigEntry MoveSpeedEntry { get; private set; } public static ConfigEntry MoveAccelerationEntry { get; private set; } public static ConfigEntry MoveDecelerationEntry { get; private set; } public static ConfigEntry RotateToLookAtPlayerEntry { get; private set; } public static ConfigEntry DelayBeforeLookingAtPlayerEntry { get; private set; } public static ConfigEntry LookAtPlayerDurationEntry { get; private set; } public static ConfigEntry RandomlyMoveWhenLooking_WaitTimeMinEntry { get; private set; } public static ConfigEntry RandomlyMoveWhenLooking_WaitTimeMaxEntry { get; private set; } public static ConfigEntry RandomlyMoveWhenLooking_RandomMoveTimeMinEntry { get; private set; } public static ConfigEntry RandomlyMoveWhenLooking_RandomMoveTimeMaxEntry { get; private set; } public static ConfigEntry LookingTooLongKeepsAgro_LookTimeBeforeAgroEntry { get; private set; } public static ConfigEntry OnceSeenAgroAfterTimer_WaitTimeMinEntry { get; private set; } public static ConfigEntry OnceSeenAgroAfterTimer_WaitTimeMaxEntry { get; private set; } public CustomConfig(ConfigFile config) { _config = config; InitInstance(this); Reload(); } public void Save() { if (_config == null) { throw new NullReferenceException("Config is null."); } _config.Save(); } public void AssignFromSaved() { GiantScaleInsideMinEntry.Value = GiantScaleInsideMin; GiantScaleInsideMaxEntry.Value = GiantScaleInsideMax; GiantScaleOutsideMinEntry.Value = GiantScaleOutsideMin; GiantScaleOutsideMaxEntry.Value = GiantScaleOutsideMax; SpawnInEntry.Value = SpawnIn; SpawnInOutsideChanceEntry.Value = SpawnInAnyOutsideChance; SpawnInAnyEntry.Value = SpawnInAny; SpawnInAnyChanceEntry.Value = SpawnInAnyChance; SpawnInAnyOutsideChanceEntry.Value = SpawnInAnyOutsideChance; CanSpawnInsideEntry.Value = CanSpawnInside; CanSpawnOutsideEntry.Value = CanSpawnOutside; DisableOutsideAtNightEntry.Value = DisableOutsideAtNight; MaxPerLevelEntry.Value = MaxPerLevel; SpawnPosterInEntry.Value = SpawnPosterIn; AiTypeEntry.Value = AiType; AiTypeChangeOnHourInterval = AiTypeChangeOnHourInterval; MoveSpeedEntry.Value = MoveSpeed; MoveAccelerationEntry.Value = MoveAcceleration; MoveDecelerationEntry.Value = MoveDeceleration; RotateToLookAtPlayerEntry.Value = RotateToLookAtPlayer; DelayBeforeLookingAtPlayerEntry.Value = DelayBeforeLookingAtPlayer; LookAtPlayerDurationEntry.Value = LookAtPlayerDuration; RandomlyMoveWhenLooking_WaitTimeMinEntry.Value = RandomlyMoveWhenLooking_WaitTimeMin; RandomlyMoveWhenLooking_WaitTimeMaxEntry.Value = RandomlyMoveWhenLooking_WaitTimeMax; RandomlyMoveWhenLooking_RandomMoveTimeMinEntry.Value = RandomlyMoveWhenLooking_RandomMoveTimeMin; RandomlyMoveWhenLooking_RandomMoveTimeMaxEntry.Value = RandomlyMoveWhenLooking_RandomMoveTimeMax; LookingTooLongKeepsAgro_LookTimeBeforeAgroEntry.Value = LookingTooLongKeepsAgro_LookTimeBeforeAgro; OnceSeenAgroAfterTimer_WaitTimeMinEntry.Value = OnceSeenAgroAfterTimer_WaitTimeMin; OnceSeenAgroAfterTimer_WaitTimeMaxEntry.Value = OnceSeenAgroAfterTimer_WaitTimeMax; } public void Reload(bool setValues = true) { GiantScaleInsideMinEntry = _config.Bind("1. General Settings", "GiantScaleInsideMin", 0.9f, "The min scale of the Rolling Giant inside.\nThis is a multiplier, so 0.5 is half as large."); GiantScaleInsideMaxEntry = _config.Bind("1. General Settings", "GiantScaleInsideMax", 1.1f, "The max scale of the Rolling Giant inside.\nThis is a multiplier, so 2 is twice as large."); GiantScaleOutsideMinEntry = _config.Bind("1. General Settings", "GiantScaleOutsideMin", 0.9f, "The min scale of the Rolling Giant outside.\nThis is a multiplier, so 0.5 is half as large."); GiantScaleOutsideMaxEntry = _config.Bind("1. General Settings", "GiantScaleOutsideMax", 1.1f, "The max scale of the Rolling Giant outside.\nThis is a multiplier, so 2 is twice as large."); SpawnInEntry = _config.Bind("1. General Settings", "SpawnIn", "Vow:45,March:45,Rend:54,Dine:65,Offense:45,Titan:65", "Where the Rolling Giant can spawn.\nSeparate each level with a comma, and put a chance (no decimals) separated by a colon.\nVanilla caps at 100, but you can go farther.\nThis chance is also a weight, not a percentage.\nHigher chance = higher chance to get picked\nThe names are what you see in the terminal\nExample: Vow:6,March:10"); SpawnInOutsideChanceEntry = _config.Bind("1. General Settings", "SpawnInOutsideChance", 45, "The chance for the Rolling Giant to spawn outside.\nIs used alongside SpawnIn.\nThis is a weight, not a percentage.\nHigher chance = higher chance to get picked"); SpawnInAnyEntry = _config.Bind("1. General Settings", "SpawnInAny", false, "If the Rolling Giant can spawn in any level."); SpawnInAnyChanceEntry = _config.Bind("1. General Settings", "SpawnInAnyChance", 45, "The chance for the Rolling Giant to spawn in any level.\nRequires SpawnInAny to be enabled!\nThis is a weight, not a percentage.\nHigher chance = higher chance to get picked"); SpawnInAnyOutsideChanceEntry = _config.Bind("1. General Settings", "SpawnInAnyOutsideChance", 45, "The chance for the Rolling Giant to spawn outside when spawning in any level.\nRequires SpawnInAny to be enabled!\nThis is a weight, not a percentage.\nHigher chance = higher chance to get picked"); CanSpawnInsideEntry = _config.Bind("1. General Settings", "CanSpawnInside", true, "If the Rolling Giant can spawn inside."); CanSpawnOutsideEntry = _config.Bind("1. General Settings", "CanSpawnOutside", false, "If the Rolling Giant can spawn outside."); DisableOutsideAtNightEntry = _config.Bind("1. General Settings", "DisableOutsideAtNight", false, "If the Rolling Giant will turn off if it is outside at night."); MaxPerLevelEntry = _config.Bind("1. General Settings", "MaxPerLevel", 3, "The maximum amount of Rolling Giants that can spawn in a level."); SpawnPosterInEntry = _config.Bind("1. General Settings", "SpawnPosterIn", "Vow:12,March:12,Rend:12,Dine:12,Offense:12,Titan:12", "Where the Rolling Giant poster scrap can spawn.\nSeparate each level with a comma, and put a chance separated by a colon.\nVanilla caps at 100, but you can go farther.\nThis chance is also a weight, not a percentage.\nHigher chance = higher chance to get picked\nThe names are what you see in the terminal\nExample: Vow:12,March:12,Rend:12,Dine:12,Offense:12,Titan:12"); if (GotoPreviousAiTypeKey == null) { GotoPreviousAiTypeKey = _config.Bind("Host", "GotoPreviousAiTypeKey", "/numpad7", "The key to go to the previous AI type. This uses Unity's New Input System's key-bind names.\nhttps://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Controls.html#control-paths"); } if (GotoNextAiTypeKey == null) { GotoNextAiTypeKey = _config.Bind("Host", "GotoNextAiTypeKey", "/numpad8", "The key to go to the next AI type. This uses Unity's New Input System's key-bind names.\nhttps://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Controls.html#control-paths"); } if (ReloadConfigKey == null) { ReloadConfigKey = _config.Bind("Host", "ReloadConfigKey", "/numpad9", "The key to reload the config. Does not update spawn conditions. This uses Unity's New Input System's key-bind names.\nhttps://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Controls.html#control-paths"); } string text = "The AI type of the Rolling Giant.\n(Putting multiple will randomly choose between them each time you land on a moon)"; foreach (object value in Enum.GetValues(typeof(RollingGiantAiType))) { string arg = GetAttributeOfType((Enum)value)?.Description ?? "No description found."; text += $"\n{value}: {arg}"; } AiTypeEntry = _config.Bind("2. AI Settings", "AiType", RollingGiantAiType.RandomlyMoveWhileLooking, text); AiTypeChangeOnHourInterval = _config.Bind("2. AI Settings", "AiTypeChangeOnHourInterval", 0, "If the AI type should change every X hours. This will affect already spawned Rolling Giants!\nIf set to 0 it will not change.\nWill pick from the values set in AiType.").Value; MoveSpeedEntry = _config.Bind("2. AI Settings", "MoveSpeed", 6f, "The speed of the Rolling Giant in m/s²."); MoveAccelerationEntry = _config.Bind("2. AI Settings", "MoveAcceleration", 2f, "How long it takes the Rolling Giant to get to its movement speed. in seconds"); MoveDecelerationEntry = _config.Bind("2. AI Settings", "MoveDeceleration", 0.5f, "How long it takes the Rolling Giant to stop moving in seconds."); RotateToLookAtPlayerEntry = _config.Bind("2. AI Settings", "RotateToLookAtPlayer", true, "If the Rolling Giant should rotate to look at the player."); DelayBeforeLookingAtPlayerEntry = _config.Bind("2. AI Settings", "DelayBeforeLookingAtPlayer", 2f, "The delay before the Rolling Giant looks at the player in seconds."); LookAtPlayerDurationEntry = _config.Bind("2. AI Settings", "LookAtPlayerDuration", 3f, "The duration the Rolling Giant looks at the player in seconds."); RandomlyMoveWhenLooking_WaitTimeMinEntry = _config.Bind("AI.RandomlyMoveWhenLooking", "WaitTimeMin", 1f, "The minimum duration in seconds that the Rolling Giant waits before moving again."); RandomlyMoveWhenLooking_WaitTimeMaxEntry = _config.Bind("AI.RandomlyMoveWhenLooking", "WaitTimeMax", 3f, "The maximum duration in seconds that the Rolling Giant waits before moving again."); RandomlyMoveWhenLooking_RandomMoveTimeMinEntry = _config.Bind("AI.RandomlyMoveWhenLooking", "RandomMoveTimeMin", 1f, "The minimum duration in seconds that the Rolling Giant moves for."); RandomlyMoveWhenLooking_RandomMoveTimeMaxEntry = _config.Bind("AI.RandomlyMoveWhenLooking", "RandomMoveTimeMax", 3f, "The maximum duration in seconds that the Rolling Giant moves for."); LookingTooLongKeepsAgro_LookTimeBeforeAgroEntry = _config.Bind("AI.LookingTooLongKeepsAgro", "LookTimeBeforeAgro", 12f, "How long the player can look at the Rolling Giant before it starts chasing in seconds."); OnceSeenAgroAfterTimer_WaitTimeMinEntry = _config.Bind("AI.OnceSeenAgroAfterTimer", "WaitTimeMin", 15f, "The minimum duration in seconds the Rolling Giant waits before chasing the player."); OnceSeenAgroAfterTimer_WaitTimeMaxEntry = _config.Bind("AI.OnceSeenAgroAfterTimer", "WaitTimeMax", 30f, "The minimum duration in seconds the Rolling Giant waits before chasing the player."); if (setValues) { GiantScaleInsideMin = GiantScaleInsideMinEntry.Value; GiantScaleInsideMax = GiantScaleInsideMaxEntry.Value; GiantScaleOutsideMin = GiantScaleOutsideMinEntry.Value; GiantScaleOutsideMax = GiantScaleOutsideMaxEntry.Value; SpawnIn = SpawnInEntry.Value; SpawnInOutsideChance = SpawnInOutsideChanceEntry.Value; SpawnInAny = SpawnInAnyEntry.Value; SpawnInAnyChance = SpawnInAnyChanceEntry.Value; SpawnInAnyOutsideChance = SpawnInAnyOutsideChanceEntry.Value; CanSpawnInside = CanSpawnInsideEntry.Value; CanSpawnOutside = CanSpawnOutsideEntry.Value; DisableOutsideAtNight = DisableOutsideAtNightEntry.Value; MaxPerLevel = MaxPerLevelEntry.Value; SpawnPosterIn = SpawnPosterInEntry.Value; AiType = AiTypeEntry.Value; AiTypeChangeOnHourInterval = AiTypeChangeOnHourInterval; MoveSpeed = MoveSpeedEntry.Value; MoveAcceleration = MoveAccelerationEntry.Value; MoveDeceleration = MoveDecelerationEntry.Value; RotateToLookAtPlayer = RotateToLookAtPlayerEntry.Value; DelayBeforeLookingAtPlayer = DelayBeforeLookingAtPlayerEntry.Value; LookAtPlayerDuration = LookAtPlayerDurationEntry.Value; RandomlyMoveWhenLooking_WaitTimeMin = RandomlyMoveWhenLooking_WaitTimeMinEntry.Value; RandomlyMoveWhenLooking_WaitTimeMax = RandomlyMoveWhenLooking_WaitTimeMaxEntry.Value; RandomlyMoveWhenLooking_RandomMoveTimeMin = RandomlyMoveWhenLooking_RandomMoveTimeMinEntry.Value; RandomlyMoveWhenLooking_RandomMoveTimeMax = RandomlyMoveWhenLooking_RandomMoveTimeMaxEntry.Value; LookingTooLongKeepsAgro_LookTimeBeforeAgro = LookingTooLongKeepsAgro_LookTimeBeforeAgroEntry.Value; OnceSeenAgroAfterTimer_WaitTimeMin = OnceSeenAgroAfterTimer_WaitTimeMinEntry.Value; OnceSeenAgroAfterTimer_WaitTimeMax = OnceSeenAgroAfterTimer_WaitTimeMaxEntry.Value; SetCurrentAi(); } Plugin.Log.LogInfo((object)"Config reloaded."); } private static T GetAttributeOfType(Enum enumVal) where T : Attribute { Type type = enumVal.GetType(); MemberInfo[] member = type.GetMember(enumVal.ToString()); object[] customAttributes = member[0].GetCustomAttributes(typeof(T), inherit: false); return (customAttributes.Length != 0) ? ((T)customAttributes[0]) : null; } public static SharedAiSettings GetSharedAiSettings() { SharedAiSettings result = default(SharedAiSettings); result.moveSpeed = SyncedInstance.Instance.MoveSpeed; result.moveAcceleration = SyncedInstance.Instance.MoveAcceleration; result.moveDeceleration = SyncedInstance.Instance.MoveDeceleration; result.rotateToLookAtPlayer = SyncedInstance.Instance.RotateToLookAtPlayer; result.delayBeforeLookingAtPlayer = SyncedInstance.Instance.DelayBeforeLookingAtPlayer; result.lookAtPlayerDuration = SyncedInstance.Instance.LookAtPlayerDuration; return result; } public static void RequestSync() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!SyncedInstance.IsClient) { Plugin.Log.LogError((object)"Config sync error: Not a client."); return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(SyncedInstance.IntSize, (Allocator)2, -1); try { SyncedInstance.MessageManager.SendNamedMessage("RollingGiant_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3); Plugin.Log.LogInfo((object)"Config sync request sent."); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public static void OnRequestSync(ulong clientId, FastBufferReader _) { //IL_0064: 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) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if (!SyncedInstance.IsHost) { Plugin.Log.LogError((object)"Config sync error: Not a host."); return; } Plugin.Log.LogInfo((object)$"Config sync request received from client: {clientId}"); byte[] array = SyncedInstance.SerializeToBytes(SyncedInstance.Instance); int num = array.Length; FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(num + SyncedInstance.IntSize, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0); SyncedInstance.MessageManager.SendNamedMessage("RollingGiant_OnReceiveConfigSync", clientId, val, (NetworkDelivery)4); Plugin.Log.LogInfo((object)$"Config sync sent to client: {clientId}"); } catch (Exception arg) { Plugin.Log.LogError((object)$"Error occurred syncing config with client: {clientId}\n{arg}"); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public static void OnReceiveSync(ulong _, FastBufferReader reader) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!((FastBufferReader)(ref reader)).TryBeginRead(SyncedInstance.IntSize)) { Plugin.Log.LogError((object)"Config sync error: Could not begin reading buffer."); return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe(ref num, default(ForPrimitives)); if (!((FastBufferReader)(ref reader)).TryBeginRead(num)) { Plugin.Log.LogError((object)"Config sync error: Host could not sync."); return; } byte[] data = new byte[num]; ((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0); SyncedInstance.SyncInstance(data); SetCurrentAi(); Plugin.Log.LogInfo((object)"Successfully synced config with host."); } public static void SetCurrentAi() { if (!Object.op_Implicit((Object)(object)NetworkHandler.Instance)) { return; } RollingGiantAiType aiType = NetworkHandler.AiType; if (1 == 0) { } SharedAiSettings sharedAiSettings; switch (aiType) { case RollingGiantAiType.Coilhead: sharedAiSettings = GetSharedAiSettings(); break; case RollingGiantAiType.InverseCoilhead: sharedAiSettings = GetSharedAiSettings(); break; case RollingGiantAiType.RandomlyMoveWhileLooking: { SharedAiSettings sharedAiSettings2 = GetSharedAiSettings(); sharedAiSettings2.waitTimeMin = SyncedInstance.Instance.RandomlyMoveWhenLooking_WaitTimeMin; sharedAiSettings2.waitTimeMax = SyncedInstance.Instance.RandomlyMoveWhenLooking_WaitTimeMax; sharedAiSettings2.randomMoveTimeMin = SyncedInstance.Instance.RandomlyMoveWhenLooking_RandomMoveTimeMin; sharedAiSettings2.randomMoveTimeMax = SyncedInstance.Instance.RandomlyMoveWhenLooking_RandomMoveTimeMax; sharedAiSettings = sharedAiSettings2; break; } case RollingGiantAiType.LookingTooLongKeepsAgro: { SharedAiSettings sharedAiSettings2 = GetSharedAiSettings(); sharedAiSettings2.lookTimeBeforeAgro = SyncedInstance.Instance.LookingTooLongKeepsAgro_LookTimeBeforeAgro; sharedAiSettings = sharedAiSettings2; break; } case RollingGiantAiType.FollowOnceAgro: sharedAiSettings = GetSharedAiSettings(); break; case RollingGiantAiType.OnceSeenAgroAfterTimer: { SharedAiSettings sharedAiSettings2 = GetSharedAiSettings(); sharedAiSettings2.waitTimeMin = SyncedInstance.Instance.OnceSeenAgroAfterTimer_WaitTimeMin; sharedAiSettings2.waitTimeMax = SyncedInstance.Instance.OnceSeenAgroAfterTimer_WaitTimeMax; sharedAiSettings = sharedAiSettings2; break; } default: sharedAiSettings = GetSharedAiSettings(); break; } if (1 == 0) { } SharedAiSettings = sharedAiSettings; Plugin.Log.LogInfo((object)$"[{aiType}]: {SharedAiSettings}"); if ((!NetworkManager.Singleton.IsHost && !NetworkManager.Singleton.IsServer) || !Object.op_Implicit((Object)(object)RoundManager.Instance)) { return; } List spawnedEnemies = RoundManager.Instance.SpawnedEnemies; if (spawnedEnemies == null) { return; } Plugin.Log.LogInfo((object)"Resetting all rolling giants!"); foreach (EnemyAI item in spawnedEnemies) { if (item is RollingGiantAI rollingGiantAI) { rollingGiantAI.ResetValues(); } } } } public class GeneralSettings { public const string Name = "1. General Settings"; public ConfigEntry ChanceForGiant; public ConfigEntry GiantScaleMin; public ConfigEntry GiantScaleMax; public ConfigEntry SpawnInAllLevels; public ConfigEntry SpawnInLevelsWithCoilHead; public ConfigEntry SpawnInside; public ConfigEntry SpawnDaytime; public ConfigEntry SpawnOutside; public ConfigEntry Version; public ConfigEntry GotoPreviousAiTypeKey; public ConfigEntry GotoNextAiTypeKey; public GeneralSettings(ConfigFile configFile) { ChanceForGiant = configFile.Bind("1. General Settings", "ChanceForGiant", 0.4f, "0.0-1.0: Chance for a Rolling Giant to spawn. Higher means more chances for a Rolling Giant."); GiantScaleMin = configFile.Bind("1. General Settings", "GiantScaleMin", 1f, "The minimum scale of the Rolling Giant."); GiantScaleMax = configFile.Bind("1. General Settings", "GiantScaleMax", 1f, "The maximum scale of the Rolling Giant."); SpawnInAllLevels = configFile.Bind("1. General Settings", "SpawnInAllLevels", false, "If the Rolling Giant should spawn in all levels."); SpawnInLevelsWithCoilHead = configFile.Bind("1. General Settings", "SpawnInLevelsWithCoilHead", true, "If the Rolling Giant should spawn in levels with a Coilhead."); SpawnInside = configFile.Bind("1. General Settings", "SpawnInside", true, "If the Rolling Giant should spawn inside."); SpawnDaytime = configFile.Bind("1. General Settings", "SpawnDaytime", false, "If the Rolling Giant should spawn during the day."); SpawnOutside = configFile.Bind("1. General Settings", "SpawnOutside", false, "If the Rolling Giant should spawn outside."); Version = configFile.Bind("z_Ignore", "__version", 0, "The version of this config file. Do not change this."); GotoPreviousAiTypeKey = configFile.Bind("Dev", "GotoPreviousAiTypeKey", "/numpad7", "The key to go to the previous AI type. This uses Unity's New Input System's key-bind names."); GotoNextAiTypeKey = configFile.Bind("Dev", "GotoNextAiTypeKey", "/numpad9", "The key to go to the next AI type. This uses Unity's New Input System's key-bind names."); } public float GetRandomScale(Random rng) { float num = (float)rng.NextDouble(); float value = GiantScaleMin.Value; float value2 = GiantScaleMax.Value; return Mathf.Lerp(value, value2, num); } } [Serializable] public class SyncedInstance { [NonSerialized] protected static int IntSize = 4; internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager; internal static bool IsClient => NetworkManager.Singleton.IsClient; internal static bool IsHost => NetworkManager.Singleton.IsHost; public static T Default { get; private set; } public static T Instance { get; private set; } public static bool Synced { get; internal set; } protected void InitInstance(T instance) { Default = instance; Instance = instance; IntSize = 4; } internal static void SyncInstance(byte[] data) { Instance = DeserializeFromBytes(data); Synced = true; } internal static void RevertSync() { Instance = Default; Synced = false; } public static byte[] SerializeToBytes(T val) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream memoryStream = new MemoryStream(); try { binaryFormatter.Serialize(memoryStream, val); return memoryStream.ToArray(); } catch (Exception arg) { Plugin.Log.LogError((object)$"Error serializing instance: {arg}"); return null; } } public static T DeserializeFromBytes(byte[] data) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream serializationStream = new MemoryStream(data); try { return (T)binaryFormatter.Deserialize(serializationStream); } catch (Exception arg) { Plugin.Log.LogError((object)$"Error deserializing instance: {arg}"); return default(T); } } } } namespace RollingGiant.Patches { [HarmonyPatch] public static class EnemyPatches { [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPostfix] private static void RegisterEnemy(StartOfRound __instance) { if (!__instance.allItemsList.itemsList.Contains(Plugin.PosterItem)) { __instance.allItemsList.itemsList.Add(Plugin.PosterItem); } } [HarmonyPatch(typeof(RoundManager), "Start")] [HarmonyPriority(0)] [HarmonyPostfix] private static void RegisterEnemy2(RoundManager __instance) { SelectableLevel[] levels = __instance.playersManager.levels; HandleSpawnScrap(levels); if (CustomConfig.SpawnInAny) { HandleSpawnInAny(levels); } else { HandleSpawnInSelection(levels); } } private static void HandleSpawnInSelection(SelectableLevel[] levels) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Expected O, but got Unknown //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Expected O, but got Unknown Plugin.Log.LogMessage((object)("[HandleSpawnInSelection] Adding enemies to " + CustomConfig.SpawnIn)); (string, int)[] levelChances = GetLevelChances(CustomConfig.SpawnIn); foreach (SelectableLevel val in levels) { try { string text = val.PlanetName.ToLower().Replace(" ", string.Empty); (string, int)[] array = levelChances; for (int j = 0; j < array.Length; j++) { var (value, num) = array[j]; if (text.Contains(value)) { if (CustomConfig.CanSpawnInside && val.Enemies.All((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType != (Object)(object)Plugin.EnemyTypeInside)) { val.Enemies.Add(new SpawnableEnemyWithRarity(Plugin.EnemyTypeInside, num)); Plugin.Log.LogMessage((object)$"Added {Plugin.EnemyTypeOutside.enemyName} to {val.PlanetName} with chance of {num} (inside)"); } if (!CustomConfig.DisableOutsideAtNight && CustomConfig.CanSpawnOutside && val.OutsideEnemies.All((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType != (Object)(object)Plugin.EnemyTypeOutside)) { val.OutsideEnemies.Add(new SpawnableEnemyWithRarity(Plugin.EnemyTypeOutside, CustomConfig.SpawnInOutsideChance)); Plugin.Log.LogMessage((object)$"Added {Plugin.EnemyTypeOutside.enemyName} to {val.PlanetName} with chance of {CustomConfig.SpawnInOutsideChance} (outside)"); } if (CustomConfig.DisableOutsideAtNight && CustomConfig.CanSpawnOutside && val.DaytimeEnemies.All((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType != (Object)(object)Plugin.EnemyTypeOutsideDaytime)) { val.DaytimeEnemies.Add(new SpawnableEnemyWithRarity(Plugin.EnemyTypeOutsideDaytime, CustomConfig.SpawnInOutsideChance)); Plugin.Log.LogMessage((object)$"Added {Plugin.EnemyTypeOutsideDaytime.enemyName} to {val.PlanetName} with chance of {CustomConfig.SpawnInOutsideChance} (daytime)"); } } } } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to add enemy to {val.PlanetName}!\n{arg}"); } } } private static void HandleSpawnInAny(SelectableLevel[] levels) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Expected O, but got Unknown Plugin.Log.LogMessage((object)"[HandleSpawnInAny] Adding enemies to all levels"); int spawnInAnyChance = CustomConfig.SpawnInAnyChance; int spawnInAnyOutsideChance = CustomConfig.SpawnInAnyOutsideChance; foreach (SelectableLevel val in levels) { try { if (CustomConfig.CanSpawnInside && val.Enemies.All((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType != (Object)(object)Plugin.EnemyTypeInside)) { val.Enemies.Add(new SpawnableEnemyWithRarity(Plugin.EnemyTypeInside, spawnInAnyChance)); Plugin.Log.LogMessage((object)$"Added {Plugin.EnemyTypeOutside.enemyName} to {val.PlanetName} with chance of {spawnInAnyChance} (inside)"); } if (!CustomConfig.DisableOutsideAtNight && CustomConfig.CanSpawnOutside && val.OutsideEnemies.All((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType != (Object)(object)Plugin.EnemyTypeOutside)) { if (spawnInAnyOutsideChance != 0) { val.OutsideEnemies.Add(new SpawnableEnemyWithRarity(Plugin.EnemyTypeOutside, spawnInAnyOutsideChance)); Plugin.Log.LogMessage((object)$"Added {Plugin.EnemyTypeOutside.enemyName} to {val.PlanetName} with chance of {spawnInAnyOutsideChance} (outside)"); } else { Plugin.Log.LogMessage((object)("Skipped adding " + Plugin.EnemyTypeOutside.enemyName + " to " + val.PlanetName + " since the chance was 0 (outside)")); } } if (CustomConfig.DisableOutsideAtNight && CustomConfig.CanSpawnOutside && val.DaytimeEnemies.All((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType != (Object)(object)Plugin.EnemyTypeOutsideDaytime)) { if (spawnInAnyOutsideChance != 0) { val.DaytimeEnemies.Add(new SpawnableEnemyWithRarity(Plugin.EnemyTypeOutsideDaytime, spawnInAnyOutsideChance)); Plugin.Log.LogMessage((object)$"Added {Plugin.EnemyTypeOutsideDaytime.enemyName} to {val.PlanetName} with chance of {spawnInAnyOutsideChance} (daytime)"); continue; } Plugin.Log.LogMessage((object)("Skipped adding " + Plugin.EnemyTypeOutsideDaytime.enemyName + " to " + val.PlanetName + " since the chance was 0 (outside)")); } } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to add enemy to {val.PlanetName}!\n{arg}"); } } } private static void HandleSpawnScrap(SelectableLevel[] levels) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown Plugin.Log.LogMessage((object)("[HandleSpawnScrap] Adding scrap to " + CustomConfig.SpawnPosterIn)); (string, int)[] levelChances = GetLevelChances(CustomConfig.SpawnPosterIn); foreach (SelectableLevel val in levels) { try { string levelName = val.PlanetName.ToLower().Replace(" ", string.Empty); if (!val.spawnableScrap.Any((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)Plugin.PosterItem)) { (string, int) tuple = levelChances.FirstOrDefault(((string, int) x) => levelName.Contains(x.Item1)); if (!string.IsNullOrEmpty(tuple.Item1)) { val.spawnableScrap.Add(new SpawnableItemWithRarity(Plugin.PosterItem, tuple.Item2)); Plugin.Log.LogMessage((object)$"Added {Plugin.PosterItem.itemName} to {val.PlanetName} with chance of {tuple.Item2}"); } } } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to add enemy to {val.PlanetName}!\n{arg}"); } } } private static (string, int)[] GetLevelChances(string str) { if (string.IsNullOrEmpty(str)) { return new(string, int)[0]; } return str.Replace(" ", string.Empty).Split(",").Select(delegate(string x) { if (!x.Contains(":")) { return (x.ToLower().Replace(" ", string.Empty), 0); } string[] array = x.Split(":"); if (!int.TryParse(array[1], out var result)) { result = 0; } return (array[0].ToLower().Replace(" ", string.Empty), result); }) .ToArray(); } [HarmonyPatch(typeof(QuickMenuManager), "Debug_SetEnemyDropdownOptions")] [HarmonyPrefix] private static void AddGiantToDebugList(QuickMenuManager __instance) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown SelectableLevel testAllEnemiesLevel = __instance.testAllEnemiesLevel; SpawnableEnemyWithRarity val = testAllEnemiesLevel.Enemies.FirstOrDefault(); if (val == null) { Plugin.Log.LogError((object)"Failed to get first enemy for debug list!"); return; } List enemies = testAllEnemiesLevel.Enemies; List outsideEnemies = testAllEnemiesLevel.OutsideEnemies; List daytimeEnemies = testAllEnemiesLevel.DaytimeEnemies; if (enemies.All((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType != (Object)(object)Plugin.EnemyTypeInside)) { enemies.Add(new SpawnableEnemyWithRarity(Plugin.EnemyTypeInside, val.rarity)); Plugin.Log.LogMessage((object)("Added " + Plugin.EnemyTypeInside.enemyName + " to debug list")); } if (outsideEnemies.All((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType != (Object)(object)Plugin.EnemyTypeOutside)) { outsideEnemies.Add(new SpawnableEnemyWithRarity(Plugin.EnemyTypeOutside, val.rarity)); Plugin.Log.LogMessage((object)("Added " + Plugin.EnemyTypeOutside.enemyName + " to debug list")); } if (daytimeEnemies.All((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType != (Object)(object)Plugin.EnemyTypeOutsideDaytime)) { daytimeEnemies.Add(new SpawnableEnemyWithRarity(Plugin.EnemyTypeOutsideDaytime, val.rarity)); Plugin.Log.LogMessage((object)("Added " + Plugin.EnemyTypeOutsideDaytime.enemyName + " to debug list")); } } } public static class MapPatches { } [HarmonyPatch] public static class NetworkPatches { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnRequestSync; public static HandleNamedMessageDelegate <1>__OnReceiveSync; } private static readonly List _prefabs = new List(); private static GameObject _networkPrefab; public static void RegisterPrefab(GameObject prefab) { _prefabs.Add(prefab); } [HarmonyPatch(typeof(GameNetworkManager), "Start")] [HarmonyPostfix] private static void RegisterPrefabs() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown foreach (GameObject prefab in _prefabs) { NetworkManager.Singleton.AddNetworkPrefab(prefab); } GameObject val = (GameObject)Plugin.Bundle.LoadAsset("Assets/RollingGiant/NetworkObjectRoot.prefab"); val.AddComponent(); _networkPrefab = val; NetworkManager.Singleton.AddNetworkPrefab(val); } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "Awake")] private static void SpawnNetworkHandler() { //IL_0024: 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) if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) { GameObject val = Object.Instantiate(_networkPrefab, Vector3.zero, Quaternion.identity); val.GetComponent().Spawn(false); } } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] public static void InitializeLocalPlayer() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //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_0031: Expected O, but got Unknown if (SyncedInstance.IsHost) { try { CustomMessagingManager messageManager = SyncedInstance.MessageManager; object obj = <>O.<0>__OnRequestSync; if (obj == null) { HandleNamedMessageDelegate val = CustomConfig.OnRequestSync; <>O.<0>__OnRequestSync = val; obj = (object)val; } messageManager.RegisterNamedMessageHandler("RollingGiant_OnRequestConfigSync", (HandleNamedMessageDelegate)obj); SyncedInstance.Synced = true; return; } catch (Exception ex) { Plugin.Log.LogError((object)ex); return; } } SyncedInstance.Synced = false; CustomMessagingManager messageManager2 = SyncedInstance.MessageManager; object obj2 = <>O.<1>__OnReceiveSync; if (obj2 == null) { HandleNamedMessageDelegate val2 = CustomConfig.OnReceiveSync; <>O.<1>__OnReceiveSync = val2; obj2 = (object)val2; } messageManager2.RegisterNamedMessageHandler("RollingGiant_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2); CustomConfig.RequestSync(); } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")] public static void PlayerLeave() { SyncedInstance.RevertSync(); CustomConfig.SetCurrentAi(); Plugin.Log.LogMessage((object)"Reverting sync"); } } [HarmonyPatch] public class StartOfRoundPatches { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnTimeSync; } private static int _lastHour; private static bool InLevel => Object.op_Implicit((Object)(object)StartOfRound.Instance) && !StartOfRound.Instance.inShipPhase && StartOfRound.Instance.currentLevelID != 3; [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPostfix] private static void AddCustomRagdoll(StartOfRound __instance) { List playerRagdolls = __instance.playerRagdolls; GameObject playerRagdoll = Plugin.PlayerRagdoll; if (Object.op_Implicit((Object)(object)playerRagdoll) && !playerRagdolls.Contains(playerRagdoll)) { playerRagdolls.Add(playerRagdoll); } RandomizeAiType(); } [HarmonyPatch(typeof(StartOfRound), "StartGame")] [HarmonyPostfix] private static void RandomizeAiType() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown if (!NetworkManager.Singleton.IsHost && !NetworkManager.Singleton.IsServer) { return; } RollingGiantAiType random = CustomConfig.AiType.GetRandom(0); NetworkHandler.Instance.SetAiType(random); if (!Object.op_Implicit((Object)(object)TimeOfDay.Instance)) { return; } UnityEvent onTimeSync = TimeOfDay.Instance.onTimeSync; object obj = <>O.<0>__OnTimeSync; if (obj == null) { UnityAction val = OnTimeSync; <>O.<0>__OnTimeSync = val; obj = (object)val; } onTimeSync.RemoveListener((UnityAction)obj); _lastHour = 0; if (CustomConfig.AiTypeChangeOnHourInterval > 0 && CustomConfig.AiType.AiTypesCount() > 1) { Plugin.Log.LogInfo((object)$"Setting up time sync for ai type change every {CustomConfig.AiTypeChangeOnHourInterval} hours"); UnityEvent onTimeSync2 = TimeOfDay.Instance.onTimeSync; object obj2 = <>O.<0>__OnTimeSync; if (obj2 == null) { UnityAction val2 = OnTimeSync; <>O.<0>__OnTimeSync = val2; obj2 = (object)val2; } onTimeSync2.AddListener((UnityAction)obj2); } } private static void OnTimeSync() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown if (!InLevel) { _lastHour = 0; UnityEvent onTimeSync = TimeOfDay.Instance.onTimeSync; object obj = <>O.<0>__OnTimeSync; if (obj == null) { UnityAction val = OnTimeSync; <>O.<0>__OnTimeSync = val; obj = (object)val; } onTimeSync.RemoveListener((UnityAction)obj); } else { if (!NetworkManager.Singleton.IsHost && !NetworkManager.Singleton.IsServer) { return; } int aiTypeChangeOnHourInterval = CustomConfig.AiTypeChangeOnHourInterval; if (aiTypeChangeOnHourInterval != 0) { int hour = TimeOfDay.Instance.hour; int num = hour - _lastHour; if (num >= aiTypeChangeOnHourInterval) { _lastHour = hour; RollingGiantAiType random = CustomConfig.AiType.GetRandom(hour); NetworkHandler.Instance.SetAiType(random); Plugin.Log.LogInfo((object)$"Changed ai type to {random} at hour {hour}"); Plugin.Log.LogInfo((object)$"Next ai type change at hour {hour + aiTypeChangeOnHourInterval}"); } } } } [HarmonyPatch(typeof(DeadBodyInfo), "Start")] [HarmonyPostfix] private static void SetCustomRagdoll(DeadBodyInfo __instance) { RollingGiantDeadBody rollingGiantDeadBody = default(RollingGiantDeadBody); if (((Component)__instance).TryGetComponent(ref rollingGiantDeadBody)) { GameObject playerRagdoll = Plugin.PlayerRagdoll; Material sharedMaterial = ((Renderer)playerRagdoll.GetComponent()).sharedMaterial; ((Renderer)((Component)__instance).GetComponent()).sharedMaterial = sharedMaterial; } } [HarmonyPatch(typeof(GameNetworkManager), "Start")] [HarmonyPostfix] private static void FixAudioSources() { AudioSource val = (from p in ((Component)GameNetworkManager.Instance).GetComponent().NetworkConfig.Prefabs.Prefabs select p.Prefab.GetComponentInChildren() into p where (Object)(object)p != (Object)null select ((Component)p).GetComponentInChildren() into p where (Object)(object)p != (Object)null select p).FirstOrDefault(); if (!Object.op_Implicit((Object)(object)val)) { Plugin.Log.LogError((object)"Failed to find reference audio source"); return; } AudioMixerGroup mixerGroup = val.outputAudioMixerGroup; fix(Plugin.EnemyTypeInside.enemyPrefab); fix(Plugin.PlayerRagdoll); fix(Plugin.PosterItem.spawnPrefab); void fix(GameObject target) { AudioSource[] componentsInChildren = target.GetComponentsInChildren(); foreach (AudioSource val2 in componentsInChildren) { val2.outputAudioMixerGroup = mixerGroup; } } } } [HarmonyPatch] public static class TerminalPatches { [HarmonyPatch(typeof(Terminal), "Start")] [HarmonyPrefix] private static void RegisterTerminal(Terminal __instance) { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown TerminalNode terminalNode = Plugin.EnemyTerminalNode; if (!__instance.enemyFiles.Any((TerminalNode x) => (Object)(object)x == (Object)(object)terminalNode || x.creatureName == terminalNode.creatureName)) { TerminalKeyword val = __instance.terminalNodes.allKeywords.First((TerminalKeyword x) => x.word == "info"); TerminalKeyword keyword = Plugin.EnemyTerminalKeyword; keyword.defaultVerb = val; List list = __instance.terminalNodes.allKeywords.ToList(); if (list.All((TerminalKeyword x) => x.word != keyword.word)) { list.Add(keyword); __instance.terminalNodes.allKeywords = list.ToArray(); } List list2 = val.compatibleNouns.ToList(); if (list2.All((CompatibleNoun x) => x.noun.word != keyword.word)) { list2.Add(new CompatibleNoun(keyword, terminalNode)); } val.compatibleNouns = list2.ToArray(); int count = __instance.enemyFiles.Count; terminalNode.creatureFileID = count; Plugin.EnemyTypeInside.enemyPrefab.GetComponentInChildren().creatureScanID = count; Plugin.EnemyTypeOutside.enemyPrefab.GetComponentInChildren().creatureScanID = count; Plugin.EnemyTypeOutsideDaytime.enemyPrefab.GetComponentInChildren().creatureScanID = count; __instance.enemyFiles.Add(terminalNode); } } [HarmonyPatch(typeof(Terminal), "Start")] [HarmonyPostfix] private static void ValidateIds(Terminal __instance) { List enemyFiles = __instance.enemyFiles; List scannedEnemyIDs = __instance.scannedEnemyIDs; for (int i = 0; i < scannedEnemyIDs.Count; i++) { int num = scannedEnemyIDs[i]; if (num < 0 || num >= enemyFiles.Count || !Object.op_Implicit((Object)(object)enemyFiles[num])) { scannedEnemyIDs.RemoveAt(i--); } } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace __GEN { internal class NetworkVariableSerializationHelper { [RuntimeInitializeOnLoadMethod] internal static void InitializeSerialization() { NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy(); NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedValueEquals(); NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy(); NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable(); } } } namespace RollingGiant.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }