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 Supermans Storage Custom Storage v1.5.0
SupermansCustomStorage.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [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 CustomStorage { internal static class BlueprintPiece { [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDBAwakePatch { private static void Postfix() { Register(); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class ObjectDBCopyPatch { private static void Postfix() { Register(); } } [HarmonyPatch(typeof(Player), "UpdateAvailablePiecesList")] private static class KnownPatch { private static void Prefix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && Plugin.ModEnabled.Value) { Register(); __instance.m_knownRecipes.Add("Storage Rack"); } } } [HarmonyPatch(typeof(Player), "TryPlacePiece")] private static class TryPlacePatch { private static bool Prefix(Piece piece, ref bool __result) { if ((Object)(object)piece == (Object)null || (Object)(object)piece != (Object)(object)TemplatePiece) { return true; } if (!DesignWindow.IsOpen && Time.unscaledTime - DesignWindow.ClosedAt > 0.4f) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Player), "PlacePiece")] private static class PlacePatch { private static bool Prefix(Player __instance, Piece piece, Vector3 pos, Quaternion rot) { //IL_0065: 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) if ((Object)(object)piece == (Object)null || (Object)(object)piece != (Object)(object)TemplatePiece) { return true; } if (Current == null || Current.Parts.Count == 0) { ((Character)__instance).Message((MessageType)2, "Can't lay out this rack: " + (Current?.Warning ?? "no layout"), 0, (Sprite)null, false); return false; } Blueprints.Add(Blueprint.FromLayout(Current, pos, rot, null), broadcast: true); ((Character)__instance).Message((MessageType)2, "Blueprint laid out - hit the pieces with your hammer to build", 0, (Sprite)null, false); return false; } } internal const string PieceName = "Storage Rack"; internal static GameObject Template; internal static Piece TemplatePiece; internal static Layout.Result Current; internal static Dictionary<string, int> CurrentCosts = new Dictionary<string, int>(); private static GameObject _holder; private static bool _dirty; private static float _nextRebuild; private static void EnsureTemplate() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Template != (Object)null)) { _holder = new GameObject("SupermansCustomStorage_Templates"); _holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_holder); Template = new GameObject("SupermansStorageRackBlueprint"); Template.transform.SetParent(_holder.transform, false); TemplatePiece = Template.AddComponent<Piece>(); TemplatePiece.m_name = "Storage Rack"; TemplatePiece.m_category = (PieceCategory)4; TemplatePiece.m_enabled = true; TemplatePiece.m_resources = (Requirement[])(object)new Requirement[0]; TemplatePiece.m_allowedInDungeons = true; TemplatePiece.m_canRotate = true; TemplatePiece.m_clipEverything = true; } } internal static void Register() { PieceTable val = Layout.HammerTable(); if (!((Object)(object)val == (Object)null)) { EnsureTemplate(); bool flag = val.m_pieces.Contains(Template); if (Plugin.ModEnabled.Value && !flag) { val.m_pieces.Add(Template); Rebuild(); } else if (!Plugin.ModEnabled.Value && flag) { val.m_pieces.Remove(Template); } } } internal static void MarkDirty() { _dirty = true; } internal static void RebuildIfDirty() { if (_dirty && !(Time.unscaledTime < _nextRebuild)) { _dirty = false; _nextRebuild = Time.unscaledTime + 0.08f; Rebuild(); } } internal static void Rebuild() { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_016f: 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) if ((Object)(object)Template == (Object)null || (Object)(object)Layout.HammerTable() == (Object)null) { return; } Current = Layout.Generate(Design.FromConfig()); CurrentCosts = Layout.Costs(Current.Parts); for (int num = Template.transform.childCount - 1; num >= 0; num--) { Object.DestroyImmediate((Object)(object)((Component)Template.transform.GetChild(num)).gameObject); } for (int i = 0; i < Current.Snaps.Count; i++) { GameObject val = new GameObject((i < Current.SnapNames.Count) ? Current.SnapNames[i] : ("Corner " + (i + 1))) { tag = "snappoint" }; val.transform.SetParent(Template.transform, false); val.transform.localPosition = Current.Snaps[i]; } foreach (Part part in Current.Parts) { GameObject val2 = PrefabFor(part.Prefab); if (!((Object)(object)val2 == (Object)null)) { GameObject val3 = new GameObject(part.Prefab); val3.transform.SetParent(Template.transform, false); val3.transform.localPosition = part.Pos; val3.transform.localRotation = Quaternion.Euler(0f, part.Yaw, 0f); Visuals.AddHologram(val2, val3.transform, Visuals.Look.Ghost); } } if ((Object)(object)Current.Chest != (Object)null) { TemplatePiece.m_icon = Current.Chest.GetComponent<Piece>().m_icon; } TemplatePiece.m_description = "Design a perfectly spaced storage rack, then lay it down as a blueprint and hit it with the hammer to build it."; Preview.Rebuild(Current); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && ((Character)localPlayer).InPlaceMode() && (Object)(object)localPlayer.GetSelectedPiece() == (Object)(object)TemplatePiece) { localPlayer.SetupPlacementGhost(); } } internal static string ChestName(Layout.Result r) { if (!((Object)(object)r?.Chest != (Object)null)) { return "?"; } return Localization.instance.Localize(r.Chest.GetComponent<Piece>().m_name); } internal static string Describe(Layout.Result r) { if (r?.Design == null) { return ""; } Design design = r.Design; string text = $"{design.Cols} wide x {design.Rows} high x {design.Depth} deep, {ChestName(r)}, facing {design.Facing}"; if (design.Pattern != FacingPattern.AllSame) { text += $" ({design.Pattern} sideways)"; } text += $", frame: {design.Frame}"; if (r.Size.x > 0f) { text += $" ({r.Size.x:0.#} x {r.Size.y:0.#} x {r.Size.z:0.#} m)"; } return text; } internal static GameObject PrefabFor(string name) { GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(name) : null); if ((Object)(object)val != (Object)null) { return val; } PieceTable val2 = Layout.HammerTable(); if ((Object)(object)val2 == (Object)null) { return null; } foreach (GameObject piece in val2.m_pieces) { if ((Object)(object)piece != (Object)null && ((Object)piece).name == name) { return piece; } } return null; } internal static bool Selected(Player p) { if ((Object)(object)p != (Object)null && (Object)(object)TemplatePiece != (Object)null && ((Character)p).InPlaceMode()) { return (Object)(object)p.GetSelectedPiece() == (Object)(object)TemplatePiece; } return false; } internal static bool PickUp(Player p, Blueprint bp) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)p == (Object)null || bp == null || (Object)(object)p.m_buildPieces == (Object)null || (Object)(object)TemplatePiece == (Object)null) { return false; } Design.Parse(bp.Design)?.ApplyToConfig(); Rebuild(); p.UpdateAvailablePiecesList(); Vector2Int selected = default(Vector2Int); PieceCategory category = default(PieceCategory); if (!p.m_buildPieces.GetPieceIndex(TemplatePiece, ref selected, ref category)) { return false; } Blueprints.Remove(bp.Id, broadcast: true); p.m_buildPieces.SetCategory(category); p.m_buildPieces.SetSelected(selected); p.m_placeRotation = Mathf.RoundToInt(((Quaternion)(ref bp.Rot)).eulerAngles.y / 22.5f); p.SetupPlacementGhost(); ((Character)p).Message((MessageType)2, "Aim to move it, scroll to rotate, click to place", 0, (Sprite)null, false); return true; } } internal sealed class Blueprint { public string Id; public string RackId; public Vector3 Pos; public Quaternion Rot; public Vector3 Size; public string Label; public string Design; public List<Part> Parts; public List<Vector3> Snaps = new List<Vector3>(); public GameObject Root; public List<Renderer>[] Renderers; public List<Transform> SnapTransforms; public bool[] Built; public Piece[] PartPiece; public List<Piece> Obsolete = new List<Piece>(); public int MinOpenTier; public float Radius; public float NextRefresh; public int BuiltCount; public bool BuiltHereLast; public Vector3 WorldPos(int i) { //IL_0001: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) return Pos + Rot * Parts[i].Pos; } public Quaternion WorldRot(int i) { //IL_0001: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) return Rot * Quaternion.Euler(0f, Parts[i].Yaw, 0f); } public bool Buildable(int i) { if (!Built[i]) { return Parts[i].Tier <= MinOpenTier; } return false; } internal static Blueprint FromLayout(Layout.Result r, Vector3 pos, Quaternion rot, string rackId) { //IL_002c: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) string text = Guid.NewGuid().ToString("N"); return new Blueprint { Id = text, RackId = (rackId ?? text), Pos = pos, Rot = rot, Size = r.Size, Label = BlueprintPiece.Describe(r), Design = (r.Design?.Serialize() ?? ""), Parts = new List<Part>(r.Parts), Snaps = new List<Vector3>(r.Snaps) }; } public void Write(ZPackage pkg) { //IL_0015: 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) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_011b: Unknown result type (might be due to invalid IL or missing references) pkg.Write(2); pkg.Write(Id); pkg.Write(Pos); pkg.Write(Rot); pkg.Write(Label ?? ""); pkg.Write(Parts.Count); foreach (Part part in Parts) { pkg.Write(part.Prefab); pkg.Write(part.Pos); pkg.Write(part.Yaw); pkg.Write(part.Tier); pkg.Write(part.Blocking); } pkg.Write(RackId ?? Id); pkg.Write(Size); pkg.Write(Design ?? ""); pkg.Write(Snaps.Count); foreach (Vector3 snap in Snaps) { pkg.Write(snap); } } public static Blueprint Read(ZPackage pkg) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) int num = pkg.ReadInt(); Blueprint blueprint = new Blueprint { Id = pkg.ReadString(), Pos = pkg.ReadVector3(), Rot = pkg.ReadQuaternion(), Label = pkg.ReadString(), Parts = new List<Part>() }; int num2 = pkg.ReadInt(); for (int i = 0; i < num2; i++) { blueprint.Parts.Add(new Part { Prefab = pkg.ReadString(), Pos = pkg.ReadVector3(), Yaw = pkg.ReadSingle(), Tier = pkg.ReadInt(), Blocking = pkg.ReadBool() }); } blueprint.RackId = blueprint.Id; if (num >= 2) { blueprint.RackId = pkg.ReadString(); blueprint.Size = pkg.ReadVector3(); blueprint.Design = pkg.ReadString(); int num3 = pkg.ReadInt(); for (int j = 0; j < num3; j++) { blueprint.Snaps.Add(pkg.ReadVector3()); } } return blueprint; } } internal static class Blueprints { [HarmonyPatch(typeof(Game), "Start")] private static class GameStartPatch { private static void Postfix() { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register<ZPackage>("SupermansCustomStorage_Add", (Action<long, ZPackage>)delegate(long sender, ZPackage pkg) { OnAdd(pkg); }); ZRoutedRpc.instance.Register<string>("SupermansCustomStorage_Remove", (Action<long, string>)delegate(long sender, string id) { Remove(id, broadcast: false); }); ZRoutedRpc.instance.Register("SupermansCustomStorage_Request", (Action<long>)OnRequest); } } } [HarmonyPatch(typeof(Player), "OnSpawned")] private static class SpawnPatch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { Load(); ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(0L, "SupermansCustomStorage_Request", Array.Empty<object>()); } } } } [HarmonyPatch(typeof(Piece), "GetSnapPoints", new Type[] { typeof(Vector3), typeof(float), typeof(List<Transform>), typeof(List<Piece>) })] private static class SnapPointsPatch { private static void Postfix(Vector3 point, float radius, List<Transform> points) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) float num = radius * radius; foreach (Blueprint value in All.Values) { if (value.SnapTransforms == null) { continue; } foreach (Transform snapTransform in value.SnapTransforms) { if ((Object)(object)snapTransform != (Object)null) { Vector3 val = snapTransform.position - point; if (((Vector3)(ref val)).sqrMagnitude < num) { points.Add(snapTransform); } } } } } } private const string RpcAdd = "SupermansCustomStorage_Add"; private const string RpcRemove = "SupermansCustomStorage_Remove"; private const string RpcRequest = "SupermansCustomStorage_Request"; internal static readonly Dictionary<string, Blueprint> All = new Dictionary<string, Blueprint>(); private static readonly HashSet<string> Removed = new HashSet<string>(); private static readonly List<Piece> TempPieces = new List<Piece>(); private static string _file; internal static bool Loaded => _file != null; private static string WorldKey() { World val = WorldGenerator.instance?.m_world; if (val == null) { return null; } string text = $"{val.m_seedName}_{val.m_seed}"; char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); foreach (char oldChar in invalidFileNameChars) { text = text.Replace(oldChar, '_'); } return text; } private static void Load() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown string text = WorldKey(); if (text == null) { return; } string text2 = Path.Combine(Paths.ConfigPath, "SupermansCustomStorage", text + ".txt"); if (text2 == _file) { return; } Unload(); _file = text2; if (!File.Exists(text2)) { return; } try { string[] array = File.ReadAllLines(text2); foreach (string text3 in array) { if (string.IsNullOrWhiteSpace(text3)) { continue; } if (text3.StartsWith("-")) { Removed.Add(text3.Substring(1).Trim()); continue; } Blueprint blueprint = Blueprint.Read(new ZPackage(text3.Trim())); if (!Removed.Contains(blueprint.Id)) { All[blueprint.Id] = blueprint; } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Couldn't read blueprints: " + ex.Message)); } } private static void Save() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown if (_file == null) { return; } try { Directory.CreateDirectory(Path.GetDirectoryName(_file)); List<string> list = new List<string>(); foreach (Blueprint value in All.Values) { ZPackage val = new ZPackage(); value.Write(val); list.Add(val.GetBase64()); } list.AddRange(Removed.Select((string id) => "-" + id)); File.WriteAllLines(_file, list); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Couldn't save blueprints: " + ex.Message)); } } internal static void Unload() { HideAll(); All.Clear(); Removed.Clear(); _file = null; } internal static void Add(Blueprint bp, bool broadcast) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown if (bp != null && !Removed.Contains(bp.Id) && !All.ContainsKey(bp.Id)) { All[bp.Id] = bp; Save(); if (broadcast && ZRoutedRpc.instance != null) { ZPackage val = new ZPackage(); bp.Write(val); ZRoutedRpc.instance.InvokeRoutedRPC(0L, "SupermansCustomStorage_Add", new object[1] { val }); } } } internal static void Remove(string id, bool broadcast) { if (All.TryGetValue(id, out var value)) { Hide(value); } All.Remove(id); if (Removed.Add(id)) { Save(); } if (broadcast && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(0L, "SupermansCustomStorage_Remove", new object[1] { id }); } } private static void OnAdd(ZPackage pkg) { if (!Loaded) { return; } try { Add(Blueprint.Read(pkg), broadcast: false); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Bad blueprint from another player: " + ex.Message)); } } private static void OnRequest(long sender) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown if (!Loaded || ZRoutedRpc.instance == null || sender == ZRoutedRpc.instance.m_id) { return; } foreach (Blueprint value in All.Values) { ZPackage val = new ZPackage(); value.Write(val); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "SupermansCustomStorage_Add", new object[1] { val }); } foreach (string item in Removed) { ZRoutedRpc.instance.InvokeRoutedRPC(sender, "SupermansCustomStorage_Remove", new object[1] { item }); } } internal static void HideAll() { foreach (Blueprint value in All.Values) { Hide(value); } } private static void Hide(Blueprint bp) { if ((Object)(object)bp.Root != (Object)null) { Object.Destroy((Object)(object)bp.Root); } bp.Root = null; bp.Renderers = null; bp.SnapTransforms = null; } private static void Show(Blueprint bp) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0027: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0104: 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_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) bp.Root = new GameObject("StorageRackBlueprint_" + bp.Id); bp.Root.transform.SetPositionAndRotation(bp.Pos, bp.Rot); bp.Renderers = new List<Renderer>[bp.Parts.Count]; bp.Built = new bool[bp.Parts.Count]; bp.PartPiece = (Piece[])(object)new Piece[bp.Parts.Count]; bp.Radius = 1f; for (int i = 0; i < bp.Parts.Count; i++) { Part part = bp.Parts[i]; bp.Radius = Mathf.Max(bp.Radius, ((Vector3)(ref part.Pos)).magnitude + 2f); GameObject val = new GameObject(part.Prefab); val.transform.SetParent(bp.Root.transform, false); val.transform.localPosition = part.Pos; val.transform.localRotation = Quaternion.Euler(0f, part.Yaw, 0f); GameObject val2 = BlueprintPiece.PrefabFor(part.Prefab); bp.Renderers[i] = (((Object)(object)val2 != (Object)null) ? Visuals.AddHologram(val2, val.transform, Visuals.Look.Locked) : new List<Renderer>()); } bp.SnapTransforms = new List<Transform>(); foreach (Vector3 snap in bp.Snaps) { GameObject val3 = new GameObject("_snappoint") { tag = "snappoint" }; val3.transform.SetParent(bp.Root.transform, false); val3.transform.localPosition = snap; bp.SnapTransforms.Add(val3.transform); } bp.NextRefresh = 0f; } internal static void Tick() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Loaded || (Object)(object)localPlayer == (Object)null) { return; } bool value = Plugin.ModEnabled.Value; float value2 = Plugin.ShowDistance.Value; List<Blueprint> list = null; foreach (Blueprint value3 in All.Values) { if (!value || !(Vector3.Distance(((Component)localPlayer).transform.position, value3.Pos) < value2)) { if ((Object)(object)value3.Root != (Object)null) { Hide(value3); } continue; } if ((Object)(object)value3.Root == (Object)null) { Show(value3); } if (Time.time >= value3.NextRefresh) { value3.NextRefresh = Time.time + 0.5f; if (Refresh(value3)) { (list ?? (list = new List<Blueprint>())).Add(value3); } } UpdateLooks(value3); } if (list == null) { return; } foreach (Blueprint item in list) { if (item.BuiltHereLast) { Tidy(item, localPlayer); } Remove(item.Id, broadcast: true); ((Character)localPlayer).Message((MessageType)2, "Storage rack complete!", 0, (Sprite)null, false); } } internal static bool Refresh(Blueprint bp) { //IL_002c: 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_0128: Unknown result type (might be due to invalid IL or missing references) if (bp.Built == null) { return false; } TempPieces.Clear(); Piece.GetAllPiecesInRadius(bp.Pos, bp.Radius + 10f, TempPieces); Dictionary<string, List<Piece>> dictionary = new Dictionary<string, List<Piece>>(); foreach (Piece tempPiece in TempPieces) { if (!((Object)(object)tempPiece == (Object)null) && !((Object)(object)tempPiece.m_nview == (Object)null) && tempPiece.m_nview.IsValid()) { string key = Visuals.PrefabName(((Component)tempPiece).gameObject); if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new List<Piece>()); } value.Add(tempPiece); } } HashSet<Piece> used = new HashSet<Piece>(); bp.BuiltCount = 0; bp.MinOpenTier = int.MaxValue; for (int i = 0; i < bp.Parts.Count; i++) { Vector3 wp = bp.WorldPos(i); Piece val = null; if (dictionary.TryGetValue(bp.Parts[i].Prefab, out var value2)) { val = ((IEnumerable<Piece>)value2).FirstOrDefault((Func<Piece, bool>)delegate(Piece pc) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!used.Contains(pc)) { Vector3 val2 = ((Component)pc).transform.position - wp; return ((Vector3)(ref val2)).sqrMagnitude < 0.0025f; } return false; }); } if ((Object)(object)val != (Object)null) { used.Add(val); } bp.PartPiece[i] = val; bp.Built[i] = (Object)(object)val != (Object)null; if (bp.Built[i]) { bp.BuiltCount++; } else if (bp.Parts[i].Blocking) { bp.MinOpenTier = Mathf.Min(bp.MinOpenTier, bp.Parts[i].Tier); } } bp.Obsolete = TempPieces.Where((Piece pc) => (Object)(object)pc != (Object)null && !used.Contains(pc) && Racks.IdOf(pc) == bp.RackId).ToList(); for (int num = 0; num < bp.Parts.Count; num++) { foreach (Renderer item in bp.Renderers[num]) { if ((Object)(object)item != (Object)null) { item.enabled = !bp.Built[num]; } } } return bp.BuiltCount == bp.Parts.Count; } private static void Tidy(Blueprint bp, Player player) { if (bp.Obsolete.Count == 0) { return; } List<Container> to = (from p in bp.PartPiece where (Object)(object)p != (Object)null select ((Component)p).GetComponentInChildren<Container>() into c where (Object)(object)c != (Object)null select c).ToList(); foreach (Piece item in from p in bp.Obsolete where (Object)(object)p != (Object)null orderby ((Component)p).transform.position.y descending select p) { Racks.MoveItems(((Component)item).GetComponentInChildren<Container>(), to, player); Racks.RemovePiece(item); } Piece[] partPiece = bp.PartPiece; foreach (Piece val in partPiece) { if ((Object)(object)val != (Object)null) { Racks.Tag(val, bp); } } } private static void UpdateLooks(Blueprint bp) { for (int i = 0; i < bp.Parts.Count; i++) { if (!bp.Built[i]) { Visuals.SetLook(look: (Builder.TargetBp != bp || Builder.TargetPart != i) ? (bp.Buildable(i) ? Visuals.Look.Ready : Visuals.Look.Locked) : (Builder.TargetCanBuild ? Visuals.Look.Target : Visuals.Look.Blocked), renderers: bp.Renderers[i]); } } } } internal static class Builder { private enum Result { Built, Locked, NoStation, NoMaterials, NoAccess, NoStamina, Error } [HarmonyPatch(typeof(Player), "UpdatePlacement")] private static class UpdatePlacementPatch { private static bool Prefix(Player __instance, bool takeInput) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_01bf: Unknown result type (might be due to invalid IL or missing references) if (!HammerOut(__instance) || !takeInput || Hud.IsPieceSelectionVisible() || Plugin.TypingOrMenu()) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { ClearTarget(); AimedRack = null; } return true; } UpdateTarget(__instance); if (TargetBp == null) { if (Time.time >= _nextAim) { _nextAim = Time.time + 0.2f; AimedRack = Racks.Aimed(__instance); } return true; } AimedRack = null; if ((int)Plugin.RemoveBlueprintKey.Value != 0 && Input.GetKeyDown(Plugin.RemoveBlueprintKey.Value)) { Blueprints.Remove(TargetBp.Id, broadcast: true); ((Character)__instance).Message((MessageType)2, "Blueprint removed", 0, (Sprite)null, false); ClearTarget(); return false; } if (((!ZInput.IsGamepadActive() && ZInput.GetButtonUp("Remove")) || ZInput.GetButtonUp("JoyRemove")) && !ZInput.GetButton("AltPlace") && !ZInput.GetButton("JoyAltKeys")) { if (_confirmRemove == TargetBp.Id && Time.time < _confirmUntil) { Blueprints.Remove(TargetBp.Id, broadcast: true); ((Character)__instance).Message((MessageType)2, "Blueprint removed", 0, (Sprite)null, false); _confirmRemove = null; ClearTarget(); } else { _confirmRemove = TargetBp.Id; _confirmUntil = Time.time + 3f; ((Character)__instance).Message((MessageType)2, "Middle-click again to remove this blueprint (built pieces stay)", 0, (Sprite)null, false); } __instance.m_removePressedTime = -9999f; return false; } if ((ZInput.GetButtonDown("Attack") || ZInput.GetButtonDown("JoyPlace")) && !Hud.InRadial() && Time.time - __instance.m_lastToolUseTime > __instance.m_placeDelay) { bool all = (int)Plugin.BuildAllKey.Value != 0 && Input.GetKey(Plugin.BuildAllKey.Value); Hit(__instance, all); return false; } return true; } } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] private static class GhostPatch { private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && TargetBp != null && (Object)(object)__instance.m_placementGhost != (Object)null) { __instance.m_placementGhost.SetActive(false); } } } internal static Blueprint TargetBp; internal static int TargetPart = -1; internal static bool TargetCanBuild; internal static string TargetInfo; internal static RackInfo AimedRack; private static string _confirmRemove; private static float _confirmUntil; private static float _nextAim; private static float _nextInfo; private static string _info; private static bool _canBuild; private static bool HammerOut(Player p) { if ((Object)(object)p != (Object)null && (Object)(object)p == (Object)(object)Player.m_localPlayer && Plugin.ModEnabled.Value && ((Character)p).InPlaceMode() && (Object)(object)p.m_buildPieces != (Object)null && (Object)(object)p.m_buildPieces == (Object)(object)Layout.HammerTable()) { return !BlueprintPiece.Selected(p); } return false; } private static void ClearTarget() { TargetBp = null; TargetPart = -1; TargetInfo = null; } internal static bool FindPart(Player p, out Blueprint target, out int part) { //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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) target = null; part = -1; if ((Object)(object)p == (Object)null || (Object)(object)GameCamera.instance == (Object)null) { return false; } Vector3 position = ((Component)GameCamera.instance).transform.position; Vector3 forward = ((Component)GameCamera.instance).transform.forward; float num = p.m_maxPlaceDistance + 1f; float num2 = 50f; foreach (Blueprint value in Blueprints.All.Values) { if ((Object)(object)value.Root == (Object)null || value.Built == null || Vector3.Distance(((Character)p).m_eye.position, value.Pos) > value.Radius + num + 5f) { continue; } for (int i = 0; i < value.Parts.Count; i++) { if (!value.Built[i]) { GameObject val = BlueprintPiece.PrefabFor(value.Parts[i].Prefab); if (!((Object)(object)val == (Object)null) && RayHitsBox(position, forward, value.WorldPos(i), value.WorldRot(i), Visuals.GetBounds(val), out var t) && !(t >= num2) && !(Vector3.Distance(((Character)p).m_eye.position, position + forward * t) > num)) { num2 = t; target = value; part = i; } } } } if (target == null) { return false; } RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(position, forward, ref val2, num2, p.m_placeRayMask) && ((RaycastHit)(ref val2)).distance < num2 - 0.05f) { target = null; part = -1; return false; } return true; } private static void UpdateTarget(Player p) { Blueprint targetBp = TargetBp; int targetPart = TargetPart; ClearTarget(); if (FindPart(p, out TargetBp, out TargetPart)) { if (TargetBp != targetBp || TargetPart != targetPart || Time.time >= _nextInfo || _info == null) { _nextInfo = Time.time + 0.25f; _canBuild = Check(p, TargetBp, TargetPart, out _info); } TargetCanBuild = _canBuild; TargetInfo = _info; } } private static bool RayHitsBox(Vector3 o, Vector3 d, Vector3 pos, Quaternion rot, Bounds b, out float t) { //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_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) Quaternion val = Quaternion.Inverse(rot); Vector3 val2 = val * (o - pos); Vector3 val3 = val * d; float num = 0f; float num2 = float.MaxValue; for (int i = 0; i < 3; i++) { Vector3 val4; if (Mathf.Abs(((Vector3)(ref val3))[i]) < 1E-06f) { float num3 = ((Vector3)(ref val2))[i]; val4 = ((Bounds)(ref b)).min; if (!(num3 < ((Vector3)(ref val4))[i])) { float num4 = ((Vector3)(ref val2))[i]; val4 = ((Bounds)(ref b)).max; if (!(num4 > ((Vector3)(ref val4))[i])) { continue; } } t = 0f; return false; } val4 = ((Bounds)(ref b)).min; float num5 = (((Vector3)(ref val4))[i] - ((Vector3)(ref val2))[i]) / ((Vector3)(ref val3))[i]; val4 = ((Bounds)(ref b)).max; float num6 = (((Vector3)(ref val4))[i] - ((Vector3)(ref val2))[i]) / ((Vector3)(ref val3))[i]; if (num5 > num6) { float num7 = num5; num5 = num6; num6 = num7; } num = Mathf.Max(num, num5); num2 = Mathf.Min(num2, num6); if (num > num2) { t = 0f; return false; } } t = num; return true; } private static bool Free(Player p, Piece piece) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (!p.m_noPlacementCost) { return ZoneSystem.instance.GetGlobalKey(piece.FreeBuildKey()); } return true; } internal static int Have(Player p, string itemName) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) int num = ((Humanoid)p).GetInventory().CountItems(itemName, -1, true); if (Plugin.UseNearbyChests.Value) { num += Storage.Count(itemName, ((Component)p).transform.position, Plugin.StorageRange.Value); } return num; } private static bool Check(Player p, Blueprint bp, int i, out string info) { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0252: 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_0264: Unknown result type (might be due to invalid IL or missing references) GameObject val = BlueprintPiece.PrefabFor(bp.Parts[i].Prefab); Piece val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Piece>() : null); if ((Object)(object)val2 == (Object)null) { info = "Unknown piece " + bp.Parts[i].Prefab; return false; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("<b>").Append(Localization.instance.Localize(val2.m_name)).Append("</b> ") .Append($"<color=#9ad>({bp.BuiltCount}/{bp.Parts.Count} built)</color>\n"); bool result = true; if (!bp.Buildable(i)) { stringBuilder.Append("<color=#f88>Build the pieces under it first</color>\n"); result = false; } if ((Object)(object)val2.m_craftingStation != (Object)null && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)27) && !Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(val2.m_craftingStation.m_name, bp.WorldPos(i)))) { stringBuilder.Append("<color=#f88>Needs a ").Append(Localization.instance.Localize(val2.m_craftingStation.m_name)).Append(" nearby</color>\n"); result = false; } if (Free(p, val2)) { stringBuilder.Append("<color=#8f8>Free</color>\n"); } else { Requirement[] resources = val2.m_resources; foreach (Requirement val3 in resources) { if (!((Object)(object)val3.m_resItem == (Object)null) && val3.m_amount > 0) { string name = val3.m_resItem.m_itemData.m_shared.m_name; int num = Have(p, name); bool flag = num >= val3.m_amount; if (!flag) { result = false; } stringBuilder.Append(flag ? "<color=#ddd>" : "<color=#f88>").Append(Localization.instance.Localize(name)).Append($" {val3.m_amount} (have {num})</color>\n"); } } } stringBuilder.Append("\n[<color=#fd4>Hit</color>] build"); if ((int)Plugin.UpgradeKey.Value != 0) { stringBuilder.Append($" [<color=#fd4>{Plugin.UpgradeKey.Value}</color>] redesign"); } if ((int)Plugin.BuildAllKey.Value != 0) { stringBuilder.Append($" [<color=#fd4>{Plugin.BuildAllKey.Value} + Hit</color>] build all you can"); } stringBuilder.Append(" [<color=#fd4>Middle-click</color>] remove blueprint"); info = stringBuilder.ToString(); return result; } private static Result BuildOne(Player p, Blueprint bp, int i, bool animate) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) if (bp.Built[i]) { return Result.Error; } if (!bp.Buildable(i)) { return Result.Locked; } GameObject val = BlueprintPiece.PrefabFor(bp.Parts[i].Prefab); Piece val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Piece>() : null); if ((Object)(object)val2 == (Object)null || (Object)(object)val.GetComponent<ZNetView>() == (Object)null) { return Result.Error; } Vector3 val3 = bp.WorldPos(i); Quaternion val4 = bp.WorldRot(i); if (!PrivateArea.CheckAccess(val3, 0f, true, false)) { return Result.NoAccess; } if ((Object)(object)val2.m_craftingStation != (Object)null && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)27) && !Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(val2.m_craftingStation.m_name, val3))) { return Result.NoStation; } ItemData rightItem = ((Humanoid)p).GetRightItem(); if (rightItem != null && !((Character)p).HaveStamina(rightItem.m_shared.m_attack.m_attackStamina)) { return Result.NoStamina; } if (!Free(p, val2)) { Requirement[] resources = val2.m_resources; foreach (Requirement val5 in resources) { if ((Object)(object)val5.m_resItem != (Object)null && val5.m_amount > 0 && Have(p, val5.m_resItem.m_itemData.m_shared.m_name) < val5.m_amount) { return Result.NoMaterials; } } Inventory inventory = ((Humanoid)p).GetInventory(); resources = val2.m_resources; foreach (Requirement val6 in resources) { if (!((Object)(object)val6.m_resItem == (Object)null) && val6.m_amount > 0) { string name = val6.m_resItem.m_itemData.m_shared.m_name; int num = Mathf.Min(val6.m_amount, inventory.CountItems(name, -1, true)); if (num > 0) { inventory.RemoveItem(name, num, -1, true); } int num2 = val6.m_amount - num; if (num2 > 0) { Storage.Remove(name, num2, ((Component)p).transform.position, Plugin.StorageRange.Value); } } } } Racks.Pending = bp; Racks.LastPlaced = null; try { p.PlacePiece(val2, val3, val4, animate, false); } finally { Racks.Pending = null; } Piece lastPlaced = Racks.LastPlaced; ReplaceOld(p, bp, i, lastPlaced); bp.BuiltHereLast = true; ((Character)p).UseStamina(p.GetBuildStamina()); if (rightItem != null && rightItem.m_shared.m_useDurability) { rightItem.m_durability -= p.GetPlaceDurability(rightItem) * Game.m_durabilityRate; } if ((Object)(object)p.m_buildPieces != (Object)null && (int)p.m_buildPieces.m_skill != 0) { ((Character)p).RaiseSkill(p.m_buildPieces.m_skill, 1f); } Game.instance.IncrementPlayerStat((PlayerStatType)2, 1f, false); bp.Built[i] = true; bp.PartPiece[i] = lastPlaced; bp.BuiltCount++; RecalcTier(bp); return Result.Built; } private static void ReplaceOld(Player p, Blueprint bp, int i, Piece placed) { //IL_0038: 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) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) if (bp.Obsolete.Count == 0) { return; } Part part = bp.Parts[i]; GameObject val = BlueprintPiece.PrefabFor(part.Prefab); if ((Object)(object)val == (Object)null) { return; } Bounds val2 = Layout.Rotate(Visuals.GetBounds(val), part.Yaw); ((Bounds)(ref val2)).center = ((Bounds)(ref val2)).center + part.Pos; ((Bounds)(ref val2)).Expand(-0.06f); Quaternion val3 = Quaternion.Inverse(bp.Rot); List<Container> list = new List<Container>(); Container mine = (((Object)(object)placed != (Object)null) ? ((Component)placed).GetComponentInChildren<Container>() : null); if ((Object)(object)mine != (Object)null) { list.Add(mine); } list.AddRange(from x in bp.PartPiece where (Object)(object)x != (Object)null select ((Component)x).GetComponentInChildren<Container>() into c where (Object)(object)c != (Object)null && (Object)(object)c != (Object)(object)mine select c); foreach (Piece item in bp.Obsolete.ToList()) { if ((Object)(object)item == (Object)null) { bp.Obsolete.Remove(item); continue; } GameObject val4 = BlueprintPiece.PrefabFor(Visuals.PrefabName(((Component)item).gameObject)); if ((Object)(object)val4 == (Object)null) { val4 = ((Component)item).gameObject; } Bounds bounds = Visuals.GetBounds(val4); Quaternion val5 = val3 * ((Component)item).transform.rotation; Bounds val6 = Layout.Rotate(bounds, ((Quaternion)(ref val5)).eulerAngles.y); ((Bounds)(ref val6)).center = ((Bounds)(ref val6)).center + val3 * (((Component)item).transform.position - bp.Pos); ((Bounds)(ref val6)).Expand(-0.06f); if (((Bounds)(ref val2)).Intersects(val6)) { Racks.MoveItems(((Component)item).GetComponentInChildren<Container>(), list, p); Racks.RemovePiece(item); bp.Obsolete.Remove(item); } } } private static void RecalcTier(Blueprint bp) { bp.MinOpenTier = int.MaxValue; for (int i = 0; i < bp.Parts.Count; i++) { if (!bp.Built[i] && bp.Parts[i].Blocking) { bp.MinOpenTier = Mathf.Min(bp.MinOpenTier, bp.Parts[i].Tier); } } } private static string Explain(Result r) { return r switch { Result.Locked => "Build the pieces under it first", Result.NoStation => "$msg_missingstation", Result.NoMaterials => "$msg_missingrequirement", Result.NoAccess => "$msg_privatezone", Result.NoStamina => "$hud_notenoughstamina", _ => null, }; } private static void Hit(Player p, bool all) { Blueprint bp = TargetBp; int target = TargetPart; p.m_lastToolUseTime = Time.time; if (!all) { Result result = BuildOne(p, bp, target, animate: true); if (result != Result.Built && Explain(result) != null) { ((Character)p).Message((MessageType)2, Explain(result), 0, (Sprite)null, false); } Finish(bp); return; } int num = 0; Result result2 = Result.Locked; bool flag = true; while (flag) { flag = false; foreach (int item in (from i in Enumerable.Range(0, bp.Parts.Count).Where(bp.Buildable) orderby bp.Parts[i].Tier select i).ThenBy(delegate(int i) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) Vector3 val = bp.WorldPos(i) - bp.WorldPos(target); return ((Vector3)(ref val)).sqrMagnitude; }).ToList()) { result2 = BuildOne(p, bp, item, num == 0); switch (result2) { case Result.Built: num++; flag = true; break; case Result.NoStamina: flag = false; goto end_IL_012b; } continue; end_IL_012b: break; } } if (num > 0) { ((Character)p).Message((MessageType)2, string.Format("Built {0} piece{1}", num, (num == 1) ? "" : "s"), 0, (Sprite)null, false); } else if (Explain(result2) != null) { ((Character)p).Message((MessageType)2, Explain(result2), 0, (Sprite)null, false); } Finish(bp); } private static void Finish(Blueprint bp) { bp.NextRefresh = Time.time + 0.5f; _info = null; } } internal sealed class Design { public ChestType Chest; public int Cols; public int Rows; public int Depth; public FrameStyle Frame; public bool Dividers; public float SideGap; public float TopGap; public float DepthGap; public ChestFacing Facing; public FacingPattern Pattern; internal static Design FromConfig() { return new Design { Chest = Plugin.Chest.Value, Cols = Plugin.Columns.Value, Rows = Plugin.Rows.Value, Depth = Plugin.Depth.Value, Frame = Plugin.Frame.Value, Dividers = Plugin.Dividers.Value, SideGap = Plugin.SideGap.Value, TopGap = Plugin.TopGap.Value, DepthGap = Plugin.DepthGap.Value, Facing = Plugin.Facing.Value, Pattern = Plugin.Pattern.Value }; } internal void ApplyToConfig() { Plugin.Chest.Value = Chest; Plugin.Columns.Value = Cols; Plugin.Rows.Value = Rows; Plugin.Depth.Value = Depth; Plugin.Frame.Value = Frame; Plugin.Dividers.Value = Dividers; Plugin.SideGap.Value = SideGap; Plugin.TopGap.Value = TopGap; Plugin.DepthGap.Value = DepthGap; Plugin.Facing.Value = Facing; Plugin.Pattern.Value = Pattern; } public string Serialize() { CultureInfo invariantCulture = CultureInfo.InvariantCulture; return string.Join(",", "2", Chest.ToString(), Cols.ToString(invariantCulture), Rows.ToString(invariantCulture), Depth.ToString(invariantCulture), Frame.ToString(), Dividers ? "1" : "0", SideGap.ToString(invariantCulture), TopGap.ToString(invariantCulture), Facing.ToString(), Pattern.ToString(), DepthGap.ToString(invariantCulture)); } public static Design Parse(string s) { if (string.IsNullOrEmpty(s)) { return null; } try { CultureInfo invariantCulture = CultureInfo.InvariantCulture; string[] array = s.Split(new char[1] { ',' }); if (array.Length < 11 || (array[0] != "1" && array[0] != "2")) { return null; } return new Design { Chest = (ChestType)Enum.Parse(typeof(ChestType), array[1]), Cols = int.Parse(array[2], invariantCulture), Rows = int.Parse(array[3], invariantCulture), Depth = int.Parse(array[4], invariantCulture), Frame = (FrameStyle)Enum.Parse(typeof(FrameStyle), array[5]), Dividers = (array[6] == "1"), SideGap = float.Parse(array[7], invariantCulture), TopGap = float.Parse(array[8], invariantCulture), Facing = (ChestFacing)Enum.Parse(typeof(ChestFacing), array[9]), Pattern = (FacingPattern)Enum.Parse(typeof(FacingPattern), array[10]), DepthGap = ((array[0] == "2" && array.Length > 11) ? float.Parse(array[11], invariantCulture) : 0.1f) }; } catch { return null; } } } internal static class DesignWindow { private sealed class ChestChoice { public ChestType Type; public GameObject Prefab; } [HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")] private static class MouseCapturePatch { private static void Postfix() { if (IsOpen) { ZCursor.LockState = (CursorLockMode)0; ZCursor.Show(); } } } [HarmonyPatch(typeof(Player), "TakeInput")] private static class TakeInputPatch { private static void Postfix(ref bool __result) { if (IsOpen) { __result = false; } } } [HarmonyPatch(typeof(Menu), "Update")] private static class MenuPatch { private static bool Prefix() { if (!IsOpen) { return ClosedFrame != Time.frameCount; } return false; } } [CompilerGenerated] private static class <>O { public static WindowFunction <0>__DrawWindow; } internal static bool IsOpen; internal static int ClosedFrame = -1; internal static float ClosedAt = -10f; private static RackInfo _upgrade; private static bool _wasSelected; private static bool _pending; private static bool _wasHammer; private static Rect _rect; private static bool _dragging; private static float _lastDrag; private static GUIStyle _head; private static GUIStyle _small; private static GUIStyle _rich; private const int WindowId = 96799249; private static List<ChestChoice> _chests; private static readonly Dictionary<string, int> _have = new Dictionary<string, int>(); private static float _nextHave; private static Vector2 _scroll; private static int Have(string item) { if (Time.unscaledTime >= _nextHave) { _have.Clear(); _nextHave = Time.unscaledTime + 0.5f; } if (!_have.TryGetValue(item, out var value)) { Player localPlayer = Player.m_localPlayer; value = (_have[item] = (((Object)(object)localPlayer != (Object)null) ? Builder.Have(localPlayer, item) : 0)); } return value; } internal static void Open(RackInfo upgrade) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) _upgrade = upgrade; _chests = null; _nextHave = 0f; if (upgrade?.Design != null) { upgrade.Design.ApplyToConfig(); } BlueprintPiece.MarkDirty(); float num = Mathf.Min(980f, (float)Screen.width - 40f); float num2 = Mathf.Min(620f, (float)Screen.height - 40f); _rect = new Rect(((float)Screen.width - num) / 2f, ((float)Screen.height - num2) / 2f, num, num2); IsOpen = true; } internal static void Close() { IsOpen = false; _upgrade = null; ClosedFrame = Time.frameCount; ClosedAt = Time.unscaledTime; } internal static void Update() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !Plugin.ModEnabled.Value) { if (IsOpen) { Close(); } return; } bool flag = BlueprintPiece.Selected(localPlayer); bool wasHammer = ((Character)localPlayer).InPlaceMode(); if (flag && !_wasSelected && _wasHammer) { _pending = true; } _wasHammer = wasHammer; if (!flag) { _pending = false; } _wasSelected = flag; if (IsOpen) { if (Input.GetKeyDown((KeyCode)27) || ((Character)localPlayer).IsDead()) { Close(); } else { Preview.Render(Time.unscaledDeltaTime, !_dragging && Time.unscaledTime - _lastDrag > 2f); } } else { if (Plugin.TypingOrMenu() || Hud.IsPieceSelectionVisible()) { return; } if (_pending) { _pending = false; Open(null); } else if (flag && Plugin.KeyDown(Plugin.DesignKey)) { Open(null); } else if (((Character)localPlayer).InPlaceMode() && (Object)(object)localPlayer.m_buildPieces == (Object)(object)Layout.HammerTable() && Plugin.KeyDown(Plugin.UpgradeKey)) { RackInfo rackInfo = Racks.Aimed(localPlayer); if (rackInfo != null) { Open(rackInfo); } else { ((Character)localPlayer).Message((MessageType)2, "Look at a storage rack built with this mod to upgrade it", 0, (Sprite)null, false); } } } } internal static void Draw() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_0039: Expected O, but got Unknown //IL_0043: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) if (IsOpen) { if (_head == null) { _head = new GUIStyle(GUI.skin.label) { fontSize = 15, fontStyle = (FontStyle)1, richText = true }; _small = new GUIStyle(GUI.skin.label) { fontSize = 12, richText = true, wordWrap = true }; _rich = new GUIStyle(GUI.skin.label) { fontSize = 13, richText = true, wordWrap = true }; } GUI.color = Color.white; GUI.backgroundColor = new Color(0.25f, 0.27f, 0.32f, 1f); GUI.Box(_rect, GUIContent.none); GUI.Box(_rect, GUIContent.none); Rect rect = _rect; object obj = <>O.<0>__DrawWindow; if (obj == null) { WindowFunction val = DrawWindow; <>O.<0>__DrawWindow = val; obj = (object)val; } _rect = GUILayout.Window(96799249, rect, (WindowFunction)obj, (_upgrade?.Blueprint != null) ? "Edit Storage Rack Blueprint" : ((_upgrade != null) ? "Upgrade Storage Rack" : "Storage Rack Designer"), Array.Empty<GUILayoutOption>()); } } private static void DrawWindow(int id) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_0598: Unknown result type (might be due to invalid IL or missing references) //IL_060f: Unknown result type (might be due to invalid IL or missing references) //IL_064a: Unknown result type (might be due to invalid IL or missing references) //IL_06d5: Unknown result type (might be due to invalid IL or missing references) //IL_0760: Unknown result type (might be due to invalid IL or missing references) //IL_07af: Unknown result type (might be due to invalid IL or missing references) //IL_086a: Unknown result type (might be due to invalid IL or missing references) Layout.Result current = BlueprintPiece.Current; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(((Rect)(ref _rect)).width * 0.5f) }); Rect rect = GUILayoutUtility.GetRect(((Rect)(ref _rect)).width * 0.5f - 10f, ((Rect)(ref _rect)).height * 0.55f); if ((Object)(object)Preview.Texture != (Object)null) { GUI.DrawTexture(rect, Preview.Texture, (ScaleMode)2); } HandleDrag(rect); GUILayout.Label("<color=#9ab>Drag the picture to turn it.</color>", _small, Array.Empty<GUILayoutOption>()); if (current != null) { GUILayout.Label($"<b>{current.ChestCount}</b> x {BlueprintPiece.ChestName(current)}", _rich, Array.Empty<GUILayoutOption>()); if (current.Size.x > 0f) { GUILayout.Label($"Size: {current.Size.x:0.#} m wide, {current.Size.y:0.#} m high, {current.Size.z:0.#} m deep", _rich, Array.Empty<GUILayoutOption>()); } if (current.Legs > 0.02f) { GUILayout.Label($"<color=#9ab>Bottom shelf sits {current.Legs:0.00} m up on short legs (posts come in whole pole lengths).</color>", _small, Array.Empty<GUILayoutOption>()); } if (current.Note != null) { GUILayout.Label("<color=#fd8>" + current.Note + "</color>", _small, Array.Empty<GUILayoutOption>()); } if (current.Warning != null) { GUILayout.Label("<color=#f88>" + current.Warning + "</color>", _rich, Array.Empty<GUILayoutOption>()); } GUILayout.Label("<b>Materials for the whole rack</b>" + ((_upgrade != null) ? " <color=#9ab>(pieces you already have are skipped)</color>" : ""), _rich, Array.Empty<GUILayoutOption>()); foreach (KeyValuePair<string, int> item in BlueprintPiece.CurrentCosts.OrderBy((KeyValuePair<string, int> k) => k.Key)) { int num = Have(item.Key); string text = ((num >= item.Value) ? "#ddd" : "#fb8"); GUILayout.Label($"<color={text}>{Localization.instance.Localize(item.Key)}: {item.Value} (you have {num})</color>", _small, Array.Empty<GUILayoutOption>()); } GUILayout.Label("<color=#9ab>You don't need it all now: you build the blueprint piece by piece as you gather materials.</color>", _small, Array.Empty<GUILayoutOption>()); } GUILayout.EndVertical(); GUILayout.Space(12f); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); _scroll = GUILayout.BeginScrollView(_scroll, Array.Empty<GUILayoutOption>()); GUILayout.Label("Chest", _head, Array.Empty<GUILayoutOption>()); ChestButtons(); GUILayout.Space(6f); GUILayout.Label("Size", _head, Array.Empty<GUILayoutOption>()); Counter("Wide", Plugin.Columns, 1, 12); Counter("High", Plugin.Rows, 1, 8); Counter("Deep", Plugin.Depth, 1, 4); GUILayout.Space(6f); GUILayout.Label("Chests face", _head, Array.Empty<GUILayoutOption>()); Choice<ChestFacing>(Plugin.Facing, new string[6] { "Front", "Right", "Back", "Left", "Back to back", "Face to face" }, 3); GUILayout.Label("<color=#9ab>Back to back / face to face split a rack that's 2+ deep into two halves.</color>", _small, Array.Empty<GUILayoutOption>()); GUILayout.Label("Straight / sideways mix", _head, Array.Empty<GUILayoutOption>()); Choice<FacingPattern>(Plugin.Pattern, new string[4] { "All the same", "Alternate rows", "Alternate columns", "Checkerboard" }, 2); GUILayout.Space(6f); GUILayout.Label("Frame", _head, Array.Empty<GUILayoutOption>()); Choice<FrameStyle>(Plugin.Frame, new string[3] { "Wood", "Ashwood", "None" }, 3); bool flag = GUILayout.Toggle(Plugin.Dividers.Value, " Post between every chest", Array.Empty<GUILayoutOption>()); if (flag != Plugin.Dividers.Value) { Plugin.Dividers.Value = flag; } GUILayout.Space(6f); GUILayout.Label("Spacing", _head, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("Touching", Array.Empty<GUILayoutOption>())) { SetSpacing(0f, 0.02f, 0f); } if (GUILayout.Button("Snug", Array.Empty<GUILayoutOption>())) { SetSpacing(0.1f, 0.1f, 0.05f); } if (GUILayout.Button("Roomy", Array.Empty<GUILayoutOption>())) { SetSpacing(0.35f, 0.35f, 0.25f); } if (GUILayout.Button("Wide open", Array.Empty<GUILayoutOption>())) { SetSpacing(0.75f, 0.6f, 0.5f); } GUILayout.EndHorizontal(); Spacing("Side to side", Plugin.SideGap); Spacing("Above each chest", Plugin.TopGap); if (Plugin.Depth.Value > 1) { Spacing("Front to back", Plugin.DepthGap); } GUILayout.EndScrollView(); GUILayout.FlexibleSpace(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUI.backgroundColor = new Color(0.3f, 0.6f, 0.35f); if (GUILayout.Button((_upgrade?.Blueprint != null) ? "Update blueprint" : ((_upgrade != null) ? "Upgrade rack" : "Place blueprint"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(36f) }) && current != null && current.Parts.Count > 0) { Confirm(current); } GUI.backgroundColor = new Color(0.75f, 0.25f, 0.2f); if (_upgrade?.Blueprint != null) { Blueprint blueprint = _upgrade.Blueprint; GUI.backgroundColor = new Color(0.3f, 0.45f, 0.7f); GUI.enabled = blueprint.BuiltCount == 0; if (GUILayout.Button("Move / rotate", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Height(36f), GUILayout.Width(130f) })) { Player localPlayer = Player.m_localPlayer; Close(); _wasSelected = true; if (!BlueprintPiece.PickUp(localPlayer, blueprint) && localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "Couldn't pick up the blueprint - is the hammer out?", 0, (Sprite)null, false); } } GUI.enabled = true; GUI.backgroundColor = new Color(0.75f, 0.25f, 0.2f); } if (_upgrade?.Blueprint != null && GUILayout.Button("Remove blueprint", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Height(36f), GUILayout.Width(150f) })) { Blueprints.Remove(_upgrade.Blueprint.Id, broadcast: true); Player localPlayer2 = Player.m_localPlayer; if (localPlayer2 != null) { ((Character)localPlayer2).Message((MessageType)2, "Blueprint removed (built pieces stay)", 0, (Sprite)null, false); } Close(); } GUI.backgroundColor = new Color(0.45f, 0.3f, 0.3f); if (GUILayout.Button("Cancel", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Height(36f), GUILayout.Width(110f) })) { Close(); } GUI.backgroundColor = new Color(0.25f, 0.27f, 0.32f, 1f); GUILayout.EndHorizontal(); if (_upgrade?.Blueprint != null && _upgrade.Blueprint.BuiltCount > 0) { GUILayout.Label($"<color=#fd8>{_upgrade.Blueprint.BuiltCount} pieces are already built, so this blueprint can't be moved. Remove it and place a new one, or keep building.</color>", _small, Array.Empty<GUILayoutOption>()); } GUILayout.Label((_upgrade?.Blueprint != null) ? "<color=#9ab>Move / rotate picks the blueprint up onto your hammer: aim, scroll to turn it, click to put it down.</color>" : ((_upgrade != null) ? "<color=#9ab>The rack becomes a blueprint. Hit the new pieces with the hammer: old chests are swapped out and their contents move into the new ones.</color>" : "<color=#9ab>Then aim where it goes: it snaps to floors, walls, other racks and blueprints. Scroll to rotate, click to lay it down.</color>"), _small, Array.Empty<GUILayoutOption>()); GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 22f)); } private static void SetSpacing(float side, float above, float depth) { Plugin.SideGap.Value = side; Plugin.TopGap.Value = above; Plugin.DepthGap.Value = depth; } private static void Spacing(string label, ConfigEntry<float> entry) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }); float num = entry.Value; if (GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(26f) })) { num -= 0.05f; } num = GUILayout.HorizontalSlider(num, 0f, 2f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(80f) }); if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(26f) })) { num += 0.05f; } GUILayout.Label((num <= 0.001f) ? "<b>touching</b>" : $"<b>{num * 100f:0} cm</b>", _rich, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }); GUILayout.EndHorizontal(); num = Mathf.Clamp(Mathf.Round(num * 100f) / 100f, 0f, 2f); if (Mathf.Abs(num - entry.Value) > 0.004f) { entry.Value = num; } } private static void Confirm(Layout.Result r) { Player localPlayer = Player.m_localPlayer; if (_upgrade != null && (Object)(object)localPlayer != (Object)null) { Racks.Upgrade(_upgrade, r, localPlayer); Close(); return; } Close(); if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "Aim where the rack goes - it snaps to floors, walls and other racks", 0, (Sprite)null, false); } } private static void HandleDrag(Rect view) { //IL_0007: 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_0031: Invalid comparison between Unknown and I4 //IL_0011: 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_004e: Invalid comparison between Unknown and I4 //IL_0058: Unknown result type (might be due to invalid IL or missing references) Event current = Event.current; if ((int)current.type == 0 && ((Rect)(ref view)).Contains(current.mousePosition)) { _dragging = true; current.Use(); } else if ((int)current.type == 1 && _dragging) { _dragging = false; current.Use(); } else if ((int)current.type == 3 && _dragging) { Preview.Spin(current.delta.x * 0.5f); _lastDrag = Time.unscaledTime; current.Use(); } } private static void ChestButtons() { //IL_01b8: 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_00d6: 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_0166: Unknown result type (might be due to invalid IL or missing references) if (_chests == null) { _chests = (from ChestType t in Enum.GetValues(typeof(ChestType)) select new ChestChoice { Type = t, Prefab = Layout.FindChest(t) } into x where (Object)(object)x.Prefab != (Object)null select x).ToList(); } List<ChestChoice> chests = _chests; int num = 2; for (int num2 = 0; num2 < chests.Count; num2 += num) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); for (int num3 = num2; num3 < Mathf.Min(num2 + num, chests.Count); num3++) { ChestType type = chests[num3].Type; Piece component = chests[num3].Prefab.GetComponent<Piece>(); bool flag = Plugin.Chest.Value == type; GUI.backgroundColor = (flag ? new Color(0.35f, 0.55f, 0.85f) : new Color(0.25f, 0.27f, 0.32f, 1f)); if (GUILayout.Button(" " + Localization.instance.Localize(component.m_name), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(38f) }) && !flag) { Plugin.Chest.Value = type; } Rect lastRect = GUILayoutUtility.GetLastRect(); DrawSprite(new Rect(((Rect)(ref lastRect)).x + 4f, ((Rect)(ref lastRect)).y + 3f, 32f, 32f), component.m_icon); } GUILayout.EndHorizontal(); } GUI.backgroundColor = new Color(0.25f, 0.27f, 0.32f, 1f); } private static void DrawSprite(Rect r, Sprite s) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)s == (Object)null) && !((Object)(object)s.texture == (Object)null) && (int)Event.current.type == 7) { Rect textureRect = s.textureRect; Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref textureRect)).x / (float)((Texture)s.texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)s.texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)s.texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)s.texture).height); GUI.DrawTextureWithTexCoords(r, (Texture)(object)s.texture, val); } } private static void Counter(string label, ConfigEntry<int> entry, int min, int max) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }); if (GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(34f), GUILayout.Height(26f) }) && entry.Value > min) { int value = entry.Value; entry.Value = value - 1; } GUILayout.Label($"<b>{entry.Value}</b>", _rich, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(36f) }); if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(34f), GUILayout.Height(26f) }) && entry.Value < max) { int value = entry.Value; entry.Value = value + 1; } GUILayout.EndHorizontal(); } private static void Choice<T>(ConfigEntry<T> entry, string[] labels, int perRow) where T : Enum { int num = Convert.ToInt32(entry.Value); int num2 = GUILayout.SelectionGrid(num, labels, perRow, Array.Empty<GUILayoutOption>()); if (num2 != num) { entry.Value = (T)Enum.ToObject(typeof(T), num2); } } } internal static class Hint { private static GUIStyle _style; private static string SnapKeys() { string text = null; string text2 = null; try { ZInput instance = ZInput.instance; text = ((instance != null) ? instance.GetBoundKeyString("TabLeft", true) : null); ZInput instance2 = ZInput.instance; text2 = ((instance2 != null) ? instance2.GetBoundKeyString("TabRight", true) : null); } catch { } if (!string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(text2)) { return text + " / " + text2; } return "Q / E"; } internal static void Draw() { //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Expected O, but got Unknown //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: 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_01c7: 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_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_0193: 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_00ed: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.ModEnabled.Value || DesignWindow.IsOpen || (Object)(object)Hud.instance == (Object)null || Hud.IsUserHidden()) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || Plugin.TypingOrMenu() || Hud.IsPieceSelectionVisible()) { return; } string text = null; if (Builder.TargetBp != null) { text = Builder.TargetInfo; } else if (BlueprintPiece.Selected(localPlayer)) { text = "<b>Storage Rack</b> " + BlueprintPiece.Describe(BlueprintPiece.Current) + ((BlueprintPiece.Current?.Warning != null) ? ("\n<color=#f88>" + BlueprintPiece.Current.Warning + "</color>") : "") + "\nAim to move it, scroll to rotate, click to place. Snaps to floors, walls, other racks and blueprints.\n[<color=#fd4>" + SnapKeys() + "</color>] pick the corner it snaps by [<color=#fd4>Shift</color>] hold for no snapping" + (((int)Plugin.DesignKey.Value != 0) ? $" [<color=#fd4>{Plugin.DesignKey.Value}</color>] change design" : ""); } else if (Builder.AimedRack != null && (int)Plugin.UpgradeKey.Value != 0) { Design design = Builder.AimedRack.Design; text = "<b>Storage rack</b>" + ((design != null) ? $" {design.Cols} x {design.Rows} x {design.Depth} {design.Chest}" : "") + $"\n[<color=#fd4>{Plugin.UpgradeKey.Value}</color>] upgrade / redesign"; } if (!string.IsNullOrEmpty(text)) { if (_style == null) { _style = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)1, richText = true, fontSize = 16, wordWrap = true }; } float num = Mathf.Min(760f, (float)Screen.width - 40f); GUIContent val = new GUIContent(text); float num2 = _style.CalcHeight(val, num - 20f) + 12f; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((float)Screen.width - num) / 2f, (float)Screen.height * 0.58f, num, num2); Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.55f); GUI.DrawTexture(val2, (Texture)(object)Texture2D.whiteTexture); GUI.color = color; GUI.Label(new Rect(((Rect)(ref val2)).x + 10f, ((Rect)(ref val2)).y + 6f, ((Rect)(ref val2)).width - 20f, ((Rect)(ref val2)).height - 6f), val, _style); } } } internal sealed class Part { public string Prefab; public Vector3 Pos; public float Yaw; public int Tier; public bool Blocking; } internal static class Layout { internal sealed class Result { public List<Part> Parts = new List<Part>(); public List<Vector3> Snaps = new List<Vector3>(); public List<string> SnapNames = new List<string>(); public GameObject Chest; public string Warning; public Vector3 Size; public int ChestCount; public Design Design; public string Note; public float Legs; } private static readonly Dictionary<ChestType, string> ChestTokens = new Dictionary<ChestType, string> { { ChestType.Wood, "$piece_chestwood" }, { ChestType.Reinforced, "$piece_chest" }, { ChestType.BlackMetal, "$piece_chestblackmetal" }, { ChestType.Barrel, "$piece_chestbarrel" }, { ChestType.Personal, "$piece_chestprivate" }, { ChestType.Grausten, "$piece_chestgrausten" } }; private static readonly Dictionary<FrameStyle, string> FramePrefix = new Dictionary<FrameStyle, string> { { FrameStyle.Wood, "wood_" }, { FrameStyle.Ashwood, "ashwood_" } }; private static readonly Dictionary<FrameStyle, string[]> FrameNames = new Dictionary<FrameStyle, string[]> { { FrameStyle.Wood, new string[2] { "wood_floor_1x1", "wood_pole" } }, { FrameStyle.Ashwood, new string[2] { "ashwood_floor_1x1", "ashwood_pole_1m" } } }; internal static PieceTable HammerTable() { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("Hammer") : null); if (!((Object)(object)val != (Object)null)) { return null; } return val.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_buildPieces; } private static IEnumerable<GameObject> HammerPieces() { PieceTable val = HammerTable(); if ((Object)(object)val == (Object)null) { yield break; } foreach (GameObject piece in val.m_pieces) { if ((Object)(object)piece != (Object)null && (Object)(object)piece != (Object)(object)BlueprintPiece.Template && (Object)(object)piece.GetComponent<Piece>() != (Object)null) { yield return piece; } } } internal static GameObject FindChest(ChestType type) { string token = ChestTokens[type]; return HammerPieces().FirstOrDefault((Func<GameObject, bool>)((GameObject go) => go.GetComponent<Piece>().m_name == token && (Object)(object)go.GetComponentInChildren<Container>(true) != (Object)null)); } internal static bool FindFrame(FrameStyle style, out GameObject floor, out GameObject pole) { floor = (pole = null); if (!FramePrefix.TryGetValue(style, out var prefix)) { return false; } List<GameObject> source = (from go in HammerPieces() where ((Object)go).name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) select go).ToList(); if (FrameNames.TryGetValue(style, out var names)) { floor = ((IEnumerable<GameObject>)source).FirstOrDefault((Func<GameObject, bool>)((GameObject go) => ((Object)go).name == names[0])); pole = ((IEnumerable<GameObject>)source).FirstOrDefault((Func<GameObject, bool>)((GameObject go) => ((Object)go).name == names[1])); if ((Object)(object)floor != (Object)null && (Object)(object)pole != (Object)null) { return true; } } floor = (GameObject)(((Object)(object)floor != (Object)null) ? ((object)floor) : ((object)(from x in (from go in source where ((Object)go).name.IndexOf("floor", StringComparison.OrdinalIgnoreCase) >= 0 && ((Object)go).name.IndexOf("deco", StringComparison.OrdinalIgnoreCase) < 0 && ((Object)go).name.IndexOf("tri", StringComparison.OrdinalIgnoreCase) < 0 select new { go = go, b = Visuals.GetBounds(go) }).Where(x => { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_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_0036: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) Bounds b = x.b; if (((Bounds)(ref b)).size.x > 0.8f) { b = x.b; float x2 = ((Bounds)(ref b)).size.x; b = x.b; if (Mathf.Abs(x2 - ((Bounds)(ref b)).size.z) < 0.15f) { b = x.b; return ((Bounds)(ref b)).size.y < 0.6f; } } return false; }).OrderBy(x => { //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_0009: Unknown result type (might be due to invalid IL or missing references) Bounds b = x.b; return ((Bounds)(ref b)).size.x; }) select x.go).FirstOrDefault())); pole = (GameObject)(((Object)(object)pole != (Object)null) ? ((object)pole) : ((object)(from x in (from go in source where ((Object)go).name.IndexOf("pole", StringComparison.OrdinalIgnoreCase) >= 0 && ((Object)go).name.IndexOf("log", StringComparison.OrdinalIgnoreCase) < 0 select new { go = go, b = Visuals.GetBounds(go) }).Where(x => { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) Bounds b = x.b; if (((Bounds)(ref b)).size.y > 0.5f) { b = x.b; return ((Bounds)(ref b)).size.x < 0.5f; } return false; }).OrderBy(x => { //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_0009: Unknown result type (might be due to invalid IL or missing references) Bounds b = x.b; return Mathf.Abs(((Bounds)(ref b)).size.y - 1f); }) select x.go).FirstOrDefault())); if ((Object)(object)floor != (Object)null) { return (Object)(object)pole != (Object)null; } return false; } internal static Bounds Rotate(Bounds b, float yaw) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) Quaternion val = Quaternion.Euler(0f, yaw, 0f); Bounds result = default(Bounds); ((Bounds)(ref result))..ctor(val * ((Bounds)(ref b)).center, Vector3.zero); for (int i = 0; i < 8; i++) { ((Bounds)(ref result)).Encapsulate(val * (((Bounds)(ref b)).center + Vector3.Scale(((Bounds)(ref b)).extents, new Vector3((float)(((i & 1) != 0) ? 1 : (-1)), (float)(((i & 2) != 0) ? 1 : (-1)), (float)(((i & 4) != 0) ? 1 : (-1)))))); } return result; } private static float ChestYaw(Design d, int k, int c, int z, int deep) { bool flag = z * 2 < deep - 1; return Mathf.Repeat(d.Facing switch { ChestFacing.Right => 90f, ChestFacing.Back => 180f, ChestFacing.Left => 270f, ChestFacing.BackToBack => flag ? 180f : 0f, ChestFacing.FaceToFace => flag ? 0f : 180f, _ => 0f, } + (float)(d.Pattern switch { FacingPattern.AlternateRows => k % 2, FacingPattern.AlternateColumns => c % 2, FacingPattern.Checkerboard => (k + c) % 2, _ => 0, }) * 90f, 360f); } private static bool SnapFootprint(GameObject prefab, out Vector2 size, out Vector2 center) { //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_0008: 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) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_014e: Unknown result type (might be due to invalid IL or missing references) size = (center = Vector2.zero); List<Vector3> list = new List<Vector3>(); Matrix4x4 worldToLocalMatrix = prefab.transform.worldToLocalMatrix; Transform[] componentsInChildren = prefab.GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if ((Object)(object)val != (Object)(object)prefab.transform && ((Component)val).CompareTag("snappoint")) { list.Add(((Matrix4x4)(ref worldToLocalMatrix)).MultiplyPoint3x4(val.position)); } } if (list.Count < 3) { return false; } float num = list.Min((Vector3 v) => v.x); float num2 = list.Max((Vector3 v) => v.x); float num3 = list.Min((Vector3 v) => v.z); float num4 = list.Max((Vector3 v) => v.z); size = new Vector2(num2 - num, num4 - num3); center = new Vector2((num + num2) / 2f, (num3 + num4) / 2f); if (size.x > 0.4f) { return size.y > 0.4f; } return false; } private static void ShiftForDividers(float[] centers, float size, float shelf, float tile, float margin, float pt, float clear, List<float> lines) { margin = Mathf.Max(0f, margin); float num = 0f; int num2 = -1; List<float> list = new List<float>(); for (int i = 0; i <= 40; i++) { float num3 = ((i == 0) ? 0f : ((float)((i + 1) / 2) * (margin / 20f) * ((i % 2 == 1) ? 1f : (-1f)))); if (Mathf.Abs(num3) > margin + 0.0001f) { continue; } list.Clear(); for (int j = 0; j + 1 < centers.Length; j++) { float num4 = centers[j] + num3 + size / 2f; float num5 = centers[j + 1] + num3 - size / 2f; float num6 = (num4 + num5) / 2f; float num7 = float.MaxValue; float item = 0f; for (int k = 1; k < Mathf.RoundToInt(shelf / tile); k++) { float num8 = (0f - shelf) / 2f + (float)k * tile; if (!(num8 - pt / 2f < num4 + clear) && !(num8 + pt / 2f > num5 - clear) && Mathf.Abs(num8 - num6) < num7) { num7 = Mathf.Abs(num8 - num6); item = num8; } } if (num7 < float.MaxValue) { list.Add(item); } } if (list.Count > num2) { num2 = list.Count; num = num3; lines.Clear(); lines.AddRange(list); } } for (int l = 0; l < centers.Length; l++) { centers[l] += num; } } internal static Result Generate(Design d) { //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_044e: 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_045e: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_050c: Unknown result type (might be due to invalid IL or missing references) //IL_051c: Unknown result type (might be due to invalid IL or missing references) //IL_0528: Unknown result type (might be due to invalid IL or missing references) //IL_04a8: Unknown result type (might be due to invalid IL or missing references) //IL_04af: Unknown result type (might be due to invalid IL or missing references) //IL_04d8: Unknown result type (might be due to invalid IL or missing references) //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_0409: 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_080a: Unknown result type (might be due to invalid IL or missing references) //IL_090d: Unknown result type (might be due to invalid IL or missing references) //IL_0ac6: Unknown result type (might be due to invalid IL or missing references) //IL_0acb: Unknown result type (might be due to invalid IL or missing references) //IL_0a01: Unknown result type (might be due to invalid IL or missing references) //IL_0a10: Unknown result type (might be due to invalid IL or missing references) //IL_0a38: Unknown result type (might be due to invalid IL or missing references) //IL_0a43: Unknown result type (might be due to invalid IL or missing references) //IL_0a48: Unknown result type (might be due to invalid IL or missing references) //IL_0bad: Unknown result type (might be due to invalid IL or missing references) //IL_0bb2: Unknown result type (might be due to invalid IL or missing references) //IL_0af4: Unknown result type (might be due to invalid IL or missing references) //IL_0afd: Unknown result type (might be due to invalid IL or missing references) //IL_0b10: Unknown result type (might be due to invalid IL or missing references) //IL_0b1b: Unknown result type (might be due to invalid IL or missing references) //IL_0b24: Unknown result type (might be due to invalid IL or missing references) //IL_0b2f: Unknown result type (might be due to invalid IL or missing references) //IL_0b34: Unknown result type (might be due to invalid IL or missing references) //IL_0cd9: Unknown result type (might be due to invalid IL or missing references) Result res = new Result { Design = d }; GameObject val = FindChest(d.Chest); if ((Object)(object)val == (Object)null) { { IEnumerator enumerator = Enum.GetValues(typeof(ChestType)).GetEnumerator(); try { while (enumerator.MoveNext() && !((Object)(object)(val = FindChest((ChestType)enumerator.Current)) != (Object)null)) { } } finally { IDisposable disposable = enumerato