Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Haunted v0.1.4
Haunted.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; 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.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Haunted")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Haunted")] [assembly: AssemblyCopyright("Copyright © 2023")] [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; 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 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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) { if (ServerValue != null) { ((ConfigEntryBase)_entry).SetSerializedValue(ServerValue); } } else { 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; } 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), "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>)RPC_ClientConfigReceiver); Log.Debug("PlayerChoice registered RPC_ClientConfigReceiver"); return; } catch (Exception) { Log.Warning("Failed to register RPC"); return; } } try { 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 static bool IsSetup = false; 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 static void RPC_ClientConfigReceiver(ZRpc zrpc, ZPackage package) { if (!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); } } } internal static 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 static void SendConfigToClient(ZNetPeer peer) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if (!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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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 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<bool> ghostAttacks = null; public static DelegatedConfigEntry<bool> despawnInDay = null; public static DelegatedConfigEntry<int> patrolRadius = null; public static DelegatedConfigEntry<Haunted.Spirit> typeOfSpirit = null; public static DelegatedConfigEntry<int> numberOfBats = null; public static DelegatedConfigEntry<bool> addBatsToSpirit = null; public static DelegatedConfigEntry<KeyboardShortcut> summonGhostKey = null; public static DelegatedConfigEntry<Logging.LogLevels> debugLevel = null; private static KeyCode[] keyModifiers = (KeyCode[])(object)new KeyCode[2] { (KeyCode)308, (KeyCode)304 }; public static KeyboardShortcut keyConfigItemDefault = new KeyboardShortcut((KeyCode)103, keyModifiers); public static void BepInExConfig(BaseUnityPlugin _instance) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Expected O, but got Unknown //IL_0190: Unknown result type (might be due to invalid IL or missing references) debugLevel = new DelegatedConfigEntry<Logging.LogLevels>(ChangeLogging); debugLevel.ConfigEntry = _instance.Config.Bind<Logging.LogLevels>("Utility", "LogLevel", Logging.LogLevels.Info, "Controls the level of information contained in the log"); Logging.GetLogger().LogLevel = debugLevel.Value; typeOfSpirit = new DelegatedConfigEntry<Haunted.Spirit>(); typeOfSpirit.ConfigEntry = _instance.Config.Bind<Haunted.Spirit>("Summonning", "Spirit to Summon", Haunted.Spirit.Wraith, "Controls the type of spirit to summon."); numberOfBats = new DelegatedConfigEntry<int>(); numberOfBats.ConfigEntry = _instance.Config.Bind<int>("Summonning", "Number of Bats to add to summon", 0, new ConfigDescription("Sets the number of companion Bats to summon in addition to the summoned spirit.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5), Array.Empty<object>())); ghostAttacks = new DelegatedConfigEntry<bool>(useServerDelegate: true); ghostAttacks.ConfigEntry = _instance.Config.Bind<bool>("Behavior", "Attack Enemies", false, "If enabled, the summoned spirit actively attacks and attracts enemies. If disabled the spirit ignores and is ignored by enemies."); despawnInDay = new DelegatedConfigEntry<bool>(ChangeGhostDespawn, useServerDelegate: true); despawnInDay.ConfigEntry = _instance.Config.Bind<bool>("Behavior", "Despawn in Daytime", true, "If enabled, the spirit will automatically despawn in the day and return at night and you cannot summon the spirit during the day."); patrolRadius = new DelegatedConfigEntry<int>(); patrolRadius.ConfigEntry = _instance.Config.Bind<int>("Behavior", "Patrol Radius", 15, new ConfigDescription("The distance the spirit will wander when set to stay in one area.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 50), Array.Empty<object>())); summonGhostKey = new DelegatedConfigEntry<KeyboardShortcut>(); summonGhostKey.ConfigEntry = _instance.Config.Bind<KeyboardShortcut>("Keys", "Summon & Dispel Spirit", keyConfigItemDefault, "Press this key to summon or dismiss the tamed spirit. You can only have one spirit active at a time. You need to be near the Spirit to dispel it."); } public static void ChangeLogging(object s, EventArgs e) { Logging logger = Logging.GetLogger(); SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null); logger.Debug($"ChangeLog {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}"); logger.LogLevel = debugLevel.Value; } public static void ChangeGhostDespawn(object s, EventArgs e) { Logging logger = Logging.GetLogger(); SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null); logger.Debug($"ChangeLog {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}"); if (EnvMan.IsDaylight()) { if (despawnInDay.Value) { Haunted.DeactivateHaunts(); } else { Haunted.ActivateHaunts(); } } } } [BepInPlugin("neobotics.valheim_mod.haunted", "Haunted", "0.1.4")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public class Haunted : BaseUnityPlugin { public enum Spirit { Ghost, Wraith, Bat, Skeleton } [HarmonyPatch(typeof(EnvMan), "OnMorning")] private static class EnvMan_OnMorning_Patch { [HarmonyPostfix] private static void EnvMan_OnMorning_Postfix(EnvMan __instance) { if (ZNet.instance.IsServer()) { Log.Debug("EnvMan_OnMorning_Patch_Postfix"); if (Cfg.despawnInDay.Value) { DeactivateHaunts(); } } } } [HarmonyPatch(typeof(EnvMan), "OnEvening")] private static class EnvMan_OnEvening_Patch { [HarmonyPostfix] private static void EnvMan_OnEvening_Postfix(EnvMan __instance) { if (ZNet.instance.IsServer()) { Log.Debug("EnvMan_OnEvening_Patch_Postfix"); ActivateHaunts(); } } } [HarmonyPatch(typeof(Tameable), "UpdateSavedFollowTarget")] private static class Tameable_UpdateSavedFollowTarget_Patch { [HarmonyPostfix] private static void Tameable_UpdateSavedFollowTarget_Prefix(Tameable __instance) { //IL_002f: 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) //IL_0064: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); if ((Object)(object)__instance != (Object)null && !((BaseAI)__instance.m_monsterAI).m_aggravated && __instance.m_nview.m_zdo.GetVec3(SPIRIT_FLAG, ref val) && Vector3.Distance(val, ((Component)__instance).gameObject.transform.position) > (float)Cfg.patrolRadius.Value) { __instance.m_monsterAI.SetFollowTarget((GameObject)null); ((BaseAI)__instance.m_monsterAI).SetPatrolPoint(val); __instance.m_nview.m_zdo.Set(ZDOVars.s_follow, string.Empty); } } } [HarmonyPatch(typeof(EnemyHud), "TestShow")] private static class EnemyHud_TestShow_Patch { [HarmonyPostfix] private static void EnemyHud_TestShow_Postfix(EnemyHud __instance, Character c, bool isVisible, ref bool __result) { if (!((Behaviour)c).isActiveAndEnabled) { __result = false; } } } [HarmonyPatch(typeof(BaseAI), "IsEnemy", new Type[] { typeof(Character), typeof(Character) })] private static class BaseAI_IsEnemy_Patch { [HarmonyPostfix] private static void BaseAI_IsEnemy_Postfix(BaseAI __instance, Character a, Character b, ref bool __result) { if (!Cfg.ghostAttacks.Value && ((a.m_tamed && hauntNames.Contains(a.m_name)) || (b.m_tamed && hauntNames.Contains(((Object)b).name)))) { __result = false; } } } [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 && OkToKey(__instance) && Cfg.summonGhostKey.IsKeyPressed()) { SummonAndDispelHaunt(); } } } [HarmonyPatch(typeof(ZNetScene), "CreateObject")] private static class ZNetScene_CreateObject_Patch { [HarmonyPostfix] private static void ZNetScene_CreateObject_Postfix(ZNetScene __instance, ZDO zdo, ref GameObject __result) { if (!prefabHashes.Contains(zdo.m_prefab) || !zdo.GetBool(ZDOVars.s_tamed, false)) { return; } Log.Debug("Creating tamed Haunt"); bool flag = zdo.m_prefab == prefabKeys[Spirit.Bat]; bool flag2 = zdo.m_prefab == prefabKeys[Spirit.Skeleton]; Vector3 val = default(Vector3); bool vec = zdo.GetVec3(SPIRIT_FLAG, ref val); if ((Object)(object)__result.GetComponent<Tameable>() == (Object)null) { __result.AddComponent<Tameable>().m_commandable = ((!flag || vec) ? true : false); } if (vec) { if (flag) { SetUpGiantBat(__result); } if (flag2) { SetUpGiantSkeleton(__result); } } SetUpHaunt(__result); MonsterAI val2 = default(MonsterAI); if (EnvMan.IsDaylight() && Cfg.despawnInDay.Value && __result.TryGetComponent<MonsterAI>(ref val2)) { ((BaseAI)val2).m_idleSoundChance = 0f; } } } private static Haunted _modInstance; private static string Mod = "Haunted"; private static string LcMod = Mod.ToLower(); public static Logging Log; public static Faction tamedGhostFaction = (Faction)StringExtensionMethods.GetStableHashCode("TamedGhost"); public static int SPIRIT_FLAG = StringExtensionMethods.GetStableHashCode("Haunted_Spirit"); private static Dictionary<Spirit, int> prefabKeys = new Dictionary<Spirit, int> { { Spirit.Wraith, StringExtensionMethods.GetStableHashCode("Wraith") }, { Spirit.Ghost, StringExtensionMethods.GetStableHashCode("Ghost") }, { Spirit.Bat, StringExtensionMethods.GetStableHashCode("Bat") }, { Spirit.Skeleton, StringExtensionMethods.GetStableHashCode("Skeleton") } }; private static Dictionary<int, string> prefabNames = new Dictionary<int, string> { { prefabKeys[Spirit.Wraith], "Wraith" }, { prefabKeys[Spirit.Ghost], "Ghost" }, { prefabKeys[Spirit.Bat], "Bat" }, { prefabKeys[Spirit.Skeleton], "Skeleton" } }; private static List<int> prefabHashes = new List<int>(); private static List<string> hauntNames = new List<string> { "$enemy_ghost", "$enemy_wraith", "$enemy_bat" }; private static List<ItemDrop> foodList = new List<ItemDrop>(); private static Dictionary<string, ItemDrop> foodItems = new Dictionary<string, ItemDrop>(); private static Harmony harmony = null; public static Haunted 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()); foreach (Spirit key in prefabKeys.Keys) { prefabHashes.Add(prefabKeys[key]); } ConfigureMod(); Log.Info("Awake"); } private void ConfigureMod() { Log = Logging.GetLogger(Logging.LogLevels.Info, Mod); ServerConfiguration.Instance.Setup(((BaseUnityPlugin)this).Config, (BaseUnityPlugin)(object)_modInstance); Cfg.BepInExConfig((BaseUnityPlugin)(object)_modInstance); ServerConfiguration.Instance.CreateConfigWatcher(); } private void OnDestroy() { harmony.UnpatchSelf(); } private static bool OkToKey(Player player) { if (!Chat.instance.HasFocus() && !Console.IsVisible() && (Object)(object)TextViewer.instance != (Object)null && !TextViewer.instance.IsVisible() && !GameCamera.InFreeFly() && !Minimap.IsOpen() && !TextInput.IsVisible() && !StoreGui.IsVisible() && !((Character)player).InCutscene() && !((Character)player).InBed() && !((Character)player).IsTeleporting() && !((Character)player).IsDead()) { return !((Character)player).InPlaceMode(); } return false; } public static bool GetAllTamedZDOsWithPrefab(List<int> prefabHashes, List<ZDO> zdos) { foreach (ZDO value in ZDOMan.instance.m_objectsByID.Values) { if (value.IsValid() && prefabHashes.Contains(value.GetPrefab()) && value.GetBool(ZDOVars.s_tamed, false)) { zdos.Add(value); } } return zdos.Count > 0; } public static void ActivateHaunts() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) List<ZDO> list = new List<ZDO>(); GetAllTamedZDOsWithPrefab(prefabKeys.Values.ToList(), list); MonsterAI val2 = default(MonsterAI); foreach (ZDO item in list) { if (!ZNetScene.instance.HaveInstance(item)) { continue; } GameObject val = ZNetScene.instance.FindInstance(item.m_uid); if (!val.activeInHierarchy) { val.SetActive(true); if (val.TryGetComponent<MonsterAI>(ref val2)) { ((BaseAI)val2).m_idleSoundChance = 0.5f; } } } } public static void DeactivateHaunts() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) List<ZDO> list = new List<ZDO>(); GetAllTamedZDOsWithPrefab(prefabKeys.Values.ToList(), list); MonsterAI val2 = default(MonsterAI); foreach (ZDO item in list) { if (!ZNetScene.instance.HaveInstance(item)) { continue; } GameObject val = ZNetScene.instance.FindInstance(item.m_uid); if (val.activeInHierarchy) { if (val.TryGetComponent<MonsterAI>(ref val2)) { ((BaseAI)val2).m_idleSoundChance = 0f; } val.SetActive(false); } } } private static void SetUpHaunt(GameObject haunt) { //IL_012c: Unknown result type (might be due to invalid IL or missing references) Log.Debug("SetUpHaunt"); Character component = haunt.GetComponent<Character>(); MonsterAI component2 = haunt.GetComponent<MonsterAI>(); Tameable tameable = default(Tameable); if (haunt.TryGetComponent<Tameable>(ref tameable)) { component.m_tameable = tameable; component.m_tameableMonsterAI = component2; foodList.Clear(); ItemDrop iDrop = null; string name = component.m_name; if (!(name == "$enemy_bat")) { if (name == "$enemy_skeleton") { if (TryGetFoodItems("BoneFragments", out iDrop)) { foodList.Add(iDrop); } if (TryGetFoodItems("WitheredBone", out iDrop)) { foodList.Add(iDrop); } } else if (TryGetFoodItems("Wisp", out iDrop)) { foodList.Add(iDrop); } } else { if (TryGetFoodItems("Bloodbag", out iDrop)) { foodList.Add(iDrop); } if (TryGetFoodItems("GiantBloodSack", out iDrop)) { foodList.Add(iDrop); } } component2.m_consumeItems = foodList; } component.SetTamed(true); ((BaseAI)component2).m_randomMoveRange = Cfg.patrolRadius.Value; ((BaseAI)component2).m_randomMoveInterval = 3f; ((BaseAI)component2).SetPatrolPoint(); component.m_damageModifiers.m_fire = (DamageModifier)3; component.m_tolerateSmoke = true; CharacterDrop val = default(CharacterDrop); if (haunt.TryGetComponent<CharacterDrop>(ref val)) { Object.Destroy((Object)(object)val); } if (Cfg.despawnInDay.Value && EnvMan.IsDaylight()) { haunt.SetActive(false); } } private static bool TryGetFoodItems(string foodName, out ItemDrop iDrop) { if (!foodItems.TryGetValue(foodName, out iDrop)) { GameObject prefab = Utils.GetPrefab(foodName); if ((Object)(object)prefab != (Object)null && prefab.TryGetComponent<ItemDrop>(ref iDrop)) { foodItems.Add(foodName, iDrop); } } return !((Object)(object)iDrop == (Object)null); } public static bool TryGetHauntInScene(ZDO zdo, out GameObject haunt) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) Log.Debug("TryGetHauntInScene"); haunt = null; if (ZNetScene.instance.HaveInstance(zdo)) { Log.Debug("Haunt has an instance"); haunt = ZNetScene.instance.FindInstance(zdo.m_uid); if ((Object)(object)haunt != (Object)null) { Log.Debug("Found Haunt instance in scene"); return true; } } return false; } public static bool TryGetMyHauntedZDOs(List<ZDO> haunts) { Log.Debug("TryGetMyHauntedZDOs"); haunts.Clear(); List<ZDO> list = new List<ZDO>(); Log.Debug("Searching for tamed Haunt ZDOs"); GetAllTamedZDOsWithPrefab(prefabKeys.Values.ToList(), list); string name = Game.instance.GetPlayerProfile().GetName(); if (name != null) { foreach (ZDO item in list) { if (item.GetString(ZDOVars.s_ownerName, "") == name) { Log.Debug("Found bound Haunt ZDO"); haunts.Add(item); } } } return haunts.Count > 0; } private static void SummonAndDispelHaunt() { //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: 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_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: 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_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_011d: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; Log.Debug("SummonAndDispelHaunt"); string text = string.Empty; List<ZDO> list = new List<ZDO>(); if (TryGetMyHauntedZDOs(list)) { Vector3 val = default(Vector3); Tameable val2 = default(Tameable); foreach (ZDO item in list) { if (item.GetVec3(SPIRIT_FLAG, ref val)) { Vector3 position = item.m_position; if (TryGetHauntInScene(item, out var haunt) && haunt.TryGetComponent<Tameable>(ref val2)) { text = val2.GetHoverName(); Log.Debug("Dispelling " + text + " in scene"); Object.Instantiate<GameObject>(Utils.GetPrefab("vfx_odin_despawn"), position + new Vector3(0f, 1f, 0f), Quaternion.identity); } else { Log.Debug("Dispelling Haunt not in scene"); text = prefabNames[item.m_prefab]; } } } Object.Instantiate<GameObject>(Utils.GetPrefab("sfx_dverger_heal_finish"), ((Component)Player.m_localPlayer).transform.position, Quaternion.identity); ((Character)localPlayer).Message((MessageType)2, Localization.instance.Localize("Dispelled " + text), 0, (Sprite)null); Log.Debug("Destroying all player's summoned creatures"); SendAllDestroyed(list); return; } Log.Debug("Summoning Haunt"); string name = Game.instance.GetPlayerProfile().GetName(); if (Cfg.despawnInDay.Value && EnvMan.IsDaylight()) { Log.Debug("Summon failed due to daylight configuration"); ((Character)localPlayer).Message((MessageType)2, "You can't do that right now", 0, (Sprite)null); return; } Vector3 val3 = ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward * 2f; List<Piece> list2 = new List<Piece>(); Piece.GetAllPiecesInRadius(((Component)localPlayer).transform.position, 20f, list2); if (list2.Count < 20) { Log.Debug("Summon failed due to base size or distance"); ((Character)localPlayer).Message((MessageType)2, "You need to be closer to a large enough base to haunt", 0, (Sprite)null); return; } GameObject val4 = Object.Instantiate<GameObject>(Utils.GetPrefabByHash(prefabKeys[Cfg.typeOfSpirit.Value]), val3, Quaternion.identity); Transform transform = val4.transform; transform.rotation *= Quaternion.Euler(0f, 180f, 0f); Character val5 = default(Character); if (val4.TryGetComponent<Character>(ref val5)) { text = val5.m_name; } Tameable val6 = default(Tameable); if (!val4.TryGetComponent<Tameable>(ref val6)) { Log.Debug("Adding Tameable to Haunt"); val6 = val4.AddComponent<Tameable>(); } val6.m_commandable = true; ZDO zdo = val4.GetComponent<ZNetView>().m_zdo; zdo.Set(SPIRIT_FLAG, val3); zdo.Set(ZDOVars.s_ownerName, name); ZDOMan.instance.ForceSendZDO(zdo.m_uid); if (zdo.m_prefab == prefabKeys[Spirit.Bat]) { SetUpGiantBat(val4); } if (zdo.m_prefab == prefabKeys[Spirit.Skeleton]) { SetUpGiantSkeleton(val4); } SetUpHaunt(val4); Object.Instantiate<GameObject>(Utils.GetPrefab("vfx_spawn_small"), val3, Quaternion.identity); Object.Instantiate<GameObject>(Utils.GetPrefab("sfx_dverger_heal_start"), val3, Quaternion.identity); ((Character)localPlayer).Message((MessageType)2, Localization.instance.Localize("Summoned " + text), 0, (Sprite)null); AddExtraBats(Cfg.numberOfBats.Value); } private static void SetUpGiantBat(GameObject haunt, bool resize = true) { //IL_000a: 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_0023: 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) if (resize) { Transform transform = haunt.transform; transform.localScale += new Vector3(1.5f, 1.5f, 1.5f); } SkinnedMeshRenderer componentInChildren = haunt.GetComponentInChildren<SkinnedMeshRenderer>(); if ((Object)(object)componentInChildren != (Object)null) { ((Renderer)componentInChildren).material.color = new Color(0.1f, 0f, 0.1f); } } private static void SetUpGiantSkeleton(GameObject haunt, bool resize = true) { //IL_000a: 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_0023: Unknown result type (might be due to invalid IL or missing references) if (resize) { Transform transform = haunt.transform; transform.localScale += new Vector3(0.6f, 0.5f, 0.5f); } } private static void AddExtraBats(int number) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) Log.Debug("AddExtraBats"); Player localPlayer = Player.m_localPlayer; string name = Game.instance.GetPlayerProfile().GetName(); if (number <= 0) { return; } GameObject val = null; Vector3 val2 = ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward * 2f; GameObject prefabByHash = Utils.GetPrefabByHash(prefabKeys[Spirit.Bat]); Tameable val3 = default(Tameable); Character val4 = default(Character); for (int i = 0; i < number; i++) { val = Object.Instantiate<GameObject>(prefabByHash, val2, Quaternion.identity); Transform transform = val.transform; transform.rotation *= Quaternion.Euler(0f, 180f, 0f); if (!val.TryGetComponent<Tameable>(ref val3)) { Log.Debug("Adding Tameable to Haunt"); val3 = val.AddComponent<Tameable>(); } val3.m_commandable = false; ZDO zdo = val.GetComponent<ZNetView>().m_zdo; zdo.Set(ZDOVars.s_ownerName, name); ZDOMan.instance.ForceSendZDO(zdo.m_uid); Log.Debug("Adding Bat"); if (val.TryGetComponent<Character>(ref val4)) { SetUpHaunt(val); } } } private static void SendOneDestroyed(ZDOID zdoid) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_000e: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(1); val.Write(zdoid); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "DestroyZDO", new object[1] { val }); } private static void SendAllDestroyed(List<ZDO> zdos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(zdos.Count); foreach (ZDO zdo in zdos) { val.Write(zdo.m_uid); } ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "DestroyZDO", new object[1] { val }); } private static void RandomFollowStay() { } }