Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TrulySmoothLadders v0.5.4
TrulySmoothLadders.dll
Decompiled a month agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JG224.ModCore.API; using JG224.TrulySmoothLadders.Core; using JG224.TrulySmoothLadders.Patches; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("TrulySmoothLadders")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.5.4.0")] [assembly: AssemblyInformationalVersion("0.5.4")] [assembly: AssemblyProduct("TrulySmoothLadders")] [assembly: AssemblyTitle("TrulySmoothLadders")] [assembly: AssemblyVersion("0.5.4.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace JG224.TrulySmoothLadders { [BepInPlugin("jg224.TrulySmoothLadders", "TrulySmoothLadders", "0.5.4")] [BepInProcess("valheim.exe")] [BepInDependency("com.jg224.modcore", "0.5.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "jg224.TrulySmoothLadders"; public const string PluginName = "TrulySmoothLadders"; public const string PluginVersion = "0.5.4"; public const string ModCoreGuid = "com.jg224.modcore"; public const string GeneralTweaksGuid = "JG224.GeneralTweaks"; public const int ProtocolVersion = 1; public static readonly ModuleId ModuleId = new ModuleId("trulysmoothladders"); private readonly List<IDisposable> _registrations = new List<IDisposable>(); private Harmony _harmony; private bool _runtimeActive; private bool _shutDown; internal static ManualLogSource Log { get; private set; } internal static TrulySmoothLaddersConfig Settings { get; private set; } internal static ICoreServices Core { get; private set; } private void Awake() { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Settings = TrulySmoothLaddersConfig.Load((BaseUnityPlugin)(object)this, Paths.ConfigPath, ((BaseUnityPlugin)this).Logger); try { if (!ModCoreApi.IsAvailable) { throw new InvalidOperationException("ModCore did not initialize before TrulySmoothLadders."); } Core = ModCoreApi.Services; RegisterWithCore(); if (TryGetLegacyLadderOwner(out var version)) { string text = "GeneralTweaks " + version?.ToString() + " still contains smooth ladders; TrulySmoothLadders is paused to prevent duplicate ramps."; Core.Modules.SetState(ModuleId, (ModuleRuntimeState)3, text); ((BaseUnityPlugin)this).Logger.LogWarning((object)(text + " Update GeneralTweaks to 2.0.0 or newer.")); return; } _harmony = new Harmony("jg224.TrulySmoothLadders"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); _runtimeActive = true; Core.Modules.SetState(ModuleId, (ModuleRuntimeState)2, "Client-local smooth ladder ramps ready."); Game.isModded = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("TrulySmoothLadders 0.5.4 loaded; protocol " + 1 + ".")); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("TrulySmoothLadders failed to initialize safely: " + ex)); if (Core != null) { Core.Modules.SetState(ModuleId, (ModuleRuntimeState)5, ex.Message); } Shutdown(); throw; } } private void Update() { if (_runtimeActive) { LadderRampRuntime.Tick(); } } private void OnDestroy() { Shutdown(); } private void RegisterWithCore() { //IL_0029: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0059: 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_00c2: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) SemanticVersion val = default(SemanticVersion); if (!SemanticVersion.TryParse("0.5.4", ref val)) { throw new InvalidOperationException("Invalid plugin version."); } _registrations.Add(Core.Modules.Register(new ModuleDescriptor(ModuleId, "jg224.TrulySmoothLadders", "TrulySmoothLadders", val, 1, (ModuleSide)1, (ModuleRequirement)1, 0uL, 1, 1))); foreach (IDisposable item in Settings.RegisterMetadata(Core, ModuleId)) { _registrations.Add(item); } _registrations.Add(Core.Compatibility.Register(new CompatibilityRule("jg224.TrulySmoothLadders", "BetterLaddersContinued", (CompatibilityRuleKind)2, (CompatibilitySeverity)2, "Both mods replace vanilla ladder movement; remove one implementation.", "ladders"))); _registrations.Add(Core.Lifecycle.Subscribe(ModuleId, (LifecycleEventKind)9, (Action<LifecycleEvent>)delegate { LadderRampRuntime.DestroyAll(); }, 0)); _registrations.Add(Core.Lifecycle.Subscribe(ModuleId, (LifecycleEventKind)3, (Action<LifecycleEvent>)delegate { LadderRampRuntime.DestroyAll(); }, 0)); } private static bool TryGetLegacyLadderOwner(out Version version) { version = null; if (!Chainloader.PluginInfos.TryGetValue("JG224.GeneralTweaks", out var value)) { return false; } version = value.Metadata.Version; if (version != null) { return version.CompareTo(new Version(2, 0, 0)) < 0; } return false; } private void Shutdown() { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (_shutDown) { return; } _shutDown = true; _runtimeActive = false; Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; LadderRampRuntime.DestroyAll(); for (int num = _registrations.Count - 1; num >= 0; num--) { try { _registrations[num].Dispose(); } catch (Exception ex) { ManualLogSource logger = ((BaseUnityPlugin)this).Logger; if (logger != null) { logger.LogWarning((object)("Registration cleanup failed: " + ex.Message)); } } } _registrations.Clear(); if (Core != null) { Core.Metrics.RemoveOwner(ModuleId); } Core = null; Settings = null; Log = null; } } internal sealed class TrulySmoothLaddersConfig { private readonly ConfigFile _file; internal ConfigEntry<bool> BetterLaddersEnabled { get; } internal ConfigEntry<bool> AllowMonsterClimbing { get; } internal ConfigEntry<string> PrefabAdjustments { get; } internal ConfigEntry<bool> FitDiagnostics { get; } private TrulySmoothLaddersConfig(ConfigFile file) { _file = file; BetterLaddersEnabled = file.Bind<bool>("Movement", "BetterLadders", true, "Replace vanilla ladder auto-jump bouncing with smooth forward climbing."); AllowMonsterClimbing = file.Bind<bool>("Movement", "AllowMonsterClimbing", false, "Allow monsters to climb supported ladders. False blocks climbing; true restores normal climbing. Applies while BetterLadders is enabled, to monsters simulated by this client. Changes take effect immediately."); PrefabAdjustments = file.Bind<string>("Movement", "PrefabAdjustments", "", "Optional runtime prefab=width,normalOffset,endMargin in metres; e.g. wood_ladder=1.3,0.42,0.35. Width 0.5-3, offset 0-0.75, margin 0-1. Upper ends are capped at the highest tread plus 2 cm. Changes rebuild ramps on next contact."); FitDiagnostics = file.Bind<bool>("Diagnostics", "FitDiagnostics", false, "Log each successful ramp fit and rejected ladder once, including measured geometry. No per-frame success logs."); } internal static TrulySmoothLaddersConfig Load(BaseUnityPlugin plugin, string configDirectory, ManualLogSource log) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown if (!Directory.Exists(configDirectory)) { Directory.CreateDirectory(configDirectory); } string text = LegacyLadderConfigRules.FindImportSource(Directory.GetFiles(configDirectory, "*.cfg", SearchOption.TopDirectoryOnly)); string text2 = Path.Combine(configDirectory, "jg224.TrulySmoothLadders.cfg"); TrulySmoothLaddersConfig trulySmoothLaddersConfig = new TrulySmoothLaddersConfig(PluginConfigFiles.Attach(plugin, new ConfigFile(text2, true, plugin.Info.Metadata))); if (text != null) { trulySmoothLaddersConfig.ImportLegacyGeneralTweaks(text, log); } return trulySmoothLaddersConfig; } internal IEnumerable<IDisposable> RegisterMetadata(ICoreServices services, ModuleId owner) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) yield return services.Configuration.Register(new ConfigSettingDescriptor(owner, ((ConfigEntryBase)AllowMonsterClimbing).Definition.Section, ((ConfigEntryBase)AllowMonsterClimbing).Definition.Key, (ConfigScope)1, (Func<string>)(() => AllowMonsterClimbing.Value.ToString()), 1)); yield return services.Configuration.Register(new ConfigSettingDescriptor(owner, ((ConfigEntryBase)PrefabAdjustments).Definition.Section, ((ConfigEntryBase)PrefabAdjustments).Definition.Key, (ConfigScope)1, (Func<string>)(() => PrefabAdjustments.Value), 1)); yield return services.Configuration.Register(new ConfigSettingDescriptor(owner, ((ConfigEntryBase)FitDiagnostics).Definition.Section, ((ConfigEntryBase)FitDiagnostics).Definition.Key, (ConfigScope)5, (Func<string>)(() => FitDiagnostics.Value.ToString()), 1)); yield return services.Configuration.Register(new ConfigSettingDescriptor(owner, ((ConfigEntryBase)BetterLaddersEnabled).Definition.Section, ((ConfigEntryBase)BetterLaddersEnabled).Definition.Key, (ConfigScope)1, (Func<string>)(() => Convert.ToString(((ConfigEntryBase)BetterLaddersEnabled).BoxedValue, CultureInfo.InvariantCulture)), 1)); } private void ImportLegacyGeneralTweaks(string path, ManualLogSource log) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown try { ConfigFile val = new ConfigFile(path, false); BetterLaddersEnabled.Value = val.Bind<bool>("Movement", "BetterLadders", BetterLaddersEnabled.Value, (ConfigDescription)null).Value; _file.Save(); if (log != null) { log.LogInfo((object)("Imported the BetterLadders setting from " + Path.GetFileName(path) + " into jg224.TrulySmoothLadders.cfg.")); } } catch (Exception ex) { if (log != null) { log.LogWarning((object)("Could not import the GeneralTweaks BetterLadders setting; using the TrulySmoothLadders default. " + ex.Message)); } } } } } namespace JG224.TrulySmoothLadders.Patches { [HarmonyPatch(typeof(Character), "Awake")] internal static class BetterLaddersCharacterPatch { [HarmonyPostfix] private static void Postfix(Character __instance) { TrulySmoothLaddersConfig settings = Plugin.Settings; if (settings != null && settings.BetterLaddersEnabled.Value) { LadderRampRuntime.OnCharacterInitialized(__instance); } } } [HarmonyPatch(typeof(Piece), "Awake")] internal static class BetterLaddersPiecePatch { [HarmonyPostfix] private static void Postfix(Piece __instance) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) TrulySmoothLaddersConfig settings = Plugin.Settings; if (settings == null || !settings.BetterLaddersEnabled.Value || !Object.op_Implicit((Object)(object)__instance) || !PrefabRules.IsVanillaLadder(((Object)((Component)__instance).gameObject).name)) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid()) { AutoJumpLedge componentInChildren = ((Component)__instance).GetComponentInChildren<AutoJumpLedge>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { LadderRampRuntime.Ensure(__instance, ((Component)componentInChildren).transform.forward); } } } } [HarmonyPatch(typeof(AutoJumpLedge), "OnTriggerStay")] internal static class BetterLaddersPatch { [HarmonyPrefix] private static bool Prefix(AutoJumpLedge __instance, Collider collider) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) TrulySmoothLaddersConfig settings = Plugin.Settings; if (settings == null || !settings.BetterLaddersEnabled.Value) { return true; } Character val = (Object.op_Implicit((Object)(object)collider) ? ((Component)collider).GetComponent<Character>() : null); if (!Object.op_Implicit((Object)(object)val)) { return true; } Piece componentInParent = ((Component)__instance).GetComponentInParent<Piece>(); if (!Object.op_Implicit((Object)(object)componentInParent) || !PrefabRules.IsVanillaLadder(((Object)((Component)componentInParent).gameObject).name)) { return true; } Vector3 forward = ((Component)__instance).transform.forward; if (!val.IsPlayer()) { if (!val.IsOwner()) { return true; } if (!LadderRampRuntime.Ensure(componentInParent, forward)) { return true; } return !LadderRampRuntime.IsMonsterClimbBlocked(componentInParent); } if ((Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } return LadderRampRules.ShouldUseVanillaJump(LadderRampRuntime.Ensure(componentInParent, forward)); } } [HarmonyPatch(typeof(MonsterAI), "UpdateTarget")] internal static class MonsterLadderAttackPatch { [HarmonyPostfix] private static void Postfix(MonsterAI __instance, Humanoid humanoid, Character ___m_targetCreature, ref StaticTarget ___m_targetStatic) { MonsterLadderAttackRuntime.UpdateTarget(__instance, humanoid, ___m_targetCreature, ref ___m_targetStatic); } } [HarmonyPatch(typeof(Character), "UpdateWalking")] internal static class MonsterLadderWalkingPatch { [HarmonyPrefix] private static void Prefix(Character __instance, ref Vector3 ___m_moveDir, out Vector3 __state) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) __state = ___m_moveDir; ___m_moveDir *= LadderRampRuntime.MonsterMovementMultiplier(__instance, ___m_moveDir); } [HarmonyFinalizer] private static void Finalizer(ref Vector3 ___m_moveDir, Vector3 __state) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) ___m_moveDir = __state; } } [HarmonyPatch(typeof(Character), "UpdateBodyFriction")] internal static class BetterLaddersFrictionPatch { [HarmonyPostfix] private static void Postfix(Character __instance, CapsuleCollider ___m_collider, Vector3 ___m_moveDir) { TrulySmoothLaddersConfig settings = Plugin.Settings; if (settings != null && settings.BetterLaddersEnabled.Value && Object.op_Implicit((Object)(object)Player.m_localPlayer) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)___m_collider)) { bool interrupted = __instance.IsDead() || __instance.IsSwimming() || __instance.IsFlying() || __instance.IsDebugFlying() || __instance.IsAttached() || __instance.IsTeleporting() || __instance.InAttack() || __instance.InDodge() || __instance.IsKnockedBack(); Collider lastGroundCollider = __instance.GetLastGroundCollider(); bool ramp = LadderRampRuntime.IsRampCollider(lastGroundCollider) && lastGroundCollider.enabled && ((Component)lastGroundCollider).gameObject.activeInHierarchy; if (LadderFrictionRules.ShouldHoldPosition(__instance.IsOnGround(), ramp, interrupted, ((Vector3)(ref ___m_moveDir)).magnitude)) { PhysicsMaterial material = ((Collider)___m_collider).material; material.staticFriction = Mathf.Max(material.staticFriction, 2f); material.dynamicFriction = Mathf.Max(material.dynamicFriction, 2f); material.frictionCombine = (PhysicsMaterialCombine)3; } } } } [HarmonyPatch(typeof(Character), "GetSlideAngle")] internal static class BetterLaddersSlidePatch { private const float LadderSlideAngle = 55f; [HarmonyPostfix] private static void Postfix(Character __instance, ref float __result) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && LadderRampRuntime.IsRampCollider(__instance.GetLastGroundCollider())) { __result = Mathf.Max(__result, 55f); } } } internal static class LadderRampRuntime { private sealed class RampEntry { internal GameObject Root; internal Collider[] Colliders; internal Transform Ladder; internal Piece Piece; internal Vector3 LocalBottom; internal Vector3 LocalForward; internal float Span; internal float Rise; internal float Width; } private sealed class CharacterEntry { internal Character Owner; internal Collider[] Colliders; internal readonly List<RampEntry> NearbyRamps = new List<RampEntry>(); } private sealed class Rejection { internal Piece Piece; internal float RetryAfter; } internal const string RampObjectName = "JG224_BetterLadderRamp"; private const float RampThickness = 0.08f; private static readonly Dictionary<int, RampEntry> Ramps = new Dictionary<int, RampEntry>(); private static readonly Dictionary<int, CharacterEntry> Isolated = new Dictionary<int, CharacterEntry>(); private static readonly List<Character> Nearby = new List<Character>(); private static readonly Dictionary<int, Rejection> Rejected = new Dictionary<int, Rejection>(); private static readonly List<int> Stale = new List<int>(); private static Dictionary<string, LadderAdjustment> _adjustments = LadderAdjustment.Parse(""); private static string _raw; private static float _nextCleanup; internal static bool MonsterClimbingBlocked { get { TrulySmoothLaddersConfig settings = Plugin.Settings; if (settings != null && settings.BetterLaddersEnabled.Value) { return !Plugin.Settings.AllowMonsterClimbing.Value; } return false; } } internal static bool Ensure(Piece ladder, Vector3 ladderForward) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: 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_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: 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_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_041f: 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_0428: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_0494: Unknown result type (might be due to invalid IL or missing references) //IL_049b: Expected O, but got Unknown //IL_04b4: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_04d3: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Unknown result type (might be due to invalid IL or missing references) //IL_04d7: Unknown result type (might be due to invalid IL or missing references) //IL_050e: Unknown result type (might be due to invalid IL or missing references) //IL_05e3: Unknown result type (might be due to invalid IL or missing references) //IL_05e7: Unknown result type (might be due to invalid IL or missing references) //IL_05ec: Unknown result type (might be due to invalid IL or missing references) //IL_05f0: Unknown result type (might be due to invalid IL or missing references) //IL_05f5: Unknown result type (might be due to invalid IL or missing references) //IL_05fa: Unknown result type (might be due to invalid IL or missing references) //IL_0600: Unknown result type (might be due to invalid IL or missing references) //IL_0605: Unknown result type (might be due to invalid IL or missing references) //IL_0609: Unknown result type (might be due to invalid IL or missing references) //IL_064c: Unknown result type (might be due to invalid IL or missing references) //IL_064e: Unknown result type (might be due to invalid IL or missing references) //IL_0653: Unknown result type (might be due to invalid IL or missing references) //IL_065f: Unknown result type (might be due to invalid IL or missing references) //IL_0661: Unknown result type (might be due to invalid IL or missing references) //IL_0666: Unknown result type (might be due to invalid IL or missing references) //IL_0679: Unknown result type (might be due to invalid IL or missing references) //IL_067e: Unknown result type (might be due to invalid IL or missing references) //IL_0682: Unknown result type (might be due to invalid IL or missing references) //IL_068c: Unknown result type (might be due to invalid IL or missing references) //IL_053a: Unknown result type (might be due to invalid IL or missing references) //IL_053f: Unknown result type (might be due to invalid IL or missing references) //IL_0547: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0566: Unknown result type (might be due to invalid IL or missing references) //IL_056b: Unknown result type (might be due to invalid IL or missing references) //IL_056f: Unknown result type (might be due to invalid IL or missing references) //IL_0574: Unknown result type (might be due to invalid IL or missing references) //IL_0579: Unknown result type (might be due to invalid IL or missing references) //IL_058f: Unknown result type (might be due to invalid IL or missing references) //IL_0595: Unknown result type (might be due to invalid IL or missing references) //IL_059c: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05a4: 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_05b3: Unknown result type (might be due to invalid IL or missing references) //IL_05d9: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)ladder)) { TrulySmoothLaddersConfig settings = Plugin.Settings; if (settings != null && settings.BetterLaddersEnabled.Value && PrefabRules.IsVanillaLadder(((Object)((Component)ladder).gameObject).name)) { RefreshSettings(); int instanceID = ((Object)ladder).GetInstanceID(); if (Ramps.TryGetValue(instanceID, out var value) && Object.op_Implicit((Object)(object)value.Root)) { return true; } if (Rejected.TryGetValue(instanceID, out var value2) && (Object)(object)value2.Piece == (Object)(object)ladder && Time.unscaledTime < value2.RetryAfter) { return false; } string text = ((Object)((Component)ladder).gameObject).name.Replace("(Clone)", "").Trim(); if (!_adjustments.TryGetValue(text, out var value3)) { value3 = LadderAdjustment.Default; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(ladderForward.x, 0f, ladderForward.z); if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { return Reject(ladder, "ladder forward direction is vertical"); } ((Vector3)(ref val)).Normalize(); Vector3 val2 = Vector3.Cross(Vector3.up, val); Vector3 normalized = ((Vector3)(ref val2)).normalized; Collider[] componentsInChildren = ((Component)ladder).GetComponentsInChildren<Collider>(true); Collider val3 = null; Collider val4 = null; float num = float.MaxValue; float num2 = float.MinValue; float num3 = 0f; int num4 = 0; int layer = ((Component)ladder).gameObject.layer; Bounds bounds; foreach (Collider val5 in componentsInChildren) { if (!Object.op_Implicit((Object)(object)val5) || val5.isTrigger || ((Object)((Component)val5).gameObject).name == "JG224_BetterLadderRamp") { continue; } layer = ((Component)val5).gameObject.layer; bounds = val5.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (LadderColliderRules.IsStepSurface(size.x, size.y, size.z)) { bounds = val5.bounds; float num5 = Vector3.Dot(((Bounds)(ref bounds)).center, val); float num6 = num3; bounds = val5.bounds; num3 = num6 + Vector3.Dot(((Bounds)(ref bounds)).center, normalized); num4++; if (num5 < num) { num = num5; val3 = val5; } if (num5 > num2) { num2 = num5; val4 = val5; } } } if (num4 >= 2 && Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val4)) { float lowerForward = num; bounds = val3.bounds; float y = ((Bounds)(ref bounds)).max.y; float upperForward = num2; bounds = val4.bounds; if (LadderRampRules.TryCreateProfile(lowerForward, y, upperForward, ((Bounds)(ref bounds)).max.y, out var profile)) { float num7 = float.MinValue; foreach (Collider val6 in componentsInChildren) { if (Object.op_Implicit((Object)(object)val6) && !val6.isTrigger && !(((Object)((Component)val6).gameObject).name == "JG224_BetterLadderRamp")) { bounds = val6.bounds; Vector3 size2 = ((Bounds)(ref bounds)).size; if (LadderColliderRules.IsStepSurface(size2.x, size2.y, size2.z)) { bounds = val6.bounds; float num8 = Vector3.Dot(((Bounds)(ref bounds)).center, val); float num9 = num7; bounds = val6.bounds; num7 = Mathf.Max(num9, ((Bounds)(ref bounds)).max.y - profile.Slope * num8); } } } float num10 = (num + num2) * 0.5f; float num11 = num3 / (float)num4; val2 = val + Vector3.up * profile.Slope; Vector3 normalized2 = ((Vector3)(ref val2)).normalized; val2 = Vector3.up - val * profile.Slope; Vector3 normalized3 = ((Vector3)(ref val2)).normalized; Vector3 val7 = val * num10 + normalized * num11; val7.y = profile.Slope * num10 + num7; Vector3 val8 = val7 + normalized3 * value3.Offset; float length = profile.SurfaceLength + value3.Margin * 2f; float centerForward = Vector3.Dot(val8, val); float y2 = val8.y; float slope = profile.Slope; bounds = val4.bounds; if (!LadderRampRules.TryCreateLanding(centerForward, y2, slope, length, ((Bounds)(ref bounds)).max.y, out var landing)) { return Reject(ladder, "ramp cannot meet the upper tread safely"); } val8 = val * ((landing.LowerForward + landing.UpperForward) * 0.5f) + normalized * num11; val8.y = (landing.LowerHeight + landing.UpperHeight) * 0.5f; GameObject val9 = new GameObject("JG224_BetterLadderRamp"); ((Object)val9).hideFlags = (HideFlags)61; val9.layer = layer; val9.transform.position = val8 - normalized3 * 0.04f; val9.transform.rotation = Quaternion.LookRotation(normalized2, normalized3); val9.transform.SetParent(((Component)ladder).transform, true); val9.AddComponent<BoxCollider>().size = new Vector3(value3.Width, 0.08f, landing.InclineLength); float num12 = landing.CapEndForward - landing.UpperForward; if (num12 > 0.001f) { GameObject val10 = new GameObject("JG224_BetterLadderRamp") { hideFlags = (HideFlags)61, layer = layer }; Vector3 position = val * ((landing.UpperForward + landing.CapEndForward) * 0.5f) + normalized * num11; position.y = landing.UpperHeight - 0.04f; val10.transform.position = position; val10.transform.rotation = Quaternion.LookRotation(val, Vector3.up); val10.transform.SetParent(val9.transform, true); val10.AddComponent<BoxCollider>().size = new Vector3(value3.Width, 0.08f, num12); } Vector3 val11 = val * num + normalized * num11; bounds = val3.bounds; val11.y = ((Bounds)(ref bounds)).max.y; RampEntry obj = new RampEntry { Root = val9, Colliders = CollectColliders(val9), Ladder = ((Component)ladder).transform, Piece = ladder, LocalBottom = ((Component)ladder).transform.InverseTransformPoint(val11), LocalForward = ((Component)ladder).transform.InverseTransformDirection(val), Span = num2 - num }; bounds = val4.bounds; obj.Rise = ((Bounds)(ref bounds)).max.y - val11.y; obj.Width = value3.Width; RampEntry rampEntry = obj; Ramps[instanceID] = rampEntry; Rejected.Remove(instanceID); IsolateRamp(rampEntry); if (Plugin.Settings.FitDiagnostics.Value) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("Ladder fit " + text + ": steps=" + num4 + ", slope=" + profile.Slope + ", inclineLength=" + landing.InclineLength + ", landingLength=" + num12 + ", landingHeight=" + landing.UpperHeight)); } } return true; } } return Reject(ladder, "fewer than two suitable steps or unsupported slope/span"); } } return false; } private static bool Reject(Piece ladder, string reason) { int instanceID = ((Object)ladder).GetInstanceID(); if (!Rejected.TryGetValue(instanceID, out var value) || (Object)(object)value.Piece != (Object)(object)ladder) { value = new Rejection { Piece = ladder }; Rejected[instanceID] = value; TrulySmoothLaddersConfig settings = Plugin.Settings; if (settings != null && settings.FitDiagnostics.Value) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("Ladder fit rejected for " + ((Object)ladder).name + ": " + reason + "; vanilla auto-jump retained.")); } } } value.RetryAfter = Time.unscaledTime + 2f; return false; } private static void RefreshSettings() { string text = Plugin.Settings?.PrefabAdjustments.Value ?? ""; if (!(_raw == text)) { DestroyAll(); _raw = text; _adjustments = LadderAdjustment.Parse(text); } } internal static void Tick() { //IL_0291: Unknown result type (might be due to invalid IL or missing references) TrulySmoothLaddersConfig settings = Plugin.Settings; if (settings == null || !settings.BetterLaddersEnabled.Value) { DestroyAll(); return; } RefreshSettings(); if (!MonsterClimbingBlocked) { MonsterLadderAttackRuntime.DestroyAll(); } if (Time.unscaledTime < _nextCleanup) { return; } _nextCleanup = Time.unscaledTime + 1f; MonsterLadderAttackRuntime.Sweep(); Stale.Clear(); foreach (KeyValuePair<int, RampEntry> ramp in Ramps) { if (!Object.op_Implicit((Object)(object)ramp.Value.Root)) { Stale.Add(ramp.Key); } } for (int i = 0; i < Stale.Count; i++) { Ramps.Remove(Stale[i]); } Stale.Clear(); foreach (KeyValuePair<int, Rejection> item in Rejected) { if (!Object.op_Implicit((Object)(object)item.Value.Piece)) { Stale.Add(item.Key); } } for (int j = 0; j < Stale.Count; j++) { Rejected.Remove(Stale[j]); } Stale.Clear(); foreach (KeyValuePair<int, CharacterEntry> item2 in Isolated) { if ((Object)(object)item2.Value.Owner == (Object)null || !Object.op_Implicit((Object)(object)item2.Value.Owner)) { Stale.Add(item2.Key); } } for (int k = 0; k < Stale.Count; k++) { Isolated.Remove(Stale[k]); } Stale.Clear(); foreach (CharacterEntry value in Isolated.Values) { value.NearbyRamps.Clear(); } foreach (RampEntry value2 in Ramps.Values) { if (Object.op_Implicit((Object)(object)value2.Root)) { Nearby.Clear(); Character.GetCharactersInRange(value2.Root.transform.position, 30f, Nearby); for (int l = 0; l < Nearby.Count; l++) { IsolateCharacter(Nearby[l], value2); } Nearby.Clear(); } } } internal static void OnCharacterInitialized(Character character) { TrulySmoothLaddersConfig settings = Plugin.Settings; if (settings == null || !settings.BetterLaddersEnabled.Value || !Object.op_Implicit((Object)(object)character) || Ramps.Count == 0 || !LadderIsolationRules.ShouldIsolateCharacter(character.IsPlayer())) { return; } foreach (RampEntry value in Ramps.Values) { IsolateCharacter(character, value); } } private static void IsolateRamp(RampEntry ramp) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)ramp.Root)) { Nearby.Clear(); Character.GetCharactersInRange(ramp.Root.transform.position, 30f, Nearby); for (int i = 0; i < Nearby.Count; i++) { IsolateCharacter(Nearby[i], ramp); } Nearby.Clear(); } } private static void IsolateCharacter(Character character, RampEntry ramp) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)character) || !Object.op_Implicit((Object)(object)ramp.Root) || !LadderIsolationRules.ShouldIsolateCharacter(character.IsPlayer())) { return; } Collider[] characterColliders = GetCharacterColliders(character); CharacterEntry characterEntry = Isolated[((Object)character).GetInstanceID()]; Vector3 val = ((Component)character).transform.position - ramp.Root.transform.position; if (((Vector3)(ref val)).sqrMagnitude <= 900f && !characterEntry.NearbyRamps.Contains(ramp)) { characterEntry.NearbyRamps.Add(ramp); } foreach (Collider val2 in characterColliders) { if (!ShouldUse(val2, character)) { continue; } for (int j = 0; j < ramp.Colliders.Length; j++) { Collider val3 = ramp.Colliders[j]; if (ShouldUse(val3, null)) { Physics.IgnoreCollision(val2, val3, true); } } } } private static bool ShouldUse(Collider collider, Character owner) { if (Object.op_Implicit((Object)(object)collider)) { return LadderIsolationRules.ShouldIsolateCollider(collider.isTrigger, collider.enabled, ((Component)collider).gameObject.activeInHierarchy, (Object)(object)owner == (Object)null || (Object)(object)((Component)collider).GetComponentInParent<Character>() == (Object)(object)owner); } return false; } private static Collider[] GetCharacterColliders(Character character) { int instanceID = ((Object)character).GetInstanceID(); if (Isolated.TryGetValue(instanceID, out var value) && (Object)(object)value.Owner == (Object)(object)character && value.Colliders != null && value.Colliders.Length != 0) { return value.Colliders; } List<Collider> list = new List<Collider>(); AddCollider(list, character, (Collider)(object)character.GetCollider()); Collider[] componentsInChildren = ((Component)character).GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { AddCollider(list, character, componentsInChildren[i]); } Collider[] array = list.ToArray(); Isolated[instanceID] = new CharacterEntry { Owner = character, Colliders = array }; return array; } private static void AddCollider(List<Collider> colliders, Character owner, Collider collider) { if (Object.op_Implicit((Object)(object)collider) && !collider.isTrigger && !(((Object)((Component)collider).gameObject).name == "JG224_BetterLadderRamp") && !((Object)(object)((Component)collider).GetComponentInParent<Character>() != (Object)(object)owner) && !colliders.Contains(collider)) { colliders.Add(collider); } } private static Collider[] CollectColliders(GameObject ramp) { Collider[] componentsInChildren = ramp.GetComponentsInChildren<Collider>(true); List<Collider> list = new List<Collider>(componentsInChildren.Length); for (int i = 0; i < componentsInChildren.Length; i++) { if (Object.op_Implicit((Object)(object)componentsInChildren[i]) && !componentsInChildren[i].isTrigger) { list.Add(componentsInChildren[i]); } } return list.ToArray(); } internal static bool IsRampCollider(Collider collider) { if (Object.op_Implicit((Object)(object)collider)) { return ((Object)((Component)collider).gameObject).name == "JG224_BetterLadderRamp"; } return false; } internal static bool IsMonsterClimbBlocked(Piece ladder) { if (MonsterClimbingBlocked && Object.op_Implicit((Object)(object)ladder) && Ramps.TryGetValue(((Object)ladder).GetInstanceID(), out var value) && Object.op_Implicit((Object)(object)value.Root)) { return value.Root.activeInHierarchy; } return false; } internal static bool IsAtLadder(Character character, Piece ladder) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_0054: 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_005e: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_0091: 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_00af: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)character) || !IsMonsterClimbBlocked(ladder) || !Object.op_Implicit((Object)(object)character.GetCollider())) { return false; } RampEntry rampEntry = Ramps[((Object)ladder).GetInstanceID()]; Vector3 val = rampEntry.Ladder.TransformDirection(rampEntry.LocalForward); Vector3 val2 = ((Component)character).transform.position - rampEntry.Ladder.TransformPoint(rampEntry.LocalBottom); Bounds bounds = ((Collider)character.GetCollider()).bounds; Vector3 extents = ((Bounds)(ref bounds)).extents; return MonsterLadderRules.IsInClimbArea(Vector3.Dot(val2, val), Vector3.Dot(val2, Vector3.Cross(Vector3.up, val)), val2.y, rampEntry.Span, rampEntry.Rise, rampEntry.Width, Mathf.Max(extents.x, extents.z)); } internal static bool IsPursuitBeyondLadder(Character character, Character enemy, Piece ladder) { //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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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) if (!Object.op_Implicit((Object)(object)character) || !Object.op_Implicit((Object)(object)enemy) || !IsMonsterClimbBlocked(ladder)) { return false; } RampEntry rampEntry = Ramps[((Object)ladder).GetInstanceID()]; Vector3 val = rampEntry.Ladder.TransformDirection(rampEntry.LocalForward); Vector3 val2 = rampEntry.Ladder.TransformPoint(rampEntry.LocalBottom); return MonsterLadderRules.IsPursuitBeyondLadder(Vector3.Dot(((Component)character).transform.position - val2, val), Vector3.Dot(((Component)enemy).transform.position - val2, val), ((Component)character).transform.position.y - val2.y, ((Component)enemy).transform.position.y - val2.y); } internal static float MonsterMovementMultiplier(Character character, Vector3 movement) { //IL_00aa: 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_00b1: 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_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_00ca: 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_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)character) || character.IsPlayer()) { return 1f; } int instanceID = ((Object)character).GetInstanceID(); if (!MonsterClimbingBlocked || !character.IsOwner() || character.IsDead() || character.IsSwimming() || character.IsFlying() || character.IsDebugFlying() || character.IsAttached() || character.IsTeleporting() || character.InAttack() || character.InDodge() || character.IsKnockedBack()) { return 1f; } CapsuleCollider collider = character.GetCollider(); if (!Object.op_Implicit((Object)(object)collider) || !((Collider)collider).enabled || !((Component)collider).gameObject.activeInHierarchy) { return 1f; } Vector3 position = ((Component)character).transform.position; Bounds bounds = ((Collider)collider).bounds; float x = ((Bounds)(ref bounds)).extents.x; bounds = ((Collider)collider).bounds; float radius = Mathf.Max(x, ((Bounds)(ref bounds)).extents.z); if (!Isolated.TryGetValue(instanceID, out var value) || (Object)(object)value.Owner != (Object)(object)character) { return 1f; } foreach (RampEntry nearbyRamp in value.NearbyRamps) { if (!Object.op_Implicit((Object)(object)nearbyRamp.Root) || !nearbyRamp.Root.activeInHierarchy || !Object.op_Implicit((Object)(object)nearbyRamp.Ladder)) { continue; } Vector3 val = nearbyRamp.Ladder.TransformDirection(nearbyRamp.LocalForward); Vector3 val2 = position - nearbyRamp.Ladder.TransformPoint(nearbyRamp.LocalBottom); float num = Vector3.Dot(val2, val); float across = Vector3.Dot(val2, Vector3.Cross(Vector3.up, val)); if (MonsterLadderRules.IsInClimbArea(num, across, val2.y, nearbyRamp.Span, nearbyRamp.Rise, nearbyRamp.Width, radius) && MonsterLadderRules.IsAscending(Vector3.Dot(movement, val))) { Piece piece = nearbyRamp.Piece; if (num < 0f && MonsterLadderAttackRuntime.IsAttacking(character, piece)) { return 1f; } MonsterLadderAttackRuntime.ObserveBlock(character, piece); return 0f; } } return 1f; } internal static void DestroyAll() { MonsterLadderAttackRuntime.DestroyAll(); foreach (RampEntry value in Ramps.Values) { if (Object.op_Implicit((Object)(object)value.Root)) { value.Root.SetActive(false); Object.Destroy((Object)(object)value.Root); } } Ramps.Clear(); Rejected.Clear(); Isolated.Clear(); Nearby.Clear(); Stale.Clear(); _nextCleanup = 0f; } } internal static class MonsterLadderAttackRuntime { private sealed class Entry { internal Character Character; internal MonsterAI AI; internal Piece Ladder; internal float BlockedAt; internal float UpdatedAt; internal StaticTarget Assigned; internal StaticTarget Previous; internal Character Pursuit; } private static readonly Dictionary<int, Entry> Entries = new Dictionary<int, Entry>(); private static readonly List<StaticTarget> CreatedTargets = new List<StaticTarget>(); private static readonly List<int> Stale = new List<int>(); private static readonly FieldRef<MonsterAI, StaticTarget> TargetField = AccessTools.FieldRefAccess<MonsterAI, StaticTarget>("m_targetStatic"); internal static void ObserveBlock(Character character, Piece ladder) { BaseAI baseAI = character.GetBaseAI(); MonsterAI val = (MonsterAI)(object)((baseAI is MonsterAI) ? baseAI : null); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)ladder) || character.IsTamed() || !val.m_attackPlayerObjects || !((BaseAI)val).IsAlerted()) { return; } int instanceID = ((Object)character).GetInstanceID(); if (Entries.TryGetValue(instanceID, out var value)) { if ((Object)(object)value.Character == (Object)(object)character && (Object)(object)value.Ladder == (Object)(object)ladder) { value.BlockedAt = Time.time; return; } if (Object.op_Implicit((Object)(object)value.Assigned) && LadderRampRuntime.IsAtLadder(character, value.Ladder)) { return; } Release(value); } Entries[instanceID] = new Entry { Character = character, AI = val, Ladder = ladder, BlockedAt = Time.time, UpdatedAt = Time.time }; } internal static bool IsAttacking(Character character, Piece ladder) { if (Object.op_Implicit((Object)(object)character) && Object.op_Implicit((Object)(object)ladder) && Entries.TryGetValue(((Object)character).GetInstanceID(), out var value) && (Object)(object)value.Character == (Object)(object)character && (Object)(object)value.Ladder == (Object)(object)ladder && Object.op_Implicit((Object)(object)value.Assigned) && Object.op_Implicit((Object)(object)value.AI)) { return (Object)(object)TargetField.Invoke(value.AI) == (Object)(object)value.Assigned; } return false; } internal static void UpdateTarget(MonsterAI ai, Humanoid character, Character enemy, ref StaticTarget target) { if (!Object.op_Implicit((Object)(object)character) || !Entries.TryGetValue(((Object)character).GetInstanceID(), out var value)) { return; } int instanceID = ((Object)character).GetInstanceID(); bool pursuingPlayer = Object.op_Implicit((Object)(object)enemy) && enemy.IsPlayer() && !enemy.IsDead() && BaseAI.IsEnemy((Character)(object)character, enemy); if ((Object)(object)value.Character != (Object)(object)character || (Object)(object)value.AI != (Object)(object)ai || !((Character)character).IsOwner() || !LadderRampRuntime.MonsterClimbingBlocked || ((Character)character).IsPlayer() || ((Character)character).IsDead() || ((Character)character).m_aiCannotTargetOthers || ((Character)character).IsSwimming() || ((Character)character).IsFlying() || ((Character)character).IsDebugFlying() || ((Character)character).IsAttached() || ((Character)character).IsTeleporting() || !Object.op_Implicit((Object)(object)ZoneSystem.instance) || !MonsterLadderRules.CanAttackObstruction(ai.m_attackPlayerObjects, ((Character)character).IsTamed(), ((BaseAI)ai).IsAlerted(), !((BaseAI)ai).m_aggravatable || ((BaseAI)ai).IsAggravated(), ZoneSystem.instance.GetGlobalKey((GlobalKeys)30), pursuingPlayer) || !LadderRampRuntime.IsAtLadder((Character)(object)character, value.Ladder) || !LadderRampRuntime.IsPursuitBeyondLadder((Character)(object)character, enemy, value.Ladder) || (Object.op_Implicit((Object)(object)value.Assigned) && (Object)(object)value.Pursuit != (Object)(object)enemy) || (!Object.op_Implicit((Object)(object)value.Assigned) && !MonsterLadderRules.IsRecentBlock(Time.time, value.BlockedAt))) { Release(value); Entries.Remove(instanceID); return; } value.UpdatedAt = Time.time; if (((Character)character).InAttack() || ((Character)character).InDodge() || ((Character)character).IsKnockedBack()) { return; } Piece ladder = value.Ladder; ZNetView component = ((Component)ladder).GetComponent<ZNetView>(); WearNTear component2 = ((Component)ladder).GetComponent<WearNTear>(); if (!ladder.IsPlacedByPlayer() || !Object.op_Implicit((Object)(object)component) || !component.IsValid() || !Object.op_Implicit((Object)(object)component2) || component2.GetHealthPercentage() <= 0f) { Release(value); Entries.Remove(instanceID); return; } if (!Object.op_Implicit((Object)(object)value.Assigned)) { StaticTarget val = ((Component)ladder).GetComponent<StaticTarget>(); if (!Object.op_Implicit((Object)(object)val)) { val = (StaticTarget)(object)((Component)ladder).gameObject.AddComponent<LadderObstructionTarget>(); val.m_primaryTarget = false; val.m_randomTarget = false; CreatedTargets.Add(val); } List<Collider> allColliders = val.GetAllColliders(); Collider[] componentsInChildren = ((Component)ladder).GetComponentsInChildren<Collider>(); foreach (Collider val2 in componentsInChildren) { if (Object.op_Implicit((Object)(object)val2) && val2.enabled && ((Component)val2).gameObject.activeInHierarchy && !val2.isTrigger && !allColliders.Contains(val2)) { allColliders.Add(val2); } } value.Assigned = val; value.Previous = target; value.Pursuit = enemy; } target = value.Assigned; } private static void Release(Entry entry) { if (Object.op_Implicit((Object)(object)entry.AI) && Object.op_Implicit((Object)(object)entry.Assigned) && (Object)(object)TargetField.Invoke(entry.AI) == (Object)(object)entry.Assigned) { TargetField.Invoke(entry.AI) = (Object.op_Implicit((Object)(object)entry.Previous) ? entry.Previous : null); } entry.Assigned = null; } internal static void Sweep() { Stale.Clear(); foreach (KeyValuePair<int, Entry> entry in Entries) { if (!Object.op_Implicit((Object)(object)entry.Value.Character) || !Object.op_Implicit((Object)(object)entry.Value.Ladder) || !entry.Value.Character.IsOwner() || Time.time - entry.Value.UpdatedAt > 2f) { Release(entry.Value); Stale.Add(entry.Key); } } foreach (int item in Stale) { Entries.Remove(item); } Stale.Clear(); CreatedTargets.RemoveAll((StaticTarget target) => !Object.op_Implicit((Object)(object)target)); } internal static void DestroyAll() { foreach (Entry value in Entries.Values) { Release(value); } Entries.Clear(); foreach (StaticTarget createdTarget in CreatedTargets) { if (Object.op_Implicit((Object)(object)createdTarget)) { ((Behaviour)createdTarget).enabled = false; Object.Destroy((Object)(object)createdTarget); } } CreatedTargets.Clear(); Stale.Clear(); } } internal sealed class LadderObstructionTarget : StaticTarget { public override bool IsPriorityTarget() { return false; } public override bool IsRandomTarget() { return false; } } } namespace JG224.TrulySmoothLadders.Core { internal readonly struct LadderAdjustment { internal float Width { get; } internal float Offset { get; } internal float Margin { get; } internal static LadderAdjustment Default => new LadderAdjustment(1.3f, 0.42f, 0.35f); internal LadderAdjustment(float width, float offset, float margin) { Width = width; Offset = offset; Margin = margin; } internal static Dictionary<string, LadderAdjustment> Parse(string raw) { Dictionary<string, LadderAdjustment> dictionary = new Dictionary<string, LadderAdjustment>(StringComparer.OrdinalIgnoreCase); string[] array = (raw ?? "").Split(new char[1] { ';' }); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { '=' }); if (array2.Length == 2 && PrefabRules.IsVanillaLadder(array2[0].Trim())) { string[] array3 = array2[1].Split(new char[1] { ',' }); if (array3.Length == 3 && Number(array3[0], 0.5f, 3f, out var number) && Number(array3[1], 0f, 0.75f, out var number2) && Number(array3[2], 0f, 1f, out var number3)) { dictionary[array2[0].Trim()] = new LadderAdjustment(number, number2, number3); } } } return dictionary; } private static bool Number(string value, float min, float max, out float number) { if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out number) && !float.IsNaN(number) && !float.IsInfinity(number) && number >= min) { return number <= max; } return false; } } internal static class MonsterLadderRules { internal static bool CanAttackObstruction(bool attacksStructures, bool tamed, bool alerted, bool aggressionAllowed, bool passiveWorld, bool pursuingPlayer) { return attacksStructures && !tamed && alerted && aggressionAllowed && !passiveWorld && pursuingPlayer; } internal static bool IsRecentBlock(float now, float blockedAt) { if (now - blockedAt >= 0f) { return now - blockedAt <= 0.5f; } return false; } internal static bool IsPursuitBeyondLadder(float actorAlong, float enemyAlong, float actorHeight, float enemyHeight) { if (enemyAlong >= 0f && enemyAlong > actorAlong + 0.25f && !float.IsInfinity(enemyAlong) && enemyHeight > Math.Max(0f, actorHeight) + 0.25f) { return !float.IsInfinity(enemyHeight); } return false; } internal static bool IsInClimbArea(float forward, float across, float height, float span, float rise, float width, float radius) { if (forward >= 0f - radius - 0.5f && forward <= span && Math.Abs(across) <= width * 0.5f + radius && span > 0f && rise > 0f && radius >= 0f && width > 0f && height >= Math.Max(0f, forward) * rise / span - 0.75f) { return height <= Math.Max(0f, forward) * rise / span + 0.5f; } return false; } internal static bool IsAscending(float forwardInput) { if (forwardInput > 0f) { return !float.IsInfinity(forwardInput); } return false; } } internal static class LadderFrictionRules { internal const float MinimumIdleFriction = 2f; internal static bool ShouldHoldPosition(bool grounded, bool ramp, bool interrupted, float movementMagnitude) { if (grounded && ramp && !interrupted && movementMagnitude >= 0f) { return movementMagnitude < 0.1f; } return false; } } internal static class LadderColliderRules { internal static bool IsStepSurface(float width, float height, float depth) { if (!IsFinitePositive(width) || !IsFinitePositive(height) || !IsFinitePositive(depth)) { return false; } float num = Math.Max(width, depth); if (height <= 0.35f) { return height <= num * 0.5f; } return false; } private static bool IsFinitePositive(float value) { if (value > 0f) { return IsFinite(value); } return false; } private static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } } internal static class LadderIsolationRules { internal const float IsolationRadius = 30f; internal static bool ShouldIsolateCharacter(bool isPlayer) { return !isPlayer; } internal static bool ShouldIsolateCollider(bool isTrigger, bool enabled, bool activeInHierarchy, bool ownedByIsolatedCharacter) { return !isTrigger && enabled && activeInHierarchy && ownedByIsolatedCharacter; } } internal readonly struct LadderRampProfile { internal float Slope { get; } internal float HorizontalSpan { get; } internal float SurfaceLength => HorizontalSpan * (float)Math.Sqrt(1f + Slope * Slope); internal LadderRampProfile(float slope, float horizontalSpan) { Slope = slope; HorizontalSpan = horizontalSpan; } } internal static class LadderRampRules { internal const float LandingClearance = 0.02f; internal static bool TryCreateLanding(float centerForward, float centerHeight, float slope, float length, float highestTread, out LadderLanding landing) { landing = default(LadderLanding); if (!IsFinite(centerForward) || !IsFinite(centerHeight) || !IsFinite(slope) || !IsFinite(length) || !IsFinite(highestTread) || slope <= 0f || length <= 0f) { return false; } float num = (float)Math.Sqrt(1f + slope * slope); float num2 = length / (2f * num); float num3 = num2 * slope; float num4 = centerHeight - num3; float num5 = Math.Min(centerHeight + num3, highestTread + 0.02f); if (num5 - num4 < 0.01f) { return false; } float num6 = centerForward - num2; float num7 = num6 + (num5 - num4) / slope; landing = new LadderLanding(num6, num4, num7, num5, Math.Max(num7, centerForward + num2)); return true; } internal static bool ShouldUseVanillaJump(bool rampReady) { return !rampReady; } internal static bool TryCreateProfile(float lowerForward, float lowerTop, float upperForward, float upperTop, out LadderRampProfile profile) { profile = default(LadderRampProfile); if (!IsFinite(lowerForward) || !IsFinite(lowerTop) || !IsFinite(upperForward) || !IsFinite(upperTop)) { return false; } float num = upperForward - lowerForward; float num2 = upperTop - lowerTop; if (num < 0.25f || num2 < 0.1f) { return false; } float num3 = num2 / num; if (num3 < 0.4f || num3 > 2.5f) { return false; } float slope = Math.Min(num3, 1.35f); profile = new LadderRampProfile(slope, num); return true; } private static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } } internal readonly struct LadderLanding { internal float LowerForward { get; } internal float LowerHeight { get; } internal float UpperForward { get; } internal float UpperHeight { get; } internal float CapEndForward { get; } internal float InclineLength => (float)Math.Sqrt((UpperForward - LowerForward) * (UpperForward - LowerForward) + (UpperHeight - LowerHeight) * (UpperHeight - LowerHeight)); internal LadderLanding(float lowerForward, float lowerHeight, float upperForward, float upperHeight, float capEndForward) { LowerForward = lowerForward; LowerHeight = lowerHeight; UpperForward = upperForward; UpperHeight = upperHeight; CapEndForward = capEndForward; } } internal static class PrefabRules { private static readonly HashSet<string> Ladders = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "piece_wood_ladder", "piece_wood_ladder_45", "piece_woodstepladder", "piece_grausten_stoneladder", "wood_ladder", "wood_stepladder", "woodstepladder", "grausten_ladder", "grausten_stone_ladder", "piece_grausten_stone_ladder" }; internal static bool IsVanillaLadder(string prefabName) { return Ladders.Contains(Clean(prefabName)); } private static string Clean(string value) { if (string.IsNullOrEmpty(value)) { return string.Empty; } int num = value.IndexOf("(Clone)", StringComparison.OrdinalIgnoreCase); return ((num >= 0) ? value.Substring(0, num) : value).Trim(); } } internal static class LegacyLadderConfigRules { internal const string CurrentFileName = "jg224.TrulySmoothLadders.cfg"; internal const string GeneralTweaksFileName = "jg224.GeneralTweaks.cfg"; internal const string LegacyGeneralTweaksFileName = "JG224.GeneralTweaks.cfg"; internal static string FindImportSource(IEnumerable<string> candidatePaths) { string[] paths = ((candidatePaths == null) ? Array.Empty<string>() : candidatePaths.ToArray()); if (FindExact(paths, "jg224.TrulySmoothLadders.cfg") != null) { return null; } return FindExact(paths, "jg224.GeneralTweaks.cfg") ?? FindExact(paths, "JG224.GeneralTweaks.cfg"); } private static string FindExact(IEnumerable<string> paths, string fileName) { return paths.FirstOrDefault((string path) => string.Equals(Path.GetFileName(path), fileName, StringComparison.Ordinal)); } } }