using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TrinketAndBindingFramework; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ClimbingAxesMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ClimbingAxesMod")] [assembly: AssemblyTitle("ClimbingAxesMod")] [assembly: AssemblyVersion("1.0.0.0")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ClimbingAxesMod { [BepInPlugin("com.cicismods.climbingaxes", "Climbing Axes Mod", "1.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string ItemTag = "climbingaxe"; public const int StartingDurability = 30; public const float RegenIntervalSeconds = 60f; public const float HandholdLifetimeSeconds = 0f; public const string DurabilityDataKey = "axe_durability"; public const string PrefabNameRed = "ClimbingAxe_Red"; public const int StartingDurabilityRed = 10; public const float RegenIntervalSecondsRed = 15f; public const float BrokenRegenDelaySecondsRed = 60f; public const string PrefabNameGreen = "ClimbingAxe_Green"; public const float AxeRange = 4f; public const float LodgeDelaySeconds = 0f; public const float AxeMinChargeTime = 0.05f; public const float AxeChargeDamage = 1f; public const float AxeAutoReleaseDelay = 0.5f; public const float AxeHitShakeAmount = 0.025f; public static readonly Vector3 LodgedAxeEulerOffset = new Vector3(-90f, 180f, -90f); public const float LodgedAxeHandleTiltDegrees = 40f; public static Item_Object AxeTemplate; public static Item_Object RedAxeTemplate; public static Item_Object GreenAxeTemplate; public static HandItem ClimbingAxeHandItemTemplate; public static ManualLogSource Log; public static GameObject AxePrefab; public static GameObject AxeBrokenPrefab; public static GameObject RedAxePrefab; public static GameObject RedAxeBrokenPrefab; public static GameObject GreenAxePrefab; public static Sprite AxeHandSprite; public static Sprite AxeSpriteState2; public static Sprite AxeSpriteState3; public static Sprite AxeSpriteFinal; public static Sprite AxeSpriteBroken; public static Sprite AxeRedSpritePristine; public static Sprite AxeRedSpriteState2; public static Sprite AxeRedSpriteState3; public static Sprite AxeRedSpriteFinal; public static Sprite AxeRedSpriteBroken; public static Sprite AxeGreenSprite; public static Texture2D AxeTexture; public static Sprite WallRunnerIcon; public static Sprite AlpinePuristIcon; public static Sprite FreeClimberIcon; public static Sprite YellowAxesVendingSprite; public static Sprite MendingAxesPerkCardSprite; public static Material OutlineMaterial; public static Material OutlineMaterialRed; public static Material OutlineMaterialGreen; public static readonly Color GreenShimmerColor = new Color(0.5f, 1.3f, 0.75f, 1f); public static Material GreenAxeShimmerSpriteMaterial; public static readonly Vector3 OutlineHaloScale = new Vector3(1.04f, 1.04f, 1.04f); public static readonly Vector3 OutlineHaloOffset = Vector3.zero; public static readonly List AxeHitClips = new List(); public static AudioClip AxeBreakClip; private Harmony _harmony; private static bool _cachedAlpinePuristActive; private static bool _cacheValid; public static readonly HashSet AlpinePuristBlockedPrefabs = new HashSet { "Item_Piton", "Item_AutoPiton", "Item_Piton_Holiday", "Item_Rebar", "Item_Rebar_Explosive", "Item_Rebar_Bone", "Item_RebarRope", "Item_Rebar_Holiday", "Item_RebarRope_Holiday", "Item_Hammer" }; public static readonly string[] AlpinePuristBlockedPerkSubstrings = new string[3] { "piton", "rebar", "hammer" }; public static readonly string[] AlpinePuristBlockedPerkNameSubstrings = new string[1] { "hangtight" }; public const string RedAxePerkId = "cici_red_axes_perk"; private static Purchase _yellowAxeVendingPurchase; private static Perk _redAxePerkAsset; public static Item_Object AxeVendingSpawnTemplate; private static GameObject _axeVendingSpawnContainer; private static readonly Dictionary _invertedMeshCache = new Dictionary(); private static readonly Dictionary _lastHaloMaterial = new Dictionary(); public static bool AlpinePuristActive { get { if (!_cacheValid) { Recompute(); } return _cachedAlpinePuristActive; } } public static Sprite GetSpriteForDurability(int dur, int maxDur) { if (dur <= 0) { return AxeSpriteBroken ?? AxeHandSprite; } if (dur == 1) { return AxeSpriteFinal ?? AxeHandSprite; } if (maxDur <= 0) { return AxeHandSprite; } float num = (float)dur / (float)maxDur; if (num >= 2f / 3f) { return AxeHandSprite; } if (num >= 1f / 3f) { return AxeSpriteState2 ?? AxeHandSprite; } return AxeSpriteState3 ?? AxeHandSprite; } public static Sprite GetSpriteForDurability(Item item) { if (IsInfiniteDurability(item)) { return AxeGreenSprite ?? AxeHandSprite; } int durability = GetDurability(item); bool num = item?.prefabName == "ClimbingAxe_Red"; int maxDur = (num ? 10 : 30); if (num) { return GetRedSpriteForDurability(durability, maxDur); } return GetSpriteForDurability(durability, maxDur); } public static bool IsInfiniteDurability(Item item) { if (item != null) { return item.prefabName == "ClimbingAxe_Green"; } return false; } private static Sprite GetRedSpriteForDurability(int dur, int maxDur) { if (dur <= 0) { return AxeRedSpriteBroken ?? AxeRedSpritePristine ?? AxeHandSprite; } if (dur == 1) { return AxeRedSpriteFinal ?? AxeRedSpritePristine ?? AxeHandSprite; } if (maxDur <= 0) { return AxeRedSpritePristine ?? AxeHandSprite; } float num = (float)dur / (float)maxDur; if (num >= 2f / 3f) { return AxeRedSpritePristine ?? AxeHandSprite; } if (num >= 1f / 3f) { return AxeRedSpriteState2 ?? AxeRedSpritePristine ?? AxeHandSprite; } return AxeRedSpriteState3 ?? AxeRedSpritePristine ?? AxeHandSprite; } private void Awake() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; LoadAssetBundle(); LoadCustomAudio(); LoadTrinketIcons(); _harmony = new Harmony("com.cicismods.climbingaxes"); _harmony.PatchAll(); GameObject val = new GameObject("ClimbingAxesMod_Handler") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); val.AddComponent(); TrinketRegistry.RegisterTrinket("cici_wall_runner", "Wall Runner", "Start with a pair of climbing axes. Alternate hands to scale any surface, whiff a swing to let go.", "Some climbers don't trust pitons.", 1, 0f, 0f, WallRunnerIcon, (Func>)delegate { try { EnsureAxeTemplate(); } catch { } return ((Object)(object)AxeTemplate == (Object)null) ? new List() : new List { AxeTemplate, AxeTemplate }; }, (Func>)null, 0); TrinketRegistry.RegisterBinding("cici_alpine_purist", "Alpine Purist", "Start with axes instead of the hammer. Pitons, auto-pitons, rebar, and rebar-ropes do not appear in the world or in vending machines. Related perks are disabled.", "Trust the steel.", 1, 0.5f, 0f, AlpinePuristIcon, (Func>)delegate { try { EnsureRedAxeTemplate(); } catch { } return ((Object)(object)RedAxeTemplate == (Object)null) ? new List() : new List { RedAxeTemplate, RedAxeTemplate }; }, (Func>)null, 0); TrinketRegistry.RegisterTrinket("cici_free_climber", "Free Climber", "Start with a pair of climbing axes that never wear down. Lodge into any surface, forever.", "For those who will never stop climbing.", 3, 0f, 0f, FreeClimberIcon ?? WallRunnerIcon, (Func>)delegate { try { EnsureGreenAxeTemplate(); } catch { } return ((Object)(object)GreenAxeTemplate == (Object)null) ? new List() : new List { GreenAxeTemplate, GreenAxeTemplate }; }, (Func>)null, 0); } public static void InvalidateAlpinePuristCache() { _cacheValid = false; } private static void Recompute() { _cachedAlpinePuristActive = IsAlpinePuristActiveNow(); _cacheValid = true; } private static bool IsAlpinePuristActiveNow() { try { M_Gamemode currentGamemode = CL_GameManager.GetCurrentGamemode(); if ((Object)(object)currentGamemode == (Object)null) { return false; } SaveData saveData = StatManager.saveData; List list = ((saveData != null) ? saveData.GetGamemodeTrinkets(currentGamemode.GetGamemodeName(true)) : null); if (list == null) { return false; } foreach (string item in list) { if (!string.IsNullOrEmpty(item) && item.ToLowerInvariant().Contains("cici_alpine_purist")) { return true; } } } catch { } return false; } public static string GetAlpinePuristBestTimeFilePath() { return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "CiCisMods", "AlpinePurist", "best.txt"); } public static float LoadAlpinePuristBestTime() { try { string alpinePuristBestTimeFilePath = GetAlpinePuristBestTimeFilePath(); if (!File.Exists(alpinePuristBestTimeFilePath)) { return 0f; } if (float.TryParse(File.ReadAllText(alpinePuristBestTimeFilePath).Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return (result > 0f) ? result : 0f; } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[AlpinePurist] Load persistent best failed: " + ex.Message)); } } return 0f; } public static void SaveAlpinePuristBestTime(float seconds) { try { string alpinePuristBestTimeFilePath = GetAlpinePuristBestTimeFilePath(); string directoryName = Path.GetDirectoryName(alpinePuristBestTimeFilePath); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } File.WriteAllText(alpinePuristBestTimeFilePath, seconds.ToString("R", CultureInfo.InvariantCulture)); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[AlpinePurist] Save persistent best failed: " + ex.Message)); } } } private void LoadAssetBundle() { //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "climbingaxemod"); if (!File.Exists(text)) { Log.LogError((object)("Asset bundle not found at: " + text)); return; } AssetBundle val = AssetBundle.LoadFromFile(text); if ((Object)(object)val == (Object)null) { Log.LogError((object)"AssetBundle.LoadFromFile returned null"); return; } GameObject[] array = val.LoadAllAssets(); if (array != null && array.Length != 0) { AxePrefab = PickByExactName(array, "climbing_axe_new"); AxeBrokenPrefab = PickByExactName(array, "climbing_axe_new_broken"); RedAxePrefab = PickByExactName(array, "climbing_axe_red"); RedAxeBrokenPrefab = PickByExactName(array, "climbing_axe_red_broken"); GreenAxePrefab = PickByExactName(array, "climbing_axe_green"); if ((Object)(object)AxePrefab == (Object)null) { AxePrefab = PickPreferredByName(array, "_new") ?? array[0]; } if ((Object)(object)AxeBrokenPrefab == (Object)null) { Log.LogWarning((object)"[Bundle] climbing_axe_new_broken not found"); } if ((Object)(object)RedAxePrefab == (Object)null) { Log.LogWarning((object)"[Bundle] climbing_axe_red not found"); } if ((Object)(object)RedAxeBrokenPrefab == (Object)null) { Log.LogWarning((object)"[Bundle] climbing_axe_red_broken not found"); } if ((Object)(object)GreenAxePrefab == (Object)null) { Log.LogWarning((object)"[Bundle] climbing_axe_green not found (green variant falls back to yellow mesh until art ships)"); } } else { Log.LogError((object)"Bundle loaded but contains no GameObject assets"); } Sprite[] array2 = val.LoadAllAssets(); if (array2 != null && array2.Length != 0) { AxeSpriteState2 = PickPreferredByName(array2, "_state_2"); AxeSpriteState3 = PickPreferredByName(array2, "_state_3"); AxeSpriteFinal = PickPreferredByName(array2, "_state_final"); AxeSpriteBroken = PickPreferredByName(array2, "_state_broken"); AxeHandSprite = PickPreferredBy(array2, (Func)((Sprite a) => ((Object)a).name != null && ((Object)a).name.ToLowerInvariant().Contains("_new") && !((Object)a).name.ToLowerInvariant().Contains("_state_"))) ?? PickPreferredByName(array2, "_new") ?? array2[0]; if ((Object)(object)AxeHandSprite != (Object)null && (Object)(object)AxeHandSprite.texture != (Object)null) { ((Texture)AxeHandSprite.texture).filterMode = (FilterMode)0; AxeTexture = AxeHandSprite.texture; } Sprite[] array3 = (Sprite[])(object)new Sprite[4] { AxeSpriteState2, AxeSpriteState3, AxeSpriteFinal, AxeSpriteBroken }; foreach (Sprite val2 in array3) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2.texture != (Object)null) { ((Texture)val2.texture).filterMode = (FilterMode)0; } } } if ((Object)(object)AxeHandSprite == (Object)null) { Texture2D[] array4 = val.LoadAllAssets(); if (array4 != null && array4.Length != 0) { AxeTexture = PickPreferredByName(array4, "_new") ?? array4[0]; ((Texture)AxeTexture).filterMode = (FilterMode)0; AxeHandSprite = Sprite.Create(AxeTexture, new Rect(0f, 0f, (float)((Texture)AxeTexture).width, (float)((Texture)AxeTexture).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0); ((Object)AxeHandSprite).name = "ClimbingAxe_HandSprite"; } } if ((Object)(object)AxeHandSprite == (Object)null) { Log.LogWarning((object)"No axe sprite/texture found in bundle"); } } private static T PickByExactName(T[] assets, string exact) where T : Object { if (assets == null) { return default(T); } foreach (T val in assets) { if (!((Object)(object)val == (Object)null) && ((Object)val).name == exact) { return val; } } return default(T); } private static T PickPreferredByName(T[] assets, string needle) where T : Object { if (assets == null) { return default(T); } needle = needle.ToLowerInvariant(); foreach (T val in assets) { if (!((Object)(object)val == (Object)null) && ((Object)val).name != null && ((Object)val).name.ToLowerInvariant().Contains(needle)) { return val; } } return default(T); } private static T PickPreferredBy(T[] assets, Func pred) where T : Object { if (assets == null) { return default(T); } foreach (T val in assets) { if (!((Object)(object)val == (Object)null) && pred(val)) { return val; } } return default(T); } private void LoadCustomAudio() { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string[] array = new string[2] { "climbingaxe_hit_1.wav", "climbingaxe_hit_2.wav" }; foreach (string filename in array) { AudioClip val = TryLoadWav(directoryName, filename); if ((Object)(object)val != (Object)null) { AxeHitClips.Add(val); } } AxeBreakClip = TryLoadWav(directoryName, "climbingaxe_break.wav"); } private void LoadTrinketIcons() { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); WallRunnerIcon = TryLoadSpritePng(directoryName, "cici_wall_runner_icon.png"); AlpinePuristIcon = TryLoadSpritePng(directoryName, "cici_alpine_purist_icon.png"); FreeClimberIcon = TryLoadSpritePng(directoryName, "Perk_Icon_Axes_Inf.png"); AxeRedSpritePristine = TryLoadSpritePng(directoryName, "climbing_axe_sprite_red.png"); AxeRedSpriteState2 = TryLoadSpritePng(directoryName, "climbing_axe_sprite_red_state_2.png"); AxeRedSpriteState3 = TryLoadSpritePng(directoryName, "climbing_axe_sprite_red_state_3.png"); AxeRedSpriteFinal = TryLoadSpritePng(directoryName, "climbing_axe_sprite_red_state_final.png"); AxeRedSpriteBroken = TryLoadSpritePng(directoryName, "climbing_axe_sprite_red_state_broken.png"); AxeGreenSprite = TryLoadSpritePng(directoryName, "climbing_axe_sprite_inf.png"); YellowAxesVendingSprite = TryLoadSpritePng(directoryName, "Vending_Yellow_Axes.png"); MendingAxesPerkCardSprite = TryLoadSpritePng(directoryName, "Perk_Card_Mending_Axes.png"); } private Sprite TryLoadSpritePng(string dir, string filename) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) string text = Path.Combine(dir, filename); if (!File.Exists(text)) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("Trinket icon not found: " + filename + " (at " + text + ") — will use vanilla fallback")); } return null; } try { byte[] array = File.ReadAllBytes(text); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, array)) { return null; } ((Texture)val).filterMode = (FilterMode)0; ((Texture)val).wrapMode = (TextureWrapMode)1; Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); ((Object)obj).name = filename; Object.DontDestroyOnLoad((Object)(object)obj); Object.DontDestroyOnLoad((Object)(object)val); return obj; } catch (Exception ex) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)("Trinket icon load failed for " + filename + ": " + ex.Message)); } return null; } } private AudioClip TryLoadWav(string dir, string filename) { string text = Path.Combine(dir, filename); if (!File.Exists(text)) { Log.LogWarning((object)("Audio not found: " + filename + " (at " + text + ")")); return null; } try { AudioClip val = WavLoader.LoadFromFile(text); if ((Object)(object)val != (Object)null) { ((Object)val).name = filename; } return val; } catch (Exception ex) { Log.LogError((object)("WAV load failed for " + filename + ": " + ex.Message)); return null; } } public static void EnsureAxeTemplate() { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown if ((Object)(object)AxeTemplate != (Object)null) { return; } GameObject val = AxePrefab; if ((Object)(object)val == (Object)null) { val = CL_AssetManager.GetAssetGameObject("Item_Hammer", ""); if ((Object)(object)val == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"Neither AxePrefab (bundle) nor Item_Hammer available"); } return; } ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)"AxePrefab bundle missing — falling back to Item_Hammer clone"); } } GameObject val2 = Object.Instantiate(val); val2.SetActive(false); ((Object)val2).name = "cici_normal_axes"; ((Object)val2).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val2); ApplyGameShader(val2, addShimmer: true); EnsureHaloOnGameObject(val2); ConfigureAsPickup(val2); Item_Object val3 = val2.GetComponent(); if ((Object)(object)val3 == (Object)null) { val3 = val2.AddComponent(); } AxeTemplate = val3; if (val3.itemData != null) { return; } Item val4 = new Item { itemName = "Climbing Axe", itemTag = "climbingaxe", itemTags = new List { "tool", "climbingaxe" }, prefabName = "ClimbingAxe", upDirection = Vector3.up, pocketable = true, pouchable = true, worth = 2, inventoryScale = 1f, itemWeight = 1f, itemAsset = AxeTemplate, data = new List { string.Format("{0}={1}", "axe_durability", 30) }, dataModules = new List(), dataModuleSaves = new List(), pickupSounds = new List(), executionModules = new List() }; try { GameObject assetGameObject = CL_AssetManager.GetAssetGameObject("Item_Hammer", ""); Item_Object val5 = (((Object)(object)assetGameObject != (Object)null) ? assetGameObject.GetComponent() : null); if ((Object)(object)val5?.itemData?.handItemAsset != (Object)null) { EnsureClimbingAxeHandItemTemplate(); val4.handItemAsset = ClimbingAxeHandItemTemplate ?? val5.itemData.handItemAsset; val4.itemWeight = val5.itemData.itemWeight / 3f; } } catch (Exception ex) { ManualLogSource log3 = Log; if (log3 != null) { log3.LogWarning((object)("Template handItemAsset lookup failed: " + ex.Message)); } } val3.itemData = val4; } public static void EnsureRedAxeTemplate() { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Expected O, but got Unknown if ((Object)(object)RedAxeTemplate != (Object)null) { return; } EnsureAxeTemplate(); GameObject val = RedAxePrefab ?? AxePrefab ?? (((Object)(object)AxeTemplate != (Object)null) ? ((Component)AxeTemplate).gameObject : null); if ((Object)(object)val == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"Red axe template deferred — no source prefab available"); } return; } GameObject val2 = Object.Instantiate(val); val2.SetActive(false); ((Object)val2).name = "cici_regenerating_axes"; ((Object)val2).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val2); ApplyGameShader(val2, addShimmer: true); if ((Object)(object)OutlineMaterialRed == (Object)null) { OutlineMaterialRed = TryBuildGameOutlineMaterialRed(); } EnsureHaloOnGameObject(val2, OutlineMaterialRed); ConfigureAsPickup(val2); Item_Object val3 = val2.GetComponent(); if ((Object)(object)val3 == (Object)null) { val3 = val2.AddComponent(); } RedAxeTemplate = val3; if (val3.itemData != null) { return; } Item val4 = new Item { itemName = "Climbing Axe (Red)", itemTag = "climbingaxe", itemTags = new List { "tool", "climbingaxe" }, prefabName = "ClimbingAxe_Red", upDirection = Vector3.up, pocketable = true, pouchable = true, worth = 2, inventoryScale = 1f, itemWeight = 1f, itemAsset = RedAxeTemplate, data = new List { string.Format("{0}={1}", "axe_durability", 10) }, dataModules = new List(), dataModuleSaves = new List(), pickupSounds = new List(), executionModules = new List() }; try { GameObject assetGameObject = CL_AssetManager.GetAssetGameObject("Item_Hammer", ""); Item_Object val5 = (((Object)(object)assetGameObject != (Object)null) ? assetGameObject.GetComponent() : null); if ((Object)(object)val5?.itemData?.handItemAsset != (Object)null) { EnsureClimbingAxeHandItemTemplate(); val4.handItemAsset = ClimbingAxeHandItemTemplate ?? val5.itemData.handItemAsset; val4.itemWeight = val5.itemData.itemWeight / 3f; } } catch (Exception ex) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)("Red axe template handItemAsset lookup failed: " + ex.Message)); } } val3.itemData = val4; } public static void EnsureGreenAxeTemplate() { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Expected O, but got Unknown if ((Object)(object)GreenAxeTemplate != (Object)null) { return; } EnsureAxeTemplate(); GameObject val = GreenAxePrefab ?? AxePrefab ?? (((Object)(object)AxeTemplate != (Object)null) ? ((Component)AxeTemplate).gameObject : null); if ((Object)(object)val == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"Green axe template deferred — no source prefab available"); } return; } GameObject val2 = Object.Instantiate(val); val2.SetActive(false); ((Object)val2).name = "cici_infinate_axes"; ((Object)val2).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val2); ApplyGameShader(val2, addShimmer: true, GreenShimmerColor); if ((Object)(object)OutlineMaterialGreen == (Object)null) { OutlineMaterialGreen = TryBuildGameOutlineMaterialGreen(); } EnsureHaloOnGameObject(val2, OutlineMaterialGreen); ConfigureAsPickup(val2); Item_Object val3 = val2.GetComponent(); if ((Object)(object)val3 == (Object)null) { val3 = val2.AddComponent(); } GreenAxeTemplate = val3; if (val3.itemData != null) { return; } Item val4 = new Item { itemName = "Climbing Axe (Green)", itemTag = "climbingaxe", itemTags = new List { "tool", "climbingaxe" }, prefabName = "ClimbingAxe_Green", upDirection = Vector3.up, pocketable = true, pouchable = true, worth = 2, inventoryScale = 1f, itemWeight = 1f, itemAsset = GreenAxeTemplate, data = new List { "axe_durability=999" }, dataModules = new List(), dataModuleSaves = new List(), pickupSounds = new List(), executionModules = new List() }; try { GameObject assetGameObject = CL_AssetManager.GetAssetGameObject("Item_Hammer", ""); Item_Object val5 = (((Object)(object)assetGameObject != (Object)null) ? assetGameObject.GetComponent() : null); if ((Object)(object)val5?.itemData?.handItemAsset != (Object)null) { EnsureClimbingAxeHandItemTemplate(); val4.handItemAsset = ClimbingAxeHandItemTemplate ?? val5.itemData.handItemAsset; val4.itemWeight = val5.itemData.itemWeight / 3f; } } catch (Exception ex) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)("Green axe template handItemAsset lookup failed: " + ex.Message)); } } val3.itemData = val4; } public static void EnsureAxeVendingSpawnTemplate() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown if ((Object)(object)AxeVendingSpawnTemplate != (Object)null && (Object)(object)((Component)AxeVendingSpawnTemplate).gameObject != (Object)null) { return; } EnsureAxeTemplate(); if (!((Object)(object)AxeTemplate == (Object)null)) { if ((Object)(object)_axeVendingSpawnContainer == (Object)null) { _axeVendingSpawnContainer = new GameObject("CiCiAxeVendingSpawnContainer"); _axeVendingSpawnContainer.SetActive(false); ((Object)_axeVendingSpawnContainer).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)_axeVendingSpawnContainer); } GameObject obj = Object.Instantiate(((Component)AxeTemplate).gameObject, _axeVendingSpawnContainer.transform); obj.SetActive(true); ((Object)obj).name = "ClimbingAxe_VendingSpawnTemplate"; Item_Object component = obj.GetComponent(); if ((Object)(object)component != (Object)null && component.itemData == null) { component.itemData = AxeTemplate.itemData; } AxeVendingSpawnTemplate = component; } } public static Purchase GetOrBuildYellowAxeVendingPurchase() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_007f: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00cd: Expected O, but got Unknown if (_yellowAxeVendingPurchase != null && (Object)(object)_yellowAxeVendingPurchase.itemObject != (Object)null) { return _yellowAxeVendingPurchase; } EnsureAxeVendingSpawnTemplate(); if ((Object)(object)AxeVendingSpawnTemplate == (Object)null) { return null; } List spawnAssets = new List { ((Component)AxeVendingSpawnTemplate).gameObject, ((Component)AxeVendingSpawnTemplate).gameObject }; _yellowAxeVendingPurchase = new Purchase { name = "cici_climbing_axe_yellow", chance = 1f, spawnSettings = new SpawnSettings(), itemObject = AxeVendingSpawnTemplate, spawnAssets = spawnAssets, price = 12, purchaseSprite = (YellowAxesVendingSprite ?? WallRunnerIcon ?? AxeHandSprite), requiredItemTag = "", ignoreUnlocked = true }; return _yellowAxeVendingPurchase; } public static Perk GetOrBuildRedAxePerkAsset() { //IL_0053: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown if ((Object)(object)_redAxePerkAsset != (Object)null) { return _redAxePerkAsset; } Perk val = ScriptableObject.CreateInstance(); val.id = "cici_red_axes_perk"; val.title = "Mending Axes"; val.description = $"Receive 2 Mending Axes. Fragile but self-repair over time.\nCost: {23}"; val.flavorText = ""; val.perkType = (PerkType)2; val.cost = 23; val.spawnPool = (PerkPool)0; val.useBuff = false; val.useBaseBuff = false; val.canStack = false; val.tags = new List { "basic", "standard" }; val.flags = new List(); val.playerTag = new List(); val.modules = new List(); val.spawnSettings = new SpawnSettings(); val.buff = new BuffContainer { id = "", buffs = new List() }; val.baseBuff = new BuffContainer { id = "", buffs = new List() }; val.perkCard = MendingAxesPerkCardSprite ?? val.perkCard; val.icon = MendingAxesPerkCardSprite ?? AxeRedSpritePristine ?? AxeHandSprite; try { WKAssetDatabase fullCombinedAssetDatabase = CL_AssetManager.GetFullCombinedAssetDatabase(); if (fullCombinedAssetDatabase?.perkAssets != null) { foreach (Perk perkAsset in fullCombinedAssetDatabase.perkAssets) { if (!((Object)(object)perkAsset == (Object)null) && (Object)(object)val.perkFrame == (Object)null && (Object)(object)perkAsset.perkFrame != (Object)null) { val.perkFrame = perkAsset.perkFrame; break; } } } } catch { } ((Object)val).hideFlags = (HideFlags)61; ((Object)val).name = "Perk_CiCiRedAxes"; _redAxePerkAsset = val; return _redAxePerkAsset; } public static void EnsureClimbingAxeHandItemTemplate() { if ((Object)(object)ClimbingAxeHandItemTemplate != (Object)null) { return; } HandItem val = null; try { GameObject assetGameObject = CL_AssetManager.GetAssetGameObject("Item_Hammer", ""); val = (((Object)(object)assetGameObject != (Object)null) ? assetGameObject.GetComponent() : null)?.itemData?.handItemAsset; } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("Hammer HandItem lookup failed during clone: " + ex.Message)); } return; } if ((Object)(object)val == (Object)null) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)"Hammer HandItem_Melee prefab not found — climbing axe HandItem decouple deferred"); } return; } GameObject val2 = Object.Instantiate(((Component)val).gameObject); ((Object)val2).name = "ClimbingAxesMod_HandItem"; val2.SetActive(false); ((Object)val2).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val2); HandItem component = val2.GetComponent(); if ((Object)(object)component == (Object)null) { ManualLogSource log3 = Log; if (log3 != null) { log3.LogWarning((object)"Cloned hammer HandItem prefab has no HandItem component — skipping adoption"); } Object.Destroy((Object)(object)val2); return; } ClimbingAxeHandItemTemplate = component; ManualLogSource log4 = Log; if (log4 != null) { log4.LogInfo((object)("[Decouple] ClimbingAxeHandItemTemplate cloned from '" + ((Object)val).name + "' as '" + ((Object)val2).name + "'")); } } internal static void ApplyGameShader(GameObject target, bool addShimmer = false, Color? shimmerColor = null) { Shader val = Shader.Find("Dark Machine/SHDR_Base") ?? Shader.Find("Unlit/Texture"); if ((Object)(object)val == (Object)null) { return; } Renderer[] componentsInChildren = target.GetComponentsInChildren(true); foreach (Renderer val2 in componentsInChildren) { if (((Object)((Component)val2).gameObject).name.StartsWith("ClimbingAxeHalo_")) { continue; } Material[] materials = val2.materials; for (int j = 0; j < materials.Length; j++) { if (!((Object)(object)materials[j] == (Object)null)) { Texture val3 = (materials[j].HasProperty("_MainTex") ? materials[j].GetTexture("_MainTex") : null); materials[j].shader = val; if ((Object)(object)val3 != (Object)null && materials[j].HasProperty("_MainTex")) { materials[j].SetTexture("_MainTex", val3); } if (addShimmer) { ApplyItemShimmer(materials[j], shimmerColor); } } } val2.materials = materials; } } public static Material TryBuildGameOutlineMaterial() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) return BuildOutlineMaterial("ClimbingAxesMod_Outline_Yellow", new Color(1f, 0.92f, 0.1f, 1f)); } public static Material TryBuildGameOutlineMaterialRed() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) return BuildOutlineMaterial("ClimbingAxesMod_Outline_Red", new Color(1f, 0.2f, 0.2f, 1f)); } public static Material TryBuildGameOutlineMaterialGreen() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) return BuildOutlineMaterial("ClimbingAxesMod_Outline_Green", new Color(0.2f, 1f, 0.3f, 1f)); } public static Material EnsureGreenAxeShimmerSpriteMaterial() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)GreenAxeShimmerSpriteMaterial != (Object)null) { return GreenAxeShimmerSpriteMaterial; } Shader val = Shader.Find("Dark Machine/SHDR_Base_Inventory") ?? Shader.Find("Dark Machine/SHDR_Base") ?? Shader.Find("Sprites/Default"); if ((Object)(object)val == (Object)null) { return null; } Material val2 = new Material(val) { name = "ClimbingAxesMod_GreenShimmer_HeldSprite" }; if (val2.HasProperty("_Shimmer")) { val2.SetFloat("_Shimmer", 2.5f); } if (val2.HasProperty("_ShimmerFrequency")) { val2.SetFloat("_ShimmerFrequency", 1f); } if (val2.HasProperty("_ShimmerSpeed")) { val2.SetFloat("_ShimmerSpeed", 1f); } if (val2.HasProperty("_ShimmerOffset")) { val2.SetFloat("_ShimmerOffset", 0f); } if (val2.HasProperty("_ShimmerColor")) { val2.SetColor("_ShimmerColor", GreenShimmerColor); } if (val2.HasProperty("_Brightness")) { val2.SetFloat("_Brightness", 0f); } if (val2.HasProperty("_DitherAmount")) { val2.SetFloat("_DitherAmount", 0.2f); } if (val2.HasProperty("_ROUNDMULT")) { val2.SetFloat("_ROUNDMULT", 1f); } if (val2.HasProperty("_WiggleFreq")) { val2.SetFloat("_WiggleFreq", 2f); } if (val2.HasProperty("_WiggleSpeed")) { val2.SetFloat("_WiggleSpeed", 5f); } if (val2.HasProperty("_Color")) { val2.SetColor("_Color", new Color(0.85f, 0.85f, 0.85f, 1f)); } Object.DontDestroyOnLoad((Object)(object)val2); GreenAxeShimmerSpriteMaterial = val2; return GreenAxeShimmerSpriteMaterial; } private static Material BuildOutlineMaterial(string name, Color color) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) Shader val = Shader.Find("Dark Machine/SHDR_Outline"); if ((Object)(object)val == (Object)null) { return null; } Material val2 = new Material(val) { name = name }; if (val2.HasProperty("_Color")) { val2.SetColor("_Color", color); } if (val2.HasProperty("_Brightness")) { val2.SetFloat("_Brightness", 1f); } Object.DontDestroyOnLoad((Object)(object)val2); return val2; } public static Material PickOutlineMaterialForItem(Item item) { if (IsInfiniteDurability(item)) { if ((Object)(object)OutlineMaterialGreen == (Object)null) { OutlineMaterialGreen = TryBuildGameOutlineMaterialGreen(); } return OutlineMaterialGreen ?? OutlineMaterial; } if (item != null && item.prefabName == "ClimbingAxe_Red") { if ((Object)(object)OutlineMaterialRed == (Object)null) { OutlineMaterialRed = TryBuildGameOutlineMaterialRed(); } return OutlineMaterialRed ?? OutlineMaterial; } if ((Object)(object)OutlineMaterial == (Object)null) { OutlineMaterial = TryBuildGameOutlineMaterial(); } return OutlineMaterial; } public static Mesh GetInvertedHullMesh(Mesh source) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } if (_invertedMeshCache.TryGetValue(source, out var value)) { return value; } if (!source.isReadable) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[Outline] Mesh '" + ((Object)source).name + "' is not readable (Read/Write disabled at import). Halo skipped. Enable Read/Write on the FBX and rebuild the bundle to get the outline glow.")); } _invertedMeshCache[source] = null; return null; } try { Mesh val = new Mesh { name = ((Object)source).name + "_Inverted" }; val.indexFormat = source.indexFormat; val.vertices = source.vertices; val.normals = source.normals; val.uv = source.uv; val.subMeshCount = source.subMeshCount; for (int i = 0; i < source.subMeshCount; i++) { int[] triangles = source.GetTriangles(i); for (int j = 0; j < triangles.Length; j += 3) { int num = triangles[j + 1]; triangles[j + 1] = triangles[j + 2]; triangles[j + 2] = num; } val.SetTriangles(triangles, i); } val.RecalculateBounds(); Object.DontDestroyOnLoad((Object)(object)val); _invertedMeshCache[source] = val; return val; } catch (Exception ex) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)("[Outline] Failed to invert mesh '" + ((Object)source).name + "': " + ex.Message + ". Halo skipped.")); } _invertedMeshCache[source] = null; return null; } } public static void ApplyItemShimmer(Material m, Color? shimmerColor = null) { //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)m == (Object)null)) { if (m.HasProperty("_Shimmer")) { m.SetFloat("_Shimmer", 1f); } if (m.HasProperty("_ShimmerFrequency")) { m.SetFloat("_ShimmerFrequency", 1f); } if (m.HasProperty("_ShimmerSpeed")) { m.SetFloat("_ShimmerSpeed", 1f); } if (m.HasProperty("_ShimmerOver")) { m.SetFloat("_ShimmerOver", 0f); } if (m.HasProperty("_ShimmerOffset")) { m.SetFloat("_ShimmerOffset", 0f); } if (m.HasProperty("_ShimmerTextureMix")) { m.SetFloat("_ShimmerTextureMix", 1f); } if (m.HasProperty("_ShimmerColor")) { m.SetColor("_ShimmerColor", (Color)(((??)shimmerColor) ?? Color.white)); } if (m.HasProperty("_Shading")) { m.SetFloat("_Shading", 0.96f); } if (m.HasProperty("_DitherAmount")) { m.SetFloat("_DitherAmount", 0.63f); } if (m.HasProperty("_ROUNDMULT")) { m.SetFloat("_ROUNDMULT", 1.27f); } if (m.HasProperty("_Wiggle")) { m.SetFloat("_Wiggle", 0.0003f); } if (m.HasProperty("_WiggleFreq")) { m.SetFloat("_WiggleFreq", 2f); } if (m.HasProperty("_WiggleSpeed")) { m.SetFloat("_WiggleSpeed", 5f); } } } public static void EnsureHaloOnGameObject(GameObject go, Material outlineOverride = null) { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)go == (Object)null) { return; } if ((Object)(object)OutlineMaterial == (Object)null) { OutlineMaterial = TryBuildGameOutlineMaterial(); } Material val = outlineOverride ?? OutlineMaterial; if ((Object)(object)val == (Object)null) { return; } int instanceID = ((Object)go).GetInstanceID(); if (_lastHaloMaterial.TryGetValue(instanceID, out var value) && (Object)(object)value == (Object)(object)val) { return; } _lastHaloMaterial[instanceID] = val; MeshRenderer[] componentsInChildren = go.GetComponentsInChildren(true); foreach (MeshRenderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || ((Object)((Component)val2).gameObject).name.StartsWith("ClimbingAxeHalo_")) { continue; } Transform val3 = null; foreach (Transform item in ((Component)val2).transform) { Transform val4 = item; if (((Object)val4).name.StartsWith("ClimbingAxeHalo_")) { val3 = val4; break; } } MeshFilter component = ((Component)val2).GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null) { if ((Object)(object)val3 != (Object)null) { Object.Destroy((Object)(object)((Component)val3).gameObject); } continue; } Mesh invertedHullMesh = GetInvertedHullMesh(component.sharedMesh); if ((Object)(object)invertedHullMesh == (Object)null) { if ((Object)(object)val3 != (Object)null) { Object.Destroy((Object)(object)((Component)val3).gameObject); } } else if ((Object)(object)val3 != (Object)null) { MeshFilter component2 = ((Component)val3).GetComponent(); if ((Object)(object)component2 != (Object)null && (Object)(object)component2.sharedMesh != (Object)(object)invertedHullMesh) { component2.sharedMesh = invertedHullMesh; } MeshRenderer component3 = ((Component)val3).GetComponent(); if ((Object)(object)component3 != (Object)null && (Object)(object)((Renderer)component3).sharedMaterial != (Object)(object)val) { ((Renderer)component3).sharedMaterial = val; } } else { GameObject val5 = new GameObject("ClimbingAxeHalo_" + ((Object)val2).name) { layer = ((Component)val2).gameObject.layer }; val5.transform.SetParent(((Component)val2).transform, false); val5.transform.localPosition = OutlineHaloOffset; val5.transform.localRotation = Quaternion.identity; val5.transform.localScale = OutlineHaloScale; val5.AddComponent().sharedMesh = invertedHullMesh; MeshRenderer obj = val5.AddComponent(); ((Renderer)obj).sharedMaterial = val; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).lightProbeUsage = (LightProbeUsage)0; ((Renderer)obj).reflectionProbeUsage = (ReflectionProbeUsage)0; } } } private static void ConfigureAsPickup(GameObject go) { //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) go.layer = 10; Transform[] componentsInChildren = go.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = 10; } try { go.tag = "Pickupable"; } catch { } ObjectTagger val = go.GetComponent() ?? go.AddComponent(); if (val.tags == null) { val.tags = new List(); } if (!val.tags.Contains("Pickupable")) { val.tags.Add("Pickupable"); } if (!val.tags.Contains("Item")) { val.tags.Add("Item"); } if ((Object)(object)go.GetComponentInChildren() == (Object)null) { Renderer[] componentsInChildren2 = go.GetComponentsInChildren(); if (componentsInChildren2.Length != 0) { Bounds bounds = componentsInChildren2[0].bounds; for (int j = 1; j < componentsInChildren2.Length; j++) { ((Bounds)(ref bounds)).Encapsulate(componentsInChildren2[j].bounds); } BoxCollider obj2 = go.AddComponent(); obj2.center = go.transform.InverseTransformPoint(((Bounds)(ref bounds)).center); obj2.size = ((Bounds)(ref bounds)).size; } else { go.AddComponent().size = new Vector3(0.6f, 0.3f, 0.3f); } } (go.GetComponent() ?? go.AddComponent()).mass = 0.4f; CL_Prop val2 = go.GetComponent(); if ((Object)(object)val2 == (Object)null) { val2 = go.AddComponent(); } if (val2.hitSounds == null) { val2.hitSounds = new List(); } if (val2.dragSounds == null) { val2.dragSounds = new List(); } if (val2.breakSounds == null) { val2.breakSounds = new List(); } if (val2.unstickSounds == null) { val2.unstickSounds = new List(); } if (val2.damageSounds == null) { val2.damageSounds = new List(); } } public static Item CreateAxeItem() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown Item val = new Item { itemName = "Climbing Axe", itemTag = "climbingaxe", itemTags = new List { "tool", "climbingaxe" }, prefabName = "ClimbingAxe", upDirection = Vector3.up, pocketable = true, pouchable = true, worth = 2, inventoryScale = 1f, itemWeight = 1f, data = new List { string.Format("{0}={1}", "axe_durability", 30) }, dataModules = new List(), dataModuleSaves = new List(), pickupSounds = new List(), executionModules = new List() }; try { EnsureAxeTemplate(); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("Template build deferred: " + ex.Message)); } } if ((Object)(object)AxeTemplate != (Object)null) { val.itemAsset = AxeTemplate; } AxeModHandler.MarkAxeUsedNow(val); try { EnsureClimbingAxeHandItemTemplate(); GameObject assetGameObject = CL_AssetManager.GetAssetGameObject("Item_Hammer", ""); Item_Object val2 = (((Object)(object)assetGameObject != (Object)null) ? assetGameObject.GetComponent() : null); if ((Object)(object)ClimbingAxeHandItemTemplate != (Object)null) { val.handItemAsset = ClimbingAxeHandItemTemplate; } else if ((Object)(object)val2?.itemData?.handItemAsset != (Object)null) { val.handItemAsset = val2.itemData.handItemAsset; } if (val2?.itemData != null) { val.itemWeight = val2.itemData.itemWeight / 3f; } } catch (Exception ex2) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)("Hammer hand lookup failed: " + ex2.Message)); } } return val; } public static int GetDurability(Item item) { if (item?.data == null) { return 0; } foreach (string datum in item.data) { if (datum != null && datum.StartsWith("axe_durability=") && int.TryParse(datum.Substring("axe_durability".Length + 1), out var result)) { return result; } } return 0; } public static void SetDurability(Item item, int value) { if (item == null) { return; } if (item.data == null) { item.data = new List(); } string text = string.Format("{0}={1}", "axe_durability", value); for (int i = 0; i < item.data.Count; i++) { if (item.data[i] != null && item.data[i].StartsWith("axe_durability=")) { item.data[i] = text; return; } } item.data.Add(text); } } [HarmonyPatch(typeof(Item), "GetClone")] public static class AxePreserveItemTagPatch { [HarmonyPostfix] public static void Postfix(Item __instance, Item __result) { if (__instance != null && __result != null) { __result.itemTag = __instance.itemTag; } } } [HarmonyPatch(typeof(Item), "CopyNonDataFromItemAsset")] public static class AxeSaveMigrationPatch { [HarmonyPrefix] public static void Prefix(Item __instance) { if (__instance != null && (__instance.prefabName == "ClimbingAxe" || __instance.prefabName == "ClimbingAxe_Red" || __instance.prefabName == "ClimbingAxe_Green" || __instance.itemTag == "climbingaxe" || __instance.itemName == "Climbing Axe" || __instance.itemName == "Climbing Axe (Red)" || __instance.itemName == "Climbing Axe (Green)")) { bool flag = __instance.prefabName == "ClimbingAxe_Red" || __instance.itemName == "Climbing Axe (Red)"; string text = ((__instance.prefabName == "ClimbingAxe_Green" || __instance.itemName == "Climbing Axe (Green)") ? "ClimbingAxe_Green" : (flag ? "ClimbingAxe_Red" : "ClimbingAxe")); if (__instance.prefabName != text) { __instance.prefabName = text; } if (__instance.itemTag != "climbingaxe") { __instance.itemTag = "climbingaxe"; } if (__instance.itemTags == null) { __instance.itemTags = new List(); } if (!__instance.itemTags.Contains("climbingaxe")) { __instance.itemTags.Add("climbingaxe"); } if (!__instance.itemTags.Contains("tool")) { __instance.itemTags.Add("tool"); } } } } public static class AxeLodgeRotationFix { private static readonly Dictionary _relativeRotations = new Dictionary(); public static void Track(UT_SoftParent soft, Quaternion relativeRotation) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)soft == (Object)null)) { _relativeRotations[soft] = relativeRotation; } } internal static bool TryGet(UT_SoftParent soft, out Quaternion rel) { return _relativeRotations.TryGetValue(soft, out rel); } } [HarmonyPatch(typeof(UT_SoftParent), "CheckEnable")] public static class AxeSoftParentRotationPatch { [HarmonyPostfix] public static void Postfix(UT_SoftParent __instance) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.parent == (Object)null) && AxeLodgeRotationFix.TryGet(__instance, out var rel)) { ((Component)__instance).transform.rotation = __instance.parent.rotation * rel; } } } [HarmonyPatch(typeof(UI_TrinketPicker), "UpdateTrinketActivation")] public static class WallRunnerAlpinePuristMutexPatch { private static readonly FieldInfo _isLockedField = AccessTools.Field(typeof(UI_TrinketPicker_Icon), "isLocked"); public static readonly HashSet MutexLockedIcons = new HashSet(); public static readonly Dictionary> MutexLockReasons = new Dictionary>(); private const string TagWallRunner = "cici_wall_runner"; private const string TagAlpinePurist = "cici_alpine_purist"; private const string TagFreeClimber = "cici_free_climber"; private const string TagCarabiner = "trinket_carabiner"; private const string TagPitonsAndBeans = "pitonandbean"; [HarmonyPostfix] public static void Postfix(UI_TrinketPicker __instance) { if ((Object)(object)__instance == (Object)null || _isLockedField == null) { return; } MutexLockedIcons.Clear(); MutexLockReasons.Clear(); bool flag = false; bool flag2 = false; bool flag3 = false; bool flag4 = false; bool flag5 = false; List list = new List(); foreach (Trinket selectedTrinket in __instance.selectedTrinkets) { if ((Object)(object)selectedTrinket == (Object)null) { continue; } string text = ((Object)selectedTrinket).name?.ToLowerInvariant(); if (!string.IsNullOrEmpty(text)) { if (text.Contains("cici_wall_runner")) { flag = true; continue; } if (text.Contains("cici_alpine_purist")) { flag2 = true; continue; } if (text.Contains("cici_free_climber")) { flag3 = true; continue; } if (text.Contains("trinket_carabiner")) { flag4 = true; continue; } if (text.Contains("pitonandbean")) { flag5 = true; continue; } } if (TrinketGrantsAlpinePuristBlocked(selectedTrinket)) { list.Add(string.IsNullOrEmpty(selectedTrinket.title) ? "Unknown" : selectedTrinket.title); } } foreach (UI_TrinketPicker_Icon trinketIcon in __instance.trinketIcons) { if ((Object)(object)trinketIcon?.trinket == (Object)null) { continue; } bool flag6 = !trinketIcon.trinket.IsUnlocked() || trinketIcon.trinket.comingSoon; List list2 = new List(); string text2 = ((Object)trinketIcon.trinket).name?.ToLowerInvariant(); if (!string.IsNullOrEmpty(text2)) { if (text2.Contains("cici_wall_runner")) { if (flag2) { list2.Add("Alpine Purist"); } if (flag3) { list2.Add("Free Climber"); } } else if (text2.Contains("cici_alpine_purist")) { if (flag) { list2.Add("Wall Runner"); } if (flag3) { list2.Add("Free Climber"); } if (flag4) { list2.Add("Carabiner"); } if (flag5) { list2.Add("Pitons and Beans"); } foreach (string item in list) { list2.Add(item); } } else if (text2.Contains("cici_free_climber")) { if (flag) { list2.Add("Wall Runner"); } if (flag2) { list2.Add("Alpine Purist"); } } else if (text2.Contains("trinket_carabiner") && flag2) { list2.Add("Alpine Purist"); } else if (text2.Contains("pitonandbean") && flag2) { list2.Add("Alpine Purist"); } } if (flag2 && list2.Count == 0 && TrinketGrantsAlpinePuristBlocked(trinketIcon.trinket)) { list2.Add("Alpine Purist"); } bool flag7 = list2.Count > 0; _isLockedField.SetValue(trinketIcon, flag6 || flag7); if (flag7) { MutexLockedIcons.Add(trinketIcon); MutexLockReasons[trinketIcon.trinket] = list2; } } } private static bool TrinketGrantsAlpinePuristBlocked(Trinket t) { if ((Object)(object)t == (Object)null) { return false; } if (t.itemsToGrant != null) { for (int i = 0; i < t.itemsToGrant.Count; i++) { string text = t.itemsToGrant[i]?.itemData?.prefabName; if (!string.IsNullOrEmpty(text) && Plugin.AlpinePuristBlockedPrefabs.Contains(text)) { return true; } } } if (t.perksToGrant != null) { for (int j = 0; j < t.perksToGrant.Count; j++) { Perk val = t.perksToGrant[j]; if ((Object)(object)val == (Object)null) { continue; } string text2 = val.description?.ToLowerInvariant(); if (!string.IsNullOrEmpty(text2)) { for (int k = 0; k < Plugin.AlpinePuristBlockedPerkSubstrings.Length; k++) { if (text2.Contains(Plugin.AlpinePuristBlockedPerkSubstrings[k])) { return true; } } } string text3 = ((Object)val).name?.ToLowerInvariant(); if (string.IsNullOrEmpty(text3)) { continue; } for (int l = 0; l < Plugin.AlpinePuristBlockedPerkNameSubstrings.Length; l++) { if (text3.Contains(Plugin.AlpinePuristBlockedPerkNameSubstrings[l])) { return true; } } } } return false; } } [HarmonyPatch(typeof(Trinket), "GetLockedDescription")] public static class MutexLockedDescriptionOverridePatch { [HarmonyPrefix] public static bool Prefix(Trinket __instance, ref string __result) { if ((Object)(object)__instance == (Object)null) { return true; } if (!WallRunnerAlpinePuristMutexPatch.MutexLockReasons.TryGetValue(__instance, out var value)) { return true; } if (value == null || value.Count == 0) { return true; } string text = ((((Object)__instance).name == null || !((Object)__instance).name.Contains("cici_wall_runner")) ? (__instance.isBinding ? "red" : "#FF8AFF") : "#FFEB1A"); string text2 = (__instance.isBinding ? "Binding" : "Trinket"); string text3 = "" + __instance.title + ""; string text4 = string.Join(", ", value); __result = "Locked " + text2 + ": " + text3 + "\nConflicts with: " + text4 + ""; return false; } } [HarmonyPatch(typeof(UI_TrinketPicker_Icon), "Update")] public static class MutexLockedIconDarkenPatch { private static readonly Color MutexLockedColor = new Color(0.95f, 0.45f, 0.1f, 1f); [HarmonyPostfix] public static void Postfix(UI_TrinketPicker_Icon __instance) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.image == (Object)null) && WallRunnerAlpinePuristMutexPatch.MutexLockedIcons.Contains(__instance)) { ((Graphic)__instance.image).color = Color.Lerp(((Graphic)__instance.image).color, MutexLockedColor, Time.unscaledDeltaTime * 15f); } } } [HarmonyPatch(typeof(M_Gamemode), "StartFreshGamemode")] public static class AlpinePuristActivationLogPatch { [HarmonyPostfix] public static void Postfix(M_Gamemode __instance) { Plugin.InvalidateAlpinePuristCache(); if (Plugin.AlpinePuristActive) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"[AlpinePurist] Active for this run — climbing tools will be blocked"); } } } } [HarmonyPatch(typeof(UI_TrinketPicker), "SelectTrinket")] public static class AlpinePuristCacheInvalidateOnSelectPatch { [HarmonyPostfix] public static void Postfix() { Plugin.InvalidateAlpinePuristCache(); } } [HarmonyPatch(typeof(Item_Object), "Start")] public static class AlpinePuristBanItemSpawnPatch { [HarmonyPostfix] public static void Postfix(Item_Object __instance) { if (Plugin.AlpinePuristActive && __instance?.itemData != null) { string prefabName = __instance.itemData.prefabName; if (prefabName != null && Plugin.AlpinePuristBlockedPrefabs.Contains(prefabName)) { ((Component)__instance).gameObject.SetActive(false); } } } } [HarmonyPatch(typeof(Item_Object), "Start")] public static class AxeItemObjectTrackPatch { [HarmonyPostfix] public static void Postfix(Item_Object __instance) { if (__instance?.itemData != null && !(__instance.itemData.itemTag != "climbingaxe")) { AxeModHandler.RegisterTrackedAxe(__instance); } } } [HarmonyPatch(typeof(ENV_VendingMachine), "GenerateOptions")] public static class AlpinePuristBanVendingPatch { [HarmonyPrefix] public static void Prefix(ENV_VendingMachine __instance) { if (!Plugin.AlpinePuristActive || __instance?.purchaseList == null) { return; } for (int num = __instance.purchaseList.Count - 1; num >= 0; num--) { string text = __instance.purchaseList[num]?.itemObject?.itemData?.prefabName; if (text != null && Plugin.AlpinePuristBlockedPrefabs.Contains(text)) { __instance.purchaseList.RemoveAt(num); } } } } [HarmonyPatch(typeof(UI_TrinketPicker), "ReloadTrinkets")] public static class AlpinePuristDescriptionRefreshPatch { public const string BaseDescription = "Start with axes instead of the hammer. Pitons, auto-pitons, rebar, and rebar-ropes do not appear in the world or in vending machines. Related perks are disabled."; [HarmonyPostfix] public static void Postfix(UI_TrinketPicker __instance) { Trinket runtimeTrinket = TrinketRegistry.GetRuntimeTrinket("cici_alpine_purist"); if (!((Object)(object)runtimeTrinket == (Object)null)) { object? obj = AccessTools.Field(typeof(UI_TrinketPicker), "currentGamemode")?.GetValue(__instance); object? obj2 = ((obj is M_Gamemode) ? obj : null) ?? CL_GameManager.GetBaseGamemode(); GameStats val = ((obj2 == null) ? null : ((M_Gamemode)obj2).GetGamemodeSaveData()?.stats); float num = 0f; try { float num2 = ((val != null) ? StatManager.GetStatisticFloat(val, "alpine-purist-best-time") : 0f); float num3 = Plugin.LoadAlpinePuristBestTime(); num = ((num2 > 0f && num3 > 0f) ? Mathf.Min(num2, num3) : ((num2 > 0f) ? num2 : num3)); } catch { } string text = "Start with axes instead of the hammer. Pitons, auto-pitons, rebar, and rebar-ropes do not appear in the world or in vending machines. Related perks are disabled."; if (num > 0f) { text = text + "\nBest speedrun: " + FormatTime(num) + ""; } runtimeTrinket.description = text; } } private static string FormatTime(float seconds) { int num = (int)(seconds / 60f); float num2 = seconds - (float)num * 60f; return $"{num:00}:{num2:00.00}"; } } [HarmonyPatch(typeof(App_PerkPage), "GenerateCards")] public static class AlpinePuristTerminalPerkFilterPatch { private static readonly FieldInfo _cardsField = AccessTools.Field(typeof(App_PerkPage), "cards"); [HarmonyPostfix] public static void Postfix(App_PerkPage __instance) { if (!Plugin.AlpinePuristActive || !(_cardsField?.GetValue(__instance) is List list)) { return; } for (int num = list.Count - 1; num >= 0; num--) { App_PerkPage_Card val = list[num]; if (!((Object)(object)val?.perk == (Object)null) && IsPerkBlockedByAlpinePurist(val.perk, out var reason)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[AlpinePurist] Removed terminal perk card '" + ((Object)val.perk).name + "' (" + reason + ")")); } ((Component)val).gameObject.SetActive(false); list.RemoveAt(num); } } } public static bool IsPerkBlockedByAlpinePurist(Perk perk, out string reason) { reason = null; if ((Object)(object)perk == (Object)null) { return false; } string text = perk.description?.ToLowerInvariant(); if (!string.IsNullOrEmpty(text)) { string[] alpinePuristBlockedPerkSubstrings = Plugin.AlpinePuristBlockedPerkSubstrings; foreach (string text2 in alpinePuristBlockedPerkSubstrings) { if (text.Contains(text2)) { reason = "description mentions '" + text2 + "'"; return true; } } } string text3 = ((Object)perk).name?.ToLowerInvariant(); if (!string.IsNullOrEmpty(text3)) { string[] alpinePuristBlockedPerkSubstrings = Plugin.AlpinePuristBlockedPerkNameSubstrings; foreach (string text4 in alpinePuristBlockedPerkSubstrings) { if (text3.Contains(text4)) { reason = "name matches '" + text4 + "'"; return true; } } } return false; } } [HarmonyPatch(typeof(ENV_VendingMachine), "GenerateOptions")] public static class CiciYellowAxeVendingInjectPatch { public const float YellowAxeVendingChance = 0.05f; [HarmonyPostfix] public static void Postfix(ENV_VendingMachine __instance) { if (!((Object)(object)__instance == (Object)null) && __instance.buttons != null && __instance.buttons.Length != 0 && !Plugin.AlpinePuristActive && !(Random.value > 0.05f)) { Purchase orBuildYellowAxeVendingPurchase = Plugin.GetOrBuildYellowAxeVendingPurchase(); if (orBuildYellowAxeVendingPurchase != null) { int num = Random.Range(0, __instance.buttons.Length); __instance.buttons[num].purchase = orBuildYellowAxeVendingPurchase; __instance.buttons[num].available = true; } } } } [HarmonyPatch(typeof(App_PerkPage), "GenerateCards")] public static class CiciRedAxePerkInjectPatch { public const float MendingAxesPerkChance = 1f / 30f; private static readonly FieldInfo _cardsField = AccessTools.Field(typeof(App_PerkPage), "cards"); [HarmonyPostfix] public static void Postfix(App_PerkPage __instance) { if ((Object)(object)__instance == (Object)null || Plugin.AlpinePuristActive || Random.value > 1f / 30f || !(_cardsField?.GetValue(__instance) is List list) || list.Count == 0) { return; } Perk orBuildRedAxePerkAsset = Plugin.GetOrBuildRedAxePerkAsset(); if ((Object)(object)orBuildRedAxePerkAsset == (Object)null) { return; } try { int index = Random.Range(0, list.Count); list[index].Initialize(__instance, orBuildRedAxePerkAsset); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[RedAxePerk] Inject failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(ENT_Player), "AddPerk")] public static class CiciRedAxePerkGrantPatch { [CompilerGenerated] private sealed class d__2 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; DoGrantRedAxes(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPostfix] public static void Postfix(Perk perk) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[RedAxePerk] AddPerk fired — id='" + perk?.id + "' name='" + ((perk != null) ? ((Object)perk).name : null) + "'")); } if ((Object)(object)perk == (Object)null || perk.id != "cici_red_axes_perk") { return; } AxeModHandler axeModHandler = Object.FindObjectOfType(); if ((Object)(object)axeModHandler == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)"[RedAxePerk] No AxeModHandler in scene — running grant directly"); } DoGrantRedAxes(); } else { ((MonoBehaviour)axeModHandler).StartCoroutine(GrantRedAxesNextFrame()); } } private static void DoGrantRedAxes() { //IL_007f: Unknown result type (might be due to invalid IL or missing references) try { Plugin.EnsureRedAxeTemplate(); } catch { } if ((Object)(object)Plugin.RedAxeTemplate == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[RedAxePerk] RedAxeTemplate null at grant"); } return; } Inventory instance = Inventory.instance; if ((Object)(object)instance == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)"[RedAxePerk] Inventory.instance null at grant"); } return; } for (int i = 0; i < 2; i++) { try { Item clone = Plugin.RedAxeTemplate.itemData.GetClone((Item)null); instance.AddItemToInventoryScreen(new Vector3(0.15f * ((float)i - 0.5f), 0.1f, 1f), clone, true, false, true); } catch (Exception ex) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("[RedAxePerk] Grant failed: " + ex.Message)); } } } ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)"[RedAxePerk] Granted 2 red axes after perk purchase"); } } [IteratorStateMachine(typeof(d__2))] private static IEnumerator GrantRedAxesNextFrame() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__2(0); } } [HarmonyPatch(typeof(CL_GameManager), "Win")] public static class AlpinePuristSpeedrunLogPatch { private static readonly FieldInfo _gameTimeField = AccessTools.Field(typeof(CL_GameManager), "gameTime"); public const string SpeedrunStatKey = "alpine-purist-best-time"; [HarmonyPostfix] public static void Postfix(CL_GameManager __instance) { if (!Plugin.AlpinePuristActive) { return; } try { M_Gamemode currentGamemode = CL_GameManager.GetCurrentGamemode(); if ((Object)(object)currentGamemode == (Object)null) { return; } SaveData saveData = StatManager.saveData; List list = ((saveData != null) ? saveData.GetGamemodeTrinkets(currentGamemode.GetGamemodeName(true)) : null); if (list == null || list.Count != 1 || !list[0].ToLowerInvariant().Contains("cici_alpine_purist")) { return; } if (CommandConsole.hasCheated) { float num = (float)(_gameTimeField?.GetValue(__instance) ?? ((object)0f)); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[AlpinePurist] Run complete — {num:F2}s BUT cheats were used. Time not saved."); } return; } float num2 = (float)(_gameTimeField?.GetValue(__instance) ?? ((object)0f)); ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"[AlpinePurist] Speedrun complete — {num2:F2}s"); } GameStats val = currentGamemode.GetGamemodeSaveData()?.stats; if (val == null) { return; } float statisticFloat = StatManager.GetStatisticFloat(val, "alpine-purist-best-time"); float num3 = Plugin.LoadAlpinePuristBestTime(); float num4 = ((statisticFloat > 0f && num3 > 0f) ? Mathf.Min(statisticFloat, num3) : ((statisticFloat > 0f) ? statisticFloat : num3)); bool flag = num4 <= 0f; bool flag2 = !flag && num2 < num4; if (flag || flag2) { val.UpdateStatistic("alpine-purist-best-time", (object)num2, (DataType)2, (ModType)0, (DisplayType)4, (ModType)1); Plugin.SaveAlpinePuristBestTime(num2); if (flag) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)$"[AlpinePurist] First speedrun logged: {num2:F2}s"); } } else { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)$"[AlpinePurist] New best: {num2:F2}s (prev {num4:F2}s)"); } } } else { ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)$"[AlpinePurist] Run time {num2:F2}s (not a best — {num4:F2}s still stands)"); } } } catch (Exception ex) { ManualLogSource log6 = Plugin.Log; if (log6 != null) { log6.LogWarning((object)("[AlpinePurist] Speedrun log failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(Trinket), "GetDescription")] public static class WallRunnerTitleYellowPatch { private const string YellowHex = "#FFEB1A"; private const string GreenHex = "#7AFF4D"; [HarmonyPrefix] public static bool Prefix(Trinket __instance, ref string __result) { if (__instance == null || ((Object)__instance).name == null) { return true; } string text = null; if (((Object)__instance).name.Contains("cici_wall_runner")) { text = "#FFEB1A"; } else if (((Object)__instance).name.Contains("cici_free_climber")) { text = "#7AFF4D"; } if (text == null) { return true; } __result = "Trinket: " + __instance.title + ". " + __instance.description + "\n" + __instance.flavorText + ""; return false; } } [HarmonyPatch(typeof(CL_AssetManager), "GetAssetGameObject")] public static class AxeAssetLookupPatch { [HarmonyPostfix] public static void Postfix(string name, ref GameObject __result) { if ((Object)(object)__result != (Object)null) { return; } switch (name) { case "ClimbingAxe": try { Plugin.EnsureAxeTemplate(); } catch { } if ((Object)(object)Plugin.AxeTemplate != (Object)null) { __result = ((Component)Plugin.AxeTemplate).gameObject; } break; case "ClimbingAxe_Red": try { Plugin.EnsureRedAxeTemplate(); } catch { } if ((Object)(object)Plugin.RedAxeTemplate != (Object)null) { __result = ((Component)Plugin.RedAxeTemplate).gameObject; } break; case "ClimbingAxe_Green": try { Plugin.EnsureGreenAxeTemplate(); } catch { } if ((Object)(object)Plugin.GreenAxeTemplate != (Object)null) { __result = ((Component)Plugin.GreenAxeTemplate).gameObject; } break; } } } [HarmonyPatch(typeof(CL_AssetManager), "GetFullCombinedAssetDatabase")] public static class AxeSpawnItemDatabasePatch { [HarmonyPostfix] public static void Postfix(WKAssetDatabase __result) { if (!((Object)(object)__result == (Object)null)) { if (__result.itemPrefabs == null) { __result.itemPrefabs = new List(); } try { Plugin.EnsureAxeTemplate(); } catch { } try { Plugin.EnsureRedAxeTemplate(); } catch { } try { Plugin.EnsureGreenAxeTemplate(); } catch { } List itemPrefabs = __result.itemPrefabs; Item_Object axeTemplate = Plugin.AxeTemplate; AddIfMissing(itemPrefabs, (axeTemplate != null) ? ((Component)axeTemplate).gameObject : null); List itemPrefabs2 = __result.itemPrefabs; Item_Object redAxeTemplate = Plugin.RedAxeTemplate; AddIfMissing(itemPrefabs2, (redAxeTemplate != null) ? ((Component)redAxeTemplate).gameObject : null); List itemPrefabs3 = __result.itemPrefabs; Item_Object greenAxeTemplate = Plugin.GreenAxeTemplate; AddIfMissing(itemPrefabs3, (greenAxeTemplate != null) ? ((Component)greenAxeTemplate).gameObject : null); } } private static void AddIfMissing(List list, GameObject go) { if ((Object)(object)go == (Object)null) { return; } for (int i = 0; i < list.Count; i++) { if ((Object)(object)list[i] == (Object)(object)go) { return; } } list.Add(go); } } [HarmonyPatch(typeof(HandItem), "Initialize")] public static class AxeRangePatch { [HarmonyPostfix] public static void Postfix(HandItem __instance, Item i) { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown if (i?.itemTag != "climbingaxe") { return; } HandItem_Melee val = (HandItem_Melee)(object)((__instance is HandItem_Melee) ? __instance : null); if (val != null) { val.range = 4f; val.canCharge = true; val.minimumChargeAttackTime = 0.05f; val.chargeAttackDamage = 1f; } if (!(i.prefabName == "ClimbingAxe_Green")) { return; } Material val2 = Plugin.EnsureGreenAxeShimmerSpriteMaterial(); Sprite val3 = Plugin.AxeGreenSprite ?? Plugin.AxeHandSprite; if (!((Object)(object)val2 != (Object)null) || !((Object)(object)val3 != (Object)null) || !((Object)(object)val3.texture != (Object)null)) { return; } SpriteRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren(true); foreach (SpriteRenderer val4 in componentsInChildren) { if (!((Object)(object)val4 == (Object)null)) { string name = ((Object)((Component)val4).gameObject).name; if (!(name != "Sprite") || !(name != "ChargeSprite")) { Material val5 = new Material(val2) { name = ((Object)val2).name + "_Inst" }; val5.SetTexture("_MainTex", (Texture)(object)val3.texture); Object.DontDestroyOnLoad((Object)(object)val5); ((Renderer)val4).sharedMaterial = val5; } } } } } [HarmonyPatch(typeof(HandItem_Melee), "Use")] public static class AxeAutoReleasePatch { [HarmonyPostfix] public static void Postfix(HandItem_Melee __instance) { if (!(((HandItem)(__instance?)).item?.itemTag != "climbingaxe") && !((HandItem)__instance).used && !AxeModHandler.HasPendingAutoRelease(__instance)) { AxeModHandler.ScheduleAutoRelease(__instance, 0.5f); } } } [HarmonyPatch(typeof(HandItem_Melee), "Hit")] public static class AxeHitPatch { internal static readonly FieldInfo _hitField = AccessTools.Field(typeof(HandItem_Melee), "hit"); internal static readonly FieldInfo _hasHitField = AccessTools.Field(typeof(HandItem_Melee), "hasHit"); internal static readonly FieldInfo _hitTaggerField = AccessTools.Field(typeof(HandItem_Melee), "hitTagger"); internal static readonly FieldInfo _grabAnywhereHitField = AccessTools.Field(typeof(ENT_Player), "grabAnywhereHit"); internal static readonly FieldInfo _grabAnywherePositionField = AccessTools.Field(typeof(ENT_Player), "grabAnywherePosition"); public static bool OurAxeIsHitting; public const float RedAxeDamageMultiplier = 1.5f; private static bool _damageBoostActive; private static float _cachedDamage; private static float _cachedChargeDamage; [HarmonyPrefix] public static void Prefix(HandItem_Melee __instance) { if (((HandItem)(__instance?)).item?.itemTag == "climbingaxe") { OurAxeIsHitting = true; AxeModHandler.MarkAxeUsedNow(((HandItem)__instance).item); if (((HandItem)__instance).item.prefabName == "ClimbingAxe_Red") { _cachedDamage = __instance.damage; _cachedChargeDamage = __instance.chargeAttackDamage; __instance.damage = _cachedDamage * 1.5f; __instance.chargeAttackDamage = _cachedChargeDamage * 1.5f; _damageBoostActive = true; } } } [HarmonyPostfix] public static void Postfix(HandItem_Melee __instance) { //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) if (_damageBoostActive && (Object)(object)__instance != (Object)null) { __instance.damage = _cachedDamage; __instance.chargeAttackDamage = _cachedChargeDamage; _damageBoostActive = false; } bool num = ((HandItem)(__instance?)).item?.itemTag == "climbingaxe"; if (num) { OurAxeIsHitting = false; } if (!num) { return; } bool flag = (bool)(_hasHitField?.GetValue(__instance) ?? ((object)false)); RaycastHit hit = (RaycastHit)_hitField.GetValue(__instance); object? value = _hitTaggerField.GetValue(__instance); ObjectTagger val = (ObjectTagger)((value is ObjectTagger) ? value : null); if (flag && Plugin.AxeHitClips.Count > 0) { AudioClip val2 = Plugin.AxeHitClips[Random.Range(0, Plugin.AxeHitClips.Count)]; if ((Object)(object)val2 != (Object)null) { AudioSource.PlayClipAtPoint(val2, ((RaycastHit)(ref hit)).point); } } if (flag) { try { CL_CameraControl.Shake(0.025f); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Shake failed: " + ex.Message)); } } bool flag2 = flag; if (flag2 && !Plugin.IsInfiniteDurability(((HandItem)__instance).item) && Plugin.GetDurability(((HandItem)__instance).item) <= 0) { flag2 = false; } if (flag2 && (Object)(object)val != (Object)null && val.HasTag("Damageable")) { flag2 = false; } if (flag2 && AxeModHandler.HasActiveLodge(__instance)) { flag2 = false; } if (flag2) { AxeModHandler.QueuePendingLodge(__instance, hit, 0f); } else { AxeModHandler.DislodgeAxe(__instance); } } internal static void DoLodgeNow(HandItem_Melee axe, RaycastHit hit) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SpawnTempHandhold(axe, hit); } private static void SpawnTempHandhold(HandItem_Melee axe, RaycastHit hit) { //IL_0570: Unknown result type (might be due to invalid IL or missing references) //IL_0575: Unknown result type (might be due to invalid IL or missing references) //IL_057a: Unknown result type (might be due to invalid IL or missing references) //IL_057f: Unknown result type (might be due to invalid IL or missing references) //IL_0583: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_05f8: Unknown result type (might be due to invalid IL or missing references) //IL_060d: Unknown result type (might be due to invalid IL or missing references) //IL_05b7: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c1: Unknown result type (might be due to invalid IL or missing references) //IL_05c6: Unknown result type (might be due to invalid IL or missing references) //IL_05ca: Unknown result type (might be due to invalid IL or missing references) //IL_05cf: Unknown result type (might be due to invalid IL or missing references) //IL_05a9: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05eb: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_05ed: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Unknown result type (might be due to invalid IL or missing references) //IL_04af: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04c3: Unknown result type (might be due to invalid IL or missing references) //IL_04d1: Unknown result type (might be due to invalid IL or missing references) //IL_04e4: Unknown result type (might be due to invalid IL or missing references) //IL_051e: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Unknown result type (might be due to invalid IL or missing references) //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Unknown result type (might be due to invalid IL or missing references) if (AxeModHandler.HasActiveLodge(axe) && AxeModHandler.DislodgeAndReportBreak(axe)) { return; } ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null || ((Hand_Base)axe).hand == null) { Plugin.Log.LogWarning((object)"SpawnTempHandhold: player or axe.hand is null"); return; } int id = ((Hand_Base)axe).hand.id; CL_Handhold[] grabAnywhereFakeHandholds = playerObject.grabAnywhereFakeHandholds; if (grabAnywhereFakeHandholds == null || grabAnywhereFakeHandholds.Length <= id || (Object)(object)grabAnywhereFakeHandholds[id] == (Object)null) { Plugin.Log.LogWarning((object)"grabAnywhereFakeHandholds not set up on player"); return; } CL_Handhold val = grabAnywhereFakeHandholds[id]; try { Transform[] array = _grabAnywhereHitField?.GetValue(playerObject) as Transform[]; Vector3[] array2 = _grabAnywherePositionField?.GetValue(playerObject) as Vector3[]; if (array != null) { array[id] = ((Component)((RaycastHit)(ref hit)).collider).transform; } if (array2 != null) { array2[id] = ((Component)((RaycastHit)(ref hit)).collider).transform.InverseTransformPoint(((RaycastHit)(ref hit)).point); } ((Component)val).transform.position = ((RaycastHit)(ref hit)).point; ((Component)val).transform.rotation = Quaternion.identity; ((Component)val).gameObject.SetActive(true); GameObject val2 = null; Vector3 val6; try { bool flag = ((HandItem)(axe?)).item?.prefabName == "ClimbingAxe_Red"; bool flag2 = Plugin.IsInfiniteDurability(((HandItem)(axe?)).item); GameObject val3 = (flag2 ? Plugin.GreenAxePrefab : (flag ? Plugin.RedAxePrefab : Plugin.AxePrefab)) ?? Plugin.AxePrefab ?? CL_AssetManager.GetAssetGameObject("Item_Hammer", ""); if ((Object)(object)val3 != (Object)null) { GameObject val4 = new GameObject("AxeStuckTemp"); val4.SetActive(false); val2 = Object.Instantiate(val3, val4.transform); ((Object)val2).name = "ClimbingAxe_LodgedVisual"; Collider[] componentsInChildren = val2.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } Rigidbody[] componentsInChildren2 = val2.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } Item_Object[] componentsInChildren3 = val2.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren3.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[i]); } CL_Prop[] componentsInChildren4 = val2.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren4.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren4[i]); } CL_Handhold[] componentsInChildren5 = val2.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren5.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren5[i]); } List list = new List(); Transform[] componentsInChildren6 = val2.GetComponentsInChildren(true); foreach (Transform val5 in componentsInChildren6) { if (!((Object)(object)val5 == (Object)null) && ((Object)((Component)val5).gameObject).name.StartsWith("Scan_Target")) { list.Add(val5); } } foreach (Transform item in list) { if ((Object)(object)item != (Object)null) { Object.DestroyImmediate((Object)(object)((Component)item).gameObject); } } int layer = LayerMask.NameToLayer("Ignore Raycast"); componentsInChildren6 = val2.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren6.Length; i++) { ((Component)componentsInChildren6[i]).gameObject.layer = layer; } if (flag2) { Plugin.ApplyGameShader(val2, addShimmer: true, Plugin.GreenShimmerColor); } else { Plugin.ApplyGameShader(val2); } Transform currentLevelParentRoot = WorldLoader.GetCurrentLevelParentRoot(); if ((Object)(object)currentLevelParentRoot != (Object)null) { val2.transform.SetParent(currentLevelParentRoot, false); } val2.transform.position = ((RaycastHit)(ref hit)).point + ((RaycastHit)(ref hit)).normal * 0.1f; _ = Camera.main; val6 = Vector3.Cross(((RaycastHit)(ref hit)).normal, Vector3.up); Vector3 val7 = ((Vector3)(ref val6)).normalized; if (((Vector3)(ref val7)).sqrMagnitude < 0.001f) { val7 = Vector3.right; } Quaternion val8 = Quaternion.LookRotation(-((RaycastHit)(ref hit)).normal) * Quaternion.Euler(Plugin.LodgedAxeEulerOffset); Quaternion rotation = Quaternion.AngleAxis(40f, val7) * val8; Transform parent = val2.transform.parent; Vector3 val9 = (((Object)(object)parent != (Object)null) ? parent.lossyScale : Vector3.one); Vector3 val10 = default(Vector3); ((Vector3)(ref val10))..ctor((val9.x < 0f) ? (-1f) : 1f, (val9.y < 0f) ? (-1f) : 1f, (val9.z < 0f) ? (-1f) : 1f); _ = val10 != Vector3.one; val2.transform.rotation = rotation; val2.transform.localScale = val10; _ = ((Component)((RaycastHit)(ref hit)).collider).transform.eulerAngles; UT_SoftParent val11 = val2.AddComponent(); val11.Initialize(((Component)((RaycastHit)(ref hit)).collider).transform); if ((Object)(object)val11.parent != (Object)null) { AxeLodgeRotationFix.Track(val11, Quaternion.Inverse(val11.parent.rotation) * val2.transform.rotation); } val2.SetActive(true); Object.Destroy((Object)(object)val4); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Stuck-axe visual spawn failed: " + ex.Message)); } val6 = Vector3.ProjectOnPlane(((RaycastHit)(ref hit)).normal, Vector3.up); Vector3 wallNormal = ((Vector3)(ref val6)).normalized; if (((Vector3)(ref wallNormal)).sqrMagnitude < 0.001f) { Camera main = Camera.main; Vector3 val12; if (!((Object)(object)main != (Object)null)) { val12 = Vector3.forward; } else { val6 = Vector3.ProjectOnPlane(((Component)main).transform.forward, Vector3.up); val12 = -((Vector3)(ref val6)).normalized; } Vector3 val13 = val12; wallNormal = ((((Vector3)(ref val13)).sqrMagnitude > 0.001f) ? val13 : Vector3.forward); } AxeModHandler.RegisterHandhold(axe, ((Component)val).gameObject, val2, wallNormal); try { ((Hand_Base)axe).hand.GrabHold(((Component)val).transform, ((RaycastHit)(ref hit)).point, (InteractionInfo)null); ((Hand_Base)axe).hand.lockHand = true; } catch (Exception ex2) { Plugin.Log.LogWarning((object)("GrabHold failed: " + ex2.Message)); } } catch (Exception arg) { Plugin.Log.LogError((object)$"SpawnTempHandhold failed: {arg}"); } } } public class AxeModHandler : MonoBehaviour { private struct ActiveLodge { public GameObject handhold; public GameObject stuckVisual; public bool firstPersonHidden; public Hand hand; public Item axeItem; public Vector3 wallNormal; } private struct PendingLodge { public float fireAt; public RaycastHit hit; } private struct AxeAppearance { public bool IsGreen; public bool IsRed; public bool IsBroken; } private struct CachedRender { public Mesh Mesh; public Material[] Materials; } private class CachedHandItemLists { public HandItem HandItem; public readonly List MeshFilters = new List(8); public readonly List MeshRenderers = new List(8); public readonly List SpriteRenderers = new List(16); } [CompilerGenerated] private sealed class d__31 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__31(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0118: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; try { Plugin.EnsureRedAxeTemplate(); } catch { } if ((Object)(object)Plugin.RedAxeTemplate == (Object)null) { return false; } Inventory instance = Inventory.instance; if ((Object)(object)instance == (Object)null) { return false; } int num = 0; if (instance.bagItems != null) { foreach (Item bagItem in instance.bagItems) { if (IsRedAxe(bagItem)) { num++; } } } if (instance.itemHands != null) { ItemHand[] itemHands = instance.itemHands; foreach (ItemHand val in itemHands) { if (val != null && IsRedAxe(val.currentItem)) { num++; } } } int num2 = Math.Max(0, 2 - num); for (int j = 0; j < num2; j++) { try { Item clone = Plugin.RedAxeTemplate.itemData.GetClone((Item)null); instance.AddItemToInventoryScreen(new Vector3(0.15f * ((float)j - 0.5f), 0.1f, 1f), clone, true, false, true); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[AlpinePurist] Revive top-up failed: " + ex.Message)); } } } if (num2 > 0) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"[AlpinePurist] Revive top-up — added {num2} red axe(s)"); } } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private bool _jumpHookInstalled; private bool _wasDead; private static readonly FieldInfo _gManDeadField = AccessTools.Field(typeof(CL_GameManager), "dead"); private static readonly Dictionary _activeLodges = new Dictionary(); private static readonly Dictionary _pendingLodges = new Dictionary(); private static readonly Dictionary _lastUseTime = new Dictionary(); private float _nextRegenCheck; private static readonly MaterialPropertyBlock _mpb = new MaterialPropertyBlock(); private static readonly int _colorId = Shader.PropertyToID("_Color"); private static readonly Dictionary _pendingAutoReleases = new Dictionary(); private static readonly Dictionary _lastAppliedAppearance = new Dictionary(); private static readonly HashSet _trackedAxes = new HashSet(); private static readonly Dictionary _cachedRenderByPrefab = new Dictionary(); private static readonly Dictionary _handItemListCache = new Dictionary(); private void OnEnable() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnCameraPreCull)); } private void OnDisable() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnCameraPreCull)); } private void OnCameraPreCull(Camera cam) { if (!((Object)(object)cam != (Object)(object)Camera.main)) { UpdateTintAndSlide(); } } private void UpdateTintAndSlide() { ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null || playerObject.hands == null) { return; } Hand[] hands = playerObject.hands; foreach (Hand val in hands) { if (val == null) { continue; } HandItem handItem = val.GetHandItem(); if (!(handItem?.item?.itemTag != "climbingaxe")) { Sprite spriteForDurability = Plugin.GetSpriteForDurability(handItem.item); SwapHandItemMeshIfNeeded(handItem); SwapHandItemWeaponSpriteIfNeeded(handItem, spriteForDurability); HandItem_Melee val2 = (HandItem_Melee)(object)((handItem is HandItem_Melee) ? handItem : null); if (val2 != null) { UpdateAimCircleForAxe(playerObject, val2); } HandItem_Melee val3 = (HandItem_Melee)(object)((handItem is HandItem_Melee) ? handItem : null); if (val3 != null && _activeLodges.TryGetValue(val3, out var value)) { _ = (Object)(object)value.handhold != (Object)null; } } } } public static Vector3 GetWallNormalForHand(Hand hand) { //IL_0003: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (hand == null) { return Vector3.zero; } foreach (KeyValuePair activeLodge in _activeLodges) { ActiveLodge value = activeLodge.Value; if (!((Object)(object)value.handhold == (Object)null)) { CL_Handhold component = value.handhold.GetComponent(); if ((Object)(object)hand.handhold == (Object)(object)component) { return value.wallNormal; } } } return Vector3.zero; } public static void QueuePendingLodge(HandItem_Melee axe, RaycastHit hit, float delay) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)axe == (Object)null)) { _pendingLodges[axe] = new PendingLodge { fireAt = Time.time + delay, hit = hit }; } } public static void CancelPendingLodge(HandItem_Melee axe) { if (!((Object)(object)axe == (Object)null)) { _pendingLodges.Remove(axe); } } public static bool HasActiveLodge(HandItem_Melee axe) { if ((Object)(object)axe != (Object)null) { return _activeLodges.ContainsKey(axe); } return false; } public static void MarkAxeUsedNow(Item axeItem) { if (axeItem != null) { _lastUseTime[axeItem] = Time.time; } } public static bool HasPendingAutoRelease(HandItem_Melee axe) { if ((Object)(object)axe != (Object)null) { return _pendingAutoReleases.ContainsKey(axe); } return false; } public static void ScheduleAutoRelease(HandItem_Melee axe, float delay) { if (!((Object)(object)axe == (Object)null)) { _pendingAutoReleases[axe] = Time.time + delay; } } public static bool DislodgeAndReportBreak(HandItem_Melee axe) { if ((Object)(object)axe == (Object)null) { return false; } _pendingLodges.Remove(axe); return EndLodgeAndTick(axe); } public static void RegisterHandhold(HandItem_Melee axe, GameObject handhold, GameObject stuckVisual, Vector3 wallNormal) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) SetFirstPersonAxeVisible(axe, visible: false); _activeLodges[axe] = new ActiveLodge { handhold = handhold, stuckVisual = stuckVisual, firstPersonHidden = true, hand = ((Hand_Base)axe).hand, axeItem = ((HandItem)axe).item, wallNormal = wallNormal }; AutoDislodgeOtherHand(axe); } private static void AutoDislodgeOtherHand(HandItem_Melee currentAxe) { if ((Object)(object)currentAxe == (Object)null || ((Hand_Base)currentAxe).hand == null) { return; } List list = null; foreach (KeyValuePair activeLodge in _activeLodges) { if (!((Object)(object)activeLodge.Key == (Object)(object)currentAxe) && activeLodge.Value.hand != null && activeLodge.Value.hand != ((Hand_Base)currentAxe).hand) { (list ?? (list = new List())).Add(activeLodge.Key); } } if (list == null) { return; } foreach (HandItem_Melee item in list) { DislodgeAxe(item); } } public static void DislodgeAxe(HandItem_Melee axe) { if ((Object)(object)axe != (Object)null) { _pendingLodges.Remove(axe); } EndLodgeAndTick(axe); } private static bool EndLodgeAndTick(HandItem_Melee axe) { //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) if (!_activeLodges.TryGetValue(axe, out var value)) { return false; } bool flag = (Object)(object)value.handhold != (Object)null; if (value.hand != null) { value.hand.lockHand = false; try { value.hand.DropHand(false); } catch (Exception ex) { Plugin.Log.LogWarning((object)("DropHand failed during cleanup: " + ex.Message)); } } ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject != (Object)null && value.hand != null) { try { int id = value.hand.id; if (AxeHitPatch._grabAnywhereHitField?.GetValue(playerObject) is Transform[] array && id < array.Length) { array[id] = null; } if (playerObject.grabAnywhereFakeHandholds != null && id < playerObject.grabAnywhereFakeHandholds.Length && (Object)(object)playerObject.grabAnywhereFakeHandholds[id] != (Object)null) { ((Component)playerObject.grabAnywhereFakeHandholds[id]).gameObject.SetActive(false); } } catch (Exception ex2) { Plugin.Log.LogWarning((object)("grabAnywhere cleanup failed: " + ex2.Message)); } } if ((Object)(object)value.stuckVisual != (Object)null) { Object.Destroy((Object)(object)value.stuckVisual); } if ((Object)(object)axe != (Object)null) { SetFirstPersonAxeVisible(axe, visible: true); } _activeLodges.Remove(axe); if (value.axeItem != null) { if (Plugin.IsInfiniteDurability(value.axeItem)) { return false; } MarkAxeUsedNow(value.axeItem); int num = Plugin.GetDurability(value.axeItem) - 1; if (num <= 0) { Plugin.SetDurability(value.axeItem, 0); if (flag && (Object)(object)Plugin.AxeBreakClip != (Object)null) { Camera main = Camera.main; Vector3 val = (((Object)(object)main != (Object)null) ? ((Component)main).transform.position : Vector3.zero); AudioSource.PlayClipAtPoint(Plugin.AxeBreakClip, val); } return true; } Plugin.SetDurability(value.axeItem, num); } return false; } private static void FinalizeBreak(HandItem_Melee axe) { if (!((Object)(object)axe == (Object)null)) { _pendingLodges.Remove(axe); } } private void Update() { ProcessPendingLodges(); ProcessPendingAutoReleases(); HookPlayerJumpIfNeeded(); ProcessDurabilityRegen(); DetectRespawnAndTopUpAlpinePurist(); if (Input.GetKeyDown((KeyCode)291)) { SpawnTestAxe(); } } private void DetectRespawnAndTopUpAlpinePurist() { bool flag; try { flag = _gManDeadField != null && (bool)_gManDeadField.GetValue(null); } catch { return; } bool num = _wasDead && !flag; _wasDead = flag; if (num && Plugin.AlpinePuristActive) { ((MonoBehaviour)this).StartCoroutine(TopUpAlpinePuristAxesNextFrame()); } } [IteratorStateMachine(typeof(d__31))] private IEnumerator TopUpAlpinePuristAxesNextFrame() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__31(0); } private static bool IsRedAxe(Item it) { if (it == null) { return false; } if (it.prefabName == "ClimbingAxe_Red") { return true; } if (it.itemName == "Climbing Axe (Red)") { return true; } return false; } private void ProcessDurabilityRegen() { if (Time.time < _nextRegenCheck) { return; } _nextRegenCheck = Time.time + 1f; if (_lastUseTime.Count == 0) { return; } HashSet hashSet = null; if (_activeLodges.Count > 0) { hashSet = new HashSet(); foreach (ActiveLodge value in _activeLodges.Values) { if (value.axeItem != null) { hashSet.Add(value.axeItem); } } } List list = null; foreach (Item item in new List(_lastUseTime.Keys)) { if (item == null) { (list ?? (list = new List())).Add(item); } else { if ((hashSet != null && hashSet.Contains(item)) || item.prefabName != "ClimbingAxe_Red") { continue; } float num = Time.time - _lastUseTime[item]; int durability = Plugin.GetDurability(item); if (durability >= 10) { continue; } if (durability <= 0) { if (num < 60f) { continue; } } else if (num < 15f) { continue; } Plugin.SetDurability(item, durability + 1); _lastUseTime[item] = Time.time; } } if (list == null) { return; } foreach (Item item2 in list) { _lastUseTime.Remove(item2); } } public static void RegisterTrackedAxe(Item_Object io) { if ((Object)(object)io != (Object)null) { _trackedAxes.Add(io); } } private void RefreshWorldAxeAppearances() { if (_trackedAxes.Count == 0) { return; } _trackedAxes.RemoveWhere((Item_Object io) => (Object)(object)io == (Object)null); if (_lastAppliedAppearance.Count > 0) { List list = null; foreach (Item_Object key in _lastAppliedAppearance.Keys) { if ((Object)(object)key == (Object)null) { (list ?? (list = new List())).Add(key); } } if (list != null) { foreach (Item_Object item in list) { _lastAppliedAppearance.Remove(item); } } } foreach (Item_Object trackedAxis in _trackedAxes) { if ((Object)(object)trackedAxis == (Object)null || trackedAxis.itemData == null || trackedAxis.itemData.itemTag != "climbingaxe") { continue; } bool flag = trackedAxis.itemData.prefabName == "ClimbingAxe_Green"; bool flag2 = trackedAxis.itemData.prefabName == "ClimbingAxe_Red"; bool flag3 = !flag && Plugin.GetDurability(trackedAxis.itemData) <= 0; if (_lastAppliedAppearance.TryGetValue(trackedAxis, out var value) && value.IsGreen == flag && value.IsRed == flag2 && value.IsBroken == flag3) { continue; } GameObject val = (flag ? (Plugin.GreenAxePrefab ?? Plugin.AxePrefab) : ((!flag2) ? (flag3 ? (Plugin.AxeBrokenPrefab ?? Plugin.AxePrefab) : Plugin.AxePrefab) : (flag3 ? (Plugin.RedAxeBrokenPrefab ?? Plugin.RedAxePrefab) : Plugin.RedAxePrefab))); if ((Object)(object)val == (Object)null) { continue; } MeshFilter componentInChildren = val.GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren.sharedMesh == (Object)null) { continue; } Mesh sharedMesh = componentInChildren.sharedMesh; MeshFilter[] componentsInChildren = ((Component)trackedAxis).GetComponentsInChildren(true); foreach (MeshFilter val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !((Object)((Component)val2).gameObject).name.StartsWith("ClimbingAxeHalo_") && (Object)(object)val2.sharedMesh != (Object)(object)sharedMesh) { val2.sharedMesh = sharedMesh; } } Material outlineOverride = (flag ? (Plugin.OutlineMaterialGreen ?? Plugin.OutlineMaterial) : (flag2 ? (Plugin.OutlineMaterialRed ?? Plugin.OutlineMaterial) : Plugin.OutlineMaterial)); Plugin.EnsureHaloOnGameObject(((Component)trackedAxis).gameObject, outlineOverride); _lastAppliedAppearance[trackedAxis] = new AxeAppearance { IsGreen = flag, IsRed = flag2, IsBroken = flag3 }; } } private void HookPlayerJumpIfNeeded() { if (!_jumpHookInstalled) { ENT_Player playerObject = ENT_Player.playerObject; if (!((Object)(object)playerObject == (Object)null)) { playerObject._OnJump = (Action)Delegate.Combine(playerObject._OnJump, new Action(OnPlayerJumped)); _jumpHookInstalled = true; } } } private void OnPlayerJumped() { if (_activeLodges.Count == 0) { return; } foreach (HandItem_Melee item in new List(_activeLodges.Keys)) { DislodgeAxe(item); } } private void ProcessPendingAutoReleases() { if (_pendingAutoReleases.Count == 0) { return; } List list = null; List list2 = null; foreach (KeyValuePair pendingAutoRelease in _pendingAutoReleases) { HandItem_Melee key = pendingAutoRelease.Key; if ((Object)(object)key == (Object)null || !((Component)key).gameObject.activeInHierarchy) { (list2 ?? (list2 = new List())).Add(key); } else if (Time.time >= pendingAutoRelease.Value) { (list ?? (list = new List())).Add(key); } } if (list2 != null) { foreach (HandItem_Melee item in list2) { _pendingAutoReleases.Remove(item); } } if (list == null) { return; } foreach (HandItem_Melee item2 in list) { _pendingAutoReleases.Remove(item2); try { ((HandItem)item2).StopUse(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Auto-release StopUse failed: " + ex.Message)); } } } private void ProcessPendingLodges() { //IL_0112: Unknown result type (might be due to invalid IL or missing references) if (_pendingLodges.Count == 0) { return; } List list = null; List list2 = null; foreach (KeyValuePair pendingLodge in _pendingLodges) { HandItem_Melee key = pendingLodge.Key; PendingLodge value = pendingLodge.Value; if ((Object)(object)key == (Object)null || !((Component)key).gameObject.activeInHierarchy) { (list2 ?? (list2 = new List())).Add(key); } else if (Time.time >= value.fireAt) { (list ?? (list = new List())).Add(key); } } if (list2 != null) { foreach (HandItem_Melee item in list2) { _pendingLodges.Remove(item); } } if (list == null) { return; } foreach (HandItem_Melee item2 in list) { if (_pendingLodges.TryGetValue(item2, out var value2)) { _pendingLodges.Remove(item2); AxeHitPatch.DoLodgeNow(item2, value2.hit); } } } private void LateUpdate() { if (Time.frameCount % 60 == 0) { RefreshWorldAxeAppearances(); } if (_activeLodges.Count == 0) { return; } List list = null; foreach (KeyValuePair activeLodge in _activeLodges) { HandItem_Melee key = activeLodge.Key; ActiveLodge value = activeLodge.Value; if ((Object)(object)key == (Object)null || (Object)(object)value.handhold == (Object)null) { (list ?? (list = new List())).Add(key); } else if (!((Component)key).gameObject.activeInHierarchy) { (list ?? (list = new List())).Add(key); } else if (((Hand_Base)key).hand != null) { CL_Handhold component = value.handhold.GetComponent(); if (!((Object)(object)((Hand_Base)key).hand.handhold == (Object)(object)component) && !((HandItem)key).used) { (list ?? (list = new List())).Add(key); } } } if (list == null) { return; } foreach (HandItem_Melee item in list) { _pendingLodges.Remove(item); if (EndLodgeAndTick(item)) { FinalizeBreak(item); } } } private static CachedRender GetCachedRender(GameObject prefab) { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown if ((Object)(object)prefab == (Object)null) { return default(CachedRender); } if (_cachedRenderByPrefab.TryGetValue(prefab, out var value)) { return value; } MeshFilter componentInChildren = prefab.GetComponentInChildren(true); MeshRenderer val = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).GetComponent() : null); if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren.sharedMesh == (Object)null) { return default(CachedRender); } Material[] array = null; if ((Object)(object)val != (Object)null) { Material[] sharedMaterials = ((Renderer)val).sharedMaterials; array = (Material[])(object)new Material[sharedMaterials.Length]; Shader val2 = Shader.Find("Dark Machine/SHDR_Base") ?? Shader.Find("Unlit/Texture"); for (int i = 0; i < sharedMaterials.Length; i++) { if ((Object)(object)sharedMaterials[i] == (Object)null) { continue; } Material val3 = new Material(sharedMaterials[i]); if ((Object)(object)val2 != (Object)null) { Texture val4 = (val3.HasProperty("_MainTex") ? val3.GetTexture("_MainTex") : null); val3.shader = val2; if ((Object)(object)val4 != (Object)null && val3.HasProperty("_MainTex")) { val3.SetTexture("_MainTex", val4); } } Plugin.ApplyItemShimmer(val3); array[i] = val3; } } CachedRender cachedRender = default(CachedRender); cachedRender.Mesh = componentInChildren.sharedMesh; cachedRender.Materials = array; CachedRender cachedRender2 = cachedRender; _cachedRenderByPrefab[prefab] = cachedRender2; return cachedRender2; } private static GameObject PickPrefabForItem(Item item) { if (item == null) { return Plugin.AxePrefab; } if (Plugin.IsInfiniteDurability(item)) { return Plugin.GreenAxePrefab ?? Plugin.AxePrefab; } bool num = item.prefabName == "ClimbingAxe_Red"; bool flag = Plugin.GetDurability(item) <= 0; GameObject val = ((!num) ? (flag ? (Plugin.AxeBrokenPrefab ?? Plugin.AxePrefab) : Plugin.AxePrefab) : (flag ? (Plugin.RedAxeBrokenPrefab ?? Plugin.RedAxePrefab) : Plugin.RedAxePrefab)); return val ?? Plugin.AxePrefab; } private static CachedHandItemLists GetHandItemLists(HandItem hi) { int instanceID = ((Object)hi).GetInstanceID(); if (_handItemListCache.TryGetValue(instanceID, out var value) && (Object)(object)value.HandItem == (Object)(object)hi) { return value; } value = new CachedHandItemLists { HandItem = hi }; ((Component)hi).GetComponentsInChildren(true, value.MeshFilters); ((Component)hi).GetComponentsInChildren(true, value.MeshRenderers); ((Component)hi).GetComponentsInChildren(true, value.SpriteRenderers); _handItemListCache[instanceID] = value; if (_handItemListCache.Count > 16) { PruneHandItemListCache(); } return value; } private static void PruneHandItemListCache() { List list = null; foreach (KeyValuePair item in _handItemListCache) { if ((Object)(object)item.Value.HandItem == (Object)null) { (list ?? (list = new List())).Add(item.Key); } } if (list == null) { return; } foreach (int item2 in list) { _handItemListCache.Remove(item2); } } private static void SwapHandItemMeshIfNeeded(HandItem hi) { if ((Object)(object)hi == (Object)null) { return; } GameObject val = PickPrefabForItem(hi.item); if ((Object)(object)val == (Object)null) { return; } CachedRender cachedRender = GetCachedRender(val); if ((Object)(object)cachedRender.Mesh == (Object)null) { return; } Plugin.EnsureHaloOnGameObject(((Component)hi).gameObject, Plugin.PickOutlineMaterialForItem(hi.item)); List meshFilters = GetHandItemLists(hi).MeshFilters; for (int i = 0; i < meshFilters.Count; i++) { MeshFilter val2 = meshFilters[i]; if ((Object)(object)val2 == (Object)null) { continue; } if ((Object)(object)val2.sharedMesh != (Object)(object)cachedRender.Mesh) { val2.sharedMesh = cachedRender.Mesh; } MeshRenderer component = ((Component)val2).GetComponent(); if ((Object)(object)component == (Object)null) { continue; } if (cachedRender.Materials != null && cachedRender.Materials.Length != 0) { ((Renderer)component).sharedMaterials = cachedRender.Materials; } bool num = hi.item != null && hi.item.prefabName == "ClimbingAxe_Red"; bool flag = Plugin.IsInfiniteDurability(hi.item); if (num || flag || !((Object)(object)Plugin.AxeTexture != (Object)null)) { continue; } Material[] sharedMaterials = ((Renderer)component).sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { if (!((Object)(object)sharedMaterials[j] == (Object)null) && sharedMaterials[j].HasProperty("_MainTex")) { sharedMaterials[j].SetTexture("_MainTex", (Texture)(object)Plugin.AxeTexture); } } } } private static void SwapHandItemWeaponSpriteIfNeeded(HandItem hi, Sprite desired = null) { if ((Object)(object)hi == (Object)null) { return; } if ((Object)(object)desired == (Object)null) { desired = Plugin.AxeHandSprite; } if ((Object)(object)desired == (Object)null) { return; } List spriteRenderers = GetHandItemLists(hi).SpriteRenderers; for (int i = 0; i < spriteRenderers.Count; i++) { SpriteRenderer val = spriteRenderers[i]; if (!((Object)(object)val == (Object)null)) { string name = ((Object)((Component)val).gameObject).name; if ((!(name != "Sprite") || !(name != "ChargeSprite")) && !((Object)(object)val.sprite == (Object)(object)desired)) { val.sprite = desired; } } } } private static void UpdateAimCircleForAxe(ENT_Player player, HandItem_Melee melee) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player.aimCircle == (Object)null || (Object)(object)melee == (Object)null) { return; } Camera main = Camera.main; if (!((Object)(object)main == (Object)null)) { float num = Mathf.Max(melee.sphereCastSize, 0.05f); RaycastHit val = default(RaycastHit); if (!Physics.SphereCast(((Component)main).transform.position, num, ((Component)main).transform.forward, ref val, 4f, LayerMask.op_Implicit(melee.hitMask))) { ((Component)player.aimCircle).gameObject.SetActive(false); return; } ((Component)player.aimCircle).gameObject.SetActive(true); ((Component)player.aimCircle).transform.position = ((RaycastHit)(ref val)).point + ((RaycastHit)(ref val)).normal * 0.01f; ((Component)player.aimCircle).transform.rotation = Quaternion.LookRotation(((RaycastHit)(ref val)).normal); } } private static void ApplyTintToHierarchy(GameObject root, Color tint) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return; } Renderer[] componentsInChildren = root.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Material[] materials = componentsInChildren[i].materials; for (int j = 0; j < materials.Length; j++) { if (!((Object)(object)materials[j] == (Object)null) && materials[j].HasProperty(_colorId)) { materials[j].SetColor(_colorId, tint); } } } } private static void SetFirstPersonAxeVisible(HandItem_Melee axe, bool visible) { if (!((Object)(object)axe == (Object)null)) { Renderer[] componentsInChildren = ((Component)axe).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = visible; } } } private void SpawnTestAxe() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) Plugin.EnsureAxeTemplate(); if ((Object)(object)Plugin.AxeTemplate == (Object)null) { Plugin.Log.LogError((object)"Test spawn: axe template unavailable"); return; } Camera main = Camera.main; if (!((Object)(object)main == (Object)null)) { Vector3 val = ((Component)main).transform.position + ((Component)main).transform.forward * 2f; GameObject obj = Object.Instantiate(((Component)Plugin.AxeTemplate).gameObject, val, Quaternion.identity); obj.SetActive(true); Item_Object component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { component.itemData = Plugin.CreateAxeItem(); } Plugin.Log.LogInfo((object)$"Test axe spawned at {val}"); } } } public static class WavLoader { public static AudioClip LoadFromFile(string path) { byte[] array = File.ReadAllBytes(path); if (array.Length < 44 || array[0] != 82 || array[1] != 73 || array[2] != 70 || array[3] != 70) { throw new Exception("Not a RIFF file"); } if (array[8] != 87 || array[9] != 65 || array[10] != 86 || array[11] != 69) { throw new Exception("Not a WAVE file"); } int i = 12; int num = 0; int num2 = 0; int num3 = 0; int num4 = -1; int num5 = -1; int num6; for (; i < array.Length - 8; i += 8 + num6) { string @string = Encoding.ASCII.GetString(array, i, 4); num6 = BitConverter.ToInt32(array, i + 4); if (@string == "fmt ") { num = BitConverter.ToInt16(array, i + 10); num2 = BitConverter.ToInt32(array, i + 12); num3 = BitConverter.ToInt16(array, i + 22); } else if (@string == "data") { num4 = i + 8; num5 = num6; break; } } if (num4 < 0) { throw new Exception("No data chunk found"); } int num7 = num3 / 8; int num8 = num5 / num7; float[] array2 = new float[num8]; switch (num3) { case 16: { for (int m = 0; m < num8; m++) { short num12 = BitConverter.ToInt16(array, num4 + m * 2); array2[m] = (float)num12 / 32768f; } break; } case 24: { for (int k = 0; k < num8; k++) { int num9 = array[num4 + k * 3]; int num10 = array[num4 + k * 3 + 1]; int num11 = ((sbyte)array[num4 + k * 3 + 2] << 16) | (num10 << 8) | num9; array2[k] = (float)num11 / 8388608f; } break; } case 32: { for (int l = 0; l < num8; l++) { array2[l] = BitConverter.ToSingle(array, num4 + l * 4); } break; } case 8: { for (int j = 0; j < num8; j++) { array2[j] = (float)(array[num4 + j] - 128) / 128f; } break; } default: throw new Exception($"Unsupported bit depth: {num3}"); } AudioClip obj = AudioClip.Create("climbingaxe_hit_custom", num8 / num, num, num2, false); obj.SetData(array2, 0); return obj; } } [HarmonyPatch(typeof(AudioGroup), "PlayAudioSet")] public static class SuppressHammerHitAudioPatch { [HarmonyPrefix] public static bool Prefix() { return !AxeHitPatch.OurAxeIsHitting; } } [HarmonyPatch(typeof(UT_AudioClipHandler), "PlaySound", new Type[] { typeof(string) })] public static class SuppressHammerPlaySoundPatch { [HarmonyPrefix] public static bool Prefix() { return !AxeHitPatch.OurAxeIsHitting; } } [HarmonyPatch(typeof(CL_Handhold), "HammerIn")] public static class SuppressAxeHammerPatch { [HarmonyPrefix] public static bool Prefix() { return !AxeHitPatch.OurAxeIsHitting; } } [HarmonyPatch] public static class HangWallNormalPatch { private static readonly FieldInfo _hasHitField = AccessTools.Field(typeof(ENT_Player), "hasHit"); private static readonly FieldInfo _hitNormalField = AccessTools.Field(typeof(ENT_Player), "hitNormal"); public static MethodBase TargetMethod() { return AccessTools.Method(typeof(ENT_Player), "Hang", (Type[])null, (Type[])null); } [HarmonyPrefix] public static void Prefix(ENT_Player __instance) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || __instance.hands == null) { return; } for (int i = 0; i < __instance.hands.Length; i++) { Hand val = __instance.hands[i]; if (val == null || (Object)(object)val.handhold == (Object)null) { continue; } Vector3 wallNormalForHand = AxeModHandler.GetWallNormalForHand(val); if (!(wallNormalForHand == Vector3.zero)) { try { _hasHitField?.SetValue(__instance, true); _hitNormalField?.SetValue(__instance, wallNormalForHand); break; } catch { break; } } } } } }