Decompiled source of CotLSpineLoader v1.1.0
plugins/CultTweaker/CultTweaker.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using COTL_API.CustomEnemy; using COTL_API.CustomFollowerCommand; using COTL_API.CustomInventory; using COTL_API.CustomSkins; using COTL_API.CustomStructures; using COTL_API.CustomTarotCard; using COTL_API.Guid; using COTL_API.Helpers; using CustomSpineLoader.APIHelper; using CustomSpineLoader.Commands; using CustomSpineLoader.SpineLoaderHelper; using HarmonyLib; using Lamb.UI; using Lamb.UI.DeathScreen; using MMBiomeGeneration; using MMRoomGeneration; using MMTools; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Pathfinding; using Spine; using Spine.Unity; using Spine.Unity.AttachmentTools; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("CultTweaker")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+6ba6dd7a71f3b2d20d3065563c95237c021ae4aa")] [assembly: AssemblyProduct("CultTweaker")] [assembly: AssemblyTitle("CultTweaker")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 CustomSpineLoader { [BepInPlugin("InfernoDragon0.cotl.CustomSpineLoader", "CultTweaker", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [HarmonyPatch] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "InfernoDragon0.cotl.CustomSpineLoader"; public const string PluginName = "CultTweaker"; public const string PluginVer = "1.1.0"; internal static ManualLogSource Log; internal static readonly Harmony Harmony = new Harmony("InfernoDragon0.cotl.CustomSpineLoader"); internal static string PluginPath; public static ConfigEntry<int> CurrentFleeceIndexP1 { get; set; } public static ConfigEntry<int> CurrentFleeceIndexP2 { get; set; } public static ConfigEntry<bool> DebugDumpFollowerSpineAtlas { get; set; } public static ConfigEntry<bool> FleeceCyclingEnabled { get; set; } private void Awake() { //IL_003d: 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_016b: 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_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; PluginPath = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); PlayerSpineLoader.LoadAllPlayerSpines(); Log.LogInfo((object)"Cult Tweaker is loading! For more information or templates on how to use this mod, go to the NexusMods page!"); CustomFollowerCommandManager.Add((CustomFollowerCommand)(object)new CustomColorCommand()); StructureBuildingOverrideHelper.LoadBuildingOverrides(); Log.LogInfo((object)"Loading Custom Items..."); CustomItemLoader.LoadAllCustomItems(); Log.LogInfo((object)"Loading Custom Meals..."); CustomMealLoader.LoadAllCustomMeals(); Log.LogInfo((object)"Loading Custom Tarots..."); CustomTarotLoader.LoadAllCustomTarots(); Log.LogInfo((object)"Loading Custom Structures..."); CustomStructureLoader.LoadAllCustomStructures(); Log.LogInfo((object)"Loading Custom Follower Overrides..."); FollowerSpineLoader.LoadAllNonSpineSkins(); CurrentFleeceIndexP1 = ((BaseUnityPlugin)this).Config.Bind<int>("Fleece", "CurrentFleeceIndexP1", -1, "Current Fleece Index for Player 1"); CurrentFleeceIndexP2 = ((BaseUnityPlugin)this).Config.Bind<int>("Fleece", "CurrentFleeceIndexP2", -1, "Current Fleece Index for Player 2"); DebugDumpFollowerSpineAtlas = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DumpFollowerSpineAtlas", false, "If true, will dump the follower spine slots to a json file. May impact performance when enabled. Ensure followerSlots.json is not present before dumping."); FleeceCyclingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Fleece", "FleeceCyclingEnabled", true, "Enable Fleece Cycling for all players."); PlayerSpineLoader.currentFleeceIndexP1 = CurrentFleeceIndexP1.Value; PlayerSpineLoader.currentFleeceIndexP2 = CurrentFleeceIndexP2.Value; CustomDungeon customDungeon = new CustomDungeon(); BaseCustomEnemy baseCustomEnemy = new BaseCustomEnemy(); Enemy val = CustomEnemyManager.Add((CustomEnemy)(object)baseCustomEnemy); ((MonoBehaviour)this).StartCoroutine(CustomEnemyManager.BuildEnemyPrefab((CustomEnemy)(object)baseCustomEnemy)); customDungeon.NormalEnemyList.Add(val); Log.LogInfo((object)$"Custom Test Enemy added with type {val}, now size is {customDungeon.NormalEnemyList.Count}"); CustomDungeonManager.Add(customDungeon); } public void Update() { if (Input.GetKeyDown((KeyCode)290)) { Log.LogInfo((object)("Toggling Fleece Cycling to " + !FleeceCyclingEnabled.Value)); FleeceCyclingEnabled.Value = !FleeceCyclingEnabled.Value; if (!FleeceCyclingEnabled.Value && (Object)(object)PlayerFarming.Instance != (Object)null) { if (CoopManager.CoopActive) { PlayerFarming.players[1].SetSkin(); } PlayerFarming.Instance.SetSkin(); } else { TestApplySpineOverride(0, cycle: false); } } if (Input.GetKeyDown((KeyCode)288)) { Log.LogInfo((object)"F7 Pressed - Fleece Cycle Player 1"); TestApplySpineOverride(); } if (Input.GetKeyDown((KeyCode)289)) { Log.LogInfo((object)"F8 Pressed - Fleece Cycle Player 2"); TestApplySpineOverride(1); } if (Input.GetKeyDown((KeyCode)286)) { Log.LogInfo((object)"F5 Pressed - Test Custom Dungeon"); CustomDungeonManager.CustomDungeonList.Values.ElementAt(0).EnterDungeon(); } } private void TestApplySpineOverride(int playerID = 0, bool cycle = true) { if (!FleeceCyclingEnabled.Value) { Log.LogWarning((object)"Fleece Cycling is disabled, Press F9 to enable first!"); return; } int num = -1; if (cycle) { num = PlayerSpineLoader.CycleNextFleece(playerID); } else { if (1 == 0) { } int num2 = playerID switch { 0 => CurrentFleeceIndexP1.Value, 1 => CurrentFleeceIndexP2.Value, _ => -1, }; if (1 == 0) { } num = num2; } string text = PlayerSpineLoader.FleeceRotation[num]; Log.LogInfo((object)("Applying fleece skin: " + text)); SkeletonAnimation spine = PlayerFarming.Instance.Spine; if (playerID >= 1) { if (!CoopManager.CoopActive) { Log.LogInfo((object)"Coop not active, no fleece cycling"); return; } spine = PlayerFarming.players[1].Spine; CurrentFleeceIndexP2.Value = num; } else { CurrentFleeceIndexP1.Value = num; } Skin val; if (text.Contains("CultTweaker_")) { string[] array = text.Split(new char[1] { '_' }, 3); if (array.Length < 3) { Log.LogWarning((object)("Invalid custom fleece skin name: " + text)); return; } string text2 = array[1]; if (!PlayerSpineLoader.FleeceCyclingSpines.ContainsKey(text2)) { Log.LogWarning((object)("Invalid spine skin name: " + text + " for spine: " + text2)); return; } val = PlayerSpineLoader.FleeceCyclingSpines[text2].Item1.skeletonData.FindSkin(array[2]); if (val == null) { Log.LogWarning((object)("Defaulting to default as Custom Fleece skin not found: " + text)); val = ((SkeletonRenderer)spine).Skeleton.Data.FindSkin("Lamb"); } } else { val = ((SkeletonRenderer)spine).Skeleton.Data.FindSkin(text); } if ((Object)(object)spine == (Object)null || val == null) { Log.LogInfo((object)("Lamb skin was null after cycling, an error occurred! at skin name " + text)); return; } Skin skin = ((SkeletonRenderer)spine).Skeleton.Skin; foreach (var fleeceOverrideSlot in PlayerSpineLoader.FleeceOverrideSlots) { int num3 = ((SkeletonRenderer)spine).Skeleton.FindSlotIndex(fleeceOverrideSlot.Item1); Attachment attachment = val.GetAttachment(num3, fleeceOverrideSlot.Item2); Log.LogInfo((object)string.Format("Slot {0} index is {1}, attachment {2}", fleeceOverrideSlot.Item1, num3, (attachment != null) ? "found" : "not found")); if (attachment == null) { skin.RemoveAttachment(num3, fleeceOverrideSlot.Item2); } else { skin.SetAttachment(num3, fleeceOverrideSlot.Item2, attachment); } Log.LogInfo((object)("Applied " + fleeceOverrideSlot.Item2 + " attachment to current skin.")); } Log.LogInfo((object)("Applied" + text + " attachment to current skin.")); ((SkeletonRenderer)spine).Skeleton.SetSlotsToSetupPose(); spine.Update(0f, false); } private void OnEnable() { Harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded CultTweaker!"); } private void OnDisable() { Harmony.UnpatchSelf(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Unloaded CultTweaker!"); } } } namespace CustomSpineLoader.SpineLoaderHelper { public class CustomColorHelper { public static Dictionary<int, CustomFollowerColor> CustomColors { get; private set; } = new Dictionary<int, CustomFollowerColor>(); public static Dictionary<int, CustomFollowerSpineSkin> CustomFollowerSkinConfigs { get; private set; } = new Dictionary<int, CustomFollowerSpineSkin>(); public static void LoadCustomColors(int saveSlot) { if (!File.Exists(Path.Combine(Plugin.PluginPath, $"CustomColors{saveSlot}.json"))) { Plugin.Log.LogInfo((object)("Creating new CustomColors.json file for save slot " + saveSlot + ".")); string contents = JsonConvert.SerializeObject((object)CustomColors, (Formatting)1); File.WriteAllText(Path.Combine(Plugin.PluginPath, $"CustomColors{saveSlot}.json"), contents); } else { string text = File.ReadAllText(Path.Combine(Plugin.PluginPath, $"CustomColors{saveSlot}.json")); CustomColors = JsonConvert.DeserializeObject<Dictionary<int, CustomFollowerColor>>(text) ?? new Dictionary<int, CustomFollowerColor>(); } } public static void SaveCustomColors() { string contents = JsonConvert.SerializeObject((object)CustomColors, (Formatting)1); File.WriteAllText(Path.Combine(Plugin.PluginPath, $"CustomColors{SaveAndLoad.SAVE_SLOT}.json"), contents); Plugin.Log.LogInfo((object)"Saved custom colors"); } public static CustomFollowerColor GetCustomColor(int id) { CustomFollowerColor value; return CustomColors.TryGetValue(id, out value) ? value : null; } public static float GetCustomScale(int id) { CustomFollowerColor value; return CustomColors.TryGetValue(id, out value) ? CustomColors[id].scale : (-1f); } public static void SetCustomColor(int id, float r, float g, float b, float a, float scale = 1f) { CustomFollowerColor value = new CustomFollowerColor(id, r, g, b, a, scale); CustomColors[id] = value; Plugin.Log.LogInfo((object)$"Set custom color for follower {id} to ({r}, {g}, {b}, {a}) with scale {scale}"); } public static void SetCustomCostume(int id, bool enabled, int FollowerClothingType, int FollowerSpecialType, int FollowerHatType, int FollowerOutfitType, int FollowerNecklaceType) { if (CustomColors.ContainsKey(id)) { CustomColors[id].CustomFollowerCostume = enabled; CustomColors[id].FollowerClothingType = FollowerClothingType; CustomColors[id].FollowerSpecialType = FollowerSpecialType; CustomColors[id].FollowerHatType = FollowerHatType; CustomColors[id].FollowerOutfitType = FollowerOutfitType; CustomColors[id].FollowerNecklaceType = FollowerNecklaceType; Plugin.Log.LogInfo((object)$"Set custom costume for follower {id} to ClothingType: {FollowerClothingType}, SpecialType: {FollowerSpecialType}, HatType: {FollowerHatType}, OutfitType: {FollowerOutfitType}"); } else { Plugin.Log.LogWarning((object)("Tried to set custom costume for follower " + id + " but no custom color exists. Enable Customization first.")); } } public static void RemoveCustomColor(int id) { if (CustomColors.ContainsKey(id)) { CustomColors.Remove(id); Plugin.Log.LogInfo((object)$"Removed custom color for follower {id}"); } } } [Serializable] public class CustomFollowerColor { public bool CustomFollowerCostume; public float scale; public int FollowerId { get; set; } public float R { get; set; } public float G { get; set; } public float B { get; set; } public float A { get; set; } public int FollowerClothingType { get; set; } public int FollowerSpecialType { get; set; } public int FollowerHatType { get; set; } public int FollowerOutfitType { get; set; } public int FollowerNecklaceType { get; set; } public CustomFollowerColor(int id, float r, float g, float b, float a, float scale = 1f) { FollowerId = id; R = Mathf.Clamp(r, 0f, 1f); G = Mathf.Clamp(g, 0f, 1f); B = Mathf.Clamp(b, 0f, 1f); A = Mathf.Clamp(a, 0f, 1f); CustomFollowerCostume = false; FollowerClothingType = 0; FollowerSpecialType = 0; FollowerHatType = 0; FollowerOutfitType = 0; FollowerNecklaceType = 0; this.scale = Mathf.Clamp(scale, 0.1f, 5f); base..ctor(); } } [Serializable] public class CustomFollowerSpineSkin { public string SpineName; public List<string> SkinsApplied; } public class FollowerSpineLoader { public static Dictionary<string, List<Tuple<int, string, Texture2D, FollowerSkinPartConfig>>> FollowerSkinOverrides = new Dictionary<string, List<Tuple<int, string, Texture2D, FollowerSkinPartConfig>>>(); public static Dictionary<string, List<SlotsAndColours>> FollowerSlotColors = new Dictionary<string, List<SlotsAndColours>>(); public static Dictionary<string, Skin> CustomFollowerSkins = new Dictionary<string, Skin>(); public static void LoadAllFollowerSpines(Material material = null) { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Expected O, but got Unknown //IL_0235: Unknown result type (might be due to invalid IL or missing references) string path = Path.Combine(Plugin.PluginPath, "FollowerSpines"); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } string[] directories = Directory.GetDirectories(path); string[] array = directories; foreach (string path2 in array) { string fileName = Path.GetFileName(path2); string[] array2 = (from x in Directory.GetFiles(path2, "*.json", SearchOption.TopDirectoryOnly) where !x.Contains("config") select x).ToArray(); string[] files = Directory.GetFiles(path2, "*.png", SearchOption.TopDirectoryOnly); string[] files2 = Directory.GetFiles(path2, "*.atlas", SearchOption.TopDirectoryOnly); string[] files3 = Directory.GetFiles(path2, "config.json", SearchOption.TopDirectoryOnly); List<string> list = new List<string>(1) { "Cat" }; string[] array3 = new string[0]; if (files3.Length != 0) { TextAsset val = new TextAsset(File.ReadAllText(files3[0])); FollowerSpineConfig followerSpineConfig = JsonConvert.DeserializeObject<FollowerSpineConfig>(val.text); if (followerSpineConfig != null) { list = followerSpineConfig.DefaultSkin; array3 = followerSpineConfig.Skins; Plugin.Log.LogInfo((object)$"Using default skin: {list}"); Plugin.Log.LogInfo((object)("Using skin list: " + string.Join(", ", array3))); } } if (array2.Length != 0 && files.Length != 0 && files2.Length != 0) { Plugin.Log.LogInfo((object)("Reading atlas from " + files2[0])); TextAsset val2 = new TextAsset(File.ReadAllText(files2[0])); Plugin.Log.LogInfo((object)("Reading skeleton from " + array2[0])); TextAsset val3 = new TextAsset(File.ReadAllText(array2[0])); Texture2D[] array4 = (Texture2D[])(object)new Texture2D[files.Length]; string[] array5 = files; foreach (string text in array5) { Plugin.Log.LogInfo((object)("Reading texture from " + text)); Texture2D val4 = TextureHelper.CreateTextureFromPath(text, (TextureFormat)4, false, false); ((Object)val4).name = Path.GetFileNameWithoutExtension(text); array4[Array.IndexOf(files, text)] = val4; } Material val5 = (Material)(((object)material) ?? ((object)new Material(Shader.Find("Spine/Skeleton")))); SpineAtlasAsset val6 = SpineAtlasAsset.CreateRuntimeInstance(val2, array4, val5, true); SkeletonDataAsset val7 = SkeletonDataAsset.CreateRuntimeInstance(val3, (AtlasAssetBase)(object)val6, true, 0.005f); Plugin.Log.LogInfo((object)("Creating skeleton for " + fileName)); Plugin.Log.LogInfo((object)("Using material name " + ((Object)val5).name)); CustomSkinManager.AddFollowerSpine(fileName, val7); for (int k = 0; k < list.Count; k++) { string text2 = list[k]; } } else { Plugin.Log.LogInfo((object)("Failed to load follower skin " + fileName + ", ensure that the folder contains at least one of each .json, .png and .atlas file.")); } } } public static void LoadAllNonSpineSkins() { //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown string path = Path.Combine(Plugin.PluginPath, "FollowerSkins"); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } string[] directories = Directory.GetDirectories(path); string[] array = directories; foreach (string path2 in array) { string fileName = Path.GetFileName(path2); Plugin.Log.LogInfo((object)("Loading Follower Override Skin: " + fileName)); List<string> list = new List<string>(); string[] directories2 = Directory.GetDirectories(path2); foreach (string text in directories2) { Plugin.Log.LogInfo((object)("Creating Variant: " + Path.GetFileName(text))); string[] files = Directory.GetFiles(text, "*.png", SearchOption.TopDirectoryOnly); string[] files2 = Directory.GetFiles(text, "config.json", SearchOption.TopDirectoryOnly); Plugin.Log.LogInfo((object)("Variant has a total of " + files.Length + " overrides.")); if (files2.Length != 0) { TextAsset val = new TextAsset(File.ReadAllText(files2[0])); FollowerSkinConfig followerSkinConfig = JsonConvert.DeserializeObject<FollowerSkinConfig>(val.text); if (followerSkinConfig == null) { Plugin.Log.LogWarning((object)("Failed to deserialize config.json for follower skin " + fileName + " variant: " + text + ", please check syntax.")); continue; } Plugin.Log.LogInfo((object)("Variant will be created using base skin: " + followerSkinConfig.OverrideBaseSkin)); List<Tuple<int, string, Texture2D, FollowerSkinPartConfig>> list2 = new List<Tuple<int, string, Texture2D, FollowerSkinPartConfig>>(); string[] array2 = files; foreach (string text2 in array2) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text2); if (!followerSkinConfig.PartConfigs.ContainsKey(fileNameWithoutExtension)) { Plugin.Log.LogWarning((object)(fileName + " variant: " + text + " - " + fileNameWithoutExtension + " is not registered as a part in the config.json! Ignoring...")); } else { FollowerSkinPartConfig followerSkinPartConfig = followerSkinConfig.PartConfigs[fileNameWithoutExtension]; Plugin.Log.LogInfo((object)("Reading texture from " + Path.GetFileName(text2))); Texture2D val2 = TextureHelper.CreateTextureFromPath(text2, (TextureFormat)4, false, false); ((Object)val2).name = Path.GetFileNameWithoutExtension(text2); list2.Add(new Tuple<int, string, Texture2D, FollowerSkinPartConfig>(followerSkinPartConfig.SlotIndex, followerSkinPartConfig.PartName, val2, followerSkinPartConfig)); } } Plugin.Log.LogInfo((object)(fileName + " variant " + text + " has a total of " + files.Length + " and " + list2.Count + " were registered successfully.")); FollowerSkinOverrides.Add(fileName + "_" + Path.GetFileName(text), list2); FollowerSlotColors.Add(fileName + "_" + Path.GetFileName(text), BuildColorsByIndex(followerSkinConfig)); string text3 = BuildCustomOverrideSkin(fileName + "_" + Path.GetFileName(text), followerSkinConfig.OverrideBaseSkin); if (text3 != null) { list.Add(text3); } } else { Plugin.Log.LogWarning((object)("No config.json found for follower skin " + fileName + " variant: " + text + ", please create one.")); } } if (list.Count > 0) { Plugin.Log.LogInfo((object)("Creating Follower Skin " + fileName + " with " + list.Count + " variant(s).")); CreateNewFollowerType(list[0], list, FollowerSlotColors[list[0]]); } } } public static string BuildCustomOverrideSkin(string skinVariantName, string baseSkinName) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Expected O, but got Unknown //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Expected O, but got Unknown if (CustomFollowerSkins.ContainsKey(skinVariantName)) { Plugin.Log.LogWarning((object)(skinVariantName + " has already been built!")); return null; } List<Tuple<int, string, Texture2D, FollowerSkinPartConfig>> list = FollowerSkinOverrides[skinVariantName]; Skin val = ((SkeletonRenderer)WorshipperData.Instance.SkeletonData).Skeleton.Data.FindSkin(baseSkinName); if (val == null) { Plugin.Log.LogWarning((object)("Could not find base skin " + baseSkinName + " for variant " + skinVariantName + "! Defaulting to Cat.")); val = ((SkeletonRenderer)WorshipperData.Instance.SkeletonData).Skeleton.Data.FindSkin("Cat"); } Skin finalSkin = new Skin(skinVariantName); Plugin.Log.LogInfo((object)$"Attempting to build skin with {list.Count} override parts for variant {skinVariantName}"); val.Attachments.ToList().ForEach(delegate(SkinEntry attachment) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) finalSkin.SetAttachment(((SkinEntry)(ref attachment)).SlotIndex, ((SkinEntry)(ref attachment)).Name, attachment.attachment.Copy()); }); ((IEnumerable<BoneData>)val.Bones).ToList().ForEach((Action<BoneData>)finalSkin.Bones.Add); ((IEnumerable<ConstraintData>)val.Constraints).ToList().ForEach((Action<ConstraintData>)finalSkin.Constraints.Add); foreach (Tuple<int, string, Texture2D, FollowerSkinPartConfig> item in list) { try { ((Object)item.Item3).name = skinVariantName + "_" + item.Item2; Material val2 = new Material(Shader.Find("Spine/Skeleton")) { mainTexture = (Texture)(object)item.Item3 }; Material[] array = (Material[])(object)new Material[1] { val2 }; SpineAtlasAsset val3 = SpineAtlasAsset.CreateRuntimeInstance(GenerateAtlasText(skinVariantName + "_" + item.Item2, item.Item2, ((Texture)item.Item3).width.ToString(), ((Texture)item.Item3).height.ToString()), array, true); Attachment attachment2 = val.GetAttachment(item.Item1, item.Item2); if (attachment2 == null) { continue; } attachment2 = attachment2.Copy(); float offsetX = item.Item4.OffsetX; float offsetY = item.Item4.OffsetY; float rotation = item.Item4.Rotation; float scaleX = item.Item4.ScaleX; float scaleY = item.Item4.ScaleY; Attachment val4 = attachment2; Attachment val5 = val4; MeshAttachment val6 = (MeshAttachment)(object)((val5 is MeshAttachment) ? val5 : null); if (val6 == null) { RegionAttachment val7 = (RegionAttachment)(object)((val5 is RegionAttachment) ? val5 : null); if (val7 != null) { ((Attachment)val7).Name = skinVariantName + "_" + item.Item2; ((AtlasAssetBase)val3).GetAtlas().regions[0].name = "Custom" + ((AtlasAssetBase)val3).GetAtlas().regions[0].name; AttachmentRegionExtensions.SetRegion(val7, ((AtlasAssetBase)val3).GetAtlas().regions[0], true); val7.X += offsetX; val7.Y += offsetY; val7.ScaleX = scaleX; val7.ScaleY = scaleY; val7.rotation = rotation; finalSkin.SetAttachment(item.Item1, item.Item2, (Attachment)(object)val7); } else { Plugin.Log.LogWarning((object)("Attachment " + attachment2.Name + " is not a MeshAttachment or RegionAttachment, skipping...")); } } else { float num = 2.1474836E+09f; float num2 = -2.1474836E+09f; float num3 = 2.1474836E+09f; float num4 = -2.1474836E+09f; for (int i = 0; i < ((VertexAttachment)val6).Vertices.Length; i++) { switch (i % 3) { case 0: num3 = Math.Min(num3, ((VertexAttachment)val6).Vertices[i]); num4 = Math.Max(num4, ((VertexAttachment)val6).Vertices[i]); break; case 1: num = Math.Min(num, ((VertexAttachment)val6).Vertices[i]); num2 = Math.Max(num2, ((VertexAttachment)val6).Vertices[i]); break; } } float num5 = num2 - num; float num6 = num4 - num3; float num7 = num + num5 / 2f; float num8 = num3 + num6 / 2f; RegionAttachment val8 = new RegionAttachment(item.Item2); AttachmentRegionExtensions.SetRegion(val8, ((AtlasAssetBase)val3).GetAtlas().regions[0], true); val8.X = num8 - offsetY; val8.Y = num7 - offsetX; val8.rotation = rotation; val8.ScaleX = scaleX; val8.ScaleY = scaleY; val8.Width = num5; val8.Height = num6; finalSkin.SetAttachment(item.Item1, item.Item2, (Attachment)(object)val8); } Plugin.Log.LogInfo((object)("Attached override part " + item.Item2 + " to slot " + item.Item1 + " for skin variant " + skinVariantName)); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to apply override part " + item.Item2 + " to skin variant " + skinVariantName + ": " + ex.Message)); return null; } } Plugin.Log.LogInfo((object)("Successfully created skin variant " + skinVariantName)); Material val9 = default(Material); Texture2D val10 = default(Texture2D); Skin repackedSkin = AtlasUtilities.GetRepackedSkin(finalSkin, skinVariantName, ((SkeletonRenderer)WorshipperData.Instance.SkeletonData).SkeletonDataAsset.atlasAssets[0].PrimaryMaterial, ref val9, ref val10, 1024, 2, (TextureFormat)4, false, true, false, (int[])null, (Texture2D[])null, (TextureFormat[])null, (bool[])null); CustomFollowerSkins.Add(skinVariantName, repackedSkin); DataManager.SetFollowerSkinUnlocked(skinVariantName); return skinVariantName; } public static void CreateNewFollowerType(string name, List<string> variantNames, List<SlotsAndColours> colors, bool hidden = false, bool twitchPremium = false, bool invariant = false) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown List<CharacterSkin> skin = ((IEnumerable<string>)variantNames).Select((Func<string, CharacterSkin>)((string v) => new CharacterSkin { Skin = v })).ToList(); WorshipperData.Instance.Characters.Add(new SkinAndData { Title = name, Skin = skin, SlotAndColours = colors, TwitchPremium = twitchPremium, _hidden = hidden, _dropLocation = (DropLocation)4, _invariant = invariant }); } public static TextAsset GenerateAtlasText(string filename, string name, string width, string height) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(); stringBuilder.AppendLine(filename ?? ""); stringBuilder.AppendLine("size: " + width + ", " + height); stringBuilder.AppendLine("format: RGBA8888"); stringBuilder.AppendLine("filter: Linear,Linear"); stringBuilder.AppendLine("repeat: none"); stringBuilder.AppendLine(name ?? ""); stringBuilder.AppendLine(" rotate: false"); stringBuilder.AppendLine(" xy: 0,0"); stringBuilder.AppendLine(" size: " + width + "," + height); stringBuilder.AppendLine(" orig: " + width + "," + height); stringBuilder.AppendLine(" offset: 0,0"); stringBuilder.AppendLine(" index: -1"); return new TextAsset(stringBuilder.ToString()); } public static List<SlotsAndColours> BuildColorsByIndex(FollowerSkinConfig config) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_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_00b0: Expected O, but got Unknown //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_00d5: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Expected O, but got Unknown //IL_01e3: Expected O, but got Unknown List<FollowerSkinPartConfig> parts = config.PartConfigs.Values.Where((FollowerSkinPartConfig p) => p.ColorChoices?.Any() ?? false).ToList(); int num = parts.Min((FollowerSkinPartConfig p) => p.ColorChoices.Count); if (num == 0) { return new List<SlotsAndColours>(1) { new SlotsAndColours { SlotAndColours = new List<SlotAndColor>(9) { new SlotAndColor("ARM_LEFT_SKIN", new Color(1f, 1f, 1f)), new SlotAndColor("ARM_RIGHT_SKIN", new Color(1f, 1f, 1f)), new SlotAndColor("LEG_LEFT_SKIN", new Color(1f, 1f, 1f)), new SlotAndColor("LEG_RIGHT_SKIN", new Color(1f, 1f, 1f)), new SlotAndColor("Body_Naked", new Color(1f, 1f, 1f)), new SlotAndColor("Body_Naked_Up", new Color(1f, 1f, 1f)), new SlotAndColor("BODY_BTM", new Color(1f, 1f, 1f)), new SlotAndColor("BODY_BTM_UP", new Color(1f, 1f, 1f)), new SlotAndColor("BODY_TOP", new Color(1f, 1f, 1f)) } } }; } return Enumerable.Range(0, num).Select((Func<int, SlotsAndColours>)((int i) => new SlotsAndColours { SlotAndColours = ((IEnumerable<FollowerSkinPartConfig>)parts).Select((Func<FollowerSkinPartConfig, SlotAndColor>)((FollowerSkinPartConfig p) => new SlotAndColor(p.PartName, HexToColor(p.ColorChoices[i])))).ToList() })).ToList(); } public static Color HexToColor(string hex) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); ColorUtility.TryParseHtmlString(hex, ref result); return result; } } public class FollowerSpineConfig { public List<string> DefaultSkin { get; set; } public string[] Skins { get; set; } public bool InitializeWithoutBase { get; set; } = true; } [Serializable] public class FollowerSkinConfig { public string OverrideBaseSkin { get; set; } = "Cat"; public Dictionary<string, FollowerSkinPartConfig> PartConfigs { get; set; } } [Serializable] public class FollowerSkinPartConfig { public int SlotIndex { get; set; } public string PartName { get; set; } public float ScaleX { get; set; } = 1f; public float ScaleY { get; set; } = 1f; public float Rotation { get; set; } = -90f; public float OffsetX { get; set; } = 0f; public float OffsetY { get; set; } = 0f; public List<string> ColorChoices { get; set; } = new List<string>(1) { "#FFF" }; } [Serializable] public class DebugOutputSkin { public int SlotIndex { get; set; } public string PartName { get; set; } } public class PlayerSpineLoader { public static List<string> FleeceRotation = new List<string>(); public static Dictionary<string, Tuple<SkeletonDataAsset, List<string>>> FleeceCyclingSpines = new Dictionary<string, Tuple<SkeletonDataAsset, List<string>>>(); public static int currentFleeceIndexP1 = -1; public static int currentFleeceIndexP2 = -1; public static string currentFleeceSpineNameP1 = ""; public static string currentFleeceSpineNameP2 = ""; public static bool LoadedCustomSpines = false; public static bool LoadedFleeceCycling = false; public static List<(string, string)> FleeceOverrideSlots = new List<(string, string)>(14) { ("images/PonchoLeft", "PonchoLeft"), ("images/PonchoRight", "PonchoRight"), ("images/PonchoLeft", "PonchoLeft2"), ("images/PonchoRight", "PonchoRight2"), ("images/PonchoExtra", "PonchoExtra"), ("images/PonchoRightCorner2", "PonchoRightCorner"), ("images/PonchoRightCorner", "PonchoRightCorner"), ("images/PonchoShoulder", "PonchoShoulder"), ("images/PonchoShoulder2", "PonchoShoulder_Right"), ("RopeTopLeft", "images/RopeTopLeft"), ("RopeTopRight", "images/RopeTopRight"), ("images/Rope", "images/Rope"), ("images/Bell", "Bell"), ("images/Body", "Body") }; public static int CycleNextFleece(int playerID) { int num = 0; switch (playerID) { case 0: currentFleeceIndexP1++; if (currentFleeceIndexP1 >= FleeceRotation.Count) { currentFleeceIndexP1 = 0; } num = currentFleeceIndexP1; break; case 1: currentFleeceIndexP2++; if (currentFleeceIndexP2 >= FleeceRotation.Count) { currentFleeceIndexP2 = 0; } num = currentFleeceIndexP2; break; } Plugin.Log.LogInfo((object)("Player " + (playerID + 1) + " cycled to fleece index " + num + " (" + FleeceRotation[num] + ")")); return num; } public static void LoadAllPlayerSpines(Material material = null) { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Expected O, but got Unknown //IL_0258: Unknown result type (might be due to invalid IL or missing references) if (LoadedCustomSpines) { Plugin.Log.LogInfo((object)"Load Player Spines was called again but already loaded!"); return; } string path = Path.Combine(Plugin.PluginPath, "PlayerSkins"); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } string[] directories = Directory.GetDirectories(path); string[] array = directories; foreach (string path2 in array) { string fileName = Path.GetFileName(path2); string[] array2 = (from x in Directory.GetFiles(path2, "*.json", SearchOption.TopDirectoryOnly) where !x.Contains("config") select x).ToArray(); string[] files = Directory.GetFiles(path2, "*.png", SearchOption.TopDirectoryOnly); string[] files2 = Directory.GetFiles(path2, "*.atlas", SearchOption.TopDirectoryOnly); string[] files3 = Directory.GetFiles(path2, "config.json", SearchOption.TopDirectoryOnly); string text = "Lamb"; string[] array3 = new string[0]; bool flag = false; if (files3.Length != 0) { TextAsset val = new TextAsset(File.ReadAllText(files3[0])); PlayerSpineConfig playerSpineConfig = JsonConvert.DeserializeObject<PlayerSpineConfig>(val.text); if (playerSpineConfig != null) { text = playerSpineConfig.DefaultSkin; array3 = playerSpineConfig.Skins; flag = playerSpineConfig.FleeceCyclingOnly; Plugin.Log.LogInfo((object)("Using default skin: " + text)); Plugin.Log.LogInfo((object)("Using skin list: " + string.Join(", ", array3))); } } if (array2.Length != 0 && files.Length != 0 && files2.Length != 0) { Plugin.Log.LogInfo((object)("Reading atlas from " + files2[0])); TextAsset val2 = new TextAsset(File.ReadAllText(files2[0])); Plugin.Log.LogInfo((object)("Reading skeleton from " + array2[0])); TextAsset val3 = new TextAsset(File.ReadAllText(array2[0])); Texture2D[] array4 = (Texture2D[])(object)new Texture2D[files.Length]; string[] array5 = files; foreach (string text2 in array5) { Plugin.Log.LogInfo((object)("Reading texture from " + text2)); Texture2D val4 = TextureHelper.CreateTextureFromPath(text2, (TextureFormat)4, false, false); ((Object)val4).name = Path.GetFileNameWithoutExtension(text2); array4[Array.IndexOf(files, text2)] = val4; } Material val5 = (Material)(((object)material) ?? ((object)new Material(Shader.Find("Spine/Skeleton")))); SpineAtlasAsset val6 = SpineAtlasAsset.CreateRuntimeInstance(val2, array4, val5, true); SkeletonDataAsset val7 = SkeletonDataAsset.CreateRuntimeInstance(val3, (AtlasAssetBase)(object)val6, true, 0.005f); Plugin.Log.LogInfo((object)("Creating skeleton for " + fileName)); Plugin.Log.LogInfo((object)("Using material name " + ((Object)val5).name)); if (flag) { Plugin.Log.LogInfo((object)("Skin: " + fileName + " is added as a fleece cycle skin.")); FleeceCyclingSpines.Add(fileName, new Tuple<SkeletonDataAsset, List<string>>(val7, array3.ToList())); } else { CustomSkinManager.AddPlayerSpine(fileName, val7, array3.ToList()); CustomSkinManager.ChangeSelectedPlayerSpine(fileName + "/" + text, 0); } } else { Plugin.Log.LogInfo((object)("Failed to load player skin " + fileName + ", ensure that the folder contains at least one of each .json, .png and .atlas file.")); } } LoadedCustomSpines = true; } } public class PlayerSpineConfig { public string DefaultSkin { get; set; } public string[] Skins { get; set; } public bool FleeceCyclingOnly { get; set; } = false; } public class StructureBuildingOverrideHelper { public static Dictionary<string, List<StructureBuildingOverride>> StructureBuildingOverrides { get; private set; } = new Dictionary<string, List<StructureBuildingOverride>>(); public static void LoadBuildingOverrides() { if (!Directory.Exists(Path.Combine(Plugin.PluginPath, "BuildingOverrides"))) { Directory.CreateDirectory(Path.Combine(Plugin.PluginPath, "BuildingOverrides")); Plugin.Log.LogInfo((object)"Created BuildingOverrides directory."); return; } string[] directories = Directory.GetDirectories(Path.Combine(Plugin.PluginPath, "BuildingOverrides")); foreach (string text in directories) { string name = new DirectoryInfo(text).Name; List<StructureBuildingOverride> list = new List<StructureBuildingOverride>(); if (File.Exists(Path.Combine(text, "config.json"))) { string text2 = File.ReadAllText(Path.Combine(text, "config.json")); try { StructureBuildingOverrideData structureBuildingOverrideData = JsonConvert.DeserializeObject<StructureBuildingOverrideData>(text2) ?? null; if (structureBuildingOverrideData != null && structureBuildingOverrideData.Overrides != null) { list.AddRange(structureBuildingOverrideData.Overrides); } } catch (Exception arg) { Plugin.Log.LogError((object)$"Error loading building override from config.json in {text}: {arg}"); } } if (list.Count > 0) { StructureBuildingOverrides[name] = list; Plugin.Log.LogInfo((object)$"Loaded {list.Count} overrides for building {name}."); } } } public static List<CustomStructureBuildingData> GetOverridesForBuilding(string buildingName) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) List<StructureBuildingOverride> value; List<StructureBuildingOverride> list = (StructureBuildingOverrides.TryGetValue(buildingName, out value) ? value : null); if (list == null) { return null; } List<CustomStructureBuildingData> list2 = new List<CustomStructureBuildingData>(); foreach (StructureBuildingOverride item in list) { CustomStructureBuildingData val = new CustomStructureBuildingData { Offset = item.Offset.ToVector3(), Scale = item.Scale.ToVector3(), Rotation = item.Rotation.ToVector3(), Sprite = TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "BuildingOverrides/" + buildingName + "/" + item.SpriteImageName)) }; list2.Add(val); Plugin.Log.LogInfo((object)$"Custom Spine Loader: Loaded override with sprite {item.SpriteImageName} for building {buildingName}: offset {val.Offset}, scale {val.Scale}, rotation {val.Rotation}."); } return list2; } } [Serializable] public class StructureBuildingOverrideData { public List<StructureBuildingOverride> Overrides = new List<StructureBuildingOverride>(); } [Serializable] public class StructureBuildingOverride { public SerializableVector3 Offset; public SerializableVector3 Scale; public SerializableVector3 Rotation; public string SpriteImageName; } [Serializable] public class SerializableVector3 { public float X; public float Y; public float Z; public Vector3 ToVector3() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(X, Y, Z); } } [Serializable] public class SerializableVector2 { public float X; public float Y; public Vector2 ToVector2() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return new Vector2(X, Y); } } } namespace CustomSpineLoader.Patches { [HarmonyPatch] public class DungeonPatches { public static ConnectionTypes NextRoomConnectionType = (ConnectionTypes)2; public static bool GenCheck = false; [HarmonyPatch(typeof(BiomeGenerator), "OnEnable")] [HarmonyPrefix] private static void BiomeGenerator_OnEnable(BiomeGenerator __instance) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (CustomDungeonManager.CustomDungeonList.ContainsKey(CustomDungeonManager.EnteringCustomDungeon)) { Plugin.Log.LogInfo((object)("Entering Custom Dungeon ONENABLE " + ((object)(FollowerLocation)(ref CustomDungeonManager.EnteringCustomDungeon)).ToString())); __instance.DungeonLocation = CustomDungeonManager.EnteringCustomDungeon; Plugin.Log.LogInfo((object)("Custom Room Count for " + ((object)(FollowerLocation)(ref __instance.DungeonLocation)).ToString() + ": " + CustomDungeonManager.CustomDungeonList[__instance.DungeonLocation].NumRooms)); __instance.NumberOfRooms = CustomDungeonManager.CustomDungeonList[__instance.DungeonLocation].NumRooms; CustomDungeonManager.EnteringCustomDungeon = (FollowerLocation)(-1); } else { Plugin.Log.LogInfo((object)("Not a custom dungeon, using default dungeon for " + ((object)(FollowerLocation)(ref __instance.DungeonLocation)).ToString())); } } [HarmonyPatch(typeof(GameManager), "IsDungeon")] [HarmonyPrefix] private static bool GameManager_IsDungeon(GameManager __instance, FollowerLocation location, ref bool __result) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (!CustomDungeonManager.CustomDungeonList.ContainsKey(location)) { return true; } __result = true; return false; } [HarmonyPatch(typeof(Door), "OnTriggerEnter2D")] [HarmonyPrefix] public static bool Door_OnTriggerEnter2D(Door __instance) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)BiomeGenerator.Instance == (Object)null) { return true; } if (!CustomDungeonManager.CustomDungeonList.ContainsKey(BiomeGenerator.Instance.DungeonLocation)) { return true; } if ((int)__instance.ConnectionType == 6) { Plugin.Log.LogInfo((object)("Exit Door Triggered for custom dungeon " + ((object)(FollowerLocation)(ref BiomeGenerator.Instance.DungeonLocation)).ToString())); CustomDungeonManager.CustomDungeonList[BiomeGenerator.Instance.DungeonLocation].ExitDoor(); return false; } Plugin.Log.LogInfo((object)("Entering room type " + ((object)(ConnectionTypes)(ref __instance.ConnectionType)).ToString())); NextRoomConnectionType = __instance.ConnectionType; GenCheck = false; return true; } [HarmonyPatch(typeof(LocationManager), "LocationIsDungeon")] [HarmonyPrefix] public static bool LocationManager_LocationIsDungeon(LocationManager __instance, FollowerLocation location, ref bool __result) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (!CustomDungeonManager.CustomDungeonList.ContainsKey(location)) { return true; } __result = true; return false; } [HarmonyPatch(typeof(HUD_DisplayName), "Play")] [HarmonyPatch(new Type[] { typeof(string), typeof(int), typeof(Positions), typeof(textBlendMode), typeof(int) })] [HarmonyPrefix] public static bool HUD_DisplayName_Play(ref string Name, ref Positions Position, ref textBlendMode blend, ref int winterSeverity) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected I4, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected I4, but got Unknown if ((Object)(object)BiomeGenerator.Instance == (Object)null) { return true; } if (!CustomDungeonManager.CustomDungeonList.ContainsKey(BiomeGenerator.Instance.DungeonLocation)) { return true; } Plugin.Log.LogInfo((object)("Custom Dungeon HUD_DisplayName_Play for " + ((object)(FollowerLocation)(ref BiomeGenerator.Instance.DungeonLocation)).ToString())); CustomDungeon customDungeon = CustomDungeonManager.CustomDungeonList[BiomeGenerator.Instance.DungeonLocation]; Position = (Positions)(int)customDungeon.TitleTextPosition; blend = (textBlendMode)(int)customDungeon.TitleTextBlendMode; winterSeverity = customDungeon.Difficulty; return true; } [HarmonyPatch(typeof(HUD_DisplayName), "Show")] [HarmonyPrefix] public static bool HUD_DisplayName_Show(ref string Name) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)BiomeGenerator.Instance == (Object)null) { return true; } if (!CustomDungeonManager.CustomDungeonList.ContainsKey(BiomeGenerator.Instance.DungeonLocation)) { return true; } Plugin.Log.LogInfo((object)("Custom Dungeon HUD_DisplayName_Show for " + ((object)(FollowerLocation)(ref BiomeGenerator.Instance.DungeonLocation)).ToString())); CustomDungeon customDungeon = CustomDungeonManager.CustomDungeonList[BiomeGenerator.Instance.DungeonLocation]; Name = customDungeon.DungeonName; return true; } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPatch(new Type[] { })] [HarmonyPostfix] public static void GenerateRoom_Generate(GenerateRoom __instance) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_00fc: Expected I4, but got Unknown //IL_0130: 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) if ((Object)(object)BiomeGenerator.Instance == (Object)null || GenCheck || !CustomDungeonManager.CustomDungeonList.ContainsKey(BiomeGenerator.Instance.DungeonLocation)) { return; } GenCheck = true; Plugin.Log.LogInfo((object)("GenerateRoom_Generate for custom dungeon " + ((object)(FollowerLocation)(ref BiomeGenerator.Instance.DungeonLocation)).ToString())); Plugin.Log.LogInfo((object)("Room complete status: " + BiomeGenerator.Instance.CurrentRoom.Completed)); if (!BiomeGenerator.Instance.CurrentRoom.Completed) { ConnectionTypes nextRoomConnectionType = NextRoomConnectionType; ConnectionTypes val = nextRoomConnectionType; switch ((int)val) { case 0: Plugin.Log.LogInfo((object)"False Room Generated"); break; case 1: Plugin.Log.LogInfo((object)"True Room Generated"); CustomDungeonManager.CustomDungeonList[BiomeGenerator.Instance.DungeonLocation].SpawnEnemies(__instance, NextRoomConnectionType); break; case 2: Plugin.Log.LogInfo((object)"Entrance Room Generated"); break; case 3: Plugin.Log.LogInfo((object)"Exit Room Generated"); break; case 4: Plugin.Log.LogInfo((object)"Boss Room Generated"); break; case 5: Plugin.Log.LogInfo((object)"Door Room Generated"); break; case 6: Plugin.Log.LogInfo((object)"NextLayer Room Generated"); break; case 7: Plugin.Log.LogInfo((object)"DungeonFirstRoom Generated"); break; case 8: Plugin.Log.LogInfo((object)"LeaderBoss Room Generated"); break; case 9: Plugin.Log.LogInfo((object)"Tarot Room Generated"); break; case 10: Plugin.Log.LogInfo((object)"WeaponShop Room Generated"); break; case 11: Plugin.Log.LogInfo((object)"RelicShop Room Generated"); break; case 12: Plugin.Log.LogInfo((object)"LoreStoneRoom Generated"); break; default: Plugin.Log.LogInfo((object)"Default Room Generated"); break; } } } } [HarmonyPatch] public class SkinSelectorPatch { [HarmonyPatch(typeof(FollowerInformationBox), "ConfigureImpl")] [HarmonyPostfix] private static void FollowerInformationBox_ConfigureImpl(FollowerInformationBox __instance) { if (FollowerSpineLoader.CustomFollowerSkins.ContainsKey(((FollowerSelectItem)__instance).FollowerInfo.SkinName)) { __instance.FollowerSpine.Skeleton.Skin = FollowerSpineLoader.CustomFollowerSkins[((FollowerSelectItem)__instance).FollowerInfo.SkinName]; } } [HarmonyPatch(typeof(SkeletonData), "FindSkin", new Type[] { typeof(string) })] [HarmonyPostfix] private static void SkeletonData_FindSkin(ref Skin? __result, SkeletonData __instance, string skinName) { if (__result == null && FollowerSpineLoader.CustomFollowerSkins.TryGetValue(skinName, out var value)) { __result = value; DataManager.SetFollowerSkinUnlocked(skinName); } } [HarmonyPatch(typeof(PlayerFarming), "Awake")] [HarmonyPrefix] private static bool PlayerFarming_Awake(PlayerFarming __instance) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) if (!PlayerSpineLoader.LoadedFleeceCycling) { Plugin.Log.LogInfo((object)"Creating Fleece Rotation!"); SkeletonAnimation spine = __instance.Spine; Enumerator<Skin> enumerator = ((SkeletonRenderer)spine).Skeleton.Data.Skins.GetEnumerator(); try { while (enumerator.MoveNext()) { Skin current = enumerator.Current; if (!PlayerSpineLoader.FleeceRotation.Contains(current.Name) && !current.Name.ToLower().Contains("lamb_0") && current.Name.ToLower().Contains("lamb")) { PlayerSpineLoader.FleeceRotation.Add(current.Name); Plugin.Log.LogInfo((object)("Added fleece skin: " + current.Name)); } } } finally { ((IDisposable)enumerator).Dispose(); } if (!PlayerSpineLoader.FleeceRotation.Contains("Goat")) { PlayerSpineLoader.FleeceRotation.Add("Goat"); Plugin.Log.LogInfo((object)"Added fleece skin: Goat"); } if (!PlayerSpineLoader.FleeceRotation.Contains("Snake")) { PlayerSpineLoader.FleeceRotation.Add("Snake"); Plugin.Log.LogInfo((object)"Added fleece skin: Snake"); } if (!PlayerSpineLoader.FleeceRotation.Contains("Owl")) { PlayerSpineLoader.FleeceRotation.Add("Owl"); Plugin.Log.LogInfo((object)"Added fleece skin: Owl"); } foreach (KeyValuePair<string, Tuple<SkeletonDataAsset, List<string>>> fleeceCyclingSpine in PlayerSpineLoader.FleeceCyclingSpines) { string key = fleeceCyclingSpine.Key; foreach (string item in fleeceCyclingSpine.Value.Item2) { string text = "CultTweaker_" + key + "_" + item; if (!PlayerSpineLoader.FleeceRotation.Contains(text)) { PlayerSpineLoader.FleeceRotation.Add(text); Plugin.Log.LogInfo((object)("Added custom fleece skin: " + text)); } } } PlayerSpineLoader.LoadedFleeceCycling = true; } if (!PlayerSpineLoader.LoadedCustomSpines) { Plugin.Log.LogInfo((object)"PlayerFarming Awake called, checking for custom spines..."); Material primaryMaterial = ((SkeletonRenderer)__instance.Spine).skeletonDataAsset.atlasAssets[0].PrimaryMaterial; Plugin.Log.LogInfo((object)("Test result is " + ((Object)primaryMaterial).name)); Plugin.Log.LogInfo((object)("Test shader is " + ((Object)primaryMaterial.shader).name)); primaryMaterial.SetTextureScale("_EmissionMap", new Vector2(0f, 0f)); PlayerSpineLoader.LoadAllPlayerSpines(primaryMaterial); } return true; } [HarmonyPatch(typeof(PlayerFarming), "SetSkin", new Type[] { typeof(bool) })] [HarmonyPostfix] private static void PlayerFarming_SetSkin(ref Skin __result, PlayerFarming __instance, bool BlackAndWhite) { if (!Plugin.FleeceCyclingEnabled.Value) { return; } int num = -1; string text = ""; if (CoopManager.CoopActive && __instance.playerID == 1) { num = PlayerSpineLoader.currentFleeceIndexP2; Plugin.Log.LogInfo((object)("Applying fleece skin for Player 2: " + text)); } else { num = PlayerSpineLoader.currentFleeceIndexP1; } if (num == -1) { Plugin.Log.LogInfo((object)"No fleece skin to apply."); return; } if (num >= PlayerSpineLoader.FleeceRotation.Count) { Plugin.Log.LogInfo((object)"Fleece skin index out of range. Cycle with F7 or F8 to fix."); return; } text = PlayerSpineLoader.FleeceRotation[num]; Plugin.Log.LogInfo((object)("Applying fleece skin: " + text)); SkeletonAnimation spine = __instance.Spine; Skin val; if (text.Contains("CultTweaker_")) { string[] array = text.Split(new char[1] { '_' }, 3); if (array.Length < 3) { Plugin.Log.LogWarning((object)("Invalid custom fleece skin name: " + text)); return; } string text2 = array[1]; if (!PlayerSpineLoader.FleeceCyclingSpines.ContainsKey(text2)) { Plugin.Log.LogWarning((object)("Invalid spine skin name: " + text + " for spine: " + text2)); return; } val = PlayerSpineLoader.FleeceCyclingSpines[text2].Item1.skeletonData.FindSkin(array[2]); if (val == null) { Plugin.Log.LogWarning((object)("Defaulting to default as Custom Fleece skin not found: " + text)); val = ((SkeletonRenderer)spine).Skeleton.Data.FindSkin("Lamb"); } } else { val = ((SkeletonRenderer)spine).Skeleton.Data.FindSkin(text); } if ((Object)(object)spine == (Object)null) { Plugin.Log.LogInfo((object)("Lamb skin was null after cycling, an error occurred! at skin name " + text)); return; } Skin skin = ((SkeletonRenderer)spine).Skeleton.Skin; foreach (var fleeceOverrideSlot in PlayerSpineLoader.FleeceOverrideSlots) { int num2 = ((SkeletonRenderer)spine).Skeleton.FindSlotIndex(fleeceOverrideSlot.Item1); Attachment attachment = val.GetAttachment(num2, fleeceOverrideSlot.Item2); Plugin.Log.LogInfo((object)string.Format("Slot {0} index is {1}, attachment {2}", fleeceOverrideSlot.Item1, num2, (attachment != null) ? "found" : "not found")); if (attachment == null) { skin.RemoveAttachment(num2, fleeceOverrideSlot.Item2); } else { skin.SetAttachment(num2, fleeceOverrideSlot.Item2, attachment); } Plugin.Log.LogInfo((object)("Applied " + fleeceOverrideSlot.Item2 + " attachment to current skin.")); } Plugin.Log.LogInfo((object)("Applied" + text + " attachment to current skin.")); ((SkeletonRenderer)spine).Skeleton.SetSlotsToSetupPose(); spine.Update(0f, false); } [HarmonyPatch(typeof(Follower), "Update")] [HarmonyPostfix] public static void Follower_FacePosition(Follower __instance) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) int iD = __instance.Brain.Info.ID; float customScale = CustomColorHelper.GetCustomScale(iD); if (!(customScale <= 0f)) { ((SkeletonRenderer)__instance.Spine).skeleton.ScaleX = ((((Component)__instance).transform.position.x < __instance._destPos.x) ? (0f - customScale) : customScale); } } [HarmonyPatch(typeof(FollowerBrain), "SetFollowerCostume", new Type[] { typeof(Skeleton), typeof(int), typeof(string), typeof(int), typeof(FollowerOutfitType), typeof(FollowerHatType), typeof(FollowerClothingType), typeof(FollowerCustomisationType), typeof(FollowerSpecialType), typeof(ITEM_TYPE), typeof(string), typeof(FollowerInfo) })] [HarmonyPrefix] public static bool FollowerBrain_SetFollowerCostume_Prefix(FollowerBrain __instance, Skeleton skeleton, ref string skinName, ref FollowerOutfitType outfit, ref FollowerHatType hat, ref FollowerClothingType clothing, FollowerCustomisationType customisation, ref FollowerSpecialType special, ref ITEM_TYPE necklace, FollowerInfo info) { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected I4, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Invalid comparison between Unknown and I4 //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Invalid comparison between Unknown and I4 //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Invalid comparison between Unknown and I4 //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Invalid comparison between Unknown and I4 if (info != null) { Plugin.Log.LogInfo((object)$"Follower ID: {info.ID}, Name: {info.Name}"); CustomFollowerColor customColor = CustomColorHelper.GetCustomColor(info.ID); if (customColor == null) { return true; } if (!customColor.CustomFollowerCostume) { return true; } Plugin.Log.LogInfo((object)$"Custom costume enabled: {customColor.CustomFollowerCostume}, ClothingType: {customColor.FollowerClothingType}, SpecialType: {customColor.FollowerSpecialType}, HatType: {customColor.FollowerHatType}, OutfitType: {customColor.FollowerOutfitType}"); hat = (FollowerHatType)customColor.FollowerHatType; necklace = (ITEM_TYPE)(int)CustomColorCommand.GetNecklaceToUse(customColor.FollowerNecklaceType, info); special = (FollowerSpecialType)customColor.FollowerSpecialType; clothing = (FollowerClothingType)customColor.FollowerClothingType; outfit = (FollowerOutfitType)customColor.FollowerOutfitType; FollowerSpecialType val = special; if (val - 11 <= 2) { skinName = CustomColorCommand.GetSnowmanRandomSkin(special); Plugin.Log.LogInfo((object)("Applying snowman skin: " + skinName)); } FollowerClothingType val2 = clothing; if (((int)val2 == 1 || val2 - 3 <= 1 || (int)val2 == 40) ? true : false) { clothing = (FollowerClothingType)27; Plugin.Log.LogInfo((object)"Clothing type was blacklisted, defaulting to Normal."); } if ((int)outfit == 4) { outfit = (FollowerOutfitType)18; Plugin.Log.LogInfo((object)"Outfit type was blacklisted, defaulting to None."); } } return true; } [HarmonyPatch(typeof(FollowerBrain), "SetFollowerCostume", new Type[] { typeof(Skeleton), typeof(int), typeof(string), typeof(int), typeof(FollowerOutfitType), typeof(FollowerHatType), typeof(FollowerClothingType), typeof(FollowerCustomisationType), typeof(FollowerSpecialType), typeof(ITEM_TYPE), typeof(string), typeof(FollowerInfo) })] [HarmonyPostfix] private static void FollowerBrain_SetFollowerCostume(FollowerBrain __instance, Skeleton skeleton, FollowerInfo info) { //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) if (Plugin.DebugDumpFollowerSpineAtlas.Value) { Plugin.Log.LogWarning((object)"Debug Dump is enabled! Performance may be impacted"); string path = Path.Combine(Plugin.PluginPath, "followerSlots.json"); if (File.Exists(path)) { Plugin.Log.LogInfo((object)"followerSlots.json already exists, skipping dump. Delete the file to dump again."); } else { Plugin.Log.LogInfo((object)"Creating dump for followerslots"); List<DebugOutputSkin> list = new List<DebugOutputSkin>(); foreach (SkinEntry attachment in skeleton.Skin.Attachments) { SkinEntry current = attachment; list.Add(new DebugOutputSkin { SlotIndex = ((SkinEntry)(ref current)).SlotIndex, PartName = ((SkinEntry)(ref current)).Name }); } string contents = JsonConvert.SerializeObject((object)list, (Formatting)1); File.AppendAllText(path, contents); } } Plugin.Log.LogInfo((object)"Setting follower costume for"); if (info != null) { Plugin.Log.LogInfo((object)$"Follower ID: {info.ID}, Name: {info.Name}"); CustomFollowerColor customColor = CustomColorHelper.GetCustomColor(info.ID); if (customColor == null) { return; } Plugin.Log.LogInfo((object)$"Custom color found for follower {info.ID}: R={customColor.R}, G={customColor.G}, B={customColor.B}, A={customColor.A}"); SkeletonExtensions.SetColor(skeleton.FindSlot("ARM_LEFT_SKIN"), new Color(customColor.R, customColor.G, customColor.B, 1f)); SkeletonExtensions.SetColor(skeleton.FindSlot("LEG_LEFT_SKIN"), new Color(customColor.R, customColor.G, customColor.B, 1f)); SkeletonExtensions.SetColor(skeleton.FindSlot("LEG_RIGHT_SKIN"), new Color(customColor.R, customColor.G, customColor.B, 1f)); SkeletonExtensions.SetColor(skeleton.FindSlot("ARM_RIGHT_SKIN"), new Color(customColor.R, customColor.G, customColor.B, 1f)); SkeletonExtensions.SetColor(skeleton.FindSlot("HEAD_SKIN_BTM"), new Color(customColor.R, customColor.G, customColor.B, 1f)); skeleton.A = customColor.A; Follower val = FollowerManager.FindFollowerByID(info.ID); if ((Object)(object)val != (Object)null) { ((SkeletonRenderer)val.Spine).skeleton.scaleY = customColor.scale; ((SkeletonRenderer)val.Spine).skeleton.scaleX = customColor.scale; Plugin.Log.LogInfo((object)("Set follower scale to " + customColor.scale)); } if (customColor.CustomFollowerCostume) { try { Plugin.Log.LogInfo((object)"Costume override applied successfully."); } catch (Exception) { Plugin.Log.LogWarning((object)"The costume combinations were invalid, try another!"); } } } else { Plugin.Log.LogInfo((object)"Follower info is null, skipping costume setting."); } } [HarmonyPatch(typeof(SaveAndLoad), "Load")] [HarmonyPostfix] private static void SaveAndLoad_Load(int saveSlot) { CustomColorHelper.LoadCustomColors(saveSlot); } [HarmonyPatch(typeof(SaveAndLoad), "Save", new Type[] { })] [HarmonyPostfix] private static void SaveAndLoad_Save() { CustomColorHelper.SaveCustomColors(); } [HarmonyPatch(typeof(Structure), "Start")] [HarmonyPostfix] private static void Structure_Start(Structure __instance) { string text = ((object)(TYPES)(ref __instance.Type)).ToString(); List<CustomStructureBuildingData> overridesForBuilding = StructureBuildingOverrideHelper.GetOverridesForBuilding(text); if (overridesForBuilding != null && overridesForBuilding.Count != 0) { Plugin.Log.LogInfo((object)$"Custom Spine Loader: {overridesForBuilding.Count} overrides to building {text}."); CustomStructureManager.OverrideStructureBuilding(((Component)__instance).gameObject, overridesForBuilding); } } } } namespace CustomSpineLoader.Commands { public class CustomColorCommand : CustomFollowerCommand { public UIFollowerSummaryMenuController _followerSummaryMenuController; public float currentRed = 1f; public float currentGreen = 1f; public float currentBlue = 1f; public float currentAlpha = 1f; public float currentScale = 1f; public bool isCustomColorEnabled = false; public bool isCustomFollowerCostumeEnabled = false; public int selectedClothingTypeIndex = 0; public int selectedSpecialTypeIndex = 0; public int selectedHatTypeIndex = 0; public int selectedOutfitTypeIndex = 0; public int selectedNecklaceTypeIndex = 0; public override string InternalName => "CustomColor_Command"; public override Sprite CommandIcon => TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/colorwheel.png")); public override List<FollowerCommandCategory> Categories { get; } = new List<FollowerCommandCategory>(1) { (FollowerCommandCategory)0 }; public override string GetTitle(Follower follower) { return "Customize Follower"; } public override string GetDescription(Follower follower) { return "Customize Me!"; } public override void Execute(interaction_FollowerInteraction interaction, FollowerCommands finalCommand) { ((MonoBehaviour)interaction).StartCoroutine(interaction.FrameDelayCallback((Action)delegate { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown interaction.follower.Brain.HardSwapToTask((FollowerTask)new FollowerTask_ManualControl()); _followerSummaryMenuController = MonoSingleton<UIManager>.Instance.ShowFollowerSummaryMenu(interaction.follower); CreateColorUI(); UIFollowerSummaryMenuController followerSummaryMenuController = _followerSummaryMenuController; ((UIMenuBase)followerSummaryMenuController).OnHidden = (Action)Delegate.Combine(((UIMenuBase)followerSummaryMenuController).OnHidden, (Action)delegate { //IL_00bc: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) _followerSummaryMenuController = null; if (isCustomColorEnabled) { CustomColorHelper.SetCustomColor(interaction.follower.Brain.Info.ID, currentRed, currentGreen, currentBlue, currentAlpha, currentScale); SkeletonExtensions.SetColor(((SkeletonRenderer)interaction.follower.Spine).skeleton.FindSlot("ARM_LEFT_SKIN"), new Color(currentRed, currentGreen, currentBlue, 1f)); SkeletonExtensions.SetColor(((SkeletonRenderer)interaction.follower.Spine).skeleton.FindSlot("LEG_LEFT_SKIN"), new Color(currentRed, currentGreen, currentBlue, 1f)); SkeletonExtensions.SetColor(((SkeletonRenderer)interaction.follower.Spine).skeleton.FindSlot("LEG_RIGHT_SKIN"), new Color(currentRed, currentGreen, currentBlue, 1f)); SkeletonExtensions.SetColor(((SkeletonRenderer)interaction.follower.Spine).skeleton.FindSlot("ARM_RIGHT_SKIN"), new Color(currentRed, currentGreen, currentBlue, 1f)); SkeletonExtensions.SetColor(((SkeletonRenderer)interaction.follower.Spine).skeleton.FindSlot("HEAD_SKIN_BTM"), new Color(currentRed, currentGreen, currentBlue, 1f)); ((SkeletonRenderer)interaction.follower.Spine).skeleton.A = currentAlpha; ((SkeletonRenderer)interaction.follower.Spine).skeleton.ScaleX = currentScale; ((SkeletonRenderer)interaction.follower.Spine).skeleton.ScaleY = currentScale; Plugin.Log.LogInfo((object)("Scale is set to: " + currentScale + "X is " + ((SkeletonRenderer)interaction.follower.Spine).Skeleton.ScaleX + " Y is " + ((SkeletonRenderer)interaction.follower.Spine).Skeleton.ScaleY)); if (isCustomFollowerCostumeEnabled) { CustomColorHelper.SetCustomCostume(interaction.follower.Brain.Info.ID, enabled: true, selectedClothingTypeIndex, selectedSpecialTypeIndex, selectedHatTypeIndex, selectedOutfitTypeIndex, selectedNecklaceTypeIndex); } else { CustomColorHelper.SetCustomCostume(interaction.follower.Brain.Info.ID, enabled: false, 0, 0, 0, 0, 0); } } else { CustomColorHelper.RemoveCustomColor(interaction.follower.Brain.Info.ID); } interaction.Close(true, true, false); }); HUD_Manager.Instance.Hide(false, 0, false); })); } public void CreateColorUI() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0c04: Unknown result type (might be due to invalid IL or missing references) //IL_0c0e: Expected I4, but got Unknown //IL_0c26: Unknown result type (might be due to invalid IL or missing references) //IL_0c30: Expected I4, but got Unknown //IL_0c48: Unknown result type (might be due to invalid IL or missing references) //IL_0c52: Expected I4, but got Unknown //IL_0c6a: Unknown result type (might be due to invalid IL or missing references) //IL_0c74: Expected I4, but got Unknown if ((Object)(object)_followerSummaryMenuController == (Object)null) { Debug.LogError((object)"Follower Summary Menu Controller is not initialized."); return; } Debug.Log((object)"Creating color picker UI..."); Time.timeScale = 1f; Transform val = ((Component)_followerSummaryMenuController).transform.Find("BlurImageBackground"); ((Component)val).gameObject.SetActive(false); GameManager.GetInstance().CameraSetOffset(new Vector3(-2f, 0f, 0f)); Transform val2 = ((Component)_followerSummaryMenuController).transform.Find("FollowerSummaryContainer"); Transform val3 = ((val2 != null) ? val2.Find("Left") : null); Transform val4 = ((val3 != null) ? val3.Find("Transform") : null); Transform val5 = ((val4 != null) ? val4.Find("Top") : null); Transform val6 = ((val5 != null) ? val5.Find("Header") : null); TMP_Text val7 = ((val6 != null) ? ((Component)val6).GetComponent<TMP_Text>() : null); if ((Object)(object)val7 != (Object)null) { val7.text = "Customize Follower"; } Transform val8 = ((val4 != null) ? val4.Find("Content") : null); Transform val9 = ((val8 != null) ? val8.Find("Scroll View") : null); Transform val10 = ((val9 != null) ? val9.Find("Viewport") : null); Transform val11 = ((val10 != null) ? val10.Find("Content") : null); Transform val12 = ((val11 != null) ? val11.Find("Follower Traits Header") : null); TMP_Text val13 = ((val12 != null) ? ((Component)val12).GetComponent<TMP_Text>() : null); if ((Object)(object)val13 != (Object)null) { val13.text = "Color preview above."; } Transform val14 = ((val11 != null) ? val11.Find("Follower Traits Content") : null); if (val14 != null) { ((Component)val14).gameObject.SetActive(false); } Transform val15 = ((val11 != null) ? val11.Find("Cult Traits Header") : null); TMP_Text val16 = ((val15 != null) ? ((Component)val15).GetComponent<TMP_Text>() : null); if ((Object)(object)val15 != (Object)null) { val16.text = "Costume Preview on the right."; } Transform val17 = ((val11 != null) ? val11.Find("Cult Traits Content") : null); if (val17 != null) { ((Component)val17).gameObject.SetActive(false); } Transform val18 = ((val11 != null) ? val11.Find("Follower Thoughts") : null); if (val18 != null) { ((Component)val18).gameObject.SetActive(false); } Transform val19 = ((val11 != null) ? val11.Find("Follower Thoughts Content") : null); if (val19 != null) { ((Component)val19).gameObject.SetActive(false); } Transform val20 = ((val11 != null) ? val11.Find("Spacer") : null); GameObject gameObject = ((Component)((Transform)((Component)MonoSingleton<UIManager>.Instance.SettingsMenuControllerTemplate._audioSettings).GetComponentInChildren<ScrollRect>().content).GetChild(0)).gameObject; GameObject gameObject2 = ((Component)((Transform)((Component)MonoSingleton<UIManager>.Instance.SettingsMenuControllerTemplate._graphicsSettings).GetComponentInChildren<ScrollRect>().content).GetChild(4)).gameObject; GameObject gameObject3 = ((Component)((Transform)((Component)MonoSingleton<UIManager>.Instance.SettingsMenuControllerTemplate._graphicsSettings).GetComponentInChildren<ScrollRect>().content).GetChild(3)).gameObject; GameObject val21 = Object.Instantiate<GameObject>(gameObject2, val11); Transform val22 = Object.Instantiate<Transform>(val20, val11); GameObject val23 = Object.Instantiate<GameObject>(gameObject, val11); Transform val24 = Object.Instantiate<Transform>(val20, val11); GameObject val25 = Object.Instantiate<GameObject>(gameObject, val11); Transform val26 = Object.Instantiate<Transform>(val20, val11); GameObject val27 = Object.Instantiate<GameObject>(gameObject, val11); Transform val28 = Object.Instantiate<Transform>(val20, val11); GameObject val29 = Object.Instantiate<GameObject>(gameObject, val11); Transform val30 = Object.Instantiate<Transform>(val20, val11); GameObject val31 = Object.Instantiate<GameObject>(gameObject, val11); Transform val32 = Object.Instantiate<Transform>(val20, val11); GameObject val33 = Object.Instantiate<GameObject>(gameObject2, val11); Transform val34 = Object.Instantiate<Transform>(val20, val11); GameObject val35 = Object.Instantiate<GameObject>(gameObject3, val11); Transform val36 = Object.Instantiate<Transform>(val20, val11); GameObject val37 = Object.Instantiate<GameObject>(gameObject3, val11); Transform val38 = Object.Instantiate<Transform>(val20, val11); GameObject val39 = Object.Instantiate<GameObject>(gameObject3, val11); Transform val40 = Object.Instantiate<Transform>(val20, val11); GameObject val41 = Object.Instantiate<GameObject>(gameObject3, val11); Transform val42 = Object.Instantiate<Transform>(val20, val11); GameObject val43 = Object.Instantiate<GameObject>(gameObject3, val11); TMP_Text componentInChildren = val23.GetComponentInChildren<TMP_Text>(); TMP_Text componentInChildren2 = val25.GetComponentInChildren<TMP_Text>(); TMP_Text componentInChildren3 = val27.GetComponentInChildren<TMP_Text>(); TMP_Text componentInChildren4 = val29.GetComponentInChildren<TMP_Text>(); TMP_Text componentInChildren5 = val31.GetComponentInChildren<TMP_Text>(); TMP_Text componentInChildren6 = val21.GetComponentInChildren<TMP_Text>(); MMSlider componentInChildren7 = val23.GetComponentInChildren<MMSlider>(); MMSlider componentInChildren8 = val25.GetComponentInChildren<MMSlider>(); MMSlider componentInChildren9 = val27.GetComponentInChildren<MMSlider>(); MMSlider componentInChildren10 = val29.GetComponentInChildren<MMSlider>(); MMSlider componentInChildren11 = val31.GetComponentInChildren<MMSlider>(); MMToggle componentInChildren12 = val21.GetComponentInChildren<MMToggle>(); ((Object)val23).name = "SliderRed"; ((Object)val25).name = "SliderGreen"; ((Object)val27).name = "SliderBlue"; ((Object)val29).name = "SliderAlpha"; ((Object)val31).name = "SliderScale"; ((Object)val21).name = "ToggleCustomColor"; componentInChildren.text = "Red"; componentInChildren2.text = "Green"; componentInChildren3.text = "Blue"; componentInChildren4.text = "Alpha"; componentInChildren5.text = "Scale"; componentInChildren6.text = "Enable Customization"; ((UnityEvent<float>)(object)((Slider)componentInChildren7).onValueChanged).AddListener((UnityAction<float>)delegate(float value) { OnSliderValueChanged("Red", value); }); ((UnityEvent<float>)(object)((Slider)componentInChildren8).onValueChanged).AddListener((UnityAction<float>)delegate(float value) { OnSliderValueChanged("Green", value); }); ((UnityEvent<float>)(object)((Slider)componentInChildren9).onValueChanged).AddListener((UnityAction<float>)delegate(float value) { OnSliderValueChanged("Blue", value); }); ((UnityEvent<float>)(object)((Slider)componentInChildren10).onValueChanged).AddListener((UnityAction<float>)delegate(float value) { OnSliderValueChanged("Alpha", value); }); ((UnityEvent<float>)(object)((Slider)componentInChildren11).onValueChanged).AddListener((UnityAction<float>)delegate(float value) { OnSliderValueChanged("Scale", value); }); componentInChildren12.OnValueChanged = (Action<bool>)Delegate.Combine(componentInChildren12.OnValueChanged, (Action<bool>)delegate(bool value) { OnToggleValueChanged(value, _followerSummaryMenuController._follower); }); componentInChildren7._increment = 1; componentInChildren8._increment = 1; componentInChildren9._increment = 1; componentInChildren10._increment = 1; componentInChildren11._increment = 1; ((Slider)componentInChildren7).value = ((SkeletonRenderer)_followerSummaryMenuController._follower.Spine).skeleton.FindSlot("ARM_LEFT_SKIN").R * 100f; ((Slider)componentInChildren8).value = ((SkeletonRenderer)_followerSummaryMenuController._follower.Spine).skeleton.FindSlot("ARM_LEFT_SKIN").G * 100f; ((Slider)componentInChildren9).value = ((SkeletonRenderer)_followerSummaryMenuController._follower.Spine).skeleton.FindSlot("ARM_LEFT_SKIN").B * 100f; ((Slider)componentInChildren10).value = ((SkeletonRenderer)_followerSummaryMenuController._follower.Spine).skeleton.A * 100f; ((Slider)componentInChildren11).value = (currentScale - 0.1f) / 4.9f * 100f; MMToggle componentInChildren13 = val33.GetComponentInChildren<MMToggle>(); TMP_Text componentInChildren14 = val33.GetComponentInChildren<TMP_Text>(); TMP_Text componentInChildren15 = val35.GetComponentInChildren<TMP_Text>(); TMP_Text componentInChildren16 = val37.GetComponentInChildren<TMP_Text>(); TMP_Text componentInChildren17 = val39.GetComponentInChildren<TMP_Text>(); TMP_Text componentInChildren18 = val41.GetComponentInChildren<TMP_Text>(); TMP_Text componentInChildren19 = val43.GetComponentInChildren<TMP_Text>(); ((Object)val35).name = "FollowerClothingType"; ((Object)val37).name = "FollowerSpecialOverlayType"; ((Object)val39).name = "FollowerHatType"; ((Object)val41).name = "FollowerOutfitType"; ((Object)val43).name = "FollowerNecklaceType"; ((Object)val33).name = "EnableFollowerCostumeOverride"; componentInChildren15.text = "Clothing Type"; componentInChildren16.text = "Special Type"; componentInChildren17.text = "Hat Type"; componentInChildren18.text = "Outfit Type"; componentInChildren19.text = "Necklace Type"; componentInChildren14.text = "Follower Costume Override"; Array values = Enum.GetValues(typeof(FollowerClothingType)); List<string> list = (from FollowerClothingType x in values select ((object)(FollowerClothingType)(ref x)).ToString()).ToList(); Array values2 = Enum.GetValues(typeof(FollowerSpecialType)); List<string> list2 = (from FollowerSpecialType x in values2 select ((object)(FollowerSpecialType)(ref x)).ToString()).ToList(); for (int i = 0; i < list2.Count; i++) { if (list2[i].Contains("Palworld")) { list2[i] = "Unused_" + i; } } Array values3 = Enum.GetValues(typeof(FollowerHatType)); List<string> list3 = (from FollowerHatType x in values3 select ((object)(FollowerHatType)(ref x)).ToString()).ToList(); Array values4 = Enum.GetValues(typeof(FollowerOutfitType)); List<string> list4 = (from FollowerOutfitType x in values4 select ((object)(FollowerOutfitType)(ref x)).ToString()).ToList(); List<string> list5 = DataManager.AllNecklaces.Select((ITEM_TYPE x) => ((object)(ITEM_TYPE)(ref x)).ToString()).ToList(); list5.Insert(0, "Original"); list5.Insert(1, "None"); componentInChildren13.OnValueChanged = (Action<bool>)Delegate.Combine(componentInChildren13.OnValueChanged, (Action<bool>)delegate(bool value) { OnFollowerCostumeToggleChanged(value, _followerSummaryMenuController._follower); }); MMHorizontalSelector componentInChildren20 = val35.GetComponentInChildren<MMHorizontalSelector>(); componentInChildren20._localizeContent = false; componentInChildren20.UpdateContent(list.ToArray()); componentInChildren20.OnSelectionChanged = (Action<int>)Delegate.Combine(componentInChildren20.OnSelectionChanged, (Action<int>)delegate(int index) { OnFollowerCostumeSelectorsChanged(typeof(FollowerClothingType), index); }); MMHorizontalSelector componentInChildren21 = val37.GetComponentInChildren<MMHorizontalSelector>(); componentInChildren21._localizeContent = false; componentInChildren21.UpdateContent(list2.ToArray()); componentInChildren21.OnSelectionChanged = (Action<int>)Delegate.Combine(componentInChildren21.OnSelectionChanged, (Action<int>)delegate(int index) { OnFollowerCostumeSelectorsChanged(typeof(FollowerSpecialType), index); }); MMHorizontalSelector componentInChildren22 = val39.GetComponentInChildren<MMHorizontalSelector>(); componentInChildren22._localizeContent = false; componentInChildren22.UpdateContent(list3.ToArray()); componentInChildren22.OnSelectionChanged = (Action<int>)Delegate.Combine(componentInChildren22.OnSelectionChanged, (Action<int>)delegate(int index) { OnFollowerCostumeSelectorsChanged(typeof(FollowerHatType), index); }); MMHorizontalSelector componentInChildren23 = val41.GetComponentInChildren<MMHorizontalSelector>(); componentInChildren23._localizeContent = false; componentInChildren23.UpdateContent(list4.ToArray()); componentInChildren23.OnSelectionChanged = (Action<int>)Delegate.Combine(componentInChildren23.OnSelectionChanged, (Action<int>)delegate(int index) { OnFollowerCostumeSelectorsChanged(typeof(FollowerOutfitType), index); }); MMHorizontalSelector componentInChildren24 = val43.GetComponentInChildren<MMHorizontalSelector>(); componentInChildren24._localizeContent = false; componentInChildren24.UpdateContent(list5.ToArray()); componentInChildren24.OnSelectionChanged = (Action<int>)Delegate.Combine(componentInChildren24.OnSelectionChanged, (Action<int>)delegate(int index) { OnFollowerCostumeSelectorsChanged(typeof(ITEM_TYPE), index); }); CustomFollowerColor customColor = CustomColorHelper.GetCustomColor(_followerSummaryMenuController._follower.Brain.Info.ID); if (customColor != null) { componentInChildren12.Value = true; componentInChildren12.UpdateState(true); isCustomColorEnabled = true; componentInChildren13.Value = customColor.CustomFollowerCostume; componentInChildren13.UpdateState(true); isCustomFollowerCostumeEnabled = customColor.CustomFollowerCostume; componentInChildren20.ContentIndex = Mathf.Clamp(customColor.FollowerClothingType, 0, list.Count - 1); componentInChildren21.ContentIndex = Mathf.Clamp(customColor.FollowerSpecialType, 0, list2.Count - 1); componentInChildren22.ContentIndex = Mathf.Clamp(customColor.FollowerHatType, 0, list3.Count - 1); componentInChildren23.ContentIndex = Mathf.Clamp(customColor.FollowerOutfitType, 0, list4.Count - 1); componentInChildren24.ContentIndex = Mathf.Clamp(customColor.FollowerNecklaceType, 0, list5.Count - 1); } else { componentInChildren12.Value = false; componentInChildren12.UpdateState(true); isCustomColorEnabled = false; componentInChildren13.Value = false; componentInChildren13.UpdateState(true); isCustomFollowerCostumeEnabled = false; componentInChildren20.ContentIndex = (int)_followerSummaryMenuController._follower.Brain.Info.Clothing; componentInChildren21.ContentIndex = (int)_followerSummaryMenuController._follower.Brain.Info.Special; componentInChildren22.ContentIndex = (int)_followerSummaryMenuController._follower.Brain.Info.Hat; componentInChildren23.ContentIndex = (int)_followerSummaryMenuController._follower.Brain.Info.Outfit; componentInChildren24.ContentIndex = 0; } } public void OnFollowerCostumeSelectorsChanged(Type enumType, int value) { //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Invalid comparison between Unknown and I4 //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) switch (enumType.Name) { case "FollowerClothingType": Plugin.Log.LogInfo((object)$"Setting clothing type to {(object)(FollowerClothingType)value}"); selectedClothingTypeIndex = value; break; case "FollowerSpecialType": Plugin.Log.LogInfo((object)$"Setting special type to {(object)(FollowerSpecialType)value}"); selectedSpecialTypeIndex = value; break; case "FollowerHatType": Plugin.Log.LogInfo((object)$"Setting hat type to {(object)(FollowerHatType)value}"); selectedHatTypeIndex = value; break; case "FollowerOutfitType": Plugin.Log.LogInfo((object)$"Setting outfit type to {(object)(FollowerOutfitType)value}"); selectedOutfitTypeIndex = value; break; case "ITEM_TYPE": Plugin.Log.LogInfo((object)$"Setting necklace type to {(object)(ITEM_TYPE)value}"); selectedNecklaceTypeIndex = value; break; default: Plugin.Log.LogWarning((object)("Unknown enum type for follower costume selector change: " + enumType.Name)); break; } if (!isCustomFollowerCostumeEnabled || !isCustomColorEnabled) { Plugin.Log.LogInfo((object)"Custom follower costume not enabled, skipping costume set."); return; } Plugin.Log.LogInfo((object)("Setting costume override now... overrides are: " + $"ClothingType: {(object)(FollowerClothingType)selectedClothingTypeIndex}, " + $"SpecialType: {(object)(FollowerSpecialType)selectedSpecialTypeIndex}, " + $"HatType: {(object)(FollowerHatType)selectedHatTypeIndex}, " + $"OutfitType: {(object)(FollowerOutfitType)selectedOutfitTypeIndex}")); try { FollowerSpecialType val = (FollowerSpecialType)selectedSpecialTypeIndex; string text = _followerSummaryMenuController._follower.Brain.Info.SkinName; if (val - 11 <= 2) { text = GetSnowmanRandomSkin((FollowerSpecialType)selectedSpecialTypeIndex); Plugin.Log.LogInfo((object)("Applying snowman skin: " + text)); } FollowerBrain.SetFollowerCostume(((SkeletonRenderer)_followerSummaryMenuController._follower.Spine).skeleton, _followerSummaryMenuController._follower.Brain.Info.XPLevel, text, _followerSummaryMenuController._follower.Brain.Info.SkinColour, (FollowerOutfitType)selectedOutfitTypeIndex, (FollowerHatType)selectedHatTypeIndex, (FollowerClothingType)selectedClothingTypeIndex, _followerSummaryMenuController._follower.Brain.Info.Customisation, val, GetNecklaceToUse(selectedNecklaceTypeIndex, _followerSummaryMenuController._follower.Brain._directInfoAccess), "", _followerSummaryMenuController._follower.Brain._directInfoAccess); Plugin.Log.LogInfo((object)"Costume override applied successfully."); } catch (Exception) { Plugin.Log.LogWarning((object)"The costume combinations were invalid, try another!"); } } public static string GetSnowmanRandomSkin(FollowerSpecialType snowmanType) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected I4, but got Unknown if (1 == 0) { } string text = (snowmanType - 11) switch { 2 => "Snowman/Bad_", 1 => "Snowman/Mid_", 0 => "Snowman/Good_", _ => "Snowman/Good_", }; if (1 == 0) { } string arg = text; return $"{arg}{Random.Range(1, 4)}"; } public static ITEM_TYPE GetNecklaceToUse(int selectedNecklaceTypeIndex, FollowerInfo follower) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) int num = selectedNecklaceTypeIndex - 2; if (selectedNecklaceTypeIndex > 1 && (num < 0 || num >= DataManager.AllNecklaces.Count)) { Plugin.Log.LogWarning((object)"Selected necklace type index is out of bounds, defaulting to Original."); return follower.Necklace; } if (1 == 0) { } ITEM_TYPE result = (ITEM_TYPE)(selectedNecklaceTypeIndex switch { 0 => follower.Necklace, 1 => 0, _ => DataManager.AllNecklaces[selectedNecklaceTypeIndex - 2], }); if (1 == 0) { } return result; } public void OnFollowerCostumeToggleChanged(bool value, Follower follower) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)$"Follower costume toggle changed to {value}"); isCustomFollowerCostumeEnabled = value; if (!isCustomFollowerCostumeEnabled) { Debug.Log((object)"Custom follower costume disabled, reset costume."); FollowerBrain.SetFollowerCostume(((SkeletonRenderer)follower.Spine).skeleton, follower.Brain.Info.XPLevel, follower.Brain.Info.SkinName, follower.Brain.Info.SkinColour, follower.Brain.Info.Outfit, follower.Brain.Info.Hat, follower.Brain.Info.Clothing, follower.Brain.Info.Customisation, follower.Brain.Info.Special, follower.Brain.Info.Necklace, "", follower.Brain._directInfoAccess); } else { OnFollowerCostumeSelectorsChanged(typeof(FollowerClothingType), selectedClothingTypeIndex); } } public void OnToggleValueChanged(bool value, Follower follower) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)$"Toggle value changed to {value}"); isCustomColorEnabled = value; if (!isCustomColorEnabled) { Debug.Log((object)"Custom color disabled, reset to default colors."); FollowerBrain.SetFollowerCostume(((SkeletonRenderer)follower.Spine).skeleton, follower.Brain.Info.XPLevel, follower.Brain.Info.SkinName, follower.Brain.Info.SkinColour, follower.Brain.Info.Outfit, follower.Brain.Info.Hat, follower.Brain.Info.Clothing, follower.Brain.Info.Customisation, follower.Brain.Info.Special, follower.Brain.Info.Necklace, "", follower.Brain._directInfoAccess); } } public void OnSliderValueChanged(string color, float value) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0271: 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_02b3: Unknown result type (might be due to invalid IL or missing references) value /= 100f; Debug.Log((object)$"Slider {color} value changed to {value}"); if ((Object)(object)_followerSummaryMenuController == (Object)null) { Debug.LogError((object)"Follower Summary Menu Controller is not initialized."); return; } Follower follower = _followerSummaryMenuController._follower; SkeletonGraphic followerSpine = _followerSummaryMenuController._infoBox.FollowerSpine; Color color2 = SkeletonExtensions.GetColor(((SkeletonRenderer)follower.Spine).skeleton.FindSlot("ARM_LEFT_SKIN")); switch (color) { case "Red": currentRed = value; followerSpine.skeleton.FindSlot("ARM_LEFT_SKIN").R = value; followerSpine.skeleton.FindSlot("LEG_LEFT_SKIN").R = value; followerSpine.skeleton.FindSlot("LEG_RIGHT_SKIN").R = value; followerSpine.skeleton.FindSlot("ARM_RIGHT_SKIN").R = value; followerSpine.skeleton.FindSlot("HEAD_SKIN_BTM").R = value; break; case "Green": currentGreen = value; fo