Please disclose if any significant portion of your mod was created 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 Ravenwood Crystals v2.0.4
plugins/RavenwoodCrystals/RavenwoodCrystals.dll
Decompiled a week 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 BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("RavenwoodCrystals")] [assembly: AssemblyDescription("Ravenwood Crystals Mod")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Ravenwood")] [assembly: AssemblyProduct("RavenwoodCrystals")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("8ad799d2-7e36-4098-b363-92c0f7924b6a")] [assembly: AssemblyFileVersion("1.0.1")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.1.0")] namespace Ravenwood.Crystals; public class CrystalBreakVisual : MonoBehaviour { [CompilerGenerated] private sealed class <ForceBreakRoutine>d__9 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float totalDuration; public CrystalBreakVisual <>4__this; private float <stepDelay>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ForceBreakRoutine>d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (<>4__this.parts.Count == 0) { return false; } <stepDelay>5__1 = ((totalDuration <= 0f) ? 0f : (totalDuration / (float)Mathf.Max(1, <>4__this.parts.Count))); break; case 1: <>1__state = -1; break; case 2: <>1__state = -1; break; } if (<>4__this.currentIndex < <>4__this.parts.Count) { <>4__this.RemoveOneChunk(); if (<stepDelay>5__1 <= 0f) { <>2__current = null; <>1__state = 1; return true; } <>2__current = (object)new WaitForSeconds(<stepDelay>5__1); <>1__state = 2; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private readonly List<GameObject> parts = new List<GameObject>(); private int currentIndex = 0; private float lastHealth; private bool forceBreaking; private WearNTear wear; private void Awake() { Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if ((Object)(object)val != (Object)(object)((Component)this).transform) { parts.Add(((Component)val).gameObject); } } for (int j = 0; j < parts.Count; j++) { int index = Random.Range(j, parts.Count); GameObject value = parts[j]; parts[j] = parts[index]; parts[index] = value; } wear = ((Component)this).GetComponent<WearNTear>(); if ((Object)(object)wear != (Object)null) { lastHealth = wear.m_health; } } private void Update() { if (!forceBreaking) { if ((Object)(object)wear == (Object)null) { wear = ((Component)this).GetComponent<WearNTear>(); } else if (wear.m_health < lastHealth) { RemoveOneChunk(); lastHealth = wear.m_health; } } } public void ForceBreak(float totalDuration = 0.28f) { if (!forceBreaking) { forceBreaking = true; ((MonoBehaviour)this).StartCoroutine(ForceBreakRoutine(totalDuration)); } } public void ForceBreakImmediate() { if (!forceBreaking) { forceBreaking = true; while (currentIndex < parts.Count) { RemoveOneChunk(); } } } [IteratorStateMachine(typeof(<ForceBreakRoutine>d__9))] private IEnumerator ForceBreakRoutine(float totalDuration) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ForceBreakRoutine>d__9(0) { <>4__this = this, totalDuration = totalDuration }; } private void RemoveOneChunk() { if (currentIndex < parts.Count) { if ((Object)(object)parts[currentIndex] != (Object)null) { parts[currentIndex].SetActive(false); } currentIndex++; } } } public static class CrystalConfigFile { public sealed class CrystalDefinition { public string PrefabName; public string DefaultDropItem; public int DefaultDropMin; public int DefaultDropMax; public bool IsRavenCrystal; public ConfigEntry<string> DropItem; public ConfigEntry<int> DropMin; public ConfigEntry<int> DropMax; public ConfigEntry<string>[] RavenDropItems = new ConfigEntry<string>[4]; public ConfigEntry<int>[] RavenDropMins = new ConfigEntry<int>[4]; public ConfigEntry<int>[] RavenDropMaxs = new ConfigEntry<int>[4]; } private const int RavenDropSlotCount = 4; private static readonly List<CrystalDefinition> CrystalDefinitions = new List<CrystalDefinition>(); public static IReadOnlyList<CrystalDefinition> Definitions => CrystalDefinitions; public static void Initialize(ConfigFile configFile) { if (configFile != null) { BuildCrystalDefinitions(); BindCrystalConfigs(configFile); } } public static void BuildCrystalDefinitions() { if (CrystalDefinitions.Count <= 0) { CrystalDefinitions.Add(CreateCrystalDefinition("Poison_Crystal_Small", "Essence_Poison", 2, 2, isRavenCrystal: false)); CrystalDefinitions.Add(CreateCrystalDefinition("Poison_Crystal", "Essence_Poison", 5, 5, isRavenCrystal: false)); CrystalDefinitions.Add(CreateCrystalDefinition("Poison_Crystal_Large", "Essence_Poison", 10, 10, isRavenCrystal: false)); CrystalDefinitions.Add(CreateCrystalDefinition("Frost_Crystal_Small", "Essence_Frost", 2, 2, isRavenCrystal: false)); CrystalDefinitions.Add(CreateCrystalDefinition("Frost_Crystal", "Essence_Frost", 5, 5, isRavenCrystal: false)); CrystalDefinitions.Add(CreateCrystalDefinition("Frost_Crystal_Large", "Essence_Frost", 10, 10, isRavenCrystal: false)); CrystalDefinitions.Add(CreateCrystalDefinition("Fire_Crystal_Small", "Essence_Fire", 2, 2, isRavenCrystal: false)); CrystalDefinitions.Add(CreateCrystalDefinition("Fire_Crystal", "Essence_Fire", 5, 5, isRavenCrystal: false)); CrystalDefinitions.Add(CreateCrystalDefinition("Fire_Crystal_Large", "Essence_Fire", 10, 10, isRavenCrystal: false)); CrystalDefinitions.Add(CreateCrystalDefinition("Lightning_Crystal_Small", "Essence_Lightning", 2, 2, isRavenCrystal: false)); CrystalDefinitions.Add(CreateCrystalDefinition("Lightning_Crystal", "Essence_Lightning", 5, 5, isRavenCrystal: false)); CrystalDefinitions.Add(CreateCrystalDefinition("Lightning_Crystal_Large", "Essence_Lightning", 10, 10, isRavenCrystal: false)); CrystalDefinitions.Add(CreateCrystalDefinition("Raven_Crystal_Small", string.Empty, 2, 2, isRavenCrystal: true)); CrystalDefinitions.Add(CreateCrystalDefinition("Raven_Crystal", string.Empty, 3, 3, isRavenCrystal: true)); CrystalDefinitions.Add(CreateCrystalDefinition("Raven_Crystal_Large", string.Empty, 5, 5, isRavenCrystal: true)); } } private static CrystalDefinition CreateCrystalDefinition(string prefabName, string defaultDropItem, int defaultDropMin, int defaultDropMax, bool isRavenCrystal) { CrystalDefinition crystalDefinition = new CrystalDefinition(); crystalDefinition.PrefabName = prefabName; crystalDefinition.DefaultDropItem = defaultDropItem; crystalDefinition.DefaultDropMin = defaultDropMin; crystalDefinition.DefaultDropMax = defaultDropMax; crystalDefinition.IsRavenCrystal = isRavenCrystal; return crystalDefinition; } private static void BindCrystalConfigs(ConfigFile config) { for (int i = 0; i < CrystalDefinitions.Count; i++) { CrystalDefinition crystalDefinition = CrystalDefinitions[i]; string text = "Crystal." + crystalDefinition.PrefabName; if (!crystalDefinition.IsRavenCrystal) { crystalDefinition.DropItem = config.Bind<string>(text, "DropItem", crystalDefinition.DefaultDropItem, "Drop item prefab for " + crystalDefinition.PrefabName + "."); crystalDefinition.DropMin = config.Bind<int>(text, "DropMin", crystalDefinition.DefaultDropMin, "Minimum drop amount for " + crystalDefinition.PrefabName + "."); crystalDefinition.DropMax = config.Bind<int>(text, "DropMax", crystalDefinition.DefaultDropMax, "Maximum drop amount for " + crystalDefinition.PrefabName + "."); continue; } for (int j = 0; j < 4; j++) { string text2 = string.Empty; if (j == 0) { text2 = "Essence_Poison"; } if (j == 1) { text2 = "Essence_Frost"; } if (j == 2) { text2 = "Essence_Fire"; } if (j == 3) { text2 = "Essence_Lightning"; } crystalDefinition.RavenDropItems[j] = config.Bind<string>(text, "Drop" + (j + 1) + "Item", text2, "Drop item prefab for Raven drop slot " + (j + 1) + " on " + crystalDefinition.PrefabName + ". Leave blank to disable the slot."); crystalDefinition.RavenDropMins[j] = config.Bind<int>(text, "Drop" + (j + 1) + "Min", crystalDefinition.DefaultDropMin, "Minimum drop amount for Raven drop slot " + (j + 1) + " on " + crystalDefinition.PrefabName + "."); crystalDefinition.RavenDropMaxs[j] = config.Bind<int>(text, "Drop" + (j + 1) + "Max", crystalDefinition.DefaultDropMax, "Maximum drop amount for Raven drop slot " + (j + 1) + " on " + crystalDefinition.PrefabName + "."); } } } public static List<CrystalDropEntry> BuildDropEntries(CrystalDefinition crystal) { List<CrystalDropEntry> list = new List<CrystalDropEntry>(); if (crystal == null) { return list; } if (crystal.IsRavenCrystal) { for (int i = 0; i < 4; i++) { string text = ((crystal.RavenDropItems[i] != null) ? crystal.RavenDropItems[i].Value : string.Empty); if (!string.IsNullOrWhiteSpace(text)) { int num = ((crystal.RavenDropMins[i] != null) ? crystal.RavenDropMins[i].Value : crystal.DefaultDropMin); int num2 = ((crystal.RavenDropMaxs[i] != null) ? crystal.RavenDropMaxs[i].Value : crystal.DefaultDropMax); num = Mathf.Max(0, num); num2 = Mathf.Max(num, num2); list.Add(new CrystalDropEntry(text, num, num2)); } } return list; } int num3 = ((crystal.DropMin != null) ? crystal.DropMin.Value : crystal.DefaultDropMin); int num4 = ((crystal.DropMax != null) ? crystal.DropMax.Value : crystal.DefaultDropMax); num3 = Mathf.Max(0, num3); num4 = Mathf.Max(num3, num4); string text2 = ((crystal.DropItem != null) ? crystal.DropItem.Value : crystal.DefaultDropItem); if (!string.IsNullOrWhiteSpace(text2)) { list.Add(new CrystalDropEntry(text2, num3, num4)); } return list; } public static CrystalDefinition FindCrystalDefinition(string prefabName) { for (int i = 0; i < CrystalDefinitions.Count; i++) { CrystalDefinition crystalDefinition = CrystalDefinitions[i]; if (crystalDefinition != null && string.Equals(crystalDefinition.PrefabName, prefabName, StringComparison.Ordinal)) { return crystalDefinition; } } return null; } } public sealed class CrystalDropEntry { public string ItemName; public int Min; public int Max; public CrystalDropEntry(string itemName, int min, int max) { ItemName = itemName; Min = min; Max = max; } } public class CrystalHoverText : MonoBehaviour, Hoverable { private string hoverName; private void Awake() { EnsureHoverName(); } public void Configure(string prefabName) { hoverName = BuildHoverName(prefabName); } public string GetHoverText() { EnsureHoverName(); string text = (string.IsNullOrWhiteSpace(hoverName) ? "Crystal" : hoverName); return text + "\n[<color=yellow><b>E</b></color>] Pick up"; } public string GetHoverName() { EnsureHoverName(); return string.IsNullOrWhiteSpace(hoverName) ? "Crystal" : hoverName; } private void EnsureHoverName() { if (string.IsNullOrWhiteSpace(hoverName)) { string text = (((Object)(object)((Component)this).gameObject != (Object)null) ? ((Object)((Component)this).gameObject).name : string.Empty); if (!string.IsNullOrWhiteSpace(text) && text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - "(Clone)".Length).Trim(); } hoverName = BuildHoverName(text); } } private static string BuildHoverName(string prefabName) { if (string.IsNullOrWhiteSpace(prefabName)) { return "Crystal"; } string[] array = prefabName.Split(new char[1] { '_' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length == 0) { return "Crystal"; } string text = "Medium"; List<string> list = new List<string>(); foreach (string text2 in array) { if (string.Equals(text2, "Small", StringComparison.OrdinalIgnoreCase)) { text = "Small"; } else if (string.Equals(text2, "Large", StringComparison.OrdinalIgnoreCase)) { text = "Large"; } else if (!string.Equals(text2, "Crystal", StringComparison.OrdinalIgnoreCase) && !string.Equals(text2, "Regrow", StringComparison.OrdinalIgnoreCase)) { list.Add(UppercaseFirst(text2)); } } if (list.Count == 0) { return text + " Crystal"; } return text + " " + string.Join(" ", list.ToArray()) + " Crystal"; } private static string UppercaseFirst(string value) { if (string.IsNullOrWhiteSpace(value)) { return string.Empty; } if (value.Length == 1) { return value.ToUpperInvariant(); } return char.ToUpperInvariant(value[0]) + value.Substring(1).ToLowerInvariant(); } } public sealed class CrystalManager : MonoBehaviour { private static readonly string[] RegrowPrefabNames = new string[5] { "Poison_Crystal_Regrow", "Frost_Crystal_Regrow", "Fire_Crystal_Regrow", "Lightning_Crystal_Regrow", "Raven_Crystal_Regrow" }; private static CrystalManager instance; private static bool prefabsRegistered; private static readonly Dictionary<string, GameObject> RegisteredCrystalPrefabs = new Dictionary<string, GameObject>(); public static void Initialize(BaseUnityPlugin plugin, AssetBundle bundle, ConfigFile config) { CrystalConfigFile.Initialize(config); if ((Object)(object)instance == (Object)null) { instance = ((Component)plugin).GetComponent<CrystalManager>(); if ((Object)(object)instance == (Object)null) { instance = ((Component)plugin).gameObject.AddComponent<CrystalManager>(); } } } public static void RegisterCrystalPrefabs(AssetBundle bundle) { //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown if (prefabsRegistered || (Object)(object)bundle == (Object)null) { return; } CrystalConfigFile.BuildCrystalDefinitions(); int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; IReadOnlyList<CrystalConfigFile.CrystalDefinition> definitions = CrystalConfigFile.Definitions; for (int i = 0; i < definitions.Count; i++) { CrystalConfigFile.CrystalDefinition crystalDefinition = definitions[i]; GameObject val = bundle.LoadAsset<GameObject>(crystalDefinition.PrefabName); if ((Object)(object)val == (Object)null) { num2++; Debug.LogWarning((object)("Crystal prefab missing from asset bundle: " + crystalDefinition.PrefabName)); } else { PrepareCrystalPrefab(val, crystalDefinition); RegisteredCrystalPrefabs[crystalDefinition.PrefabName] = val; num++; } } for (int j = 0; j < RegrowPrefabNames.Length; j++) { string text = RegrowPrefabNames[j]; GameObject val2 = bundle.LoadAsset<GameObject>(text); if ((Object)(object)val2 == (Object)null) { num4++; Debug.LogWarning((object)("Crystal regrow prefab missing from asset bundle: " + text)); continue; } PrepareRegrowPrefab(val2); PrefabManager.Instance.AddPrefab(new CustomPrefab(val2, true)); RegisteredCrystalPrefabs[text] = val2; num3++; } prefabsRegistered = true; Debug.Log((object)("Crystal prefab preparation complete. Prepared crystals: " + num + ", Missing crystals: " + num2 + ", Regrow registered: " + num3 + ", Regrow missing: " + num4)); } public static GameObject GetPreparedCrystalPrefab(string prefabName) { if (string.IsNullOrWhiteSpace(prefabName)) { return null; } RegisteredCrystalPrefabs.TryGetValue(prefabName, out var value); return value; } private static void PrepareCrystalPrefab(GameObject prefab, CrystalConfigFile.CrystalDefinition crystal) { //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown if (!((Object)(object)prefab == (Object)null) && crystal != null) { ((Object)prefab).name = crystal.PrefabName; RemoveItemDrops(prefab); ZNetView val = prefab.GetComponent<ZNetView>(); if ((Object)(object)val == (Object)null) { val = prefab.AddComponent<ZNetView>(); } val.m_persistent = true; val.m_syncInitialScale = true; if (!Object.op_Implicit((Object)(object)prefab.GetComponent<ZSyncTransform>())) { prefab.AddComponent<ZSyncTransform>(); } Piece val2 = prefab.GetComponent<Piece>(); if ((Object)(object)val2 == (Object)null) { val2 = prefab.AddComponent<Piece>(); } val2.m_groundOnly = false; val2.m_canBeRemoved = false; EnsureCollider(prefab); WearNTear val3 = prefab.GetComponent<WearNTear>(); if ((Object)(object)val3 == (Object)null) { val3 = prefab.AddComponent<WearNTear>(); } val3.m_health = ResolveDefaultHealth(crystal.PrefabName); val3.m_noRoofWear = true; GameObject val4 = null; GameObject val5 = null; if ((Object)(object)ZNetScene.instance != (Object)null) { val4 = ZNetScene.instance.GetPrefab("vfx_destroyed"); val5 = ZNetScene.instance.GetPrefab("sfx_clay_pot_break"); } List<EffectData> list = new List<EffectData>(); if ((Object)(object)val4 != (Object)null) { list.Add(new EffectData { m_prefab = val4, m_enabled = true }); } if ((Object)(object)val5 != (Object)null) { list.Add(new EffectData { m_prefab = val5, m_enabled = true }); } EffectList val6 = new EffectList(); val6.m_effectPrefabs = list.ToArray(); val3.m_destroyedEffect = val6; CrystalRuntimeState crystalRuntimeState = prefab.GetComponent<CrystalRuntimeState>(); if ((Object)(object)crystalRuntimeState == (Object)null) { crystalRuntimeState = prefab.AddComponent<CrystalRuntimeState>(); } crystalRuntimeState.Configure(CrystalConfigFile.BuildDropEntries(crystal)); CrystalHoverText crystalHoverText = prefab.GetComponent<CrystalHoverText>(); if ((Object)(object)crystalHoverText == (Object)null) { crystalHoverText = prefab.AddComponent<CrystalHoverText>(); } crystalHoverText.Configure(crystal.PrefabName); if (!Object.op_Implicit((Object)(object)prefab.GetComponent<CrystalBreakVisual>())) { prefab.AddComponent<CrystalBreakVisual>(); } } } private static void PrepareRegrowPrefab(GameObject prefab) { if (!((Object)(object)prefab == (Object)null)) { ((Object)prefab).name = ((Object)prefab).name.Trim(); RemoveItemDrops(prefab); RemovePickables(prefab); RemoveCrystalHoverText(prefab); ZNetView val = prefab.GetComponent<ZNetView>(); if ((Object)(object)val == (Object)null) { val = prefab.AddComponent<ZNetView>(); } val.m_persistent = true; val.m_syncInitialScale = true; if (!Object.op_Implicit((Object)(object)prefab.GetComponent<ZSyncTransform>())) { prefab.AddComponent<ZSyncTransform>(); } Piece val2 = prefab.GetComponent<Piece>(); if ((Object)(object)val2 == (Object)null) { val2 = prefab.AddComponent<Piece>(); } val2.m_groundOnly = false; val2.m_canBeRemoved = false; EnsureCollider(prefab); WearNTear val3 = prefab.GetComponent<WearNTear>(); if ((Object)(object)val3 == (Object)null) { val3 = prefab.AddComponent<WearNTear>(); } val3.m_health = 1f; val3.m_noRoofWear = true; if ((Object)(object)prefab.GetComponent<CrystalRegrowTimer>() == (Object)null) { prefab.AddComponent<CrystalRegrowTimer>(); } } } private static void EnsureCollider(GameObject prefab) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null || (Object)(object)prefab.GetComponentInChildren<Collider>(true) != (Object)null) { return; } BoxCollider val = prefab.GetComponent<BoxCollider>(); if ((Object)(object)val == (Object)null) { val = prefab.AddComponent<BoxCollider>(); } Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); if (componentsInChildren.Length != 0) { Bounds bounds = componentsInChildren[0].bounds; for (int i = 1; i < componentsInChildren.Length; i++) { ((Bounds)(ref bounds)).Encapsulate(componentsInChildren[i].bounds); } val.center = prefab.transform.InverseTransformPoint(((Bounds)(ref bounds)).center); val.size = ((Bounds)(ref bounds)).size; } } private static float ResolveDefaultHealth(string prefabName) { if (string.IsNullOrWhiteSpace(prefabName)) { return 200f; } if (prefabName.IndexOf("_Small", StringComparison.OrdinalIgnoreCase) >= 0) { return 100f; } if (prefabName.IndexOf("_Large", StringComparison.OrdinalIgnoreCase) >= 0) { return 300f; } return 200f; } private static void RemoveItemDrops(GameObject root) { if ((Object)(object)root == (Object)null) { return; } ItemDrop[] componentsInChildren = root.GetComponentsInChildren<ItemDrop>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { Object.DestroyImmediate((Object)(object)componentsInChildren[i], true); } } } private static void RemovePickables(GameObject root) { if ((Object)(object)root == (Object)null) { return; } Pickable[] componentsInChildren = root.GetComponentsInChildren<Pickable>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { Object.DestroyImmediate((Object)(object)componentsInChildren[i], true); } } } private static void RemoveCrystalHoverText(GameObject root) { if ((Object)(object)root == (Object)null) { return; } CrystalHoverText[] componentsInChildren = root.GetComponentsInChildren<CrystalHoverText>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { Object.DestroyImmediate((Object)(object)componentsInChildren[i], true); } } } public static bool TryRestoreExistingCrystalState(CrystalRuntimeState runtime) { if ((Object)(object)runtime == (Object)null || (Object)(object)((Component)runtime).gameObject == (Object)null) { return false; } CrystalConfigFile.BuildCrystalDefinitions(); string text = CleanPrefabName(((Object)((Component)runtime).gameObject).name); if (string.IsNullOrWhiteSpace(text)) { return false; } CrystalConfigFile.CrystalDefinition crystalDefinition = CrystalConfigFile.FindCrystalDefinition(text); if (crystalDefinition == null) { return false; } runtime.Configure(CrystalConfigFile.BuildDropEntries(crystalDefinition)); CrystalHoverText component = ((Component)runtime).GetComponent<CrystalHoverText>(); if ((Object)(object)component != (Object)null) { component.Configure(crystalDefinition.PrefabName); } return true; } private static string CleanPrefabName(string prefabName) { if (string.IsNullOrWhiteSpace(prefabName)) { return string.Empty; } string text = prefabName.Trim(); if (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - "(Clone)".Length).Trim(); } return text; } } public class CrystalRegrowTimer : MonoBehaviour, Hoverable, Interactable { [HarmonyPatch(typeof(Piece), "DropResources")] private static class Piece_DropResources_Patch { private static bool Prefix(Piece __instance) { if ((Object)(object)__instance == (Object)null) { return true; } CrystalRegrowTimer component = ((Component)__instance).GetComponent<CrystalRegrowTimer>(); if ((Object)(object)component == (Object)null) { return true; } component.RequestSilentRemove(); return false; } } [HarmonyPatch(typeof(WearNTear), "RPC_Damage")] private static class WearNTear_RPC_Damage_Patch { private static void Postfix(WearNTear __instance) { if (!((Object)(object)__instance == (Object)null)) { CrystalRegrowTimer component = ((Component)__instance).GetComponent<CrystalRegrowTimer>(); if (!((Object)(object)component == (Object)null) && !(__instance.m_health > 0f)) { component.RequestSilentRemove(); } } } } [CompilerGenerated] private sealed class <SilentRemoveRoutine>d__26 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CrystalRegrowTimer <>4__this; private float <timeout>5__1; private ZDO <zdo>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SilentRemoveRoutine>d__26(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <zdo>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this.removalInProgress = true; <timeout>5__1 = 1f; goto IL_0072; case 1: <>1__state = -1; goto IL_0072; case 2: { <>1__state = -1; <>4__this.DestroySelf(); return false; } IL_0072: if (!<>4__this.TryClaimOwnership() && <timeout>5__1 > 0f) { <timeout>5__1 -= Time.deltaTime; <>2__current = null; <>1__state = 1; return true; } <zdo>5__2 = <>4__this.GetCarrierZdo(); if (<zdo>5__2 != null && <>4__this.CanWriteZdo()) { <zdo>5__2.Set("rwc_regrow_completed", 1); <zdo>5__2.Set("picked", 1); } <>4__this.PlayDestroyEffects(); <>4__this.DisableInteraction(); <>2__current = (object)new WaitForSeconds(0.05f); <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const string CrystalRespawnerKey = "crystalRespawner"; private const string PickedKey = "picked"; private const string StartTicksZdoKey = "rwc_regrow_startticks"; private const string DurationMinutesZdoKey = "rwc_regrow_durationminutes"; private const string CompletedZdoKey = "rwc_regrow_completed"; private const float DefaultRegrowMinutes = 1500f; private const float NearbyWorkbenchSuppressRadius = 20f; private const float NearbyBuildingSuppressRadius = 20f; private const string DestroyVfxPrefabName = "vfx_destroyed"; private const string DestroySfxPrefabName = "sfx_clay_pot_break"; private ZNetView znv; private Renderer[] cachedRenderers; private Collider[] cachedColliders; private float nextStateCheckTime; private bool removalInProgress; private void Awake() { znv = ((Component)this).GetComponent<ZNetView>(); cachedRenderers = ((Component)this).GetComponentsInChildren<Renderer>(true); cachedColliders = ((Component)this).GetComponentsInChildren<Collider>(true); EnsureVisible(); EnsureInitialized(); } private void OnEnable() { EnsureVisible(); EnsureInitialized(); } private void LateUpdate() { EnsureVisible(); if (!(Time.time < nextStateCheckTime)) { nextStateCheckTime = Time.time + 1f; UpdateRespawnState(); } } public string GetHoverName() { return BuildHoverName(); } public string GetHoverText() { return BuildHoverText(); } public bool Interact(Humanoid character, bool hold, bool alt) { return false; } public bool UseItem(Humanoid user, ItemData item) { return false; } public bool IsRegrowCarrier() { ZDO carrierZdo = GetCarrierZdo(); if (carrierZdo == null) { return false; } return carrierZdo.GetInt("crystalRespawner", 0) == 1; } public string BuildHoverName() { string text = ResolveRespawnPrefabName(); if (string.IsNullOrWhiteSpace(text)) { return "Regrowing Crystal"; } return BuildDisplayName(text) + " Regrowing"; } public string BuildHoverText() { string text = BuildHoverName(); double remainingSeconds = GetRemainingSeconds(); if (remainingSeconds > 0.0) { return text + "\n<color=orange>Respawns in " + FormatRemaining(TimeSpan.FromSeconds(remainingSeconds)) + "</color>"; } if (IsBlockedByNearbyBase()) { return text + "\n<color=orange>Respawn blocked by nearby base/workbench</color>"; } return text + "\n<color=orange>Respawning now...</color>"; } public void RequestSilentRemove() { if (!removalInProgress) { ((MonoBehaviour)this).StartCoroutine(SilentRemoveRoutine()); } } [IteratorStateMachine(typeof(<SilentRemoveRoutine>d__26))] private IEnumerator SilentRemoveRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SilentRemoveRoutine>d__26(0) { <>4__this = this }; } private void PlayDestroyEffects() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) if (!((Object)(object)ZNetScene.instance == (Object)null)) { GameObject prefab = ZNetScene.instance.GetPrefab("vfx_destroyed"); if ((Object)(object)prefab != (Object)null) { Object.Instantiate<GameObject>(prefab, ((Component)this).transform.position, ((Component)this).transform.rotation); } GameObject prefab2 = ZNetScene.instance.GetPrefab("sfx_clay_pot_break"); if ((Object)(object)prefab2 != (Object)null) { Object.Instantiate<GameObject>(prefab2, ((Component)this).transform.position, ((Component)this).transform.rotation); } } } private void DisableInteraction() { if (cachedColliders == null || cachedColliders.Length == 0) { cachedColliders = ((Component)this).GetComponentsInChildren<Collider>(true); } for (int i = 0; i < cachedColliders.Length; i++) { if ((Object)(object)cachedColliders[i] != (Object)null) { cachedColliders[i].enabled = false; } } } private void DestroySelf() { if (!((Object)(object)((Component)this).gameObject == (Object)null)) { if ((Object)(object)ZNetScene.instance != (Object)null) { ZNetScene.instance.Destroy(((Component)this).gameObject); } else { Object.Destroy((Object)(object)((Component)this).gameObject); } } } private void EnsureInitialized() { ZDO carrierZdo = GetCarrierZdo(); if (carrierZdo == null) { return; } if (carrierZdo.GetLong("rwc_regrow_startticks", 0L) <= 0 && CanWriteZdo()) { carrierZdo.Set("rwc_regrow_startticks", GetNetworkTime().Ticks); } if (carrierZdo.GetFloat("rwc_regrow_durationminutes", 0f) <= 0f && CanWriteZdo()) { float num = carrierZdo.GetFloat("rwc_regrowminutes", 0f); if (num <= 0f) { num = carrierZdo.GetFloat("Pickable.m_respawnTimeMinutes", 0f); } if (num <= 0f) { num = carrierZdo.GetFloat("Pickable.m_respawnTimeInitMin", 0f); } if (num <= 0f) { num = 1500f; } carrierZdo.Set("rwc_regrow_durationminutes", num); } if (carrierZdo.GetInt("rwc_regrow_completed", 0) == 0 && GetRemainingSeconds(carrierZdo) > 0.0 && CanWriteZdo() && carrierZdo.GetInt("picked", 1) != 1) { carrierZdo.Set("picked", 1); } } private void UpdateRespawnState() { ZDO carrierZdo = GetCarrierZdo(); if (carrierZdo == null || carrierZdo.GetInt("rwc_regrow_completed", 0) == 1) { return; } double remainingSeconds = GetRemainingSeconds(carrierZdo); if (remainingSeconds > 0.0) { if (CanWriteZdo() && carrierZdo.GetInt("picked", 1) != 1) { carrierZdo.Set("picked", 1); } } else if (IsBlockedByNearbyBase()) { if (CanWriteZdo() && carrierZdo.GetInt("picked", 1) != 1) { carrierZdo.Set("picked", 1); } } else if (CanWriteZdo()) { carrierZdo.Set("rwc_regrow_completed", 1); carrierZdo.Set("picked", 0); } } private void EnsureVisible() { if (!IsRegrowCarrier()) { return; } if (cachedRenderers == null || cachedRenderers.Length == 0) { cachedRenderers = ((Component)this).GetComponentsInChildren<Renderer>(true); } if (cachedColliders == null || cachedColliders.Length == 0) { cachedColliders = ((Component)this).GetComponentsInChildren<Collider>(true); } for (int i = 0; i < cachedRenderers.Length; i++) { Renderer val = cachedRenderers[i]; if (!((Object)(object)val == (Object)null)) { if (!((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } val.enabled = true; } } for (int j = 0; j < cachedColliders.Length; j++) { Collider val2 = cachedColliders[j]; if (!((Object)(object)val2 == (Object)null)) { if (!((Component)val2).gameObject.activeSelf) { ((Component)val2).gameObject.SetActive(true); } val2.enabled = true; } } } private bool IsBlockedByNearbyBase() { //IL_0017: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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) float num = Mathf.Max(20f, 20f); Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, num, -1, (QueryTriggerInteraction)2); if (array == null || array.Length == 0) { return false; } HashSet<int> hashSet = new HashSet<int>(); foreach (Collider val in array) { if ((Object)(object)val == (Object)null) { continue; } CraftingStation componentInParent = ((Component)val).GetComponentInParent<CraftingStation>(); if ((Object)(object)componentInParent != (Object)null) { int instanceID = ((Object)((Component)componentInParent).gameObject).GetInstanceID(); if (hashSet.Add(instanceID) && (Object)(object)((Component)componentInParent).gameObject != (Object)(object)((Component)this).gameObject && Vector3.Distance(((Component)this).transform.position, ((Component)componentInParent).transform.position) <= 20f && HasPlayerCreator((Component)(object)componentInParent)) { return true; } } Piece componentInParent2 = ((Component)val).GetComponentInParent<Piece>(); if ((Object)(object)componentInParent2 != (Object)null) { int instanceID2 = ((Object)((Component)componentInParent2).gameObject).GetInstanceID(); if (hashSet.Add(instanceID2) && (Object)(object)((Component)componentInParent2).gameObject != (Object)(object)((Component)this).gameObject && Vector3.Distance(((Component)this).transform.position, ((Component)componentInParent2).transform.position) <= 20f && HasPlayerCreator((Component)(object)componentInParent2)) { return true; } } } return false; } private static bool HasPlayerCreator(Component component) { if ((Object)(object)component == (Object)null) { return false; } ZNetView val = component.GetComponent<ZNetView>(); if ((Object)(object)val == (Object)null) { val = component.GetComponentInParent<ZNetView>(); } if ((Object)(object)val == (Object)null || !val.IsValid()) { return false; } ZDO zDO = val.GetZDO(); if (zDO == null) { return false; } return zDO.GetLong(ZDOVars.s_creator, 0L) != 0; } private ZDO GetCarrierZdo() { znv = (((Object)(object)znv != (Object)null) ? znv : ((Component)this).GetComponent<ZNetView>()); if ((Object)(object)znv == (Object)null || !znv.IsValid()) { return null; } ZDO zDO = znv.GetZDO(); if (zDO == null) { return null; } if (zDO.GetInt("crystalRespawner", 0) != 1) { return null; } return zDO; } private bool CanWriteZdo() { znv = (((Object)(object)znv != (Object)null) ? znv : ((Component)this).GetComponent<ZNetView>()); if ((Object)(object)znv == (Object)null || !znv.IsValid()) { return false; } if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { return true; } return znv.IsOwner(); } private bool TryClaimOwnership() { znv = (((Object)(object)znv != (Object)null) ? znv : ((Component)this).GetComponent<ZNetView>()); if ((Object)(object)znv == (Object)null || !znv.IsValid()) { return true; } if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { return true; } if (!znv.IsOwner()) { znv.ClaimOwnership(); } return znv.IsOwner(); } private double GetRemainingSeconds() { ZDO carrierZdo = GetCarrierZdo(); if (carrierZdo == null) { return 0.0; } return GetRemainingSeconds(carrierZdo); } private double GetRemainingSeconds(ZDO zdo) { if (zdo == null) { return 0.0; } long @long = zdo.GetLong("rwc_regrow_startticks", 0L); float @float = zdo.GetFloat("rwc_regrow_durationminutes", 0f); if (@long <= 0 || @float <= 0f) { return 0.0; } DateTime dateTime = new DateTime(@long, DateTimeKind.Utc); DateTime networkTime = GetNetworkTime(); double totalSeconds = (networkTime - dateTime).TotalSeconds; double num = (double)@float * 60.0; return Math.Max(0.0, num - totalSeconds); } private static DateTime GetNetworkTime() { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.GetTime(); } return DateTime.UtcNow; } private string ResolveRespawnPrefabName() { ZDO carrierZdo = GetCarrierZdo(); if (carrierZdo != null) { string @string = carrierZdo.GetString("respawnprefab", string.Empty); if (!string.IsNullOrWhiteSpace(@string)) { return @string; } @string = carrierZdo.GetString("rwc_respawnprefab", string.Empty); if (!string.IsNullOrWhiteSpace(@string)) { return @string; } } string text = (((Object)(object)((Component)this).gameObject != (Object)null) ? ((Object)((Component)this).gameObject).name : string.Empty); if (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - "(Clone)".Length).Trim(); } if (text.EndsWith("_Regrow", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - "_Regrow".Length).Trim(); } return text; } private static string FormatRemaining(TimeSpan remaining) { int num = Mathf.Max(0, Mathf.CeilToInt((float)remaining.TotalSeconds)); int num2 = num / 86400; int num3 = num % 86400 / 3600; int num4 = num % 3600 / 60; int num5 = num % 60; if (num2 > 0) { return num2 + "d " + num3 + "h " + num4 + "m"; } if (num3 > 0) { return num3 + "h " + num4 + "m " + num5 + "s"; } if (num4 > 0) { return num4 + "m " + num5 + "s"; } return num5 + "s"; } private static string BuildDisplayName(string prefabName) { if (string.IsNullOrWhiteSpace(prefabName)) { return "Crystal"; } string[] array = prefabName.Split(new char[1] { '_' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length == 0) { return "Crystal"; } string text = "Medium"; List<string> list = new List<string>(); foreach (string text2 in array) { if (string.Equals(text2, "Small", StringComparison.OrdinalIgnoreCase)) { text = "Small"; } else if (string.Equals(text2, "Large", StringComparison.OrdinalIgnoreCase)) { text = "Large"; } else if (!string.Equals(text2, "Crystal", StringComparison.OrdinalIgnoreCase) && !string.Equals(text2, "Regrow", StringComparison.OrdinalIgnoreCase)) { list.Add(UppercaseFirst(text2)); } } if (list.Count == 0) { return text + " Crystal"; } return text + " " + string.Join(" ", list.ToArray()) + " Crystal"; } private static string UppercaseFirst(string value) { if (string.IsNullOrWhiteSpace(value)) { return string.Empty; } if (value.Length == 1) { return value.ToUpperInvariant(); } return char.ToUpperInvariant(value[0]) + value.Substring(1).ToLowerInvariant(); } } public class CrystalRuntimeState : MonoBehaviour, Interactable { [HarmonyPatch(typeof(WearNTear), "RPC_Damage")] private static class WearNTear_RPC_Damage_Patch { private static void Postfix(WearNTear __instance) { if (!((Object)(object)__instance == (Object)null)) { CrystalRuntimeState component = ((Component)__instance).GetComponent<CrystalRuntimeState>(); if (!((Object)(object)component == (Object)null)) { component.TryHandleDestroyed(fromOnDestroy: false); } } } } [HarmonyPatch(typeof(Piece), "SetCreator")] private static class Piece_SetCreator_Patch { private static void Postfix(Piece __instance) { if (!((Object)(object)__instance == (Object)null)) { CrystalRuntimeState component = ((Component)__instance).GetComponent<CrystalRuntimeState>(); if (!((Object)(object)component == (Object)null)) { component.MarkPlayerPlaced(); component.EnsurePieceRules(); } } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDB_Awake_Patch { private static void Postfix() { EnsureCultivatorRemoveEnabled(); } } [HarmonyPatch(typeof(Player), "Awake")] private static class Player_Awake_Patch { private static void Postfix() { EnsureCultivatorRemoveEnabled(); } } [HarmonyPatch(typeof(Player), "CheckCanRemovePiece")] private static class Player_CheckCanRemovePiece_Patch { private static bool Prefix(Player __instance, Piece piece, ref bool __result) { if (!IsManagedCrystalPiece(piece)) { return true; } EnsureCultivatorRemoveEnabled(); ItemData equippedRightItem = GetEquippedRightItem(__instance); if (!IsCultivator(equippedRightItem)) { __result = false; return false; } bool flag = CanCultivatorRemovePiece(piece); if (!flag && (Object)(object)__instance != (Object)null) { ((Character)__instance).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null); } __result = flag; return false; } } [HarmonyPatch(typeof(Player), "RemovePiece")] private static class Player_RemovePiece_Patch { private static bool Prefix(Player __instance) { EnsureCultivatorRemoveEnabled(); ItemData equippedRightItem = GetEquippedRightItem(__instance); if (!IsCultivator(equippedRightItem)) { return true; } if (!TryFindManagedPiece(__instance, out var targetPiece)) { return true; } if (!CanCultivatorRemovePiece(targetPiece)) { if ((Object)(object)__instance != (Object)null) { ((Character)__instance).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null); } return false; } CrystalRuntimeState component = ((Component)targetPiece).GetComponent<CrystalRuntimeState>(); if ((Object)(object)component != (Object)null) { component.RequestCultivatorMiddleMouseRemove(); return false; } CrystalRegrowTimer component2 = ((Component)targetPiece).GetComponent<CrystalRegrowTimer>(); if ((Object)(object)component2 != (Object)null) { component2.RequestSilentRemove(); return false; } return true; } } [HarmonyPatch(typeof(Piece), "DropResources")] private static class Piece_DropResources_Patch { private static bool Prefix(Piece __instance) { if ((Object)(object)__instance == (Object)null) { return true; } CrystalRuntimeState component = ((Component)__instance).GetComponent<CrystalRuntimeState>(); if ((Object)(object)component == (Object)null) { return true; } component.HandleToolRemove(); return false; } } [CompilerGenerated] private sealed class <CultivatorRemoveRoutine>d__25 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CrystalRuntimeState <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CultivatorRemoveRoutine>d__25(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this.pickupInProgress = true; <>4__this.suppressDropSpawn = true; <>4__this.handledDestroyed = true; <>4__this.breakVisual = (((Object)(object)<>4__this.breakVisual != (Object)null) ? <>4__this.breakVisual : ((Component)<>4__this).GetComponent<CrystalBreakVisual>()); if ((Object)(object)<>4__this.breakVisual != (Object)null) { <>4__this.breakVisual.ForceBreak(); } <>4__this.SpawnDrops(); <>4__this.CreateDestroyedEffects(); <>4__this.DisableInteraction(); <>2__current = (object)new WaitForSeconds(0.32f); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.DestroySelf(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <PickupRoutine>d__24 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CrystalRuntimeState <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PickupRoutine>d__24(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this.pickupInProgress = true; <>4__this.suppressDropSpawn = true; <>4__this.handledDestroyed = true; <>4__this.breakVisual = (((Object)(object)<>4__this.breakVisual != (Object)null) ? <>4__this.breakVisual : ((Component)<>4__this).GetComponent<CrystalBreakVisual>()); if ((Object)(object)<>4__this.breakVisual != (Object)null) { <>4__this.breakVisual.ForceBreak(); } <>4__this.SpawnDrops(); <>4__this.CreateDestroyedEffects(); <>4__this.DisableInteraction(); <>2__current = (object)new WaitForSeconds(0.32f); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.DestroySelf(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const string PlayerPlacedZdoKey = "rwc_playerplaced"; private const string CultivatorPrefabName = "Cultivator"; private const float RemoveRayDistance = 50f; private static readonly FieldInfo RightItemField = AccessTools.Field(typeof(Humanoid), "m_rightItem"); private static readonly MethodInfo GetRightItemMethod = AccessTools.Method(typeof(Humanoid), "GetRightItem", (Type[])null, (Type[])null); private static readonly int RemoveRayMask = LayerMask.GetMask(new string[5] { "piece", "piece_nonsolid", "item", "Default_small", "Default" }); private readonly List<CrystalDropEntry> dropEntries = new List<CrystalDropEntry>(); private bool handledDestroyed; private bool restoredExistingState; private bool suppressDropSpawn; private bool pickupInProgress; private WearNTear wear; private ZNetView znv; private CrystalBreakVisual breakVisual; private Piece piece; public void Configure(List<CrystalDropEntry> entries) { dropEntries.Clear(); if (entries == null) { return; } for (int i = 0; i < entries.Count; i++) { CrystalDropEntry crystalDropEntry = entries[i]; if (crystalDropEntry != null) { dropEntries.Add(new CrystalDropEntry(crystalDropEntry.ItemName, crystalDropEntry.Min, crystalDropEntry.Max)); } } } public void MarkPlayerPlaced() { znv = (((Object)(object)znv != (Object)null) ? znv : ((Component)this).GetComponent<ZNetView>()); if (!((Object)(object)znv == (Object)null) && znv.IsValid()) { ZDO zDO = znv.GetZDO(); if (zDO != null) { zDO.Set("rwc_playerplaced", 1); } } } public bool IsPlayerPlaced() { znv = (((Object)(object)znv != (Object)null) ? znv : ((Component)this).GetComponent<ZNetView>()); if ((Object)(object)znv == (Object)null || !znv.IsValid()) { return false; } ZDO zDO = znv.GetZDO(); if (zDO == null) { return false; } return zDO.GetInt("rwc_playerplaced", 0) == 1; } public bool Interact(Humanoid character, bool hold, bool alt) { if (hold) { return false; } if (pickupInProgress || handledDestroyed) { return true; } if (!TryClaimOwnership()) { return true; } ((MonoBehaviour)this).StartCoroutine(PickupRoutine()); return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } public void RequestCultivatorMiddleMouseRemove() { if (!pickupInProgress && !handledDestroyed && TryClaimOwnership()) { ((MonoBehaviour)this).StartCoroutine(CultivatorRemoveRoutine()); } } public void HandleToolRemove() { if (handledDestroyed) { suppressDropSpawn = true; return; } suppressDropSpawn = true; handledDestroyed = true; breakVisual = (((Object)(object)breakVisual != (Object)null) ? breakVisual : ((Component)this).GetComponent<CrystalBreakVisual>()); if ((Object)(object)breakVisual != (Object)null) { breakVisual.ForceBreakImmediate(); } SpawnDrops(); CreateDestroyedEffects(); } private void Awake() { wear = ((Component)this).GetComponent<WearNTear>(); znv = ((Component)this).GetComponent<ZNetView>(); breakVisual = ((Component)this).GetComponent<CrystalBreakVisual>(); piece = ((Component)this).GetComponent<Piece>(); EnsurePieceRules(); TryRestoreExistingState(); } private void OnDestroy() { TryHandleDestroyed(fromOnDestroy: true); } [IteratorStateMachine(typeof(<PickupRoutine>d__24))] private IEnumerator PickupRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PickupRoutine>d__24(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<CultivatorRemoveRoutine>d__25))] private IEnumerator CultivatorRemoveRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CultivatorRemoveRoutine>d__25(0) { <>4__this = this }; } private void DisableInteraction() { Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { componentsInChildren[i].enabled = false; } } } private void DestroySelf() { if (!((Object)(object)((Component)this).gameObject == (Object)null)) { if ((Object)(object)ZNetScene.instance != (Object)null) { ZNetScene.instance.Destroy(((Component)this).gameObject); } else { Object.Destroy((Object)(object)((Component)this).gameObject); } } } private void EnsurePieceRules() { piece = (((Object)(object)piece != (Object)null) ? piece : ((Component)this).GetComponent<Piece>()); if (!((Object)(object)piece == (Object)null)) { piece.m_groundOnly = false; piece.m_canBeRemoved = false; } } private void TryRestoreExistingState() { if (!restoredExistingState) { restoredExistingState = CrystalManager.TryRestoreExistingCrystalState(this); EnsurePieceRules(); } } private bool TryClaimOwnership() { znv = (((Object)(object)znv != (Object)null) ? znv : ((Component)this).GetComponent<ZNetView>()); if ((Object)(object)znv == (Object)null || !znv.IsValid()) { return true; } if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { return true; } if (!znv.IsOwner()) { znv.ClaimOwnership(); } return znv.IsOwner(); } private bool CanHandleDestroyedState() { znv = (((Object)(object)znv != (Object)null) ? znv : ((Component)this).GetComponent<ZNetView>()); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { return true; } if ((Object)(object)znv == (Object)null) { return true; } return !znv.IsValid() || znv.IsOwner(); } private void TryHandleDestroyed(bool fromOnDestroy) { if (handledDestroyed) { return; } if (suppressDropSpawn) { handledDestroyed = true; } else { if (!CanHandleDestroyedState()) { return; } wear = (((Object)(object)wear != (Object)null) ? wear : ((Component)this).GetComponent<WearNTear>()); if ((Object)(object)wear == (Object)null) { if (fromOnDestroy) { } } else if (!(wear.m_health > 0f)) { handledDestroyed = true; SpawnDrops(); } } } private void CreateDestroyedEffects() { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) wear = (((Object)(object)wear != (Object)null) ? wear : ((Component)this).GetComponent<WearNTear>()); if ((Object)(object)wear == (Object)null || wear.m_destroyedEffect == null || wear.m_destroyedEffect.m_effectPrefabs == null) { return; } for (int i = 0; i < wear.m_destroyedEffect.m_effectPrefabs.Length; i++) { EffectData val = wear.m_destroyedEffect.m_effectPrefabs[i]; if (val != null && val.m_enabled && !((Object)(object)val.m_prefab == (Object)null)) { Object.Instantiate<GameObject>(val.m_prefab, ((Component)this).transform.position, ((Component)this).transform.rotation); } } } private void SpawnDrops() { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: 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) if ((Object)(object)ZNetScene.instance == (Object)null || dropEntries.Count == 0) { return; } for (int i = 0; i < dropEntries.Count; i++) { CrystalDropEntry crystalDropEntry = dropEntries[i]; if (crystalDropEntry == null || string.IsNullOrWhiteSpace(crystalDropEntry.ItemName)) { continue; } GameObject prefab = ZNetScene.instance.GetPrefab(crystalDropEntry.ItemName); if ((Object)(object)prefab == (Object)null) { Debug.LogWarning((object)("Crystal drop prefab not found: " + crystalDropEntry.ItemName)); continue; } int num = Mathf.Max(0, crystalDropEntry.Min); int num2 = Mathf.Max(num, crystalDropEntry.Max); int num3 = Random.Range(num, num2 + 1); for (int j = 0; j < num3; j++) { Vector3 val = ((Component)this).transform.position + Vector3.up + Random.insideUnitSphere * 0.15f; val.y = Mathf.Max(val.y, ((Component)this).transform.position.y + 0.5f); Object.Instantiate<GameObject>(prefab, val, Quaternion.identity); } } } private static bool IsCultivator(ItemData item) { if (item == null) { return false; } if ((Object)(object)item.m_dropPrefab != (Object)null) { string a = CleanPrefabName(((Object)item.m_dropPrefab).name); if (string.Equals(a, "Cultivator", StringComparison.Ordinal)) { return true; } } if (item.m_shared != null && (string.Equals(item.m_shared.m_name, "$item_cultivator", StringComparison.Ordinal) || string.Equals(item.m_shared.m_name, "Cultivator", StringComparison.Ordinal))) { return true; } return false; } private static ItemData GetEquippedRightItem(Player player) { if ((Object)(object)player == (Object)null) { return null; } if (RightItemField != null) { try { object? value = RightItemField.GetValue(player); return (ItemData)((value is ItemData) ? value : null); } catch { } } if (GetRightItemMethod != null) { try { object? obj2 = GetRightItemMethod.Invoke(player, null); return (ItemData)((obj2 is ItemData) ? obj2 : null); } catch { } } return null; } private static bool IsManagedCrystalPiece(Piece targetPiece) { if ((Object)(object)targetPiece == (Object)null) { return false; } return (Object)(object)((Component)targetPiece).GetComponent<CrystalRuntimeState>() != (Object)null || (Object)(object)((Component)targetPiece).GetComponent<CrystalRegrowTimer>() != (Object)null; } private static bool CanCultivatorRemovePiece(Piece targetPiece) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (!IsManagedCrystalPiece(targetPiece)) { return false; } return PrivateArea.CheckAccess(((Component)targetPiece).transform.position, 0f, true, false); } private static void EnsureCultivatorRemoveEnabled() { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { return; } GameObject itemPrefab = instance.GetItemPrefab("Cultivator"); if ((Object)(object)itemPrefab == (Object)null) { return; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null) && component.m_itemData != null && component.m_itemData.m_shared != null) { PieceTable buildPieces = component.m_itemData.m_shared.m_buildPieces; if (!((Object)(object)buildPieces == (Object)null)) { buildPieces.m_canRemovePieces = true; } } } private static bool TryFindManagedPiece(Player player, out Piece targetPiece) { //IL_0045: 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) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) targetPiece = null; if ((Object)(object)player == (Object)null || (Object)(object)GameCamera.instance == (Object)null) { return false; } Transform transform = ((Component)GameCamera.instance).transform; if ((Object)(object)transform == (Object)null) { return false; } RaycastHit val = default(RaycastHit); if (!Physics.Raycast(transform.position, transform.forward, ref val, 50f, RemoveRayMask)) { return false; } if (Vector3.Distance(((RaycastHit)(ref val)).point, ((Character)player).m_eye.position) > player.m_maxPlaceDistance) { return false; } targetPiece = (((Object)(object)((RaycastHit)(ref val)).collider != (Object)null) ? ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>() : null); return IsManagedCrystalPiece(targetPiece); } private static string CleanPrefabName(string prefabName) { if (string.IsNullOrWhiteSpace(prefabName)) { return string.Empty; } string text = prefabName.Trim(); if (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - "(Clone)".Length).Trim(); } return text; } } public class LocalizeKey : MonoBehaviour { public string Key; public void Awake() { if (!string.IsNullOrEmpty(Key)) { string text = LocalizationCache.Get(Key); } } } public static class Localizer { public static void Add(string key, string value) { LocalizationCache.Add(key, value); } public static void Register() { LocalizationCache.RegisterToJotunnLocalization(); } } public class PlacementWatcher : MonoBehaviour { public List<GameObject> RegisterList; private void Start() { if (RegisterList != null && !RegisterList.Contains(((Component)this).gameObject)) { RegisterList.Add(((Component)this).gameObject); } } private void OnDestroy() { if (RegisterList != null) { RegisterList.Remove(((Component)this).gameObject); } } } public static class LocalizationCache { private static Dictionary<string, string> translations = new Dictionary<string, string>(); public static void Add(string key, string value) { translations[key] = value; } public static string Get(string key, string fallback = null) { if (translations.TryGetValue(key, out var value)) { return value; } return fallback ?? key; } public static void RegisterToJotunnLocalization() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); foreach (KeyValuePair<string, string> translation in translations) { string text = "English"; string key = translation.Key; localization.AddTranslation(ref text, ref key, translation.Value); } } } [BepInPlugin("Ravenwood.Crystals", "Ravenwood Crystals", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class RavenwoodCrystals : BaseUnityPlugin { [CompilerGenerated] private sealed class <DelayedRegister>d__10 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public AssetBundle bundle; public RavenwoodCrystals <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedRegister>d__10(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if ((Object)(object)ZNetScene.instance == (Object)null) { <>2__current = null; <>1__state = 1; return true; } RelicRegistrar.RegisterAllRelics(bundle); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string PluginGUID = "Ravenwood.Crystals"; public const string PluginName = "Ravenwood Crystals"; public const string PluginVersion = "1.0.1"; private const string PreferredCategoryName = "RavenCrystals"; private AssetBundle gatesBundle; private static readonly List<GameObject> placedObjects = new List<GameObject>(); public static string GetPreferredCategoryName() { return "RavenCrystals"; } private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) new Harmony("ravenwood.crystals").PatchAll(); gatesBundle = EmbeddedAssetBundleLoader.LoadBundle("RavenwoodCrystals.ravenwoodcrystals"); if ((Object)(object)gatesBundle == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Failed to load embedded AssetBundle."); return; } TrackAllPrefabsInBundle(gatesBundle); foreach (string allCategory in RelicRegistrar.GetAllCategories()) { PieceManager.Instance.AddPieceCategory(allCategory); } CrystalManager.Initialize((BaseUnityPlugin)(object)this, gatesBundle, ((BaseUnityPlugin)this).Config); CrystalManager.RegisterCrystalPrefabs(gatesBundle); PrefabManager.OnPrefabsRegistered += OnPrefabsRegistered; } private void OnDestroy() { PrefabManager.OnPrefabsRegistered -= OnPrefabsRegistered; } private void OnPrefabsRegistered() { ((MonoBehaviour)this).StartCoroutine(DelayedRegister(gatesBundle)); } [IteratorStateMachine(typeof(<DelayedRegister>d__10))] private IEnumerator DelayedRegister(AssetBundle bundle) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedRegister>d__10(0) { <>4__this = this, bundle = bundle }; } public static void TrackAllPrefabsInBundle(AssetBundle bundle) { GameObject[] array = bundle.LoadAllAssets<GameObject>(); foreach (GameObject val in array) { if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<PlacementWatcher>() == (Object)null) { val.AddComponent<PlacementWatcher>().RegisterList = placedObjects; } } } } public static class EmbeddedAssetBundleLoader { public static AssetBundle LoadBundle(string resourcePath) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); using Stream stream = executingAssembly.GetManifestResourceStream(resourcePath); if (stream == null) { Debug.LogError((object)("AssetBundle resource not found: " + resourcePath)); return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); return AssetBundle.LoadFromMemory(array); } } public class RelicRegistration { public string PrefabName; public string DisplayName; public RequirementConfig[] Requirements; public string Description; public string Category; public int Comfort; public string CraftingStation; public string PieceTable; public RelicRegistration(string prefab, string display, RequirementConfig[] reqs, string desc, string cat, string pieceTable = "_CultivatorPieceTable", int comfort = 0, string craftingStation = "") { PrefabName = prefab; DisplayName = display; Requirements = reqs; Description = desc; Category = cat; PieceTable = pieceTable; Comfort = comfort; CraftingStation = craftingStation; } } public static class RelicRegistrar { private static bool wasAlreadyRegistered = false; public static readonly List<RelicRegistration> AllRegistrations = new List<RelicRegistration> { CreateElementCrystal("Poison_Crystal_Small", "Small Poison Crystal", "Essence_Poison", 50), CreateElementCrystal("Poison_Crystal", "Medium Poison Crystal", "Essence_Poison", 100), CreateElementCrystal("Poison_Crystal_Large", "Large Poison Crystal", "Essence_Poison", 200), CreateElementCrystal("Frost_Crystal_Small", "Small Frost Crystal", "Essence_Frost", 50), CreateElementCrystal("Frost_Crystal", "Medium Frost Crystal", "Essence_Frost", 100), CreateElementCrystal("Frost_Crystal_Large", "Large Frost Crystal", "Essence_Frost", 200), CreateElementCrystal("Fire_Crystal_Small", "Small Fire Crystal", "Essence_Fire", 50), CreateElementCrystal("Fire_Crystal", "Medium Fire Crystal", "Essence_Fire", 100), CreateElementCrystal("Fire_Crystal_Large", "Large Fire Crystal", "Essence_Fire", 200), CreateElementCrystal("Lightning_Crystal_Small", "Small Lightning Crystal", "Essence_Lightning", 50), CreateElementCrystal("Lightning_Crystal", "Medium Lightning Crystal", "Essence_Lightning", 100), CreateElementCrystal("Lightning_Crystal_Large", "Large Lightning Crystal", "Essence_Lightning", 200), CreateRavenCrystal("Raven_Crystal_Small", "Small Raven Crystal", 33, 33, 33, 33), CreateRavenCrystal("Raven_Crystal", "Medium Raven Crystal", 50, 50, 50, 50), CreateRavenCrystal("Raven_Crystal_Large", "Large Raven Crystal", 100, 100, 100, 100) }; public static IEnumerable<string> GetAllCategories() { return AllRegistrations.Select((RelicRegistration r) => CategoryToTab(r.Category)).Distinct(); } private static string CategoryToTab(string category) { if (string.IsNullOrWhiteSpace(category)) { return RavenwoodCrystals.GetPreferredCategoryName(); } switch (category.ToLowerInvariant()) { case "building": case "cultivator": case "ravenwoodcrystals": case "ravenwoodcrysta": case "raven crystals": case "ravencrystals": return RavenwoodCrystals.GetPreferredCategoryName(); default: return category; } } public static void RegisterAllRelics(AssetBundle bundle) { if (wasAlreadyRegistered) { return; } foreach (RelicRegistration allRegistration in AllRegistrations) { RegisterRelic(bundle, allRegistration); } wasAlreadyRegistered = true; } private static void RegisterRelic(AssetBundle bundle, RelicRegistration reg) { //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Expected O, but got Unknown //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Expected O, but got Unknown //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Expected O, but got Unknown //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: 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_0240: Expected O, but got Unknown //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Expected O, but got Unknown //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Expected O, but got Unknown GameObject val = CrystalManager.GetPreparedCrystalPrefab(reg.PrefabName); if ((Object)(object)val == (Object)null && (Object)(object)bundle != (Object)null) { val = bundle.LoadAsset<GameObject>(reg.PrefabName); } if (!((Object)(object)val == (Object)null)) { ((Object)val).name = reg.PrefabName; ZNetView val2 = val.GetComponent<ZNetView>(); if ((Object)(object)val2 == (Object)null) { val2 = val.AddComponent<ZNetView>(); } val2.m_persistent = true; val2.m_syncInitialScale = true; if (!Object.op_Implicit((Object)(object)val.GetComponent<ZSyncTransform>())) { val.AddComponent<ZSyncTransform>(); } Piece val3 = val.GetComponent<Piece>(); if ((Object)(object)val3 == (Object)null) { val3 = val.AddComponent<Piece>(); } val3.m_name = reg.DisplayName; val3.m_description = reg.Description; val3.m_groundOnly = false; val3.m_canBeRemoved = false; GameObject val4 = null; GameObject val5 = null; GameObject val6 = null; GameObject val7 = null; if ((Object)(object)ZNetScene.instance != (Object)null) { val4 = ZNetScene.instance.GetPrefab("vfx_Place_stone"); val5 = ZNetScene.instance.GetPrefab("sfx_build_hammer_stone"); val6 = ZNetScene.instance.GetPrefab("vfx_destroyed"); val7 = ZNetScene.instance.GetPrefab("sfx_clay_pot_break"); } List<EffectData> list = new List<EffectData>(); if ((Object)(object)val4 != (Object)null) { list.Add(new EffectData { m_prefab = val4, m_enabled = true }); } if ((Object)(object)val5 != (Object)null) { list.Add(new EffectData { m_prefab = val5, m_enabled = true }); } EffectList val8 = new EffectList(); val8.m_effectPrefabs = list.ToArray(); val3.m_placeEffect = val8; WearNTear val9 = val.GetComponent<WearNTear>(); if ((Object)(object)val9 == (Object)null) { val9 = val.AddComponent<WearNTear>(); } val9.m_noRoofWear = true; List<EffectData> list2 = new List<EffectData>(); if ((Object)(object)val6 != (Object)null) { list2.Add(new EffectData { m_prefab = val6, m_enabled = true }); } if ((Object)(object)val7 != (Object)null) { list2.Add(new EffectData { m_prefab = val7, m_enabled = true }); } EffectList val10 = new EffectList(); val10.m_effectPrefabs = list2.ToArray(); val9.m_destroyedEffect = val10; Sprite val11 = ResolveCrystalIcon(bundle, reg.PrefabName); if ((Object)(object)val11 != (Object)null) { val3.m_icon = val11; } PieceConfig val12 = new PieceConfig(); val12.PieceTable = reg.PieceTable; val12.Category = CategoryToTab(reg.Category); val12.CraftingStation = reg.CraftingStation; val12.Requirements = reg.Requirements; PieceManager.Instance.AddPiece(new CustomPiece(val, true, val12)); } } private static Sprite ResolveCrystalIcon(AssetBundle bundle, string prefabName) { if ((Object)(object)bundle == (Object)null || string.IsNullOrWhiteSpace(prefabName)) { return null; } Sprite val = bundle.LoadAsset<Sprite>(prefabName); if ((Object)(object)val != (Object)null) { return val; } val = bundle.LoadAsset<Sprite>(prefabName.ToLowerInvariant()); if ((Object)(object)val != (Object)null) { return val; } string[] array = BuildIconFallbacks(prefabName); foreach (string text in array) { if (!string.IsNullOrWhiteSpace(text)) { val = bundle.LoadAsset<Sprite>(text); if ((Object)(object)val != (Object)null) { return val; } val = bundle.LoadAsset<Sprite>(text.ToLowerInvariant()); if ((Object)(object)val != (Object)null) { return val; } } } return null; } private static string[] BuildIconFallbacks(string prefabName) { if (prefabName.StartsWith("Poison_Crystal", StringComparison.Ordinal)) { return new string[3] { "Poison_Crystal", "Poison_Crystal_Small", "Poison_Crystal_Large" }; } if (prefabName.StartsWith("Frost_Crystal", StringComparison.Ordinal)) { return new string[3] { "Frost_Crystal", "Frost_Crystal_Small", "Frost_Crystal_Large" }; } if (prefabName.StartsWith("Fire_Crystal", StringComparison.Ordinal)) { return new string[3] { "Fire_Crystal", "Fire_Crystal_Small", "Fire_Crystal_Large" }; } if (prefabName.StartsWith("Lightning_Crystal", StringComparison.Ordinal)) { return new string[3] { "Lightning_Crystal", "Lightning_Crystal_Small", "Lightning_Crystal_Large" }; } if (prefabName.StartsWith("Raven_Crystal", StringComparison.Ordinal)) { return new string[3] { "Raven_Crystal", "Raven_Crystal_Small", "Raven_Crystal_Large" }; } return new string[0]; } private static RelicRegistration CreateElementCrystal(string prefabName, string displayName, string essenceName, int amount) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown return new RelicRegistration(prefabName, displayName, (RequirementConfig[])(object)new RequirementConfig[1] { new RequirementConfig(essenceName, amount, 0, true) }, "Can be planted with the cultivator.", "Cultivator"); } private static RelicRegistration CreateRavenCrystal(string prefabName, string displayName, int poisonAmount, int frostAmount, int fireAmount, int lightningAmount) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown return new RelicRegistration(prefabName, displayName, (RequirementConfig[])(object)new RequirementConfig[4] { new RequirementConfig("Essence_Poison", poisonAmount, 0, true), new RequirementConfig("Essence_Frost", frostAmount, 0, true), new RequirementConfig("Essence_Fire", fireAmount, 0, true), new RequirementConfig("Essence_Lightning", lightningAmount, 0, true) }, "Can be planted with the cultivator.", "Cultivator"); } }