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 ValheimTomrer v0.1.0
ValheimTomrer.dll
Decompiled 3 weeks 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 System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.TextCore; using UnityEngine.U2D; using UnityEngine.UI; using ValheimTomrer.Blueprints; using ValheimTomrer.Blueprints.Sites; using ValheimTomrer.Editor; using ValheimTomrer.Editor.Catalog; using ValheimTomrer.Editor.Doc; using ValheimTomrer.Editor.Input; using ValheimTomrer.Editor.Placement; using ValheimTomrer.Editor.Ui; using ValheimTomrer.Editor.View; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: AssemblyCompany("ValheimTomrer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+f134bd0b2b72768a8df561f6404b91be58c6e570")] [assembly: AssemblyProduct("ValheimTomrer")] [assembly: AssemblyTitle("ValheimTomrer")] [assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was partially or fully created with the assistance of Generative AI (Claude Opus 5).")] [assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.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 ValheimTomrer { [BepInPlugin("com.mikamarik.valheimtomrer", "ValheimTomrer", "0.1.0")] public class ValheimTomrerPlugin : BaseUnityPlugin { public const string PluginGuid = "com.mikamarik.valheimtomrer"; public const string PluginName = "ValheimTomrer"; public const string PluginVersion = "0.1.0"; internal static ValheimTomrerPlugin Instance; internal static ManualLogSource Log; internal static ConfigEntry<bool> ModEnabled; internal static ConfigEntry<KeyCode> BlueprintKey; private Harmony _harmony; private void Awake() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch. Turn off to neutralise ValheimTomrer without uninstalling it."); BlueprintKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Blueprints", "Key", (KeyCode)98, "With a hammer in hand: selects the next blueprint. After the last one, back to normal building."); EditorConfig.Bind(((BaseUnityPlugin)this).Config); BuildConfig.Bind(((BaseUnityPlugin)this).Config); BlueprintLibrary.Reload(); _harmony = new Harmony("com.mikamarik.valheimtomrer"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); Log.LogInfo((object)"ValheimTomrer 0.1.0 loaded."); } private void Update() { EditorSession.Tick(); SiteTracker.Tick(); SiteRemovePopup.Tick(); } private void OnDestroy() { SiteRemovePopup.Destroy(); HintRow.Destroy(); BlueprintMode.Exit(); BlueprintInfoCard.Destroy(); SiteStore.Clear(); EditorSession.Shutdown(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"ValheimTomrer unloaded."); } } } } namespace ValheimTomrer.Patches { [HarmonyPatch(typeof(BuildUi), "OnLayoutChanged")] internal static class BuildUiOnLayoutChangedPatch { private static bool Prefix(BuildUi __instance) { if (!ModUi.Open) { return true; } if ((Object)(object)__instance.m_favoritesDropdown != (Object)null) { __instance.m_favoritesDropdown.Close(); } return false; } } internal static class EditorInputBlockPatches { [HarmonyPatch(typeof(Player), "TakeInput")] private static class PlayerTakeInput { private static void Postfix(ref bool __result) { if (ModUi.Blocking) { __result = false; } } } [HarmonyPatch(typeof(PlayerController), "TakeInput", new Type[] { typeof(bool) })] private static class PlayerControllerTakeInput { private static void Postfix(ref bool __result) { if (ModUi.Blocking) { __result = false; } } } [HarmonyPatch(typeof(TextInput), "IsVisible")] private static class TextInputIsVisible { private static void Postfix(ref bool __result) { if (ModUi.Blocking) { __result = true; } } } [HarmonyPatch(typeof(InventoryGui), "Show", new Type[] { typeof(Container), typeof(int) })] private static class InventoryGuiShow { private static bool Prefix() { return !ModUi.Blocking; } } [HarmonyPatch(typeof(HotkeyBar), "Update")] private static class HotkeyBarUpdate { private static bool Prefix() { return !ModUi.Blocking; } } [HarmonyPatch(typeof(Menu), "Update")] private static class MenuUpdate { private static bool Prefix() { if (!ModUi.Blocking && !WorldCapture.TakesEscape) { return !SiteRemovePopup.TakesEscape; } return false; } } [HarmonyPatch(typeof(Minimap), "Update")] private static class MinimapUpdate { private static bool Prefix() { return !ModUi.Blocking; } } [HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")] private static class GameCameraUpdateMouseCapture { private static void Postfix() { if (ModUi.Blocking) { if (ModUi.LockCursor) { ZCursor.LockState = (CursorLockMode)1; ZCursor.Hide(); } else { ZCursor.LockState = (CursorLockMode)0; ZCursor.Show(); } } } } [HarmonyPatch(typeof(ZInput), "Internal_GetMouseScrollWheel")] private static class ZInputMouseScrollWheel { private static void Postfix(ref float __result) { if (ModUi.Blocking || WorldCapture.Active) { __result = 0f; } } } } [HarmonyPatch(typeof(EnvMan), "Awake")] internal static class EnvManAwakePatch { private static void Postfix(EnvMan __instance) { if (ValheimTomrerPlugin.ModEnabled.Value && !((Object)(object)__instance.m_dirLight == (Object)null)) { Light dirLight = __instance.m_dirLight; dirLight.cullingMask &= -1073741825; ValheimTomrerPlugin.Log.LogInfo((object)($"the world's sun drops layer {30}" + $" (mask 0x{__instance.m_dirLight.cullingMask:X8})")); } } } [HarmonyPatch(typeof(FejdStartup), "Awake")] internal static class FejdStartupAwakePatch { private static void Postfix() { if (ValheimTomrerPlugin.ModEnabled.Value) { bool flag = (Object)(object)FejdStartup.m_instance != (Object)null; ValheimTomrerPlugin.Log.LogInfo((object)("main menu reached | harmony=OK | publicizer=" + (flag ? "OK" : "returned null"))); } } } [HarmonyPatch(typeof(GameCamera), "Awake")] internal static class GameCameraAwakePatch { private static void Postfix(GameCamera __instance) { if (ValheimTomrerPlugin.ModEnabled.Value) { int num = -1073741825; if ((Object)(object)__instance.m_camera != (Object)null) { Camera camera = __instance.m_camera; camera.cullingMask &= num; } if ((Object)(object)__instance.m_skyCamera != (Object)null) { Camera skyCamera = __instance.m_skyCamera; skyCamera.cullingMask &= num; } ValheimTomrerPlugin.Log.LogInfo((object)($"main camera drops layer {30}" + $" (mask 0x{(((Object)(object)__instance.m_camera != (Object)null) ? __instance.m_camera.cullingMask : 0):X8})")); } } } [HarmonyPatch(typeof(Hud), "SetupPieceInfo")] internal static class HudSetupPieceInfoPatch { private static void Postfix(Hud __instance) { if (!ValheimTomrerPlugin.ModEnabled.Value || !BlueprintMode.Active || Hud.IsPieceSelectionVisible() || (Object)(object)Player.m_localPlayer == (Object)null) { BlueprintInfoCard.Hide(); } else { BlueprintInfoCard.Show(__instance, Player.m_localPlayer, BlueprintMode.Current); } } } [HarmonyPatch(typeof(KeyHints), "UpdateHints")] internal static class KeyHintsUpdateHintsPatch { private static bool Prefix(KeyHints __instance) { return !HintRow.TakeOver(__instance); } } [HarmonyPatch(typeof(Player), "CanRotatePiece")] internal static class PlayerCanRotatePiecePatch { private static void Postfix(Player __instance, ref bool __result) { if (BlueprintMode.Active && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { __result = true; } } } [HarmonyPatch(typeof(Player), "InRepairMode")] internal static class PlayerInRepairModePatch { private static void Postfix(Player __instance, ref bool __result) { if (BlueprintMode.Active && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { __result = false; } } } [HarmonyPatch(typeof(Player), "SetSelectedPiece", new Type[] { typeof(Vector2Int) })] internal static class PlayerSetSelectedPiecePatch { private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { BlueprintMode.Exit(); } } } [HarmonyPatch(typeof(Player), "UpdateAvailablePiecesList")] internal static class PlayerUpdateAvailablePiecesListPatch { private static void Postfix(Player __instance) { if (ValheimTomrerPlugin.ModEnabled.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { PieceCatalog.Invalidate(); } } } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] internal static class PlayerUpdatePlacementGhostPatch { private static bool Prefix(Player __instance) { if (!BlueprintMode.Active || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } BlueprintMode.UpdatePreview(__instance); return false; } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] internal static class PlayerUpdatePlacementPatch { private static bool Prefix(Player __instance, bool takeInput) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } if (!ValheimTomrerPlugin.ModEnabled.Value || !((Character)__instance).InPlaceMode() || ((Character)__instance).IsDead()) { BlueprintMode.Exit(); return true; } if (takeInput && !Hud.IsPieceSelectionVisible() && (ZInput.GetKeyDown(ValheimTomrerPlugin.BlueprintKey.Value, false) || WorldPad.NextBlueprint)) { BlueprintMode.Cycle(__instance); } if (!BlueprintMode.Active) { return true; } __instance.m_hoveringPiece = null; if (!takeInput) { return false; } __instance.UpdateBuildGuiInput(); if (!Hud.IsPieceSelectionVisible()) { BlueprintMode.HandleInput(__instance); } return false; } } [HarmonyPatch(typeof(ZInput), "TryGetButtonState")] internal static class ZInputTryGetButtonStatePatch { private static bool Prefix(string name, ref bool __result) { if (!WorldPad.HeldBack(name)) { return true; } __result = false; return false; } } } namespace ValheimTomrer.Editor { internal sealed class BlueprintCard { public string Name = ""; public Sprite Icon; public string Description = ""; public static BlueprintCard Build(BlueprintDocument document) { BlueprintCard blueprintCard = new BlueprintCard(); if (document == null) { return blueprintCard; } List<PieceEntry> list = new List<PieceEntry>(document.Pieces.Count); foreach (DocPiece piece in document.Pieces) { PieceEntry pieceEntry = PieceCatalog.Find(piece.PrefabName); if (pieceEntry != null) { list.Add(pieceEntry); } } blueprintCard.Name = document.Name ?? ""; blueprintCard.Icon = (list.FirstOrDefault((PieceEntry e) => e.PrefabName == document.IconPrefab) ?? list.FirstOrDefault())?.Icon; blueprintCard.Description = BlueprintInfoCard.Description(document.Description, document.Pieces.Count); return blueprintCard; } public static Tally Materials(BlueprintDocument document, MaterialSources sources, bool costsOff, Vector3? stationsAt = null) { List<Piece> list = new List<Piece>(document?.Pieces.Count ?? 0); HashSet<string> hashSet = new HashSet<string>(); if (document != null) { foreach (DocPiece piece in document.Pieces) { PieceEntry entry; Piece val = PieceOf(piece.PrefabName, out entry); if (!((Object)(object)val == (Object)null)) { list.Add(val); if (!string.IsNullOrEmpty(entry.OwnStationToken)) { hashSet.Add(entry.OwnStationToken); } } } } return MaterialTally.For(list, hashSet, null, costsOff ? null : sources, costsOff, stationsAt); } private static Piece PieceOf(string prefabName, out PieceEntry entry) { entry = PieceCatalog.Find(prefabName); if (entry == null) { return null; } GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefabName) : null); Piece val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Piece>() : null); if (!((Object)(object)val2 != (Object)null)) { return entry.Piece; } return val2; } } internal enum CheckLevel { Error, Warning, Note } internal sealed class Check { public CheckLevel Level; public string Message; public int[] Pieces; public string LevelWord { get { if (Level != CheckLevel.Error) { if (Level != CheckLevel.Warning) { return "Note"; } return "Warning"; } return "Error"; } } } internal static class Checks { public const float SameSpot = 0.05f; public const float RotatedOverlapAngle = 10f; public const float OriginTolerance = 1f; public static List<Check> Run(BlueprintDocument document, string readError = null) { List<Check> list = new List<Check>(); if (document == null) { return list; } IReadOnlyList<DocPiece> pieces = document.Pieces; ReadError(list, readError); if (pieces.Count == 0) { Add(list, CheckLevel.Warning, "No pieces yet. The build tool skips an empty blueprint."); } else if (pieces.Count > 2000) { Add(list, CheckLevel.Error, $"{pieces.Count} pieces. The mod reads at most {2000}."); } Kinds(list, pieces); Scaled(list, pieces); SameSpotPieces(list, pieces); Falling(list, pieces); Icon(list, document); Origin(list, pieces); return list.OrderBy((Check c) => (int)c.Level).ToList(); } public static string Summary(IList<Check> checks) { if (checks == null || checks.Count == 0) { return ""; } List<string> list = new List<string>(3); Count(list, checks, CheckLevel.Error, "error"); Count(list, checks, CheckLevel.Warning, "warning"); Count(list, checks, CheckLevel.Note, "note"); return string.Join(", ", list.ToArray()); } public static Vector3? ScaleOf(DocPiece piece) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) if (piece == null || string.IsNullOrEmpty(piece.Rest)) { return null; } string[] array = piece.Rest.Split(';'); if (array.Length < 4) { return null; } float[] array2 = new float[3]; for (int i = 0; i < 3; i++) { if (!float.TryParse(array[i + 1].Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out array2[i])) { return null; } } return new Vector3(array2[0], array2[1], array2[2]); } public static List<int> SameSpotIds(IReadOnlyList<DocPiece> pieces) { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) Dictionary<string, List<DocPiece>> dictionary = new Dictionary<string, List<DocPiece>>(); foreach (DocPiece piece in pieces) { string key = CellKey(piece); if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new List<DocPiece>()); } value.Add(piece); } List<int> list2 = new List<int>(); HashSet<int> hashSet = new HashSet<int>(); foreach (DocPiece piece2 in pieces) { bool flag = PieceCatalog.Find(piece2.PrefabName)?.AllowRotatedOverlap ?? false; for (int i = -1; i <= 1; i++) { if (hashSet.Contains(piece2.Id)) { break; } for (int j = -1; j <= 1; j++) { if (hashSet.Contains(piece2.Id)) { break; } for (int k = -1; k <= 1; k++) { if (hashSet.Contains(piece2.Id)) { break; } string key2 = CellKey(piece2, i, j, k); if (!dictionary.TryGetValue(key2, out var value2)) { continue; } foreach (DocPiece item in value2) { if (item.Id != piece2.Id && !(Vector3.Distance(piece2.Position, item.Position) >= 0.05f) && (!flag || !(Quaternion.Angle(piece2.Rotation, item.Rotation) > 10f))) { list2.Add(piece2.Id); hashSet.Add(piece2.Id); break; } } } } } } return list2; } public static Bounds? Box(IReadOnlyList<DocPiece> pieces) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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) if (pieces == null || pieces.Count == 0) { return null; } Bounds value = default(Bounds); ((Bounds)(ref value))..ctor(pieces[0].Position, Vector3.zero); foreach (DocPiece piece in pieces) { PieceEntry pieceEntry = PieceCatalog.Find(piece.PrefabName); if (pieceEntry != null && !(((Bounds)(ref pieceEntry.Bounds)).size == Vector3.zero)) { ((Bounds)(ref value)).Encapsulate(EditorState.BoxOf(piece)); } } return value; } private static void ReadError(List<Check> found, string readError) { if (string.IsNullOrEmpty(readError)) { return; } int result = 0; string text = readError; int num = readError.IndexOf("line ", StringComparison.OrdinalIgnoreCase); if (num >= 0) { string text2 = readError.Substring(num + 5); int num2 = text2.IndexOf(':'); if (num2 > 0 && int.TryParse(text2.Substring(0, num2), out result)) { text = text2.Substring(num2 + 1).Trim(); } } Add(found, CheckLevel.Error, (result > 0) ? $"Line {result} cannot be read ({text}). The game skips this file." : ("The file cannot be read (" + text + "). The game skips it.")); } private static void Kinds(List<Check> found, IReadOnlyList<DocPiece> pieces) { List<string> list = new List<string>(); Dictionary<string, List<int>> dictionary = new Dictionary<string, List<int>>(); foreach (DocPiece piece in pieces) { if (!dictionary.TryGetValue(piece.PrefabName, out var value)) { value = new List<int>(); dictionary[piece.PrefabName] = value; list.Add(piece.PrefabName); } value.Add(piece.Id); } foreach (string item in list) { int[] array = dictionary[item].ToArray(); PieceEntry pieceEntry = PieceCatalog.Find(item); if (pieceEntry == null) { string text = PieceCatalog.OtherTool(item); Add(found, CheckLevel.Error, (text != null) ? (item + " is a " + text.ToLowerInvariant() + " piece (" + Plural(array.Length, "piece") + "). The blueprint is never offered.") : $"Unknown piece {item} ({array.Length}x). The game skips the whole blueprint.", array); continue; } if (pieceEntry.Seasonal) { Add(found, CheckLevel.Warning, pieceEntry.DisplayName + " is seasonal. The blueprint is offered only in its season.", array); } if (pieceEntry.Dlc.Length > 0 && (Object)(object)DLCMan.instance != (Object)null && !DLCMan.instance.IsDLCInstalled(pieceEntry.Dlc)) { Add(found, CheckLevel.Warning, pieceEntry.DisplayName + " needs the " + pieceEntry.Dlc + " DLC, which is not installed.", array); } if (!pieceEntry.Seasonal && !PieceCatalog.IsUnlocked(pieceEntry)) { Add(found, CheckLevel.Warning, pieceEntry.DisplayName + " is not unlocked yet. The blueprint is not offered in build mode.", array); } } } private static void Scaled(List<Check> found, IReadOnlyList<DocPiece> pieces) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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) List<int> list = new List<int>(); foreach (DocPiece piece in pieces) { Vector3? val = ScaleOf(piece); if (val.HasValue && (Mathf.Abs(val.Value.x - 1f) > 0.0001f || Mathf.Abs(val.Value.y - 1f) > 0.0001f || Mathf.Abs(val.Value.z - 1f) > 0.0001f)) { list.Add(piece.Id); } } if (list.Count > 0) { Add(found, CheckLevel.Warning, Plural(list.Count, "piece") + " with a scale other than 1. The mod builds them at normal size.", list.ToArray()); } } private static void SameSpotPieces(List<Check> found, IReadOnlyList<DocPiece> pieces) { List<int> list = SameSpotIds(pieces); if (list.Count > 0) { Add(found, CheckLevel.Warning, Plural(list.Count, "piece") + " sit in the same spot as another piece of the same kind.", list.ToArray()); } } private static void Falling(List<Check> found, IReadOnlyList<DocPiece> pieces) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) List<ScenePiece> list = new List<ScenePiece>(pieces.Count); foreach (DocPiece piece in pieces) { list.Add(new ScenePiece { Id = piece.Id, Prefab = piece.PrefabName, Pos = piece.Position, Rot = piece.Rotation, Entry = PieceCatalog.Find(piece.PrefabName) }); } IReadOnlyList<int> fallen = Support.Solve(list).Fallen; if (fallen.Count > 0) { Add(found, CheckLevel.Warning, Plural(fallen.Count, "piece") + " would fall down in the game. Nothing holds " + ((fallen.Count == 1) ? "it" : "them") + " up.", fallen.ToArray()); } } private static void Icon(List<Check> found, BlueprintDocument document) { string icon = document.IconPrefab; if (!string.IsNullOrEmpty(icon) && !document.Pieces.Any((DocPiece p) => p.PrefabName == icon)) { Add(found, CheckLevel.Warning, "The icon piece " + icon + " is not in the blueprint. The game shows the first piece's icon."); } } private static void Origin(List<Check> found, IReadOnlyList<DocPiece> pieces) { //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_001d: 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) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Bounds? val = Box(pieces); if (val.HasValue) { Bounds value = val.Value; float x = ((Bounds)(ref value)).center.x; value = val.Value; float y = ((Bounds)(ref value)).min.y; value = val.Value; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(x, y, ((Bounds)(ref value)).center.z); if (((Vector3)(ref val2)).magnitude > 1f) { Add(found, CheckLevel.Note, $"The origin is {((Vector3)(ref val2)).magnitude:0.0} m from the bottom centre. Our mod doesn't mind; " + "other mods place blueprints by the origin."); } } } private static void Add(List<Check> found, CheckLevel level, string message, int[] pieces = null) { found.Add(new Check { Level = level, Message = message, Pieces = pieces }); } private static void Count(List<string> parts, IList<Check> checks, CheckLevel level, string word) { int num = 0; foreach (Check check in checks) { if (check.Level == level) { num++; } } if (num > 0) { parts.Add(Plural(num, word)); } } private static string Plural(int count, string word) { return count + " " + word + ((count == 1) ? "" : "s"); } private static string CellKey(DocPiece piece, int dx = 0, int dy = 0, int dz = 0) { return piece.PrefabName + "|" + (Mathf.FloorToInt(piece.Position.x / 0.05f) + dx) + "|" + (Mathf.FloorToInt(piece.Position.y / 0.05f) + dy) + "|" + (Mathf.FloorToInt(piece.Position.z / 0.05f) + dz); } } internal static class EditorCommands { private const float MinBusySeconds = 0.35f; private static bool _working; private static float _busyUntil; private static bool _discardOk; public static string Busy { get; private set; } public static void NewBlueprint() { if (!AskFirst("Start a new blueprint?", NewBlueprint)) { EditorSession.Replace(DocumentStore.New()); Toasts.Info("New blueprint."); } } public static void OpenDialog() { Dialogs.Open(); } public static void OpenEntry(BlueprintEntry entry) { if (entry != null && !AskFirst("Open " + entry.Name + "?", delegate { OpenEntry(entry); })) { Begin("Opening"); BlueprintDocument document; string error; bool num = (entry.IsKit ? DocumentStore.OpenKit(entry, out document, out error) : DocumentStore.Open(entry.Path, out document, out error)); Done(); if (!num) { Toasts.Error(error); return; } Dialogs.Close(); EditorSession.Replace(document); Toasts.Ok($"Opened {document.Name}, {document.Pieces.Count} pieces."); } } public static bool DeleteEntry(BlueprintEntry entry) { if (entry == null || entry.IsKit || string.IsNullOrEmpty(entry.Path)) { return false; } string fileName = Path.GetFileName(entry.Path); if (!File.Exists(entry.Path)) { Toasts.Error(fileName + " is not there any more."); return false; } Begin("Deleting"); string error; bool num = DocumentStore.Delete(entry.Path, out error); Done(); if (!num) { Toasts.Error(error); return false; } BlueprintDocument document = EditorState.Document; if (document != null && string.Equals(document.SourcePath, entry.Path, StringComparison.OrdinalIgnoreCase)) { document.LoseFile(); } ValheimTomrerPlugin.Log.LogInfo((object)("editor deleted blueprint file " + entry.Path)); Toasts.Ok("Deleted " + fileName + "."); return true; } public static void Take(BlueprintDocument document, ResolvedBlueprint blueprint, Action taken = null) { if (document != null) { string text = (string.IsNullOrEmpty(document.Name) ? "this blueprint" : document.Name); if (!AskFirst("Open " + text + "?", delegate { Take(document, blueprint, taken); })) { EditorSession.Replace(document, blueprint); taken?.Invoke(); } } } public static bool Save() { BlueprintDocument document = EditorState.Document; if (document == null) { return false; } if (document.ReadOnly || string.IsNullOrEmpty(document.SourcePath)) { Dialogs.SaveAs(document.Name); return false; } Begin("Saving"); string error; bool num = DocumentStore.Save(document, out error); Done(); if (!num) { Toasts.Error(error); return false; } Toasts.Ok("Saved " + Path.GetFileName(document.SourcePath) + "."); return true; } public static bool SaveAs(string name, bool overwrite) { BlueprintDocument document = EditorState.Document; if (document == null) { return false; } Begin("Saving"); string error; bool num = DocumentStore.SaveAs(document, name, overwrite, out error); Done(); if (!num) { Toasts.Error(error); return false; } Dialogs.Close(); Toasts.Ok("Saved " + Path.GetFileName(document.SourcePath) + "."); return true; } public static bool BuildThis() { BlueprintDocument document = EditorState.Document; if (document == null) { return false; } if (document.Pieces.Count == 0) { Toasts.Error("A blueprint needs at least one piece."); return false; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { Toasts.Error("No player to build with."); return false; } if (!((Character)localPlayer).InPlaceMode()) { Toasts.Error("Take the hammer out first, then press Build this again."); return false; } if (document.Dirty && !Save()) { return false; } if (!ResolvedBlueprint.TryResolve(document.ToBlueprint(), out var resolved, out var error)) { Toasts.Error(error); return false; } List<Piece> list = BlueprintRules.UnavailablePieces(localPlayer, resolved); if (list.Count > 0) { Toasts.Error("Not unlocked yet: " + string.Join(", ", list.Select((Piece p) => Localization.instance.Localize(p.m_name)))); return false; } EditorSession.Close(); BlueprintMode.Select(localPlayer, resolved); ((Character)localPlayer).Message((MessageType)2, resolved.Name + ": click to build", 0, (Sprite)null, false); ValheimTomrerPlugin.Log.LogInfo((object)$"editor handed '{resolved.Name}' ({resolved.Parts.Count} pieces) to the build tool"); return true; } public static void CenterOrigin() { BlueprintDocument document = EditorState.Document; if (document != null) { if (document.HasSections) { Toasts.Error("This file has snap point or terrain sections that would have to move too."); } else if (!EditorState.CenterOrigin()) { Toasts.Info("The origin is already at the bottom centre."); } else { Toasts.Ok("The origin is now the bottom centre."); } } } public static void ToggleBoxes() { EditorState.PieceBoxesOn = !EditorState.PieceBoxesOn; Remember(EditorConfig.Boxes, EditorState.PieceBoxesOn); Toasts.Info(EditorState.PieceBoxesOn ? "Pieces as boxes." : "Pieces as models."); } public static void ToggleSnapDots() { EditorState.SnapDotsOn = !EditorState.SnapDotsOn; Remember(EditorConfig.SnapDots, EditorState.SnapDotsOn); Toasts.Info(EditorState.SnapDotsOn ? "Snap dots on." : "Snap dots off."); } private static void Remember(ConfigEntry<bool> entry, bool value) { if (entry != null && entry.Value != value) { entry.Value = value; } } public static void Help() { Dialogs.Help(); } public static void Tick() { if (!_working && Busy != null && Time.unscaledTime >= _busyUntil) { Busy = null; } } public static void Reset() { _working = false; _discardOk = false; Busy = null; } private static bool AskFirst(string title, Action again) { if (_discardOk) { _discardOk = false; return false; } BlueprintDocument document = EditorState.Document; if (document == null || !document.Dirty) { return false; } string text = (string.IsNullOrEmpty(document.Name) ? "This blueprint" : document.Name); Dialogs.Confirm(title, text + " has changes that are not saved. They will be lost.", "Discard", delegate { _discardOk = true; again(); _discardOk = false; }); return true; } private static void Begin(string what) { _working = true; Busy = what; _busyUntil = Time.unscaledTime + 0.35f; } private static void Done() { _working = false; } } internal static class EditorConfig { public const int Layer = 30; public static ConfigEntry<KeyCode> Key; public static ConfigEntry<KeyCode> CaptureKey; public static ConfigEntry<bool> ShowAllPieces; public static ConfigEntry<bool> SnapDots; public static ConfigEntry<bool> Boxes; public static void Bind(ConfigFile config) { Key = config.Bind<KeyCode>("Editor", "Key", (KeyCode)288, "Opens and closes the blueprint editor. Esc and the pad's circle close it too."); CaptureKey = config.Bind<KeyCode>("Editor", "CaptureKey", (KeyCode)289, "With the editor closed: puts a rectangle on the ground where you aim. The wheel turns it, Shift + wheel and Alt + wheel change its sides. Press again and what stands inside opens in the editor as a new blueprint. Esc stops it."); ShowAllPieces = config.Bind<bool>("Editor", "ShowAllPieces", false, "Show every building piece in the editor. Off means only the ones this character has unlocked."); SnapDots = config.Bind<bool>("Editor", "SnapDots", true, "Show the snap dots while placing a piece. Snapping itself is always on."); Boxes = config.Bind<bool>("Editor", "Boxes", false, "Draw pieces as plain boxes instead of models. Easier to see through a full blueprint."); Drop(config, "Editor", "LookSensitivity"); Drop(config, "Editor", "PadLookSensitivity"); Drop(config, "Editor", "CameraMode"); } private static void Drop(ConfigFile config, string section, string key) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown if (AccessTools.Property(typeof(ConfigFile), "OrphanedEntries")?.GetValue(config) is Dictionary<ConfigDefinition, string> dictionary && dictionary.Remove(new ConfigDefinition(section, key))) { config.Save(); } } } internal static class EditorSession { private static int _syncedSelection = -1; public static bool IsOpen => ModUi.Open; public static BlueprintDocument Document => EditorState.Document; public static bool Kept { get { if (!ModUi.Open) { return EditorState.Document != null; } return false; } } public static void Tick() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) WorldPad.Tick(); if (!ValheimTomrerPlugin.ModEnabled.Value) { WorldCapture.Cancel(); if (ModUi.Open) { Close(); } return; } EditorInput.Poll(); if (!ModUi.Open) { if (!CanOpen()) { WorldCapture.Cancel(); } else if (ZInput.GetKeyDown(EditorConfig.Key.Value, true) || WorldPad.OpenEditor) { ResolvedBlueprint current = BlueprintMode.Current; Open(current); if (current != null && ModUi.Open) { BlueprintMode.Exit(); ValheimTomrerPlugin.Log.LogInfo((object)("editor took '" + current.Name + "' out of the build tool's hand")); } } else { WorldCapture.Tick(); } return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).IsTeleporting()) { Close(); } else { if (Console.IsVisible() || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || UnifiedPopup.IsVisible()) { return; } ViewportHost.Tick(); Palette.Tick(); PiecePicker.Tick(); PieceListPanel.Tick(); BlueprintPanel.Tick(); SelectionPanel.Tick(); ChecksPanel.Tick(); TopBar.Tick(); Dialogs.Tick(); Toasts.Tick(); SyncSelection(); if (ModUi.JustTyping) { if (EditorInput.Pressed(PadButton.Circle)) { FocusNav.StopTyping(); } return; } bool cancel = EditorInput.Cancel; if ((!cancel || !Bindings.Cancel()) && (ZInput.GetKeyDown(EditorConfig.Key.Value, true) || cancel || PadBindings.ClosePressed())) { Close(); } } } public static void Open(ResolvedBlueprint inHand = null) { if (ModUi.Open) { return; } if (EditorState.Document == null) { ResolvedBlueprint resolvedBlueprint = inHand ?? FirstKit(); Begin((resolvedBlueprint != null) ? BlueprintDocument.FromBlueprint(resolvedBlueprint.Blueprint) : BlueprintDocument.New(), resolvedBlueprint); return; } Begin(null, null); if (ModUi.Open && inHand != null && !Holds(EditorState.Document, inHand.Blueprint)) { EditorCommands.Take(BlueprintDocument.FromBlueprint(inHand.Blueprint), inHand); } } public static void OpenDocument(BlueprintDocument document, Action opened = null) { if (ModUi.Open || document == null) { return; } if (EditorState.Document == null) { Begin(document, null); if (ModUi.Open) { opened?.Invoke(); } } else { Begin(null, null); if (ModUi.Open) { EditorCommands.Take(document, null, opened); } } } public static void Replace(BlueprintDocument document, ResolvedBlueprint blueprint = null) { if (ModUi.Open && document != null) { EditorState.Open(document); PiecePicker.Close(); ViewportHost.Show(blueprint); Palette.Selected = null; PieceListPanel.Show(document); BlueprintPanel.Show(document); SelectionPanel.Show(); ChecksPanel.Show(document); _syncedSelection = -1; ValheimTomrerPlugin.Log.LogInfo((object)$"editor now on '{document.Name}' ({document.Pieces.Count} pieces)"); } } private static void Begin(BlueprintDocument document, ResolvedBlueprint blueprint) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 WorldCapture.Cancel(); if (!EditorWindow.Ensure()) { ValheimTomrerPlugin.Log.LogWarning((object)"editor could not open: the HUD is not ready yet."); return; } Hud.HidePieceSelection(); if (InventoryGui.IsVisible()) { InventoryGui.instance.Hide(); } if (StoreGui.IsVisible()) { StoreGui.instance.Hide(); } Minimap instance = Minimap.instance; if ((Object)(object)instance != (Object)null && (int)instance.m_mode == 2) { instance.SetMapMode((MapMode)1); } UITooltip.HideTooltip(); EditorWindow.Show(visible: true); PieceCatalog.Ensure(); ViewportHost.Ensure(EditorWindow.ViewportHost); if (document != null) { EditorState.Open(document); ViewportHost.Show(blueprint); } else { EditorState.Rebind(); ViewportHost.Wake(); } Palette.Ensure(EditorWindow.PalettePane); Palette.Show(); Palette.PieceChosen = StartAdd; PiecePicker.Ensure(EditorWindow.Root); PiecePicker.PieceChosen = StartAdd; PieceListPanel.Ensure(EditorWindow.PieceListPane); PieceListPanel.Show(Document); PieceListPanel.PieceClicked = RowClicked; BlueprintPanel.Ensure(EditorWindow.BlueprintPane); BlueprintPanel.Show(Document); SelectionPanel.Ensure(EditorWindow.SelectionPane); SelectionPanel.Show(); ChecksPanel.Ensure(EditorWindow.ChecksPane); ChecksPanel.Show(Document); TopBar.Ensure(EditorWindow.TopBar); Dialogs.Ensure(EditorWindow.Root); Toasts.Ensure(EditorWindow.Root); FocusNav.Ensure(EditorWindow.Root); _syncedSelection = -1; ModUi.Open = true; EditorInput.Reset(); if (document == null) { FocusNav.Resume(); } ValheimTomrerPlugin.Log.LogInfo((object)((document != null) ? "editor opened" : ($"editor opened again on '{Document.Name}' ({Document.Pieces.Count} pieces" + (Document.Dirty ? ", unsaved changes" : "") + ")"))); } public static void Close() { if (ModUi.Open) { FocusNav.StopTyping(); ViewportHost.Sleep(); PiecePicker.PieceChosen = null; Palette.PieceChosen = null; Palette.Selected = null; Palette.Close(); PieceListPanel.PieceClicked = null; PieceListPanel.Close(); BlueprintPanel.Close(); SelectionPanel.Close(); ChecksPanel.Close(); Toasts.Clear(); EditorCommands.Reset(); Bindings.Reset(); PadBindings.Reset(); EditorWindow.Show(visible: false); ModUi.MarkClosed(); UITooltip.HideTooltip(); PlayerController.SetTakeInputDelay(0.2f); ZInput.ResetAllButtonStates(); EditorInput.Reset(); ValheimTomrerPlugin.Log.LogInfo((object)"editor closed, its state kept"); } } public static void Forget() { Close(); Dialogs.Close(); PiecePicker.Close(); FocusNav.Leave(); ViewportHost.Close(); EditorState.Close(); } public static void StartAdd(PieceEntry entry) { if (EditorState.StartAdd(entry)) { Palette.Selected = entry; } } private static void RowClicked(int id, bool additive) { EditorState.Select(id, additive ? SelectHow.Toggle : SelectHow.Set); } private static void SyncSelection() { if (_syncedSelection != EditorState.Version) { _syncedSelection = EditorState.Version; PieceListPanel.SetSelection(EditorState.Selection); Palette.Selected = ((EditorState.Mode == EditMode.Place) ? EditorState.Held : null); } } public static void Shutdown() { Forget(); WorldCapture.Shutdown(); EditorWindow.Destroy(); PieceCatalog.Clear(); UiTheme.Clear(); } private static ResolvedBlueprint FirstKit() { foreach (Blueprint item in BlueprintLibrary.All) { if (ResolvedBlueprint.TryResolve(item, out var resolved, out var error)) { return resolved; } ValheimTomrerPlugin.Log.LogWarning((object)error); } return null; } private static bool Holds(BlueprintDocument document, Blueprint blueprint) { if (string.IsNullOrEmpty(document.SourcePath) || string.IsNullOrEmpty(blueprint.SourcePath)) { if (string.IsNullOrEmpty(document.SourcePath) && string.IsNullOrEmpty(blueprint.SourcePath) && document.ReadOnly && blueprint.ReadOnly) { return document.Name == blueprint.Name; } return false; } return string.Equals(Path.GetFullPath(document.SourcePath), Path.GetFullPath(blueprint.SourcePath), StringComparison.Ordinal); } internal static bool CanOpen() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).IsTeleporting()) { return false; } if ((Object)(object)Hud.instance == (Object)null) { return false; } if (Menu.IsVisible() || Console.IsVisible() || TextInput.IsVisible() || UnifiedPopup.IsVisible()) { return false; } if (!((Object)(object)Chat.instance == (Object)null)) { return !Chat.instance.HasFocus(); } return true; } } internal enum EditMode { Idle, Place } internal enum PlaceAction { Add, Move, Duplicate } internal enum SelectHow { Set, Add, Toggle } internal static class EditorState { private const int SearchAllFrom = 8; private static readonly HashSet<int> Selected = new HashSet<int>(); private static readonly List<int> MovingIds = new List<int>(); private static SceneIndex _index; private static int _indexRevision = -1; private static int _indexMoving = -1; private static SupportMap _stability; private static SceneIndex _stabilityIndex; private static PlaceResult _weighed; private static SupportMap _weighedMap; private static MovingSet _weighedSet; private static PieceTable _catalog; private static readonly int[] EmptyIds = new int[0]; public static bool PieceBoxesOn { get; set; } public static bool SnapDotsOn { get; set; } = true; public static BlueprintDocument Document { get; private set; } public static IReadOnlyCollection<int> Selection => Selected; public static int SelectionCount => Selected.Count; public static IReadOnlyList<int> Carrying { get { if (Mode != EditMode.Place || Action != PlaceAction.Move) { return EmptyIds; } return MovingIds; } } public static EditMode Mode { get; private set; } = EditMode.Idle; public static PlaceAction Action { get; private set; } public static MovingSet Moving { get; private set; } public static PieceEntry Held { get; private set; } public static int Steps { get; private set; } public static int PlaceSteps { get; private set; } public static int Manual { get; private set; } = -1; public static bool Snapping { get; set; } = true; public static PlaceResult Aimed { get; private set; } public static string Message { get; private set; } public static float MessageAt { get; private set; } public static int Version { get; private set; } public static SceneIndex Index { get { int num = ((Action == PlaceAction.Move && Mode == EditMode.Place) ? MovingIds.Count : 0); if (_index != null && Document != null && _indexRevision == Document.Revision && _indexMoving == num) { return _index; } _indexRevision = ((Document != null) ? Document.Revision : (-1)); _indexMoving = num; _index = new SceneIndex(StandingPieces()); return _index; } } public static SupportMap Stability { get { SceneIndex index = Index; if (_stability == null || _stabilityIndex != index) { _stability = Support.Solve(index); _stabilityIndex = index; } return _stability; } } public static void Open(BlueprintDocument document) { if (document != null) { PieceBoxesOn = EditorConfig.Boxes != null && EditorConfig.Boxes.Value; SnapDotsOn = EditorConfig.SnapDots == null || EditorConfig.SnapDots.Value; } Document = document; Selected.Clear(); MovingIds.Clear(); Mode = EditMode.Idle; Moving = null; Held = null; Steps = 0; PlaceSteps = 0; Manual = -1; Snapping = true; Aimed = null; Message = null; _index = null; _indexRevision = -1; _stability = null; _stabilityIndex = null; _weighed = null; _catalog = PieceCatalog.Table; Version++; } public static void Close() { Open(null); } public static void Rebind() { if (_catalog == PieceCatalog.Table) { return; } _catalog = PieceCatalog.Table; _index = null; _stability = null; _stabilityIndex = null; _weighed = null; if (Document == null || Mode != EditMode.Place || Moving == null) { return; } bool flag = false; foreach (MovingPiece piece in Moving.Pieces) { flag |= piece.Entry != PieceCatalog.Find(piece.Prefab); } if (!flag) { return; } if (Held != null) { PieceEntry pieceEntry = PieceCatalog.Find(Held.PrefabName); if (pieceEntry == null) { CancelMode(); return; } Held = pieceEntry; Moving = MovingSet.One(pieceEntry); Version++; return; } List<DocPiece> list = new List<DocPiece>(); foreach (MovingPiece piece2 in Moving.Pieces) { DocPiece docPiece = Document.Find(piece2.Id); if (docPiece == null) { CancelMode(); return; } list.Add(docPiece); } Moving = MovingSet.Of(MovingPieces(list)); Version++; } public static void Select(IEnumerable<int> ids, SelectHow how = SelectHow.Set) { if (how == SelectHow.Set) { Selected.Clear(); } if (ids != null) { foreach (int id in ids) { if (how == SelectHow.Toggle && Selected.Contains(id)) { Selected.Remove(id); } else { Selected.Add(id); } } } Version++; } public static bool IsSelected(int id) { return Selected.Contains(id); } public static void Select(int id, SelectHow how = SelectHow.Set) { Select(new int[1] { id }, how); } public static void SelectAll() { Selected.Clear(); if (Document != null) { foreach (DocPiece piece in Document.Pieces) { Selected.Add(piece.Id); } } Version++; } public static void DeleteSelection() { if (Document != null && Selected.Count != 0) { int count = Selected.Count; Document.RemovePieces(new List<int>(Selected)); Selected.Clear(); CancelMode(); Say("Deleted " + Count(count) + ". Ctrl+Z brings " + ((count == 1) ? "it" : "them") + " back."); Version++; } } public static List<DocPiece> SelectedPieces() { List<DocPiece> list = new List<DocPiece>(Selected.Count); if (Document == null) { return list; } foreach (DocPiece piece in Document.Pieces) { if (Selected.Contains(piece.Id)) { list.Add(piece); } } return list; } public static bool StartAdd(PieceEntry entry) { if (Document == null || entry == null) { return false; } Held = entry; Moving = MovingSet.One(entry); Action = PlaceAction.Add; Mode = EditMode.Place; Steps = PlaceSteps; Manual = -1; Aimed = null; Version++; return true; } public static bool StartMove() { List<DocPiece> list = SelectedPieces(); if (list.Count == 0) { return false; } MovingIds.Clear(); foreach (DocPiece item in list) { MovingIds.Add(item.Id); } Held = null; Moving = MovingSet.Of(MovingPieces(list)); Action = PlaceAction.Move; Mode = EditMode.Place; Steps = 0; Manual = -1; Aimed = null; _index = null; Version++; return true; } public static bool StartDuplicate() { List<DocPiece> list = SelectedPieces(); if (list.Count == 0) { return false; } MovingIds.Clear(); Held = null; Moving = MovingSet.Of(MovingPieces(list)); Action = PlaceAction.Duplicate; Mode = EditMode.Place; Steps = 0; Manual = -1; Aimed = null; Version++; return true; } public static void CancelMode() { if (Mode != EditMode.Idle) { Mode = EditMode.Idle; Moving = null; Held = null; MovingIds.Clear(); Aimed = null; _index = null; Version++; } } public static void SetPlaceSteps(int steps) { if (Mode == EditMode.Place) { Steps = steps; if (Action == PlaceAction.Add) { PlaceSteps = steps; } Version++; } } public static void SetManualSnap(int manual) { if (Mode == EditMode.Place && Moving != null) { Manual = Placer.WrapManual(manual, Moving.Snaps.Count); Version++; } } public static string ManualName() { if (Moving == null || Manual < 0 || Manual >= Moving.Snaps.Count) { return null; } return Moving.Snaps[Manual].Name; } public static bool Aim(Vector3 origin, Vector3 dir, out PlaceResult result) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) result = null; if (Mode != EditMode.Place || Moving == null || Moving.Count == 0) { Aimed = null; return false; } PlaceOptions opts = new PlaceOptions { Steps = Steps, Manual = Manual, Snapping = Snapping, SearchAll = (Moving.Count > 8), Assist = true }; bool num = Placer.Place(Index, Moving, origin, ((Vector3)(ref dir)).normalized, opts, out result); if (num) { Weigh(result); } Aimed = (num ? result : null); return num; } private static void Weigh(PlaceResult result) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) SupportMap stability = Stability; if (_weighed != null && _weighedMap == stability && _weighedSet == Moving && _weighed.Pos == result.Pos && _weighed.Rot == result.Rot) { result.Support = _weighed.Support; result.Falls = _weighed.Falls; result.WouldFall = _weighed.WouldFall; return; } int num = result.World.Length; result.Support = new float[num]; result.Falls = new bool[num]; result.WouldFall = Support.Evaluate(stability, result.World, result.Support, result.Falls); _weighed = result; _weighedMap = stability; _weighedSet = Moving; } public static string FallText(PlaceResult result) { int num = 0; if (result != null && result.Falls != null) { bool[] falls = result.Falls; foreach (bool flag in falls) { num += (flag ? 1 : 0); } } if (num > 1 || (result != null && result.World.Length > 1)) { return Count(num) + " would fall down, nothing holds " + ((num == 1) ? "it" : "them") + " up there"; } return "it would fall down, nothing holds it up there"; } public static void ClearAim() { Aimed = null; } public static bool CommitPlacement(PlaceResult result) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_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_0186: Unknown result type (might be due to invalid IL or missing references) if (Document == null || Mode != EditMode.Place || Moving == null || result == null || result.Duplicate) { return false; } if (result.WouldFall) { string text = FallText(result); Say(char.ToUpperInvariant(text[0]) + text.Substring(1) + "."); return false; } PlacedPiece[] world = result.World; switch (Action) { case PlaceAction.Add: Select(Document.AddPiece(world[0].Prefab, world[0].Pos, Clean(world[0].Rot))); break; case PlaceAction.Move: { List<PieceMove> list2 = new List<PieceMove>(world.Length); PlacedPiece[] array = world; for (int i = 0; i < array.Length; i++) { PlacedPiece placedPiece2 = array[i]; list2.Add(new PieceMove { Id = placedPiece2.Id, Position = placedPiece2.Pos, Rotation = Clean(placedPiece2.Rot) }); } Document.SetPieces(list2); CancelMode(); break; } default: { List<NewPiece> list = new List<NewPiece>(world.Length); PlacedPiece[] array = world; for (int i = 0; i < array.Length; i++) { PlacedPiece placedPiece = array[i]; list.Add(new NewPiece { PrefabName = placedPiece.Prefab, Position = placedPiece.Pos, Rotation = Clean(placedPiece.Rot) }); } Select(Document.AddPieces(list)); break; } } Aimed = null; Version++; return true; } public static void Nudge(Vector3 delta) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //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_0058: 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_0065: 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) List<DocPiece> list = SelectedPieces(); if (list.Count == 0 || delta == Vector3.zero) { return; } List<PieceMove> list2 = new List<PieceMove>(list.Count); foreach (DocPiece item in list) { list2.Add(new PieceMove { Id = item.Id, Position = item.Position + delta, Rotation = item.Rotation }); } Document.SetPieces(list2, "nudge"); } public static void RotateSelection(int direction) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_00d4: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) List<DocPiece> list = SelectedPieces(); if (list.Count == 0) { return; } foreach (DocPiece item in list) { PieceEntry pieceEntry = PieceCatalog.Find(item.PrefabName); if (pieceEntry != null && !pieceEntry.CanRotate) { Say("This piece can't turn in the game."); return; } } Quaternion val = Quaternion.Euler(0f, 22.5f * Mathf.Sign((float)direction), 0f); Vector3 val2 = ((list.Count == 1) ? list[0].Position : BottomCentre(list)); List<PieceMove> list2 = new List<PieceMove>(list.Count); foreach (DocPiece item2 in list) { list2.Add(new PieceMove { Id = item2.Id, Position = val2 + val * (item2.Position - val2), Rotation = Clean(val * item2.Rotation) }); } Document.SetPieces(list2); } public static void SetYaw(int id, float degrees) { //IL_002b: 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_0035: 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_0081: 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_0064: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) DocPiece docPiece = ((Document != null) ? Document.Find(id) : null); if (docPiece != null && !float.IsNaN(degrees) && !float.IsInfinity(degrees)) { Quaternion q = ((Vector3.Angle(docPiece.Rotation * Vector3.up, Vector3.up) < 0.01f) ? Quaternion.Euler(0f, degrees, 0f) : (Quaternion.Euler(0f, degrees - YawOf(docPiece.Rotation), 0f) * docPiece.Rotation)); Document.SetPieces(new List<PieceMove> { new PieceMove { Id = id, Position = docPiece.Position, Rotation = Clean(q) } }, "yaw:" + id); } } public static void SetPosition(int id, Vector3 position) { //IL_0037: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) DocPiece docPiece = ((Document != null) ? Document.Find(id) : null); if (docPiece != null) { Document.SetPieces(new List<PieceMove> { new PieceMove { Id = id, Position = position, Rotation = docPiece.Rotation } }, "pos:" + id); } } public static bool CenterOrigin() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) if (Document == null || Document.HasSections || Document.Pieces.Count == 0) { return false; } List<DocPiece> list = new List<DocPiece>(Document.Pieces); Vector3 val = BottomCentre(list); if (((Vector3)(ref val)).magnitude < 0.0001f) { Say("The origin is already at the bottom centre."); return false; } List<PieceMove> list2 = new List<PieceMove>(list.Count); foreach (DocPiece item in list) { list2.Add(new PieceMove { Id = item.Id, Position = item.Position - val, Rotation = item.Rotation }); } Document.SetPieces(list2); Say($"Moved the origin by {val.x:0.00}, {val.y:0.00}, {val.z:0.00} m."); return true; } public static bool Undo() { CancelMode(); if (Document == null || !Document.Undo()) { return false; } Prune(); return true; } public static bool Redo() { CancelMode(); if (Document == null || !Document.Redo()) { return false; } Prune(); return true; } public static Bounds BoxOf(DocPiece piece) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_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_0042: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) PieceEntry pieceEntry = PieceCatalog.Find(piece.PrefabName); if (pieceEntry == null || ((Bounds)(ref pieceEntry.Bounds)).size == Vector3.zero) { return new Bounds(piece.Position, Vector3.one * 0.5f); } Vector3 val = piece.Position + piece.Rotation * ((Bounds)(ref pieceEntry.Bounds)).center; Vector3 extents = ((Bounds)(ref pieceEntry.Bounds)).extents; Vector3 val2 = Abs(piece.Rotation * new Vector3(extents.x, 0f, 0f)) + Abs(piece.Rotation * new Vector3(0f, extents.y, 0f)) + Abs(piece.Rotation * new Vector3(0f, 0f, extents.z)); return new Bounds(val, val2 * 2f); } public static Bounds? BoxOf(IList<DocPiece> pieces) { //IL_001c: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (pieces == null || pieces.Count == 0) { return null; } Bounds value = BoxOf(pieces[0]); for (int i = 1; i < pieces.Count; i++) { ((Bounds)(ref value)).Encapsulate(BoxOf(pieces[i])); } return value; } public static Vector3 BottomCentre(IList<DocPiece> pieces) { //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_0011: 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_0029: 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) Bounds valueOrDefault = BoxOf(pieces).GetValueOrDefault(); return new Vector3(((Bounds)(ref valueOrDefault)).center.x, ((Bounds)(ref valueOrDefault)).min.y, ((Bounds)(ref valueOrDefault)).center.z); } public static void Say(string text) { Message = text; MessageAt = Time.unscaledTime; ValheimTomrerPlugin.Log.LogInfo((object)("editor: " + text)); } public static void ClearMessage() { Message = null; } private static IEnumerable<ScenePiece> StandingPieces() { if (Document == null) { yield break; } bool moving = Mode == EditMode.Place && Action == PlaceAction.Move; foreach (DocPiece piece in Document.Pieces) { if (!moving || !MovingIds.Contains(piece.Id)) { yield return new ScenePiece { Id = piece.Id, Prefab = piece.PrefabName, Pos = piece.Position, Rot = piece.Rotation, Entry = PieceCatalog.Find(piece.PrefabName) }; } } } private static List<MovingPiece> MovingPieces(IList<DocPiece> pieces) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) List<MovingPiece> list = new List<MovingPiece>(pieces.Count); foreach (DocPiece piece in pieces) { list.Add(new MovingPiece { Id = piece.Id, Prefab = piece.PrefabName, Pos = piece.Position, Rot = piece.Rotation, Entry = PieceCatalog.Find(piece.PrefabName) }); } return list; } private static void Prune() { List<int> list = new List<int>(); foreach (int item in Selected) { if (Document.Find(item) == null) { list.Add(item); } } foreach (int item2 in list) { Selected.Remove(item2); } Version++; } private static float YawOf(Quaternion q) { //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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) Vector3 val = q * Vector3.forward; return Mathf.Atan2(val.x, val.z) * 57.29578f; } private static Quaternion Clean(Quaternion q) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return ((Quaternion)(ref q)).normalized; } private static Vector3 Abs(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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) return new Vector3(Mathf.Abs(v.x), Mathf.Abs(v.y), Mathf.Abs(v.z)); } private static string Count(int n) { if (n != 1) { return n + " pieces"; } return "1 piece"; } } internal static class WorldCapture { public const string Name = "Captured build"; public const float Reach = 50f; public const float DefaultSide = 8f; public const float MinSide = 2f; public const float MaxSide = 64f; public const float SideStep = 2f; public const float TurnStep = 22.5f; public const float Below = 8f; public const float Above = 64f; public const float EdgeReach = 4f; public const float BusyRefresh = 0.3f; public const float StillRefresh = 1f; private const float WheelScale = 0.15f; private const float WheelThreshold = 0.1f; private static readonly List<Piece> Around = new List<Piece>(); private static readonly List<Piece> Taken = new List<Piece>(); private static readonly List<Piece> Edge = new List<Piece>(); private static readonly List<Collider> Colliders = new List<Collider>(); private static CaptureBox _drawn; private static int _fallbackMask; private static bool _pinned; private static bool _moved; private static float _refreshedAt; private static float _wheel; private static float _wheelScale; private static int _escapeFrame = -1; private static Vector3 _shownShape; private static int _shownInside; private static int _shownLeft; public static bool Active { get; private set; } public static Vector3 Centre { get; private set; } public static float Yaw { get; private set; } public static float Width { get; private set; } = 8f; public static float Depth { get; private set; } = 8f; public static int InsideNow { get; private set; } public static int EdgeNow { get; private set; } public static int SkippedNow { get; private set; } public static int LastCount { get; private set; } public static int LastSkipped { get; private set; } public static string LastMessage { get; private set; } = ""; public static bool Drawn { get { if (_drawn != null) { return _drawn.Visible; } return false; } } public static bool TakesEscape { get { if (_escapeFrame != Time.frameCount) { if (Active) { return ZInput.GetKeyDown((KeyCode)27, true); } return false; } return true; } } public static void Tick() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) ConfigEntry<KeyCode> captureKey = EditorConfig.CaptureKey; Player localPlayer = Player.m_localPlayer; if (captureKey == null || (Object)(object)localPlayer == (Object)null) { Cancel(); return; } bool flag = Active && ZInput.GetKeyDown((KeyCode)27, true); if (flag || (Active && WorldPad.CancelCapture)) { if (flag) { _escapeFrame = Time.frameCount; } Cancel(); Say(localPlayer, "Capture off."); } else if (ZInput.GetKeyDown(captureKey.Value, true) || WorldPad.Capture) { Vector3 point; if (Active) { Capture(); } else if (!AimPoint(localPlayer, out point)) { Say(localPlayer, "Aim at the ground or at a piece, then press the key."); } else { Begin(point); } } else { if (!Active) { return; } if (!_pinned && AimPoint(localPlayer, out var point2)) { MoveCentre(point2); } bool num = Wheel() | PadShape(); Piece hoveringPiece = localPlayer.GetHoveringPiece(); if ((Object)(object)hoveringPiece != (Object)null) { CaptureTint.Hovered(((Component)hoveringPiece).gameObject); } if (num) { Refresh(); } else { float num2 = Time.unscaledTime - _refreshedAt; if ((_moved && num2 >= 0.3f) || num2 >= 1f) { Refresh(); } } ShowStatus(); } } public static void Begin(Vector3 centre) { //IL_0039: 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_0062: Unknown result type (might be due to invalid IL or missing references) _drawn = _drawn ?? new CaptureBox(); Active = true; _pinned = false; _wheel = 0f; _wheelScale = WheelScaleNow(); PieceCatalog.Ensure(); Centre = OnGround(centre); Refresh(); ShowStatus(); LastMessage = ""; ValheimTomrerPlugin.Log.LogInfo((object)$"capture: started at {Centre}"); } public static void Pin(Vector3 centre) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (Active) { _pinned = true; Centre = OnGround(centre); Refresh(); ShowStatus(); } } public static void ResetShape() { Yaw = 0f; Width = 8f; Depth = 8f; } public static void Cancel() { Active = false; _pinned = false; _drawn?.Hide(); CaptureTint.Clear(); CaptureHud.Hide(); } public static void Shutdown() { Cancel(); _drawn?.Destroy(); _drawn = null; CaptureHud.Destroy(); } public static bool Capture() { //IL_000f: 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_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) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return false; } Vector3 centre = Centre; Quaternion val = Quaternion.Euler(0f, Yaw, 0f); Cancel(); LastCount = 0; LastSkipped = 0; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return false; } PieceCatalog.Ensure(); Collect(Taken, null, out var skipped); LastSkipped = skipped; if (Taken.Count == 0) { Say(localPlayer, (skipped > 0) ? ("Nothing in the rectangle the hammer can build. " + Left(skipped)) : "Nothing in the rectangle."); return false; } Quaternion val2 = Quaternion.Inverse(val); List<DocPiece> list = new List<DocPiece>(Taken.Count); for (int i = 0; i < Taken.Count; i++) { Piece val3 = Taken[i]; list.Add(new DocPiece(i + 1, Utils.GetPrefabName(((Component)val3).gameObject), "", val2 * (((Component)val3).transform.position - centre), val2 * ((Component)val3).transform.rotation, null)); } Vector3 origin = EditorState.BottomCentre(list); List<NewPiece> list2 = (from p in list select new NewPiece { PrefabName = p.PrefabName, Position = p.Position - origin, Rotation = p.Rotation } into p orderby p.Position.y, p.Position.x, p.Position.z select p).ToList(); BlueprintDocument blueprintDocument = BlueprintDocument.New("Captured build"); blueprintDocument.AddPieces(list2); LastCount = list2.Count; ValheimTomrerPlugin.Log.LogInfo((object)($"capture: {LastCount} pieces, {skipped} skipped, centre {centre}, turned {Yaw:0.#}, " + $"{Width:0.#} x {Depth:0.#} m, origin {origin}")); string message = $"Captured {LastCount} pieces." + ((skipped > 0) ? (" " + Left(skipped)) : ""); LastMessage = message; EditorSession.OpenDocument(blueprintDocument, delegate { Dialogs.SaveAs("Captured build"); Toasts.Ok(message); }); if (!ModUi.Open) { Say(localPlayer, message); } return true; } public static void Collect(List<Piece> taken, List<Piece> edge, out int skipped) { //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) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_010f: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) skipped = 0; taken.Clear(); edge?.Clear(); Quaternion val = Quaternion.Inverse(Quaternion.Euler(0f, Yaw, 0f)); float num = Width * 0.5f; float num2 = Depth * 0.5f; float num3 = Centre.y - 8f; float num4 = Centre.y + 64f; float num5 = Mathf.Sqrt(num * num + num2 * num2 + 4096f) + 4f; Around.Clear(); Piece.GetAllPiecesInRadius(Centre, num5, Around); foreach (Piece item in Around) { if ((Object)(object)item == (Object)null || !item.IsPlacedByPlayer()) { continue; } Vector3 position = ((Component)item).transform.position; Vector3 val2 = val * (position - Centre); if (Mathf.Abs(val2.x) <= num && Mathf.Abs(val2.z) <= num2 && position.y >= num3 && position.y <= num4) { if (PieceCatalog.Find(Utils.GetPrefabName(((Component)item).gameObject)) == null) { skipped++; } else { taken.Add(item); } } else if (edge != null && Mathf.Abs(val2.x) <= num + 4f && Mathf.Abs(val2.z) <= num2 + 4f && ReachesIn(item, val, num, num2, num3, num4)) { edge.Add(item); } } taken.Sort((Piece a, Piece b) => ((Component)a).transform.position.y.CompareTo(((Component)b).transform.position.y)); } private static void Refresh() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) _refreshedAt = Time.unscaledTime; _moved = false; Collect(Taken, Edge, out var skipped); InsideNow = Taken.Count; EdgeNow = Edge.Count; SkippedNow = skipped; CaptureTint.Show(Taken, Edge); _drawn?.Show(Centre, Yaw, Width, Depth); } private static bool ReachesIn(Piece piece, Quaternion back, float halfWidth, float halfDepth, float low, float high) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00ac: 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) Colliders.Clear(); ((Component)piece).GetComponentsInChildren<Collider>(false, Colliders); Vector3 min = default(Vector3); Vector3 max = default(Vector3); foreach (Collider collider in Colliders) { if (!((Object)(object)collider == (Object)null) && collider.enabled && !collider.isTrigger) { ((Vector3)(ref min))..ctor(float.MaxValue, float.MaxValue, float.MaxValue); ((Vector3)(ref max))..ctor(float.MinValue, float.MinValue, float.MinValue); if (Corners(collider, back, ref min, ref max) && min.x <= halfWidth && max.x >= 0f - halfWidth && min.z <= halfDepth && max.z >= 0f - halfDepth && min.y <= high && max.y >= low) { return true; } } } return false; } private static bool Corners(Collider collider, Quaternion back, ref Vector3 min, ref Vector3 max) { //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_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_0058: 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_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_0072: 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) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)collider).transform; BoxCollider val2 = (BoxCollider)(object)((collider is BoxCollider) ? collider : null); Bounds bounds = default(Bounds); if (val2 == null) { MeshCollider val3 = (MeshCollider)(object)((collider is MeshCollider) ? collider : null); if (val3 != null && (Object)(object)val3.sharedMesh != (Object)null) { bounds = val3.sharedMesh.bounds; } else { bounds = collider.bounds; val = null; } } else { ((Bounds)(ref bounds))..ctor(val2.center, val2.size); } Vector3 extents = ((Bounds)(ref bounds)).extents; for (int i = 0; i < 8; i++) { Vector3 val4 = ((Bounds)(ref bounds)).center + new Vector3(((i & 1) == 0) ? (0f - extents.x) : extents.x, ((i & 2) == 0) ? (0f - extents.y) : extents.y, ((i & 4) == 0) ? (0f - extents.z) : extents.z); Vector3 val5 = (((Object)(object)val != (Object)null) ? val.TransformPoint(val4) : val4); Vector3 val6 = back * (val5 - Centre); val6.y = val5.y; min = Vector3.Min(min, val6); max = Vector3.Max(max, val6); } return true; } private static bool Wheel() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) Mouse current = Mouse.current; if (current == null) { return false; } _wheel += ((InputControl<Vector2>)(object)current.scroll).ReadValue().y * _wheelScale; int num; if (_wheel > 0.1f) { num = 1; } else { if (!(_wheel < -0.1f)) { return false; } num = -1; } _wheel = 0f; bool flag = ZInput.GetKey((KeyCode)304, false) || ZInput.GetKey((KeyCode)303, false); bool flag2 = ZInput.GetKey((KeyCode)308, false) || ZInput.GetKey((KeyCode)307, false); if (!flag && !flag2) { Yaw = Mathf.Repeat(Yaw + (float)num * 22.5f, 360f); return true; } if (flag) { Width = Side(Width + (float)num * 2f); } if (flag2) { Depth = Side(Depth + (float)num * 2f); } return true; } private static bool PadShape() { if (!WorldPad.Live) { return false; } bool modifierHeld = WorldPad.ModifierHeld; bool result = false; if (WorldPad.Pressed("JoyDPadLeft")) { Step(modifierHeld ? 0f : (-22.5f), modifierHeld ? (-2f) : 0f, 0f); result = true; } if (WorldPad.Pressed("JoyDPadRight")) { Step(modifierHeld ? 0f : 22.5f, modifierHeld ? 2f : 0f, 0f); result = true; } if (WorldPad.Pressed("JoyDPadUp")) { Step(0f, modifierHeld ? 0f : 2f, 2f); result = true; } if (WorldPad.Pressed("JoyDPadDown")) { Step(0f, modifierHeld ? 0f : (-2f), -2f); result = true; } return result; } private static void Step(float turn, float width, float depth) { Yaw = Mathf.Repeat(Yaw + turn, 360f); Width = Side(Width + width); Depth = Side(Depth + depth); } private static float Side(float side) { return Mathf.Clamp(side, 2f, 64f); } private static float WheelScaleNow() { try { return 0.15f * ZInput.GetScrollModifier(); } catch (Exception ex) { ValheimTomrerPlugin.Log.LogWarning((object)("capture: no wheel scale from the game, using 1: " + ex.Message)); return 0.15f; } } private static void MoveCentre(Vector3 point) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) Vector3 val = OnGround(point); Vector3 val2 = val - Centre; if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f) { Centre = val; _moved = true; _drawn?.Show(Centre, Yaw, Width, Depth); } } private static Vector3 OnGround(Vector3 point) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) ZoneSystem instance = ZoneSystem.instance; if ((Object)(object)instance != (Object)null) { point.y = instance.GetGroundHeight(point); } return point; } private static void ShowStatus() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0037: Unknown result type (might be due to invalid IL or missing references) if (!Active) { CaptureHud.Hide(); return; } int num = EdgeNow + SkippedNow; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Width, Depth, Yaw); if (!CaptureHud.Visible || !(val == _shownShape) || InsideNow != _shownInside || num != _shownLeft) { _shownShape = val; _shownInside = InsideNow; _shownLeft = num; CaptureHud.Show($"Capture {Width:0} x {Depth:0} m, turned {Yaw:0.#}°, {Pieces(InsideNow)}, {num} left out"); } } private static string Pieces(int count) { if (count != 1) { return $"{count} pieces"; } return "1 piece"; } private static bool AimPoint(Player player, out Vector3 point) { //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_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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) point = Vector3.zero; GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return false; } int num = ((player.m_placeRayMask != 0) ? player.m_placeRayMask : FallbackMask()); RaycastHit val = default(RaycastHit); if (!Physics.Raycast(((Component)instance).transform.position, ((Component)instance).transform.forward, ref val, 50f, num)) { return false; } if ((Object)(object)((RaycastHit)(ref val)).collider == (Object)null || (Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody != (Object)null) { return false; } point = ((RaycastHit)(ref val)).point; return true; } private static int FallbackMask() { if (_fallbackMask == 0) { _fallbackMask = LayerMask.GetMask(new string[7] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "vehicle" }); } return _fallbackMask; } private static string Left(int skipped) { if (skipped != 1) { return $"{skipped} pieces were left out: the hammer cannot build them."; } return "1 piece was left out: the hammer cannot build it."; } private static void Say(Player player, string text) { LastMessage = text; ValheimTomrerPlugin.Log.LogInfo((object)("capture: " + text)); if (player != null) { ((Character)player).Message((MessageType)2, text, 0, (Sprite)null, false); } } } } namespace ValheimTomrer.Editor.View { internal sealed class CaptureBox { public static readonly Color Colour = new Color(1f, 0.9f, 0.2f, 0.9f); public const float LineWidth = 0.05f; public const float Lift = 0.25f; private readonly List<Vector3> _points = new List<Vector3>(); private GameObject _object; private LineRenderer _line; private Material _material; private Vector3 _centre; private float _yaw; private float _width; private float _depth; public bool Visible { get { if ((Object)(object)_object != (Object)null) { return _object.activeSelf; } return false; } } public int PointCount { get { if (!((Object)(object)_line != (Object)null)) { return 0; } return _line.positionCount; } } public static int Segments(float side) { return Mathf.Clamp(Mathf.CeilToInt(side / 4f), 4, 64); } public void Show(Vector3 centre, float yaw, float width, float depth) { //IL_001d: 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_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_0075: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_00dd: 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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012d: 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) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) Build(); if ((Object)(object)_object == (Object)null || (Visible && centre == _centre && yaw == _yaw && width == _width && depth == _depth)) { return; } _centre = centre; _yaw = yaw; _width = width; _depth = depth; Quaternion val = Quaternion.Euler(0f, yaw, 0f); float num = width * 0.5f; float num2 = depth * 0.5f; Vector3[] array = (Vector3[])(object)new Vector3[4] { new Vector3(0f - num, 0f, 0f - num2), new Vector3(num, 0f, 0f - num2), new Vector3(num, 0f, num2), new Vector3(0f - num, 0f, num2) }; _points.Clear(); ZoneSystem instance = ZoneSystem.instance; for (int i = 0; i < 4; i++) { Vector3 val2 = array[i]; Vector3 val3 = array[(i + 1) % 4]; int num3 = Segments((i % 2 == 0) ? width : depth); for (int j = 0; j < num3; j++) { Vector3 val4 = centre + val * Vecto