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 VargheimStatueWorkshop v0.3.12
plugins/VargheimStatueWorkshop.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [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 VargheimStatueWorkshop { [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] internal static class AutoAlignPatch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { GameObject val = (GameObject)((Workshop.GhostField == null) ? null : /*isinst with value type is only supported in some contexts*/); if (!((Object)(object)val == (Object)null) && val.activeInHierarchy && Workshop.IsStatue(val) && Workshop.Prefabs.TryGetValue(Workshop.Canonical(((Object)val).name), out var value) && value.IsModule) { AutoAlign.Apply(__instance, val, value); } } } } internal static class AutoAlign { private static readonly FieldInfo RayMask = AccessTools.Field(typeof(Player), "m_placeRayMask"); internal static Transform Datum(GameObject go) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown foreach (Transform item in go.transform) { Transform val = item; if (((Object)val).name == "workshop_snap_assembly_datum") { return val; } } return null; } internal static void Apply(Player player, GameObject ghost, Workshop.StatueInfo info) { //IL_0059: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0243: 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_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) try { if (ZInput.GetButton("AltPlace") || ZInput.GetButton("JoyAltPlace") || (Object)(object)GameCamera.instance == (Object)null || RayMask == null) { return; } int num = (int)RayMask.GetValue(player); Transform transform = ((Component)GameCamera.instance).transform; RaycastHit[] array = Physics.RaycastAll(transform.position, transform.forward, 60f, num); Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); Piece val = null; RaycastHit[] array2 = array; for (int num2 = 0; num2 < array2.Length; num2++) { RaycastHit val2 = array2[num2]; if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) && !((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(ghost.transform)) { val = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Piece>(); break; } } if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)(object)ghost || !Workshop.IsStatue(((Component)val).gameObject) || !Workshop.Prefabs.TryGetValue(Workshop.Canonical(((Object)((Component)val).gameObject).name), out var value) || !value.IsModule || value.SelectionKey != info.SelectionKey) { return; } float num3 = ((value.StandardScale.x > 0f) ? (((Component)val).transform.localScale.x / value.StandardScale.x) : 1f); int num4 = 1; float num5 = float.MaxValue; for (int num6 = 0; num6 < Workshop.Multipliers.Length; num6++) { float num7 = Mathf.Abs(Workshop.Multipliers[num6] - num3); if (num7 < num5) { num5 = num7; num4 = num6; } } Workshop.Selection[info.SelectionKey] = num4; ghost.transform.localScale = info.StandardScale * Workshop.Multipliers[num4]; ghost.transform.rotation = ((Component)val).transform.rotation; Transform val3 = Datum(((Component)val).gameObject); Transform val4 = Datum(ghost); if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val4 == (Object)null)) { Transform transform2 = ghost.transform; transform2.position += val3.position - val4.position; Workshop.HudText = Workshop.Labels[num4] + " | lined up with the part you aim at | hold Shift to place freely"; } } catch (Exception) { } } } [Serializable] public sealed class CollectionFile { public CollectionFigure[] figures; public string[] replaceKeys; } [Serializable] public sealed class CollectionFigure { public string key; public string model; public string label; } internal static class CollectionRegistration { internal static void Register() { string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "collection.json"); if (!File.Exists(path)) { return; } CollectionFile collectionFile = SpecReader.Collection(File.ReadAllText(path)); if (collectionFile == null || collectionFile.figures == null) { throw new InvalidDataException("Workshop collection manifest missing figures"); } Type type = AccessTools.TypeByName("VargheimStatues.Plugin"); FieldInfo fieldInfo = ((type == null) ? null : AccessTools.Field(type, "Figures")); ConfigEntry<string> val = ((fieldInfo == null) ? null : (fieldInfo.GetValue(null) as ConfigEntry<string>)); if (val == null) { throw new MissingFieldException("Original statue Figures configuration unavailable"); } HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); string[] array = val.Value.Split(';'); foreach (string text in array) { hashSet.Add(text.Split(':')[0].Trim()); } string current = val.Value; CollectionFigure[] figures = collectionFile.figures; foreach (CollectionFigure collectionFigure in figures) { if (string.IsNullOrEmpty(collectionFigure.key) || string.IsNullOrEmpty(collectionFigure.model) || string.IsNullOrEmpty(collectionFigure.label)) { throw new InvalidDataException("Incomplete collection entry"); } if (collectionFigure.key.IndexOfAny(new char[2] { ':', ';' }) >= 0 || collectionFigure.label.IndexOfAny(new char[2] { ':', ';' }) >= 0 || Path.GetFileName(collectionFigure.model) != collectionFigure.model) { throw new InvalidDataException("Invalid collection entry format"); } if (!hashSet.Contains(collectionFigure.key)) { string text2 = (collectionFigure.model.EndsWith(".obj", StringComparison.OrdinalIgnoreCase) ? collectionFigure.model.Substring(0, collectionFigure.model.Length - 4) : collectionFigure.model); if (ModelFiles.Find(collectionFigure.model).Length + ModelFiles.Find(text2 + ".vsm").Length <= 0 || ModelFiles.Find(collectionFigure.model + ".statue.json").Length != 1) { throw new InvalidDataException("Collection model/metadata missing or ambiguous: " + collectionFigure.model); } current = CollectionRows.Append(current, collectionFigure.key, collectionFigure.model, collectionFigure.label); hashSet.Add(collectionFigure.key); Workshop.Instance.LoggerForImport("Added collection hammer entry: " + collectionFigure.label); } } current = CollectionRows.WithoutKeys(current, collectionFile.replaceKeys); if (current != val.Value) { val.Value = current; } } } internal static class CollectionRows { internal static string WithoutKeys(string current, string[] keys) { if (keys == null || keys.Length == 0) { return current ?? ""; } HashSet<string> hashSet = new HashSet<string>(keys, StringComparer.OrdinalIgnoreCase); List<string> list = new List<string>(); string[] array = (current ?? "").Split(';'); foreach (string text in array) { if (!string.IsNullOrWhiteSpace(text) && !hashSet.Contains(text.Split(':')[0].Trim())) { list.Add(text.Trim()); } } return string.Join("; ", list.ToArray()); } internal static string Append(string current, string key, string model, string label) { if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(model) || string.IsNullOrEmpty(label)) { throw new InvalidDataException("Incomplete collection entry"); } if (key.IndexOfAny(new char[2] { ':', ';' }) >= 0 || label.IndexOfAny(new char[2] { ':', ';' }) >= 0 || model.IndexOfAny(new char[4] { ':', ';', '/', '\\' }) >= 0 || !model.EndsWith(".obj", StringComparison.OrdinalIgnoreCase)) { throw new InvalidDataException("Invalid collection entry format"); } current = current ?? ""; string[] array = current.Split(';'); for (int i = 0; i < array.Length; i++) { if (string.Equals(array[i].Split(':')[0].Trim(), key, StringComparison.OrdinalIgnoreCase)) { return current; } } string text = current.TrimEnd().TrimEnd(';'); return ((text.Length == 0) ? "" : (text + "; ")) + key + ":" + model + ":" + label + ":1"; } } internal static class Diag { [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class Register { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; internal void <Postfix>b__0_0(ConsoleEventArgs args) { try { string text = Run(); Workshop.Instance.LoggerForImport(text); string[] array = text.Split('\n'); foreach (string text2 in array) { args.Context.AddString(text2); } } catch (Exception ex) { args.Context.AddString("vst_lod failed: " + ex.Message); } } } [HarmonyPostfix] private static void Postfix() { //IL_0033: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown try { object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { try { string text = Run(); Workshop.Instance.LoggerForImport(text); string[] array = text.Split('\n'); foreach (string text2 in array) { args.Context.AddString(text2); } } catch (Exception ex2) { args.Context.AddString("vst_lod failed: " + ex2.Message); } }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("vst_lod", "Statue Workshop: renderer/LOD state of statues within 40 m (also written to the BepInEx log)", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } catch (Exception ex) { Workshop.Instance.LoggerForImport("vst_lod not registered: " + ex.Message); } } } private static string F(float v) { return v.ToString("0.###", CultureInfo.InvariantCulture); } private static string V(Vector3 v) { //IL_0010: 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_003c: Unknown result type (might be due to invalid IL or missing references) return "(" + F(v.x) + "," + F(v.y) + "," + F(v.z) + ")"; } private static string Run() { //IL_0057: 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_00b7: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_015c: 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) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03db: 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_03e4: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; Camera main = Camera.main; if ((Object)(object)localPlayer == (Object)null || (Object)(object)main == (Object)null) { return "vst_lod: load a world first."; } StringBuilder stringBuilder = new StringBuilder(); int num = 0; Piece[] array = Object.FindObjectsByType<Piece>((FindObjectsSortMode)0); foreach (Piece val in array) { if (!Workshop.IsStatue(((Component)val).gameObject)) { continue; } float num2 = Vector3.Distance(((Component)val).transform.position, ((Component)main).transform.position); if (num2 > 40f) { continue; } num++; stringBuilder.Append(Workshop.Canonical(((Object)val).name)).Append(" d=").Append(F(num2)) .Append(" pos=") .Append(V(((Component)val).transform.position)) .Append(" scale=") .Append(V(((Component)val).transform.localScale)) .Append(" active=") .Append(((Component)val).gameObject.activeInHierarchy) .Append('\n'); LODGroup[] componentsInChildren = ((Component)val).GetComponentsInChildren<LODGroup>(true); foreach (LODGroup val2 in componentsInChildren) { float num3 = val2.size * Mathf.Max(Mathf.Abs(((Component)val2).transform.lossyScale.x), Mathf.Max(Mathf.Abs(((Component)val2).transform.lossyScale.y), Mathf.Abs(((Component)val2).transform.lossyScale.z))); Vector3 val3 = ((Component)val2).transform.TransformPoint(val2.localReferencePoint); float num4 = Vector3.Distance(val3, ((Component)main).transform.position); float v = num3 / (2f * Mathf.Max(0.01f, num4) * Mathf.Tan(main.fieldOfView * 0.5f * ((float)Math.PI / 180f))); stringBuilder.Append(" LODGroup on ").Append(((Object)val2).name).Append(" enabled=") .Append(val2.enabled) .Append(" size=") .Append(F(val2.size)) .Append(" (") .Append(F(num3)) .Append(" m) ref=") .Append(V(val3)) .Append(" screen=") .Append(F(v)) .Append(" levels:"); LOD[] lODs = val2.GetLODs(); foreach (LOD val4 in lODs) { stringBuilder.Append(' ').Append(F(val4.screenRelativeTransitionHeight)).Append('/') .Append(val4.renderers.Length); } stringBuilder.Append('\n'); } Renderer[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Renderer>(true); foreach (Renderer val5 in componentsInChildren2) { if (((Component)val5).gameObject.activeInHierarchy || ((Object)val5).name.StartsWith("statue", StringComparison.Ordinal) || ((Object)val5).name.StartsWith("workshop", StringComparison.Ordinal)) { MeshFilter component = ((Component)val5).GetComponent<MeshFilter>(); StringBuilder stringBuilder2 = stringBuilder.Append(" ").Append(((Object)val5).name).Append(" on=") .Append(val5.enabled) .Append(" act=") .Append(((Component)val5).gameObject.activeInHierarchy) .Append(" visible=") .Append(val5.isVisible) .Append(" layer=") .Append(LayerMask.LayerToName(((Component)val5).gameObject.layer)) .Append(" bounds="); Bounds bounds = val5.bounds; StringBuilder stringBuilder3 = stringBuilder2.Append(V(((Bounds)(ref bounds)).center)).Append('+'); bounds = val5.bounds; stringBuilder3.Append(V(((Bounds)(ref bounds)).size)).Append(" mesh=").Append(((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) ? (component.sharedMesh.vertexCount + "v") : "none") .Append(" mat=") .Append(((Object)(object)val5.sharedMaterial != (Object)null) ? ((Object)val5.sharedMaterial.shader).name : "none") .Append('\n'); } } } if (num == 0) { return "vst_lod: no Vargheim statue within 40 m."; } return stringBuilder.ToString().TrimEnd(); } } internal static class MiniJson { internal static object Parse(string s) { int i = 0; object result = Value(s, ref i); Ws(s, ref i); if (i < s.Length) { throw new FormatException("trailing text at " + i); } return result; } private static void Ws(string s, ref int i) { while (i < s.Length && char.IsWhiteSpace(s[i])) { i++; } } private static object Value(string s, ref int i) { Ws(s, ref i); if (i >= s.Length) { throw new FormatException("unexpected end"); } switch (s[i]) { case '{': return Obj(s, ref i); case '[': return Arr(s, ref i); case '"': return Str(s, ref i); default: { if (s.Length - i >= 4 && string.CompareOrdinal(s, i, "true", 0, 4) == 0) { i += 4; return true; } if (s.Length - i >= 5 && string.CompareOrdinal(s, i, "false", 0, 5) == 0) { i += 5; return false; } if (s.Length - i >= 4 && string.CompareOrdinal(s, i, "null", 0, 4) == 0) { i += 4; return null; } int num = i; while (i < s.Length && "+-0123456789.eE".IndexOf(s[i]) >= 0) { i++; } if (i == num) { throw new FormatException("bad value at " + i); } return double.Parse(s.Substring(num, i - num), NumberStyles.Float, CultureInfo.InvariantCulture); } } } private static Dictionary<string, object> Obj(string s, ref int i) { Dictionary<string, object> dictionary = new Dictionary<string, object>(StringComparer.Ordinal); i++; Ws(s, ref i); if (i < s.Length && s[i] == '}') { i++; return dictionary; } while (true) { Ws(s, ref i); string key = Str(s, ref i); Ws(s, ref i); if (i >= s.Length || s[i] != ':') { throw new FormatException("':' expected at " + i); } i++; dictionary[key] = Value(s, ref i); Ws(s, ref i); if (i >= s.Length || s[i] != ',') { break; } i++; } if (i < s.Length && s[i] == '}') { i++; return dictionary; } throw new FormatException("',' or '}' expected at " + i); } private static List<object> Arr(string s, ref int i) { List<object> list = new List<object>(); i++; Ws(s, ref i); if (i < s.Length && s[i] == ']') { i++; return list; } while (true) { list.Add(Value(s, ref i)); Ws(s, ref i); if (i >= s.Length || s[i] != ',') { break; } i++; } if (i < s.Length && s[i] == ']') { i++; return list; } throw new FormatException("',' or ']' expected at " + i); } private static string Str(string s, ref int i) { if (s[i] != '"') { throw new FormatException("string expected at " + i); } i++; StringBuilder stringBuilder = new StringBuilder(); while (i < s.Length) { char c = s[i++]; switch (c) { case '"': return stringBuilder.ToString(); default: stringBuilder.Append(c); break; case '\\': { char c2 = s[i++]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': stringBuilder.Append((char)int.Parse(s.Substring(i, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture)); i += 4; break; default: stringBuilder.Append(c2); break; } break; } } } throw new FormatException("unterminated string"); } internal static string S(Dictionary<string, object> d, string k) { if (d == null || !d.TryGetValue(k, out var value) || !(value is string)) { return null; } return (string)value; } internal static float F(Dictionary<string, object> d, string k) { if (d == null || !d.TryGetValue(k, out var value) || value == null) { return 0f; } if (value is double) { return (float)(double)value; } if (value is bool) { if (!(bool)value) { return 0f; } return 1f; } return 0f; } internal static bool B(Dictionary<string, object> d, string k) { if (d != null && d.TryGetValue(k, out var value) && value is bool) { return (bool)value; } return false; } internal static float[] Floats(Dictionary<string, object> d, string k) { if (d == null || !d.TryGetValue(k, out var value)) { return null; } if (!(value is List<object> list)) { return null; } float[] array = new float[list.Count]; for (int i = 0; i < list.Count; i++) { array[i] = ((list[i] is double) ? ((float)(double)list[i]) : 0f); } return array; } internal static List<Dictionary<string, object>> Objects(Dictionary<string, object> d, string k) { List<Dictionary<string, object>> list = new List<Dictionary<string, object>>(); if (d == null || !d.TryGetValue(k, out var value)) { return list; } if (!(value is List<object> list2)) { return list; } foreach (object item2 in list2) { if (item2 is Dictionary<string, object> item) { list.Add(item); } } return list; } } internal static class ModelFiles { private static string s_baseDir; private static string BaseDir() { if (s_baseDir != null) { return s_baseDir; } Type type = AccessTools.TypeByName("VargheimStatues.Plugin"); s_baseDir = ((type == null) ? "" : (Path.GetDirectoryName(type.Assembly.Location) ?? "")); return s_baseDir; } internal static string[] Find(string fileName) { List<string> list = new List<string>(Directory.GetFiles(Paths.PluginPath, fileName, SearchOption.AllDirectories)); string path = Path.Combine(Path.Combine(Paths.ConfigPath, "VargheimStatues"), "models"); if (Directory.Exists(path)) { list.AddRange(Directory.GetFiles(path, fileName, SearchOption.AllDirectories)); } if (list.Count <= 1) { return list.ToArray(); } string b = BaseDir(); if (b.Length > 0) { List<string> list2 = list.FindAll((string f) => f.StartsWith(b + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)); if (list2.Count == 1) { return list2.ToArray(); } } return list.ToArray(); } } [Serializable] public sealed class SnapAnchor { public string name; public float x; public float y; public float z; } internal static class ModularPieces { private static readonly Dictionary<string, List<float>> s_joints = new Dictionary<string, List<float>>(StringComparer.Ordinal); private static List<float> FamilyJoints(string family) { if (s_joints.TryGetValue(family, out var value)) { return value; } value = new List<float>(); HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); List<string> list = new List<string>(Directory.GetFiles(Paths.PluginPath, "*.obj.statue.json", SearchOption.AllDirectories)); string path = Path.Combine(Path.Combine(Paths.ConfigPath, "VargheimStatues"), "models"); if (Directory.Exists(path)) { list.AddRange(Directory.GetFiles(path, "*.obj.statue.json", SearchOption.AllDirectories)); } foreach (string item in list) { string fileName = Path.GetFileName(item); fileName = fileName.Substring(0, fileName.Length - ".statue.json".Length); if (!hashSet.Add(fileName)) { continue; } try { AssetSpec assetSpec = AssetFinish.ReadSpec(fileName); if (assetSpec == null || assetSpec.family != family || assetSpec.snaps == null) { continue; } SnapAnchor[] snaps = assetSpec.snaps; foreach (SnapAnchor snapAnchor in snaps) { if (snapAnchor != null && snapAnchor.name == "assembly_datum") { float j = 0f - snapAnchor.y; if (j > 0.002f && !value.Exists((float h) => Mathf.Abs(h - j) < 0.002f)) { value.Add(j); } } } } catch (Exception) { } } s_joints[family] = value; return value; } private static bool SupportWearOff() { try { Type type = AccessTools.TypeByName("VargheimStatues.SupportWear"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "Off", (Type[])null, (Type[])null)); if (methodInfo != null) { return (bool)methodInfo.Invoke(null, null); } } catch (Exception ex) { Workshop.Instance.LoggerForImport("SupportWear.Off unavailable (" + ex.Message + "); falling back to a vanilla read."); } GameObject val = (((Object)(object)ZNetScene.instance == (Object)null) ? null : (ZNetScene.instance.GetPrefab("woodwall") ?? ZNetScene.instance.GetPrefab("wood_floor"))); WearNTear val2 = (((Object)(object)val == (Object)null) ? null : val.GetComponent<WearNTear>()); if (!((Object)(object)val2 == (Object)null)) { return !val2.m_noSupportWear; } return false; } internal static bool IsModule(AssetSpec spec) { if (spec != null && !string.IsNullOrEmpty(spec.family)) { return !string.IsNullOrEmpty(spec.pieceKind); } return false; } internal static void Configure(GameObject root, AssetSpec spec) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00f1: Expected O, but got Unknown //IL_0107: 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) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_04a3: Unknown result type (might be due to invalid IL or missing references) //IL_04a8: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Unknown result type (might be due to invalid IL or missing references) //IL_04e4: Unknown result type (might be due to invalid IL or missing references) //IL_04e9: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Unknown result type (might be due to invalid IL or missing references) //IL_050a: Unknown result type (might be due to invalid IL or missing references) if (!IsModule(spec)) { return; } if (spec.figureHeight <= 0f || spec.assemblyHeight <= 0f || spec.stoneCost < 1) { throw new InvalidDataException("Invalid modular dimensions or Stone cost"); } Piece component = root.GetComponent<Piece>(); GameObject val = (((Object)(object)ObjectDB.instance == (Object)null) ? null : ObjectDB.instance.GetItemPrefab("Stone")); ItemDrop val2 = (((Object)(object)val == (Object)null) ? null : val.GetComponent<ItemDrop>()); if ((Object)(object)component == (Object)null || (Object)(object)val2 == (Object)null) { throw new InvalidDataException("Modular piece or Stone resource unavailable"); } GameObject val3 = (((Object)(object)ObjectDB.instance == (Object)null) ? null : ObjectDB.instance.GetItemPrefab("Wood")); ItemDrop val4 = (((Object)(object)val3 == (Object)null) ? null : val3.GetComponent<ItemDrop>()); List<Requirement> list = new List<Requirement> { new Requirement { m_resItem = val2, m_amount = spec.stoneCost, m_amountPerLevel = 0, m_recover = true } }; if (spec.woodCost > 0 && (Object)(object)val4 != (Object)null) { list.Add(new Requirement { m_resItem = val4, m_amount = spec.woodCost, m_amountPerLevel = 0, m_recover = true }); } component.m_resources = list.ToArray(); component.m_groundOnly = false; WearNTear component2 = root.GetComponent<WearNTear>(); if ((Object)(object)component2 != (Object)null) { component2.m_noSupportWear = SupportWearOff(); } component.m_comfort = ((spec.pieceKind == "Torso") ? 1 : 0); string text = ((spec.family == "SpearSentinel") ? "Spear Guardian" : ((spec.family == "AxeSentinel") ? "Axe Guardian" : spec.family)); string text2 = ((spec.pieceKind == "LowerBody") ? "lower body" : spec.pieceKind.ToLowerInvariant()); component.m_description = text + " " + text2 + ", carved in grey stone. " + spec.stoneCost + " Stone" + ((spec.woodCost > 0) ? (" and " + spec.woodCost + " Wood") : "") + " at every size. Match sizes when assembling the statue."; Transform val5 = root.transform.Find("statue_figure"); MeshFilter val6 = (((Object)(object)val5 == (Object)null) ? null : ((Component)val5).GetComponentInChildren<MeshFilter>()); if ((Object)(object)val6 == (Object)null) { throw new InvalidDataException("Module snap reference mesh missing"); } SnapAnchor snapAnchor = null; if (spec.snaps != null) { SnapAnchor[] snaps = spec.snaps; foreach (SnapAnchor snapAnchor2 in snaps) { if (snapAnchor2 != null && snapAnchor2.name == "assembly_datum") { if (snapAnchor != null) { throw new InvalidDataException("Duplicate statue assembly datum"); } snapAnchor = snapAnchor2; } } } if (snapAnchor == null) { throw new InvalidDataException("Statue module requires one assembly_datum snap"); } Transform[] componentsInChildren = root.GetComponentsInChildren<Transform>(true); foreach (Transform val7 in componentsInChildren) { if ((Object)(object)val7 != (Object)(object)root.transform && ((Component)val7).CompareTag("snappoint")) { ((Component)val7).gameObject.tag = "Untagged"; Object.Destroy((Object)(object)((Component)val7).gameObject); } } Mesh sharedMesh = val6.sharedMesh; float num; Bounds bounds; if (!((Object)(object)sharedMesh != (Object)null)) { num = 0f; } else { bounds = sharedMesh.bounds; num = ((Bounds)(ref bounds)).min.y - snapAnchor.y; } float num2 = num; float num3; if (!((Object)(object)sharedMesh != (Object)null)) { num3 = 0f; } else { bounds = sharedMesh.bounds; num3 = ((Bounds)(ref bounds)).max.y - snapAnchor.y; } float num4 = num3; List<float> list2 = new List<float> { 0f }; foreach (float j in FamilyJoints(spec.family)) { if (j >= num2 - 0.002f && j <= num4 + 0.002f && !list2.Exists((float h) => Mathf.Abs(h - j) < 0.002f)) { list2.Add(j); } } foreach (float item in list2) { GameObject val8 = new GameObject("workshop_snap_" + ((item == 0f) ? snapAnchor.name : ("joint_" + item.ToString("0.000", CultureInfo.InvariantCulture)))) { tag = "snappoint", layer = root.layer }; Vector3 val9 = ((Component)val6).transform.TransformPoint(new Vector3(0f - snapAnchor.x, snapAnchor.y + item, snapAnchor.z)); val8.transform.SetParent(root.transform, false); val8.transform.localPosition = root.transform.InverseTransformPoint(val9); } } } [HarmonyPatch(typeof(Piece), "DropResources")] internal static class PaidStoneRefund { private static void Prefix(Piece __instance, out Requirement[] __state) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown __state = null; if (!Workshop.IsStatue(((Component)__instance).gameObject)) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component == (Object)null) ? null : component.GetZDO()); if (val == null) { return; } int num = val.GetInt("vargheim_statue_stone_paid", -1); int num2 = val.GetInt("vargheim_statue_wood_paid", -1); if (num < 0 || __instance.m_resources == null || __instance.m_resources.Length < 1) { return; } __state = __instance.m_resources; List<Requirement> list = new List<Requirement>(); Requirement[] resources = __instance.m_resources; foreach (Requirement val2 in resources) { if (!((Object)(object)val2.m_resItem == (Object)null)) { string name = ((Object)((Component)val2.m_resItem).gameObject).name; int amount = ((name == "Stone") ? num : ((name == "Wood" && num2 >= 0) ? num2 : val2.m_amount)); list.Add(new Requirement { m_resItem = val2.m_resItem, m_amount = amount, m_amountPerLevel = 0, m_recover = val2.m_recover }); } } __instance.m_resources = list.ToArray(); } private static Exception Finalizer(Exception __exception, Piece __instance, Requirement[] __state) { if (__state != null) { __instance.m_resources = __state; } return __exception; } } internal sealed class ObjData { internal readonly List<float[]> Positions = new List<float[]>(); internal readonly List<float[]> Normals = new List<float[]>(); internal readonly List<float[]> UVs = new List<float[]>(); internal readonly List<int> Indices = new List<int>(); internal static bool IsWorkshop(string[] lines) { for (int i = 0; i < Math.Min(lines.Length, 8); i++) { string text = lines[i].Trim(); if (text.StartsWith("# Odin Workshop v7.", StringComparison.Ordinal) || text.StartsWith("# Workshop Odin UV-preserving distance LOD", StringComparison.Ordinal) || text == "# Vargheim Workshop OBJ" || text.StartsWith("# Welded pos+uv+normal", StringComparison.Ordinal)) { return true; } } return false; } internal static ObjData Parse(string[] lines) { ObjData objData = new ObjData(); List<float[]> list = new List<float[]>(); List<float[]> list2 = new List<float[]>(); List<float[]> list3 = new List<float[]>(); Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.Ordinal); for (int i = 0; i < lines.Length; i++) { string text = lines[i].Split('#')[0].Trim(); if (text.Length == 0) { continue; } string[] array = text.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (array[0] == "v") { Require(array.Length >= 4, "Incomplete position"); list.Add(new float[3] { 0f - Number(array[1]), Number(array[2]), Number(array[3]) }); } else if (array[0] == "vn") { Require(array.Length >= 4, "Incomplete normal"); list2.Add(new float[3] { 0f - Number(array[1]), Number(array[2]), Number(array[3]) }); } else if (array[0] == "vt") { Require(array.Length >= 3, "Incomplete texture coordinate"); list3.Add(new float[2] { Number(array[1]), Number(array[2]) }); } else { if (!(array[0] == "f")) { continue; } Require(array.Length >= 4, "Incomplete face"); int[] array2 = new int[array.Length - 1]; for (int j = 1; j < array.Length; j++) { string[] array3 = array[j].Split('/'); Require(array3.Length == 3 && array3[1].Length > 0 && array3[2].Length > 0, "Workshop faces require position/texture/normal indices"); int index = Index(array3[0], list.Count); int index2 = Index(array3[1], list3.Count); int index3 = Index(array3[2], list2.Count); string key = index.ToString(CultureInfo.InvariantCulture) + "/" + index2.ToString(CultureInfo.InvariantCulture) + "/" + index3.ToString(CultureInfo.InvariantCulture); if (!dictionary.TryGetValue(key, out var value)) { value = objData.Positions.Count; dictionary.Add(key, value); objData.Positions.Add(list[index]); objData.UVs.Add(list3[index2]); objData.Normals.Add(list2[index3]); } array2[j - 1] = value; } for (int k = 1; k < array2.Length - 1; k++) { objData.Indices.Add(array2[0]); objData.Indices.Add(array2[k + 1]); objData.Indices.Add(array2[k]); } } } Require(objData.Indices.Count > 0, "Workshop OBJ has no faces"); return objData; } private static float Number(string value) { float num = float.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); Require(!float.IsNaN(num) && !float.IsInfinity(num), "Nonfinite OBJ value"); return num; } private static int Index(string value, int count) { int num = int.Parse(value, CultureInfo.InvariantCulture); int num2 = ((num < 0) ? (count + num) : (num - 1)); Require(num != 0 && num2 >= 0 && num2 < count, "OBJ index outside source range"); return num2; } private static void Require(bool condition, string message) { if (!condition) { throw new InvalidDataException(message); } } } internal static class SpecReader { internal static CollectionFile Collection(string text) { if (!(MiniJson.Parse(text) is Dictionary<string, object> dictionary)) { return null; } CollectionFile collectionFile = new CollectionFile(); List<CollectionFigure> list = new List<CollectionFigure>(); foreach (Dictionary<string, object> item in MiniJson.Objects(dictionary, "figures")) { list.Add(new CollectionFigure { key = MiniJson.S(item, "key"), model = MiniJson.S(item, "model"), label = MiniJson.S(item, "label") }); } collectionFile.figures = list.ToArray(); List<string> list2 = new List<string>(); if (dictionary.TryGetValue("replaceKeys", out var value) && value is List<object>) { foreach (object item2 in (List<object>)value) { if (item2 is string) { list2.Add((string)item2); } } } collectionFile.replaceKeys = list2.ToArray(); return collectionFile; } internal static AssetSpec Asset(string text) { if (!(MiniJson.Parse(text) is Dictionary<string, object> dictionary)) { return null; } AssetSpec assetSpec = new AssetSpec { family = MiniJson.S(dictionary, "family"), pieceKind = MiniJson.S(dictionary, "pieceKind"), assemblyHeight = MiniJson.F(dictionary, "assemblyHeight"), stoneCost = (int)Math.Round(MiniJson.F(dictionary, "stoneCost")), woodCost = (int)Math.Round(MiniJson.F(dictionary, "woodCost")), ownBase = MiniJson.B(dictionary, "ownBase"), baseHeight = MiniJson.F(dictionary, "baseHeight"), figureHeight = MiniJson.F(dictionary, "figureHeight"), albedo = MiniJson.S(dictionary, "albedo"), normal = MiniJson.S(dictionary, "normal"), metallicGloss = MiniJson.S(dictionary, "metallicGloss"), lod1 = MiniJson.S(dictionary, "lod1"), lod2 = MiniJson.S(dictionary, "lod2"), collision = MiniJson.S(dictionary, "collision"), lod1Normal = MiniJson.S(dictionary, "lod1Normal"), lod2Normal = MiniJson.S(dictionary, "lod2Normal"), lod1Albedo = MiniJson.S(dictionary, "lod1Albedo"), lod2Albedo = MiniJson.S(dictionary, "lod2Albedo") }; if (dictionary.ContainsKey("smoothness")) { assetSpec.smoothness = MiniJson.F(dictionary, "smoothness"); } if (dictionary.ContainsKey("normalStrength")) { assetSpec.normalStrength = MiniJson.F(dictionary, "normalStrength"); } if (dictionary.ContainsKey("tintR")) { assetSpec.tintR = MiniJson.F(dictionary, "tintR"); } if (dictionary.ContainsKey("tintG")) { assetSpec.tintG = MiniJson.F(dictionary, "tintG"); } if (dictionary.ContainsKey("tintB")) { assetSpec.tintB = MiniJson.F(dictionary, "tintB"); } if (dictionary.ContainsKey("snaps")) { List<SnapAnchor> list = new List<SnapAnchor>(); foreach (Dictionary<string, object> item in MiniJson.Objects(dictionary, "snaps")) { list.Add(new SnapAnchor { name = MiniJson.S(item, "name"), x = MiniJson.F(item, "x"), y = MiniJson.F(item, "y"), z = MiniJson.F(item, "z") }); } assetSpec.snaps = list.ToArray(); } return assetSpec; } } [BepInPlugin("digi.vargheim.statueworkshop", "Vargheim Statue Workshop", "0.3.12")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Workshop : BaseUnityPlugin { internal sealed class StatueInfo { internal string Name; internal Vector3 StandardScale; internal float StandardHeight; internal string SelectionKey; internal bool IsModule; internal int StoneCost; internal int WoodCost; } internal sealed class Placement { internal string Name; internal Vector3 Scale; internal float Multiplier; internal int PaidStone = -1; internal int PaidWood = -1; } [HarmonyPatch(typeof(Player), "UpdatePlacement")] private static class PreviewPatch { private static void Prefix(Player __instance, bool takeInput) { //IL_00af: 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_010b: 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_007f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } HudText = null; GameObject val = (GameObject)((GhostField == null) ? null : /*isinst with value type is only supported in some contexts*/); if ((Object)(object)val == (Object)null || !val.activeInHierarchy || !IsStatue(val)) { return; } string key = Canonical(((Object)val).name); if (Prefabs.TryGetValue(key, out var value)) { int num = Selected(value.SelectionKey); if (takeInput && Input.GetKeyDown(CycleKey.Value)) { num = (num + 1) % Multipliers.Length; Selection[value.SelectionKey] = num; } val.transform.localScale = value.StandardScale * Multipliers[num]; HudText = Labels[num] + " | " + (value.StandardHeight * Multipliers[num]).ToString("0.#") + " m assembly | " + ((object)CycleKey.Value/*cast due to .constrained prefix*/).ToString() + ": change size"; } } private static void Postfix(Player __instance) { //IL_0071: 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) if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } GameObject val = (GameObject)((GhostField == null) ? null : /*isinst with value type is only supported in some contexts*/); if ((Object)(object)val == (Object)null || !val.activeInHierarchy || !IsStatue(val)) { HudText = null; return; } string key = Canonical(((Object)val).name); if (Prefabs.TryGetValue(key, out var value)) { val.transform.localScale = value.StandardScale * Multipliers[Selected(value.SelectionKey)]; } } } [HarmonyPatch(typeof(Player), "PlacePiece")] private static class PlacePatch { private static void Prefix(Player __instance, Piece piece, out Placement __state) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) __state = Scope; Scope = null; if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)piece == (Object)null) && IsStatue(((Component)piece).gameObject)) { string text = Canonical(((Object)((Component)piece).gameObject).name); if (Prefabs.TryGetValue(text, out var value)) { Scope = new Placement { Name = text, Scale = value.StandardScale * Multipliers[Selected(value.SelectionKey)], Multiplier = Multipliers[Selected(value.SelectionKey)], PaidStone = ((!value.IsModule) ? (-1) : ((!__instance.NoCostCheat()) ? value.StoneCost : 0)), PaidWood = ((!value.IsModule) ? (-1) : ((!__instance.NoCostCheat()) ? value.WoodCost : 0)) }; } } } private static Exception Finalizer(Exception __exception, Placement __state) { Scope = __state; return __exception; } } [HarmonyPatch(typeof(ZNetView), "Awake")] private static class NetScalePatch { private static void Prefix(ZNetView __instance) { if (IsStatue(((Component)__instance).gameObject)) { __instance.m_syncInitialScale = true; } } private static void Postfix(ZNetView __instance) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (Scope != null && IsStatue(((Component)__instance).gameObject) && !(Canonical(((Object)((Component)__instance).gameObject).name) != Scope.Name) && __instance.GetZDO() != null && __instance.IsOwner()) { __instance.m_syncInitialScale = true; __instance.SetLocalScale(Scope.Scale); __instance.GetZDO().Set("vargheim_statue_size", Scope.Multiplier); if (Scope.PaidStone >= 0) { __instance.GetZDO().Set("vargheim_statue_stone_paid", Scope.PaidStone); } if (Scope.PaidWood >= 0) { __instance.GetZDO().Set("vargheim_statue_wood_paid", Scope.PaidWood); } } } } internal static Workshop Instance; internal static ConfigEntry<KeyCode> CycleKey; internal static ConfigEntry<float> OdinHeight; internal static ConfigEntry<float> OtherRatio; internal static ConfigEntry<float> Lod1At; internal static ConfigEntry<float> Lod2At; internal static ConfigEntry<float> CullAt; internal static ConfigEntry<bool> UseLods; internal static readonly Dictionary<string, StatueInfo> Prefabs = new Dictionary<string, StatueInfo>(StringComparer.Ordinal); internal static readonly Dictionary<string, int> Selection = new Dictionary<string, int>(StringComparer.Ordinal); internal static readonly string[] Labels = new string[4] { "Small", "Standard", "Large", "Monument" }; internal static readonly float[] Multipliers = new float[4] { 0.4f, 1f, 1.5f, 2f }; internal static readonly FieldInfo GhostField = AccessTools.Field(typeof(Player), "m_placementGhost"); internal static string HudText; [ThreadStatic] internal static Placement Scope; private Harmony patches; internal void LoggerForImport(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); } private void Awake() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Expected O, but got Unknown //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Expected O, but got Unknown //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Expected O, but got Unknown Instance = this; CycleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Placement", "CycleSizeKey", (KeyCode)287, "Cycle statue size while placing it. One hammer entry per statue."); OdinHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Collection", "OdinStandardHeight", 10f, new ConfigDescription("Odin's Standard figure height in metres, excluding its own base.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 30f), Array.Empty<object>())); OtherRatio = ((BaseUnityPlugin)this).Config.Bind<float>("Collection", "OtherStatueHeightRatio", 0.82f, new ConfigDescription("Other statues' height relative to Odin at the same size setting.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 0.99f), Array.Empty<object>())); Lod1At = ((BaseUnityPlugin)this).Config.Bind<float>("Detail", "Lod1ScreenHeight", 0.1f, new ConfigDescription("Whole statue's share of screen height below which parts switch to the first distance model (all parts of one statue switch together). Restart to apply.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.9f), Array.Empty<object>())); Lod2At = ((BaseUnityPlugin)this).Config.Bind<float>("Detail", "Lod2ScreenHeight", 0.04f, new ConfigDescription("Share of screen height below which parts switch to the coarse distance model. Restart to apply.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.005f, 0.5f), Array.Empty<object>())); CullAt = ((BaseUnityPlugin)this).Config.Bind<float>("Detail", "HideBelowScreenHeight", 0.006f, new ConfigDescription("Share of screen height below which the statue is not drawn. Restart to apply.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.1f), Array.Empty<object>())); UseLods = ((BaseUnityPlugin)this).Config.Bind<bool>("Detail", "UseDistanceModels", true, "Swap to lighter models at a distance. Turn off if statue parts do not show; full detail is then always drawn. Restart to apply."); patches = new Harmony("digi.vargheim.statueworkshop"); Type type = AccessTools.TypeByName("VargheimStatues.Carve"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "MakePiece", (Type[])null, (Type[])null)); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Compatible VargheimStatues MakePiece method not found; workshop disabled."); return; } Type type2 = AccessTools.TypeByName("VargheimStatues.ObjModel"); MethodInfo methodInfo2 = ((type2 == null) ? null : AccessTools.Method(type2, "Parse", new Type[2] { typeof(string[]), typeof(string) }, (Type[])null)); if (methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Compatible OBJ import method not found; workshop disabled."); return; } patches.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(WorkshopObjImport), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); patches.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Workshop), "BuiltStatue", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); patches.PatchAll(typeof(Workshop).Assembly); CollectionRegistration.Register(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Statue Workshop 0.3.12 ready: F6 cycles sizes; Odin is tallest at matching sizes. Fresh-server configuration."); } private void OnDestroy() { if (patches != null) { patches.UnpatchSelf(); } } private void OnGUI() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(HudText)) { GameObject val = (GameObject)(((Object)(object)Player.m_localPlayer == (Object)null || GhostField == null) ? null : /*isinst with value type is only supported in some contexts*/); if (!((Object)(object)val == (Object)null) && val.activeInHierarchy) { GUI.Box(new Rect((float)Screen.width * 0.5f - 200f, (float)Screen.height * 0.73f, 400f, 30f), HudText); } } } internal static string Canonical(string n) { return (n ?? "").Replace("(Clone)", "").Trim(); } internal static bool IsStatue(GameObject go) { if ((Object)(object)go != (Object)null) { return Canonical(((Object)go).name).StartsWith("VargheimStatue_", StringComparison.Ordinal); } return false; } internal static int Selected(string key) { if (!Selection.TryGetValue(key, out var value)) { return 1; } return value; } internal static float NativeHeight(float tweak) { Type type = AccessTools.TypeByName("VargheimStatues.Plugin"); FieldInfo fieldInfo = ((type == null) ? null : AccessTools.Field(type, "Height")); return Mathf.Max(0.01f, (((fieldInfo == null) ? null : (fieldInfo.GetValue(null) as ConfigEntry<float>))?.Value ?? 10f) * tweak); } private static void BuiltStatue(GameObject __result, string key, string creature, float tweak) { //IL_0086: 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_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) if ((Object)(object)__result == (Object)null) { return; } try { float num = NativeHeight(tweak); AssetSpec assetSpec = AssetFinish.ReadSpec(creature); bool num2 = AssetFinish.Apply(__result, creature); bool flag = ModularPieces.IsModule(assetSpec); bool flag2 = (flag ? assetSpec.family : key).IndexOf("odin", StringComparison.OrdinalIgnoreCase) >= 0; float num3 = OdinHeight.Value * (flag2 ? 1f : OtherRatio.Value); float num4 = (flag ? (assetSpec.figureHeight / assetSpec.assemblyHeight) : 1f); Transform transform = __result.transform; transform.localScale *= num3 / num * num4; ModularPieces.Configure(__result, assetSpec); ZNetView component = __result.GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null) { component.m_syncInitialScale = true; } Prefabs[Canonical(((Object)__result).name)] = new StatueInfo { Name = Canonical(((Object)__result).name), StandardScale = __result.transform.localScale, StandardHeight = num3, SelectionKey = (flag ? ("family:" + assetSpec.family) : Canonical(((Object)__result).name)), IsModule = flag, StoneCost = (flag ? assetSpec.stoneCost : (-1)), WoodCost = (flag ? assetSpec.woodCost : (-1)) }; if (num2) { RefreshIcon(__result, key); } } catch (Exception ex) { ((BaseUnityPlugin)Instance).Logger.LogError((object)("Statue asset setup failed for " + key + ": " + ex)); } } private static void RefreshIcon(GameObject piece, string key) { Type type = AccessTools.TypeByName("VargheimStatues.Icon"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "Render", new Type[2] { typeof(GameObject), typeof(string) }, (Type[])null)); if (methodInfo == null) { return; } LODGroup componentInChildren = piece.GetComponentInChildren<LODGroup>(); try { if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.ForceLOD(0); } object? obj = methodInfo.Invoke(null, new object[2] { piece, key }); Sprite val = (Sprite)((obj is Sprite) ? obj : null); Piece component = piece.GetComponent<Piece>(); if ((Object)(object)val != (Object)null && (Object)(object)component != (Object)null) { component.m_icon = val; } } catch (Exception ex) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Statue icon refresh failed: " + ex.Message)); } finally { if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.ForceLOD(-1); } } } } [Serializable] public sealed class AssetSpec { public string family; public string pieceKind; public float assemblyHeight; public int stoneCost; public int woodCost; public SnapAnchor[] snaps; public bool ownBase; public float baseHeight; public float figureHeight; public string albedo; public string normal; public string metallicGloss; public string lod1; public string lod2; public string lod1Normal; public string lod2Normal; public string lod1Albedo; public string lod2Albedo; public string collision; public float smoothness = 0.04f; public float normalStrength = 0.3f; public float tintR = 1f; public float tintG = 1f; public float tintB = 1f; } internal static class AssetFinish { private static readonly Dictionary<string, Material> Materials = new Dictionary<string, Material>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, Texture2D> Textures = new Dictionary<string, Texture2D>(StringComparer.OrdinalIgnoreCase); internal static AssetSpec ReadSpec(string model) { if (string.IsNullOrEmpty(model) || !model.EndsWith(".obj", StringComparison.OrdinalIgnoreCase)) { return null; } string[] array = ModelFiles.Find(Path.GetFileName(model) + ".statue.json"); if (array.Length == 0) { return null; } if (array.Length != 1) { throw new InvalidDataException("Ambiguous statue finish metadata for " + model); } return SpecReader.Asset(File.ReadAllText(array[0])); } internal static bool Apply(GameObject piece, string model) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Expected O, but got Unknown //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_0441: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_044b: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_047d: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_04ac: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_0506: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Unknown result type (might be due to invalid IL or missing references) //IL_053c: Unknown result type (might be due to invalid IL or missing references) //IL_0548: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(model) || !model.EndsWith(".obj", StringComparison.OrdinalIgnoreCase)) { return false; } string[] array = ModelFiles.Find(Path.GetFileName(model) + ".statue.json"); if (array.Length == 0) { return false; } if (array.Length != 1) { throw new InvalidDataException("Ambiguous statue finish metadata for " + model); } string text = array[0]; string directoryName = Path.GetDirectoryName(text); AssetSpec assetSpec = SpecReader.Asset(File.ReadAllText(text)); if (assetSpec == null) { throw new InvalidDataException("Empty statue finish metadata"); } Transform val = piece.transform.Find("statue_figure"); if ((Object)(object)val == (Object)null) { throw new InvalidDataException("Statue figure transform missing"); } Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true); if (!Materials.TryGetValue(text, out var value)) { if (componentsInChildren.Length == 0) { throw new InvalidDataException("No figure renderer"); } value = new Material(componentsInChildren[0].sharedMaterial); ((Object)value).name = "Workshop carved stone"; if (value.HasProperty("_Color")) { value.SetColor("_Color", new Color(assetSpec.tintR, assetSpec.tintG, assetSpec.tintB, 1f)); } Texture2D val2 = LoadTexture(directoryName, assetSpec.albedo, linear: false); if ((Object)(object)val2 != (Object)null && value.HasProperty("_MainTex")) { value.SetTexture("_MainTex", (Texture)(object)val2); value.SetTextureScale("_MainTex", Vector2.one); value.SetTextureOffset("_MainTex", Vector2.zero); } Texture2D val3 = LoadTexture(directoryName, assetSpec.normal, linear: true); if ((Object)(object)val3 != (Object)null && value.HasProperty("_BumpMap")) { value.SetTexture("_BumpMap", (Texture)(object)val3); value.SetTextureScale("_BumpMap", Vector2.one); value.SetTextureOffset("_BumpMap", Vector2.zero); value.EnableKeyword("_NORMALMAP"); } Float(value, "_BumpScale", Mathf.Clamp(assetSpec.normalStrength, 0f, 1f)); Float(value, "_Metallic", 0f); Float(value, "_Glossiness", Mathf.Clamp01(assetSpec.smoothness)); Float(value, "_Smoothness", Mathf.Clamp01(assetSpec.smoothness)); Float(value, "_GlossMapScale", 1f); if (value.HasProperty("_MetallicGlossMap")) { Texture2D val4 = LoadTexture(directoryName, assetSpec.metallicGloss, linear: true); if ((Object)(object)val4 != (Object)null) { value.SetTexture("_MetallicGlossMap", (Texture)(object)val4); value.SetTextureScale("_MetallicGlossMap", Vector2.one); value.SetTextureOffset("_MetallicGlossMap", Vector2.zero); } else { Texture2D val5 = new Texture2D(1, 1, (TextureFormat)4, false, true); val5.SetPixel(0, 0, new Color(0f, 0f, 0f, Mathf.Clamp01(assetSpec.smoothness))); val5.Apply(false, true); value.SetTexture("_MetallicGlossMap", (Texture)(object)val5); } } if (value.HasProperty("_SpecColor")) { value.SetColor("_SpecColor", new Color(0.03f, 0.03f, 0.03f, 1f)); } Materials[text] = value; } Renderer[] array2 = componentsInChildren; for (int i = 0; i < array2.Length; i++) { array2[i].sharedMaterial = value; } if (assetSpec.ownBase || ModularPieces.IsModule(assetSpec)) { if (assetSpec.figureHeight <= 0f || (!ModularPieces.IsModule(assetSpec) && assetSpec.baseHeight <= 0f)) { throw new InvalidDataException("Own-base dimensions must be positive"); } Transform[] componentsInChildren2 = piece.GetComponentsInChildren<Transform>(true); foreach (Transform val6 in componentsInChildren2) { if (((Object)val6).name.StartsWith("statue_plinth", StringComparison.Ordinal)) { ((Component)val6).gameObject.SetActive(false); } } if (ModularPieces.IsModule(assetSpec)) { val.localPosition = new Vector3(0f, val.localPosition.y, 0f); } Bounds val7 = LocalBounds(piece.transform, val); float num = assetSpec.figureHeight + assetSpec.baseHeight; if (!ModularPieces.IsModule(assetSpec)) { val.localScale *= num / assetSpec.figureHeight; } val7 = LocalBounds(piece.transform, val); val.localPosition -= new Vector3(0f, ((Bounds)(ref val7)).min.y, 0f); val7 = LocalBounds(piece.transform, val); if (!string.IsNullOrEmpty(assetSpec.collision)) { AddCollision(piece, componentsInChildren, directoryName, assetSpec.collision); BoxCollider obj = piece.AddComponent<BoxCollider>(); obj.center = new Vector3(((Bounds)(ref val7)).center.x, ((Bounds)(ref val7)).min.y + 0.03f, ((Bounds)(ref val7)).center.z); obj.size = new Vector3(Mathf.Max(0.05f, ((Bounds)(ref val7)).size.x * 0.6f), 0.06f, Mathf.Max(0.05f, ((Bounds)(ref val7)).size.z * 0.6f)); } else { BoxCollider[] components = piece.GetComponents<BoxCollider>(); foreach (BoxCollider obj2 in components) { obj2.center = ((Bounds)(ref val7)).center; obj2.size = ((Bounds)(ref val7)).size; } } } AddLods(val, componentsInChildren, value, assetSpec, directoryName, text); return true; } private static void AddCollision(GameObject piece, Renderer[] renderers, string dir, string model) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0083: 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_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_00a5: Unknown result type (might be due to invalid IL or missing references) if (renderers.Length != 1) { throw new InvalidDataException("Workshop collision requires one primary mesh renderer"); } if (Path.GetFileName(model) != model) { throw new InvalidDataException("Collision must be a model filename"); } Mesh val = LoadModel(model); if ((Object)(object)val == (Object)null) { throw new InvalidDataException("Could not load statue collision " + model); } GameObject val2 = new GameObject("workshop_collision") { layer = piece.layer }; Transform transform = ((Component)renderers[0]).transform; val2.transform.SetParent(transform.parent, false); val2.transform.localPosition = transform.localPosition; val2.transform.localRotation = transform.localRotation; val2.transform.localScale = transform.localScale; MeshCollider obj = val2.AddComponent<MeshCollider>(); obj.convex = false; obj.sharedMesh = val; BoxCollider[] components = piece.GetComponents<BoxCollider>(); for (int i = 0; i < components.Length; i++) { Object.DestroyImmediate((Object)(object)components[i]); } Workshop.Instance.LoggerForImport("Installed fitted static collision: " + val.triangles.Length / 3 + " triangles."); } private static Mesh LoadModel(string model) { Type type = AccessTools.TypeByName("VargheimStatues.ObjModel"); MethodInfo obj = ((type == null) ? null : AccessTools.Method(type, "Load", new Type[1] { typeof(string) }, (Type[])null)); if (obj == null) { throw new MissingMethodException("Statue model loader unavailable"); } object? obj2 = obj.Invoke(null, new object[1] { model }); return (Mesh)((obj2 is Mesh) ? obj2 : null); } private static void AddLods(Transform figure, Renderer[] renderers, Material mat, AssetSpec spec, string dir, string file) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_027b: 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_028f: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: 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_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(spec.lod1) || !Workshop.UseLods.Value) { return; } if (renderers.Length != 1) { throw new InvalidDataException("Workshop LODs require one primary mesh renderer"); } string[] array = new string[2] { spec.lod1, spec.lod2 }; string[] array2 = new string[2] { spec.lod1Normal, spec.lod2Normal }; string[] array3 = new string[2] { spec.lod1Albedo, spec.lod2Albedo }; float value = Workshop.Lod1At.Value; float num = Mathf.Min(Workshop.Lod2At.Value, value * 0.9f); float num2 = Mathf.Min(Workshop.CullAt.Value, num * 0.9f); List<LOD> list = new List<LOD>(); list.Add(new LOD(value, renderers)); float[] array4 = new float[2] { num, num2 }; for (int i = 0; i < array.Length; i++) { if (!string.IsNullOrEmpty(array[i])) { if (Path.GetFileName(array[i]) != array[i]) { throw new InvalidDataException("LOD must be a model filename"); } Mesh val = LoadModel(array[i]); if ((Object)(object)val == (Object)null) { throw new InvalidDataException("Could not load statue LOD " + array[i]); } GameObject val2 = new GameObject("workshop_lod" + (i + 1)) { layer = ((Component)renderers[0]).gameObject.layer }; val2.transform.SetParent(((Component)renderers[0]).transform.parent, false); val2.transform.localPosition = ((Component)renderers[0]).transform.localPosition; val2.transform.localRotation = ((Component)renderers[0]).transform.localRotation; val2.transform.localScale = ((Component)renderers[0]).transform.localScale; val2.AddComponent<MeshFilter>().sharedMesh = val; MeshRenderer val3 = val2.AddComponent<MeshRenderer>(); ((Renderer)val3).sharedMaterial = LodMaterial(mat, spec, dir, file, i + 1, array2[i], array3[i]); ((Renderer)val3).shadowCastingMode = renderers[0].shadowCastingMode; list.Add(new LOD((i + 1 < array.Length && !string.IsNullOrEmpty(array[i + 1])) ? array4[i] : num2, (Renderer[])(object)new Renderer[1] { (Renderer)val3 })); } } if (list.Count == 1) { return; } LODGroup val4 = ((Component)figure).gameObject.AddComponent<LODGroup>(); val4.SetLODs(list.ToArray()); Bounds val5 = LocalBounds(figure, figure); val4.localReferencePoint = ((Bounds)(ref val5)).center; val4.size = Mathf.Max(((Bounds)(ref val5)).size.x, Mathf.Max(((Bounds)(ref val5)).size.y, ((Bounds)(ref val5)).size.z)); if (ModularPieces.IsModule(spec) && spec.figureHeight > 0f && spec.assemblyHeight > spec.figureHeight) { Bounds val6 = LocalBounds(figure, figure); float y = ((Bounds)(ref val6)).size.y; if (y > 0f) { val4.size = Mathf.Max(val4.size, y * spec.assemblyHeight / spec.figureHeight); } } } private static Material LodMaterial(Material full, AssetSpec spec, string dir, string file, int level, string normal, string albedo) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(normal) && string.IsNullOrEmpty(albedo)) { return full; } string key = file + "#lod" + level; if (Materials.TryGetValue(key, out var value)) { return value; } value = new Material(full); ((Object)value).name = "Workshop carved stone LOD" + level; bool flag = !string.IsNullOrEmpty(albedo); if (flag) { Texture2D val = LoadTexture(dir, albedo, linear: false); if (value.HasProperty("_MainTex")) { value.SetTexture("_MainTex", (Texture)(object)val); } if (value.HasProperty("_MetallicGlossMap")) { Texture2D val2 = new Texture2D(1, 1, (TextureFormat)4, false, true); val2.SetPixel(0, 0, new Color(0f, 0f, 0f, Mathf.Clamp01(spec.smoothness))); val2.Apply(false, true); value.SetTexture("_MetallicGlossMap", (Texture)(object)val2); } } if (!string.IsNullOrEmpty(normal)) { if (value.HasProperty("_BumpMap")) { value.SetTexture("_BumpMap", (Texture)(object)LoadTexture(dir, normal, linear: true)); value.EnableKeyword("_NORMALMAP"); } } else if (flag) { if (value.HasProperty("_BumpMap")) { value.SetTexture("_BumpMap", (Texture)null); } value.DisableKeyword("_NORMALMAP"); Float(value, "_BumpScale", 0f); } Materials[key] = value; return value; } private static Bounds LocalBounds(Transform root, Transform figure) { //IL_0004: 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) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_0097: 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_00b7: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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_00e4: 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_00d4: Unknown result type (might be due to invalid IL or missing references) bool flag = true; Bounds result = default(Bounds); MeshFilter[] componentsInChildren = ((Component)figure).GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { if ((Object)(object)val.sharedMesh == (Object)null) { continue; } Bounds bounds = val.sharedMesh.bounds; Matrix4x4 val2 = root.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix; for (int j = 0; j < 8; j++) { Vector3 val3 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(new Vector3(((j & 1) == 0) ? ((Bounds)(ref bounds)).min.x : ((Bounds)(ref bounds)).max.x, ((j & 2) == 0) ? ((Bounds)(ref bounds)).min.y : ((Bounds)(ref bounds)).max.y, ((j & 4) == 0) ? ((Bounds)(ref bounds)).min.z : ((Bounds)(ref bounds)).max.z)); if (flag) { ((Bounds)(ref result))..ctor(val3, Vector3.zero); flag = false; } else { ((Bounds)(ref result)).Encapsulate(val3); } } } if (flag) { throw new InvalidDataException("Figure has no mesh bounds"); } return result; } private static void Float(Material mat, string name, float value) { if (mat.HasProperty(name)) { mat.SetFloat(name, value); } } private static Texture2D LoadTexture(string dir, string name, bool linear) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown if (string.IsNullOrEmpty(name)) { return null; } string value = Path.GetFullPath(dir) + Path.DirectorySeparatorChar; string fullPath = Path.GetFullPath(Path.Combine(dir, name)); if (!fullPath.StartsWith(value, StringComparison.OrdinalIgnoreCase)) { throw new InvalidDataException("Asset texture escapes model folder"); } if (!File.Exists(fullPath)) { throw new FileNotFoundException("Statue texture missing", fullPath); } string key = fullPath + (linear ? "|lin" : "|srgb"); if (Textures.TryGetValue(key, out var value2) && (Object)(object)value2 != (Object)null) { return value2; } value2 = new Texture2D(2, 2, (TextureFormat)4, true, linear); ((Object)value2).name = Path.GetFileName(fullPath); if (!ImageConversion.LoadImage(value2, File.ReadAllBytes(fullPath), true)) { throw new InvalidDataException("Invalid statue texture " + name); } ((Texture)value2).wrapMode = (TextureWrapMode)1; ((Texture)value2).filterMode = (FilterMode)2; ((Texture)value2).anisoLevel = 4; Textures[key] = value2; return value2; } } internal static class WorkshopObjImport { private static bool Prefix(string[] __0, string __1, ref Mesh __result) { //IL_0069: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown if (!ObjData.IsWorkshop(__0)) { return true; } ObjData objData = ObjData.Parse(__0); List<Vector3> list = new List<Vector3>(objData.Positions.Count); List<Vector3> list2 = new List<Vector3>(objData.Normals.Count); List<Vector2> list3 = new List<Vector2>(objData.UVs.Count); foreach (float[] position in objData.Positions) { list.Add(new Vector3(position[0], position[1], position[2])); } foreach (float[] normal in objData.Normals) { list2.Add(new Vector3(normal[0], normal[1], normal[2])); } foreach (float[] uV in objData.UVs) { list3.Add(new Vector2(uV[0], uV[1])); } Mesh val = new Mesh(); ((Object)val).name = __1 + "_WorkshopUV"; val.indexFormat = (IndexFormat)(list.Count > 65535); val.SetVertices(list); val.SetNormals(list2); val.SetUVs(0, list3); val.SetTriangles(objData.Indices, 0); val.RecalculateBounds(); val.RecalculateTangents(); __result = val; Workshop.Instance.LoggerForImport("Imported " + __1 + " with authored UVs: " + list.Count + " vertices, " + objData.Indices.Count / 3 + " triangles."); return false; } } }