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 BoneSpire v0.1.6
BepInEx/plugins/BoneSpire/BoneSpire.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("BoneSpire")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.6.0")] [assembly: AssemblyInformationalVersion("0.1.6")] [assembly: AssemblyProduct("BoneSpire")] [assembly: AssemblyTitle("BoneSpire")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")] [assembly: AssemblyVersion("0.1.6.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace GreyPoint.BoneSpire { internal static class SpireAccess { private static readonly FieldInfo Current = AccessTools.Field(typeof(InventoryGui), "m_currentContainer"); internal static bool InRange(SpireBehaviour spire, Humanoid player) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)spire == (Object)null || (Object)(object)player == (Object)null) { return false; } float num = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_autoCloseDistance : 4f); Player val = (Player)(object)((player is Player) ? player : null); if (val != null) { num = Mathf.Min(num, val.m_maxInteractDistance); } Vector3 position = ((Component)player).transform.position; float num2 = float.PositiveInfinity; Transform val2 = ((Component)spire).transform.Find("BS_Collision"); if ((Object)(object)val2 == (Object)null) { return false; } Collider[] components = ((Component)val2).GetComponents<Collider>(); foreach (Collider val3 in components) { float num3 = num2; Vector3 val4 = val3.ClosestPoint(position) - position; num2 = Mathf.Min(num3, ((Vector3)(ref val4)).sqrMagnitude); } return num2 <= num * num; } internal static float ContainerDistance(Vector3 containerPosition, Vector3 playerPosition, InventoryGui gui, Player player) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) object? value = Current.GetValue(gui); Container val = (Container)((value is Container) ? value : null); SpireBehaviour spireBehaviour = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<SpireBehaviour>() : null); if (!((Object)(object)spireBehaviour == (Object)null)) { if (!InRange(spireBehaviour, (Humanoid)(object)player)) { return gui.m_autoCloseDistance + 1f; } return 0f; } return Vector3.Distance(containerPosition, playerPosition); } } [HarmonyPatch(typeof(Container), "Interact")] internal static class SpireInteractRangePatch { private static bool Prefix(Container __instance, Humanoid __0, ref bool __result) { SpireBehaviour component = ((Component)__instance).GetComponent<SpireBehaviour>(); if ((Object)(object)component == (Object)null || SpireAccess.InRange(component, __0)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(InventoryGui), "UpdateContainer")] internal static class SpireContainerRangePatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = instructions.ToList(); MethodInfo distance = AccessTools.Method(typeof(Vector3), "Distance", new Type[2] { typeof(Vector3), typeof(Vector3) }, (Type[])null); if (list.Count((CodeInstruction i) => CodeInstructionExtensions.Calls(i, distance)) != 1) { throw new InvalidOperationException("Inventory distance hook changed; update Bone Spire for this game version."); } foreach (CodeInstruction instruction in list) { if (!CodeInstructionExtensions.Calls(instruction, distance)) { yield return instruction; continue; } CodeInstruction val = new CodeInstruction(OpCodes.Ldarg_0, (object)null); val.labels.AddRange(instruction.labels); instruction.labels.Clear(); val.blocks.AddRange(instruction.blocks); instruction.blocks.Clear(); yield return val; yield return new CodeInstruction(OpCodes.Ldarg_1, (object)null); instruction.operand = AccessTools.Method(typeof(SpireAccess), "ContainerDistance", (Type[])null, (Type[])null); yield return instruction; } } } public sealed class SpireBehaviour : MonoBehaviour { public bool IsGreater; public Transform VisualRoot; public BoxCollider GrowingBody; public Transform UpperPost; public Transform TopPost; private int _variant; private int _detail = -1; private float _nextDetail; private Container _container; private ZNetView _view; private Inventory _inventory; private int _stage = -1; private bool _hadBones; private float _nextRefresh; private bool _visualError; internal const string CountKey = "gp_bs_bones_v1"; public int Capacity => SpireRules.Capacity(IsGreater, StorageRules.BoneStackSize()); public int Stored { get; private set; } private void Start() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) _view = ((Component)this).GetComponent<ZNetView>(); _container = ((Component)this).GetComponent<Container>(); if (!((Object)(object)_view == (Object)null) && _view.IsValid() && !((Object)(object)_container == (Object)null)) { Vector3 position = ((Component)this).transform.position; int num = (Mathf.RoundToInt(position.x * 10f) * 73856093) ^ (Mathf.RoundToInt(position.z * 10f) * 19349663); _variant = (int)((!IsGreater) ? ((uint)num % 3u) : 0); if (!IsGreater) { VisualRoot.localRotation = Quaternion.Euler(0f, (float)((uint)num % 360u), 0f); } _inventory = _container.GetInventory(); if (_inventory != null) { StorageRules.Track(_inventory, this); Inventory inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(InventoryChanged)); SpawnProtection.Invalidate(); Refresh(); } } } private void OnDestroy() { if (_inventory != null) { Inventory inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Remove(inventory.m_onChanged, new Action(InventoryChanged)); StorageRules.Untrack(_inventory); } SpawnProtection.Invalidate(); } private void InventoryChanged() { StorageRules.Repack(_inventory, notify: true); if ((Object)(object)_view != (Object)null && _view.IsValid() && _view.IsOwner()) { int num = StorageRules.Count(_inventory); ZDO zDO = _view.GetZDO(); if (zDO.GetInt("gp_bs_bones_v1", -1) != num) { zDO.Set("gp_bs_bones_v1", num); } } _nextRefresh = 0f; SpawnProtection.Invalidate(); Refresh(); } private void Update() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_006b: Unknown result type (might be due to invalid IL or missing references) if (Time.time >= _nextDetail) { _nextDetail = Time.time + 0.35f; Camera main = Camera.main; float num = (((Object)(object)main != (Object)null) ? Vector3.Distance(((Component)main).transform.position, ((Component)this).transform.position + Vector3.up * (IsGreater ? 10f : 6f)) : 0f); int num2 = ((num > 200f) ? 3 : ((num > 70f) ? 2 : ((num > 25f) ? 1 : 0))); if (num2 != _detail) { _detail = num2; BoneMesh.SetModel(VisualRoot, IsGreater, Math.Max(0, _stage), num2, _variant); } } if (_inventory != null && !(Time.time < _nextRefresh)) { _nextRefresh = Time.time + 0.5f; Refresh(); } } private void Refresh() { //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_view == (Object)null || !_view.IsValid()) { return; } int num = StorageRules.Count(_inventory); if (_view.IsOwner()) { if (_view.GetZDO().GetInt("gp_bs_bones_v1", -1) != num) { _view.GetZDO().Set("gp_bs_bones_v1", num); } } else { num = _view.GetZDO().GetInt("gp_bs_bones_v1", num); } if (Stored != num) { SpawnProtection.Invalidate(); } Stored = num; int num2 = SpireRules.Stage(num, IsGreater, Capacity); bool flag = num > 0; if (_visualError || (num2 == _stage && (IsGreater || flag == _hadBones))) { return; } try { BoneMesh.SetModel(VisualRoot, IsGreater, num2, Math.Max(0, _detail), _variant); if (!IsGreater) { float num3 = SpireRules.LesserHeight(num2); NativeTimber.Show(UpperPost, num3 > 4f); NativeTimber.Show(TopPost, num3 > 8f); if ((Object)(object)GrowingBody != (Object)null) { GrowingBody.center = new Vector3(0f, num3 * 0.5f, 0f); GrowingBody.size = new Vector3(GrowingBody.size.x, num3, GrowingBody.size.z); } } _stage = num2; _hadBones = flag; } catch (Exception ex) { _visualError = true; BoneSpirePlugin.Log.LogError((object)("Spire visual update failed; retaining last model. " + ex)); } } public string Status() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) string text = "\nBone Fragments: " + Stored + " / " + Capacity; if (IsGreater) { float lesserBonus = SpawnProtection.BonusAt(((Component)this).transform.position); text = text + "\nProtection: " + SpireRules.Radius(Stored, Capacity, lesserBonus).ToString("0.##") + "m | Lesser bonus: +" + lesserBonus.ToString("0.##") + "m"; } else { text = text + "\nHeight: " + SpireRules.LesserHeight(SpireRules.Stage(Stored, greater: false, Capacity)).ToString("0") + "m"; float num = SpireRules.LesserBonus(Stored, Capacity); text = ((!(num <= 0f)) ? (text + (SpawnProtection.HasGreaterAt(((Component)this).transform.position) ? ("\nActive: +" + num.ToString("0.##") + "m to nearby Greater Spires.") : ("\nAvailable bonus: +" + num.ToString("0.##") + "m. No Greater Spire within 100m."))) : (text + "\nAdd Bone Fragments to contribute up to +5m protection.")); } if (StorageRules.IsRecovering(_inventory)) { text += "\nLegacy contents preserved. Withdraw items to finish resizing."; } return text; } } [HarmonyPatch(typeof(Container), "GetHoverText")] internal static class SpireHoverPatch { private static void Postfix(Container __instance, ref string __result) { SpireBehaviour component = ((Component)__instance).GetComponent<SpireBehaviour>(); if ((Object)(object)component != (Object)null) { __result = (SpireAccess.InRange(component, (Humanoid)(object)Player.m_localPlayer) ? (__result + component.Status()) : __instance.GetHoverName()); } } } internal static class StorageRules { private sealed class State { public SpireBehaviour Spire; public int Loading; public bool Repacking; } private static readonly ConditionalWeakTable<Inventory, State> States = new ConditionalWeakTable<Inventory, State>(); private static readonly FieldInfo WidthField = AccessTools.Field(typeof(Inventory), "m_width"); private static readonly FieldInfo HeightField = AccessTools.Field(typeof(Inventory), "m_height"); internal static int BoneStackSize() { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("BoneFragments") : null); if (!((Object)(object)val != (Object)null)) { return 50; } return Math.Max(1, val.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize); } internal static bool IsRecovering(Inventory inv) { if (inv != null && States.TryGetValue(inv, out var value) && (Object)(object)value.Spire != (Object)null) { return inv.GetAllItems().Count > SpireRules.Width(value.Spire.IsGreater) * SpireRules.Rows(value.Spire.IsGreater); } return false; } internal static void PrepareLoad(Container container) { SpireBehaviour component = ((Component)container).GetComponent<SpireBehaviour>(); Inventory inventory = container.GetInventory(); if (!((Object)(object)component == (Object)null) && inventory != null) { Track(inventory, component); WidthField.SetValue(inventory, Math.Max(8, inventory.GetWidth())); HeightField.SetValue(inventory, Math.Max(SpireRules.RecoveryRows(greater: false, 120), inventory.GetHeight())); } } internal static void Repack(Inventory inv, bool notify) { //IL_0140: 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_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) if (inv == null || !States.TryGetValue(inv, out var value) || (Object)(object)value.Spire == (Object)null || value.Loading > 0 || value.Repacking) { return; } value.Repacking = true; try { int width = SpireRules.Width(value.Spire.IsGreater); ItemData[] array = (from i in inv.GetAllItems() orderby i.m_gridPos.y, i.m_gridPos.x select i).ToArray(); int neededRows = SpireRules.RecoveryRows(value.Spire.IsGreater, array.Length); WidthField.SetValue(inv, width); HeightField.SetValue(inv, neededRows); HashSet<long> occupied = new HashSet<long>(); if (!array.Any((ItemData i) => i.m_gridPos.x < 0 || i.m_gridPos.x >= width || i.m_gridPos.y < 0 || i.m_gridPos.y >= neededRows || !occupied.Add((long)i.m_gridPos.y * (long)width + i.m_gridPos.x))) { return; } bool flag = false; Vector2i val = default(Vector2i); for (int num = 0; num < array.Length; num++) { ((Vector2i)(ref val))..ctor(num % width, num / width); if (array[num].m_gridPos.x != val.x || array[num].m_gridPos.y != val.y) { array[num].m_gridPos = val; flag = true; } } if (flag && notify) { inv.m_onChanged?.Invoke(); } } finally { value.Repacking = false; } } internal static void Track(Inventory inv, SpireBehaviour spire) { States.GetOrCreateValue(inv).Spire = spire; } internal static void Untrack(Inventory inv) { if (States.TryGetValue(inv, out var value)) { value.Spire = null; } } internal static void BeginLoad(Inventory inv) { States.GetOrCreateValue(inv).Loading++; } internal static void EndLoad(Inventory inv) { if (States.TryGetValue(inv, out var value)) { value.Loading = Math.Max(0, value.Loading - 1); } } internal static bool IsBone(ItemData item) { if (item == null) { return false; } if (!((Object)(object)item.m_dropPrefab != (Object)null)) { if (item.m_shared != null) { return item.m_shared.m_name == "$item_bonefragments"; } return false; } return Utils.GetPrefabName(item.m_dropPrefab) == "BoneFragments"; } internal static int Count(Inventory inv) { long num = 0L; if (inv != null) { foreach (ItemData allItem in inv.GetAllItems()) { if (IsBone(allItem)) { num += Math.Max(0, allItem.m_stack); } } } return (int)Math.Min(2147483647L, num); } internal static bool Allows(Inventory inv, ItemData item, int amount) { if (inv == null || !States.TryGetValue(inv, out var value) || (Object)(object)value.Spire == (Object)null || value.Loading > 0) { return true; } if (item != null && inv.ContainsItem(item)) { return true; } if (IsRecovering(inv)) { return false; } return SpireRules.CanDeposit(IsBone(item), Count(inv), (amount >= 0) ? amount : (item?.m_stack ?? 0), value.Spire.Capacity); } internal static bool CheckArgs(Inventory inv, object[] args) { object obj = args[0]; ItemData item = (ItemData)((obj is ItemData) ? obj : null); object obj2 = args[0]; GameObject val = (GameObject)((obj2 is GameObject) ? obj2 : null); if (val != null) { item = val.GetComponent<ItemDrop>()?.m_itemData; } int amount = ((args.Length > 1 && args[1] is int num) ? num : (-1)); return Allows(inv, item, amount); } } [HarmonyPatch(typeof(Container), "Load")] internal static class BoneContainerResizePatch { private static void Prefix(Container __instance) { StorageRules.PrepareLoad(__instance); } private static void Postfix(Container __instance) { if (!((Object)(object)((Component)__instance).GetComponent<SpireBehaviour>() == (Object)null)) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); StorageRules.Repack(__instance.GetInventory(), (Object)(object)component != (Object)null && component.IsValid() && component.IsOwner()); } } } [HarmonyPatch] internal static class BoneInventoryAddPatch { private static IEnumerable<MethodBase> TargetMethods() { return from m in typeof(Inventory).GetMethods(AccessTools.all) where (m.Name == "AddItem" || m.Name == "CanAddItem") && m.ReturnType == typeof(bool) && m.GetParameters().Length != 0 && (m.GetParameters()[0].ParameterType == typeof(ItemData) || m.GetParameters()[0].ParameterType == typeof(GameObject)) select m; } private static bool Prefix(Inventory __instance, object[] __args, ref bool __result) { if (StorageRules.CheckArgs(__instance, __args)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[] { typeof(Inventory), typeof(ItemData) })] internal static class BoneInventoryMovePatch { private static bool Prefix(Inventory __instance, Inventory __0, ItemData __1) { if (__instance != __0) { return StorageRules.Allows(__instance, __1, -1); } return true; } } [HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[] { typeof(Inventory), typeof(ItemData), typeof(int), typeof(int), typeof(int) })] internal static class BoneInventoryMoveAtPatch { private static bool Prefix(Inventory __instance, Inventory __0, ItemData __1, int __2, ref bool __result) { if (__instance == __0 || StorageRules.Allows(__instance, __1, __2)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(InventoryGrid), "DropItem")] internal static class BoneInventoryDropPatch { private static bool Prefix(InventoryGrid __instance, Inventory __0, ItemData __1, int __2, ref bool __result) { Inventory inventory = __instance.GetInventory(); if (inventory == __0 || StorageRules.Allows(inventory, __1, __2)) { return true; } Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, StorageRules.IsBone(__1) ? "Bone storage is full. Split the stack to fit the remaining capacity." : "Bone Spires only accept Bone Fragments.", 0, (Sprite)null, false); } __result = false; return false; } } [HarmonyPatch] internal static class BoneInventoryLoadPatch { private static IEnumerable<MethodBase> TargetMethods() { return from m in typeof(Inventory).GetMethods(AccessTools.all) where m.Name == "Load" select m; } private static void Prefix(Inventory __instance) { StorageRules.BeginLoad(__instance); } private static void Finalizer(Inventory __instance) { StorageRules.EndLoad(__instance); } } public static class SpireRules { public const int GreaterWidth = 8; public const int GreaterHeight = 4; public const int LesserWidth = 3; public const int LesserRows = 2; public const int GreaterCapacity = 1600; public const int LesserCapacity = 300; public const float MinimumRadius = 10f; public const float MaximumRadius = 100f; public const float LinkRadius = 100f; public const float SatelliteBonus = 5f; public static int Width(bool greater) { if (!greater) { return 3; } return 8; } public static int Rows(bool greater) { if (!greater) { return 2; } return 4; } public static int Capacity(bool greater, int stackSize) { return (int)Math.Min(2147483647L, (long)Width(greater) * (long)Rows(greater) * Math.Max(1, stackSize)); } public static int RecoveryRows(bool greater, int itemCount) { return (int)Math.Max(Rows(greater), ((long)Math.Max(0, itemCount) + (long)Width(greater) - 1) / Width(greater)); } public static int Stage(int stored, bool greater, int capacity = 0) { if (capacity <= 0) { capacity = (greater ? 1600 : 300); } int num = (int)((long)Math.Max(0, Math.Min(capacity, stored)) * 20L / capacity); if (greater || stored <= 0) { return num; } return Math.Max(1, num); } public static float LesserHeight(int stage) { if (stage < 11) { if (stage < 4) { return 4f; } return 8f; } return 12f; } public static bool Full(int stored, int capacity) { if (capacity > 0) { return stored >= capacity; } return false; } public static float Fill(int stored, int capacity) { if (capacity <= 0) { return 0f; } return (float)Math.Max(0.0, Math.Min(1.0, (double)stored / (double)capacity)); } public static float LesserBonus(int stored, int capacity) { return 5f * Fill(stored, capacity); } public static float Radius(int stored, int capacity, float lesserBonus) { return 10f + 90f * Fill(stored, capacity) + Math.Max(0f, lesserBonus); } public static bool Within(float ax, float az, float bx, float bz, float radius) { double num = (double)ax - (double)bx; double num2 = (double)az - (double)bz; return num * num + num2 * num2 <= (double)radius * (double)radius; } public static bool CanDeposit(bool bone, int stored, int amount, int capacity) { if (bone && amount > 0 && stored >= 0) { return (long)stored + (long)amount <= capacity; } return false; } public static bool ShouldSuppressSpawn(bool protectedPosition, bool hostileFaction, bool raid) { if (protectedPosition) { return hostileFaction || raid; } return false; } } public sealed class BakedMeshData { public byte Tier; public byte Material; public byte Kind; public byte Fill; public float[] Vertices; public int VertexCount => Vertices.Length / 6; public static List<BakedMeshData> Read(string path) { using FileStream stream = File.OpenRead(path); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using BinaryReader binaryReader = new BinaryReader(gZipStream); if (new string(binaryReader.ReadChars(4)) != "BSMD" || binaryReader.ReadByte() != 1) { throw new InvalidDataException("Invalid Bone Spire mesh header: " + path); } if (binaryReader.ReadBytes(3).Length != 3) { throw new EndOfStreamException(); } int num = binaryReader.ReadInt32(); int num2 = 0; if (num < 1 || num > 1024) { throw new InvalidDataException("Invalid mesh count"); } List<BakedMeshData> list = new List<BakedMeshData>(num); for (int i = 0; i < num; i++) { BakedMeshData bakedMeshData = new BakedMeshData { Tier = binaryReader.ReadByte(), Material = binaryReader.ReadByte(), Kind = binaryReader.ReadByte(), Fill = binaryReader.ReadByte() }; int num3 = binaryReader.ReadInt32(); if (num3 < 3 || num3 > 4000000 || num3 % 3 != 0 || bakedMeshData.Tier > 20 || bakedMeshData.Material > 8 || bakedMeshData.Kind > 3 || bakedMeshData.Fill > 100) { throw new InvalidDataException("Invalid mesh record " + i); } checked { num2 += num3; if (num2 > 5000000) { throw new InvalidDataException("Mesh vertex budget exceeded"); } bakedMeshData.Vertices = new float[num3 * 6]; } for (int j = 0; j < bakedMeshData.Vertices.Length; j++) { float num4 = binaryReader.ReadSingle(); if (float.IsNaN(num4) || float.IsInfinity(num4)) { throw new InvalidDataException("Non-finite mesh coordinate"); } bakedMeshData.Vertices[j] = num4; } list.Add(bakedMeshData); } if (gZipStream.ReadByte() != -1) { throw new InvalidDataException("Unexpected trailing mesh data"); } return list; } } internal static class ReleaseExport { internal static void Save() { if (SpireThumbnail.GreaterPng == null || SpireThumbnail.LesserPng == null) { return; } string text = null; try { string text2 = Path.Combine(Paths.ConfigPath, "BoneSpire"); Directory.CreateDirectory(text2); File.WriteAllBytes(Path.Combine(text2, "BoneSpire-Greater-icon.png"), SpireThumbnail.GreaterPng); File.WriteAllBytes(Path.Combine(text2, "BoneSpire-Lesser-icon.png"), SpireThumbnail.LesserPng); string text3 = Path.Combine(text2, "BoneSpire_0.1.6_Thunderstore.zip"); text = text3 + ".tmp"; using (FileStream stream = File.Create(text)) { using ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Create); Write(archive, "icon.png", SpireThumbnail.GreaterPng); Assembly assembly = typeof(BoneSpirePlugin).Assembly; string[] array = new string[3] { "manifest.json", "README.md", "CHANGELOG.md" }; foreach (string text4 in array) { using Stream stream2 = assembly.GetManifestResourceStream("BoneSpire.Release." + text4); if (stream2 == null) { throw new InvalidDataException("Missing package document: " + text4); } using MemoryStream memoryStream = new MemoryStream(); stream2.CopyTo(memoryStream); Write(archive, text4, memoryStream.ToArray()); } Write(archive, "BepInEx/plugins/BoneSpire/BoneSpire.dll", File.ReadAllBytes(assembly.Location)); array = new string[4] { "greater", "lesser", "lesser_v1", "lesser_v2" }; foreach (string text5 in array) { for (int j = 0; j < 3; j++) { string text6 = text5 + ((j == 0) ? "" : ("_lod" + j)) + ".bsm"; Write(archive, "BepInEx/plugins/BoneSpire/Assets/" + text6, File.ReadAllBytes(Path.Combine(BoneSpirePlugin.AssetDirectory, text6))); } } Write(archive, "BepInEx/plugins/BoneSpire/Assets/greater-icon.png", SpireThumbnail.GreaterPng); Write(archive, "BepInEx/plugins/BoneSpire/Assets/lesser-icon.png", SpireThumbnail.LesserPng); } if (File.Exists(text3)) { File.Replace(text, text3, null); } else { File.Move(text, text3); } text = null; BoneSpirePlugin.Log.LogInfo((object)("Exported Bone Spire upload package with the in-game icon: " + text3)); } catch (Exception ex) { BoneSpirePlugin.Log.LogWarning((object)("Could not export Bone Spire artwork/package: " + ex.Message)); } finally { try { if (text != null && File.Exists(text)) { File.Delete(text); } } catch (Exception ex2) { BoneSpirePlugin.Log.LogWarning((object)("Could not remove incomplete package: " + ex2.Message)); } } } private static void Write(ZipArchive archive, string name, byte[] bytes) { using Stream stream = archive.CreateEntry(name, CompressionLevel.Optimal).Open(); stream.Write(bytes, 0, bytes.Length); } } public sealed class NativeTimberPart : MonoBehaviour { public Mesh Geometry; } internal static class NativeTimber { internal const float PoleRadius = 0.143f; private static Transform Pole(Transform parent, Vector3 bottom, Vector3 direction, float span, float radius) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) int length = ((span <= 2.05f) ? 2 : 4); return NativePole(parent, bottom, direction, length, span, radius); } private static Transform NativePole(Transform parent, Vector3 bottom, Vector3 direction, int length, float span, float radius) { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0546: Unknown result type (might be due to invalid IL or missing references) GameObject source = PrefabManager.Instance.GetPrefab((length == 4) ? "wood_pole_log_4" : "wood_pole_log"); if ((Object)(object)source == (Object)null) { throw new InvalidOperationException("Native Core Wood pole unavailable: " + length + "m"); } WearNTear component = source.GetComponent<WearNTear>(); MeshRenderer[] array = (((Object)(object)component != (Object)null && (Object)(object)component.m_new != (Object)null) ? component.m_new : source).GetComponentsInChildren<MeshRenderer>(true).Where(delegate(MeshRenderer r) { MeshFilter component2 = ((Component)r).GetComponent<MeshFilter>(); return (Object)(object)((component2 != null) ? component2.sharedMesh : null) != (Object)null && !Damaged(((Component)r).transform, source.transform); }).ToArray(); if (array.Length == 0) { throw new InvalidOperationException("Native Core Wood visual missing."); } Bounds val = default(Bounds); bool flag = true; MeshRenderer[] array2 = array; foreach (MeshRenderer val2 in array2) { Bounds bounds = ((Component)val2).GetComponent<MeshFilter>().sharedMesh.bounds; for (int num2 = 0; num2 < 8; num2++) { Vector3 val3 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((num2 & 1) != 0) ? 1 : (-1)), (float)(((num2 & 2) != 0) ? 1 : (-1)), (float)(((num2 & 4) != 0) ? 1 : (-1)))); val3 = source.transform.InverseTransformPoint(((Component)val2).transform.TransformPoint(val3)); if (flag) { ((Bounds)(ref val))..ctor(val3, Vector3.zero); flag = false; } else { ((Bounds)(ref val)).Encapsulate(val3); } } } Vector3 val4 = ((Bounds)(ref val)).center - Vector3.up * ((float)length * 0.5f); float num3 = (float)Math.Sqrt((double)((Bounds)(ref val)).extents.x * (double)((Bounds)(ref val)).extents.x + (double)((Bounds)(ref val)).extents.z * (double)((Bounds)(ref val)).extents.z); if (array.All((MeshRenderer r) => ((Component)r).GetComponent<MeshFilter>().sharedMesh.isReadable)) { float num4 = 0f; array2 = array; foreach (MeshRenderer val5 in array2) { Vector3[] vertices = ((Component)val5).GetComponent<MeshFilter>().sharedMesh.vertices; foreach (Vector3 val6 in vertices) { Vector3 val7 = source.transform.InverseTransformPoint(((Component)val5).transform.TransformPoint(val6)) - ((Bounds)(ref val)).center; num4 = Mathf.Max(num4, val7.x * val7.x + val7.z * val7.z); } } num3 = (float)Math.Sqrt(num4); } if (num3 <= 0.001f) { throw new InvalidOperationException("Invalid native Core Wood bounds."); } Transform transform = new GameObject("CoreWood_" + length + "m").transform; transform.SetParent(parent, false); transform.localPosition = bottom; transform.localRotation = Quaternion.FromToRotation(Vector3.up, ((Vector3)(ref direction)).normalized); transform.localScale = new Vector3(radius / num3, span / (float)length, radius / num3); Dictionary<Renderer, Renderer> map = new Dictionary<Renderer, Renderer>(); array2 = array; foreach (MeshRenderer val8 in array2) { GameObject val9 = new GameObject(((Object)val8).name) { layer = ((Component)parent).gameObject.layer }; val9.transform.SetParent(transform, false); val9.transform.localPosition = source.transform.InverseTransformPoint(((Component)val8).transform.position) - val4; val9.transform.localRotation = Quaternion.Inverse(source.transform.rotation) * ((Component)val8).transform.rotation; Vector3 lossyScale = source.transform.lossyScale; Vector3 lossyScale2 = ((Component)val8).transform.lossyScale; val9.transform.localScale = new Vector3(lossyScale2.x / lossyScale.x, lossyScale2.y / lossyScale.y, lossyScale2.z / lossyScale.z); Mesh sharedMesh = ((Component)val8).GetComponent<MeshFilter>().sharedMesh; val9.AddComponent<MeshFilter>().sharedMesh = sharedMesh; val9.AddComponent<NativeTimberPart>().Geometry = sharedMesh; MeshRenderer val10 = val9.AddComponent<MeshRenderer>(); ((Renderer)val10).sharedMaterials = ((Renderer)val8).sharedMaterials; ((Renderer)val10).shadowCastingMode = ((Renderer)val8).shadowCastingMode; ((Renderer)val10).receiveShadows = ((Renderer)val8).receiveShadows; map.Add((Renderer)(object)val8, (Renderer)(object)val10); } LODGroup[] componentsInChildren = source.GetComponentsInChildren<LODGroup>(true); foreach (LODGroup val11 in componentsInChildren) { LOD[] array3 = ((IEnumerable<LOD>)val11.GetLODs()).Select((Func<LOD, LOD>)((LOD l) => new LOD(l.screenRelativeTransitionHeight, (from r in l.renderers where (Object)(object)r != (Object)null && map.ContainsKey(r) select map[r]).ToArray()))).ToArray(); if (array3.Any((LOD l) => l.renderers.Length != 0)) { LODGroup obj = ((Component)transform).gameObject.AddComponent<LODGroup>(); obj.fadeMode = val11.fadeMode; obj.animateCrossFading = val11.animateCrossFading; obj.SetLODs(array3); obj.RecalculateBounds(); break; } } return transform; } private static bool Damaged(Transform node, Transform stop) { while ((Object)(object)node != (Object)null && (Object)(object)node != (Object)(object)stop) { string text = ((Object)node).name.ToLowerInvariant(); if (text.Contains("worn") || text.Contains("broken") || text.Contains("damaged")) { return true; } node = node.parent; } return false; } internal static Transform[] BuildLesser(Transform parent) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) Pole(parent, Vector3.zero, Vector3.up, 4f, 0.143f); Transform val = Pole(parent, Vector3.up * 4f, Vector3.up, 4f, 0.143f); Transform val2 = Pole(parent, Vector3.up * 8f, Vector3.up, 4f, 0.143f); Show(val, visible: false); Show(val2, visible: false); return (Transform[])(object)new Transform[2] { val, val2 }; } internal static void Show(Transform root, bool visible) { if (!((Object)(object)root == (Object)null)) { NativeTimberPart[] componentsInChildren = ((Component)root).GetComponentsInChildren<NativeTimberPart>(true); foreach (NativeTimberPart nativeTimberPart in componentsInChildren) { ((Component)nativeTimberPart).GetComponent<MeshFilter>().sharedMesh = (visible ? nativeTimberPart.Geometry : BoneMesh.Empty); } } } internal static float GreaterRadius(float y) { return 2.55f * (1f - 0.79f * Mathf.Pow(Mathf.Clamp01(y / 20f), 0.982f)); } private static Vector3 At(float angle, float y, float inset = 0.1f) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) return new Vector3(Mathf.Sin(angle), 0f, Mathf.Cos(angle)) * Mathf.Max(0.1f, GreaterRadius(y) - inset) + Vector3.up * y; } private static void Beam(Transform parent, Vector3 a, Vector3 b, float radius) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) Vector3 direction = b - a; Pole(parent, a, direction, ((Vector3)(ref direction)).magnitude, radius); } internal static void BuildGreater(Transform parent) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); for (int i = 0; i < 8; i++) { float num = (float)i * (float)Math.PI / 4f + 0.13f; for (int j = 0; j < 5; j++) { Beam(parent, At(num, j * 4), At(num, (j == 4) ? (20f - 0.28f * (float)(i % 3)) : ((float)((j + 1) * 4))), Mathf.Lerp(0.15f, 0.095f, (float)j / 4f)); } float[] array = new float[5] { 1.8f, 5.8f, 9.8f, 13.8f, 17.8f }; foreach (float num2 in array) { Beam(parent, At(num, num2), At(num + (float)Math.PI / 4f, num2), 0.055f); if (i % 2 == 0) { Beam(parent, At(num, num2), At(num + (float)Math.PI / 4f, num2 + 1.6f), 0.065f); } } if (i % 2 == 0) { float y = 4.2f + (float)i * 1.8f; ((Vector3)(ref val))..ctor(Mathf.Sin(num), 0f, Mathf.Cos(num)); Vector3 val2 = At(num, y); Beam(parent, val2 - val * 0.25f, val2 + val * 1.1f + Vector3.up * 0.35f, 0.075f); } } for (int l = 0; l < 4; l++) { float num3 = (float)l * (float)Math.PI / 2f + (float)Math.PI / 4f; for (int m = 0; m < 5; m++) { Vector3 val3 = new Vector3(Mathf.Sin(num3), 0f, Mathf.Cos(num3)); Vector3 a = val3 * Mathf.Lerp(1.05f, 0.2f, (float)m / 5f) + Vector3.up * (float)(m * 4); Vector3 b = val3 * Mathf.Lerp(1.05f, 0.2f, (float)(m + 1) / 5f) + Vector3.up * ((m == 4) ? (19.45f - 0.12f * (float)l) : ((float)((m + 1) * 4))); Beam(parent, a, b, 0.085f); } } } } [BepInPlugin("greypoint.bonespire", "Bone Spire", "0.1.6")] [BepInDependency("com.jotunn.jotunn", "2.30.2")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class BoneSpirePlugin : BaseUnityPlugin { public const string Guid = "greypoint.bonespire"; public const string Version = "0.1.6"; public const string GreaterName = "gp_bonespire_greater"; public const string LesserName = "gp_bonespire_lesser"; internal static ManualLogSource Log; internal static string AssetDirectory; internal static Material[] Palette; private Harmony _harmony; private void Awake() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; AssetDirectory = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Assets"); try { SpawnProtection.ValidateApi(); _harmony = new Harmony("greypoint.bonespire"); _harmony.PatchAll(typeof(BoneSpirePlugin).Assembly); PrefabManager.OnVanillaPrefabsAvailable += Register; Log.LogInfo((object)"Bone Spire 0.1.6: hooks installed; waiting for vanilla prefabs"); } catch (Exception ex) { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } Log.LogError((object)("Bone Spire initialization failed. No spires registered. " + ex)); } } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= Register; Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } SpireThumbnail.Dispose(); BoneMesh.Dispose(); if (Palette != null) { Material[] palette = Palette; foreach (Material val in palette) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } } SpawnProtection.Reset(); } private void Register() { PrefabManager.OnVanillaPrefabsAvailable -= Register; CustomPiece val = null; bool flag = false; try { Palette = BoneMesh.BuildPalette(); ((Component)this).gameObject.AddComponent<SpireCoverage>().Initialize(); val = CreatePiece(greater: true); CustomPiece val2 = CreatePiece(greater: false); if (!val.IsValid() || !val2.IsValid()) { throw new InvalidOperationException("Invalid spire prefab"); } flag = PieceManager.Instance.AddPiece(val); if (!flag || !PieceManager.Instance.AddPiece(val2)) { throw new InvalidOperationException("Jotunn rejected spire registration"); } ReleaseExport.Save(); Log.LogInfo((object)"Registered Greater and Lesser Bone Spires in Hammer > Misc; bone-only storage; hostile spawn protection active."); } catch (Exception ex) { if (flag) { PieceManager.Instance.RemovePiece(val); } Log.LogError((object)("Bone Spire prefab registration failed: " + ex)); } } private static CustomPiece CreatePiece(bool greater) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Expected O, but got Unknown //IL_0372: Unknown result type (might be due to invalid IL or missing references) string text = (greater ? "gp_bonespire_greater" : "gp_bonespire_lesser"); string name = (greater ? "Greater Bone Spire" : "Lesser Bone Spire"); PieceConfig val = new PieceConfig(); val.Name = name; val.Description = (greater ? "Stores Bone Fragments. Protection grows from 10m to 100m as it fills. Lesser Spires within 100m contribute up to 5m each." : "Grows from 4m to 12m. Adds up to 5m to Greater Spires within 100m, proportional to stored Bone Fragments. No protection on its own."); val.PieceTable = "Hammer"; val.Category = "Misc"; val.Usage = new string[2] { "Misc", "Storage" }; PieceConfig val2 = val; val2.AddRequirement("BoneFragments", greater ? 100 : 20, true); val2.AddRequirement("RoundLog", (!greater) ? 1 : 10, true); CustomPiece val3 = new CustomPiece(text, "piece_chest_wood", val2); GameObject piecePrefab = val3.PiecePrefab; if ((Object)(object)piecePrefab == (Object)null) { throw new InvalidOperationException("Failed to clone chest for " + text); } Container component = piecePrefab.GetComponent<Container>(); WearNTear component2 = piecePrefab.GetComponent<WearNTear>(); ZNetView component3 = piecePrefab.GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null) { throw new InvalidOperationException("Chest components missing"); } component.m_name = name; component.m_width = SpireRules.Width(greater); component.m_height = SpireRules.Rows(greater); component.m_privacy = (PrivacySetting)2; component.m_autoDestroyEmpty = false; component.m_open = null; component.m_closed = null; component.m_defaultItems = new DropTable(); component3.m_persistent = true; Collider componentInChildren = piecePrefab.GetComponentInChildren<Collider>(true); int layer = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).gameObject.layer : piecePrefab.layer); Renderer[] componentsInChildren = piecePrefab.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } Collider[] componentsInChildren2 = piecePrefab.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } EffectArea[] componentsInChildren3 = piecePrefab.GetComponentsInChildren<EffectArea>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[i]); } Animator[] componentsInChildren4 = piecePrefab.GetComponentsInChildren<Animator>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { ((Behaviour)componentsInChildren4[i]).enabled = false; } LODGroup[] componentsInChildren5 = piecePrefab.GetComponentsInChildren<LODGroup>(true); for (int i = 0; i < componentsInChildren5.Length; i++) { componentsInChildren5[i].enabled = false; } component2.m_new = null; component2.m_worn = null; component2.m_broken = null; component2.m_wet = null; component2.m_noRoofWear = true; component2.m_noSupportWear = true; component2.m_autoCreateFragments = false; component2.m_fragmentRoots = Array.Empty<GameObject>(); val3.Piece.m_groundOnly = true; val3.Piece.m_clipGround = true; GameObject val4 = new GameObject("BS_Collision"); val4.layer = layer; val4.transform.SetParent(piecePrefab.transform, false); BoxCollider growingBody = null; if (greater) { AddBox(val4, 0f, 4f, 4.7f); AddBox(val4, 4f, 8f, 3.9f); AddBox(val4, 8f, 12f, 3.1f); AddBox(val4, 12f, 16f, 2.3f); AddBox(val4, 16f, 20f, 1.5f); } else { growingBody = AddBox(val4, 0f, 4f, 0.68f); } Transform transform = new GameObject("BS_CoreWood").transform; transform.SetParent(piecePrefab.transform, false); Transform[] array = null; if (greater) { NativeTimber.BuildGreater(transform); } else { array = NativeTimber.BuildLesser(transform); } Transform val5 = BoneMesh.Create(greater ? "greater.bsm" : "lesser.bsm", piecePrefab.transform); BoneMesh.SetModel(val5, greater, 0, 0); SpireBehaviour spireBehaviour = piecePrefab.AddComponent<SpireBehaviour>(); spireBehaviour.IsGreater = greater; spireBehaviour.VisualRoot = val5; spireBehaviour.GrowingBody = growingBody; spireBehaviour.UpperPost = ((array != null) ? array[0] : null); spireBehaviour.TopPost = ((array != null) ? array[1] : null); GameObject prefab = PrefabManager.Instance.GetPrefab("BoneFragments"); ItemDrop val6 = ((prefab != null) ? prefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val6 != (Object)null && val6.m_itemData.m_shared.m_icons.Length != 0) { val3.Piece.m_icon = val6.m_itemData.m_shared.m_icons[0]; } SpireThumbnail.Apply(piecePrefab, greater); return val3; } private static BoxCollider AddBox(GameObject obj, float bottom, float top, float width) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) BoxCollider obj2 = obj.AddComponent<BoxCollider>(); obj2.center = new Vector3(0f, (bottom + top) * 0.5f, 0f); obj2.size = new Vector3(width, top - bottom, width); return obj2; } } internal static class SpireThumbnail { private static Sprite greaterCached; private static Sprite lesserCached; internal static byte[] GreaterPng; internal static byte[] LesserPng; private static readonly List<Sprite> Fallbacks = new List<Sprite>(); internal static void Dispose() { Sprite[] array = (Sprite[])(object)new Sprite[2] { greaterCached, lesserCached }; foreach (Sprite val in array) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val.texture); Object.Destroy((Object)(object)val); } } greaterCached = (lesserCached = null); foreach (Sprite fallback in Fallbacks) { if ((Object)(object)fallback != (Object)null) { Object.Destroy((Object)(object)fallback.texture); Object.Destroy((Object)(object)fallback); } } Fallbacks.Clear(); GreaterPng = (LesserPng = null); } private static void Soften(Texture2D texture) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: 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_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) int width = ((Texture)texture).width; int height = ((Texture)texture).height; Color[] pixels = texture.GetPixels(); Color[] array = (Color[])(object)new Color[pixels.Length]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { Color clear = Color.clear; float num = 0f; float num2 = 0f; for (int k = -1; k <= 1; k++) { for (int l = -1; l <= 1; l++) { int num3 = Mathf.Clamp(j + l, 0, width - 1); int num4 = Mathf.Clamp(i + k, 0, height - 1); float num5 = ((l == 0) ? 2f : 1f) * ((k == 0) ? 2f : 1f); Color val = pixels[num4 * width + num3]; clear.r += val.r * val.a * num5; clear.g += val.g * val.a * num5; clear.b += val.b * val.a * num5; num += val.a * num5; num2 += num5; } } Color val2 = pixels[i * width + j]; float a = Mathf.Lerp(val2.a, num / num2, 0.3f); float num6 = val2.a * 0.7f + num / num2 * 0.3f; Color clear2 = Color.clear; if (num6 > 1E-05f) { clear2.r = (val2.r * val2.a * 0.7f + clear.r / num2 * 0.3f) / num6 * 0.9f; clear2.g = (val2.g * val2.a * 0.7f + clear.g / num2 * 0.3f) / num6 * 0.9f; clear2.b = (val2.b * val2.a * 0.7f + clear.b / num2 * 0.3f) / num6 * 0.9f; clear2.a = a; } array[i * width + j] = clear2; } } texture.SetPixels(array); } internal static void Apply(GameObject prefab, bool greater) { //IL_0914: Unknown result type (might be due to invalid IL or missing references) //IL_091b: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_008b: 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_055f: Unknown result type (might be due to invalid IL or missing references) //IL_0564: Unknown result type (might be due to invalid IL or missing references) //IL_059b: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05fe: Unknown result type (might be due to invalid IL or missing references) //IL_0603: Unknown result type (might be due to invalid IL or missing references) //IL_0607: Unknown result type (might be due to invalid IL or missing references) //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_0616: Unknown result type (might be due to invalid IL or missing references) //IL_0629: Unknown result type (might be due to invalid IL or missing references) //IL_06ef: Unknown result type (might be due to invalid IL or missing references) //IL_06f4: Unknown result type (might be due to invalid IL or missing references) //IL_0743: Unknown result type (might be due to invalid IL or missing references) //IL_0762: Unknown result type (might be due to invalid IL or missing references) //IL_0768: Expected O, but got Unknown //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_032c: 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_0336: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_0341: 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_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_07e8: Unknown result type (might be due to invalid IL or missing references) //IL_07ee: Expected O, but got Unknown //IL_0803: Unknown result type (might be due to invalid IL or missing references) //IL_0842: Unknown result type (might be due to invalid IL or missing references) //IL_0851: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Expected O, but got Unknown //IL_064e: Unknown result type (might be due to invalid IL or missing references) //IL_0655: Unknown result type (might be due to invalid IL or missing references) //IL_0663: Unknown result type (might be due to invalid IL or missing references) //IL_0668: Unknown result type (might be due to invalid IL or missing references) //IL_066d: Unknown result type (might be due to invalid IL or missing references) //IL_0672: Unknown result type (might be due to invalid IL or missing references) //IL_067b: Unknown result type (might be due to invalid IL or missing references) //IL_067d: Unknown result type (might be due to invalid IL or missing references) //IL_0682: Unknown result type (might be due to invalid IL or missing references) //IL_0691: Unknown result type (might be due to invalid IL or missing references) //IL_06a0: Unknown result type (might be due to invalid IL or missing references) //IL_07a8: Unknown result type (might be due to invalid IL or missing references) //IL_07ae: Invalid comparison between Unknown and I4 //IL_0530: Unknown result type (might be due to invalid IL or missing references) //IL_0520: Unknown result type (might be due to invalid IL or missing references) //IL_0525: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) Sprite val = (greater ? greaterCached : lesserCached); if ((Object)(object)val != (Object)null) { prefab.GetComponent<Piece>().m_icon = val; } else { if ((int)SystemInfo.graphicsDeviceType == 4) { return; } try { string path = Path.Combine(BoneSpirePlugin.AssetDirectory, greater ? "greater-icon.png" : "lesser-icon.png"); if (File.Exists(path)) { Texture2D val2 = new Texture2D(2, 2, (TextureFormat)4, false); if (ImageConversion.LoadImage(val2, File.ReadAllBytes(path))) { Sprite val3 = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f), 100f); Fallbacks.Add(val3); prefab.GetComponent<Piece>().m_icon = val3; } else { Object.Destroy((Object)(object)val2); } } } catch (Exception ex) { BoneSpirePlugin.Log.LogWarning((object)("Could not load fallback thumbnail: " + ex.Message)); } GameObject val4 = null; RenderTexture val5 = null; Texture2D val6 = null; RenderTexture active = RenderTexture.active; AmbientMode ambientMode = RenderSettings.ambientMode; Color ambientLight = RenderSettings.ambientLight; bool fog = RenderSettings.fog; List<Material> list = new List<Material>(); List<Light> list2 = new List<Light>(); SpireBehaviour component = prefab.GetComponent<SpireBehaviour>(); try { BoneMesh.SetModel(component.VisualRoot, greater, 20, 0); NativeTimber.Show(component.UpperPost, visible: true); NativeTimber.Show(component.TopPost, visible: true); Shader val7 = Shader.Find("Standard"); if ((Object)(object)val7 == (Object)null) { val7 = Shader.Find("Legacy Shaders/Diffuse"); } if ((Object)(object)val7 == (Object)null) { throw new Exception("Neutral thumbnail shader unavailable."); } RenderSettings.ambientMode = (AmbientMode)3; RenderSettings.ambientLight = new Color(0.55f, 0.55f, 0.55f, 1f); RenderSettings.fog = false; val4 = new GameObject("BoneSpireIconStage"); val4.transform.position = new Vector3(10000f, 10000f, 10000f); HashSet<Renderer> hashSet = new HashSet<Renderer>(); LODGroup[] componentsInChildren = prefab.GetComponentsInChildren<LODGroup>(true); for (int i = 0; i < componentsInChildren.Length; i++) { LOD[] lODs = componentsInChildren[i].GetLODs(); for (int j = 1; j < lODs.Length; j++) { Renderer[] renderers = lODs[j].renderers; foreach (Renderer val8 in renderers) { if ((Object)(object)val8 != (Object)null && (lODs.Length == 0 || Array.IndexOf(lODs[0].renderers, val8) < 0)) { hashSet.Add(val8); } } } } bool flag = false; Bounds val9 = default(Bounds); MeshFilter[] componentsInChildren2 = ((Component)prefab.transform).GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val10 in componentsInChildren2) { MeshRenderer component2 = ((Component)val10).GetComponent<MeshRenderer>(); if ((Object)(object)component2 == (Object)null || !((Renderer)component2).enabled || hashSet.Contains((Renderer)(object)component2) || (Object)(object)val10.sharedMesh == (Object)null || val10.sharedMesh.vertexCount == 0) { continue; } GameObject val11 = new GameObject("IconPart") { layer = 31 }; val11.transform.SetParent(val4.transform, false); Matrix4x4 val12 = prefab.transform.worldToLocalMatrix * ((Component)val10).transform.localToWorldMatrix; val11.transform.localPosition = Vector4.op_Implicit(((Matrix4x4)(ref val12)).GetColumn(3)); val11.transform.localRotation = Quaternion.LookRotation(Vector4.op_Implicit(((Matrix4x4)(ref val12)).GetColumn(2)), Vector4.op_Implicit(((Matrix4x4)(ref val12)).GetColumn(1))); Transform transform = val11.transform; Vector4 column = ((Matrix4x4)(ref val12)).GetColumn(0); float magnitude = ((Vector4)(ref column)).magnitude; column = ((Matrix4x4)(ref val12)).GetColumn(1); float magnitude2 = ((Vector4)(ref column)).magnitude; column = ((Matrix4x4)(ref val12)).GetColumn(2); transform.localScale = new Vector3(magnitude, magnitude2, ((Vector4)(ref column)).magnitude); val11.AddComponent<MeshFilter>().sharedMesh = val10.sharedMesh; MeshRenderer val13 = val11.AddComponent<MeshRenderer>(); Material[] sharedMaterials = ((Renderer)component2).sharedMaterials; Material[] array = (Material[])(object)new Material[sharedMaterials.Length]; for (int l = 0; l < array.Length; l++) { Material val14 = sharedMaterials[l]; Material val15 = new Material(val7); list.Add(val15); if ((Object)(object)val14 != (Object)null) { if (val14.HasProperty("_MainTex")) { val15.mainTexture = val14.GetTexture("_MainTex"); val15.mainTextureScale = val14.GetTextureScale("_MainTex"); val15.mainTextureOffset = val14.GetTextureOffset("_MainTex"); } if (val14.HasProperty("_Color")) { val15.color = val14.GetColor("_Color"); } } if (val15.HasProperty("_Metallic")) { val15.SetFloat("_Metallic", 0f); } if (val15.HasProperty("_Glossiness")) { val15.SetFloat("_Glossiness", 0f); } if (val15.HasProperty("_SpecularHighlights")) { val15.SetFloat("_SpecularHighlights", 0f); } if (val15.HasProperty("_GlossyReflections")) { val15.SetFloat("_GlossyReflections", 0f); } array[l] = val15; } ((Renderer)val13).sharedMaterials = array; if (!flag) { val9 = ((Renderer)val13).bounds; flag = true; } else { ((Bounds)(ref val9)).Encapsulate(((Renderer)val13).bounds); } } if (!flag) { throw new Exception("No wagon visual found for thumbnail."); } GameObject val16 = new GameObject("IconCamera"); val16.transform.SetParent(val4.transform, false); Camera val17 = val16.AddComponent<Camera>(); ((Behaviour)val17).enabled = false; val17.cullingMask = int.MinValue; val17.clearFlags = (CameraClearFlags)2; val17.backgroundColor = Color.clear; val17.orthographic = true; val17.aspect = 1f; val17.nearClipPlane = 0.1f; val17.farClipPlane = 100f; val17.allowHDR = false; val17.allowMSAA = true; Transform transform2 = ((Component)val17).transform; Vector3 center = ((Bounds)(ref val9)).center; Vector3 val18 = new Vector3(10f, 7f, -12f); transform2.position = center + ((Vector3)(ref val18)).normalized * 25f; ((Component)val17).transform.LookAt(((Bounds)(ref val9)).center); float num = 0f; for (int m = -1; m <= 1; m += 2) { for (int n = -1; n <= 1; n += 2) { for (int num2 = -1; num2 <= 1; num2 += 2) { Vector3 val19 = ((Bounds)(ref val9)).center + Vector3.Scale(((Bounds)(ref val9)).extents, new Vector3((float)m, (float)n, (float)num2)); Vector3 val20 = ((Component)val17).transform.InverseTransformPoint(val19); num = Mathf.Max(new float[3] { num, Mathf.Abs(val20.x), Mathf.Abs(val20.y) }); } } } val17.orthographicSize = num * 1.08f; GameObject val21 = new GameObject("IconLight"); val21.transform.SetParent(val4.transform, false); Light val22 = val21.AddComponent<Light>(); val22.type = (LightType)1; val22.intensity = 1f; val22.cullingMask = int.MinValue; ((Component)val22).transform.rotation = Quaternion.Euler(40f, -35f, 0f); val22.shadows = (LightShadows)0; val5 = new RenderTexture(256, 256, 24, (RenderTextureFormat)0); val5.antiAliasing = 4; val5.Create(); val17.targetTexture = val5; Light[] array2 = Object.FindObjectsByType<Light>((FindObjectsSortMode)0); foreach (Light val23 in array2) { if ((Object)(object)val23 != (Object)(object)val22 && ((Behaviour)val23).enabled && (int)val23.type == 1) { list2.Add(val23); ((Behaviour)val23).enabled = false; } } val17.Render(); RenderTexture.active = val5; val6 = new Texture2D(256, 256, (TextureFormat)4, false); val6.ReadPixels(new Rect(0f, 0f, 256f, 256f), 0, 0); Soften(val6); ((Texture)val6).filterMode = (FilterMode)1; val6.Apply(); ((Object)val6).name = "BoneSpireBuildIcon"; Sprite icon = Sprite.Create(val6, new Rect(0f, 0f, 256f, 256f), new Vector2(0.5f, 0.5f), 100f); if (greater) { greaterCached = icon; GreaterPng = ImageConversion.EncodeToPNG(val6); } else { lesserCached = icon; LesserPng = ImageConversion.EncodeToPNG(val6); } prefab.GetComponent<Piece>().m_icon = icon; BoneSpirePlugin.Log.LogDebug((object)("Rendered " + (greater ? "Greater" : "Lesser") + " Bone Spire build-menu thumbnail.")); } catch (Exception ex2) { if ((Object)(object)val6 != (Object)null && (Object)(object)(greater ? greaterCached : lesserCached) == (Object)null) { Object.Destroy((Object)(object)val6); } BoneSpirePlugin.Log.LogWarning((object)("Spire thumbnail failed; retaining original icon: " + ex2.Message)); } finally { RenderTexture.active = active; RenderSettings.ambientMode = ambientMode; RenderSettings.ambientLight = ambientLight; RenderSettings.fog = fog; foreach (Light item in list2) { if ((Object)(object)item != (Object)null) { ((Behaviour)item).enabled = true; } } foreach (Material item2 in list) { Object.Destroy((Object)(object)item2); } if ((Object)(object)val4 != (Object)null) { val4.SetActive(false); Object.Destroy((Object)(object)val4); } if ((Object)(object)val5 != (Object)null) { val5.Release(); Object.Destroy((Object)(object)val5); } BoneMesh.SetModel(component.VisualRoot, greater, 0, 0); NativeTimber.Show(component.UpperPost, visible: false); NativeTimber.Show(component.TopPost, visible: false); } } } } internal static class NativeMaterials { private static readonly Color[] Tints = (Color[])(object)new Color[9] { new Color(0.75f, 0.7f, 0.62f), new Color(0.95f, 0.9f, 0.8f), new Color(1f, 0.98f, 0.88f), new Color(0.48f, 0.37f, 0.23f), new Color(0.9f, 0.86f, 0.76f), new Color(1f, 1f, 0.95f), new Color(0.7f, 0.66f, 0.56f), new Color(0.16f, 0.14f, 0.11f), new Color(0.72f, 0.72f, 0.65f) }; internal static Material[] Build() { //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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) Material val = FindSurface("wood_pole_log", "logwall") ?? FindSurface("wood_pole", null); Material val2 = FindSurface("bone_stack", "bonefragments") ?? FindSurface("BoneFragments", "bonefragments"); Material val3 = FindSurface("LinenThread", "thread") ?? FindSurface("LeatherScraps", "leatherscraps"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { throw new InvalidOperationException("Textured native wood, bone or thread surface unavailable. Refusing to substitute a snow/effect material."); } Shader shader = val.shader; if ((Object)(object)shader == (Object)null) { throw new InvalidOperationException("Native wood surface has no shader reference."); } Material[] array = (Material[])(object)new Material[9]; try { for (int i = 0; i < array.Length; i++) { Material val4 = ((i == 3) ? val3 : ((i <= 2 || i == 8) ? val : val2)); Material val5 = new Material(shader) { name = "BS_Rigid_" + i, renderQueue = 2000 }; Material val6 = (array[i] = val5); val6.SetTexture("_MainTex", val4.GetTexture("_MainTex")); val6.SetTextureScale("_MainTex", Vector2.one); val6.SetTextureOffset("_MainTex", Vector2.zero); if (val6.HasProperty("_MainTex_ST")) { val6.SetVector("_MainTex_ST", new Vector4(1f, 1f, 0f, 0f)); } val6.SetColor("_Color", Tints[i]); if (val4.HasProperty("_BumpMap") && (Object)(object)val4.GetTexture("_BumpMap") != (Object)null) { val6.SetTexture("_BumpMap", val4.GetTexture("_BumpMap")); Set(val6, "_BumpScale", 0.65f); val6.EnableKeyword("_NORMALMAP"); } string[] array2 = new string[8] { "_ALPHATEST_ON", "_ALPHABLEND_ON", "_ALPHAPREMULTIPLY_ON", "_EMISSION", "_ADDSNOW_ON", "_VALUENOISEVERTEX_ON", "_TRIPLANARMAP_ON", "_WIND_ON" }; foreach (string text in array2) { val6.DisableKeyword(text); } array2 = new string[11] { "_Cutoff", "_Metallic", "_MetallicAlphaGloss", "_AddSnow", "_ValueNoise", "_ValueNoiseVertex", "_RippleDistance", "_RippleFreq", "_TriplanarMap", "_Wind", "_WindStrength" }; foreach (string property in array2) { Set(val6, property, 0f); } Set(val6, "_Glossiness", 0.06f); Set(val6, "_Cull", 0f); Set(val6, "_TwoSidedNormals", 1f); Set(val6, "_MoveableObject", 1f); val6.EnableKeyword("_MOVEABLEOBJECT_ON"); val6.EnableKeyword("_TWOSIDEDNORMALS_ON"); if (val6.HasProperty("_EmissionColor")) { val6.SetColor("_EmissionColor", Color.black); } val6.SetOverrideTag("RenderType", "Opaque"); if ((Object)(object)val6.GetTexture("_MainTex") == (Object)null) { throw new InvalidOperationException("Missing albedo after material assembly"); } } KeyValuePair<string, Material>[] array3 = new KeyValuePair<string, Material>[3] { new KeyValuePair<string, Material>("wood", val), new KeyValuePair<string, Material>("bone", val2), new KeyValuePair<string, Material>("lashings", val3) }; for (int j = 0; j < array3.Length; j++) { KeyValuePair<string, Material> keyValuePair = array3[j]; BoneSpirePlugin.Log.LogInfo((object)("Native surface " + keyValuePair.Key + ": " + ((Object)keyValuePair.Value).name + ", albedo=" + ((Object)keyValuePair.Value.GetTexture("_MainTex")).name + "; shader=" + ((Object)shader).name + " (native reference); displacement=off; opaque")); } return array; } catch { Material[] array4 = array; foreach (Material val7 in array4) { if ((Object)(object)val7 != (Object)null) { Object.Destroy((Object)(object)val7); } } throw; } } private static void Set(Material m, string property, float value) { if (m.HasProperty(property)) { m.SetFloat(property, value); } } private static Material FindSurface(string prefabName, string expectedName) { GameObject val = PrefabManager.Instance.GetPrefab(prefabName); if ((Object)(object)val == (Object)null && (Object)(object)ObjectDB.instance != (Object)null) { val = ObjectDB.instance.GetItemPrefab(prefabName); } if ((Object)(object)val == (Object)null) { return null; } Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if (!(val2 is MeshRenderer) && !(val2 is SkinnedMeshRenderer)) { continue; } Material[] sharedMaterials = val2.sharedMaterials; foreach (Material val3 in sharedMaterials) { if ((Object)(object)val3 == (Object)null || (Object)(object)val3.shader == (Object)null || !val3.HasProperty("_MainTex")) { continue; } string text = ((Object)val3).name.Replace(" (Instance)", ""); if (expectedName != null && !text.Equals(expectedName, StringComparison.OrdinalIgnoreCase)) { continue; } string name = ((Object)val3.shader).name; if (!(name != "Custom/Piece") || !(name != "Standard") || !(name != "Custom/Creature")) { Texture texture = val3.GetTexture("_MainTex"); if (!((Object)(object)texture == (Object)null) && texture.width > 4 && texture.height > 4 && text.IndexOf("worn", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("broken", StringComparison.OrdinalIgnoreCase) < 0) { return val3; } } } } return null; } } public sealed class SpireMeshPart : MonoBehaviour { public Mesh Geometry; public int Tier; } public static class BoneMesh { private sealed class Part { public int Tier; public int Material; public int Kind; public Mesh Mesh; } private static readonly Dictionary<string, List<Part>> Cache = new Dictionary<string, List<Part>>(); private static Mesh _empty; internal static Mesh Empty { get { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0024: Expected O, but got Unknown if (!((Object)(object)_empty != (Object)null)) { Mesh val = new Mesh { name = "BS_EmptyStage" }; _empty = val; return val; } return _empty; } } public static Material[] BuildPalette() { return NativeMaterials.Build(); } private static List<Part> Get(string filename) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: 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_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) if (Cache.TryGetValue(filename, out var value)) { return value; } List<Part> list = new List<Part>(); try { Vector3 val2 = default(Vector3); foreach (BakedMeshData item in BakedMeshData.Read(Path.Combine(BoneSpirePlugin.AssetDirectory, filename))) { int vertexCount = item.VertexCount; Vector3[] array = (Vector3[])(object)new Vector3[vertexCount]; Vector3[] array2 = (Vector3[])(object)new Vector3[vertexCount]; Vector2[] array3 = (Vector2[])(object)new Vector2[vertexCount]; Color32[] array4 = (Color32[])(object)new Color32[vertexCount]; int[] array5 = new int[vertexCount]; for (int i = 0; i < vertexCount; i += 3) { int num = i * 6; Vector3 val = new Vector3(item.Vertices[num + 3], item.Vertices[num + 4], item.Vertices[num + 5]); Vector3 normalized = ((Vector3)(ref val)).normalized; int num2 = ((Mathf.Abs(normalized.y) > 0.7f) ? 1 : ((!(Mathf.Abs(normalized.x) > Mathf.Abs(normalized.z))) ? 2 : 0)); float num3 = ((item.Kind == 1) ? 3f : ((item.Kind >= 2) ? 1.6f : 0.6f)); for (int j = 0; j < 3; j++) { int num4 = (i + j) * 6; ((Vector3)(ref val2))..ctor(item.Vertices[num4], item.Vertices[num4 + 1], item.Vertices[num4 + 2]); array[i + j] = val2; array2[i + j] = normalized; array3[i + j] = (Vector2)(num2 switch { 0 => new Vector2(val2.z, val2.y), 1 => new Vector2(val2.x, val2.z), _ => new Vector2(val2.x, val2.y), }) * num3; array4[i + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue); array5[i + j] = i + j; } } Mesh val3 = new Mesh(); ((Object)val3).name = filename + " tier " + item.Tier + " material " + item.Material + " kind " + item.Kind; val3.indexFormat = (IndexFormat)1; Mesh val4 = val3; list.Add(new Part { Tier = item.Tier, Material = item.Material, Kind = item.Kind, Mesh = val4 }); val4.vertices = array; val4.normals = array2; val4.uv = array3; val4.colors32 = array4; val4.triangles = array5; val4.RecalculateBounds(); val4.RecalculateTangents(); val4.UploadMeshData(true); } Cache.Add(filename, list); return list; } catch { foreach (Part item2 in list) { Object.Destroy((Object)(object)item2.Mesh); } throw; } } public static Transform Create(string filename, Transform parent) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) List<Part> list = new List<Part>(Get(filename)); if (filename == "lesser.bsm") { for (int i = 1; i < 3; i++) { foreach (Part part in Get("lesser_v" + i + ".bsm")) { if (!list.Exists((Part p) => PartName(p) == PartName(part))) { list.Add(part); } } } } GameObject val = new GameObject("BS_Visual"); val.transform.SetParent(parent, false); foreach (Part item in list) { GameObject val2 = new GameObject(PartName(item)) { layer = ((Component)parent).gameObject.layer }; val2.transform.SetParent(val.transform, false); val2.AddComponent<MeshFilter>().sharedMesh = item.Mesh; SpireMeshPart spireMeshPart = val2.AddComponent<SpireMeshPart>(); spireMeshPart.Geometry = item.Mesh; spireMeshPart.Tier = item.Tier; MeshRenderer obj = val2.AddComponent<MeshRenderer>(); ((Renderer)obj).sharedMaterial = BoneSpirePlugin.Palette[item.Material]; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)2; } return val.transform; } private static string PartName(Part p) { return "Tier_" + p.Tier + "_Material_" + p.Material + "_Kind_" + p.Kind; } public static void SetModel(Transform root, bool greater, int maxTier, int detail, int variant = 0) { if ((Object)(object)root == (Object)null) { return; } string filename = (greater ? "greater" : ("lesser" + ((variant > 0) ? ("_v" + Math.Min(2, variant)) : ""))) + ((detail == 1) ? "_lod1" : ((detail >= 2) ? "_lod2" : "")) + ".bsm"; List<Part> list = ((detail == 3) ? null : Get(filename)); SpireMeshPart[] componentsInChildren = ((Component)root).GetComponentsInChildren<SpireMeshPart>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).GetComponent<MeshFilter>().sharedMesh = Empty; } if (list == null) { return; } foreach (Part item in list) { Transform obj = root.Find(PartName(item)); if ((Object)(object)obj == (Object)null) { throw new InvalidDataException("Growth/LOD has an unknown renderer slot: " + PartName(item)); } ((Component)obj).GetComponent<MeshFilter>().sharedMesh = ((item.Tier <= maxTier) ? item.Mesh : Empty); } } public static void Dispose() { foreach (List<Part> value in Cache.Values) { foreach (Part item in value) { Object.Destroy((Object)(object)item.Mesh); } } Cache.Clear(); if ((Object)(object)_empty != (Object)null) { Object.Destroy((Object)(object)_empty); } _empty = null; } } internal static class SpawnProtection { internal sealed class Zone { public ZDO Id; public Vector3 Position; public float Radius; } private sealed class Contributor { public Vector3 Position; public float Bonus; } private static readonly FieldInfo ObjectsField = AccessTools.Field(typeof(ZDOMan), "m_objectsByID"); private static readonly int GreaterHash = StringExtensionMethods.GetStableHashCode("gp_bonespire_greater"); private static readonly int LesserHash = StringExtensionMethods.GetStableHashCode("gp_bonespire_lesser"); private static readonly List<Zone> Zones = new List<Zone>(); private static readonly List<Contributor> Lesser = new List<Contributor>(); private static ZDOMan _world; private static float _nextRefresh; private static bool _warned; internal static void ValidateApi() { if (ObjectsField == null || ObjectsField.FieldType != typeof(Dictionary<ZDOID, ZDO>)) { throw new MissingFieldException("ZDOMan.m_objectsByID contract changed; update Bone Spire for this game version."); } if (AccessTools.Method(typeof(SpawnSystem), "IsSpawnPointGood", new Type[2] { typeof(SpawnData), typeof(Vector3).MakeByRefType() }, (Type[])null) == null || AccessTools.Method(typeof(SpawnSystem), "Spawn", new Type[3] { typeof(SpawnData), typeof(Vector3), typeof(bool) }, (Type[])null) == null) { throw new MissingMethodException("SpawnSystem hook signatures changed."); } } internal static void Reset() { _world = null; Zones.Clear(); Lesser.Clear(); _nextRefresh = 0f; _warned = false; } internal static void Invalidate() { _nextRefresh = 0f; } private static void Refresh() { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_0154: Unknown result type (might be due to invalid IL or missing references) ZDOMan instance = ZDOMan.instance; if (instance != _world) { Reset(); _world = instance; } if (instance == null || Time.time < _nextRefresh) { return; } _nextRefresh = Time.time + 2f; Zones.Clear(); Lesser.Clear(); try { foreach (ZDO value in ((Dictionary<ZDOID, ZDO>)ObjectsField.GetValue(instance)).Values) { if (value == null) { continue; } int prefab = value.GetPrefab(); if (prefab == GreaterHash) { Zones.Add(new Zone { Id = value, Position = value.GetPosition() }); } else if (prefab == LesserHash) { float num = SpireRules.LesserBonus(value.GetInt("gp_bs_bones_v1", 0), SpireRules.Capacity(greater: false, StorageRules.BoneStackSize())); if (num > 0f) { Lesser.Add(new Contributor { Position = value.GetPosition(), Bonus = num }); } } } foreach (Zone zone in Zones) { zone.Radius = SpireRules.Radius(zone.Id.GetInt("gp_bs_bones_v1", 0), SpireRules.Capacity(greater: true, StorageRules.BoneStackSize()), SumBonuses(zone.Position)); } } catch (Exception ex) { Zones.Clear(); Lesser.Clear(); if (!_warned) { _warned = true; BoneSpirePlugin.Log.LogError((object)("Spawn protection index failed: " + ex)); } } } private static float SumBonuses(Vector3 center) { //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 = 0f; foreach (Contributor item in Lesser) { if (SpireRules.Within(center.x, center.z, item.Position.x, item.Position.z, 100f)) { num += item.Bonus; } } return num; } internal static float BonusAt(Vector3 center) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) Refresh(); return SumBonuses(center); } internal static IReadOnlyList<Zone> CurrentZones() { Refresh(); return Zones; } internal static bool HasGreaterAt(Vector3 position) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Refresh(); foreach (Zone zone in Zones) { if (SpireRules.Within(zone.Position.x, zone.Position.z, position.x, position.z, 100f)) { return true; } } return false; } internal static bool IsProtected(Vector3 position) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) Refresh(); foreach (Zone zone in Zones) { if (zone.Radius > 0f && SpireRules.Within(zone.Position.x, zone.Position.z, position.x, position.z, zone.Radius)) { return true; } } return false; } internal static bool IsHostile(GameObject prefab) { //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) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 Character val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Character>() : null); if ((Object)(object)val == (Object)null) { return false; } Faction faction = val.m_faction; if ((int)faction <= 1 || faction - 10 <= 2) { return false; } return true; } internal static bool Reject(SpawnData spawn, Vector3 position, bool raid = false) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (spawn == null) { return false; } bool flag = IsHostile(spawn.m_prefab); if (!fl