Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RollingGiant v2.6.0
BepInEx/plugins/RollingGiant/RollingGiant.dll
Decompiled 2 years 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