Decompiled source of RollingGiant v2.6.0
BepInEx/plugins/RollingGiant/RollingGiant.dll
Decompiled 8 months ago
The result has been truncated due to the large size, download it to view full contents!
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.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.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RollingGiant")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+9c97ebf1cb02f050d1774ba039eca4d54fbcb93b")] [assembly: AssemblyProduct("RollingGiant")] [assembly: AssemblyTitle("RollingGiant")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] internal class <Module> { static <Module>() { NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<RollingGiantAiType>(); NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedValueEquals<RollingGiantAiType>(); NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<float>(); NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<float>(); } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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<RollingGiantAiType> _aiTypes = Enum.GetValues(typeof(RollingGiantAiType)).Cast<RollingGiantAiType>().Take(Enum.GetValues(typeof(RollingGiantAiType)).Length - 1) .ToList(); private NetworkVariable<RollingGiantAiType> _aiType = new NetworkVariable<RollingGiantAiType>(RollingGiantAiType.RandomlyMoveWhileLooking, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private static InputAction _gotoPreviousAiType; private static InputAction _gotoNextAiType; private static InputAction _reloadConfig; public static NetworkHandler Instance { get; private set; } public static RollingGiantAiType AiType => Instance._aiType.Value; public override void OnNetworkSpawn() { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) { if (Object.op_Implicit((Object)(object)Instance)) { ((Component)Instance).gameObject.GetComponent<NetworkObject>().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(); ((NetworkBehaviour)this).OnNetworkSpawn(); } public void SetAiType(RollingGiantAiType aiType) { if (((NetworkBehaviour)this).IsServer || ((NetworkBehaviour)this).IsHost) { SetNewAiType(aiType, showTip: false); } } private void Update() { 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<CustomConfig>.Instance.Reload(); _aiType.Value = CustomConfig.AiType.GetFirst(); SetNewAiType(_aiType.Value); HUDManager.Instance.DisplayTip("Config reloaded", $"Ai defaulted to {_aiType.Value}", 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (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 == 2 && (networkManager.IsClient || networkManager.IsHost)) { CustomConfig.RequestSync(); } } } 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(); } [RuntimeInitializeOnLoadMethod] internal static void InitializeRPCS_NetworkHandler() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown NetworkManager.__rpc_func_table.Add(4257552972u, new RpcReceiveHandler(__rpc_handler_4257552972)); } 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)2; ((NetworkHandler)(object)target).EmitSharedServerSettingsClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "NetworkHandler"; } } [BepInPlugin("nomnomab.rollinggiant", "Rolling Giant", "2.6.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "nomnomab.rollinggiant"; public const string PluginName = "Rolling Giant"; public const string PluginVersion = "2.6.0"; 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 RollingGiant is loaded!"); } private void LoadNetWeaver() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); foreach (Type type in types) { try { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).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<int>("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<int>("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_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: 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_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) try { Bundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(PluginDirectory) ?? throw new Exception("Failed to get directory name!"), "rollinggiant")); EnemyTypeInside = Bundle.LoadAsset<EnemyType>("Assets/RollingGiant/Data/RollingGiant_EnemyType.asset"); EnemyTypeOutside = Bundle.LoadAsset<EnemyType>("Assets/RollingGiant/Data/RollingGiant_EnemyType_Outside.asset"); EnemyTypeOutsideDaytime = Bundle.LoadAsset<EnemyType>("Assets/RollingGiant/Data/RollingGiant_EnemyType_Outside_Daytime.asset"); EnemyTypeInside.MaxCount = CustomConfig.MaxPerLevel; EnemyTypeOutside.MaxCount = CustomConfig.MaxPerLevel; EnemyTypeOutsideDaytime.MaxCount = CustomConfig.MaxPerLevel; NetworkPatches.RegisterPrefab(EnemyTypeInside.enemyPrefab); NetworkPatches.RegisterPrefab(EnemyTypeOutside.enemyPrefab); NetworkPatches.RegisterPrefab(EnemyTypeOutsideDaytime.enemyPrefab); EnemyTerminalNode = Bundle.LoadAsset<TerminalNode>("Assets/RollingGiant/Data/RollingGiant_TerminalNode.asset"); EnemyTerminalKeyword = Bundle.LoadAsset<TerminalKeyword>("Assets/RollingGiant/Data/RollingGiant_TerminalKeyword.asset"); } catch (Exception arg) { Log.LogError((object)$"Failed to load asset bundle! {arg}"); } try { WalkSound = Bundle.LoadAsset<AudioClip>("Assets/RollingGiant/Audio/MovingLoop.wav"); StopSounds = (AudioClip[])(object)new AudioClip[5]; for (int i = 0; i < 5; i++) { StopSounds[i] = Bundle.LoadAsset<AudioClip>($"Assets/RollingGiant/Audio/Stopped{i + 1}.wav"); } PlayerRagdoll = Bundle.LoadAsset<GameObject>("Assets/RollingGiant/PlayerRagdollRollingGiant Variant.prefab"); PlayerRagdoll.AddComponent<RollingGiantDeadBody>(); PosterItem = Bundle.LoadAsset<Item>("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<PhysicsProp>()); PosterItem.spawnPrefab.AddComponent<Poster>().Init(); NetworkPatches.RegisterPrefab(PosterItem.spawnPrefab); BlackAndWhiteMaterial = Bundle.LoadAsset<Material>("Assets/RollingGiant/Materials/RollingGiant_Gray.mat"); } catch (Exception arg2) { Log.LogError((object)$"Failed to load assets! {arg2}"); } } } [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<RollingGiantAiType>().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_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) List<RollingGiantAiType> list = default(List<RollingGiantAiType>); PooledObject<List<RollingGiantAiType>> val = CollectionPool<List<RollingGiantAiType>, RollingGiantAiType>.Get(ref list); try { RollingGiantAiType[] array = Enum.GetValues(typeof(RollingGiantAiType)).Cast<RollingGiantAiType>().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<RollingGiantAiType>().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<MeshRenderer>(); ((GrabbableObject)this).grabbableToEnemies = true; } protected override void __initializeVariables() { ((PhysicsProp)this).__initializeVariables(); } 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<float> _velocity = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private NetworkVariable<float> _waitTimer = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private NetworkVariable<float> _moveTimer = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private NetworkVariable<float> _lookTimer = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private NetworkVariable<float> _agroTimer = new NetworkVariable<float>(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) { } 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_000d: 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<NavMeshAgent>(); _rollingSFX = ((Component)((Component)this).transform.Find("RollingSFX")).GetComponent<AudioSource>(); 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; ((EnemyAI)this).SetEnemyOutside(base.isOutside); } 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (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 == 2 && (networkManager.IsClient || networkManager.IsHost)) { _isAgro = false; _wasStopped = false; _wasFeared = false; } } } public override void DaytimeEnemyLeave() { ((EnemyAI)this).DaytimeEnemyLeave(); Renderer[] componentsInChildren = ((Component)((Component)this).transform).GetComponentsInChildren<Renderer>(); foreach (Renderer val in componentsInChildren) { if (!(((Object)val).name == "object_3")) { val.sharedMaterial = Plugin.BlackAndWhiteMaterial; } } _mainCollider.isTrigger = true; } public override void DoAIInterval() { //IL_0076: 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_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015f: 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))) { 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) { 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) && Vector3.Distance(((Component)this).transform.position, ((Component)closestPlayer).transform.position) < (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)) { 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_04cb: Unknown result type (might be due to invalid IL or missing references) //IL_04d0: Unknown result type (might be due to invalid IL or missing references) //IL_04e2: 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<float> 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)) { _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) && !_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)) { ((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)) { 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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<float> 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<float> 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<float> moveTimer = _moveTimer; moveTimer.Value -= Time.deltaTime; if (_moveTimer.Value <= 0f) { GenerateWaitTime(); } } break; case RollingGiantAiType.LookingTooLongKeepsAgro: if (!_isAgro) { if (flag) { if (((NetworkBehaviour)this).IsOwner) { NetworkVariable<float> 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<float> 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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)) && !val.isPlayerDead && ((NetworkBehaviour)val).IsSpawned && val.HasLineOfSightToPosition(((Component)this).transform.position + Vector3.up * 1.6f, 68f, 60, -1f)) { 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_0014: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)player)) { return ((EnemyAI)this).CheckLineOfSightForPosition(((Component)player.gameplayCamera).transform.position, 68f, 60, -1f, (Transform)null); } return false; } private bool CheckLineOfSightToAnyPlayer() { PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (((NetworkBehaviour)val).IsSpawned && !val.isPlayerDead && CheckLineOfSightTo(val)) { return true; } } return false; } private bool IsAgentOnNavMesh(GameObject agentObject) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) 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) 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)) { 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (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 == 2 && (networkManager.IsClient || networkManager.IsHost)) { ((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) 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)) { 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (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 == 2 && (networkManager.IsClient || networkManager.IsHost)) { 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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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<float>(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)) { AssignAgentData(scale); ((Component)base.agent).transform.localScale = Vector3.one * scale; AssignInitData_ClientRpc(scale); } } } private void AssignInitData_LocalClient() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) CustomConfig instance = SyncedInstance<CustomConfig>.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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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 != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3644677666u, val, (RpcDelivery)0); ((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref scale, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3644677666u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost)) { 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(); } [RuntimeInitializeOnLoadMethod] internal static void InitializeRPCS_RollingGiantAI() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown NetworkManager.__rpc_func_table.Add(1389605656u, new RpcReceiveHandler(__rpc_handler_1389605656)); NetworkManager.__rpc_func_table.Add(913739805u, new RpcReceiveHandler(__rpc_handler_913739805)); NetworkManager.__rpc_func_table.Add(2111596117u, new RpcReceiveHandler(__rpc_handler_2111596117)); NetworkManager.__rpc_func_table.Add(3771085912u, new RpcReceiveHandler(__rpc_handler_3771085912)); NetworkManager.__rpc_func_table.Add(1947504516u, new RpcReceiveHandler(__rpc_handler_1947504516)); NetworkManager.__rpc_func_table.Add(2584131514u, new RpcReceiveHandler(__rpc_handler_2584131514)); NetworkManager.__rpc_func_table.Add(3644677666u, new RpcReceiveHandler(__rpc_handler_3644677666)); } 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)2; ((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)2; ((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)2; ((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<float>(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<float>(ref scale, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)2; ((RollingGiantAI)(object)target).AssignInitData_ClientRpc(scale); target.__rpc_exec_stage = (__RpcExecStage)0; } } 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 obj = parameters[i]; iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Ldc_I4_S, i); iLGenerator.Emit(OpCodes.Ldelem_Ref); Type parameterType = obj.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 }); } } public static class PluginInfo { public const string PLUGIN_GUID = "RollingGiant"; public const string PLUGIN_NAME = "RollingGiant"; public const string PLUGIN_VERSION = "1.0.0"; } } 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<T>(BufferSerializer<T> serializer) where T : IReaderWriter { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0026: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_0078: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) ((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref moveSpeed, default(ForPrimitives)); ((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref moveAcceleration, default(ForPrimitives)); ((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref moveDeceleration, default(ForPrimitives)); ((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref rotateToLookAtPlayer, default(ForPrimitives)); ((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref delayBeforeLookingAtPlayer, default(ForPrimitives)); ((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref lookAtPlayerDuration, default(ForPrimitives)); ((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref waitTimeMin, default(ForPrimitives)); ((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref waitTimeMax, default(ForPrimitives)); ((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref randomMoveTimeMin, default(ForPrimitives)); ((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref randomMoveTimeMax, default(ForPrimitives)); ((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(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<CustomConfig> { 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<string> GotoPreviousAiTypeKey { get; private set; } public static ConfigEntry<string> GotoNextAiTypeKey { get; private set; } public static ConfigEntry<string> ReloadConfigKey { get; private set; } public static ConfigEntry<string> SpawnInEntry { get; private set; } public static ConfigEntry<int> SpawnInOutsideChanceEntry { get; private set; } public static ConfigEntry<bool> SpawnInAnyEntry { get; private set; } public static ConfigEntry<int> SpawnInAnyChanceEntry { get; private set; } public static ConfigEntry<int> SpawnInAnyOutsideChanceEntry { get; private set; } public static ConfigEntry<bool> CanSpawnInsideEntry { get; private set; } public static ConfigEntry<bool> CanSpawnOutsideEntry { get; private set; } public static ConfigEntry<bool> DisableOutsideAtNightEntry { get; private set; } public static ConfigEntry<int> MaxPerLevelEntry { get; private set; } public static ConfigEntry<string> 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<float> GiantScaleInsideMinEntry { get; private set; } public static ConfigEntry<float> GiantScaleInsideMaxEntry { get; private set; } public static ConfigEntry<float> GiantScaleOutsideMinEntry { get; private set; } public static ConfigEntry<float> GiantScaleOutsideMaxEntry { get; private set; } public static ConfigEntry<RollingGiantAiType> AiTypeEntry { get; private set; } public static ConfigEntry<float> MoveSpeedEntry { get; private set; } public static ConfigEntry<float> MoveAccelerationEntry { get; private set; } public static ConfigEntry<float> MoveDecelerationEntry { get; private set; } public static ConfigEntry<bool> RotateToLookAtPlayerEntry { get; private set; } public static ConfigEntry<float> DelayBeforeLookingAtPlayerEntry { get; private set; } public static ConfigEntry<float> LookAtPlayerDurationEntry { get; private set; } public static ConfigEntry<float> RandomlyMoveWhenLooking_WaitTimeMinEntry { get; private set; } public static ConfigEntry<float> RandomlyMoveWhenLooking_WaitTimeMaxEntry { get; private set; } public static ConfigEntry<float> RandomlyMoveWhenLooking_RandomMoveTimeMinEntry { get; private set; } public static ConfigEntry<float> RandomlyMoveWhenLooking_RandomMoveTimeMaxEntry { get; private set; } public static ConfigEntry<float> LookingTooLongKeepsAgro_LookTimeBeforeAgroEntry { get; private set; } public static ConfigEntry<float> OnceSeenAgroAfterTimer_WaitTimeMinEntry { get; private set; } public static ConfigEntry<float> 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<float>("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<float>("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<float>("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<float>("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<string>("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<int>("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<bool>("1. General Settings", "SpawnInAny", false, "If the Rolling Giant can spawn in any level."); SpawnInAnyChanceEntry = _config.Bind<int>("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<int>("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<bool>("1. General Settings", "CanSpawnInside", true, "If the Rolling Giant can spawn inside."); CanSpawnOutsideEntry = _config.Bind<bool>("1. General Settings", "CanSpawnOutside", false, "If the Rolling Giant can spawn outside."); DisableOutsideAtNightEntry = _config.Bind<bool>("1. General Settings", "DisableOutsideAtNight", false, "If the Rolling Giant will turn off if it is outside at night."); MaxPerLevelEntry = _config.Bind<int>("1. General Settings", "MaxPerLevel", 3, "The maximum amount of Rolling Giants that can spawn in a level."); SpawnPosterInEntry = _config.Bind<string>("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<string>("Host", "GotoPreviousAiTypeKey", "<Keyboard>/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/[email protected]/manual/Controls.html#control-paths"); } if (GotoNextAiTypeKey == null) { GotoNextAiTypeKey = _config.Bind<string>("Host", "GotoNextAiTypeKey", "<Keyboard>/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/[email protected]/manual/Controls.html#control-paths"); } if (ReloadConfigKey == null) { ReloadConfigKey = _config.Bind<string>("Host", "ReloadConfigKey", "<Keyboard>/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/[email protected]/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<DescriptionAttribute>((Enum)value)?.Description ?? "No description found."; text += $"\n{value}: {arg}"; } AiTypeEntry = _config.Bind<RollingGiantAiType>("2. AI Settings", "AiType", RollingGiantAiType.RandomlyMoveWhileLooking, text); AiTypeChangeOnHourInterval = _config.Bind<int>("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<float>("2. AI Settings", "MoveSpeed", 6f, "The speed of the Rolling Giant in m/s²."); MoveAccelerationEntry = _config.Bind<float>("2. AI Settings", "MoveAcceleration", 2f, "How long it takes the Rolling Giant to get to its movement speed. in seconds"); MoveDecelerationEntry = _config.Bind<float>("2. AI Settings", "MoveDeceleration", 0.5f, "How long it takes the Rolling Giant to stop moving in seconds."); RotateToLookAtPlayerEntry = _config.Bind<bool>("2. AI Settings", "RotateToLookAtPlayer", true, "If the Rolling Giant should rotate to look at the player."); DelayBeforeLookingAtPlayerEntry = _config.Bind<float>("2. AI Settings", "DelayBeforeLookingAtPlayer", 2f, "The delay before the Rolling Giant looks at the player in seconds."); LookAtPlayerDurationEntry = _config.Bind<float>("2. AI Settings", "LookAtPlayerDuration", 3f, "The duration the Rolling Giant looks at the player in seconds."); RandomlyMoveWhenLooking_WaitTimeMinEntry = _config.Bind<float>("AI.RandomlyMoveWhenLooking", "WaitTimeMin", 1f, "The minimum duration in seconds that the Rolling Giant waits before moving again."); RandomlyMoveWhenLooking_WaitTimeMaxEntry = _config.Bind<float>("AI.RandomlyMoveWhenLooking", "WaitTimeMax", 3f, "The maximum duration in seconds that the Rolling Giant waits before moving again."); RandomlyMoveWhenLooking_RandomMoveTimeMinEntry = _config.Bind<float>("AI.RandomlyMoveWhenLooking", "RandomMoveTimeMin", 1f, "The minimum duration in seconds that the Rolling Giant moves for."); RandomlyMoveWhenLooking_RandomMoveTimeMaxEntry = _config.Bind<float>("AI.RandomlyMoveWhenLooking", "RandomMoveTimeMax", 3f, "The maximum duration in seconds that the Rolling Giant moves for."); LookingTooLongKeepsAgro_LookTimeBeforeAgroEntry = _config.Bind<float>("AI.LookingTooLongKeepsAgro", "LookTimeBeforeAgro", 12f, "How long the player can look at the Rolling Giant before it starts chasing in seconds."); OnceSeenAgroAfterTimer_WaitTimeMinEntry = _config.Bind<float>("AI.OnceSeenAgroAfterTimer", "WaitTimeMin", 15f, "The minimum duration in seconds the Rolling Giant waits before chasing the player."); OnceSeenAgroAfterTimer_WaitTimeMaxEntry = _config.Bind<float>("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<T>(Enum enumVal) where T : Attribute { object[] customAttributes = enumVal.GetType().GetMember(enumVal.ToString())[0].GetCustomAttributes(typeof(T), inherit: false); if (customAttributes.Length == 0) { return null; } return (T)customAttributes[0]; } public static SharedAiSettings GetSharedAiSettings() { SharedAiSettings result = default(SharedAiSettings); result.moveSpeed = SyncedInstance<CustomConfig>.Instance.MoveSpeed; result.moveAcceleration = SyncedInstance<CustomConfig>.Instance.MoveAcceleration; result.moveDeceleration = SyncedInstance<CustomConfig>.Instance.MoveDeceleration; result.rotateToLookAtPlayer = SyncedInstance<CustomConfig>.Instance.RotateToLookAtPlayer; result.delayBeforeLookingAtPlayer = SyncedInstance<CustomConfig>.Instance.DelayBeforeLookingAtPlayer; result.lookAtPlayerDuration = SyncedInstance<CustomConfig>.Instance.LookAtPlayerDuration; return result; } public static void RequestSync() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!SyncedInstance<CustomConfig>.IsClient) { Plugin.Log.LogError((object)"Config sync error: Not a client."); return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(SyncedInstance<CustomConfig>.IntSize, (Allocator)2, -1); try { SyncedInstance<CustomConfig>.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_0056: 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_0077: Unknown result type (might be due to invalid IL or missing references) if (!SyncedInstance<CustomConfig>.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<CustomConfig>.SerializeToBytes(SyncedInstance<CustomConfig>.Instance); int num = array.Length; FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(num + SyncedInstance<CustomConfig>.IntSize, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0); SyncedInstance<CustomConfig>.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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!((FastBufferReader)(ref reader)).TryBeginRead(SyncedInstance<CustomConfig>.IntSize)) { Plugin.Log.LogError((object)"Config sync error: Could not begin reading buffer."); return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(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<CustomConfig>.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; 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<CustomConfig>.Instance.RandomlyMoveWhenLooking_WaitTimeMin; sharedAiSettings2.waitTimeMax = SyncedInstance<CustomConfig>.Instance.RandomlyMoveWhenLooking_WaitTimeMax; sharedAiSettings2.randomMoveTimeMin = SyncedInstance<CustomConfig>.Instance.RandomlyMoveWhenLooking_RandomMoveTimeMin; sharedAiSettings2.randomMoveTimeMax = SyncedInstance<CustomConfig>.Instance.RandomlyMoveWhenLooking_RandomMoveTimeMax; sharedAiSettings = sharedAiSettings2; break; } case RollingGiantAiType.LookingTooLongKeepsAgro: { SharedAiSettings sharedAiSettings2 = GetSharedAiSettings(); sharedAiSettings2.lookTimeBeforeAgro = SyncedInstance<CustomConfig>.Instance.LookingTooLongKeepsAgro_LookTimeBeforeAgro; sharedAiSettings = sharedAiSettings2; break; } case RollingGiantAiType.FollowOnceAgro: sharedAiSettings = GetSharedAiSettings(); break; case RollingGiantAiType.OnceSeenAgroAfterTimer: { SharedAiSettings sharedAiSettings2 = GetSharedAiSettings(); sharedAiSettings2.waitTimeMin = SyncedInstance<CustomConfig>.Instance.OnceSeenAgroAfterTimer_WaitTimeMin; sharedAiSettings2.waitTimeMax = SyncedInstance<CustomConfig>.Instance.OnceSeenAgroAfterTimer_WaitTimeMax; sharedAiSettings = sharedAiSettings2; break; } default: sharedAiSettings = GetSharedAiSettings(); break; } SharedAiSettings = sharedAiSettings; Plugin.Log.LogInfo((object)$"[{aiType}]: {SharedAiSettings}"); if ((!NetworkManager.Singleton.IsHost && !NetworkManager.Singleton.IsServer) || !Object.op_Implicit((Object)(object)RoundManager.Instance)) { return; } List<EnemyAI> 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<float> ChanceForGiant; public ConfigEntry<float> GiantScaleMin; public ConfigEntry<float> GiantScaleMax; public ConfigEntry<bool> SpawnInAllLevels; public ConfigEntry<bool> SpawnInLevelsWithCoilHead; public ConfigEntry<bool> SpawnInside; public ConfigEntry<bool> SpawnDaytime; public ConfigEntry<bool> SpawnOutside; public ConfigEntry<int> Version; public ConfigEntry<string> GotoPreviousAiTypeKey; public ConfigEntry<string> GotoNextAiTypeKey; public GeneralSettings(ConfigFile configFile) { ChanceForGiant = configFile.Bind<float>("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<float>("1. General Settings", "GiantScaleMin", 1f, "The minimum scale of the Rolling Giant."); GiantScaleMax = configFile.Bind<float>("1. General Settings", "GiantScaleMax", 1f, "The maximum scale of the Rolling Giant."); SpawnInAllLevels = configFile.Bind<bool>("1. General Settings", "SpawnInAllLevels", false, "If the Rolling Giant should spawn in all levels."); SpawnInLevelsWithCoilHead = configFile.Bind<bool>("1. General Settings", "SpawnInLevelsWithCoilHead", true, "If the Rolling Giant should spawn in levels with a Coilhead."); SpawnInside = configFile.Bind<bool>("1. General Settings", "SpawnInside", true, "If the Rolling Giant should spawn inside."); SpawnDaytime = configFile.Bind<bool>("1. General Settings", "SpawnDaytime", false, "If the Rolling Giant should spawn during the day."); SpawnOutside = configFile.Bind<bool>("1. General Settings", "SpawnOutside", false, "If the Rolling Giant should spawn outside."); Version = configFile.Bind<int>("z_Ignore", "__version", 0, "The version of this config file. Do not change this."); GotoPreviousAiTypeKey = configFile.Bind<string>("Dev", "GotoPreviousAiTypeKey", "<Keyboard>/numpad7", "The key to go to the previous AI type. This uses Unity's New Input System's key-bind names."); GotoNextAiTypeKey = configFile.Bind<string>("Dev", "GotoNextAiTypeKey", "<Keyboard>/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<T> { [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 by