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 Valheim Paintings v1.0.0
Valheim_Paintings.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; using Valheim_Paintings.Capture; using Valheim_Paintings.Components; using Valheim_Paintings.Prefabs; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Valheim_Paintings { public static class PaintingsConfig { public static ConfigEntry<bool> Enabled; public static ConfigEntry<KeyCode> CaptureKey; public static ConfigEntry<int> WoodCost; public static ConfigEntry<float> ScreenFraction; public static ConfigEntry<bool> ThirdsGrid; public static ConfigEntry<int> TextureSize; public static ConfigEntry<int> JpegQuality; public static ConfigEntry<int> MaxBytes; public static ConfigEntry<bool> ExportPng; public static ConfigEntry<bool> DropOnDamage; public static ConfigEntry<float> CanvasGap; public static ConfigEntry<bool> Diagnostics; public static ConfigEntry<string> ExportFolder; public static void Bind(ConfigFile config) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown Enabled = config.Bind<bool>("General", "Enabled", true, "Master switch. Turn off to disable the mod without uninstalling it."); CaptureKey = config.Bind<KeyCode>("General", "CaptureKey", (KeyCode)112, "Key that paints what the crosshair is looking at. Hold it to frame the picture: the game's interface goes away and only the capture rectangle stays, so you can walk, turn and change your camera distance until the view is right. The painting is taken when you let go. F11 is the game's own screenshot and F12 belongs to the Steam overlay, so neither is a good choice here."); WoodCost = config.Bind<int>("General", "WoodCost", 2, new ConfigDescription("Wood taken from the inventory for one painting.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), Array.Empty<object>())); ScreenFraction = config.Bind<float>("Capture", "ScreenFraction", 0.5f, new ConfigDescription("Side of the captured square, as a fraction of the screen's smaller side. 0.5 paints half the screen height, centred on the crosshair.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>())); ThirdsGrid = config.Bind<bool>("Capture", "ThirdsGrid", true, "Show the rule of thirds inside the framing rectangle while the capture key is held: two lines each way, cutting the frame into nine, whose four crossings are where a subject sits when it should not sit in the middle. Turn off for a bare frame."); TextureSize = config.Bind<int>("Capture", "TextureSize", 384, new ConfigDescription("Side of the texture carried by the painting, in pixels. Every painting travels with its image, so this is what a painting costs in the world save and on the wire.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(64, 1024), Array.Empty<object>())); JpegQuality = config.Bind<int>("Capture", "JpegQuality", 75, new ConfigDescription("JPEG quality of that texture. Lowered automatically when the result does not fit under MaxBytes.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(20, 100), Array.Empty<object>())); MaxBytes = config.Bind<int>("Capture", "MaxBytes", 32768, new ConfigDescription("Hard ceiling for one painting's encoded image.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(4096, 262144), Array.Empty<object>())); ExportPng = config.Bind<bool>("Export", "ExportPng", false, "Also write the capture to disk as a full resolution png. That copy is never read back by the mod and never deleted by it: it is only there for a player who wants to keep the picture."); DropOnDamage = config.Bind<bool>("General", "DropOnDamage", true, "A painting destroyed by damage falls to the ground with its image instead of being lost. A troll levelling your house should not erase a picture you cannot take again. Turn off for vanilla harshness."); CanvasGap = config.Bind<float>("Appearance", "CanvasGap", 0f, new ConfigDescription("How far the picture sits in front of the planks, in metres. Zero is the normal value: the painting's front face is cut off the panel and the picture takes its place, so there is no wood left in front of it to clear. Raise it only if wood still shows through the image. Read once when the piece is built, so a change needs a restart of the game.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.2f), Array.Empty<object>())); Diagnostics = config.Bind<bool>("Debug", "Diagnostics", false, "Log the geometry of every painting as it appears in the world: each of its meshes, whether it is showing, and how far it reaches in front of the panel. Turn it on to find out what a stray plank belongs to."); ExportFolder = config.Bind<string>("Export", "ExportFolder", "", "Absolute path for those png files. Leave empty to write under BepInEx/config/Valheim_Paintings/<world name>."); } } public static class PaintingsLocalization { public static void Register() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "vp_item_painting", "Painting" }, { "vp_item_painting_description", "A moment of your journey, painted on two planks." }, { "vp_piece_painting", "Painting" }, { "vp_piece_painting_description", "Hang a moment of your journey on the wall." }, { "vp_msg_painted", "Painting done" }, { "vp_msg_nowood", "Not enough wood to paint" }, { "vp_msg_noroom", "No room for the painting" }, { "vp_msg_failed", "The painting failed, see the log" } }); text = "French"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "vp_item_painting", "Tableau" }, { "vp_item_painting_description", "Un instant de ton voyage, peint sur deux planches." }, { "vp_piece_painting", "Tableau" }, { "vp_piece_painting_description", "Accroche au mur un instant de ton voyage." }, { "vp_msg_painted", "Tableau peint" }, { "vp_msg_nowood", "Pas assez de bois pour peindre" }, { "vp_msg_noroom", "Pas de place pour le tableau" }, { "vp_msg_failed", "Le tableau a rate, voir le journal" } }); } } [BepInPlugin("Tchernobill.Valheim_Paintings", "Valheim Paintings", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class PaintingsPlugin : BaseUnityPlugin { public const string GUID = "Tchernobill.Valheim_Paintings"; public const string NAME = "Valheim Paintings"; public const string VERSION = "1.0.0"; private static string s_woodName; public static ManualLogSource Log { get; private set; } private void Awake() { //IL_0046: 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) Log = ((BaseUnityPlugin)this).Logger; PaintingsConfig.Bind(((BaseUnityPlugin)this).Config); if (!PaintingsConfig.Enabled.Value) { Log.LogInfo((object)"Disabled by configuration, nothing is hooked."); return; } PaintingsLocalization.Register(); PaintingItem.Register(); PaintingPiece.Register(); new Harmony("Tchernobill.Valheim_Paintings").PatchAll(); Log.LogInfo((object)string.Format("{0} {1} ready, capture key is {2}.", "Valheim Paintings", "1.0.0", PaintingsConfig.CaptureKey.Value)); } private void Update() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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) if (!PaintingsConfig.Enabled.Value || ScreenGrabber.Busy || ZInput.instance == null) { return; } KeyCode value = PaintingsConfig.CaptureKey.Value; if (FramingOverlay.Visible) { Aim(value); } else if (ZInput.GetKeyDown(value, false)) { if (!ScreenGrabber.CanCapture(out var reason)) { Log.LogDebug((object)("Capture ignored: " + reason + ".")); } else if (!HasWood()) { Message("$vp_msg_nowood"); } else { FramingOverlay.Show(); } } } private void Aim(KeyCode key) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!ScreenGrabber.CanCapture(out var reason)) { FramingOverlay.Hide(); Log.LogDebug((object)("Framing cancelled: " + reason + ".")); } else if (!ZInput.GetKey(key, false)) { FramingOverlay.Hide(); if (!HasWood()) { Message("$vp_msg_nowood"); } else { ((MonoBehaviour)this).StartCoroutine(ScreenGrabber.Run(OnCaptured)); } } } private void OnGUI() { FramingOverlay.Draw(); } private void OnCaptured(PaintingCapture capture) { if (capture == null) { Message("$vp_msg_failed"); return; } string text = null; if (capture.Png != null) { text = PaintingStore.WritePng(capture.Id, capture.Png); } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { Inventory inventory = ((Humanoid)localPlayer).GetInventory(); ItemData val = inventory.AddItem("VP_painting", 1, 1, 0, localPlayer.GetPlayerID(), localPlayer.GetPlayerName(), false, false); if (val == null) { Message("$vp_msg_noroom"); return; } PaintingItem.SetImage(val, capture.Id, capture.Jpeg); PaintingStore.Put(capture.Id, capture.Texture); inventory.RemoveItem(WoodName(), PaintingsConfig.WoodCost.Value, -1, true); Log.LogInfo((object)($"Painted {capture.Id}: {capture.CropSize}px crop, " + $"{((Texture)capture.Texture).width}px texture, {(float)capture.Jpeg.Length / 1024f:0.0} KB jpeg " + $"at quality {capture.Quality}" + ((text != null) ? (", exported to " + text) : string.Empty))); Message("$vp_msg_painted"); } } private static bool HasWood() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { return ((Humanoid)localPlayer).GetInventory().CountItems(WoodName(), -1, true) >= PaintingsConfig.WoodCost.Value; } return false; } private static string WoodName() { if (!string.IsNullOrEmpty(s_woodName)) { return s_woodName; } GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("Wood") : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 != (Object)null) { s_woodName = val2.m_itemData.m_shared.m_name; } return s_woodName ?? "$item_wood"; } private static void Message(string text) { if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false); } } } } namespace Valheim_Paintings.Prefabs { public static class PaintingItem { public const string PrefabName = "VP_painting"; public const string NameToken = "$vp_item_painting"; public const string DescriptionToken = "$vp_item_painting_description"; public const string IdKey = "vp_id"; public const string ImageKey = "vp_img"; public const string ModelName = "vp_model"; private const float ModelScale = 0.5f; private static GameObject s_prefab; public static string SharedName => "$vp_item_painting"; public static void Register() { PrefabManager.OnVanillaPrefabsAvailable += Create; } private static void Create() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) PrefabManager.OnVanillaPrefabsAvailable -= Create; CustomItem val = new CustomItem("VP_painting", "Wood"); SharedData shared = val.ItemDrop.m_itemData.m_shared; shared.m_name = "$vp_item_painting"; shared.m_description = "$vp_item_painting_description"; shared.m_itemType = (ItemType)16; shared.m_maxStackSize = 1; shared.m_weight = 2f; shared.m_teleportable = true; shared.m_questItem = false; if ((Object)(object)PaintingIcons.Fallback != (Object)null) { shared.m_icons = (Sprite[])(object)new Sprite[1] { PaintingIcons.Fallback }; } s_prefab = val.ItemPrefab; ItemManager.Instance.AddItem(val); PaintingsPlugin.Log.LogInfo((object)"Item VP_painting registered."); } public static void Shape(GameObject piece) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Expected O, but got Unknown //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_prefab == (Object)null) { return; } Transform val = piece.transform.Find("Pivot/New/_Combined Mesh [high]"); Transform val2 = piece.transform.Find("vp_canvas"); Transform val3 = piece.transform.Find("vp_backing"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { PaintingsPlugin.Log.LogWarning((object)"Painting piece incomplete, the item keeps the wood model."); return; } List<GameObject> list = new List<GameObject>(); foreach (Transform item in s_prefab.transform) { Transform val4 = item; if ((Object)(object)((Component)val4).GetComponent<Renderer>() != (Object)null || (Object)(object)((Component)val4).GetComponent<Collider>() != (Object)null) { list.Add(((Component)val4).gameObject); } } foreach (GameObject item2 in list) { Object.DestroyImmediate((Object)(object)item2); } GameObject val5 = new GameObject("vp_model"); val5.transform.SetParent(s_prefab.transform, false); val5.transform.localRotation = Quaternion.Euler(-90f, 0f, 0f); val5.transform.localScale = Vector3.one * 0.5f; Bounds panel = PaintingPiece.Panel; GameObject val6 = new GameObject("Frame"); val6.transform.SetParent(val5.transform, false); val6.transform.localPosition = -((Bounds)(ref panel)).center; List<Renderer> list2 = new List<Renderer> { Copy(piece.transform, val, val6.transform), Copy(piece.transform, val2, val6.transform), Copy(piece.transform, val3, val6.transform) }; list2.RemoveAll((Renderer renderer) => (Object)(object)renderer == (Object)null); BoxCollider obj = val6.AddComponent<BoxCollider>(); obj.center = ((Bounds)(ref panel)).center; obj.size = ((Bounds)(ref panel)).size; LODGroup component = s_prefab.GetComponent<LODGroup>(); if ((Object)(object)component != (Object)null) { LOD[] lODs = component.GetLODs(); for (int num = 0; num < lODs.Length; num++) { List<Renderer> list3 = new List<Renderer>(list2); Renderer[] renderers = lODs[num].renderers; foreach (Renderer val7 in renderers) { if ((Object)(object)val7 != (Object)null) { list3.Add(val7); } } lODs[num].renderers = list3.ToArray(); } component.SetLODs(lODs); component.RecalculateBounds(); } s_prefab.AddComponent<PaintingDrop>(); PaintingsPlugin.Log.LogInfo((object)string.Format("Item {0} shaped as a {1:0.00} m painting.", "VP_painting", ((Bounds)(ref panel)).size.x * 0.5f)); } private static Renderer Copy(Transform root, Transform source, Transform destination) { //IL_004d: 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_005f: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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) List<Transform> list = new List<Transform>(); Transform val = source; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root) { list.Insert(0, val); val = val.parent; } Transform val2 = destination; foreach (Transform item in list) { GameObject val3 = new GameObject(((Object)item).name); val3.transform.SetParent(val2, false); val3.transform.localPosition = item.localPosition; val3.transform.localRotation = item.localRotation; val3.transform.localScale = item.localScale; val2 = val3.transform; } MeshFilter component = ((Component)source).GetComponent<MeshFilter>(); Renderer component2 = ((Component)source).GetComponent<Renderer>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { return null; } ((Component)val2).gameObject.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh; MeshRenderer obj = ((Component)val2).gameObject.AddComponent<MeshRenderer>(); ((Renderer)obj).sharedMaterials = component2.sharedMaterials; ((Renderer)obj).shadowCastingMode = component2.shadowCastingMode; return (Renderer)(object)obj; } public static void SetImage(ItemData item, string id, byte[] jpeg) { item.m_customData["vp_id"] = id; item.m_customData["vp_img"] = ImageCodec.ToBase64(jpeg); } public static string GetId(ItemData item) { if (item == null || item.m_shared.m_name != "$vp_item_painting") { return null; } if (!item.m_customData.TryGetValue("vp_id", out var value)) { return null; } return value; } public static byte[] GetImage(ItemData item) { if (item == null || !item.m_customData.TryGetValue("vp_img", out var value)) { return null; } return ImageCodec.FromBase64(value); } } public static class PaintingPiece { public const string PrefabName = "VP_painting_piece"; public const string NameToken = "$vp_piece_painting"; public const string DescriptionToken = "$vp_piece_painting_description"; public const string CanvasName = "vp_canvas"; public const string BackingName = "vp_backing"; private const string SnapTag = "snappoint"; public const string CombinedMesh = "_Combined Mesh [high]"; public const string PanelPath = "Pivot/New/_Combined Mesh [high]"; private const string TrimmedSuffix = "_vp_trimmed"; private static readonly string[] States = new string[3] { "New", "Worn", "Broken" }; private static readonly string[] VertexNoise = new string[3] { "_ValueNoise", "_ValueNoiseVertex", "_RippleDistance" }; private const float ChamferDepth = 0.0021f; private const float FallbackGap = 0.03f; private const float FallbackBack = -0.042f; private const float BackingDepth = 0.001f; private const float Clearance = 0.002f; private const float ThicknessScale = 0.3f; private static Piece s_piece; private static float CanvasGap => PaintingsConfig.CanvasGap.Value; public static Material CanvasTemplate { get; private set; } public static Material WoodTemplate { get; private set; } public static Bounds Panel { get; private set; } public static void Register() { PrefabManager.OnVanillaPrefabsAvailable += Create; } private static void Create() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0085: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= Create; PieceConfig val = new PieceConfig(); val.Name = "$vp_piece_painting"; val.Description = "$vp_piece_painting_description"; val.PieceTable = PieceTables.Hammer; val.Category = PieceCategories.Furniture; val.Icon = PaintingIcons.Fallback; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[1] { new RequirementConfig { Item = "VP_painting", Amount = 1, Recover = false } }; PieceConfig val2 = val; CustomPiece val3 = new CustomPiece("VP_painting_piece", "wood_floor", val2); if ((Object)(object)val3.PiecePrefab == (Object)null) { PaintingsPlugin.Log.LogError((object)"Could not clone wood_floor, no painting piece."); return; } bool trimmed = Reshape(val3.PiecePrefab); Stand(val3.PiecePrefab, trimmed); Tune(val3.Piece, val3.PiecePrefab.GetComponent<WearNTear>()); val3.PiecePrefab.AddComponent<PaintingCanvas>(); s_piece = val3.Piece; PieceManager.Instance.AddPiece(val3); PaintingsPlugin.Log.LogInfo((object)"Piece VP_painting_piece registered."); PaintingItem.Shape(val3.PiecePrefab); } public static void RefreshIcon() { if (!((Object)(object)s_piece == (Object)null)) { Sprite val = PaintingIcons.ForItem(PaintingSelection.Current); if ((Object)(object)val != (Object)null) { s_piece.m_icon = val; } } } private static bool Reshape(GameObject prefab) { MeshFilter val = StateMesh(prefab.transform, "New"); if ((Object)(object)val == (Object)null || (Object)(object)val.sharedMesh == (Object)null) { PaintingsPlugin.Log.LogWarning((object)"No combined mesh on the cloned floor, its front face is left alone."); return false; } float num = Top(prefab.transform, val) - 0.0021f; bool result = false; string[] states = States; foreach (string text in states) { MeshFilter val2 = StateMesh(prefab.transform, text); if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.sharedMesh == (Object)null)) { int num2 = val2.sharedMesh.triangles.Length / 3; float num3 = Top(prefab.transform, val2); Mesh val3 = Trim(prefab.transform, val2, num, keepBelow: true); if (!((Object)(object)val3 == (Object)null)) { val2.sharedMesh = val3; result = true; PaintingsPlugin.Log.LogInfo((object)($" {text}: {num2} triangles cut down to {val3.triangles.Length / 3}, " + $"front from {num3 * 1000f:0.0} mm to {Top(prefab.transform, val2) * 1000f:0.0} mm.")); } } } PaintingsPlugin.Log.LogInfo((object)$"Front face removed at {num * 1000f:0.0} mm."); return result; } private static string Trimmed(string name) { if (!name.EndsWith("_vp_trimmed")) { return name + "_vp_trimmed"; } return name; } private static MeshFilter StateMesh(Transform root, string state) { Transform val = root.Find(state + "/_Combined Mesh [high]"); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).GetComponent<MeshFilter>(); } private static Matrix4x4 Relative(Transform root, Transform node) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_000b: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) Matrix4x4 val = Matrix4x4.identity; Transform val2 = node; while ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)root) { val = Matrix4x4.TRS(val2.localPosition, val2.localRotation, val2.localScale) * val; val2 = val2.parent; } return val; } private static float Top(Transform root, MeshFilter filter) { //IL_0007: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) Matrix4x4 val = Relative(root, ((Component)filter).transform); float num = float.NegativeInfinity; Vector3[] vertices = filter.sharedMesh.vertices; foreach (Vector3 val2 in vertices) { float y = ((Matrix4x4)(ref val)).MultiplyPoint3x4(val2).y; if (y > num) { num = y; } } return num; } private static Mesh Trim(Transform root, MeshFilter filter, float cut, bool keepBelow) { //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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Expected O, but got Unknown //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) Mesh sharedMesh = filter.sharedMesh; Vector3[] vertices = sharedMesh.vertices; int[] triangles = sharedMesh.triangles; if (vertices.Length == 0 || triangles.Length == 0) { PaintingsPlugin.Log.LogWarning((object)("Mesh " + ((Object)sharedMesh).name + " reads back empty, left alone.")); return null; } Vector3[] normals = sharedMesh.normals; Vector2[] uv = sharedMesh.uv; Vector4[] tangents = sharedMesh.tangents; bool flag = normals != null && normals.Length == vertices.Length; bool flag2 = uv != null && uv.Length == vertices.Length; bool flag3 = tangents != null && tangents.Length == vertices.Length; Matrix4x4 val = Relative(root, ((Component)filter).transform); float num = (keepBelow ? 1f : (-1f)); float[] array = new float[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { array[i] = (((Matrix4x4)(ref val)).MultiplyPoint3x4(vertices[i]).y - cut) * num; } List<Vector3> list = new List<Vector3>(vertices.Length * 2); List<Vector3> list2 = (flag ? new List<Vector3>(vertices.Length * 2) : null); List<Vector2> list3 = (flag2 ? new List<Vector2>(vertices.Length * 2) : null); List<Vector4> list4 = (flag3 ? new List<Vector4>(vertices.Length * 2) : null); List<int> list5 = new List<int>(triangles.Length * 2); Vector3[] array2 = (Vector3[])(object)new Vector3[8]; Vector3[] array3 = (Vector3[])(object)new Vector3[8]; Vector2[] array4 = (Vector2[])(object)new Vector2[8]; Vector4[] array5 = (Vector4[])(object)new Vector4[8]; for (int j = 0; j + 2 < triangles.Length; j += 3) { int num2 = 0; Vector3 val2; for (int k = 0; k < 3; k++) { int num3 = triangles[j + k]; int num4 = triangles[j + (k + 1) % 3]; float num5 = array[num3]; float num6 = array[num4]; if (num5 <= 0f && num2 < 8) { array2[num2] = vertices[num3]; if (flag) { array3[num2] = normals[num3]; } if (flag2) { array4[num2] = uv[num3]; } if (flag3) { array5[num2] = tangents[num3]; } num2++; } if (num2 < 8 && num5 <= 0f != num6 <= 0f) { float num7 = num5 / (num5 - num6); array2[num2] = Vector3.LerpUnclamped(vertices[num3], vertices[num4], num7); if (flag) { int num8 = num2; val2 = Vector3.LerpUnclamped(normals[num3], normals[num4], num7); array3[num8] = ((Vector3)(ref val2)).normalized; } if (flag2) { array4[num2] = Vector2.LerpUnclamped(uv[num3], uv[num4], num7); } if (flag3) { Vector4 val3 = Vector4.LerpUnclamped(tangents[num3], tangents[num4], num7); val3.w = tangents[num3].w; array5[num2] = val3; } num2++; } } for (int l = 1; l + 1 < num2; l++) { Vector3 val4 = array2[0]; Vector3 val5 = array2[l]; Vector3 val6 = array2[l + 1]; val2 = Vector3.Cross(val5 - val4, val6 - val4); if (!(((Vector3)(ref val2)).sqrMagnitude < 1E-16f)) { int count = list.Count; list.Add(val4); list.Add(val5); list.Add(val6); if (list2 != null) { list2.Add(array3[0]); list2.Add(array3[l]); list2.Add(array3[l + 1]); } if (list3 != null) { list3.Add(array4[0]); list3.Add(array4[l]); list3.Add(array4[l + 1]); } if (list4 != null) { list4.Add(array5[0]); list4.Add(array5[l]); list4.Add(array5[l + 1]); } list5.Add(count); list5.Add(count + 1); list5.Add(count + 2); } } } if (list5.Count == 0) { PaintingsPlugin.Log.LogWarning((object)("Cutting " + ((Object)sharedMesh).name + " left nothing, left alone.")); return null; } Mesh val7 = new Mesh { name = Trimmed(((Object)sharedMesh).name) }; val7.SetVertices(list); if (list2 != null) { val7.SetNormals(list2); } if (list3 != null) { val7.SetUVs(0, list3); } if (list4 != null) { val7.SetTangents(list4); } val7.SetTriangles(list5, 0); val7.RecalculateBounds(); if (list4 == null && list2 != null && list3 != null) { val7.RecalculateTangents(); } return val7; } private static void Stand(GameObject prefab, bool trimmed) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_00c2: 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_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Pivot"); val.transform.SetParent(prefab.transform, false); List<Transform> list = new List<Transform>(); foreach (Transform item in prefab.transform) { Transform val2 = item; if ((Object)(object)val2 != (Object)(object)val.transform) { list.Add(val2); } } foreach (Transform item2 in list) { item2.SetParent(val.transform, false); } val.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); val.transform.localScale = new Vector3(1f, 0.3f, 1f); Silence(val.transform, "WET"); Flatten(val.transform); float num = CanvasGap + (trimmed ? 0f : 0.03f); if (!trimmed) { PaintingsPlugin.Log.LogWarning((object)$"Front face still in place, the canvas falls back to a {num:0.000} m gap."); } WoodTemplate = WoodMaterial(val.transform); CanvasTemplate = CanvasMaterial(); if (!Measure(prefab, out var bounds)) { PaintingsPlugin.Log.LogWarning((object)"Could not measure the cloned floor, using 2x2 defaults."); val.transform.localPosition = new Vector3(0f, 1f, 0f); float num2 = 0.024f + num + 0.002f; AddCanvas(prefab, new Vector2(0f, 1f), 2f, 2f, num2, num2 - 0.001f); Panel = Slab(new Vector2(0f, 1f), 2f, 2f, -0.042f, num2); AddSnapPoints(prefab, -1f, 1f, 0f, 2f, -0.042f); return; } float x = ((Bounds)(ref bounds)).size.x; float y = ((Bounds)(ref bounds)).size.y; float num3 = y * 0.5f - ((Bounds)(ref bounds)).center.y; val.transform.localPosition = new Vector3(0f, num3, 0f); Vector2 centre = default(Vector2); ((Vector2)(ref centre))..ctor(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).center.y + num3); float num4 = ((Bounds)(ref bounds)).max.z + num + 0.002f; float back = num4 - 0.001f; PaintingsPlugin.Log.LogInfo((object)($"Panel {x:0.000} x {y:0.000} m, {((Bounds)(ref bounds)).size.z:0.000} m thick, " + $"canvas at z {num4:0.000}.")); AddCanvas(prefab, centre, x, y, num4, back); Panel = Slab(centre, x, y, ((Bounds)(ref bounds)).min.z, num4); AddSnapPoints(prefab, ((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).max.x, ((Bounds)(ref bounds)).min.y + num3, ((Bounds)(ref bounds)).max.y + num3, ((Bounds)(ref bounds)).min.z); LODGroup component = prefab.GetComponent<LODGroup>(); if (component != null) { component.RecalculateBounds(); } } private static Bounds Slab(Vector2 centre, float width, float height, float back, float front) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) return new Bounds(new Vector3(centre.x, centre.y, (back + front) * 0.5f), new Vector3(width, height, front - back)); } private static void Flatten(Transform pivot) { Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>(); int num = 0; Renderer[] componentsInChildren = ((Component)pivot).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { Material[] sharedMaterials = val.sharedMaterials; bool flag = false; for (int j = 0; j < sharedMaterials.Length; j++) { Material val2 = sharedMaterials[j]; if (!((Object)(object)val2 == (Object)null)) { if (!dictionary.TryGetValue(val2, out var value)) { value = (dictionary[val2] = Still(val2)); } if ((Object)(object)value != (Object)(object)val2) { sharedMaterials[j] = value; flag = true; } } } if (flag) { val.sharedMaterials = sharedMaterials; num++; } } PaintingsPlugin.Log.LogInfo((object)$"Vertex noise stilled on {num} renderers, {dictionary.Count} materials seen."); } private static Material Still(Material source) { //IL_003e: 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_005a: Expected O, but got Unknown bool flag = false; string[] vertexNoise = VertexNoise; foreach (string text in vertexNoise) { if (source.HasProperty(text) && source.GetFloat(text) != 0f) { flag = true; break; } } if (!flag) { return source; } Material val = new Material(source) { name = ((Object)source).name + "_vp_still" }; vertexNoise = VertexNoise; foreach (string text2 in vertexNoise) { if (val.HasProperty(text2)) { val.SetFloat(text2, 0f); } } return val; } private static void Silence(Transform parent, string child) { Transform val = parent.Find(child); if (!((Object)(object)val == (Object)null)) { ParticleSystemRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<ParticleSystemRenderer>(true); foreach (ParticleSystemRenderer obj in componentsInChildren) { ((Renderer)obj).enabled = false; Object.DestroyImmediate((Object)(object)obj); } ParticleSystem[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } ((Component)val).gameObject.SetActive(false); } } private static bool Measure(GameObject prefab, out Bounds bounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_0094: 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_0083: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); Transform transform = prefab.transform; Transform val = transform.Find("Pivot/New/_Combined Mesh [high]"); MeshFilter val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<MeshFilter>() : null); if ((Object)(object)val2 == (Object)null || (Object)(object)val2.sharedMesh == (Object)null) { return false; } Matrix4x4 val3 = Relative(transform, ((Component)val2).transform); bool flag = false; Vector3[] vertices = val2.sharedMesh.vertices; foreach (Vector3 val4 in vertices) { Vector3 val5 = ((Matrix4x4)(ref val3)).MultiplyPoint3x4(val4); if (flag) { ((Bounds)(ref bounds)).Encapsulate(val5); continue; } bounds = new Bounds(val5, Vector3.zero); flag = true; } return flag; } private static void AddCanvas(GameObject prefab, Vector2 centre, float width, float height, float front, float back) { //IL_0006: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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) MeshRenderer val = AddQuad(prefab, "vp_canvas", new Vector3(centre.x, centre.y, front), width, height, forward: true, WoodTemplate); ((Renderer)val).shadowCastingMode = (ShadowCastingMode)0; MeshRenderer val2 = AddQuad(prefab, "vp_backing", new Vector3(centre.x, centre.y, back), width, height, forward: false, WoodTemplate); ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; Attach(prefab, (Renderer)val, (Renderer)val2); } private static MeshRenderer AddQuad(GameObject prefab, string name, Vector3 position, float width, float height, bool forward, Material material) { //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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(prefab.transform, false); val.transform.localPosition = position; val.transform.localRotation = Quaternion.identity; val.AddComponent<MeshFilter>().sharedMesh = QuadMesh(name, width, height, forward); MeshRenderer obj = val.AddComponent<MeshRenderer>(); ((Renderer)obj).sharedMaterial = material; return obj; } private static void AddSnapPoints(GameObject prefab, float minX, float maxX, float bottom, float top, float back) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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) AddSnapPoint(prefab, "$hud_snappoint_bottom 1", new Vector3(maxX, bottom, back)); AddSnapPoint(prefab, "$hud_snappoint_bottom 2", new Vector3(minX, bottom, back)); AddSnapPoint(prefab, "$hud_snappoint_top 1", new Vector3(maxX, top, back)); AddSnapPoint(prefab, "$hud_snappoint_top 2", new Vector3(minX, top, back)); PaintingsPlugin.Log.LogInfo((object)($"Four snap points on the back plane at {back * 1000f:0.0} mm, " + $"x from {minX:0.000} to {maxX:0.000} m, y from {bottom:0.000} to {top:0.000} m.")); } private static void AddSnapPoint(GameObject prefab, string name, Vector3 position) { //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name) { tag = "snappoint" }; val.transform.SetParent(prefab.transform, false); val.transform.localPosition = position; } private static void Attach(GameObject prefab, params Renderer[] extra) { LODGroup component = prefab.GetComponent<LODGroup>(); if (!((Object)(object)component == (Object)null)) { LOD[] lODs = component.GetLODs(); if (lODs.Length != 0) { List<Renderer> list = new List<Renderer>(lODs[0].renderers); list.AddRange(extra); lODs[0].renderers = list.ToArray(); component.SetLODs(lODs); component.RecalculateBounds(); } } } private static Mesh QuadMesh(string name, float width, float height, bool forward) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00cf: 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_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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0167: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) float num = width * 0.5f; float num2 = height * 0.5f; Vector3 val = (forward ? Vector3.forward : Vector3.back); Mesh val2 = new Mesh(); ((Object)val2).name = name; val2.vertices = (Vector3[])(object)new Vector3[4] { new Vector3(0f - num, 0f - num2, 0f), new Vector3(num, 0f - num2, 0f), new Vector3(num, num2, 0f), new Vector3(0f - num, num2, 0f) }; val2.uv = (Vector2[])(object)((!forward) ? new Vector2[4] { new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(0f, 1f) } : new Vector2[4] { new Vector2(1f, 0f), new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(1f, 1f) }); val2.normals = (Vector3[])(object)new Vector3[4] { val, val, val, val }; Mesh val3 = val2; val3.triangles = ((!forward) ? new int[6] { 0, 2, 1, 0, 3, 2 } : new int[6] { 0, 1, 2, 0, 2, 3 }); val3.RecalculateBounds(); val3.RecalculateTangents(); return val3; } private static Material CanvasMaterial() { //IL_004a: 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_005b: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_009f: 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_00b0: Expected O, but got Unknown string[] array = new string[2] { "Legacy Shaders/Diffuse", "Unlit/Texture" }; foreach (string text in array) { Shader val = Shader.Find(text); if ((Object)(object)val != (Object)null) { PaintingsPlugin.Log.LogInfo((object)("Canvas shader: " + text + ".")); return new Material(val) { name = "vp_canvas" }; } } if ((Object)(object)WoodTemplate != (Object)null) { PaintingsPlugin.Log.LogInfo((object)("Canvas shader falls back to the planks: " + ((Object)WoodTemplate.shader).name + ".")); return new Material(WoodTemplate) { name = "vp_canvas" }; } PaintingsPlugin.Log.LogError((object)"No shader for the canvas, it will render pink."); return new Material(Shader.Find("Standard")) { name = "vp_canvas" }; } private static Material WoodMaterial(Transform pivot) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown MeshFilter val = StateMesh(pivot, "New"); MeshRenderer val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<MeshRenderer>() : null); if ((Object)(object)val2 == (Object)null || (Object)(object)((Renderer)val2).sharedMaterial == (Object)null) { val2 = ((Component)pivot).GetComponentInChildren<MeshRenderer>(true); } if ((Object)(object)val2 == (Object)null || (Object)(object)((Renderer)val2).sharedMaterial == (Object)null) { PaintingsPlugin.Log.LogWarning((object)"No plank material, an empty painting will render pink."); return new Material(Shader.Find("Standard")) { name = "vp_backing" }; } Material val3 = new Material(((Renderer)val2).sharedMaterial) { name = "vp_backing" }; val3.SetTextureScale("_MainTex", new Vector2(4f, 1f)); val3.SetTextureOffset("_MainTex", Vector2.zero); return val3; } private static void Tune(Piece piece, WearNTear wear) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)piece != (Object)null) { piece.m_name = "$vp_piece_painting"; piece.m_description = "$vp_piece_painting_description"; piece.m_comfort = 1; piece.m_canRotate = true; piece.m_groundPiece = false; piece.m_groundOnly = false; piece.m_clipGround = false; piece.m_allowedInDungeons = true; } if ((Object)(object)wear != (Object)null) { wear.m_supports = false; wear.m_noSupportWear = true; wear.m_noRoofWear = true; wear.m_materialType = (MaterialType)0; } } } } namespace Valheim_Paintings.Patches { [HarmonyPatch(typeof(Player), "ConsumeResources")] public static class Patch_Player_ConsumeResources { private static bool Prefix(Player __instance, Requirement[] requirements) { if (!PaintingSelection.IsPaintingCost(requirements)) { return true; } PaintingSelection.Consume(__instance); return false; } } [HarmonyPatch(typeof(Piece), "DropResources")] public static class Patch_Piece_DropResources { private static void Postfix(Piece __instance, HitData hitData) { PaintingCanvas component = ((Component)__instance).GetComponent<PaintingCanvas>(); if (!((Object)(object)component == (Object)null) && (hitData == null || PaintingsConfig.DropOnDamage.Value)) { component.DropPainting(); } } } [HarmonyPatch(typeof(ItemData), "GetIcon")] public static class Patch_ItemData_GetIcon { private static void Postfix(ItemData __instance, ref Sprite __result) { if (!(__instance.m_shared.m_name != "$vp_item_painting")) { Sprite val = PaintingIcons.ForItem(__instance); if ((Object)(object)val != (Object)null) { __result = val; } } } } [HarmonyPatch(typeof(Hud), "UpdateBuild")] public static class Patch_Hud_UpdateBuild { private static void Prefix(Player player) { if ((Object)(object)player != (Object)null && ((Character)player).InPlaceMode()) { PaintingPiece.RefreshIcon(); } } } } namespace Valheim_Paintings.Components { public class PaintingCanvas : MonoBehaviour, IPlaced { public const string IdKey = "vp_id"; public const string ImageKey = "vp_img"; private Renderer m_canvas; private ZNetView m_nview; private string m_shown; private bool m_dressed; public bool IsGhost { get { if (!((Object)(object)m_nview == (Object)null)) { return m_nview.GetZDO() == null; } return true; } } private void Awake() { m_nview = ((Component)this).GetComponent<ZNetView>(); Transform val = ((Component)this).transform.Find("vp_canvas"); m_canvas = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Renderer>() : null); if ((Object)(object)m_canvas == (Object)null) { PaintingsPlugin.Log.LogWarning((object)"Painting without a canvas renderer."); return; } if (IsGhost) { ShowItem(PaintingSelection.Current); } else { ShowFromZDO(); ((MonoBehaviour)this).InvokeRepeating("ShowFromZDO", 2f, 2f); } if (PaintingsConfig.Diagnostics.Value) { LogGeometry(); ((MonoBehaviour)this).Invoke("LogNeighbours", 0.5f); } } private void Update() { if (IsGhost && (Object)(object)m_canvas != (Object)null) { ShowItem(PaintingSelection.Current); } } public void OnPlaced() { ItemData current = PaintingSelection.Current; string id = PaintingItem.GetId(current); byte[] image = PaintingItem.GetImage(current); if (id == null || image == null) { PaintingsPlugin.Log.LogWarning((object)"A painting was placed without an image."); return; } if ((Object)(object)m_nview != (Object)null && m_nview.IsValid()) { ZDO zDO = m_nview.GetZDO(); zDO.Set("vp_id", id); zDO.Set("vp_img", image); } PaintingStore.Get(id, image); Show(id, image); } public void DropPainting() { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_00e7: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid()) { ZDO zDO = m_nview.GetZDO(); string text = zDO.GetString("vp_id", ""); byte[] byteArray = zDO.GetByteArray("vp_img", (byte[])null); GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("VP_painting") : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if (!((Object)(object)val2 == (Object)null) && !string.IsNullOrEmpty(text) && byteArray != null) { ItemData obj = val2.m_itemData.Clone(); obj.m_dropPrefab = val; obj.m_stack = 1; PaintingItem.SetImage(obj, text, byteArray); ItemDrop.DropItem(obj, 1, ((Component)this).transform.TransformPoint(new Vector3(0f, 0.3f, 0.8f)), Quaternion.Euler(0f, ((Component)this).transform.eulerAngles.y, 0f)); } } } private void ShowFromZDO() { if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid()) { ZDO zDO = m_nview.GetZDO(); string text = zDO.GetString("vp_id", ""); if (!string.IsNullOrEmpty(text) && !(text == m_shown)) { Show(text, zDO.GetByteArray("vp_img", (byte[])null)); } } } private void ShowItem(ItemData item) { string id = PaintingItem.GetId(item); if (id != null && !(id == m_shown)) { Show(id, PaintingItem.GetImage(item)); } } private void Show(string id, byte[] jpeg) { Texture2D val = PaintingStore.Get(id, jpeg); if (!((Object)(object)val == (Object)null)) { if (!m_dressed && (Object)(object)PaintingPiece.CanvasTemplate != (Object)null) { m_canvas.sharedMaterial = PaintingPiece.CanvasTemplate; m_dressed = true; } m_canvas.material.mainTexture = (Texture)(object)val; m_shown = id; } } private void LogGeometry() { //IL_000b: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) float z = ((Component)m_canvas).transform.localPosition.z; PaintingsPlugin.Log.LogInfo((object)$"Painting at {((Component)this).transform.position}, canvas at z {z:0.000}:"); MeshFilter[] componentsInChildren = ((Component)this).GetComponentsInChildren<MeshFilter>(true); Vector3 val2 = default(Vector3); foreach (MeshFilter val in componentsInChildren) { Mesh sharedMesh = val.sharedMesh; if (!((Object)(object)sharedMesh == (Object)null) && !((Object)(object)((Component)val).transform == (Object)(object)((Component)m_canvas).transform)) { float num = float.NegativeInfinity; Bounds bounds = sharedMesh.bounds; for (int j = 0; j < 8; j++) { ((Vector3)(ref val2))..ctor(((j & 1) == 0) ? (-1f) : 1f, ((j & 2) == 0) ? (-1f) : 1f, ((j & 4) == 0) ? (-1f) : 1f); Vector3 val3 = ((Component)this).transform.InverseTransformPoint(((Component)val).transform.TransformPoint(((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, val2))); num = Mathf.Max(num, val3.z); } string text = ((Object)val).name; Transform parent = ((Component)val).transform.parent; while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)((Component)this).transform) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } PaintingsPlugin.Log.LogInfo((object)(" " + (((Component)val).gameObject.activeInHierarchy ? "shown " : "hidden") + " " + string.Format("front z {0:0.000}, {1}", num, (num - z > 0f) ? ("THROUGH by " + (num - z).ToString("0.000")) : "behind") + " " + text)); } } } private void LogNeighbours() { //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_003e: 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) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) if (IsGhost) { return; } Vector3 val = ((Component)this).transform.TransformPoint(new Vector3(0f, 1f, 0.05f)); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(1.05f, 1.05f, 0.1f); Collider[] array = Physics.OverlapBox(val, val2, ((Component)this).transform.rotation, -1, (QueryTriggerInteraction)1); int num = 0; Collider[] array2 = array; foreach (Collider val3 in array2) { if (!((Component)val3).transform.IsChildOf(((Component)this).transform)) { num++; Transform val4 = ((Component)val3).transform; while ((Object)(object)val4.parent != (Object)null) { val4 = val4.parent; } PaintingsPlugin.Log.LogInfo((object)$" inside the panel: {((Object)val4).name} at {val4.position}, collider {((Object)val3).name}"); } } if (num == 0) { PaintingsPlugin.Log.LogInfo((object)" nothing else inside the panel."); } } } public class PaintingDrop : MonoBehaviour { private ItemDrop m_drop; private Renderer m_canvas; private string m_shown; private Material m_material; private void Awake() { m_drop = ((Component)this).GetComponent<ItemDrop>(); Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (((Object)val).name == "vp_canvas") { m_canvas = val; break; } } } private void Update() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown if ((Object)(object)m_drop == (Object)null || (Object)(object)m_canvas == (Object)null) { return; } ItemData itemData = m_drop.m_itemData; string id = PaintingItem.GetId(itemData); if (id == null || id == m_shown) { return; } Texture2D val = PaintingStore.Get(id, PaintingItem.GetImage(itemData)); if ((Object)(object)val == (Object)null) { m_shown = id; return; } if ((Object)(object)m_material == (Object)null && (Object)(object)PaintingPiece.CanvasTemplate != (Object)null) { m_material = new Material(PaintingPiece.CanvasTemplate); m_canvas.sharedMaterial = m_material; } if ((Object)(object)m_material != (Object)null) { m_material.mainTexture = (Texture)(object)val; } m_shown = id; } private void OnDestroy() { if ((Object)(object)m_material != (Object)null) { Object.Destroy((Object)(object)m_material); } } } public static class PaintingSelection { public static ItemData Current { get { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return null; } foreach (ItemData allItem in ((Humanoid)localPlayer).GetInventory().GetAllItems()) { if (PaintingItem.GetId(allItem) != null) { return allItem; } } return null; } } public static void Consume(Player player) { ItemData current = Current; if ((Object)(object)player != (Object)null && current != null) { ((Humanoid)player).GetInventory().RemoveItem(current, 1); } } public static bool IsPaintingCost(Requirement[] requirements) { if (requirements == null || requirements.Length != 1) { return false; } ItemDrop resItem = requirements[0].m_resItem; if ((Object)(object)resItem != (Object)null) { return resItem.m_itemData.m_shared.m_name == "$vp_item_painting"; } return false; } } } namespace Valheim_Paintings.Capture { public static class FramingOverlay { private static readonly Color LineColor = new Color(1f, 1f, 1f, 0.5f); private const float ReferenceHeight = 720f; private static Texture2D s_pixel; private static bool s_hudWasHidden; public static bool Visible { get; private set; } public static void Show() { if (!Visible) { Hud instance = Hud.instance; s_hudWasHidden = (Object)(object)instance != (Object)null && instance.m_userHidden; if ((Object)(object)instance != (Object)null) { instance.m_userHidden = true; } Visible = true; } } public static void Hide() { if (Visible) { Visible = false; Hud instance = Hud.instance; if ((Object)(object)instance != (Object)null) { instance.m_userHidden = s_hudWasHidden; } } } public static Rect Frame() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) int width = Screen.width; int height = Screen.height; int num = Mathf.Min(width, height); int num2 = Mathf.Clamp(Mathf.RoundToInt((float)num * PaintingsConfig.ScreenFraction.Value), 16, num); int num3 = (width - num2) / 2; int num4 = (height - num2) / 2; return new Rect((float)num3, (float)(height - num4 - num2), (float)num2, (float)num2); } public static void Draw() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_0066: Unknown result type (might be due to invalid IL or missing references) if (Visible && Event.current != null && (int)Event.current.type == 7) { Rect frame = Frame(); float num = Mathf.Max(1f, Mathf.Round((float)Screen.height / 720f) * 2f); Color color = GUI.color; GUI.color = LineColor; Border(frame, num); if (PaintingsConfig.ThirdsGrid.Value) { Thirds(frame, Mathf.Max(1f, num * 0.5f)); } GUI.color = color; } } private static void Border(Rect frame, float thickness) { //IL_0016: 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_0058: 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) Line(new Rect(((Rect)(ref frame)).x, ((Rect)(ref frame)).y, ((Rect)(ref frame)).width, thickness)); Line(new Rect(((Rect)(ref frame)).x, ((Rect)(ref frame)).yMax - thickness, ((Rect)(ref frame)).width, thickness)); Line(new Rect(((Rect)(ref frame)).x, ((Rect)(ref frame)).y, thickness, ((Rect)(ref frame)).height)); Line(new Rect(((Rect)(ref frame)).xMax - thickness, ((Rect)(ref frame)).y, thickness, ((Rect)(ref frame)).height)); } private static void Thirds(Rect frame, float thickness) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) float num = thickness * 0.5f; for (int i = 1; i <= 2; i++) { float num2 = (float)i / 3f; Line(new Rect(((Rect)(ref frame)).x + ((Rect)(ref frame)).width * num2 - num, ((Rect)(ref frame)).y, thickness, ((Rect)(ref frame)).height)); Line(new Rect(((Rect)(ref frame)).x, ((Rect)(ref frame)).y + ((Rect)(ref frame)).height * num2 - num, ((Rect)(ref frame)).width, thickness)); } } private static void Line(Rect rect) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) GUI.DrawTexture(rect, (Texture)(object)Pixel()); } private static Texture2D Pixel() { //IL_0011: 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_0023: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_pixel == (Object)null) { s_pixel = new Texture2D(1, 1, (TextureFormat)4, false) { hideFlags = (HideFlags)61 }; s_pixel.SetPixel(0, 0, Color.white); s_pixel.Apply(); } return s_pixel; } } public static class ImageCodec { public static byte[] EncodeJpeg(Texture2D texture, int quality, int maxBytes, out int usedQuality) { usedQuality = Mathf.Clamp(quality, 20, 100); byte[] array = ImageConversion.EncodeToJPG(texture, usedQuality); while (array.Length > maxBytes && usedQuality > 20) { usedQuality = Mathf.Max(20, usedQuality - 10); array = ImageConversion.EncodeToJPG(texture, usedQuality); } return array; } public static Texture2D Decode(byte[] bytes) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown if (bytes == null || bytes.Length == 0) { return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)3, false); if (!ImageConversion.LoadImage(val, bytes)) { Object.Destroy((Object)(object)val); return null; } ((Texture)val).wrapMode = (TextureWrapMode)1; return val; } public static string ToBase64(byte[] bytes) { if (bytes != null) { return Convert.ToBase64String(bytes); } return string.Empty; } public static byte[] FromBase64(string text) { if (string.IsNullOrEmpty(text)) { return null; } try { return Convert.FromBase64String(text); } catch (FormatException) { return null; } } } public static class PaintingIcons { public const int IconSize = 64; private const string FallbackResource = "Valheim_Paintings.painting_icon.png"; private static readonly Dictionary<string, Sprite> s_icons = new Dictionary<string, Sprite>(); private static Sprite s_fallback; public static Sprite Fallback { get { if ((Object)(object)s_fallback == (Object)null) { s_fallback = LoadFallback(); } return s_fallback; } } public static Sprite ForItem(ItemData item) { string id = PaintingItem.GetId(item); if (id == null) { return Fallback; } if (s_icons.TryGetValue(id, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = PaintingStore.Get(id, PaintingItem.GetImage(item)); Sprite val2 = (((Object)(object)val != (Object)null) ? MakeIcon(val, "vp_icon_" + id) : null); s_icons[id] = (((Object)(object)val2 != (Object)null) ? val2 : Fallback); return s_icons[id]; } private static Sprite MakeIcon(Texture2D source, string name) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_00b4: Expected O, but got Unknown if (!((Texture)source).isReadable || ((Texture)source).width != ((Texture)source).height) { PaintingsPlugin.Log.LogWarning((object)("Texture " + ((Object)source).name + " cannot be shrunk into an icon.")); return null; } int width = ((Texture)source).width; Color32[] array = source.GetPixels32(); int num = Mathf.Min(64, width); if (num != width) { array = ScreenGrabber.Downscale(array, width, num); } Texture2D val = new Texture2D(num, num, (TextureFormat)3, false) { name = name, wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; val.SetPixels32(array); val.Apply(false, true); Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f); ((Object)obj).name = name; return obj; } private static Sprite LoadFallback() { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Valheim_Paintings.painting_icon.png"); if (stream == null) { PaintingsPlugin.Log.LogError((object)"Embedded icon Valheim_Paintings.painting_icon.png is missing."); return null; } MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = ImageCodec.Decode(memoryStream.ToArray()); if ((Object)(object)val == (Object)null) { PaintingsPlugin.Log.LogError((object)"Embedded icon Valheim_Paintings.painting_icon.png does not decode."); return null; } Sprite result = MakeIcon(val, "vp_icon"); Object.Destroy((Object)(object)val); return result; } } public static class PaintingStore { private static readonly Dictionary<string, Texture2D> s_cache = new Dictionary<string, Texture2D>(); public static string NewId() { return DateTime.Now.ToString("yyyy-MM-dd_HHmmss") + "_" + Random.Range(4096, 65535).ToString("x4"); } public static Texture2D Get(string id, byte[] bytes) { if (string.IsNullOrEmpty(id)) { return null; } if (s_cache.TryGetValue(id, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = ImageCodec.Decode(bytes); if ((Object)(object)val == (Object)null) { return null; } ((Object)val).name = "vp_" + id; s_cache[id] = val; return val; } public static void Put(string id, Texture2D texture) { if (!string.IsNullOrEmpty(id) && (Object)(object)texture != (Object)null) { ((Object)texture).name = "vp_" + id; s_cache[id] = texture; } } public static string ExportFolder() { string value = PaintingsConfig.ExportFolder.Value; return Path.Combine(string.IsNullOrEmpty(value) ? Path.Combine(Paths.ConfigPath, "Valheim_Paintings") : value, SafeWorldName()); } public static string WritePng(string id, byte[] png) { try { string text = ExportFolder(); Directory.CreateDirectory(text); string text2 = Path.Combine(text, id + ".png"); File.WriteAllBytes(text2, png); return text2; } catch (Exception ex) { PaintingsPlugin.Log.LogWarning((object)("Could not export the png: " + ex.Message)); return null; } } private static string SafeWorldName() { string text = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetWorldName() : null); if (string.IsNullOrEmpty(text)) { return "unknown"; } char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); foreach (char oldChar in invalidFileNameChars) { text = text.Replace(oldChar, '_'); } return text; } } public sealed class PaintingCapture { public string Id; public byte[] Jpeg; public int Quality; public byte[] Png; public int CropSize; public Texture2D Texture; } public static class ScreenGrabber { public static bool Busy { get; private set; } public static bool CanCapture(out string reason) { reason = null; if ((Object)(object)Player.m_localPlayer == (Object)null) { reason = "no local player"; } else if (((Character)Player.m_localPlayer).IsDead() || ((Character)Player.m_localPlayer).InCutscene()) { reason = "dead or in a cutscene"; } else if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) { reason = "typing in the chat"; } else if (Console.IsVisible() || TextInput.IsVisible()) { reason = "typing somewhere else"; } else if (InventoryGui.IsVisible() || StoreGui.IsVisible() || Menu.IsVisible() || Minimap.IsOpen()) { reason = "a full screen panel is open"; } else if (UnifiedPopup.IsVisible() || ((Object)(object)TextViewer.instance != (Object)null && TextViewer.instance.IsVisible())) { reason = "a popup is open"; } return reason == null; } public static IEnumerator Run(Action<PaintingCapture> onDone) { Busy = true; Hud hud = Hud.instance; bool wasHidden = (Object)(object)hud != (Object)null && hud.m_userHidden; if ((Object)(object)hud != (Object)null) { hud.m_userHidden = true; } yield return null; yield return (object)new WaitForEndOfFrame(); Texture2D val = null; try { val = ScreenCapture.CaptureScreenshotAsTexture(); } catch (Exception ex) { PaintingsPlugin.Log.LogError((object)("Screen capture failed: " + ex)); } finally { if ((Object)(object)hud != (Object)null) { hud.m_userHidden = wasHidden; } } PaintingCapture obj = null; if ((Object)(object)val != (Object)null) { try { obj = Build(val); } catch (Exception ex2) { PaintingsPlugin.Log.LogError((object)("Could not turn the capture into a painting: " + ex2)); } Object.Destroy((Object)(object)val); } Busy = false; onDone?.Invoke(obj); } private static PaintingCapture Build(Texture2D screen) { int num = Mathf.Min(((Texture)screen).width, ((Texture)screen).height); int num2 = Mathf.Clamp(Mathf.RoundToInt((float)num * PaintingsConfig.ScreenFraction.Value), 16, num); Color32[] array = Crop(screen.GetPixels32(), ((Texture)screen).width, ((Texture)screen).height, num2); PaintingCapture paintingCapture = new PaintingCapture { Id = PaintingStore.NewId(), CropSize = num2 }; int num3 = Mathf.Min(PaintingsConfig.TextureSize.Value, num2); if (PaintingsConfig.ExportPng.Value) { Texture2D val = MakeTexture(array, num2); paintingCapture.Png = ImageConversion.EncodeToPNG(val); if (num3 == num2) { paintingCapture.Texture = val; } else { Object.Destroy((Object)(object)val); } } if ((Object)(object)paintingCapture.Texture == (Object)null) { paintingCapture.Texture = MakeTexture((num3 == num2) ? array : Downscale(array, num2, num3), num3); } paintingCapture.Jpeg = ImageCodec.EncodeJpeg(paintingCapture.Texture, PaintingsConfig.JpegQuality.Value, PaintingsConfig.MaxBytes.Value, out var usedQuality); paintingCapture.Quality = usedQuality; return paintingCapture; } private static Color32[] Crop(Color32[] pixels, int width, int height, int side) { int num = (width - side) / 2; int num2 = (height - side) / 2; Color32[] array = (Color32[])(object)new Color32[side * side]; for (int i = 0; i < side; i++) { Array.Copy(pixels, (num2 + i) * width + num, array, i * side, side); } return array; } internal static Color32[] Downscale(Color32[] source, int sourceSize, int size) { //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0182: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) Color32[] array = (Color32[])(object)new Color32[size * size]; float num = (float)sourceSize / (float)size; for (int i = 0; i < size; i++) { float num2 = (float)i * num; float num3 = (float)(i + 1) * num; int num4 = Mathf.FloorToInt(num2); int num5 = Mathf.Min(Mathf.CeilToInt(num3), sourceSize) - 1; for (int j = 0; j < size; j++) { float num6 = (float)j * num; float num7 = (float)(j + 1) * num; int num8 = Mathf.FloorToInt(num6); int num9 = Mathf.Min(Mathf.CeilToInt(num7), sourceSize) - 1; float num10 = 0f; float num11 = 0f; float num12 = 0f; float num13 = 0f; for (int k = num4; k <= num5; k++) { float num14 = Mathf.Min((float)(k + 1), num3) - Mathf.Max((float)k, num2); if (num14 <= 0f) { continue; } int num15 = k * sourceSize; for (int l = num8; l <= num9; l++) { float num16 = (Mathf.Min((float)(l + 1), num7) - Mathf.Max((float)l, num6)) * num14; if (!(num16 <= 0f)) { Color32 val = source[num15 + l]; num10 += (float)(int)val.r * num16; num11 += (float)(int)val.g * num16; num12 += (float)(int)val.b * num16; num13 += num16; } } } array[i * size + j] = ((num13 > 0f) ? new Color32((byte)(num10 / num13), (byte)(num11 / num13), (byte)(num12 / num13), byte.MaxValue) : new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue)); } } return array; } private static Texture2D MakeTexture(Color32[] pixels, int size) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown Texture2D val = new Texture2D(size, size, (TextureFormat)3, false) { wrapMode = (TextureWrapMode)1 }; val.SetPixels32(pixels); val.Apply(); return val; } } }