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 LordsOfTheKnightCape SOF v1.1.0
plugins/LordsCape/LordsCape.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; [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 LordsCape { [BepInPlugin("com.tronn.lordscape", "LordsCape", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class LordsCapePlugin : BaseUnityPlugin { public const string GUID = "com.tronn.lordscape"; public const string NAME = "LordsCape"; public const string VERSION = "1.1.0"; public const string CapeId = "CapeLongNight"; public const string MageCapeId = "CapeLongNightMage"; internal static LordsCapePlugin Instance; internal static ManualLogSource Log; internal static ConfigEntry<float> EmissionIntensity; internal static ConfigEntry<bool> FlipBack; private static Texture2D _albedo; private static Texture2D _emission; private static Texture2D _mageAlbedo; private static Texture2D _mageEmission; private static Texture2D _styleWhite; private static int _capeHash; private static int _mageHash; private static Mesh _unfolded; private static readonly HashSet<int> _fixedMeshes = new HashSet<int>(); private static readonly HashSet<int> _done = new HashSet<int>(); internal static string PluginDir => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); private void Awake() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; EmissionIntensity = ((BaseUnityPlugin)this).Config.Bind<float>("LordsCape", "EmissionIntensity", 4f, "Brightness of the raven's glowing eyes."); FlipBack = ((BaseUnityPlugin)this).Config.Bind<bool>("LordsCape", "FlipBack", false, "Flip which half of the cape unfolds - set true if the logo text appears mirrored."); Harmony val = new Harmony("com.tronn.lordscape"); try { MethodInfo methodInfo = AccessTools.Method(typeof(VisEquipment), "SetCapeEquipped", (Type[])null, (Type[])null); if (methodInfo != null) { val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(LordsCapePlugin), "OnCapeEquipped", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"VisEquipment.SetCapeEquipped not found - worn-cape fix inactive"); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("worn-cape hook failed: " + ex.Message)); } PrefabManager.OnVanillaPrefabsAvailable += AddItems; ((BaseUnityPlugin)this).Logger.LogInfo((object)"LordsCape 1.1.0 loaded"); } private static void AddItems() { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Expected O, but got Unknown //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Expected O, but got Unknown try { _capeHash = StringExtensionMethods.GetStableHashCode("CapeLongNight"); _mageHash = StringExtensionMethods.GetStableHashCode("CapeLongNightMage"); if ((Object)(object)_albedo == (Object)null) { _albedo = LoadTex("LordsCape_albedo.png"); } if ((Object)(object)_emission == (Object)null) { _emission = LoadTex("LordsCape_emission.png"); } if ((Object)(object)_mageAlbedo == (Object)null) { _mageAlbedo = LoadTex("LordsMage_albedo.png"); } if ((Object)(object)_mageEmission == (Object)null) { _mageEmission = LoadTex("LordsMage_emission.png"); } ItemConfig val = new ItemConfig(); val.Name = "Cape of the Long Night"; val.Description = "Black wings of the clan. The raven watches, and its eyes burn."; val.CraftingStation = "piece_workbench"; val.MinStationLevel = 2; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("LinenThread", 20, 10, true), new RequirementConfig("Coal", 10, 5, true) }; CustomItem val2 = new CustomItem("CapeLongNight", "CapeLinen", val); ItemManager.Instance.AddItem(val2); PatchClone(val2.ItemPrefab, _albedo, _emission, unfold: true); val = new ItemConfig(); val.Name = "Magecloak of the Long Night"; val.Description = "The raven's shadow, woven for the clan's spellweavers."; val.CraftingStation = "piece_workbench"; val.MinStationLevel = 2; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("LinenThread", 20, 10, true), new RequirementConfig("Feathers", 10, 5, true) }; CustomItem val3 = new CustomItem("CapeLongNightMage", "CapeDeepNorthMage", val); ItemManager.Instance.AddItem(val3); PatchClone(val3.ItemPrefab, _mageAlbedo, _mageEmission, unfold: false); Log.LogInfo((object)"registered CapeLongNight and CapeLongNightMage"); } catch (Exception ex) { Log.LogError((object)ex); } finally { PrefabManager.OnVanillaPrefabsAvailable -= AddItems; } } private static void PatchClone(GameObject prefab, Texture2D albedo, Texture2D emission, bool unfold) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown if ((Object)(object)prefab == (Object)null || (Object)(object)albedo == (Object)null) { Log.LogWarning((object)"clone patch skipped (missing prefab/texture)"); return; } if ((Object)(object)_styleWhite == (Object)null) { _styleWhite = new Texture2D(4, 4, (TextureFormat)4, false); Color32[] array = (Color32[])(object)new Color32[16]; for (int i = 0; i < 16; i++) { array[i] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue); } _styleWhite.SetPixels32(array); _styleWhite.Apply(); } int num = 0; Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null); if (unfold && (Object)(object)val2 != (Object)null && (Object)(object)val2.sharedMesh != (Object)null) { val2.sharedMesh = UnfoldMesh(val2.sharedMesh); } Material[] sharedMaterials = val.sharedMaterials; for (int k = 0; k < sharedMaterials.Length; k++) { if (!((Object)(object)sharedMaterials[k] == (Object)null)) { sharedMaterials[k] = new Material(sharedMaterials[k]); Patch(sharedMaterials[k], albedo, emission); num++; } } val.sharedMaterials = sharedMaterials; } Log.LogInfo((object)$"{((Object)prefab).name}: patched {num} material instance(s)"); } public static void OnCapeEquipped(VisEquipment __instance, bool __result, int hash) { if (__result && !((Object)(object)Instance == (Object)null) && hash == _capeHash) { ((MonoBehaviour)Instance).StartCoroutine(FixWornCape(__instance)); } } internal static Texture2D LoadTex(string file) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown string text = Path.Combine(PluginDir, file); if (!File.Exists(text)) { Log.LogWarning((object)("texture missing: " + text)); return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, false); byte[] array = File.ReadAllBytes(text); MethodInfo method = typeof(ImageConversion).GetMethod("LoadImage", new Type[3] { typeof(Texture2D), typeof(byte[]), typeof(bool) }); if (method == null || !(bool)method.Invoke(null, new object[3] { val, array, false })) { Log.LogError((object)("LoadImage failed for " + file)); return null; } ((Texture)val).wrapMode = (TextureWrapMode)1; Log.LogInfo((object)$"loaded {file}: {((Texture)val).width}x{((Texture)val).height}"); return val; } internal static Mesh UnfoldMesh(Mesh src) { if ((Object)(object)_unfolded != (Object)null) { return _unfolded; } Mesh val = Object.Instantiate<Mesh>(src); ((Object)val).name = ((Object)src).name + "_lords"; _fixedMeshes.Add(((Object)val).GetInstanceID()); if (TryUnfold(val)) { _unfolded = val; } return _unfolded ?? src; } internal static bool TryUnfold(Mesh m) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: 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_01b5: 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_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_010d: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) Vector3[] vertices = m.vertices; Vector2[] uv = m.uv; Dictionary<long, List<int>> dictionary = new Dictionary<long, List<int>>(); for (int i = 0; i < uv.Length; i++) { if (!(uv[i].x >= 0.228f)) { long key = (long)Mathf.Round(uv[i].x * 2000f) * 100000 + (long)Mathf.Round(uv[i].y * 2000f); if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new List<int>()); } value.Add(i); } } Vector3 val = Vector3.zero; List<KeyValuePair<int, int>> list2 = new List<KeyValuePair<int, int>>(); foreach (List<int> value3 in dictionary.Values) { for (int j = 0; j < value3.Count; j++) { for (int k = j + 1; k < value3.Count; k++) { Vector3 val2 = vertices[value3[j]] - vertices[value3[k]]; if (((Vector3)(ref val2)).sqrMagnitude > 1E-14f) { val += new Vector3(Mathf.Abs(val2.x), Mathf.Abs(val2.y), Mathf.Abs(val2.z)); list2.Add(new KeyValuePair<int, int>(value3[j], value3[k])); } } } } int num = 0; if (val.y > val.x && val.y >= val.z) { num = 1; } else if (val.z > val.x && val.z >= val.y) { num = 2; } float num2 = 0f; foreach (KeyValuePair<int, int> item in list2) { num2 += (((Vector3)(ref vertices[item.Key]))[num] + ((Vector3)(ref vertices[item.Value]))[num]) * 0.5f; } if (list2.Count > 0) { num2 /= (float)list2.Count; } if (list2.Count < 4) { Log.LogInfo((object)$"mesh '{((Object)m).name}' ({uv.Length} verts): no mirrored panel found (pairs={list2.Count}) - skipping"); return false; } bool value2 = FlipBack.Value; int num3 = 0; for (int l = 0; l < uv.Length; l++) { if (uv[l].x < 0.228f) { float num4 = ((Vector3)(ref vertices[l]))[num] - num2; if (value2 ? (num4 > 0f) : (num4 < 0f)) { uv[l].x = 0.454f - uv[l].x; num3++; } } else { uv[l].x += 0.5f; } } try { m.uv = uv; } catch (Exception ex) { Log.LogWarning((object)("uv write failed on '" + ((Object)m).name + "': " + ex.Message)); return false; } Log.LogInfo((object)$"unfold '{((Object)m).name}': axis={num} spread={val} mid={num2:F5} pairs={list2.Count} reflected={num3}/{uv.Length}"); return true; } internal static IEnumerator FixWornCape(VisEquipment ve) { FieldInfo fi = AccessTools.Field(typeof(VisEquipment), "m_capeItemInstances"); if (fi == null) { Log.LogWarning((object)"m_capeItemInstances not found"); yield break; } for (float t = 0f; t < 6f; t += 0.25f) { if ((Object)(object)ve == (Object)null) { break; } if (fi.GetValue(ve) is List<GameObject> list) { foreach (GameObject item in list) { if ((Object)(object)item == (Object)null) { continue; } SkinnedMeshRenderer[] componentsInChildren = item.GetComponentsInChildren<SkinnedMeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Mesh sharedMesh = componentsInChildren[i].sharedMesh; if (!((Object)(object)sharedMesh == (Object)null) && _fixedMeshes.Add(((Object)sharedMesh).GetInstanceID())) { Log.LogInfo((object)$"worn cape mesh: '{((Object)sharedMesh).name}' id={((Object)sharedMesh).GetInstanceID()} verts={sharedMesh.vertexCount} readable={sharedMesh.isReadable}"); TryUnfold(sharedMesh); } } } } yield return (object)new WaitForSeconds(0.25f); } } private static bool Patch(Material mat, Texture2D albedo, Texture2D emission) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)mat == (Object)null) { return false; } if (!_done.Add(((Object)mat).GetInstanceID())) { return false; } if (mat.HasProperty("_MainTex")) { mat.SetTexture("_MainTex", (Texture)(object)albedo); } if (mat.HasProperty("_Color")) { mat.SetColor("_Color", Color.white); } if (mat.HasProperty("_UseStyles")) { mat.SetFloat("_UseStyles", 0f); } if (mat.HasProperty("_Style")) { mat.SetFloat("_Style", 0f); } if (mat.HasProperty("_StyleTex")) { mat.SetTexture("_StyleTex", (Texture)(object)_styleWhite); } string[] array = new string[3] { "_USESTYLES_ON", "USE_STYLES", "_STYLES" }; foreach (string text in array) { mat.DisableKeyword(text); } if (mat.HasProperty("_Hue")) { mat.SetFloat("_Hue", 0f); } if (mat.HasProperty("_Saturation")) { mat.SetFloat("_Saturation", 0f); } if (mat.HasProperty("_Value")) { mat.SetFloat("_Value", 0f); } if ((Object)(object)emission != (Object)null) { Color val = Color.red * EmissionIntensity.Value; if (mat.HasProperty("_EmissionMap")) { mat.SetTexture("_EmissionMap", (Texture)(object)emission); } if (mat.HasProperty("_EmissiveTex")) { mat.SetTexture("_EmissiveTex", (Texture)(object)emission); } if (mat.HasProperty("_EmissionColor")) { mat.SetColor("_EmissionColor", val); } if (mat.HasProperty("_EmissiveColor")) { mat.SetColor("_EmissiveColor", val); } mat.EnableKeyword("_EMISSION"); } return true; } } }