Decompiled source of Valquake v0.1.5
Valquake.dll
Decompiled 6 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Valquake")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Valquake")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9f8a1b6e-6d0e-4dab-bbd8-9ed433836544")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] internal sealed class ConfigurationManagerAttributes { public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput); public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public CustomHotkeyDrawerFunc CustomHotkeyDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } namespace neobotics.ValheimMods; public class AudioHelper : MonoBehaviour { private Dictionary<string, AudioClip> audioClips = new Dictionary<string, AudioClip>(); public void Awake() { Logging.GetLogger().Debug("AudioHelper.Awake"); LoadAudioResources(); ZRoutedRpc.instance.Register<Vector3, string>("NeoPlayClip", (Action<long, Vector3, string>)RPC_NeoPlayClip); } public void RPC_NeoPlayClip(long sender, Vector3 sourcePoint, string clipName) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) Logging.GetLogger().Debug("AudioHelper.RPC_NeoPlayClip"); if (ZNet.instance.IsDedicated()) { return; } try { NeoPlayClip(sourcePoint, clipName); } catch (Exception e) { Logging.GetLogger().Error(e, stackTrace: false); } } public void Play(Vector3 sourcePoint, string clipName) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) Logging.GetLogger().Debug("AudioHelper.Play"); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "NeoPlayClip", new object[2] { sourcePoint, clipName }); } public void NeoPlayClip(Vector3 sourcePoint, string clipName) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)Player.m_localPlayer).transform.position; NeoPlayClip(sourcePoint, position, clipName); } public void NeoPlayClip(Vector3 sourcePoint, Vector3 targetPoint, string clipName) { //IL_000f: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) Logging.GetLogger().Debug("AudioHelper.NeoPlayClip"); Vector3 val = sourcePoint - targetPoint; Vector3 normalized = ((Vector3)(ref val)).normalized; float num = (Vector3.Distance(sourcePoint, targetPoint) + 1f) / 10f; if (audioClips.TryGetValue(clipName.ToLower(), out var value)) { AudioSource.PlayClipAtPoint(value, targetPoint + normalized * num, 1f); } else { Logging.GetLogger().Warning("Couldn't find audio clip for " + clipName); } } public float GetClipDuration(string clipName) { if (!audioClips.TryGetValue(clipName.ToLower(), out var value)) { return -1f; } return value.length; } private void LoadAudioResources() { Logging.GetLogger().Debug("AudioHelper.LoadAudioResources"); FileInfo fileInfo = new FileInfo(Assembly.GetExecutingAssembly().Location); string[] array = new string[0]; List<string> obj = new List<string> { "*.wav", "*.mp3", "*.wma" }; string directoryName = fileInfo.DirectoryName; Logging.GetLogger().Debug("filePath " + directoryName); audioClips.Clear(); foreach (string item in obj) { array = CollectionExtensions.AddRangeToArray<string>(array, Directory.GetFiles(directoryName, item, SearchOption.TopDirectoryOnly)); } Logging.GetLogger().Info($"Found {array.Length} audio files"); ((MonoBehaviour)this).StartCoroutine(Co_LoadAudio(directoryName, array)); } private IEnumerator Co_LoadAudio(string filePath, string[] audioFiles) { WWW URL = null; for (int f = 0; f < audioFiles.Length; f++) { string clipUri = new Uri(audioFiles[f]).AbsoluteUri; string clipName = audioFiles[f].Substring(filePath.Length + 1); Logging.GetLogger().Debug("Loading audio clip " + clipName); try { URL = new WWW(clipUri); } catch (Exception ex) { Logging.GetLogger().Warning("Can't find audio resource: " + ex.Message); } yield return URL; if (URL != null) { try { AudioClip audioClip = URL.GetAudioClip(true, false); audioClips.Add(clipName.ToLower(), audioClip); } catch (Exception ex2) { Logging.GetLogger().Warning("Failed to load clip " + clipUri + ": " + ex2.Message); } } else { Logging.GetLogger().Warning("Failed to get URL for " + clipUri); } } } } public class CrossPlatformRandom : Random { private const int LCG_MULTIPLIER = 134775813; private const int LCG_INCREMENT = 1; private int _seed; public float value => (float)NextDouble(); public CrossPlatformRandom() { Random random = new Random(); _seed = random.Next(); } public CrossPlatformRandom(int seed) { _seed = seed; } public float Range(int min, int max) { return Next(min, max); } public float Range(float min, float max) { return Mathf.Lerp(min, max, (float)NextDouble()); } private int GetNext() { _seed = _seed * 134775813 + 1; return _seed; } public override int Next() { return Next(int.MaxValue); } public override int Next(int maxValue) { if (maxValue < 0) { throw new ArgumentOutOfRangeException("maxValue is less than zero."); } return (int)((long)(uint)GetNext() * (long)(uint)maxValue >>> 32); } public override int Next(int minValue, int maxValue) { if (minValue > maxValue) { throw new ArgumentOutOfRangeException("minValue is greater than maxValue."); } return minValue + Next(maxValue - minValue); } public override double NextDouble() { return Sample(); } protected override double Sample() { return (double)Next() / 2147483647.0; } } internal class DebugUtils { public static void ObjectInspector(object o) { if (o == null) { Debug.Log((object)"Object is null"); return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; Type type = o.GetType(); Debug.Log((object)(o.ToString() + " Type " + type.Name)); PropertyInfo[] properties = type.GetProperties(bindingAttr); foreach (PropertyInfo propertyInfo in properties) { Debug.Log((object)$"{type.Name}.{propertyInfo.Name} = {propertyInfo.GetValue(o)}"); } FieldInfo[] fields = type.GetFields(bindingAttr); foreach (FieldInfo field in fields) { FieldPrinter(o, type, field); } } public static void MethodInspector(object o) { if (o == null) { Debug.Log((object)"Object is null"); return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; Type type = o.GetType(); Debug.Log((object)(o.ToString() + " Type " + type.Name)); MethodInfo[] methods = type.GetMethods(bindingAttr); foreach (MethodInfo methodInfo in methods) { methodInfo.GetParameters(); string arg = string.Join(", ", (from x in methodInfo.GetParameters() select x.ParameterType?.ToString() + " " + x.Name).ToArray()); Debug.Log((object)$"{methodInfo.ReturnType} {methodInfo.Name} ({arg})"); } } private static void ItemDataInspector(ItemData item) { ObjectInspector(item); ObjectInspector(item.m_shared); } private static void FieldPrinter(object o, Type t, FieldInfo field) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown try { if (field.FieldType == typeof(ItemData)) { ItemData val = (ItemData)field.GetValue(o); if (val != null) { ItemDataInspector(val); } else { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]"); } } else if (field.FieldType == typeof(Transform)) { Transform val2 = (Transform)field.GetValue(o); if ((Object)(object)val2 != (Object)null) { Debug.Log((object)("\tTransform.parent = " + ((Object)val2.parent).name)); } else { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]"); } } else if (field.FieldType == typeof(EffectList)) { EffectList val3 = (EffectList)field.GetValue(o); if (val3 != null) { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)}:"); EffectData[] effectPrefabs = val3.m_effectPrefabs; foreach (EffectData val4 in effectPrefabs) { Debug.Log((object)("\tEffectData.m_prefab = " + ((Object)val4.m_prefab).name)); } } else { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]"); } } else { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)}"); } } catch (Exception) { Debug.Log((object)("Exception accessing " + t?.Name + "." + field?.Name)); } } public static void GameObjectInspector(GameObject go) { Debug.Log((object)("\n\nInspecting GameObject " + ((Object)go).name)); ObjectInspector(go); Component[] componentsInChildren = go.GetComponentsInChildren<Component>(); foreach (Component val in componentsInChildren) { try { string obj = ((val != null) ? ((Object)val).name : null); object obj2; if (val == null) { obj2 = null; } else { Transform transform = val.transform; if (transform == null) { obj2 = null; } else { Transform parent = transform.parent; obj2 = ((parent != null) ? ((Object)parent).name : null); } } Debug.Log((object)("\n\nInspecting Component " + obj + " with parent " + (string?)obj2)); ObjectInspector(val); } catch (Exception) { } } } public static void PrintList<T>(List<T> l) { foreach (T item in l) { Debug.Log((object)item.ToString()); } } public static void ComponentInspector(Component c) { Debug.Log((object)("\n\nInspecting Component " + ((Object)c).name)); ObjectInspector(c); } public static void EffectsInspector(EffectList e) { EffectData[] effectPrefabs = e.m_effectPrefabs; Debug.Log((object)$"Effect list has effects {e.HasEffects()} count {effectPrefabs.Length}"); EffectData[] array = effectPrefabs; foreach (EffectData val in array) { Debug.Log((object)$"Effect Data {val} prefab name {((Object)val.m_prefab).name} prefab GameObject name {((Object)val.m_prefab.gameObject).name}"); } } public static void PrintInventory() { foreach (ItemData allItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems()) { Debug.Log((object)allItem.m_shared.m_name); } } public static void PrintAllObjects() { ZNetScene.instance.m_prefabs.ForEach(delegate(GameObject x) { Debug.Log((object)("GameObject " + ((Object)x).name)); }); } public static void PrintAllCharacters() { Character.GetAllCharacters().ForEach(delegate(Character x) { Debug.Log((object)("Character " + ((Object)x).name)); }); } public static void PrintAllLayers() { string[] array = (from index in Enumerable.Range(0, 31) select LayerMask.LayerToName(index) into l where !string.IsNullOrEmpty(l) select l).ToArray(); foreach (string text in array) { Debug.Log((object)("Layer " + text + " " + Convert.ToString(LayerMask.NameToLayer(text), 2).PadLeft(32, '0'))); } } } public class DelegatedConfigEntry<T> : DelegatedConfigEntryBase { private ConfigEntry<T> _entry; private EventHandler rootHandler; private Action<object, EventArgs> clientDelegate; private Logging Log; public ConfigEntry<T> ConfigEntry { get { return _entry; } set { _entry = value; if (_entry != null && rootHandler != null) { _entry.SettingChanged += rootHandler; } Name = ((ConfigEntryBase)_entry).Definition.Key; Section = ((ConfigEntryBase)_entry).Definition.Section; ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue(); Log.Trace("Set " + Section + " " + Name + " to serialized value " + ServerValue); } } public T Value { get { return _entry.Value; } set { _entry.Value = value; } } public DelegatedConfigEntry(bool useServerDelegate = false) : this((Action<object, EventArgs>)null, useServerDelegate) { } public DelegatedConfigEntry(Action<object, EventArgs> delegateHandler, bool useServerDelegate = false) { Log = Logging.GetLogger(); Log.Trace("DelegatedConfigEntry"); if (delegateHandler != null) { clientDelegate = delegateHandler; } if (useServerDelegate) { Log.Trace("Configuring server delegate"); rootHandler = delegate(object s, EventArgs e) { ServerDelegate(s, e); }; ServerConfiguration.ServerDelegatedEntries.Add(this); } else if (clientDelegate != null) { rootHandler = delegate(object s, EventArgs e) { clientDelegate(s, e); }; } } private void ServerDelegate(object sender, EventArgs args) { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown Logging.GetLogger().Trace("ServerDelegate"); _entry.SettingChanged -= rootHandler; ZNet instance = ZNet.instance; bool? flag = ((instance != null) ? new bool?(instance.IsServer()) : null); if (flag.HasValue) { if (flag == false && ServerConfiguration.Instance.ReceivedServerValues) { if (ServerValue != null) { ((ConfigEntryBase)_entry).SetSerializedValue(ServerValue); Log.Debug("Setting " + Name + " to server value " + ServerValue); } } else if (flag == true) { ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue(); ServerConfiguration.Instance.SendConfigToAllClients(sender, (SettingChangedEventArgs)args); } } if (clientDelegate != null) { clientDelegate(sender, args); } _entry.SettingChanged += rootHandler; } public void EnableHandler(bool setActive) { if (setActive) { _entry.SettingChanged += rootHandler; } else { _entry.SettingChanged -= rootHandler; } } public bool IsKeyPressed() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (ConfigEntry is ConfigEntry<KeyboardShortcut> val) { KeyboardShortcut value = val.Value; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } if (!Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { return false; } return true; } Log.Error("Keyboard read attempted on non-KeyboardShortcut config."); return false; } public bool IsKeyDown() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (ConfigEntry is ConfigEntry<KeyboardShortcut> val) { KeyboardShortcut value = val.Value; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey)) { return false; } return true; } Log.Error("Keyboard read attempted on non-KeyboardShortcut config."); return false; } public bool IsKeyReleased() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (ConfigEntry is ConfigEntry<KeyboardShortcut> val) { KeyboardShortcut value = val.Value; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!Input.GetKeyUp(modifier)) { return false; } } if (!Input.GetKeyUp(((KeyboardShortcut)(ref value)).MainKey)) { return false; } return true; } Log.Error("Keyboard read attempted on non-KeyboardShortcut config."); return false; } } public class DelegatedConfigEntryBase { public string Name; public string Section; public string ServerValue; } internal class HarmonyHelper { public enum PatchType { Prefix, Postfix, Transpiler, Finalizer } private static Dictionary<string, string> detectionSet = new Dictionary<string, string>(); private static Dictionary<string, string> unpatchMods = new Dictionary<string, string>(); public static void GetDetectionSet(Dictionary<string, string> harmonyIds) { Logging logger = Logging.GetLogger(); foreach (KeyValuePair<string, string> harmonyId in harmonyIds) { if (Harmony.HasAnyPatches(harmonyId.Key)) { logger.Debug("Detected " + harmonyId.Value + " from Harmony"); if (!detectionSet.ContainsKey(harmonyId.Key)) { detectionSet.Add(harmonyId.Key, harmonyId.Value); } } else if (Chainloader.PluginInfos.ContainsKey(harmonyId.Key)) { logger.Debug("Detected " + harmonyId.Value + " from BepInEx"); if (!detectionSet.ContainsKey(harmonyId.Key)) { detectionSet.Add(harmonyId.Key, harmonyId.Value); } } } } public static void AddExclusion(string key) { if (detectionSet.ContainsKey(key)) { unpatchMods.Add(key, detectionSet[key]); } } public static void UnpatchMods(Harmony harmony) { Logging logger = Logging.GetLogger(); foreach (KeyValuePair<string, string> unpatchMod in unpatchMods) { logger.Warning("Not compatible with " + unpatchMod.Value); harmony.UnpatchAll(unpatchMod.Key); detectionSet.Remove(unpatchMod.Key); logger.Warning("Disabled " + unpatchMod.Value); } } public static bool IsModDetected(string key) { return detectionSet.ContainsKey(key); } public static bool IsModNameDetected(string value) { return detectionSet.ContainsValue(value); } public static bool TryGetDetectedModName(string key, out string mod) { return detectionSet.TryGetValue(key, out mod); } public static bool TryGetDetectedModKey(string value, out string key) { key = null; foreach (string key2 in detectionSet.Keys) { if (detectionSet[key2] == value) { key = key2; return true; } } return false; } public static string AddAnonymousPatch(string baseMethodName, PatchType patchType, string modName, string patchMethodName = null) { string text = null; int num = 0; Logging logger = Logging.GetLogger(); foreach (MethodBase item in Harmony.GetAllPatchedMethods().ToList()) { MethodBaseExtensions.HasMethodBody(item); Patches patchInfo = Harmony.GetPatchInfo(item); ReadOnlyCollection<Patch> readOnlyCollection = patchInfo.Prefixes; switch (patchType) { case PatchType.Postfix: readOnlyCollection = patchInfo.Postfixes; break; case PatchType.Prefix: readOnlyCollection = patchInfo.Prefixes; break; case PatchType.Transpiler: readOnlyCollection = patchInfo.Transpilers; break; case PatchType.Finalizer: readOnlyCollection = patchInfo.Finalizers; break; } foreach (Patch item2 in readOnlyCollection) { if (!item2.owner.StartsWith("harmony-auto") || !(item.Name == baseMethodName)) { continue; } if (patchMethodName != null) { if (item2.PatchMethod.Name == patchMethodName) { num++; text = item2.owner; } } else { num++; text = item2.owner; } } if (num == 1) { detectionSet.Add(text, modName); logger.Info($"Added unique anonymous {baseMethodName} {patchType}: {text} as {modName}"); } else if (num > 1) { text = null; logger.Warning($"Found multiple anonymous {baseMethodName} {patchType} entries. Can't identify correct patch to remove or modify."); } } if (num == 0) { logger.Info("No patch found for " + modName); } return text; } } public class IterativeStopwatch : Stopwatch { private double startMillis; private Logging Log = Logging.GetLogger(); public long Iterations { get; private set; } public double IterationMicroseconds { get; private set; } public double TotalElapsedMicroseconds { get; private set; } public double IterationMilliseconds { get; private set; } public double TotalElapsedMilliseconds { get; private set; } public double AverageMicroseconds { get; private set; } public double AverageMilliseconds { get; private set; } public IterativeStopwatch() { Iterations = 0L; } public new void Start() { startMillis = base.Elapsed.TotalMilliseconds; base.Start(); } public new void Stop() { if (base.IsRunning) { base.Stop(); Iterations++; IterationMilliseconds = base.Elapsed.TotalMilliseconds - startMillis; IterationMicroseconds = IterationMilliseconds * 1000.0; TotalElapsedMilliseconds = base.Elapsed.TotalMilliseconds; TotalElapsedMicroseconds = base.Elapsed.TotalMilliseconds * 1000.0; AverageMilliseconds = TotalElapsedMilliseconds / (double)Iterations; AverageMicroseconds = TotalElapsedMicroseconds / (double)Iterations; } } public new void Reset() { startMillis = 0.0; Iterations = 0L; base.Reset(); } public new void Restart() { startMillis = 0.0; Iterations = 0L; base.Restart(); } } public class Logging { public enum LogLevels { Critical, Error, Warning, Info, Debug, Trace } private static Logging _logger; public LogLevels LogLevel { get; set; } public string ModName { get; set; } private Logging(LogLevels level, string name) { LogLevel = level; ModName = name; } public static Logging GetLogger(LogLevels level, string name) { if (_logger == null) { _logger = new Logging(level, name); } return _logger; } public static Logging GetLogger() { if (_logger == null) { throw new NullReferenceException("Logger not initialized"); } return _logger; } public void Trace(string msg) { if (LogLevel >= LogLevels.Trace) { Debug.Log((object)Message(msg)); } } public void Debug(string msg) { if (LogLevel >= LogLevels.Debug) { Debug.Log((object)Message(msg)); } } public void Info(string msg) { if (LogLevel >= LogLevels.Info) { Debug.Log((object)Message(msg)); } } public void Warning(string msg) { if (LogLevel >= LogLevels.Warning) { Debug.LogWarning((object)Message(msg)); } } public void Error(string msg) { if (LogLevel >= LogLevels.Error) { Debug.LogWarning((object)Message(msg)); } } public void Error(Exception e) { Error(e, stackTrace: false); } public void Error(Exception e, bool stackTrace) { if (LogLevel >= LogLevels.Error) { Warning(Message(e.Message)); if (stackTrace) { Warning(e.StackTrace); } } } public void Critical(Exception e) { if (LogLevel >= LogLevels.Critical) { Debug(Message(e.Message)); Error(e.StackTrace); } } private string Message(string msg) { return ModName + ": " + msg; } public static void ChangeLogging(object s, EventArgs e) { SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null); GetLogger().Debug($"ChangeLog {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}"); GetLogger().LogLevel = Cfg.debugLevel.Value; } } public class ServerConfiguration { [HarmonyPatch(typeof(ZNet), "StopAll")] private static class ZNet_Shutdown_Patch { [HarmonyPrefix] private static void ZNet_StopAll_Prefix(ZNet __instance) { Log.Debug("ZNet_StopAll_Patch_Prefix"); Instance.ReceivedServerValues = false; } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class ZNet_OnNewConnection_Patch { private static void Postfix(ZNet __instance, ZNetPeer peer) { Log.Debug("ZNet OnNewConnection postfix"); if (!__instance.IsServer()) { try { peer.m_rpc.Register<ZPackage>("ClientConfigReceiver." + GetPluginGuid(), (Action<ZRpc, ZPackage>)Instance.RPC_ClientConfigReceiver); Log.Debug("Player registered RPC_ClientConfigReceiver"); return; } catch (Exception) { Log.Warning("Failed to register RPC"); return; } } try { Instance.SendConfigToClient(peer); } catch (Exception) { Log.Warning("Error sending server configuration to client"); } } } public static List<DelegatedConfigEntryBase> ServerDelegatedEntries = new List<DelegatedConfigEntryBase>(); private static ConfigFile LocalConfig; private static BaseUnityPlugin Mod; private static string ConfigFileName; private static ServerConfiguration _instance; private static Logging Log; public bool IsSetup; public bool ReceivedServerValues; public FileSystemWatcher ConfigWatcher; private const string NOT_CONFIGURED = "ServerConfiguration not initialized. Setup first."; public static ServerConfiguration Instance { get { if (_instance == null) { _instance = new ServerConfiguration(); } return _instance; } } private ServerConfiguration() { } public void Setup(ConfigFile config, BaseUnityPlugin modInstance) { LocalConfig = config; Log = Logging.GetLogger(); Log.Trace("ServerConfiguration Setup"); Mod = modInstance; ConfigFileName = Path.GetFileName(LocalConfig.ConfigFilePath); IsSetup = true; } public void CreateConfigWatcher() { ConfigWatcher = Utils.CreateFileWatcher(LocalConfig.ConfigFilePath, LoadConfig); } private void LoadConfig(object sender, FileSystemEventArgs e) { if (!File.Exists(LocalConfig.ConfigFilePath)) { return; } try { Log.Debug($"Loading configuration {e.ChangeType}"); LocalConfig.Reload(); } catch { Log.Error("Error loading configuration file " + ConfigFileName); } } public static string GetPluginGuid() { return Mod.Info.Metadata.GUID; } public void RPC_ClientConfigReceiver(ZRpc zrpc, ZPackage package) { if (!Instance.IsSetup) { Log.Error("ServerConfiguration not initialized. Setup first."); return; } Log.Debug("ClientConfigReceiver"); string section; string name; while (package.GetPos() < package.Size()) { section = package.ReadString(); name = package.ReadString(); string text = package.ReadString(); Log.Trace("Reading " + section + " " + name + " value " + text + " from ZPackage"); DelegatedConfigEntryBase delegatedConfigEntryBase = ServerDelegatedEntries.Find((DelegatedConfigEntryBase e) => e.Name == name && e.Section == section); if (delegatedConfigEntryBase != null) { Log.Trace("Found DCEB on client and setting to server value " + text); delegatedConfigEntryBase.ServerValue = text; } ConfigEntryBase val = LocalConfig[section, name]; if (val != null) { Log.Trace("Found local CEB and setting underlying config value " + text); val.SetSerializedValue(text); } } ReceivedServerValues = true; } internal void WriteConfigEntries(ZPackage zpkg) { foreach (DelegatedConfigEntryBase serverDelegatedEntry in ServerDelegatedEntries) { Log.Trace("Writing " + serverDelegatedEntry.Section + " " + serverDelegatedEntry.Name + " value " + serverDelegatedEntry.ServerValue + " to ZPackage"); zpkg.Write(serverDelegatedEntry.Section); zpkg.Write(serverDelegatedEntry.Name); zpkg.Write(serverDelegatedEntry.ServerValue); } } internal void SendConfigToClient(ZNetPeer peer) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown if (!Instance.IsSetup) { Log.Error("ServerConfiguration not initialized. Setup first."); return; } Log.Debug("SendConfigToClient"); ZPackage val = new ZPackage(); WriteConfigEntries(val); peer.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { val }); Log.Trace("Invoked ClientConfigReceiver on peer"); } public void SendConfigToAllClients(object o, SettingChangedEventArgs e) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown if (!IsSetup) { Log.Error("ServerConfiguration not initialized. Setup first."); } else if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.GetPeerConnections() > 0) { Log.Debug("SendConfigToAllClients"); ZPackage zpkg = new ZPackage(); WriteConfigEntries(zpkg); ((MonoBehaviour)Mod).StartCoroutine(_instance.Co_BroadcastConfig(zpkg)); } } private IEnumerator Co_BroadcastConfig(ZPackage zpkg) { Log.Debug("Co_BroadcastConfig"); List<ZNetPeer> connectedPeers = ZNet.instance.GetConnectedPeers(); foreach (ZNetPeer item in connectedPeers) { if (item != ZNet.instance.GetServerPeer()) { item.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { zpkg }); Log.Trace("Invoked ClientConfigReceiver on peer"); } yield return null; } } } internal class Utils { public static TEnum Guardrails<TEnum>(string value, TEnum enumDefault) where TEnum : struct { if (Enum.TryParse<TEnum>(value, ignoreCase: true, out var result)) { return result; } return enumDefault; } public static int Guardrails(int value, int lbound, int ubound) { if (value < lbound) { return lbound; } if (value > ubound) { return ubound; } return value; } public static string truncate(string value, int maxChars) { if (value == null) { return null; } if (value.Length <= maxChars) { return value; } return value.Substring(0, maxChars); } public static void GetCharactersInRangeXZ(Vector3 point, float radius, List<Character> characters) { //IL_001f: 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) float num = radius * radius; foreach (Character s_character in Character.s_characters) { if (DistanceSqrXZ(((Component)s_character).transform.position, point) < num) { characters.Add(s_character); } } } public static float DistanceSqr(Vector3 v0, Vector3 v1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) float num = v1.x - v0.x; float num2 = v1.y - v0.y; float num3 = v1.z - v0.z; return num * num + num2 * num2 + num3 * num3; } public static float DistanceSqrXZ(Vector3 v0, Vector3 v1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = v1.x - v0.x; float num2 = v1.z - v0.z; return num * num + num2 * num2; } public static float DistanceXZ(Vector3 v0, Vector3 v1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = v1.x - v0.x; float num2 = v1.z - v0.z; return Mathf.Sqrt(num * num + num2 * num2); } public static float Guardrails(float value, float lbound, float ubound) { if (value < lbound) { return lbound; } if (value > ubound) { return ubound; } return value; } public static string UnClonifiedName(string name) { if (name == null) { return null; } int num = name.IndexOf("(Clone)"); if (num < 1) { return name; } return name.Substring(0, num); } public static void SetTranslator(int id, string idText) { typeof(Localization).GetMethod("AddWord", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(Localization.instance, new object[2] { "skill_" + id, idText }); } public static string GetTranslated(int id) { Logging.GetLogger().Debug(string.Format("Got translation for id {0} to {1}", id, Localization.instance.Localize("skill_" + id))); return Localization.instance.Localize("$skill_" + id); } public static string GetAssemblyPathedFile(string fileName) { return new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName.Replace('\\', '/') + "/" + fileName; } public static Sprite GetPrefabIcon(string prefabName) { Sprite result = null; GameObject prefab = GetPrefab(prefabName); ItemDrop val = default(ItemDrop); if ((Object)(object)prefab != (Object)null && prefab.TryGetComponent<ItemDrop>(ref val)) { result = val.m_itemData.GetIcon(); } return result; } public static Player GetPlayerByZDOID(ZDOID zid) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) foreach (Player allPlayer in Player.GetAllPlayers()) { ZDOID zDOID = ((Character)allPlayer).GetZDOID(); if (((ZDOID)(ref zDOID)).Equals(zid)) { return allPlayer; } } return null; } public static Character GetCharacterByZDOID(string cid) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) foreach (Character allCharacter in Character.GetAllCharacters()) { ZDOID zDOID = allCharacter.GetZDOID(); if (((object)(ZDOID)(ref zDOID)).ToString().Equals(cid)) { return allCharacter; } } return null; } public static Character GetCharacterByZDOID(ZDOID cid) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) foreach (Character allCharacter in Character.GetAllCharacters()) { ZDOID zDOID = allCharacter.GetZDOID(); if (((ZDOID)(ref zDOID)).Equals(cid)) { return allCharacter; } } return null; } public static ZNetPeer GetPeerByRPC(ZRpc rpc) { foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer.m_rpc == rpc) { return peer; } } return null; } public static List<GameObject> GetGameObjectsOfType(Type t) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) List<GameObject> list = new List<GameObject>(); Object[] array = Object.FindObjectsOfType(t); foreach (Object val in array) { list.Add(((Component)val).gameObject); } return list; } public static GameObject GetClosestGameObjectOfType(Type t, Vector3 point, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return GetGameObjectsOfTypeInRangeByDistance(t, point, radius)?[0]; } public static List<GameObject> GetGameObjectsOfTypeInRangeByDistance(Type t, Vector3 point, float radius) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) List<KeyValuePair<GameObject, float>> list = new List<KeyValuePair<GameObject, float>>(); List<GameObject> gameObjectsOfTypeInRange = GetGameObjectsOfTypeInRange(t, point, radius); if (gameObjectsOfTypeInRange.Count > 0) { foreach (GameObject item in gameObjectsOfTypeInRange) { list.Add(new KeyValuePair<GameObject, float>(item, Vector3.Distance(item.transform.position, point))); } list.Sort((KeyValuePair<GameObject, float> pair1, KeyValuePair<GameObject, float> pair2) => pair1.Value.CompareTo(pair2.Value)); return list.ConvertAll((KeyValuePair<GameObject, float> x) => x.Key); } return null; } public static List<GameObject> GetGameObjectsOfTypeInRange(Type t, Vector3 point, float radius) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return (from x in GetGameObjectsOfType(t) where Vector3.Distance(x.transform.position, point) < radius select x).ToList(); } public static float GetPointDepth(Vector3 p) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return ZoneSystem.instance.m_waterLevel - GetSolidHeight(p); } public static List<string> GetDelimitedStringAsList(string delimitedString, char delimiter) { List<string> list = new List<string>(); string[] array = delimitedString.Split(new char[1] { delimiter }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { list.Add(text.Trim()); } return list; } public static float GetSolidHeight(Vector3 p) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) int solidRayMask = ZoneSystem.instance.m_solidRayMask; float result = 0f; p.y += 1000f; RaycastHit val = default(RaycastHit); if (Physics.Raycast(p, Vector3.down, ref val, 2000f, solidRayMask) && !Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody)) { result = ((RaycastHit)(ref val)).point.y; } return result; } public static Transform FindChild(Transform aParent, string aName) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown foreach (Transform item in aParent) { Transform val = item; if (((Object)val).name == aName) { return val; } Transform val2 = FindChild(val, aName); if ((Object)(object)val2 != (Object)null) { return val2; } } return null; } public static Transform FindParent(Transform go) { while ((Object)(object)go.parent != (Object)null) { go = go.parent; } return go; } public static GameObject GetPrefab(int prefabHash) { return GetPrefabByHash(prefabHash); } public static GameObject GetPrefabByHash(int prefabHash) { GameObject val = ObjectDB.instance.GetItemPrefab(prefabHash); Logging logger = Logging.GetLogger(); if ((Object)(object)val != (Object)null) { logger.Debug("Found prefab in ObjectDB"); } else { ZNetScene instance = ZNetScene.instance; val = ((instance != null) ? instance.GetPrefab(prefabHash) : null); if ((Object)(object)val != (Object)null) { logger.Debug("Found prefab in Scene"); } } return val; } public static GameObject GetPrefab(string prefabName) { GameObject val = ObjectDB.instance.GetItemPrefab(prefabName); Logging logger = Logging.GetLogger(); if ((Object)(object)val != (Object)null) { logger.Debug("Found " + prefabName + " in ObjectDB"); } else { ZNetScene instance = ZNetScene.instance; val = ((instance != null) ? instance.GetPrefab(prefabName) : null); if ((Object)(object)val != (Object)null) { logger.Debug("Found " + prefabName + " in Scene"); } } return val; } public static string SerializeFromDictionary<K, V>(string delimp, string delimc, IDictionary<K, V> dict) { if (dict == null) { return null; } IEnumerable<string> values = dict.Select(delegate(KeyValuePair<K, V> kvp) { KeyValuePair<K, V> keyValuePair = kvp; string? obj = keyValuePair.Key?.ToString(); string text = delimc; keyValuePair = kvp; return obj + text + keyValuePair.Value; }); return string.Join(delimp, values); } public static void DeserializeToDictionary<K, V>(string serializedString, string delimp, string delimc, ref IDictionary<K, V> dict) { if (dict == null) { return; } dict.Clear(); string[] separator = new string[1] { delimp }; string[] separator2 = new string[1] { delimc }; string[] array = serializedString.Split(separator, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(separator2, StringSplitOptions.RemoveEmptyEntries); if (array2.Length == 2) { dict.Add(TypedValue<K>(array2[0]), TypedValue<V>(array2[1])); } } } public static FileSystemWatcher CreateFileWatcher(string fullPath, FileSystemEventHandler handler) { string fileName = Path.GetFileName(fullPath); FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(fullPath.Substring(0, fullPath.Length - fileName.Length), fileName); fileSystemWatcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime; fileSystemWatcher.Changed += handler; fileSystemWatcher.Created += handler; fileSystemWatcher.IncludeSubdirectories = false; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; return fileSystemWatcher; } public static T TypedValue<T>(object a) { return (T)Convert.ChangeType(a, typeof(T)); } public static float TimeAdjustedRamp(float maxValue, float duration, float elapsedTime, float pctFromStartRise, float pctFromEndFall) { float num = elapsedTime / duration; if (num <= pctFromStartRise) { return maxValue * (num / pctFromStartRise); } if (num >= 1f - pctFromEndFall) { return maxValue * ((1f - num) / pctFromEndFall); } return maxValue; } public static bool CopyComponentToGameObject(Component original, ref GameObject destination) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown Logging logger = Logging.GetLogger(); Type type = ((object)original).GetType(); logger.Debug($"Original Type is {type}"); GameObject obj = destination; logger.Debug("Destination GameObject " + ((obj != null) ? ((Object)obj).name : null)); Component val = destination.GetComponent(type); if ((Object)(object)val == (Object)null) { val = destination.AddComponent(type); } if ((Object)(object)val == (Object)null) { logger.Debug("Destination component is null"); return false; } Component val2 = (Component)Activator.CreateInstance(type); if ((Object)(object)val2 == (Object)null) { logger.Debug("Destination component is null"); return false; } if ((Object)(object)val2 == (Object)null) { logger.Debug("Boxed component is null"); return false; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(val2, fieldInfo.GetValue(original)); } val = val2; return true; } public static bool CopyObject(object original, object target) { Logging logger = Logging.GetLogger(); Type type = original.GetType(); Type type2 = target.GetType(); if (type == null) { logger.Warning("Copy Object: Source object is null"); Activator.CreateInstance(type); return false; } if (type2 == null) { logger.Warning("Copy Object: Destination object is null"); return false; } if (type2 != type) { logger.Warning("Copy Object: Source and destination components are different types"); return false; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(target, fieldInfo.GetValue(original)); } return true; } } internal class Cfg { public static DelegatedConfigEntry<int> displacementChance; public static DelegatedConfigEntry<int> maxPieceDamage; public static DelegatedConfigEntry<int> maxTreeDamage; public static DelegatedConfigEntry<bool> allowFullDestruction; public static DelegatedConfigEntry<float> faultChance; public static DelegatedConfigEntry<bool> activeWardsPreventDamage; public static DelegatedConfigEntry<bool> activeShieldsPreventDamage; public static DelegatedConfigEntry<bool> monstersFlee; public static DelegatedConfigEntry<bool> showDust; public static DelegatedConfigEntry<bool> charactersStagger; public static DelegatedConfigEntry<bool> hookedItemsFall; public static DelegatedConfigEntry<bool> activeItemsMove; public static DelegatedConfigEntry<int> earthquakeRadius; public static DelegatedConfigEntry<bool> cameraShakeOverride; public static DelegatedConfigEntry<int> cameraShakeIntensity; public static DelegatedConfigEntry<int> cameraShakeFrequency; public static DelegatedConfigEntry<bool> biomeMeadows; public static DelegatedConfigEntry<bool> biomeSwamp; public static DelegatedConfigEntry<bool> biomeBlackForest; public static DelegatedConfigEntry<bool> biomeMistlands; public static DelegatedConfigEntry<bool> biomeAshlands; public static DelegatedConfigEntry<bool> biomeDeepNorth; public static DelegatedConfigEntry<bool> biomeMountains; public static DelegatedConfigEntry<bool> biomePlains; public static DelegatedConfigEntry<float> fissureMaxDepth; public static DelegatedConfigEntry<float> fissureDeepenPct; public static DelegatedConfigEntry<int> minInterval; public static DelegatedConfigEntry<int> maxInterval; public static DelegatedConfigEntry<Logging.LogLevels> debugLevel; public static void BepInExConfig(BaseUnityPlugin _instance) { //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Expected O, but got Unknown //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Expected O, but got Unknown //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Expected O, but got Unknown //IL_048b: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Expected O, but got Unknown //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_04de: Expected O, but got Unknown //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Expected O, but got Unknown //IL_056e: Unknown result type (might be due to invalid IL or missing references) //IL_0578: Expected O, but got Unknown //IL_0641: Unknown result type (might be due to invalid IL or missing references) //IL_064b: Expected O, but got Unknown //IL_0684: Unknown result type (might be due to invalid IL or missing references) //IL_068e: Expected O, but got Unknown ServerConfiguration.Instance.Setup(_instance.Config, _instance); debugLevel = new DelegatedConfigEntry<Logging.LogLevels>(Logging.ChangeLogging); debugLevel.ConfigEntry = _instance.Config.Bind<Logging.LogLevels>("Utility", "LogLevel", Logging.LogLevels.Info, "Controls the level of information contained in the log"); Valquake.Log.LogLevel = debugLevel.Value; biomeMeadows = new DelegatedConfigEntry<bool>(useServerDelegate: true); biomeMeadows.ConfigEntry = _instance.Config.Bind<bool>("Biomes", "Meadows", true, "Earthquakes trigger in the Meadows.@"); biomeSwamp = new DelegatedConfigEntry<bool>(useServerDelegate: true); biomeSwamp.ConfigEntry = _instance.Config.Bind<bool>("Biomes", "Swamp", false, "Earthquakes trigger in the Swamp.@"); biomeBlackForest = new DelegatedConfigEntry<bool>(useServerDelegate: true); biomeBlackForest.ConfigEntry = _instance.Config.Bind<bool>("Biomes", "Black Forest", false, "Earthquakes trigger in the Black Forest.@"); biomeMountains = new DelegatedConfigEntry<bool>(useServerDelegate: true); biomeMountains.ConfigEntry = _instance.Config.Bind<bool>("Biomes", "Mountains", true, "Earthquakes trigger in the Mountains.@"); biomePlains = new DelegatedConfigEntry<bool>(useServerDelegate: true); biomePlains.ConfigEntry = _instance.Config.Bind<bool>("Biomes", "Plains", false, "Earthquakes trigger in the Plains.@"); biomeMistlands = new DelegatedConfigEntry<bool>(useServerDelegate: true); biomeMistlands.ConfigEntry = _instance.Config.Bind<bool>("Biomes", "Mistlands", true, "Earthquakes trigger in the Mistlands.@"); biomeAshlands = new DelegatedConfigEntry<bool>(useServerDelegate: true); biomeAshlands.ConfigEntry = _instance.Config.Bind<bool>("Biomes", "Ashlands", true, "Earthquakes trigger in the Ashlands.@"); biomeDeepNorth = new DelegatedConfigEntry<bool>(useServerDelegate: true); biomeDeepNorth.ConfigEntry = _instance.Config.Bind<bool>("Biomes", "Deep North", false, "Earthquakes trigger in the Deep North.@"); showDust = new DelegatedConfigEntry<bool>(useServerDelegate: true); showDust.ConfigEntry = _instance.Config.Bind<bool>("Effects", "A. Show Dust", true, "If enabled, will display a cloud of dust along the fault line during a quake. Only meaningful if Fissure Chance is > 0%.@"); monstersFlee = new DelegatedConfigEntry<bool>(useServerDelegate: true); monstersFlee.ConfigEntry = _instance.Config.Bind<bool>("Effects", "B. Creatures Scatter", true, "If enabled, creatures close enough to quake zone will scatter for a short time.@"); charactersStagger = new DelegatedConfigEntry<bool>(useServerDelegate: true); charactersStagger.ConfigEntry = _instance.Config.Bind<bool>("Effects", "C. Staggering", true, "If enabled, players and creatures can stagger during the quake while inside the quake zone.@"); allowFullDestruction = new DelegatedConfigEntry<bool>(useServerDelegate: true); allowFullDestruction.ConfigEntry = _instance.Config.Bind<bool>("Effects", "D. Allow Piece Destruction", false, "If enabled, allows the full destruction of pieces duing the quake (dropping materials). If disabled, pieces can only be reduced to 1 health.@"); displacementChance = new DelegatedConfigEntry<int>(useServerDelegate: true); displacementChance.ConfigEntry = _instance.Config.Bind<int>("Effects", "E. Piece Displacement Chance", 0, new ConfigDescription("The percent chance pieces are displaced in the horizontal plane during a quake. A value of zero (0) never displaces pieces.@", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); hookedItemsFall = new DelegatedConfigEntry<bool>(useServerDelegate: true); hookedItemsFall.ConfigEntry = _instance.Config.Bind<bool>("Effects", "F. Items Can Fall", true, "If enabled, things mounted on items stands can be shaken loose and fall during a quake.@"); activeItemsMove = new DelegatedConfigEntry<bool>(useServerDelegate: true); activeItemsMove.ConfigEntry = _instance.Config.Bind<bool>("Effects", "G. Things Can Move", true, "If enabled, some 'active' things like carts & ships, will move with the quake.@"); earthquakeRadius = new DelegatedConfigEntry<int>(useServerDelegate: true); earthquakeRadius.ConfigEntry = _instance.Config.Bind<int>("Control", "A. Quake Radius", 100, new ConfigDescription("Radius (in meters) of the earthquake zone. Effects will diminish farther from the epicenter.@", (AcceptableValueBase)(object)new AcceptableValueRange<int>(20, 200), Array.Empty<object>())); minInterval = new DelegatedConfigEntry<int>(Valquake.ChangeMinInterval, useServerDelegate: true); minInterval.ConfigEntry = _instance.Config.Bind<int>("Control", "B. Min Interval", 30, "Minimum possible time (in minutes) between earthquakes. Minimum value is 1.@"); maxInterval = new DelegatedConfigEntry<int>(Valquake.ChangeMaxInterval, useServerDelegate: true); maxInterval.ConfigEntry = _instance.Config.Bind<int>("Control", "C. Max Interval", 120, "Maximum possible time (in minutes) between earthquakes. Value must be equal to or greater than Min Interval.@"); faultChance = new DelegatedConfigEntry<float>(useServerDelegate: true); faultChance.ConfigEntry = _instance.Config.Bind<float>("Control", "D. Fault Zone Chance", 20f, new ConfigDescription("The percent chance of a zone having a 'fault line'. Quakes will only create a fissure in a zone with a fault line. A value of 0% will prevent any fissures from forming.@", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); maxPieceDamage = new DelegatedConfigEntry<int>(useServerDelegate: true); maxPieceDamage.ConfigEntry = _instance.Config.Bind<int>("Control", "E. Max Piece Damage", 1000, new ConfigDescription("The maximum damage that can be applied to pieces in the quake zone. A value of 0 will not apply any damage. Damage is attenuated by distance from the epicenter and degree of support.@", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2000), Array.Empty<object>())); maxTreeDamage = new DelegatedConfigEntry<int>(useServerDelegate: true); maxTreeDamage.ConfigEntry = _instance.Config.Bind<int>("Control", "F. Max Tree Damage", 200, new ConfigDescription("The maximum damage that can be applied to trees in the quake zone. A value of 0 will not apply any damage. Damage is attenuated by distance from the epicenter.@", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200), Array.Empty<object>())); fissureMaxDepth = new DelegatedConfigEntry<float>(useServerDelegate: true); fissureMaxDepth.ConfigEntry = _instance.Config.Bind<float>("Control", "G. Max Fissure Depth", 2f, new ConfigDescription("The maximum depth (in meters) of the fissure for the first quake along a fault line. Subsequent quakes along the same fault line are controlled by Successive Quake Depth as a percentage of this value.@", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 6f), Array.Empty<object>())); fissureDeepenPct = new DelegatedConfigEntry<float>(useServerDelegate: true); fissureDeepenPct.ConfigEntry = _instance.Config.Bind<float>("Control", "H. Successive Quake Depth", 0.2f, new ConfigDescription("Sets the percent of the Max Fissure Depth to apply to each successive quake along the same fault line. A value of 0% will not deepen the fissure.@", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); activeWardsPreventDamage = new DelegatedConfigEntry<bool>(useServerDelegate: true); activeWardsPreventDamage.ConfigEntry = _instance.Config.Bind<bool>("Control", "I. Active Wards Reduce Damage", false, "If enabled, an active ward will reduce damage to pieces if the quake epicenter is within the ward's area of protection.@"); activeShieldsPreventDamage = new DelegatedConfigEntry<bool>(useServerDelegate: true); activeShieldsPreventDamage.ConfigEntry = _instance.Config.Bind<bool>("Control", "J. Active Shields Reduce Damage", false, "If enabled, a fueled Shield Generator will reduce damage to pieces if the quake epicenter is within the shield's area of protection.@"); cameraShakeOverride = new DelegatedConfigEntry<bool>(); cameraShakeOverride.ConfigEntry = _instance.Config.Bind<bool>("Camera", "Camera Sway Override", false, "If enabled, will override Valheim's camera shake setting (just for quakes) and 'sway' camera. If disabled, will use Valheim's setting."); cameraShakeIntensity = new DelegatedConfigEntry<int>(); cameraShakeIntensity.ConfigEntry = _instance.Config.Bind<int>("Camera", "Camera Sway Intensity", 100, new ConfigDescription("Sets how much the camera 'sways'. Lower values will reduce the amount of camera movement.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); cameraShakeFrequency = new DelegatedConfigEntry<int>(); cameraShakeFrequency.ConfigEntry = _instance.Config.Bind<int>("Camera", "Camera Sway Frequency", 10, new ConfigDescription("Sets how fast the camera 'sways'. Lower values will reduce how quickly the camera moves.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), Array.Empty<object>())); ServerConfiguration.Instance.CreateConfigWatcher(); } } public class QuakeShaker { private float angle; public static float s_baseIntensity = 3f; public static float PctRise = 0.2f; public static float PctFall = 0.5f; private const float twoPi = (float)Math.PI * 2f; private float lastTime; public Vector3 Epicenter { get; set; } public float Frequency { get; set; } public float Duration { get; set; } public float Intensity { get; set; } public float Radius { get; set; } private float StopTime { get; set; } public QuakeShaker(Vector3 epicenter, float radius, float intensity, float duration, float frequency = 30f) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) Epicenter = epicenter; Frequency = frequency; Duration = duration; Intensity = intensity; Radius = radius; StopTime = 0f; } public bool isActive() { return Time.time < StopTime; } public void Start() { StopTime = Time.time + Duration; } public void Stop() { StopTime = 0f; } public float PctOfDuration() { return 1f - (StopTime - Time.time) / Duration; } public bool HasPeaked() { return PctOfDuration() >= PctRise; } public bool InPeakWindow() { float num = PctOfDuration(); if (num >= PctRise) { return num <= PctFall; } return false; } public float ElapsedTime() { return Time.time + Duration - StopTime; } public float TimeRemaining() { return StopTime - Time.time; } public float TimeAdjustedIntensity() { return Utils.TimeAdjustedRamp(Intensity, Duration, ElapsedTime(), PctRise, PctFall); } public float GetCurrentAngle() { return angle; } public void Update(float dt) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) if (!isActive()) { lastTime = 0f; return; } GameCamera instance = GameCamera.instance; float time = Time.time; if (lastTime != 0f) { dt = time - lastTime; } lastTime = time; float num = (float)Cfg.cameraShakeIntensity.Value / 100f; float num2 = TimeAdjustedIntensity() * num; angle += dt * Frequency; if (angle > (float)Math.PI * 2f) { angle -= (float)Math.PI * 2f; } Quaternion val = Quaternion.Euler(Mathf.Sin(angle) * num2, 0f, Mathf.Cos(angle * 0.9f) * num2); ((Component)instance).transform.rotation = ((Component)instance).transform.rotation * val; } } [BepInPlugin("neobotics.valheim_mod.valquake", "Valquake", "0.1.5")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public class Valquake : BaseUnityPlugin { [HarmonyPatch(typeof(Heightmap), "Regenerate")] private static class Heightmap_Regenerate_Patch { [HarmonyPrefix] private static bool Heightmap_Regenerate_Prefix(Heightmap __instance) { if (isCracking) { Log.Trace("Skipping Regenerate until fissure complete"); return false; } return true; } } [HarmonyPatch(typeof(AnimalAI), "UpdateAI")] private static class AnimalAI_UpdateAI_Patch { [HarmonyPrefix] private static bool AnimalAI_UpdateAI_Prefix(AnimalAI __instance, float dt) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (IsShaking() && Vector3.Distance(((Component)__instance).transform.position, quakeShaker.Epicenter) < quakeShaker.Radius) { ((BaseAI)__instance).SetAlerted(true); ((BaseAI)__instance).Flee(dt, quakeShaker.Epicenter); return false; } return true; } } [HarmonyPatch(typeof(MonsterAI), "UpdateAI")] private static class MonsterAI_UpdateAI_Patch { [HarmonyPrefix] private static bool MonsterAI_UpdateAI_Prefix(MonsterAI __instance, float dt) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (IsShaking() && Vector3.Distance(((Component)__instance).transform.position, quakeShaker.Epicenter) < quakeShaker.Radius * 0.75f) { ((BaseAI)__instance).SetAlerted(true); ((BaseAI)__instance).Flee(dt, quakeShaker.Epicenter); return false; } return true; } } [HarmonyPatch(typeof(Game), "Start")] private static class Game_Start_Patch { [HarmonyPostfix] private static void Game_Start_Patch_Postfix(Game __instance) { Log.Debug("Game_Start_Patch_Postfix"); audioHelper = ((Component)__instance).gameObject.AddComponent<AudioHelper>(); ZRoutedRpc.instance.Register<Vector3, float, float, float>("ValquakeShake", (Method<Vector3, float, float, float>)RPC_ValquakeShake); Log.Debug(string.Format("Registered RPC ValquakeShake {0}", StringExtensionMethods.GetStableHashCode("ValquakeShake"))); ZRoutedRpc.instance.Register("ValquakeReset", (Action<long>)RPC_ValquakeReset); Log.Debug(string.Format("Registered RPC ValquakeReset {0}", StringExtensionMethods.GetStableHashCode("ValquakeReset"))); } } [HarmonyPatch(typeof(Game), "Logout")] private static class Game_Logout_Patch { [HarmonyPrefix] private static void Game_Logout_Patch_Prefix(Game __instance) { nextQuakeTime = 0f; } } [HarmonyPatch(typeof(Player), "Update")] public static class Player_Update_Patch { private static void Prefix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && nextQuakeTime > 0f && Time.time > nextQuakeTime) { StartQuake(); } } } [HarmonyPatch(typeof(GameCamera), "UpdateCameraShake")] private static class GameCamera_UpdateCameraShake_Patch { [HarmonyPostfix] private static void GameCamera_UpdateCameraShake_Postfix(GameCamera __instance, float dt) { if (quakeShaker != null) { quakeShaker.Update(dt); if (!quakeShaker.isActive()) { quakeShaker = null; } } } } [HarmonyPatch(typeof(Player), "OnSpawned")] public static class Player_OnSpawned_Patch { public static void Postfix(Player __instance) { Log.Debug("Player_OnSpawned_Patch_Postfix"); SetNextQuake(Cfg.minInterval.Value, Cfg.maxInterval.Value); } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] private static class Terminal_InitTerminal_Patch { [HarmonyPostfix] private static void Terminal_InitTerminal_Postfix(Terminal __instance) { AddValquakeConsoleCommand(); } } [HarmonyPatch(typeof(ItemStand), "DropItem")] private static class ItemStand_DropItem_Patch { [HarmonyPrefix] private static bool ItemStand_DropItem_Prefix(ItemStand __instance) { //IL_004d: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (!IsShaking()) { return true; } Log.Debug("ItemStand_DropItem_Patch_Prefix"); if (!__instance.HaveAttachment()) { return false; } GameObject prefab = Utils.GetPrefab(__instance.m_nview.GetZDO().GetString(ZDOVars.s_item, "")); if (Object.op_Implicit((Object)(object)prefab)) { Vector3 val = Vector3.zero; Quaternion val2 = Quaternion.identity; Transform val3 = prefab.transform.Find("attach"); if (Object.op_Implicit((Object)(object)prefab.transform.Find("attachobj")) && Object.op_Implicit((Object)(object)val3)) { val2 = ((Component)val3).transform.localRotation; val = ((Component)val3).transform.localPosition; } GameObject obj = Object.Instantiate<GameObject>(prefab, __instance.m_dropSpawnPoint.position + val, __instance.m_dropSpawnPoint.rotation * val2); obj.GetComponent<ItemDrop>().LoadFromExternalZDO(__instance.m_nview.GetZDO()); obj.GetComponent<Rigidbody>().rotation = Quaternion.Euler(0.3f, 0.1f, 0.5f); } __instance.m_nview.GetZDO().Set(ZDOVars.s_item, ""); __instance.m_nview.InvokeRPC(ZNetView.Everybody, "SetVisualItem", new object[3] { "", 0, 0 }); return false; } } [HarmonyPatch(typeof(TerrainComp), "RaiseTerrain")] private static class TerrainComp_RaiseTerrain_Patch { [HarmonyPrefix] private static bool TerrainComp_RaiseTerrain_Prefix(TerrainComp __instance, Vector3 worldPos, float radius, float delta, bool square, float power) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (isCracking) { DigFissure(__instance, __instance.m_hmap, __instance.m_width, worldPos, radius, delta, square, power); return false; } return true; } } [HarmonyPatch(typeof(TreeBase), "Awake")] private static class TreeBase_Awake_Patch { [HarmonyPostfix] private static void TreeBase_Awake_Postfix(TreeBase __instance) { ZDO val = __instance?.m_nview?.m_zdo; if (val != null && !treeManager.ContainsKey(val)) { treeManager.Add(val, __instance); } } } [HarmonyPatch(typeof(ZNetScene), "Destroy")] private static class ZNetScene_Destroy_Patch { [HarmonyPrefix] private static void ZNetScene_Destroy_Prefix(ZNetScene __instance, GameObject go) { ZNetView val = default(ZNetView); if (go.TryGetComponent<ZNetView>(ref val) && val.m_zdo != null && treeManager.Remove(val.m_zdo)) { Log.Trace("Removed tree from manager"); } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__33_0; public static Func<bool> <>9__36_0; public static Func<bool> <>9__41_0; public static Func<bool> <>9__42_0; public static Func<bool> <>9__43_0; public static Func<bool> <>9__47_0; public static Func<bool> <>9__56_0; internal void <AddValquakeConsoleCommand>b__33_0(ConsoleEventArgs <p0>) { if (OkToQuake(Player.m_localPlayer)) { StartQuake(); } } internal bool <Co_Clatter>b__36_0() { return quakeShaker.HasPeaked(); } internal bool <Co_DropAttachedPieces>b__41_0() { return quakeShaker.HasPeaked(); } internal bool <Co_DamagePieces>b__42_0() { return quakeShaker.HasPeaked(); } internal bool <Co_DamageTrees>b__43_0() { return quakeShaker.HasPeaked(); } internal bool <Co_StaggerController>b__47_0() { return halfCracked; } internal bool <Co_ModifyTerrain>b__56_0() { return quakeShaker.HasPeaked(); } } internal static Valquake _modInstance; private static string Mod = "Valquake"; private static string LcMod = Mod.ToLower(); public static Logging Log; public static float nextQuakeTime = 0f; public static QuakeShaker quakeShaker = null; public static bool isCracking = false; public static bool halfCracked = false; internal static AudioHelper audioHelper; internal static GameObject fissure_vfx; internal static GameObject cracking_sfx; internal static Vector2Int lastFissureXY = Vector2Int.zero; internal static Vector3 lastWorldPos = Vector3.zero; private const float delayUntilPeak = 2f; private static float fissureRadius = 1f; private static float fissureSpacing = 1f; public static float baseCamShakeFrequency = 10f; private const string vfx_fissure_prefab = "vfx_Place_mud_road"; private const string sfx_crack_prefab = "sfx_stonegolem_attack_hit"; private const string sfx_rumble = "quake_outdoor_major.mp3"; private const string sfx_clatter = "clatter.mp3"; private const string sfx_clunk = "clunk.mp3"; public static Dictionary<ZDO, TreeBase> treeManager = new Dictionary<ZDO, TreeBase>(); private static Harmony harmony = null; private static int doN = 1; public static Valquake GetInstance() { return _modInstance; } private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown _modInstance = this; harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); harmony.PatchAll(Assembly.GetExecutingAssembly()); ConfigureMod(); Log.Info("Awake"); } private void ConfigureMod() { Log = Logging.GetLogger(Logging.LogLevels.Info, Mod); Cfg.BepInExConfig((BaseUnityPlugin)(object)_modInstance); } private void OnDestroy() { harmony.UnpatchSelf(); } public static void ChangeMinInterval(object s, EventArgs e) { SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null); Log.Debug($"ChangeLog {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}"); if (Cfg.minInterval.Value < 1) { Log.Info("Min Interval must be >= 1"); Cfg.minInterval.Value = 1; } if (Cfg.maxInterval.Value < Cfg.minInterval.Value) { Cfg.maxInterval.Value = Cfg.minInterval.Value; } } public static void ChangeMaxInterval(object s, EventArgs e) { SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null); Log.Debug($"ChangeLog {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}"); if (Cfg.maxInterval.Value < 1 || Cfg.maxInterval.Value < Cfg.minInterval.Value) { Log.Info("Max Interval must be >= the Min Interval"); Cfg.maxInterval.Value = Cfg.minInterval.Value; } } private static void SetFissureTerrainOpSettings(Settings settings, float radius, float delta) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) settings.m_levelOffset = delta; settings.m_level = false; settings.m_levelRadius = radius; settings.m_square = true; settings.m_raise = true; settings.m_raiseRadius = radius; settings.m_raisePower = 0f; settings.m_raiseDelta = delta; settings.m_smooth = false; settings.m_smoothRadius = radius; settings.m_smoothPower = 1f; settings.m_paintCleared = false; settings.m_paintHeightCheck = false; settings.m_paintType = (PaintType)0; settings.m_paintRadius = radius; } private static bool InQuakeBiome(Player aPlayer) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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) //IL_000a: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected I4, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 Biome currentBiome = aPlayer.GetCurrentBiome(); if ((int)currentBiome <= 16) { switch (currentBiome - 1) { default: if ((int)currentBiome != 8) { if ((int)currentBiome != 16) { break; } return Cfg.biomePlains.Value; } return Cfg.biomeBlackForest.Value; case 0: return Cfg.biomeMeadows.Value; case 1: return Cfg.biomeSwamp.Value; case 3: return Cfg.biomeMountains.Value; case 2: break; } } else { if ((int)currentBiome == 32) { return Cfg.biomeAshlands.Value; } if ((int)currentBiome == 64) { return Cfg.biomeDeepNorth.Value; } if ((int)currentBiome == 512) { return Cfg.biomeMistlands.Value; } } return false; } private static void AddValquakeConsoleCommand() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (!Terminal.m_terminalInitialized) { return; } object obj = <>c.<>9__33_0; if (obj == null) { ConsoleEvent val = delegate { if (OkToQuake(Player.m_localPlayer)) { StartQuake(); } }; <>c.<>9__33_0 = val; obj = (object)val; } new ConsoleCommand("valquake", "Starts an earthquake near the player location", (ConsoleEvent)obj, true, false, false, true, false, (ConsoleOptionsFetcher)null, false, false, false); } private static bool IsShaking() { if (quakeShaker != null) { return quakeShaker.isActive(); } return false; } private static void StartQuake() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) Log.Debug("StartQuake"); Player localPlayer = Player.m_localPlayer; nextQuakeTime += (float)Cfg.maxInterval.Value * 60f; if (!OkToQuake(localPlayer)) { Log.Debug("Not OK to start quake. Resetting"); SetNextQuake(5f, 15f); return; } float s_baseIntensity = QuakeShaker.s_baseIntensity; float num = audioHelper.GetClipDuration("quake_outdoor_major.mp3"); if (num <= 0f) { num = 11f; } float num2 = Cfg.earthquakeRadius.Value; Heightmap val = Heightmap.FindHeightmap(((Component)localPlayer).transform.position); Vector3 position = ((Component)val).transform.position; audioHelper.Play(position, "quake_outdoor_major.mp3"); if (localPlayer.InShelter()) { ((MonoBehaviour)_modInstance).StartCoroutine(_modInstance.Co_Clatter(((Component)localPlayer).transform.position, 2f)); } ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ValquakeShake", new object[4] { position, num2, s_baseIntensity, num }); DamageThings(position, Cfg.earthquakeRadius.Value, num); bool flag = true; if (Cfg.faultChance.Value > 0f) { flag = CreateFissure(val); } if (flag) { StartStaggering(position, Cfg.earthquakeRadius.Value, -1f); } ResetNextQuake(); } private IEnumerator Co_Clatter(Vector3 position, float delay) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (IsShaking()) { yield return (object)new WaitUntil((Func<bool>)(() => quakeShaker.HasPeaked())); } else { yield return (object)new WaitForSeconds(delay); } audioHelper.Play(position, "clatter.mp3"); } private static void DamageThings(Vector3 epicenter, float radius, float duration) { //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: 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_01d6: Unknown result type (might be due to invalid IL or missing references) Log.Debug("DamageThings"); _ = Player.m_localPlayer; if (Cfg.maxPieceDamage.Value == 0 && Cfg.maxTreeDamage.Value == 0 && !Cfg.hookedItemsFall.Value && !Cfg.activeItemsMove.Value) { return; } Dictionary<WearNTear, float> dictionary = new Dictionary<WearNTear, float>(); Dictionary<TreeBase, float> dictionary2 = new Dictionary<TreeBase, float>(); Dictionary<ItemStand, float> dictionary3 = new Dictionary<ItemStand, float>(); Ship ship = default(Ship); Vagon vagon = default(Vagon); ItemStand val = default(ItemStand); WearNTear val2 = default(WearNTear); foreach (WearNTear allInstance in WearNTear.GetAllInstances()) { GameObject gameObject = ((Component)allInstance).gameObject; if (gameObject.TryGetComponent<Ship>(ref ship)) { if (Cfg.activeItemsMove.Value && IsShaking()) { ((MonoBehaviour)_modInstance).StartCoroutine(_modInstance.Co_ShakeShip(ship)); } continue; } if (gameObject.TryGetComponent<Vagon>(ref vagon)) { if (Cfg.activeItemsMove.Value && IsShaking()) { ((MonoBehaviour)_modInstance).StartCoroutine(_modInstance.Co_ShakeVagon(vagon)); } continue; } if (Cfg.hookedItemsFall.Value && gameObject.TryGetComponent<ItemStand>(ref val)) { float value = Vector3.Distance(epicenter, ((Component)val).transform.position); if (!dictionary3.ContainsKey(val)) { dictionary3.Add(val, value); } } if (Cfg.maxPieceDamage.Value > 0 && gameObject.TryGetComponent<WearNTear>(ref val2)) { float value2 = Vector3.Distance(epicenter, ((Component)val2).transform.position); if (!dictionary.ContainsKey(val2)) { dictionary.Add(val2, value2); } } } if (Cfg.maxTreeDamage.Value > 0) { foreach (TreeBase value4 in treeManager.Values) { if ((Object)(object)value4 != (Object)null && Random.value > 0.66f) { float value3 = Vector3.Distance(epicenter, ((Component)value4).transform.position); if (!dictionary2.ContainsKey(value4)) { dictionary2.Add(value4, value3); } } } } float num = Cfg.maxPieceDamage.Value; if (TryGetClosestActiveWard(epicenter, 0f, out var distance)) { float num2 = 1f - distance / radius; num *= 0.5f * num2; Log.Debug("Active ward reduced max damage"); } if (TryGetClosestShieldGenerator(epicenter, 0f, out var distance2)) { float num3 = 1f - distance2 / radius; num *= 0.5f * num3; Log.Debug("Active shield generator reduced max damage"); } if (dictionary.Count > 0) { ((MonoBehaviour)_modInstance).StartCoroutine(_modInstance.Co_DamagePieces(dictionary, radius, num, duration, 1f)); } if (dictionary2.Count > 0) { ((MonoBehaviour)_modInstance).StartCoroutine(_modInstance.Co_DamageTrees(dictionary2, epicenter, radius, Cfg.maxTreeDamage.Value, duration, 1f)); } if (dictionary3.Count > 0) { ((MonoBehaviour)_modInstance).StartCoroutine(_modInstance.Co_DropAttachedPieces(dictionary3, radius, duration, 2f)); } } private IEnumerator Co_ShakeVagon(Vagon vagon) { Log.Trace("Co_ShakeVagon"); object obj; if (vagon == null) { obj = null; } else { GameObject gameObject = ((Component)vagon).gameObject; obj = ((gameObject != null) ? gameObject.GetComponent<Rigidbody>() : null); } Rigidbody rb = (Rigidbody)obj; while (IsShaking()) { if ((Object)(object)rb == (Object)null) { yield break; } float num = Mathf.Sign(Mathf.Sin(quakeShaker.GetCurrentAngle())); float num2 = quakeShaker.TimeAdjustedIntensity(); rb.AddRelativeForce(new Vector3(0f, 0f, num2 * 2f * num), (ForceMode)1); yield return null; } rb.velocity = Vector3.zero; } private IEnumerator Co_RollLog(TreeLog log) { Log.Trace("Co_RollLog"); object obj; if (log == null) { obj = null; } else { GameObject gameObject = ((Component)log).gameObject; obj = ((gameObject != null) ? gameObject.GetComponent<Rigidbody>() : null); } Rigidbody rb = (Rigidbody)obj; while (IsShaking()) { if ((Object)(object)rb == (Object)null) { yield break; } float num = Mathf.Sign(Mathf.Sin(quakeShaker.GetCurrentAngle())); float num2 = quakeShaker.TimeAdjustedIntensity(); rb.AddRelativeTorque(new Vector3(0f, 0f, num2 * 25f * num), (ForceMode)1); yield return null; } rb.angularVelocity = Vector3.zero; } private IEnumerator Co_ShakeShip(Ship ship) { Log.Trace("Co_ShakeVagon"); object obj; if (ship == null) { obj = null; } else { GameObject gameObject = ((Component)ship).gameObject; obj = ((gameObject != null) ? gameObject.GetComponent<Rigidbody>() : null); } Rigidbody rb = (Rigidbody)obj; while (IsShaking()) { if ((Object)(object)rb == (Object)null) { yield break; } float num = Mathf.Sign(Mathf.Sin(quakeShaker.GetCurrentAngle())); float num2 = quakeShaker.TimeAdjustedIntensity(); rb.AddRelativeTorque(new Vector3(0f, 0f, num2 / 4f * num), (ForceMode)1); yield return null; } rb.angularVelocity = Vector3.zero; } private IEnumerator Co_DropAttachedPieces(Dictionary<ItemStand, float> st, float radius, float duration, float delay) { Log.Debug("Co_DropAttachedPieces"); float num; if (IsShaking()) { yield return (object)new WaitUntil((Func<bool>)(() => quakeShaker.HasPeaked())); num = quakeShaker.TimeRemaining(); } else { yield return (object)new WaitForSeconds(delay); num = duration - delay; } float wait = Mathf.Clamp01(num / 2f / (float)st.Count); foreach (KeyValuePair<ItemStand, float> item in st) { if (Random.value < 0.5f) { item.Key.DropItem(); } yield return (object)new WaitForSeconds(wait); } } private IEnumerator Co_DamagePieces(Dictionary<WearNTear, float> wnt, float radius, float damage, float duration, float delay) { Log.Debug("Co_DamagePieces"); float num; if (IsShaking()) { yield return (object)new WaitUntil((Func<bool>)(() => quakeShaker.HasPeaked())); num = quakeShaker.TimeRemaining(); } else { yield return (object)new WaitForSeconds(delay); num = duration - delay; } float wait = Mathf.Clamp01(num / 2f / (float)wnt.Count); Container val = default(Container); foreach (KeyValuePair<WearNTear, float> item in wnt) { WearNTear key = item.Key; float value = item.Value; if ((Object)(object)key != (Object)null && !((Component)key).gameObject.TryGetComponent<Container>(ref val)) { float num2 = damage * (1f - value / radius); float maxSupport = key.GetMaxSupport(); float num3 = 1f - key.m_support * 0.9f / maxSupport; DamagePiece(key, num2 * num3); } yield return (object)new WaitForSeconds(wait); } } private IEnumerator Co_DamageTrees(Dictionary<TreeBase, float> tb, Vector3 epicenter, float radius, float damage, float duration, float delay) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Log.Debug("Co_DamageTrees"); float num; if (IsShaking()) { yield return (object)new WaitUntil((Func<bool>)(() => quakeShaker.HasPeaked())); num = quakeShaker.TimeRemaining(); } else { yield return (object)new WaitForSeconds(delay); num = duration - delay; } float wait = Mathf.Clamp01(num / 2f / (float)tb.Count); foreach (KeyValuePair<TreeBase, float> item in tb) { TreeBase key = item.Key; float value = item.Value; float distanceAdjDamage = damage * (1f - value / radius); DamageTree(key, epicenter, distanceAdjDamage); yield return (object)new WaitForSeconds(wait); } } private static void DamagePiece(WearNTear wnt, float distanceAdjDamage) { if ((Object)(object)wnt == (Object)null || (Object)(object)wnt.m_nview == (Object)null || !wnt.m_nview.IsValid() || !wnt.m_nview.IsOwner()) { return; } float @float = wnt.m_nview.GetZDO().GetFloat(ZDOVars.s_health, wnt.m_health); float num = RandomToMax(distanceAdjDamage, 0.75f); float num2 = @float - num; if (num2 <= 0f && Cfg.allowFullDestruction.Value) { wnt.Destroy((HitData)null); return; } num2 = Mathf.Clamp(num2, 1f, num2); if (@float > 1f) { if ((float)Cfg.displacementChance.Value > 0f) { Displace(((Component)wnt).transform); } wnt.m_nview.GetZDO().Set(ZDOVars.s_health, num2); wnt.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_HealthChanged", new object[1] { num2 }); wnt.SetHealthVisual(num2 / wnt.m_health, true); } } private static void DamageTree(TreeBase treeBase, Vector3 epicenter, float distanceAdjDamage) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)treeBase == (Object)null) && treeBase.m_nview.IsValid()) { treeBase.m_nview.m_zdo.Owned = true; treeBase.m_nview.m_zdo.Owner = true; HitData val = new HitData(); val.m_attacker = ZDOID.None; val.m_itemWorldLevel = 100; val.m_toolTier = 100; val.m_damage.m_chop = RandomToMax(distanceAdjDamage, 0.75f); val.m_dir = epicenter - ((Component)treeBase).transform.position; val.m_dir.y = 0f; val.m_dir = Vector3.Normalize(val.m_dir); treeBase.Damage(val); } } private static void StartStaggering(Vector3 epicenter, float radius, float delay = 0f) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) Log.Debug("StartStaggering"); if (Cfg.charactersStagger.Value) { ((MonoBehaviour)_modInstance).StartCoroutine(_modInstance.Co_StaggerController(epicenter, radius, delay)); } } private IEnumerator Co_StaggerController(Vector3 epicenter, float radius, float delay) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!IsShaking() || quakeShaker.TimeRemaining() < quakeShaker.Duration * 0.2f) { yield break; } if (delay < 0f) { yield return (object)new WaitUntil((Func<bool>)(() => halfCracked)); } else if (delay > 0f) { yield return (object)new WaitForSeconds(delay); } List<Character> characters = new List<Character>(); Utils.GetCharactersInRangeXZ(epicenter, radius, characters); Object.Instantiate<GameObject>(cracking_sfx, epicenter, Quaternion.identity); bool randomize = false; float randomChance = 0.5f; do { foreach (Character item in characters) { if ((!randomize || Random.value < randomChance) && (Object)(object)item != (Object)null && OkToStagger(item)) { item.Stagger(((Component)item).transform.position); } yield return null; } randomize = true; randomChance = Mathf.Clamp01(randomChance - 0.1f); radius *= 0.8f; yield return (object)new WaitForSeconds(2f); } while (quakeShaker.InPeakWindow()); } private static void PseudoApplyOperation(ZNetView m_nview, Vector3 epicenter, Settings tos) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) Log.Trace("PseudoApplyOperation"); ZPackage val = new ZPackage(); val.Write(epicenter); tos.Serialize(val); m_nview.InvokeRPC("ApplyOperation", new object[1] { val }); } private static bool FissureExists(Heightmap hm, Vector3 point) { //IL_0001: 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) float num = default(float); hm.GetWorldHeight(point, ref num); float num2 = default(float); hm.GetWorldBaseHeight(point, ref num2); return num < num2 - Cfg.fissureMaxDepth.Value * 0.9f; } private static int GetSeedFromHeightmap(Heightmap hm) { //IL_0006: 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_0033: Unknown result type (might be due to invalid IL or missing references) int num = Convert.ToInt32(Mathf.Clamp(Mathf.Abs(((Component)hm).transform.position.x * 3f + ((Component)hm).transform.position.z * 2f + ((Component)hm).transform.position.y), 0f, 2.1474836E+09f)); Log.Debug($"Seed from heightmap {num}"); return num; } private static Vector2Int[] GetActionPoints(Vector2Int curXY, Vector3 worldPos) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) int x = ((Vector2Int)(ref curXY)).x; int y = ((Vector2Int)(ref curXY)).y; List<Vector2Int> list = new List<Vector2Int> { curXY }; if (Vector2Int.op_Implicit(lastFissureXY) != Vector2.zero) { if (((Vector2Int)(ref lastFissureXY)).x == ((Vector2Int)(ref curXY)).x && ((Vector2Int)(ref lastFissureXY)).y == ((Vector2Int)(ref curXY)).y) { if (Mathf.Abs(worldPos.x - lastWorldPos.x) > Mathf.Abs(worldPos.y - lastWorldPos.y)) { x = ((worldPos.x > lastWorldPos.x) ? (x + 1) : (x - 1)); list.Add(new Vector2Int(x, ((Vector2Int)(ref curXY)).y)); y = ((worldPos.y > lastWorldPos.y) ? (y + 1) : (y - 1)); list.Add(new Vector2Int(((Vector2Int)(ref curXY)).x, y)); } } else if (((Vector2Int)(ref lastFissureXY)).x != ((Vector2Int)(ref curXY)).x && ((Vector2Int)(ref lastFissureXY)).y != ((Vector2Int)(ref curXY)).y) { list.Add(new Vector2Int(((Vector2Int)(ref lastFissureXY)).x, ((Vector2Int)(ref curXY)).y)); list.Add(new Vector2Int(((Vector2Int)(ref curXY)).x, ((Vector2Int)(ref lastFissureXY)).y)); } else if (((Vector2Int)(ref lastFissureXY)).x == ((Vector2Int)(ref curXY)).x) { x = ((worldPos.x > lastWorldPos.x) ? (x + 1) : (x - 1)); list.Add(new Vector2Int(x, ((Vector2Int)(ref curXY)).y)); } else if (((Vector2Int)(ref lastFissureXY)).y == ((Vector2Int)(ref curXY)).y) { y = ((worldPos.y > lastWorldPos.y) ? (y + 1) : (y - 1)); list.Add(new Vector2Int(((Vector2Int)(ref curXY)).x, y)); } } return list.ToArray(); } private static float RestrictedRandomDirection(CrossPlatformRandom random) { float num = random.Range(5f, 40f); return (float)(int)random.Range(0, 9) * 45f + num; } public static float GetDogLegDirection(float angle, CrossPlatformRandom random) { return (angle + 180f + random.Range(15f, 35f)) % 360f; } private static bool CreateFissure(Heightmap hm) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) Log.Debug("CreateFissure"); bool result = true; float num = Cfg.fissureMaxDepth.Value; CrossPlatformRandom crossPlatformRandom = new CrossPlatformRandom(GetSeedFromHeightmap(hm)); if (crossPlatformRandom.value * 100f > Cfg.faultChance.Value) { Log.Debug("No fault line in current zone"); return result; } if (FissureExists(hm, ((Bounds)(ref hm.m_bounds)).center)) { num *= Cfg.fissureDeepenPct.Value; Log.Debug("Fissure already exists. Using percentage of max depth."); } if (fissure_vfx == null) { fissure_vfx = Utils.GetPrefab("vfx_Place_mud_road"); } if (cracking_sfx == null) { cracking_sfx = Utils.GetPrefab("sfx_stonegolem_attack_hit"); } float num2 = RestrictedRandomDirection(crossPlatformRandom); float num3 = GetDogLegDirection(num2, crossPlatformRandom); Vector3 center = ((Bounds)(ref hm.m_bounds)).center; int num4 = default(int); int num5 = default(int); hm.WorldToVertex(center, ref num4, ref num5); float num6 = Mathf.Min((float)hm.m_width * crossPlatformRandom.Range(0.7f, 0.9f), (float)Cfg.earthquakeRadius.Value); float num7 = fissureSpacing; int num8 = Mathf.CeilToInt(num6 / 4f / num7); Vector3 val = center; Vector3 val2 = center; float num9 = 0f; List<Vector3> list = new List<Vector3>(); List<Vector3> list2 = new List<Vector3>(); list.Add(center); int num10 = 0; int num11 = 1; int num12 = 1; while (num9 < num6) { float num13 = num7; float num14 = num7; Vector3 val3 = val + Quaternion.Euler(0f, num3, 0f) * Vector3.forward * num13; Vector3 val4 = val2 + Quaternion.Euler(0f, num2, 0f) * Vector3.forward * num14; num9 += num13 + num14; num11 += 2; list.Add(val3); list2.Add(val4); val = val3; val2 = val4; if (++num10 % num8 == 0) { num3 += crossPlatformRandom.Range(20, 30) * (float)(-num12); num2 += crossPlatformRandom.Range(20, 30) * (float)num12; num12 = -num12; } } list2.Reverse(); list2.AddRange(list); Vector3[] tpa = list2.ToArray(); ((MonoBehaviour)_modInstance).StartCoroutine(_modInstance.Co_ModifyTerrain(tpa, center, fissureRadius, num, num11, 2f)); return result; } public static float GraduatedDepth(int nbrSegments, int seg, float depth) { float num = (float)nbrSegments / 2f; float num2 = Mathf.Abs((float)seg - num) / num; return depth * (1f - num2); } private IEnumerator Co_ModifyTerrain(Vector3[] tpa, Vector3 epicenter, float radius, float depth, int nbrSegments, float delay) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Log.Debug("Co_ModifyTerrain"); if (IsShaking()) { yield return