using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; 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: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: AssemblyCompany("ShieldSledding")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ShieldSledding")] [assembly: AssemblyTitle("ShieldSledding")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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 ShieldSledding { internal sealed class AudioController { private AudioSource _slideSource; private AudioSource _windSource; private float _lastImpactTime; internal static AudioController Instance { get; private set; } internal AudioController() { Instance = this; } internal void Begin(Player player) { EnsureSources(player); } internal void End(Player player) { if ((Object)(object)_slideSource != (Object)null) { _slideSource.Stop(); } if ((Object)(object)_windSource != (Object)null) { _windSource.Stop(); } } internal void Update(Player player, float speed) { if (!ConfigManager.EnableSoundEffects.Value || (Object)(object)player == (Object)null || Utility.IsDedicatedServer()) { return; } EnsureSources(player); Utility.GetHandShield(player); float num = 12f; if (Utility.TrySampleGround(player, out var sample)) { num = Mathf.Max(6f, ShieldSpeedRegistry.EstimateNaturalSpeed(in sample)); } float num2 = Mathf.Clamp01(speed / num); if ((Object)(object)_slideSource != (Object)null) { if (speed > 1.5f) { if (!_slideSource.isPlaying) { _slideSource.Play(); } _slideSource.volume = 0.2f + num2 * 0.6f; _slideSource.pitch = 0.8f + num2 * 0.5f; } else { _slideSource.Stop(); } } if (!((Object)(object)_windSource != (Object)null)) { return; } if (speed > 6f) { if (!_windSource.isPlaying) { _windSource.Play(); } _windSource.volume = num2 * 0.5f; _windSource.pitch = 0.9f + num2 * 0.8f; } else { _windSource.Stop(); } } internal void OnLanding(Player player, float impact) { PlayImpact(player, impact); } internal void PlayImpact(Player player, float impact) { if (ConfigManager.EnableSoundEffects.Value && !((Object)(object)player == (Object)null) && !(impact < 4f) && !(Time.time - _lastImpactTime < 0.2f)) { _lastImpactTime = Time.time; EnsureSources(player); if ((Object)(object)_slideSource != (Object)null) { _slideSource.PlayOneShot(_slideSource.clip, Mathf.Clamp01(impact / 20f)); } } } private void EnsureSources(Player player) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown if (!((Object)(object)_slideSource != (Object)null)) { GameObject val = new GameObject("ShieldSledding_Audio"); val.transform.SetParent(((Component)player).transform, false); _slideSource = val.AddComponent(); _slideSource.loop = true; _slideSource.spatialBlend = 0f; _slideSource.volume = 0.4f; _windSource = val.AddComponent(); _windSource.loop = true; _windSource.spatialBlend = 0f; _windSource.volume = 0.25f; _windSource.pitch = 1.1f; } } } internal sealed class CollisionController { private Vector3 _lastVelocity; private float _cooldownUntil; internal void Begin(Player player) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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) _lastVelocity = (((Object)(object)player != (Object)null) ? ((Character)player).GetVelocity() : Vector3.zero); _cooldownUntil = 0f; } internal void Tick(Player player, ItemData shield, PhysicsResult result) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0042: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } WildlifeImpact.TryRam(player, shield, result); if (Time.time < _cooldownUntil) { _lastVelocity = result.Velocity; return; } float horizontalSpeed = result.HorizontalSpeed; if (horizontalSpeed < ConfigManager.CollisionSpeedThreshold.Value) { _lastVelocity = result.Velocity; return; } Vector3 val = Utility.Flatten(result.Velocity - _lastVelocity); float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 4f) { _lastVelocity = result.Velocity; return; } if (!TryFindObstacle(player, out var hit)) { _lastVelocity = result.Velocity; return; } float impact = magnitude * ConfigManager.CollisionSpeedDamageScale.Value; ApplyImpact(player, shield, ((RaycastHit)(ref hit)).point, ((RaycastHit)(ref hit)).normal, impact, horizontalSpeed); _cooldownUntil = Time.time + 0.35f; _lastVelocity = result.Velocity; } internal void OnLanding(Player player, float impact) { if (!(impact < 8f)) { EffectController.Instance?.ShakeCamera(impact * 0.05f); AudioController.Instance?.PlayImpact(player, impact); } } private bool TryFindObstacle(Player player, out RaycastHit hit) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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) hit = default(RaycastHit); Vector3 val = ((Component)player).transform.position + Vector3.up * 0.6f; Vector3 val2 = Utility.Flatten((ShieldSledController.Instance != null) ? ShieldSledController.Instance.SimulatedVelocity : ((Character)player).GetVelocity()); if (((Vector3)(ref val2)).sqrMagnitude < 0.01f) { val2 = ((Component)player).transform.forward; } ((Vector3)(ref val2)).Normalize(); return Physics.SphereCast(val, 0.4f, val2, ref hit, 1.2f, -1); } private void ApplyImpact(Player player, ItemData shield, Vector3 point, Vector3 normal, float impact, float speed) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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) EffectController.Instance?.OnCollision(player, point, normal, impact); AudioController.Instance?.PlayImpact(player, impact); MultiplayerSync.Instance?.SendImpactEvent(player, point, impact); } } internal static class ConfigManager { internal static ConfigEntry EnableShieldSledding; internal static ConfigEntry ActivationKey; internal static ConfigEntry ActivationWindow; internal static ConfigEntry ArmedWindow; internal static ConfigEntry MinimumSlope; internal static ConfigEntry SledGroundClearance; internal static ConfigEntry EnableWaterSledding; internal static ConfigEntry WaterSledMinSpeed; internal static ConfigEntry WaterSledFriction; internal static ConfigEntry BaseAcceleration; internal static ConfigEntry MaximumSpeed; internal static ConfigEntry MinBlockSkillSpeedScale; internal static ConfigEntry GravityMultiplier; internal static ConfigEntry FrictionMultiplier; internal static ConfigEntry AirControl; internal static ConfigEntry SteeringStrength; internal static ConfigEntry BrakeStrength; internal static ConfigEntry ForwardLeanBonus; internal static ConfigEntry SteeringSpeedFalloff; internal static ConfigEntry UphillPenalty; internal static ConfigEntry FlatDeceleration; internal static ConfigEntry AbsorbDamageToShield; internal static ConfigEntry EndSledOnCombatHit; internal static ConfigEntry StaggerOnCombatHit; internal static ConfigEntry CombatHitMinDamage; internal static ConfigEntry EnableDurabilityLoss; internal static ConfigEntry DurabilityPerMeter; internal static ConfigEntry DurabilityPerSecond; internal static ConfigEntry LandingDamageMultiplier; internal static ConfigEntry DamageToDurabilityMultiplier; internal static ConfigEntry StumbleOnShieldBreak; internal static ConfigEntry SnowFriction; internal static ConfigEntry GrassFriction; internal static ConfigEntry BlackForestFriction; internal static ConfigEntry SwampFriction; internal static ConfigEntry AshlandsFriction; internal static ConfigEntry MountainFriction; internal static ConfigEntry MeadowsFriction; internal static ConfigEntry MistlandsFriction; internal static ConfigEntry OceanFriction; internal static ConfigEntry DeepNorthFriction; internal static ConfigEntry AshlandsDurabilityWearMultiplier; internal static ConfigEntry EnableShieldSurf; internal static ConfigEntry ShieldSurfFriction; internal static ConfigEntry CollisionSpeedThreshold; internal static ConfigEntry CollisionSpeedDamageScale; internal static ConfigEntry EnableWildlifeImpactKill; internal static ConfigEntry StaminaMode; internal static ConfigEntry StaminaActivationCost; internal static ConfigEntry StaminaPerSecond; internal static ConfigEntry StaminaJumpCost; internal static ConfigEntry EnableParticles; internal static ConfigEntry EnableCameraEffects; internal static ConfigEntry EnableSoundEffects; internal static ConfigEntry EnableSpeedometer; internal static ConfigEntry CameraShakeStrength; internal static ConfigEntry SpeedFovIncrease; internal static ConfigEntry CameraTiltStrength; internal static ConfigEntry EnableShieldSparks; internal static ConfigEntry ConfigSchemaVersion; private static ConfigDescription FloatRange(float min, float max, string description = "") { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown return new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange(min, max), Array.Empty()); } private static ConfigDescription IntRange(int min, int max, string description = "") { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown return new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange(min, max), Array.Empty()); } internal static void Init(ConfigFile config) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected O, but got Unknown //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Expected O, but got Unknown //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Expected O, but got Unknown //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Expected O, but got Unknown //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Expected O, but got Unknown //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Expected O, but got Unknown //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Expected O, but got Unknown //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Expected O, but got Unknown //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Expected O, but got Unknown //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Expected O, but got Unknown //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Expected O, but got Unknown //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Expected O, but got Unknown //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Expected O, but got Unknown //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_0462: Expected O, but got Unknown //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Expected O, but got Unknown //IL_0519: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Expected O, but got Unknown //IL_0854: Unknown result type (might be due to invalid IL or missing references) //IL_085e: Expected O, but got Unknown //IL_088c: Unknown result type (might be due to invalid IL or missing references) //IL_0896: Expected O, but got Unknown ConfigSchemaVersion = config.Bind("General", "ConfigSchemaVersion", 1, "Internal config migration version. Do not edit unless you know what you are doing."); EnableShieldSledding = config.Bind("General", "EnableShieldSledding", true, "Master toggle for shield sledding."); ActivationKey = config.Bind("General", "ActivationKey", new KeyboardShortcut((KeyCode)103, Array.Empty()), "Press while airborne after a jump to arm shield sled mode."); ActivationWindow = config.Bind("General", "ActivationWindow", 2.5f, new ConfigDescription("Seconds after jumping during which G can arm sled mode.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 5f), Array.Empty())); ArmedWindow = config.Bind("General", "ArmedWindow", 6f, new ConfigDescription("Seconds after arming to land and start sledding before the arm expires.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 15f), Array.Empty())); MinimumSlope = config.Bind("General", "MinimumSlope", 0f, new ConfigDescription("Minimum ground slope in degrees required to start sledding on landing.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 45f), Array.Empty())); SledGroundClearance = config.Bind("Physics", "SledGroundClearance", 0f, new ConfigDescription("Target height of the player's feet above the slope while sledding (meters). 0 = full contact.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 0.6f), Array.Empty())); EnableWaterSledding = config.Bind("Physics", "EnableWaterSledding", true, "Allow sledding across water when moving fast enough."); WaterSledMinSpeed = config.Bind("Physics", "WaterSledMinSpeed", 6f, new ConfigDescription("Minimum speed (m/s) required to skim across water instead of swimming.", (AcceptableValueBase)(object)new AcceptableValueRange(2f, 20f), Array.Empty())); WaterSledFriction = config.Bind("Physics", "WaterSledFriction", 0.35f, new ConfigDescription("Extra friction while skimming water. Lower = faster skim.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 2f), Array.Empty())); BaseAcceleration = config.Bind("Physics", "BaseAcceleration", 10f, new ConfigDescription("Slope pull strength (~10 ≈ gravity). Higher = faster coast on the same hill.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 100f), Array.Empty())); MaximumSpeed = config.Bind("Physics", "MaximumSpeed", 0f, new ConfigDescription("Optional safety speed cap in m/s. 0 = disabled — speed follows slope steepness and terrain friction.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 80f), Array.Empty())); MinBlockSkillSpeedScale = config.Bind("Physics", "MinBlockSkillSpeedScale", 0.8f, new ConfigDescription("Unused — speed is slope-based. Blocking skill no longer limits sled speed.", (AcceptableValueBase)(object)new AcceptableValueRange(0.35f, 1f), Array.Empty())); GravityMultiplier = config.Bind("Physics", "GravityMultiplier", 1f, new ConfigDescription("Multiplier applied to downhill gravity acceleration.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 5f), Array.Empty())); FrictionMultiplier = config.Bind("Physics", "FrictionMultiplier", 1f, new ConfigDescription("Global friction multiplier.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 5f), Array.Empty())); AirControl = config.Bind("Physics", "AirControl", 0.15f, new ConfigDescription("Fraction of ground steering applied while airborne.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); SteeringStrength = config.Bind("Physics", "SteeringStrength", 2.5f, new ConfigDescription("How quickly velocity direction can change while sledding.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 10f), Array.Empty())); BrakeStrength = config.Bind("Physics", "BrakeStrength", 1.5f, new ConfigDescription("Extra friction multiplier when holding S.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 10f), Array.Empty())); ForwardLeanBonus = config.Bind("Physics", "ForwardLeanBonus", 1.5f, new ConfigDescription("Extra acceleration when holding W.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 30f), Array.Empty())); SteeringSpeedFalloff = config.Bind("Physics", "SteeringSpeedFalloff", 0.08f, new ConfigDescription("Higher values reduce steering responsiveness at speed.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); UphillPenalty = config.Bind("Physics", "UphillPenalty", 3f, new ConfigDescription("Deceleration multiplier when moving uphill.", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 10f), Array.Empty())); FlatDeceleration = config.Bind("Physics", "FlatDeceleration", 8f, new ConfigDescription("Deceleration on flat ground.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 30f), Array.Empty())); AbsorbDamageToShield = config.Bind("Damage", "AbsorbDamageToShield", true, "When true, fall and impact damage go to shield durability instead of player HP while sledding."); EndSledOnCombatHit = config.Bind("Damage", "EndSledOnCombatHit", true, "When true, creature or player attacks knock you off the sled while sledding."); StaggerOnCombatHit = config.Bind("Damage", "StaggerOnCombatHit", true, "Apply a stagger when knocked off the sled by a creature or player attack."); CombatHitMinDamage = config.Bind("Damage", "CombatHitMinDamage", 1f, new ConfigDescription("Minimum damage before a combat hit can knock you off the sled.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 50f), Array.Empty())); DamageToDurabilityMultiplier = config.Bind("Damage", "DamageToDurabilityMultiplier", 0.15f, new ConfigDescription("Shield durability lost per point of HP damage absorbed while sledding.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); EnableDurabilityLoss = config.Bind("Durability", "EnableDurabilityLoss", true, "Whether sledding wears down the equipped shield."); DurabilityPerMeter = config.Bind("Durability", "DurabilityPerMeter", 0.02f, FloatRange(0f, 5f)); DurabilityPerSecond = config.Bind("Durability", "DurabilityPerSecond", 0.05f, FloatRange(0f, 5f)); LandingDamageMultiplier = config.Bind("Durability", "LandingDamageMultiplier", 1.5f, FloatRange(0f, 10f)); StumbleOnShieldBreak = config.Bind("Durability", "StumbleOnShieldBreak", true, "Apply a stagger when the shield breaks from sledding."); SnowFriction = config.Bind("Terrain", "SnowFriction", 0.55f, FloatRange(0.1f, 3f)); GrassFriction = config.Bind("Terrain", "GrassFriction", 0.85f, FloatRange(0.1f, 3f)); BlackForestFriction = config.Bind("Terrain", "BlackForestFriction", 0.95f, FloatRange(0.1f, 3f)); SwampFriction = config.Bind("Terrain", "SwampFriction", 1.45f, FloatRange(0.1f, 3f)); AshlandsFriction = config.Bind("Terrain", "AshlandsFriction", 0.75f, FloatRange(0.1f, 3f)); MountainFriction = config.Bind("Terrain", "MountainFriction", 0.5f, FloatRange(0.1f, 3f)); MeadowsFriction = config.Bind("Terrain", "MeadowsFriction", 1f, FloatRange(0.1f, 3f)); MistlandsFriction = config.Bind("Terrain", "MistlandsFriction", 0.9f, FloatRange(0.1f, 3f)); OceanFriction = config.Bind("Terrain", "OceanFriction", 1.2f, FloatRange(0.1f, 3f)); DeepNorthFriction = config.Bind("Terrain", "DeepNorthFriction", 0.5f, FloatRange(0.1f, 3f)); AshlandsDurabilityWearMultiplier = config.Bind("Terrain", "AshlandsDurabilityWearMultiplier", 1.35f, FloatRange(1f, 5f)); EnableShieldSurf = config.Bind("Terrain", "EnableShieldSurf", true, "Allow reduced friction when sledding on player-built wood pieces."); ShieldSurfFriction = config.Bind("Terrain", "ShieldSurfFriction", 0.65f, FloatRange(0.1f, 3f)); CollisionSpeedThreshold = config.Bind("Impacts", "CollisionSpeedThreshold", 6f, new ConfigDescription("Minimum speed (m/s) before impact camera/audio effects trigger.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 30f), Array.Empty())); CollisionSpeedDamageScale = config.Bind("Impacts", "CollisionSpeedDamageScale", 1.25f, new ConfigDescription("Impact intensity scale for camera shake and sound.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); EnableWildlifeImpactKill = config.Bind("Impacts", "EnableWildlifeImpactKill", true, "Instantly kill small wildlife when sledding into them at or above CollisionSpeedThreshold (Boar, Deer, Greyling, Neck, Crow, Gull, Hare, Ash crow)."); StaminaMode = config.Bind("Stamina", "StaminaMode", SledStaminaMode.None, "Stamina drain behavior while sledding."); StaminaActivationCost = config.Bind("Stamina", "StaminaActivationCost", 10f, FloatRange(0f, 100f)); StaminaPerSecond = config.Bind("Stamina", "StaminaPerSecond", 2f, FloatRange(0f, 50f)); StaminaJumpCost = config.Bind("Stamina", "StaminaJumpCost", 8f, FloatRange(0f, 100f)); EnableParticles = config.Bind("Effects", "EnableParticles", true, (ConfigDescription)null); EnableCameraEffects = config.Bind("Effects", "EnableCameraEffects", true, (ConfigDescription)null); EnableSoundEffects = config.Bind("Effects", "EnableSoundEffects", true, (ConfigDescription)null); EnableSpeedometer = config.Bind("Effects", "EnableSpeedometer", false, (ConfigDescription)null); CameraShakeStrength = config.Bind("Effects", "CameraShakeStrength", 0.35f, FloatRange(0f, 2f)); SpeedFovIncrease = config.Bind("Effects", "SpeedFovIncrease", 8f, FloatRange(0f, 30f)); CameraTiltStrength = config.Bind("Effects", "CameraTiltStrength", 4f, FloatRange(0f, 20f)); EnableShieldSparks = config.Bind("Effects", "EnableShieldSparks", true, (ConfigDescription)null); ShieldWearConfig.Init(config); MigrateLegacyConfig(config); } private static void MigrateLegacyConfig(ConfigFile config) { if (ConfigSchemaVersion.Value < 2) { if (ActivationWindow.Value <= 0.6f) { ActivationWindow.Value = 2.5f; Plugin.Log.LogInfo((object)"Shield Sledding: raised ActivationWindow to 2.5s (was too short)."); } if (MinimumSlope.Value >= 10f) { MinimumSlope.Value = 2f; Plugin.Log.LogInfo((object)"Shield Sledding: lowered MinimumSlope to 2° (was too steep)."); } } if (ConfigSchemaVersion.Value < 3) { if (MinimumSlope.Value > 0f) { MinimumSlope.Value = 0f; Plugin.Log.LogInfo((object)"Shield Sledding: lowered MinimumSlope to 0° so flat ground works."); } ConfigSchemaVersion.Value = 3; } if (ConfigSchemaVersion.Value < 4) { ConfigSchemaVersion.Value = 4; } if (ConfigSchemaVersion.Value < 5) { if (SledGroundClearance.Value > 0.1f) { SledGroundClearance.Value = 0.06f; Plugin.Log.LogInfo((object)"Shield Sledding: lowered SledGroundClearance to 0.06m for slope contact."); } ConfigSchemaVersion.Value = 5; } if (ConfigSchemaVersion.Value < 6) { SledGroundClearance.Value = 0f; Plugin.Log.LogInfo((object)"Shield Sledding: set SledGroundClearance to 0m for full slope contact."); ConfigSchemaVersion.Value = 6; } if (ConfigSchemaVersion.Value < 7) { if (DamageToDurabilityMultiplier.Value >= 0.99f) { DamageToDurabilityMultiplier.Value = 0.15f; Plugin.Log.LogInfo((object)"Shield Sledding: lowered DamageToDurabilityMultiplier to 0.15 (was melting shields)."); } ConfigSchemaVersion.Value = 7; } if (ConfigSchemaVersion.Value < 8) { ConfigSchemaVersion.Value = 8; } if (ConfigSchemaVersion.Value < 9) { Plugin.Log.LogInfo((object)"Shield Sledding: config v9 — removed legacy collision/ghost options."); ConfigSchemaVersion.Value = 9; } if (ConfigSchemaVersion.Value < 10) { Plugin.Log.LogInfo((object)"Shield Sledding: config v10 — simplified damage toggle and per-shield speed entries in [ShieldSpeeds]."); ConfigSchemaVersion.Value = 10; } if (ConfigSchemaVersion.Value < 11) { if (MaximumSpeed.Value >= 20f) { MaximumSpeed.Value = 13f; } if (BaseAcceleration.Value >= 16f) { BaseAcceleration.Value = 10f; } if (ForwardLeanBonus.Value >= 3f) { ForwardLeanBonus.Value = 1.5f; } Plugin.Log.LogInfo((object)"Shield Sledding: config v11 — lowered default speeds and removed stats section."); ConfigSchemaVersion.Value = 11; } if (ConfigSchemaVersion.Value < 12) { if (MaximumSpeed.Value <= 13.5f) { MaximumSpeed.Value = 10f; } Plugin.Log.LogInfo((object)"Shield Sledding: config v12 — ShieldBanded baseline 10 m/s, tier scaling, Blocking skill affects speed."); ConfigSchemaVersion.Value = 12; } if (ConfigSchemaVersion.Value < 13) { Plugin.Log.LogInfo((object)"Shield Sledding: config v13 — Blocking skill scales 80% to 100% of max speed (10 m/s on banded at skill 100)."); ConfigSchemaVersion.Value = 13; } if (ConfigSchemaVersion.Value < 14) { Plugin.Log.LogInfo((object)"Shield Sledding: config v14 — uniform sled speed; shield tier affects durability wear ([ShieldWear])."); ConfigSchemaVersion.Value = 14; } if (ConfigSchemaVersion.Value < 15) { ResetObsoleteSpeedConfig(config); Plugin.Log.LogInfo((object)"Shield Sledding: config v15 — cleared obsolete [ShieldSpeeds] values. Speed is uniform; edit [ShieldWear] only."); ConfigSchemaVersion.Value = 15; } if (ConfigSchemaVersion.Value < 16) { MaximumSpeed.Value = 0f; Plugin.Log.LogInfo((object)"Shield Sledding: config v16 — slope-natural speed (MaximumSpeed 0 = no cap; speed follows hill steepness)."); ConfigSchemaVersion.Value = 16; } if (ConfigSchemaVersion.Value < 17) { ResetObsoleteSpeedConfig(config); ShieldWearConfig.MigrateLegacyWearDefaults(config); Plugin.Log.LogInfo((object)"Shield Sledding: config v17 — updated [ShieldWear] defaults; use ModdedWolf.ShieldSledding.cfg only."); ConfigSchemaVersion.Value = 17; } } private static void ResetObsoleteSpeedConfig(ConfigFile config) { for (int i = 0; i < ShieldSpeedRegistry.VanillaShieldPrefabs.Length; i++) { string text = ShieldSpeedRegistry.VanillaShieldPrefabs[i]; ConfigEntry val = config.Bind("ShieldSpeeds", text, 1f, (ConfigDescription)null); if (!Mathf.Approximately(val.Value, 1f)) { val.Value = 1f; Plugin.Log.LogInfo((object)("Shield Sledding: reset obsolete ShieldSpeeds." + text + " to 1.0 (unused).")); } } ConfigEntry val2 = config.Bind("ShieldSpeeds", "DefaultModdedSpeed", 1f, (ConfigDescription)null); if (!Mathf.Approximately(val2.Value, 1f)) { val2.Value = 1f; } ConfigEntry val3 = config.Bind("ShieldSpeeds", "CustomModdedSpeeds", string.Empty, (ConfigDescription)null); if (!string.IsNullOrEmpty(val3.Value)) { val3.Value = string.Empty; } } } internal static class DamageAbsorption { internal static bool ShouldAbsorb(Player player) { if (!Utility.IsLocalPlayer(player)) { return false; } ShieldSledController instance = ShieldSledController.Instance; if (instance != null) { if (!instance.IsSledding) { return instance.IsArmed; } return true; } return false; } internal static bool TryAbsorb(Character character, HitData hit) { if (!ConfigManager.AbsorbDamageToShield.Value) { return false; } Player player = (Player)(object)((character is Player) ? character : null); if (!ShouldAbsorb(player) || hit == null) { return false; } float totalDamage = ((DamageTypes)(ref hit.m_damage)).GetTotalDamage(); if (totalDamage <= 0.001f) { return false; } ShieldSledController instance = ShieldSledController.Instance; bool isSledding = instance.IsSledding; Character attacker = null; if (isSledding && ConfigManager.EndSledOnCombatHit.Value && totalDamage >= ConfigManager.CombatHitMinDamage.Value && TryGetCombatAttacker(hit, character, out attacker)) { if (totalDamage > 1f) { EffectController.Instance?.ShakeCamera(totalDamage * 0.02f); } instance.EndSledding(player, SledEndReason.CombatHit); if (ConfigManager.StaggerOnCombatHit.Value) { ApplyCombatStagger(player, hit, attacker); } ClearHitDamage(hit); return true; } if (isSledding) { ItemData handShield = Utility.GetHandShield(player); if (handShield != null) { instance.ReportDamageAsShieldWear(player, handShield, totalDamage); } } if (totalDamage > 1f) { EffectController.Instance?.ShakeCamera(totalDamage * 0.01f); } ClearHitDamage(hit); return true; } internal static bool TryGetCombatAttacker(HitData hit, Character victim, out Character attacker) { attacker = hit.GetAttacker(); if ((Object)(object)attacker == (Object)null || (Object)(object)attacker == (Object)(object)victim || attacker.IsDead()) { return false; } return true; } private static void ApplyCombatStagger(Player player, HitData hit, Character attacker) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //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_0039: Unknown result type (might be due to invalid IL or missing references) Vector3 val = hit.m_dir; if (((Vector3)(ref val)).sqrMagnitude < 0.01f && (Object)(object)attacker != (Object)null) { val = ((Component)player).transform.position - ((Component)attacker).transform.position; } if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = -((Component)player).transform.forward; } ((Character)player).Stagger(((Vector3)(ref val)).normalized); } internal static void ClearHitDamage(HitData hit) { if (hit != null) { hit.m_damage.m_blunt = 0f; hit.m_damage.m_slash = 0f; hit.m_damage.m_pierce = 0f; hit.m_damage.m_fire = 0f; hit.m_damage.m_frost = 0f; hit.m_damage.m_lightning = 0f; hit.m_damage.m_poison = 0f; hit.m_damage.m_spirit = 0f; hit.m_damage.m_chop = 0f; hit.m_damage.m_pickaxe = 0f; hit.m_staggerMultiplier = 0f; hit.m_pushForce = 0f; } } } internal sealed class DurabilityController { private Vector3 _lastPosition; private float _sessionTime; internal void Begin(Player player) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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) _lastPosition = (((Object)(object)player != (Object)null) ? ((Component)player).transform.position : Vector3.zero); _sessionTime = 0f; } internal void Tick(Player player, ItemData shield, PhysicsResult result) { //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) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if (ConfigManager.EnableDurabilityLoss.Value && !((Object)(object)player == (Object)null) && shield != null) { Vector3 position = ((Component)player).transform.position; float num = Vector3.Distance(position, _lastPosition); if (num > 3f) { num = 3f; } _lastPosition = position; _sessionTime += Time.fixedDeltaTime; float num2 = 1f; if ((int)result.Ground.Biome != 0) { num2 = Utility.GetDurabilityWearBiomeMultiplier(result.Ground.Biome); } float num3 = 0f; num3 += num * ConfigManager.DurabilityPerMeter.Value; num3 += Time.fixedDeltaTime * ConfigManager.DurabilityPerSecond.Value; num3 += result.HorizontalSpeed * 0.001f * ConfigManager.DurabilityPerMeter.Value; num3 *= num2; num3 *= ShieldSpeedRegistry.GetWearMultiplier(shield); ApplyWear(player, shield, num3); } } internal void OnLanding(Player player, ItemData shield, float impact) { if (ConfigManager.EnableDurabilityLoss.Value && shield != null && !(impact <= 0.5f)) { float num = impact * ConfigManager.LandingDamageMultiplier.Value * 0.15f; num *= ShieldSpeedRegistry.GetWearMultiplier(shield); ApplyWear(player, shield, num); } } internal void OnCollision(Player player, ItemData shield, float impactForce) { } internal void OnDamage(Player player, ItemData shield, float damage) { if (ConfigManager.EnableDurabilityLoss.Value && shield != null && !(damage <= 0f)) { float num = damage * ConfigManager.DamageToDurabilityMultiplier.Value; num *= ShieldSpeedRegistry.GetWearMultiplier(shield); num = Mathf.Min(num, shield.GetMaxDurability() * 0.08f); ApplyWear(player, shield, num); } } private void ApplyWear(Player player, ItemData shield, float wear) { if (!(wear <= 0f)) { float num = shield.GetMaxDurability() * 0.05f; if (num > 0f) { wear = Mathf.Min(wear, num); } shield.m_durability -= wear; if (shield.m_durability <= 0f) { shield.m_durability = 0f; ((Humanoid)player).UnequipItem(shield, true); ShieldSledController.Instance?.EndSledding(player, SledEndReason.ShieldBroken); } } } } internal sealed class EffectController { private readonly Dictionary _remoteParticles = new Dictionary(); private ParticleSystem _localParticles; private float _shakeTimer; private float _shakeStrength; private float _baseFov = -1f; private float _tilt; internal static EffectController Instance { get; private set; } internal EffectController() { Instance = this; } internal void Begin(Player player) { if ((Object)(object)_localParticles != (Object)null) { Object.Destroy((Object)(object)((Component)_localParticles).gameObject); _localParticles = null; } EnsureLocalParticles(player); } internal void End(Player player) { CleanupForPlayer(player); RestoreFov(); _tilt = 0f; } internal void CleanupOrphans() { GameObject[] array = Object.FindObjectsByType((FindObjectsSortMode)0); foreach (GameObject val in array) { if ((Object)(object)val != (Object)null && ((Object)val).name == "ShieldSledding_LocalParticles") { Object.Destroy((Object)(object)val); } } _localParticles = null; } internal void CleanupForPlayer(Player player) { if (!((Object)(object)player == (Object)null)) { if ((Object)(object)_localParticles != (Object)null) { Object.Destroy((Object)(object)((Component)_localParticles).gameObject); _localParticles = null; } RestoreFov(); _tilt = 0f; } } internal void Update(Player player, float speed, float steerX) { if (!((Object)(object)player == (Object)null) && !Utility.IsDedicatedServer()) { UpdateParticles(player, speed); if (!ConfigManager.EnableCameraEffects.Value) { UpdateRemoteEffects(); return; } UpdateCamera(player, speed, steerX); UpdateRemoteEffects(); } } private void UpdateParticles(Player player, float speed) { if (!ConfigManager.EnableParticles.Value) { if ((Object)(object)_localParticles != (Object)null) { _localParticles.Stop(true, (ParticleSystemStopBehavior)1); } } else if (speed > 1f) { EnsureLocalParticles(player); if ((Object)(object)_localParticles != (Object)null && !_localParticles.isPlaying) { _localParticles.Play(); } } else if ((Object)(object)_localParticles != (Object)null) { _localParticles.Stop(true, (ParticleSystemStopBehavior)1); } } internal void OnLanding(Player player, float impact) { ShakeCamera(impact * ConfigManager.CameraShakeStrength.Value * 0.02f); } internal void OnCollision(Player player, Vector3 point, Vector3 normal, float impact) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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) ShakeCamera(impact * ConfigManager.CameraShakeStrength.Value * 0.03f); if (ConfigManager.EnableShieldSparks.Value && ConfigManager.EnableParticles.Value) { SpawnBurst(point, normal, new Color(1f, 0.7f, 0.2f), 12); } } internal void OnWildlifeImpact(Player player, Vector3 point, Vector3 direction, float impact) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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) ShakeCamera(impact * ConfigManager.CameraShakeStrength.Value * 0.04f); if (ConfigManager.EnableShieldSparks.Value && ConfigManager.EnableParticles.Value) { SpawnBurst(point, direction, new Color(1f, 0.7f, 0.2f), 18); } } internal void ShakeCamera(float strength) { _shakeStrength = Mathf.Max(_shakeStrength, strength); _shakeTimer = 0.2f; } private void EnsureLocalParticles(Player player) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0064: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_00fa: 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_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: 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_019d: 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_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: 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) if (!((Object)(object)_localParticles != (Object)null)) { Transform feetAttach = ShieldSledVisual.GetFeetAttach(player); GameObject val = new GameObject("ShieldSledding_LocalParticles"); val.transform.SetParent(((Object)(object)feetAttach != (Object)null) ? feetAttach : ((Component)player).transform, false); val.transform.localPosition = (Vector3)(((Object)(object)feetAttach != (Object)null) ? Vector3.zero : new Vector3(0f, 0.1f, 0.4f)); _localParticles = val.AddComponent(); MainModule main = _localParticles.main; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.45f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(1.5f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.08f); ((MainModule)(ref main)).maxParticles = 48; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.92f, 0.96f, 1f, 0.65f)); EmissionModule emission = _localParticles.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(18f); ShapeModule shape = _localParticles.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4; ((ShapeModule)(ref shape)).angle = 14f; ((ShapeModule)(ref shape)).radius = 0.15f; ColorOverLifetimeModule colorOverLifetime = _localParticles.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val2 = new Gradient(); val2.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(new Color(0.95f, 0.98f, 1f), 0f), new GradientColorKey(new Color(0.75f, 0.88f, 1f), 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[2] { new GradientAlphaKey(0.65f, 0f), new GradientAlphaKey(0f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val2); ApplyParticleMaterial(_localParticles); } } private static Shader FindParticleShader() { string[] array = new string[7] { "Particles/Standard Unlit", "Legacy Shaders/Particles/Alpha Blended", "Mobile/Particles/Additive", "Universal Render Pipeline/Particles/Unlit", "Sprites/Default", "Unlit/Color", "Unlit/Transparent" }; for (int i = 0; i < array.Length; i++) { Shader val = Shader.Find(array[i]); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static Texture2D CreateWhiteParticleTexture() { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false); val.SetPixel(0, 0, Color.white); val.Apply(false, true); return val; } private static void ApplyParticleMaterial(ParticleSystem particles) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)particles == (Object)null) { return; } ParticleSystemRenderer component = ((Component)particles).GetComponent(); if ((Object)(object)component == (Object)null) { return; } Shader val = FindParticleShader(); if (!((Object)(object)val == (Object)null)) { Color val2 = default(Color); ((Color)(ref val2))..ctor(0.92f, 0.96f, 1f, 0.65f); Material val3 = new Material(val); val3.mainTexture = (Texture)(object)CreateWhiteParticleTexture(); if (val3.HasProperty("_Color")) { val3.SetColor("_Color", val2); } if (val3.HasProperty("_TintColor")) { val3.SetColor("_TintColor", val2); } val3.color = val2; ((Renderer)component).material = val3; } } private void UpdateCamera(Player player, float speed, float steerX) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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_00f5: Unknown result type (might be due to invalid IL or missing references) Camera val = GameCamera.instance?.m_camera; if (!((Object)(object)val == (Object)null)) { if (_baseFov < 0f) { _baseFov = val.fieldOfView; } float num = 12f; if (Utility.TrySampleGround(player, out var sample)) { num = Mathf.Max(6f, ShieldSpeedRegistry.EstimateNaturalSpeed(in sample)); } float num2 = Mathf.Clamp01(speed / num); val.fieldOfView = _baseFov + num2 * ConfigManager.SpeedFovIncrease.Value; _tilt = Mathf.Lerp(_tilt, (0f - steerX) * ConfigManager.CameraTiltStrength.Value, Time.deltaTime * 6f); if (_shakeTimer > 0f) { _shakeTimer -= Time.deltaTime; Vector3 val2 = Random.insideUnitSphere * _shakeStrength; Transform transform = ((Component)val).transform; transform.localPosition += val2 * Time.deltaTime * 10f; } } } private void RestoreFov() { Camera val = GameCamera.instance?.m_camera; if ((Object)(object)val != (Object)null && _baseFov > 0f) { val.fieldOfView = _baseFov; } _baseFov = -1f; } private void UpdateRemoteEffects() { List allPlayers = Player.GetAllPlayers(); if (allPlayers == null) { return; } for (int i = 0; i < allPlayers.Count; i++) { Player val = allPlayers[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)Player.m_localPlayer)) { if (!MultiplayerSync.Instance.TryReadRemoteState(val, out var active, out var speed, out var _)) { StopRemote(val); } else if (!active || speed < 1f || !ConfigManager.EnableParticles.Value) { StopRemote(val); } else { EnsureRemoteParticles(val); } } } } private void EnsureRemoteParticles(Player player) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)player).GetInstanceID(); if (!_remoteParticles.ContainsKey(instanceID)) { GameObject val = new GameObject("ShieldSledding_RemoteParticles"); val.transform.SetParent(((Component)player).transform, false); val.transform.localPosition = new Vector3(0f, 0.1f, 0.4f); ParticleSystem val2 = val.AddComponent(); MainModule main = val2.main; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.4f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(1.2f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.08f); ((MainModule)(ref main)).maxParticles = 24; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.95f, 0.98f, 1f, 0.5f)); ApplyParticleMaterial(val2); val2.Play(); _remoteParticles[instanceID] = val2; } } private void StopRemote(Player player) { int instanceID = ((Object)player).GetInstanceID(); if (_remoteParticles.TryGetValue(instanceID, out var value) && (Object)(object)value != (Object)null) { value.Stop(true, (ParticleSystemStopBehavior)1); } } private static void SpawnBurst(Vector3 point, Vector3 normal, Color color, int count) { //IL_0004: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0016: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < count; i++) { Vector3 val = Random.insideUnitSphere * 0.2f; Debug.DrawRay(point + val, normal * 0.5f, color, 0.25f); } } } internal sealed class MultiplayerSync { internal const string ImpactRpc = "ShieldSledding_Impact"; private static readonly int ZdoActive = StringExtensionMethods.GetStableHashCode("SS_Active"); private static readonly int ZdoShieldPrefab = StringExtensionMethods.GetStableHashCode("SS_ShieldPrefab"); private static readonly int ZdoSpeed = StringExtensionMethods.GetStableHashCode("SS_Speed"); private readonly HashSet _registeredViews = new HashSet(); private float _lastWriteTime; private bool _lastActive; private float _lastSpeed; private string _lastShield = string.Empty; internal static MultiplayerSync Instance { get; private set; } internal MultiplayerSync() { Instance = this; } internal static void EnsureRegistered(ZNetView nview) { if ((Object)(object)nview == (Object)null || !nview.IsValid()) { return; } MultiplayerSync instance = Instance; if (instance == null) { return; } int instanceID = ((Object)nview).GetInstanceID(); if (!instance._registeredViews.Add(instanceID)) { return; } nview.Register("ShieldSledding_Impact", (Action)delegate(long sender, Vector3 point, float impact) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!(impact < 1f)) { EffectController.Instance?.OnCollision(null, point, Vector3.up, impact); AudioController.Instance?.PlayImpact(Player.m_localPlayer, impact); } }); } internal void WriteLocalState(Player player, bool active, float speed) { if ((Object)(object)player == (Object)null || !Utility.IsLocalPlayer(player)) { return; } ZDO playerZdo = Utility.GetPlayerZdo(player); if (playerZdo == null) { return; } string text = string.Empty; ItemData equippedShield = Utility.GetEquippedShield(player); if (equippedShield != null) { text = Utility.GetShieldPrefabName(equippedShield); } if (active != _lastActive || !Mathf.Approximately(speed, _lastSpeed) || !(text == _lastShield) || !(Time.time - _lastWriteTime < 0.1f)) { playerZdo.Set(ZdoActive, active ? 1 : 0, false); playerZdo.Set(ZdoSpeed, speed); if (!string.IsNullOrEmpty(text)) { playerZdo.Set(ZdoShieldPrefab, text); } _lastActive = active; _lastSpeed = speed; _lastShield = text; _lastWriteTime = Time.time; } } internal bool TryReadRemoteState(Player player, out bool active, out float speed, out string shieldPrefab) { active = false; speed = 0f; shieldPrefab = string.Empty; ZDO playerZdo = Utility.GetPlayerZdo(player); if (playerZdo == null) { return false; } active = playerZdo.GetInt(ZdoActive, 0) != 0; speed = playerZdo.GetFloat(ZdoSpeed, 0f); shieldPrefab = playerZdo.GetString(ZdoShieldPrefab, string.Empty); return true; } internal void UpdateRemotePlayers() { List allPlayers = Player.GetAllPlayers(); if (allPlayers == null) { return; } for (int i = 0; i < allPlayers.Count; i++) { Player val = allPlayers[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)Player.m_localPlayer)) { EnsureRegistered(((Component)val).GetComponent()); } } } internal void SendImpactEvent(Player player, Vector3 point, float impact) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { ZNetView component = ((Component)player).GetComponent(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { EnsureRegistered(component); component.InvokeRPC(ZNetView.Everybody, "ShieldSledding_Impact", new object[2] { point, impact }); } } } } internal struct SledRunRecord { public float Distance; public float MaxSpeed; public float LongestJump; public string TimestampUtc; } internal struct GhostFrame { public Vector3 Position; public Quaternion Rotation; public float Time; } internal static class GhostReplaySystem { private static readonly List Frames = new List(); private static GameObject _ghost; private static float _sessionStart; internal static void BeginSession() { Frames.Clear(); _sessionStart = Time.time; DestroyGhost(); } internal static void RecordFrame(Player player) { } internal static void EndSession() { Frames.Clear(); DestroyGhost(); } private static void SpawnGhostPlayback() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown DestroyGhost(); _ghost = new GameObject("ShieldSledding_Ghost"); _ghost.AddComponent().Initialize(Frames.ToArray()); } private static void DestroyGhost() { if ((Object)(object)_ghost != (Object)null) { Object.Destroy((Object)(object)_ghost); _ghost = null; } } } internal sealed class GhostPlayback : MonoBehaviour { private GhostFrame[] _frames; private int _index; private float _startTime; internal void Initialize(GhostFrame[] frames) { _frames = frames; _index = 0; _startTime = Time.time; TryCreateGhostVisual(((Component)this).transform); } private static void TryCreateGhostVisual(Transform parent) { //IL_0039: 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_0078: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) Shader val = FindGhostShader(); if ((Object)(object)val == (Object)null) { return; } GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)1); val2.transform.SetParent(parent, false); val2.transform.localScale = new Vector3(0.5f, 0.9f, 0.5f); Collider component = val2.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } Renderer component2 = val2.GetComponent(); if ((Object)(object)component2 == (Object)null) { Object.Destroy((Object)(object)val2); return; } Material val3 = new Material(val); Color val4 = default(Color); ((Color)(ref val4))..ctor(0.4f, 0.8f, 1f, 0.35f); if (val3.HasProperty("_Color")) { val3.SetColor("_Color", val4); } else { val3.color = val4; } component2.material = val3; } private static Shader FindGhostShader() { string[] array = new string[4] { "Custom/StandardClear", "Custom/StandardDoubleSided", "Unlit/Color", "Sprites/Default" }; for (int i = 0; i < array.Length; i++) { Shader val = Shader.Find(array[i]); if ((Object)(object)val != (Object)null) { return val; } } return null; } private void Update() { //IL_0080: 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) if (_frames == null || _frames.Length == 0) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } float num = Time.time - _startTime; while (_index < _frames.Length - 1 && _frames[_index + 1].Time <= num) { _index++; } GhostFrame ghostFrame = _frames[_index]; ((Component)this).transform.SetPositionAndRotation(ghostFrame.Position, ghostFrame.Rotation); if (_index >= _frames.Length - 1 && num > _frames[_frames.Length - 1].Time + 1f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } internal static class RecordsManager { private static string FilePath => Path.Combine(Paths.ConfigPath, "ShieldSledding_Records.json"); internal static void SaveRun(SledRunRecord record) { List list = new List(); if (File.Exists(FilePath)) { list.AddRange(File.ReadAllLines(FilePath)); } list.Add($"{record.TimestampUtc}|{record.Distance:F2}|{record.MaxSpeed:F2}|{record.LongestJump:F2}"); if (list.Count > 200) { list.RemoveAt(0); } File.WriteAllLines(FilePath, list); } } internal static class LeaderboardManager { private static readonly List Entries = new List(); private static string FilePath => Path.Combine(Paths.ConfigPath, "ShieldSledding_Leaderboard.json"); internal static void Submit(SledRunRecord record) { Entries.Add(record); Entries.Sort((SledRunRecord a, SledRunRecord b) => b.MaxSpeed.CompareTo(a.MaxSpeed)); if (Entries.Count > 25) { Entries.RemoveAt(Entries.Count - 1); } List list = new List(Entries.Count); for (int num = 0; num < Entries.Count; num++) { SledRunRecord sledRunRecord = Entries[num]; list.Add($"{sledRunRecord.TimestampUtc}|{sledRunRecord.Distance:F2}|{sledRunRecord.MaxSpeed:F2}|{sledRunRecord.LongestJump:F2}"); } File.WriteAllLines(FilePath, list); } } internal static class TimeTrialManager { private static float _startTime; private static bool _active; internal static void BeginSession() { } internal static void EndSession() { } } internal static class SledPatches { internal static bool UpdateMotionPatched; internal static void Apply(Harmony harmony) { PatchMethod(harmony, typeof(Character), "Jump", "CharacterJumpPrefix", "CharacterJumpPostfix"); PatchMethod(harmony, typeof(Player), "SetControls", "PlayerSetControlsPrefix"); PatchMethod(harmony, typeof(Humanoid), "UpdateBlock", "HumanoidUpdateBlockPrefix"); PatchMethod(harmony, typeof(Humanoid), "EquipItem", "HumanoidEquipItemPrefix"); PatchMethod(harmony, typeof(Humanoid), "UnequipItem", "HumanoidUnequipItemPrefix"); PatchMethod(harmony, typeof(Character), "UpdateMotion", "CharacterUpdateMotionPrefix", null, new Type[1] { typeof(float) }); PatchDeclaredMethod(harmony, typeof(Character), "Damage", "CharacterDamagePrefix", null, new Type[1] { typeof(HitData) }); PatchAllDeclaredMethods(harmony, typeof(Character), "RPC_Damage", "CharacterRpcDamagePrefix"); PatchMethod(harmony, typeof(Character), "UpdateGroundContact", "CharacterUpdateGroundContactPrefix", "CharacterUpdateGroundContactPostfix"); PatchMethod(harmony, typeof(Character), "UpdateWater", "CharacterUpdateWaterPrefix"); PatchMethod(harmony, typeof(VisEquipment), "UpdateEquipmentVisuals", "VisEquipmentUpdateEquipmentVisualsPrefix", "VisEquipmentUpdateEquipmentPostfix"); PatchMethod(harmony, typeof(ZNetView), "OnDestroy", "ZNetViewOnDestroyPrefix"); } private static void PatchMethod(Harmony harmony, Type type, string methodName, string prefix = null, string postfix = null, Type[] argTypes = null) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) MethodInfo methodInfo = ((argTypes == null) ? AccessTools.Method(type, methodName, (Type[])null, (Type[])null) : AccessTools.Method(type, methodName, argTypes, (Type[])null)); if (methodInfo == null) { Plugin.Log.LogError((object)("Shield Sledding: could not patch " + type.Name + "." + methodName)); return; } if (type == typeof(Character) && methodName == "UpdateMotion") { UpdateMotionPatched = true; } harmony.Patch((MethodBase)methodInfo, (prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(SledPatches), prefix, (Type[])null), (postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(SledPatches), postfix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)("Shield Sledding: patched " + type.Name + "." + methodName)); } private static void PatchDeclaredMethod(Harmony harmony, Type type, string methodName, string prefix = null, string postfix = null, Type[] argTypes = null) { //IL_0058: 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) MethodInfo methodInfo = ((argTypes == null) ? AccessTools.DeclaredMethod(type, methodName, (Type[])null, (Type[])null) : AccessTools.DeclaredMethod(type, methodName, argTypes, (Type[])null)); if (methodInfo == null) { Plugin.Log.LogError((object)("Shield Sledding: could not patch declared " + type.Name + "." + methodName)); return; } harmony.Patch((MethodBase)methodInfo, (prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(SledPatches), prefix, (Type[])null), (postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(SledPatches), postfix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)("Shield Sledding: patched declared " + type.Name + "." + methodName)); } private static void PatchAllDeclaredMethods(Harmony harmony, Type type, string methodName, string prefix = null) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) int num = 0; foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(type)) { if (!(declaredMethod.Name != methodName)) { harmony.Patch((MethodBase)declaredMethod, (prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(SledPatches), prefix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ParameterInfo[] parameters = declaredMethod.GetParameters(); string text = ((parameters.Length == 0) ? string.Empty : string.Join(", ", Array.ConvertAll(parameters, (ParameterInfo p) => p.ParameterType.Name))); Plugin.Log.LogInfo((object)("Shield Sledding: patched declared " + type.Name + "." + methodName + "(" + text + ")")); num++; } } if (num == 0) { Plugin.Log.LogInfo((object)("Shield Sledding: skipped optional patch " + type.Name + "." + methodName + " (no matching methods).")); } } private static bool CharacterJumpPrefix(Character __instance) { if (!Utility.IsLocalPlayer((Player)(object)((__instance is Player) ? __instance : null))) { return true; } ShieldSledController instance = ShieldSledController.Instance; if (instance == null || !instance.IsSledding) { return true; } return false; } private static void CharacterJumpPostfix(Character __instance) { if (Utility.IsLocalPlayer((Player)(object)((__instance is Player) ? __instance : null))) { ShieldSledController.Instance?.NotifyJump(); } } private static void PlayerSetControlsPrefix(Player __instance, ref Vector3 movedir, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold, ref bool block, ref bool blockHold, ref bool jump, ref bool crouch, ref bool run, ref bool autoRun, ref bool dodge, ref Vector3 ___m_moveDir) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (Utility.IsLocalPlayer(__instance)) { ShieldSledController instance = ShieldSledController.Instance; if (((instance != null) & jump) && !instance.IsSledding) { instance.NotifyJumpIntentFromInput(); } if (instance != null && instance.TryOverrideControls(__instance, ref movedir, ref block, ref jump, ref run)) { ___m_moveDir = Vector3.zero; movedir = Vector3.zero; attack = false; attackHold = false; secondaryAttack = false; secondaryAttackHold = false; blockHold = false; dodge = false; autoRun = false; crouch = false; } } } private static bool HumanoidUpdateBlockPrefix(Humanoid __instance) { if (!Utility.IsLocalPlayer((Player)(object)((__instance is Player) ? __instance : null))) { return true; } if (ShieldSledController.Instance != null) { return !ShieldSledController.Instance.IsSledding; } return true; } private static bool HumanoidEquipItemPrefix(Humanoid __instance, ItemData item) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 if (!Utility.IsLocalPlayer((Player)(object)((__instance is Player) ? __instance : null))) { return true; } ShieldSledController instance = ShieldSledController.Instance; if (instance == null || !instance.IsSledding) { return true; } ItemData lockedShield = instance.LockedShield; if (lockedShield == null || item == null) { return true; } SharedData shared = item.m_shared; if (shared != null && (int)shared.m_itemType == 5 && item != lockedShield) { return false; } return true; } private static bool HumanoidUnequipItemPrefix(Humanoid __instance, ItemData item) { if (!Utility.IsLocalPlayer((Player)(object)((__instance is Player) ? __instance : null))) { return true; } ShieldSledController instance = ShieldSledController.Instance; if (instance == null || !instance.IsSledding) { return true; } if (item != null && item == instance.LockedShield) { return false; } return true; } private static bool CharacterUpdateMotionPrefix(Character __instance, float dt) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) Player player = (Player)(object)((__instance is Player) ? __instance : null); if (!Utility.IsLocalPlayer(player)) { return true; } ShieldSledController instance = ShieldSledController.Instance; if (instance == null) { return true; } if (instance.IsArmed && !instance.IsSledding) { instance.TrackArmedMomentum(player); if (!instance.TryActivateOnLanding(player)) { return true; } } if (instance.IsSledding) { instance.ApplySledPhysics(player, dt); GroundSample ground; bool flag = Utility.TryGetSledGround(player, out ground); if (flag && !instance.IsInStartupGrace && !ground.IsWaterSurface) { SledGroundSolver.FixGroundClip(player); } SledGroundSolver.SyncCharacterMotionState(__instance, instance.SimulatedVelocity, flag); return false; } return true; } private static bool VisEquipmentUpdateEquipmentVisualsPrefix(VisEquipment __instance) { if (!Utility.IsLocalPlayer(((Component)__instance).GetComponent())) { return true; } ShieldSledController instance = ShieldSledController.Instance; if (instance != null) { return !instance.IsSledding; } return true; } private static void VisEquipmentUpdateEquipmentPostfix(VisEquipment __instance) { Player component = ((Component)__instance).GetComponent(); if (Utility.IsLocalPlayer(component)) { ShieldSledController instance = ShieldSledController.Instance; if (instance != null && instance.IsShieldSledActive) { ShieldSledVisual.LateUpdate(component); } } } private static bool CharacterUpdateGroundContactPrefix(Character __instance, ref float ___m_maxAirAltitude) { //IL_0048: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_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_007e: 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) Player player = (Player)(object)((__instance is Player) ? __instance : null); if (!Utility.IsLocalPlayer(player)) { return true; } ShieldSledController instance = ShieldSledController.Instance; if (instance == null || !instance.IsSledding) { if (instance != null && instance.IsShieldSledActive) { ___m_maxAirAltitude = ((Component)__instance).transform.position.y; } return true; } ___m_maxAirAltitude = ((Component)__instance).transform.position.y; if (Utility.TryGetSledGround(player, out var ground)) { if (ground.IsWaterSurface) { __instance.m_groundContact = true; __instance.m_lastGroundPoint = ground.Point; __instance.m_lastGroundNormal = Vector3.up; __instance.m_lastGroundCollider = null; } else { bool groundContact = !Utility.IsSeparatingFromGround(instance.SimulatedVelocity, in ground); __instance.m_groundContact = groundContact; __instance.m_lastGroundPoint = ground.Point; __instance.m_lastGroundNormal = ground.Normal; __instance.m_lastGroundCollider = ground.Collider; } } return false; } private static void CharacterUpdateGroundContactPostfix(Character __instance) { Player player = (Player)(object)((__instance is Player) ? __instance : null); if (Utility.IsLocalPlayer(player)) { ShieldSledController instance = ShieldSledController.Instance; if (instance != null && !instance.IsSledding && instance.IsArmed && __instance.m_groundContact) { instance.TrackArmedMomentum(player); instance.TryActivateOnLanding(player); } } } private static bool CharacterUpdateWaterPrefix(Character __instance) { Player player = (Player)(object)((__instance is Player) ? __instance : null); if (!Utility.IsLocalPlayer(player)) { return true; } ShieldSledController instance = ShieldSledController.Instance; if (instance == null || !instance.IsSledding) { return true; } if (WaterSledHelper.CanWaterSled(instance.CurrentSpeed) && WaterSledHelper.IsOverWater(player) && !instance.IsAirborneForSledJump(player)) { return false; } return true; } private static bool CharacterDamagePrefix(Character __instance, HitData hit) { if (DamageAbsorption.TryAbsorb(__instance, hit)) { return false; } return true; } private static bool CharacterRpcDamagePrefix(Character __instance, object[] __args) { HitData val = FindHitData(__args); if (val == null) { return true; } if (DamageAbsorption.TryAbsorb(__instance, val)) { return false; } return true; } private static HitData FindHitData(object[] args) { if (args == null) { return null; } foreach (object obj in args) { HitData val = (HitData)((obj is HitData) ? obj : null); if (val != null) { return val; } } return null; } private static void ZNetViewOnDestroyPrefix(ZNetView __instance) { Player component = ((Component)__instance).GetComponent(); if (!((Object)(object)component == (Object)null) && __instance.IsOwner()) { ShieldSledVisual.OnPlayerDestroyed(component); EffectController.Instance?.CleanupForPlayer(component); ShieldSledController.Instance?.EndSledding(component, SledEndReason.Manual); } } } internal struct PhysicsResult { public float HorizontalSpeed; public float LandingImpact; public bool OnGround; public GroundSample Ground; public Vector3 Velocity; } internal sealed class PhysicsController { private const float ReferenceGravity = 9.81f; private static PhysicsMaterial _frictionlessMaterial; private Vector3 _lastVelocity; private bool _wasAirborne; private bool _bodyTuned; private bool _savedUseGravity; private bool _savedIsKinematic; private float _savedDrag; private float _savedAngularDrag; private float _jumpCooldownUntil; private float _airborneGraceUntil; private float _sledStartGraceUntil; private float _sledStartDuration = 0.65f; private float _entrySpeedFloor; private float _entrySpeedFloorUntil; private bool _dynamicStartup; private bool _preferDynamicBody; private readonly List<(Collider Collider, PhysicsMaterial Material)> _savedColliderMaterials = new List<(Collider, PhysicsMaterial)>(); internal Vector3 SimulatedVelocity => _lastVelocity; internal bool IsInStartupGrace => Time.time < _sledStartGraceUntil; internal float StartupBlend { get { if (_sledStartDuration <= 0f) { return 0f; } return Mathf.Clamp01((_sledStartGraceUntil - Time.time) / _sledStartDuration); } } static PhysicsController() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown _frictionlessMaterial = new PhysicsMaterial("ShieldSledFrictionless") { dynamicFriction = 0f, staticFriction = 0f, frictionCombine = (PhysicsMaterialCombine)2, bounceCombine = (PhysicsMaterialCombine)2, bounciness = 0f }; } internal void CaptureBodyVelocity(Player player) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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) Rigidbody body = Utility.GetBody(player); if ((Object)(object)body == (Object)null) { _lastVelocity = Vector3.zero; return; } _lastVelocity = body.linearVelocity; if (((Vector3)(ref _lastVelocity)).sqrMagnitude < 0.0001f) { _lastVelocity = ((Character)player).GetVelocity(); } } internal void SetSimulatedVelocity(Player player, Vector3 velocity) { //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) //IL_0029: Unknown result type (might be due to invalid IL or missing references) _lastVelocity = velocity; Rigidbody body = Utility.GetBody(player); if (!((Object)(object)body == (Object)null) && (!_bodyTuned || !body.isKinematic)) { body.linearVelocity = velocity; } } internal bool TryJump(Player player) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: 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_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01df: 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_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: 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_0168: 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_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0263: 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_027a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || Time.time < _jumpCooldownUntil) { return false; } if (((Character)player).InTar()) { return false; } ShieldSledController instance = ShieldSledController.Instance; float speed = instance?.CurrentSpeed ?? Utility.HorizontalSpeed(_lastVelocity); bool flag = instance != null && instance.IsSledding && WaterSledHelper.IsWaterSledding(player, speed); if (((Character)player).InWater() && !flag) { return false; } if (IsAirborneForPhysics(player)) { return false; } if (!Utility.TryGetSledGround(player, out var ground) && !Utility.TryProbeGroundBelow(player, 1.5f, out ground)) { return false; } if (Utility.GetFeetHeightAboveGround(player, ground) > 0.34f) { return false; } if (!ground.IsWaterSurface && Utility.IsSeparatingFromGround(_lastVelocity, in ground, 0.35f)) { return false; } float jumpStaminaUsage = ((Character)player).m_jumpStaminaUsage; if (jumpStaminaUsage > 0f && player.GetStamina() < jumpStaminaUsage) { return false; } if (jumpStaminaUsage > 0f) { ((Character)player).UseStamina(jumpStaminaUsage); } Vector3 val = Vector3.ProjectOnPlane(_lastVelocity, ground.Normal); Vector3 val2; if (((Vector3)(ref val)).sqrMagnitude > 0.25f) { val2 = val + ground.Normal * ((Character)player).m_jumpForce; } else { Vector3 val3 = Vector3.ProjectOnPlane(((Component)player).transform.forward, ground.Normal); if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f && ((Vector3)(ref ground.SlopeDown)).sqrMagnitude > 0.0001f) { val3 = ground.SlopeDown; } else if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { val3 = Utility.Flatten(((Component)player).transform.forward); } ((Vector3)(ref val3)).Normalize(); val2 = val3 * Mathf.Max(((Character)player).m_jumpForceForward, 1f) + ground.Normal * ((Character)player).m_jumpForce; } _lastVelocity = val2; ((Character)player).m_groundContact = false; ((Character)player).m_sliding = false; ((Character)player).m_maxAirAltitude = ((Component)player).transform.position.y; _wasAirborne = true; _airborneGraceUntil = Time.time + 0.22f; _jumpCooldownUntil = Time.time + 0.35f; if (ground.IsWaterSurface) { WaterSledHelper.ResetSurfaceSmoothing(); } SetSimulatedVelocity(player, val2); Rigidbody body = Utility.GetBody(player); if ((Object)(object)body != (Object)null && _bodyTuned && body.isKinematic) { body.MovePosition(body.position + Vector3.up * 0.12f); ((Component)player).transform.position = body.position; } return true; } internal bool IsAirborneForPhysics(Player player) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } if (Time.time < _airborneGraceUntil) { return true; } if (Time.time < _sledStartGraceUntil && ((Character)player).m_groundContact) { return false; } ShieldSledController instance = ShieldSledController.Instance; if (instance != null && instance.IsSledding && WaterSledHelper.TryGetWaterSledGround(player, instance.CurrentSpeed, out var ground) && Utility.GetFeetPosition(player).y <= ground.WaterSurfaceY + 0.38f + 0.35f) { return false; } if (!Utility.TryProbeGroundBelow(player, 1.5f, out var sample)) { return true; } if (Utility.GetFeetHeightAboveGround(player, sample) > 0.38f) { return true; } return Utility.IsSeparatingFromGround(_lastVelocity, in sample); } internal void Reset(Player player) { CaptureBodyVelocity(player); _wasAirborne = false; _airborneGraceUntil = 0f; } internal void ConfigureBodyForSled(Player player) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) ConfigureBodyForSled(player, Vector3.zero); } internal void ConfigureBodyForSled(Player player, Vector3 seedVelocity) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) Rigidbody body = Utility.GetBody(player); if (!((Object)(object)body == (Object)null)) { _savedUseGravity = body.useGravity; _savedIsKinematic = body.isKinematic; _savedDrag = body.linearDamping; _savedAngularDrag = body.angularDamping; body.useGravity = false; body.linearDamping = 0f; body.angularDamping = 0f; body.isKinematic = true; ApplyFrictionlessColliders(player); _lastVelocity = seedVelocity; _dynamicStartup = false; _preferDynamicBody = false; _bodyTuned = true; } } internal Vector3 ResolveLandingSeed(Player player, in GroundSample ground, ItemData shield, Vector3 armedMomentum, float armedPeakHorizontal, bool armedLanding = false) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) //IL_003a: 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_0046: 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_0059: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_0111: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015a: 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_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) Vector3 groundNormal; Vector3 slopeDown; Vector3 best; float bestSpeed; if (!((Object)(object)player == (Object)null)) { Vector3 val = ground.Normal; if (!(((Vector3)(ref val)).sqrMagnitude < 0.01f)) { groundNormal = ground.Normal; slopeDown = ground.SlopeDown; best = Vector3.zero; bestSpeed = 0f; Vector3 hint = armedMomentum; if (((Vector3)(ref hint)).sqrMagnitude < 0.01f) { hint = ((Character)player).m_currentVel; } if (((Vector3)(ref hint)).sqrMagnitude < 0.01f) { hint = ((Character)player).GetVelocity(); } Rigidbody body = Utility.GetBody(player); if ((Object)(object)body != (Object)null) { val = body.linearVelocity; if (((Vector3)(ref val)).sqrMagnitude > ((Vector3)(ref hint)).sqrMagnitude) { hint = body.linearVelocity; } } if (((Vector3)(ref hint)).sqrMagnitude < 0.01f && (Object)(object)player != (Object)null) { hint = ((Component)player).transform.forward; } Consider(armedMomentum); Consider(((Character)player).GetVelocity()); if ((Object)(object)body != (Object)null) { Consider(body.linearVelocity); } Consider(((Character)player).m_currentVel); ConsiderCarriedHorizontal(armedPeakHorizontal, hint); if (armedPeakHorizontal > bestSpeed + 0.05f && ((Vector3)(ref slopeDown)).sqrMagnitude > 0.0001f && bestSpeed < armedPeakHorizontal * 0.9f) { Consider(((Vector3)(ref slopeDown)).normalized * armedPeakHorizontal); } if (bestSpeed < 0.12f) { return Vector3.zero; } float num = ShieldSpeedRegistry.EstimateNaturalSpeed(in ground); if (((Vector3)(ref slopeDown)).sqrMagnitude > 0.0001f && Vector3.Dot(((Vector3)(ref best)).normalized, ((Vector3)(ref slopeDown)).normalized) < -0.35f) { return Vector3.zero; } float num2 = ((num > 0.5f) ? Mathf.Min(bestSpeed, num) : bestSpeed); if (num2 < 0.12f) { return Vector3.zero; } return ((Vector3)(ref best)).normalized * num2; } } return Vector3.zero; void Consider(Vector3 worldVel) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_0035: 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) if (!(((Vector3)(ref worldVel)).sqrMagnitude < 0.01f)) { Vector3 val2 = Vector3.ProjectOnPlane(worldVel, groundNormal); float magnitude = ((Vector3)(ref val2)).magnitude; if (magnitude > bestSpeed) { bestSpeed = magnitude; best = val2; } } } void ConsiderCarriedHorizontal(float horizontalSpeed, Vector3 v) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_0053: Unknown result type (might be due to invalid IL or missing references) //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_003b: Unknown result type (might be due to invalid IL or missing references) if (!(horizontalSpeed < 0.12f)) { Vector3 val2 = Utility.Flatten(v); if (((Vector3)(ref val2)).sqrMagnitude < 0.01f && ((Vector3)(ref slopeDown)).sqrMagnitude > 0.0001f) { val2 = Utility.Flatten(slopeDown); } if (!(((Vector3)(ref val2)).sqrMagnitude < 0.01f)) { Consider(((Vector3)(ref val2)).normalized * horizontalSpeed); } } } } internal Vector3 ComputeLandingSeed(Player player, in GroundSample ground, ItemData shield, Vector3 armedMomentum) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_00a0: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0142: 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_0151: Unknown result type (might be due to invalid IL or missing references) //IL_017d: 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_0175: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { Vector3 val = ground.Normal; if (!(((Vector3)(ref val)).sqrMagnitude < 0.01f)) { Vector3 val2 = armedMomentum; if (((Vector3)(ref val2)).sqrMagnitude < 0.12f) { val2 = ((Character)player).GetVelocity(); Rigidbody body = Utility.GetBody(player); if ((Object)(object)body != (Object)null && !body.isKinematic) { val = body.linearVelocity; if (((Vector3)(ref val)).sqrMagnitude > ((Vector3)(ref val2)).sqrMagnitude) { val2 = body.linearVelocity; } } } if (((Vector3)(ref val2)).sqrMagnitude < 0.12f && ((Vector3)(ref ((Character)player).m_currentVel)).sqrMagnitude > 0.12f) { val2 = ((Character)player).m_currentVel; } Vector3 val3 = Vector3.ProjectOnPlane(val2, ground.Normal); float magnitude = ((Vector3)(ref val3)).magnitude; if (magnitude < 0.12f && ((Vector3)(ref armedMomentum)).sqrMagnitude > 0.12f) { val3 = Vector3.ProjectOnPlane(armedMomentum, ground.Normal); magnitude = ((Vector3)(ref val3)).magnitude; } if (magnitude < 0.12f) { return Vector3.zero; } float num = ShieldSpeedRegistry.EstimateNaturalSpeed(in ground); Vector3 slopeDown = ground.SlopeDown; if (((Vector3)(ref slopeDown)).sqrMagnitude > 0.0001f) { float num2 = Vector3.Dot(((Vector3)(ref val3)).normalized, ((Vector3)(ref slopeDown)).normalized); if (num2 < -0.35f) { return Vector3.zero; } if (num2 < 0.45f) { val3 = Vector3.Lerp(val3, ((Vector3)(ref slopeDown)).normalized * magnitude, 0.35f); } } float num3 = ((num > 0.5f) ? Mathf.Min(magnitude, num * 0.98f) : magnitude); if (num3 < 0.12f) { return Vector3.zero; } return ((Vector3)(ref val3)).normalized * num3; } } return Vector3.zero; } internal void PrepareSledStart(Player player, Vector3 seedVelocity, in GroundSample ground, ItemData shield) { //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) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) _lastVelocity = seedVelocity; _wasAirborne = false; _airborneGraceUntil = 0f; float magnitude = ((Vector3)(ref seedVelocity)).magnitude; float num = ShieldSpeedRegistry.EstimateNaturalSpeed(in ground); float num2 = ((num > 0.5f) ? Mathf.Clamp01(magnitude / num) : 0f); if (magnitude > 0.4f || num2 >= 0.2f) { _sledStartDuration = 0f; } else if (num2 >= 0.15f) { _sledStartDuration = 0.12f; } else { _sledStartDuration = Mathf.Lerp(0.5f, 0.18f, num2 * num2); } _sledStartGraceUntil = Time.time + _sledStartDuration; if (magnitude > 0.4f) { _entrySpeedFloor = magnitude; _entrySpeedFloorUntil = Time.time + 1.25f; } else { _entrySpeedFloor = 0f; _entrySpeedFloorUntil = 0f; } if ((Object)(object)player != (Object)null) { ((Character)player).m_running = false; ((Character)player).m_walk = false; ((Character)player).m_sliding = magnitude > 0.25f; SledGroundSolver.SyncCharacterMotionState((Character)(object)player, seedVelocity, grounded: true); } } internal void ApplySledStartMotion(Player player) { } internal void PrepareSledStart(Player player) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) PrepareSledStart(player, Vector3.zero, default(GroundSample), null); } internal void RestoreBody(Player player) { if (_bodyTuned) { RestoreColliderMaterials(); Rigidbody body = Utility.GetBody(player); if ((Object)(object)body != (Object)null) { body.useGravity = _savedUseGravity; body.isKinematic = _savedIsKinematic; body.linearDamping = _savedDrag; body.angularDamping = _savedAngularDrag; } _bodyTuned = false; _dynamicStartup = false; _preferDynamicBody = false; _entrySpeedFloor = 0f; _entrySpeedFloorUntil = 0f; } } private void FinalizeDynamicStartup(Player player, Rigidbody body) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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) if (!((Object)(object)player == (Object)null) && !((Object)(object)body == (Object)null) && !body.isKinematic && _dynamicStartup && !_preferDynamicBody) { _lastVelocity = body.linearVelocity; if (((Vector3)(ref _lastVelocity)).sqrMagnitude < 0.01f) { _lastVelocity = ((Character)player).m_currentVel; } body.isKinematic = true; body.position = ((Component)player).transform.position; _dynamicStartup = false; } } private void ApplyFrictionlessColliders(Player player) { _savedColliderMaterials.Clear(); if (!((Object)(object)player == (Object)null)) { CapsuleCollider collider = ((Character)player).m_collider; if ((Object)(object)collider != (Object)null) { _savedColliderMaterials.Add(((Collider)(object)collider, ((Collider)collider).sharedMaterial)); ((Collider)collider).sharedMaterial = _frictionlessMaterial; } } } private void RestoreColliderMaterials() { for (int i = 0; i < _savedColliderMaterials.Count; i++) { var (val, sharedMaterial) = _savedColliderMaterials[i]; if ((Object)(object)val != (Object)null) { val.sharedMaterial = sharedMaterial; } } _savedColliderMaterials.Clear(); } internal PhysicsResult Simulate(Player player, ItemData shield, Vector3 steerInput, bool brake, bool leanForward, float dt) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_067d: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_069e: Unknown result type (might be due to invalid IL or missing references) //IL_069f: Unknown result type (might be due to invalid IL or missing references) //IL_06a6: Unknown result type (might be due to invalid IL or missing references) //IL_06ad: Unknown result type (might be due to invalid IL or missing references) //IL_06b2: Unknown result type (might be due to invalid IL or missing references) //IL_06b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_06c6: Unknown result type (might be due to invalid IL or missing references) //IL_06c7: Unknown result type (might be due to invalid IL or missing references) //IL_06cc: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0773: Unknown result type (might be due to invalid IL or missing references) //IL_06e7: Unknown result type (might be due to invalid IL or missing references) //IL_06de: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_07ea: Unknown result type (might be due to invalid IL or missing references) //IL_0764: Unknown result type (might be due to invalid IL or missing references) //IL_076b: Unknown result type (might be due to invalid IL or missing references) //IL_0770: Unknown result type (might be due to invalid IL or missing references) //IL_0708: Unknown result type (might be due to invalid IL or missing references) //IL_0717: Unknown result type (might be due to invalid IL or missing references) //IL_0727: Unknown result type (might be due to invalid IL or missing references) //IL_072c: Unknown result type (might be due to invalid IL or missing references) //IL_0731: Unknown result type (might be due to invalid IL or missing references) //IL_0737: Unknown result type (might be due to invalid IL or missing references) //IL_073c: Unknown result type (might be due to invalid IL or missing references) //IL_0741: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_07ab: Unknown result type (might be due to invalid IL or missing references) //IL_07ad: Unknown result type (might be due to invalid IL or missing references) //IL_07b2: Unknown result type (might be due to invalid IL or missing references) //IL_07b7: Unknown result type (might be due to invalid IL or missing references) //IL_07bd: Unknown result type (might be due to invalid IL or missing references) //IL_07bf: Unknown result type (might be due to invalid IL or missing references) //IL_07c4: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0339: 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) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: 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_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_017e: 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_0194: 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_0824: Unknown result type (might be due to invalid IL or missing references) //IL_0825: Unknown result type (might be due to invalid IL or missing references) //IL_0835: Unknown result type (might be due to invalid IL or missing references) //IL_0836: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0440: 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_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0540: 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_054c: Unknown result type (might be due to invalid IL or missing references) //IL_0551: Unknown result type (might be due to invalid IL or missing references) //IL_0555: Unknown result type (might be due to invalid IL or missing references) //IL_055a: Unknown result type (might be due to invalid IL or missing references) //IL_055c: Unknown result type (might be due to invalid IL or missing references) //IL_055e: Unknown result type (might be due to invalid IL or missing references) //IL_056a: 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_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04f5: Unknown result type (might be due to invalid IL or missing references) //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_04ff: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03da: 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_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Unknown result type (might be due to invalid IL or missing references) //IL_04cd: Unknown result type (might be due to invalid IL or missing references) //IL_04d2: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_0649: Unknown result type (might be due to invalid IL or missing references) //IL_0643: 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_060f: Unknown result type (might be due to invalid IL or missing references) //IL_0616: Unknown result type (might be due to invalid IL or missing references) //IL_061b: Unknown result type (might be due to invalid IL or missing references) //IL_065e: 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_066b: Unknown result type (might be due to invalid IL or missing references) PhysicsResult result = default(PhysicsResult); Rigidbody body = Utility.GetBody(player); if ((Object)(object)body == (Object)null) { return result; } Vector3 velocity = (_bodyTuned ? _lastVelocity : body.linearVelocity); GroundSample ground; bool flag = Utility.TryGetSledGround(player, out ground); bool flag2 = (result.OnGround = flag && !IsAirborneForPhysics(player)); result.Velocity = velocity; result.Ground = ground; float steeringMultiplier = ShieldSpeedRegistry.GetSteeringMultiplier(shield); float slopePullStrength = GetSlopePullStrength(); float num = ConfigManager.FrictionMultiplier.Value; if (flag) { num *= Utility.GetBiomeFriction(ground.Biome); if (Utility.TryGetShieldSurfFriction(ground.Collider, out var friction)) { num *= friction; } } if (brake) { num *= 1f + ConfigManager.BrakeStrength.Value; } bool flag3 = Time.time < _sledStartGraceUntil; float startupBlend = StartupBlend; bool flag4 = _entrySpeedFloor > 0.12f && Time.time < _entrySpeedFloorUntil; Vector3 val5; if (flag2 && flag) { velocity = Vector3.ProjectOnPlane(velocity, ground.Normal); if (ground.IsWaterSurface) { velocity = Utility.Flatten(velocity); float magnitude = ((Vector3)(ref velocity)).magnitude; Vector3 val = ((magnitude > 0.01f) ? ((Vector3)(ref velocity)).normalized : Utility.Flatten(((Component)player).transform.forward)); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.forward; } if (leanForward && ((Vector3)(ref val)).sqrMagnitude > 0.0001f) { velocity += val * (ConfigManager.ForwardLeanBonus.Value * 0.35f * dt); magnitude = ((Vector3)(ref velocity)).magnitude; } if (((Vector3)(ref steerInput)).sqrMagnitude > 0.0001f) { float num2 = ConfigManager.SteeringStrength.Value * steeringMultiplier * 0.75f; num2 /= 1f + magnitude * ConfigManager.SteeringSpeedFalloff.Value; Vector3 val2 = Vector3.RotateTowards(val, Utility.Flatten(((Vector3)(ref steerInput)).normalized), num2 * dt, 0f); velocity = ((Vector3)(ref val2)).normalized * magnitude; val = ((Vector3)(ref val2)).normalized; } float num3 = ConfigManager.WaterSledFriction.Value * ConfigManager.OceanFriction.Value; if (!flag4 && (brake || num3 > 0f) && magnitude > 0.01f) { float num4 = num3 * (brake ? 2.5f : 1f) * magnitude * dt; float num5 = Mathf.Max(0f, magnitude - num4); velocity = val * num5; } if (flag4 && ((Vector3)(ref velocity)).magnitude + 0.02f < _entrySpeedFloor) { velocity = val * _entrySpeedFloor; } velocity.y = 0f; WaterSledHelper.MaintainWaterSurface(player, in ground, dt); } else { Vector3 slopeDown = ground.SlopeDown; float num6 = Mathf.Sin(ground.SlopeAngle * ((float)Math.PI / 180f)); Vector3 val3 = ((((Vector3)(ref velocity)).sqrMagnitude > 0.01f) ? ((Vector3)(ref velocity)).normalized : slopeDown); if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f && ((Vector3)(ref slopeDown)).sqrMagnitude > 0.0001f) { val3 = slopeDown; } float num7 = ((((Vector3)(ref velocity)).sqrMagnitude > 0.01f) ? Vector3.Dot(((Vector3)(ref velocity)).normalized, -slopeDown) : 0f); float magnitude2 = ((Vector3)(ref velocity)).magnitude; float num8 = ShieldSpeedRegistry.EstimateNaturalSpeed(in ground); if (flag3 && !flag4 && num6 > 0.01f && num7 < 0.4f && ((Vector3)(ref slopeDown)).sqrMagnitude > 0.0001f && magnitude2 < num8 * 0.88f) { float num9 = 1f - startupBlend; num9 = num9 * num9 * (3f - 2f * num9); float num10 = Mathf.Max(num8 * num9 * 0.92f, magnitude2); Vector3 val4 = ((Vector3)(ref slopeDown)).normalized * num10; float num11 = Mathf.Max(slopePullStrength * num6 * 2.5f, num8 * 1.8f); velocity = Vector3.MoveTowards(velocity, val4, num11 * dt); magnitude2 = ((Vector3)(ref velocity)).magnitude; val3 = ((magnitude2 > 0.01f) ? ((Vector3)(ref velocity)).normalized : slopeDown); } else if (num6 > 0.01f && num7 < 0.4f) { velocity += slopeDown * (slopePullStrength * num6 * dt); } else if (!flag4 && !flag3 && num7 > 0.15f) { velocity -= val3 * (ConfigManager.UphillPenalty.Value * slopePullStrength * dt); } else if (!flag4 && !flag3 && ground.SlopeAngle < ConfigManager.MinimumSlope.Value + 2f && num6 < 0.05f) { velocity -= val3 * (ConfigManager.FlatDeceleration.Value * 0.35f * dt); } if (leanForward && ((Vector3)(ref val3)).sqrMagnitude > 0.0001f) { velocity += val3 * (ConfigManager.ForwardLeanBonus.Value * dt); } if (((Vector3)(ref steerInput)).sqrMagnitude > 0.0001f) { float num12 = ConfigManager.SteeringStrength.Value * steeringMultiplier; float magnitude3 = ((Vector3)(ref velocity)).magnitude; num12 /= 1f + magnitude3 * ConfigManager.SteeringSpeedFalloff.Value; val5 = Vector3.ProjectOnPlane(((Vector3)(ref steerInput)).normalized, ground.Normal); Vector3 normalized = ((Vector3)(ref val5)).normalized; Vector3 val6 = Vector3.RotateTowards(val3, normalized, num12 * dt, 0f); float magnitude4 = ((Vector3)(ref velocity)).magnitude; velocity = val6 * magnitude4; } bool flag5 = num6 > 0.02f && num7 < 0.4f; float num13 = ((startupBlend > 0.001f) ? Mathf.Lerp(1f, 0.08f, startupBlend) : 1f); if (!flag4 && num > 0f && magnitude2 > 0.01f && (brake || !flag5 || startupBlend > 0.001f) && (!flag3 || brake || !flag5)) { float num14 = num * num13 * magnitude2 * dt; float num15 = Mathf.Max(0f, magnitude2 - num14); velocity = ((Vector3)(ref velocity)).normalized * num15; } if (flag4 && ((Vector3)(ref velocity)).magnitude + 0.02f < _entrySpeedFloor) { Vector3 val7 = ((((Vector3)(ref velocity)).sqrMagnitude > 0.01f) ? ((Vector3)(ref velocity)).normalized : val3); if (((Vector3)(ref val7)).sqrMagnitude > 0.0001f) { velocity = val7 * _entrySpeedFloor; } } ApplyGroundClearance(player, ground, ref velocity, dt); } } else { float num16 = Mathf.Abs(Physics.gravity.y); if (num16 < 0.01f) { num16 = 9.81f; } velocity += Vector3.down * num16 * dt; if (((Vector3)(ref steerInput)).sqrMagnitude > 0.0001f) { Vector3 val8 = Utility.Flatten(velocity); Vector3 val9 = ((((Vector3)(ref val8)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val8)).normalized : ((Vector3)(ref steerInput)).normalized); float num17 = ConfigManager.SteeringStrength.Value * ConfigManager.AirControl.Value * steeringMultiplier; Vector3 val10 = Vector3.RotateTowards(val9, ((Vector3)(ref steerInput)).normalized, num17 * dt, 0f); float magnitude5 = ((Vector3)(ref val8)).magnitude; velocity = val10 * magnitude5 + Vector3.up * velocity.y; } } float value = ConfigManager.MaximumSpeed.Value; if (value > 0f && ((Vector3)(ref velocity)).magnitude > value) { velocity = ((Vector3)(ref velocity)).normalized * value; } result.HorizontalSpeed = Utility.HorizontalSpeed(velocity); if (_wasAirborne && flag2 && flag && !ground.IsWaterSurface) { float num18 = Mathf.Max(0f, _lastVelocity.y); Vector3 v = velocity - _lastVelocity; val5 = Utility.Flatten(v); result.LandingImpact = num18 + ((Vector3)(ref val5)).magnitude * 0.25f; MaintainFeetClearance(player, body, ground); } ApplySimulatedMotion(player, body, velocity, dt, flag && ground.IsWaterSurface); if (flag2 && flag && !ground.IsWaterSurface && startupBlend < 0.25f) { MaintainFeetClearance(player, body, ground, startupBlend); } result.Velocity = velocity; ApplyStaminaDrain(player, flag2, dt); _lastVelocity = velocity; _wasAirborne = !flag2; return result; } private static void MaintainFeetClearance(Player player, Rigidbody body, GroundSample ground, float startupBlend = 0f) { //IL_0066: 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_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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)body == (Object)null) { return; } float num = Mathf.Clamp(ConfigManager.SledGroundClearance.Value, 0f, 0.6f); float feetHeightAboveGround = Utility.GetFeetHeightAboveGround(player, ground); if (!(feetHeightAboveGround <= num + 0.04f)) { float num2 = feetHeightAboveGround - num; if (startupBlend > 0.001f) { num2 *= Mathf.Lerp(1f, 0.35f, 1f - startupBlend); } Vector3 position = (body.position -= ground.Normal * num2); ((Component)player).transform.position = position; } } private void ApplySimulatedMotion(Player player, Rigidbody body, Vector3 velocity, float dt, bool waterSurface = false) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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) Vector3 val = velocity * dt; if (waterSurface) { val.y = 0f; } Vector3 val2 = body.position + val; body.MovePosition(val2); ((Component)player).transform.position = body.position; } private static float GetSlopePullStrength() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Abs(Physics.gravity.y); if (num < 0.01f) { num = 9.81f; } return num * ConfigManager.GravityMultiplier.Value * (ConfigManager.BaseAcceleration.Value / 9.81f); } private static void ApplyGroundClearance(Player player, GroundSample ground, ref Vector3 velocity, float dt) { //IL_0001: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //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) float num = Vector3.Dot(velocity, -ground.Normal); if (num > 0f) { velocity += ground.Normal * num; } } private static void ApplyStaminaDrain(Player player, bool onGround, float dt) { if (ConfigManager.StaminaMode.Value != SledStaminaMode.Constant) { return; } float num = ConfigManager.StaminaPerSecond.Value * dt; if (!(num <= 0f)) { if (player.GetStamina() < num) { ShieldSledController.Instance?.EndSledding(player, SledEndReason.Manual); } else { ((Character)player).UseStamina(num); } } } } public enum SledStaminaMode { None, Constant, ActivationOnly, JumpBurst } public enum SledState { Idle, Armed, Sledding } [BepInPlugin("ModdedWolf.ShieldSledding", "Shield Sledding", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string GUID = "ModdedWolf.ShieldSledding"; internal const string LegacyGuid = "dev.modded.shieldsledding"; public const string NAME = "Shield Sledding"; public const string VERSION = "1.0.0"; internal static Plugin Instance; internal static ManualLogSource Log; private GameObject _manager; private Harmony _harmony; private void Awake() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; MigrateLegacyConfigFile(); ConfigManager.Init(((BaseUnityPlugin)this).Config); ShieldSpeedRegistry.Init(); _harmony = new Harmony("ModdedWolf.ShieldSledding"); SledPatches.Apply(_harmony); _harmony.PatchAll(typeof(Plugin).Assembly); _manager = new GameObject("ShieldSledding_Manager"); _manager.AddComponent(); Object.DontDestroyOnLoad((Object)(object)_manager); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Shield Sledding v1.0.0 loaded."); } private static void MigrateLegacyConfigFile() { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "dev.modded.shieldsledding.cfg"); string text2 = Path.Combine(configPath, "ModdedWolf.ShieldSledding.cfg"); if (!File.Exists(text)) { return; } if (!File.Exists(text2)) { File.Copy(text, text2); ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"Shield Sledding: migrated config from dev.modded.shieldsledding.cfg to ModdedWolf.ShieldSledding.cfg"); } } else { ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)"Shield Sledding: ignoring obsolete dev.modded.shieldsledding.cfg (ModdedWolf.ShieldSledding.cfg already exists)."); } } try { File.Delete(text); ManualLogSource log3 = Log; if (log3 != null) { log3.LogInfo((object)"Shield Sledding: removed obsolete dev.modded.shieldsledding.cfg"); } } catch (IOException ex) { ManualLogSource log4 = Log; if (log4 != null) { log4.LogWarning((object)("Shield Sledding: could not remove legacy config: " + ex.Message)); } } } private void OnDestroy() { if ((Object)(object)_manager != (Object)null) { Object.Destroy((Object)(object)_manager); _manager = null; } Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; } } internal sealed class ShieldSledController { private float _jumpIntentUntil; private float _armedUntil; private float _lastArmPressTime; private float _lastActivationFailLogTime; private float _exitInputBlockedUntil; private float _activationBlockedUntil; private bool _wasOnGround = true; private bool _exitRequested; private bool _activationStaminaPaid; private bool _sessionCleaned; private Vector3 _armedMomentumSnapshot; private float _armedPeakHorizontal; private float _armedAirPeakHorizontal; private float _jumpCarryHorizontal; private bool _armedLeftGround; private float _armedLandGraceUntil; private readonly PhysicsController _physics = new PhysicsController(); private readonly DurabilityController _durability = new DurabilityController(); private readonly CollisionController _collision = new CollisionController(); private readonly EffectController _effects = new EffectController(); private readonly AudioController _audio = new AudioController(); private readonly MultiplayerSync _sync = new MultiplayerSync(); private readonly StatsTracker _stats = new StatsTracker(); internal static ShieldSledController Instance { get; private set; } internal SledState State { get; private set; } internal bool IsSledding => State == SledState.Sledding; internal bool IsArmed => State == SledState.Armed; internal bool IsShieldSledActive { get { if (!IsSledding) { return IsArmed; } return true; } } internal float CurrentSpeed { get; private set; } internal Vector3 SimulatedVelocity => _physics.SimulatedVelocity; internal ItemData LockedShield { get; private set; } internal bool IsInStartupGrace => _physics.IsInStartupGrace; internal float StartupBlend => _physics.StartupBlend; internal Vector3 MoveInput { get; private set; } internal bool BrakeInput { get; private set; } internal bool LeanForwardInput { get; private set; } internal bool IsAirborneForSledJump(Player player) { return _physics.IsAirborneForPhysics(player); } internal void SetSimulatedVelocity(Player player, Vector3 velocity) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) _physics.SetSimulatedVelocity(player, velocity); } internal ShieldSledController() { Instance = this; } internal void NotifyJump() { _jumpIntentUntil = Time.time + ConfigManager.ActivationWindow.Value; } internal void NotifyJumpIntentFromInput() { _jumpIntentUntil = Mathf.Max(_jumpIntentUntil, Time.time + ConfigManager.ActivationWindow.Value); } internal void NotifyLeftGround() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && Time.time <= _jumpIntentUntil + 0.25f) { float num = SampleBestHorizontalSpeed(localPlayer); if (num > _jumpCarryHorizontal) { _jumpCarryHorizontal = num; } } if (IsArmed) { _armedLeftGround = true; _armedLandGraceUntil = Time.time + 0.35f; } if (Time.time <= _jumpIntentUntil + 0.15f) { _jumpIntentUntil = Time.time + ConfigManager.ActivationWindow.Value; } } internal void Update() { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { _sessionCleaned = false; ResetLocalState(); return; } if (!_sessionCleaned) { ShieldSledVisual.DestroyAllOrphans(); _effects.CleanupOrphans(); _sessionCleaned = true; } if (((Character)localPlayer).IsDead()) { if (IsSledding || IsArmed) { EndSledding(localPlayer, SledEndReason.Death); } } else { if (!ConfigManager.EnableShieldSledding.Value) { return; } if (Utility.WasJumpPressed()) { if (IsSledding) { TryPerformSledJump(localPlayer); } else { NotifyJumpIntentFromInput(); } } ReadInput(localPlayer); HandleExitInput(localPlayer); UpdateArmedState(localPlayer); CheckEnvironmentalExits(localPlayer); ValidateHandShield(localPlayer); if (IsArmed || IsSledding) { ShieldSledVisual.Update(localPlayer, active: true, IsSledding); } if (IsSledding) { _stats.Update(localPlayer, CurrentSpeed); _effects.Update(localPlayer, CurrentSpeed, MoveInput.x); _audio.Update(localPlayer, CurrentSpeed); _sync.WriteLocalState(localPlayer, active: true, CurrentSpeed); } else { _effects.Update(localPlayer, 0f, 0f); _audio.Update(localPlayer, 0f); _sync.WriteLocalState(localPlayer, active: false, 0f); _sync.UpdateRemotePlayers(); } } } internal void ApplySledPhysics(Player player, float dt) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || !IsSledding) { return; } dt = Mathf.Clamp(dt, 0.001f, 0.05f); ItemData val = LockedShield ?? Utility.GetHandShield(player); if (val == null || val.m_durability <= 0f) { EndSledding(player, SledEndReason.ShieldBroken); return; } PhysicsResult result = _physics.Simulate(player, val, MoveInput, BrakeInput, LeanForwardInput, dt); CurrentSpeed = result.HorizontalSpeed; _durability.Tick(player, val, result); _collision.Tick(player, val, result); _sync.WriteLocalState(player, active: true, CurrentSpeed); bool flag = ((Character)player).IsOnGround(); if (!_wasOnGround && flag) { _durability.OnLanding(player, val, result.LandingImpact); _collision.OnLanding(player, result.LandingImpact); _effects.OnLanding(player, result.LandingImpact); _audio.OnLanding(player, result.LandingImpact); _stats.OnLanding(player, result.LandingImpact); } _wasOnGround = flag; } internal bool TryOverrideControls(Player player, ref Vector3 moveDir, ref bool block, ref bool jump, ref bool run) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if (IsSledding) { block = false; if (jump) { TryPerformSledJump(player); jump = false; } moveDir = Vector3.zero; run = false; return true; } if (IsArmed && Utility.IsAirborne(player)) { block = false; jump = false; Vector3 val = ((Character)player).GetVelocity(); Rigidbody body = Utility.GetBody(player); if ((Object)(object)body != (Object)null && !body.isKinematic && Utility.HorizontalSpeed(body.linearVelocity) > Utility.HorizontalSpeed(val)) { val = body.linearVelocity; } if (Utility.HorizontalSpeed(((Character)player).m_currentVel) > Utility.HorizontalSpeed(val)) { val = ((Character)player).m_currentVel; } Vector3 val2 = Utility.Flatten(val); if (((Vector3)(ref val2)).sqrMagnitude > 0.35f) { moveDir = ((Vector3)(ref val2)).normalized; run = true; } return true; } _ = IsArmed; return false; } private void ReadInput(Player player) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_004f: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) MoveInput = Vector3.zero; BrakeInput = false; LeanForwardInput = false; if (!Utility.IsUiBlockingInput()) { if (ZInput.GetKey((KeyCode)97, true) || ZInput.GetKey((KeyCode)276, true)) { MoveInput += -((Component)player).transform.right; } if (ZInput.GetKey((KeyCode)100, true) || ZInput.GetKey((KeyCode)275, true)) { MoveInput += ((Component)player).transform.right; } if (ZInput.GetKey((KeyCode)119, true) || ZInput.GetKey((KeyCode)273, true)) { LeanForwardInput = true; } if (ZInput.GetKey((KeyCode)115, true) || ZInput.GetKey((KeyCode)274, true)) { BrakeInput = true; } Vector3 moveInput = MoveInput; if (((Vector3)(ref moveInput)).sqrMagnitude > 1f) { moveInput = MoveInput; ((Vector3)(ref moveInput)).Normalize(); } } } private void UpdateArmedState(Player player) { bool flag = ((Character)player).IsOnGround() || ((Character)player).m_groundContact; if (_wasOnGround && !flag) { NotifyLeftGround(); } else if (IsArmed && flag && !_wasOnGround) { _armedLandGraceUntil = Mathf.Max(_armedLandGraceUntil, Time.time + 0.3f); } if (IsArmed && !IsSledding) { UpdateArmedMomentum(player); if (Time.time > _armedUntil) { State = SledState.Idle; _armedLeftGround = false; _armedLandGraceUntil = 0f; _jumpCarryHorizontal = 0f; ShieldSledVisual.Hide(player); Plugin.Log.LogInfo((object)"Shield sled arm expired before sledding started."); } } else if (!IsSledding && !IsArmed) { TryArm(player); } _wasOnGround = flag; } internal void TrackArmedMomentum(Player player) { if (!((Object)(object)player == (Object)null) && IsArmed && !IsSledding) { UpdateArmedMomentum(player); } } internal bool TryActivateOnLanding(Player player) { if ((Object)(object)player == (Object)null || !IsArmed || IsSledding) { return false; } if (!_armedLeftGround) { return false; } if (!((Character)player).IsOnGround() && !((Character)player).m_groundContact) { return false; } if (!Utility.TryProbeGroundBelow(player, 2.5f, out var sample)) { return false; } float feetHeightAboveGround = Utility.GetFeetHeightAboveGround(player, sample); bool num = !_wasOnGround; bool flag = Time.time <= _armedLandGraceUntil; if (!num && !flag) { return false; } CaptureLandingMomentum(player); if (!TryActivateSled(player, fromArmed: true, in sample, feetHeightAboveGround)) { return false; } _armedLeftGround = false; _armedLandGraceUntil = 0f; return true; } private void CaptureLandingMomentum(Player player) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //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_003b: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) UpdateArmedMomentum(player); if (!Utility.TryProbeGroundBelow(player, 2f, out var sample) || ((Vector3)(ref sample.Normal)).sqrMagnitude < 0.01f) { return; } Vector3 armedMomentumSnapshot = Vector3.ProjectOnPlane(((Character)player).m_currentVel, sample.Normal); if (((Vector3)(ref armedMomentumSnapshot)).sqrMagnitude > ((Vector3)(ref _armedMomentumSnapshot)).sqrMagnitude) { _armedMomentumSnapshot = armedMomentumSnapshot; } Rigidbody body = Utility.GetBody(player); if ((Object)(object)body != (Object)null && !body.isKinematic) { Vector3 armedMomentumSnapshot2 = Vector3.ProjectOnPlane(body.linearVelocity, sample.Normal); if (((Vector3)(ref armedMomentumSnapshot2)).sqrMagnitude > ((Vector3)(ref _armedMomentumSnapshot)).sqrMagnitude) { _armedMomentumSnapshot = armedMomentumSnapshot2; } } PromoteSnapshotToPeakHorizontal(player, in sample); } private void PromoteSnapshotToPeakHorizontal(Player player, in GroundSample ground) { //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_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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_0092: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00d0: 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) float num = Mathf.Max(new float[3] { _armedPeakHorizontal, _armedAirPeakHorizontal, _jumpCarryHorizontal }); if (num <= ((Vector3)(ref _armedMomentumSnapshot)).magnitude + 0.05f) { return; } Vector3 v = _armedMomentumSnapshot; if (((Vector3)(ref v)).sqrMagnitude < 0.01f) { v = ((Character)player).m_currentVel; } if (((Vector3)(ref v)).sqrMagnitude < 0.01f) { v = ((Character)player).GetVelocity(); } Vector3 val = Utility.Flatten(v); if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Utility.Flatten(((Component)player).transform.forward); } if (!(((Vector3)(ref val)).sqrMagnitude < 0.01f)) { Vector3 armedMomentumSnapshot = Vector3.ProjectOnPlane(((Vector3)(ref val)).normalized * num, ground.Normal); if (((Vector3)(ref armedMomentumSnapshot)).sqrMagnitude > ((Vector3)(ref _armedMomentumSnapshot)).sqrMagnitude) { _armedMomentumSnapshot = armedMomentumSnapshot; } } } internal void UpdateArmedMomentumFixed(Player player) { if (!((Object)(object)player == (Object)null) && IsArmed && !IsSledding) { UpdateArmedMomentum(player); } } private void UpdateArmedMomentum(Player player) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Character)player).GetVelocity(); Rigidbody body = Utility.GetBody(player); if ((Object)(object)body != (Object)null && !body.isKinematic) { Vector3 linearVelocity = body.linearVelocity; if (((Vector3)(ref linearVelocity)).sqrMagnitude > ((Vector3)(ref val)).sqrMagnitude) { val = body.linearVelocity; } } if (((Vector3)(ref ((Character)player).m_currentVel)).sqrMagnitude > ((Vector3)(ref val)).sqrMagnitude) { val = ((Character)player).m_currentVel; } GroundSample sample; Vector3 armedMomentumSnapshot = ((!Utility.TryProbeGroundBelow(player, 2f, out sample) || !(((Vector3)(ref sample.Normal)).sqrMagnitude > 0.01f)) ? Utility.Flatten(val) : Vector3.ProjectOnPlane(val, sample.Normal)); if (((Vector3)(ref armedMomentumSnapshot)).sqrMagnitude > ((Vector3)(ref _armedMomentumSnapshot)).sqrMagnitude) { _armedMomentumSnapshot = armedMomentumSnapshot; } float num = Utility.HorizontalSpeed(val); if (num > _armedPeakHorizontal) { _armedPeakHorizontal = num; } if (Utility.IsAirborne(player) && num > _armedAirPeakHorizontal) { _armedAirPeakHorizontal = num; } } private static float SampleBestHorizontalSpeed(Player player) { //IL_0010: 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_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return 0f; } float num = Utility.HorizontalSpeed(((Character)player).GetVelocity()); Rigidbody body = Utility.GetBody(player); if ((Object)(object)body != (Object)null && !body.isKinematic) { num = Mathf.Max(num, Utility.HorizontalSpeed(body.linearVelocity)); } return Mathf.Max(num, Utility.HorizontalSpeed(((Character)player).m_currentVel)); } internal void TryArm(Player player) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || IsSledding || IsArmed || Time.time < _activationBlockedUntil || Utility.IsUiBlockingInput() || !Utility.WasActivationPressed() || Time.time - _lastArmPressTime < 0.15f) { return; } _lastArmPressTime = Time.time; ItemData handShield = Utility.GetHandShield(player); if (handShield != null && !(handShield.m_durability <= 0f) && (WithinJumpWindow() || Utility.IsAirborne(player))) { State = SledState.Armed; _armedUntil = Time.time + ConfigManager.ArmedWindow.Value; _armedMomentumSnapshot = Vector3.zero; _armedLeftGround = Utility.IsAirborne(player); UpdateArmedMomentum(player); float armedAirPeakHorizontal = (_armedPeakHorizontal = Mathf.Max(new float[4] { SampleBestHorizontalSpeed(player), _jumpCarryHorizontal, _armedPeakHorizontal, _armedAirPeakHorizontal })); if (Utility.IsAirborne(player)) { _armedAirPeakHorizontal = armedAirPeakHorizontal; } ShieldSledVisual.Show(player, handShield); Plugin.Log.LogInfo((object)("Shield sled armed with " + Utility.GetShieldPrefabName(handShield) + ".")); } } private bool TryActivateSled(Player player, bool fromArmed, in GroundSample ground, float feetGap = 0f) { if ((Object)(object)player == (Object)null || IsSledding) { return false; } if (Time.time < _activationBlockedUntil) { return false; } if (!((Character)player).IsOnGround() && !((Character)player).m_groundContact && !Utility.IsSledGrounded(player)) { return false; } GroundSample sample = ground; if (((Vector3)(ref sample.Normal)).sqrMagnitude < 0.01f && !Utility.TrySampleGround(player, out sample)) { LogActivationFailureThrottled("no ground under player"); return false; } if (!CanActivateOnGround(player, sample, fromArmed)) { LogActivationFailureThrottled($"ground too steep uphill or not ready (slope {sample.SlopeAngle:F1}°)"); return false; } ItemData handShield = Utility.GetHandShield(player); if (handShield == null || handShield.m_durability <= 0f) { LogActivationFailureThrottled("shield missing or broken"); return false; } BeginSledding(player, handShield, fromArmed, in sample); return true; } private bool TryActivateSled(Player player, bool fromArmed) { Utility.TryProbeGroundBelow(player, 2.5f, out var sample); float feetGap = ((((Vector3)(ref sample.Normal)).sqrMagnitude > 0.01f) ? Utility.GetFeetHeightAboveGround(player, sample) : 0f); return TryActivateSled(player, fromArmed, in sample, feetGap); } private bool CanActivateOnGround(Player player, GroundSample ground, bool fromArmed) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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) Vector3 velocity = ((Character)player).GetVelocity(); if (fromArmed && ((Vector3)(ref _armedMomentumSnapshot)).sqrMagnitude > 0.04f) { velocity = _armedMomentumSnapshot; } float value = ConfigManager.MinimumSlope.Value; if (ground.SlopeAngle >= value) { return true; } if (Utility.IsSlopeValidForSledding(ground, velocity)) { return true; } return Utility.HorizontalSpeed(velocity) >= 1.5f; } private void LogActivationFailureThrottled(string reason) { if (!(Time.time - _lastActivationFailLogTime < 1f)) { _lastActivationFailLogTime = Time.time; Plugin.Log.LogInfo((object)("Shield sled not ready: " + reason + ".")); } } private void BeginSledding(Player player, ItemData shield, bool fromArmedLanding, in GroundSample activationGroundIn) { //IL_00b8: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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) if (!PayActivationStamina(player)) { State = SledState.Idle; ShieldSledVisual.Hide(player); return; } GroundSample sample = activationGroundIn; if (((Vector3)(ref sample.Normal)).sqrMagnitude < 0.01f) { Utility.TrySampleGround(player, out sample); } State = SledState.Sledding; LockedShield = shield; _armedUntil = 0f; _exitInputBlockedUntil = Time.time + 0.5f; _wasOnGround = ((Character)player).IsOnGround() || ((Character)player).m_groundContact; float num = Mathf.Max(new float[3] { _armedAirPeakHorizontal, _armedPeakHorizontal, _jumpCarryHorizontal }); Vector3 seedVelocity = (fromArmedLanding ? _physics.ResolveLandingSeed(player, in sample, shield, _armedMomentumSnapshot, num, armedLanding: true) : Vector3.zero); _armedMomentumSnapshot = Vector3.zero; _armedPeakHorizontal = 0f; _armedAirPeakHorizontal = 0f; _jumpCarryHorizontal = 0f; _armedLeftGround = false; _armedLandGraceUntil = 0f; _physics.ConfigureBodyForSled(player, seedVelocity); _physics.PrepareSledStart(player, seedVelocity, in sample, shield); SledGroundSolver.SnapToGroundOnSledStart(player, ((Vector3)(ref seedVelocity)).magnitude); ShieldSledVisual.EnsureReadyForSledding(player, shield); _durability.Begin(player); _collision.Begin(player); _effects.Begin(player); _audio.Begin(player); _stats.Begin(player); GhostReplaySystem.BeginSession(); TimeTrialManager.BeginSession(); CurrentSpeed = Utility.HorizontalSpeed(_physics.SimulatedVelocity); float num2 = ShieldSpeedRegistry.EstimateNaturalSpeed(in sample); Plugin.Log.LogInfo((object)($"Shield sledding activated on {Utility.GetShieldPrefabName(shield)} at {CurrentSpeed:F1} m/s " + $"(carry {num:F1} m/s, slope {sample.SlopeAngle:F0}°, coast ~{num2:F1} m/s).")); } private bool PayActivationStamina(Player player) { if (_activationStaminaPaid) { return true; } if (ConfigManager.StaminaMode.Value != SledStaminaMode.ActivationOnly && ConfigManager.StaminaMode.Value != SledStaminaMode.Constant && ConfigManager.StaminaMode.Value != SledStaminaMode.JumpBurst) { _activationStaminaPaid = true; return true; } float value = ConfigManager.StaminaActivationCost.Value; if (value <= 0f) { _activationStaminaPaid = true; return true; } if (player.GetStamina() < value) { return false; } ((Character)player).UseStamina(value); _activationStaminaPaid = true; return true; } private void HandleExitInput(Player player) { if (!Utility.IsUiBlockingInput()) { if (IsSledding && Time.time >= _exitInputBlockedUntil && Utility.WasActivationPressed()) { EndSledding(player, SledEndReason.Manual); } if (IsSledding && ZInput.GetKeyDown((KeyCode)27, true)) { EndSledding(player, SledEndReason.Manual); _exitRequested = true; } } } private void CheckEnvironmentalExits(Player player) { if (!IsSledding) { return; } if (WaterSledHelper.IsOverWater(player)) { if (!WaterSledHelper.CanWaterSled(CurrentSpeed)) { WaterSledHelper.ResetSurfaceSmoothing(); EndSledding(player, SledEndReason.Water); } } else if (Utility.IsInDeepWater(player)) { EndSledding(player, SledEndReason.Water); } } private void ValidateHandShield(Player player) { if (!IsShieldSledActive || (Object)(object)player == (Object)null) { return; } if (IsSledding) { ItemData handShield = Utility.GetHandShield(player); if (handShield != LockedShield || handShield == null || handShield.m_durability <= 0f) { EndSledding(player, SledEndReason.ShieldBroken); Plugin.Log.LogInfo((object)"Shield sledding ended: shield changed or removed."); } } else if (!Utility.HasUsableShield(player)) { State = SledState.Idle; _armedUntil = 0f; ShieldSledVisual.Hide(player); Plugin.Log.LogInfo((object)"Shield sled arm cancelled: shield not in hand."); } } internal bool TryPerformSledJump(Player player) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || !IsSledding || !_physics.TryJump(player)) { return false; } NotifyJump(); NotifyLeftGround(); if (ConfigManager.StaminaMode.Value == SledStaminaMode.JumpBurst) { float value = ConfigManager.StaminaJumpCost.Value; if (value > 0f && player.GetStamina() >= value) { ((Character)player).UseStamina(value); } } _stats.OnJump(player); ApplySledPhysics(player, Time.fixedDeltaTime); SledGroundSolver.SyncCharacterMotionState((Character)(object)player, SimulatedVelocity, grounded: false); return true; } internal void EndSledding(Player player, SledEndReason reason) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) if (!IsSledding && !IsArmed) { return; } bool isSledding = IsSledding; bool isArmed = IsArmed; if (isSledding && (reason == SledEndReason.Manual || reason == SledEndReason.CombatHit)) { _activationBlockedUntil = Time.time + 0.6f; } State = SledState.Idle; LockedShield = null; _activationStaminaPaid = false; _armedUntil = 0f; _exitInputBlockedUntil = 0f; CurrentSpeed = 0f; _armedMomentumSnapshot = Vector3.zero; _armedPeakHorizontal = 0f; _armedAirPeakHorizontal = 0f; _jumpCarryHorizontal = 0f; _armedLeftGround = false; _armedLandGraceUntil = 0f; Rigidbody body = Utility.GetBody(player); Vector3 simulatedVelocity = _physics.SimulatedVelocity; if ((Object)(object)body != (Object)null) { _physics.RestoreBody(player); if (isSledding) { Vector3 val = simulatedVelocity; Vector3 val2 = Utility.Flatten(val); val = (body.linearVelocity = ((reason != SledEndReason.Manual) ? (val2 * 0.5f + Vector3.up * val.y) : (val2 * 0.2f + Vector3.up * Mathf.Min(val.y, 0.5f)))); ((Character)player).m_sliding = false; SledGroundSolver.SyncCharacterMotionState((Character)(object)player, val, ((Character)player).IsOnGround()); } } if (isSledding || isArmed) { ShieldSledVisual.Hide(player); } if (isSledding) { if (reason == SledEndReason.ShieldBroken && ConfigManager.StumbleOnShieldBreak.Value) { ((Character)player).Stagger(Vector3.zero); if ((Object)(object)body != (Object)null) { body.linearVelocity = Vector3.zero; } } _stats.End(player); _effects.End(player); _audio.End(player); GhostReplaySystem.EndSession(); TimeTrialManager.EndSession(); Plugin.Log.LogInfo((object)$"Shield sledding ended: {reason}."); } _sync.WriteLocalState(player, active: false, 0f); } private bool WithinJumpWindow() { return Time.time <= _jumpIntentUntil; } private void ResetLocalState() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) State = SledState.Idle; CurrentSpeed = 0f; _activationStaminaPaid = false; _armedUntil = 0f; _armedMomentumSnapshot = Vector3.zero; _armedPeakHorizontal = 0f; _armedAirPeakHorizontal = 0f; _jumpCarryHorizontal = 0f; _armedLeftGround = false; _armedLandGraceUntil = 0f; ShieldSledVisual.Hide(null); } internal bool ConsumeExitRequest() { if (!_exitRequested) { return false; } _exitRequested = false; return true; } internal void ReportCollisionWear(Player player, ItemData shield, float impact) { _durability.OnCollision(player, shield, impact); } internal void ReportDamageAsShieldWear(Player player, ItemData shield, float damage) { _durability.OnDamage(player, shield, damage); } } internal enum SledEndReason { Manual, Water, Death, ShieldBroken, CombatHit } [DefaultExecutionOrder(32000)] internal sealed class ShieldSledManager : MonoBehaviour { private ShieldSledController _controller; internal static ShieldSledManager Instance { get; private set; } private void Awake() { Instance = this; _controller = new ShieldSledController(); ((Component)this).gameObject.AddComponent(); } private void Update() { if (ConfigManager.EnableShieldSledding.Value && !Utility.IsDedicatedServer()) { _controller.Update(); } } private void LateUpdate() { if (ConfigManager.EnableShieldSledding.Value && !Utility.IsDedicatedServer()) { Player localPlayer = Player.m_localPlayer; ShieldSledController instance = ShieldSledController.Instance; if (!((Object)(object)localPlayer == (Object)null) && instance != null && (instance.IsArmed || instance.IsSledding)) { ShieldSledVisual.LateUpdate(localPlayer); } } } private void FixedUpdate() { if (!ConfigManager.EnableShieldSledding.Value || Utility.IsDedicatedServer()) { return; } Player localPlayer = Player.m_localPlayer; ShieldSledController instance = ShieldSledController.Instance; if (!((Object)(object)localPlayer == (Object)null) && instance != null) { GroundSample ground; if (instance.IsArmed && !instance.IsSledding) { instance.UpdateArmedMomentumFixed(localPlayer); } else if (instance.IsSledding && !instance.IsInStartupGrace && Utility.TryGetSledGround(localPlayer, out ground) && Utility.GetFeetHeightAboveGround(localPlayer, ground) < -0.04f) { SledGroundSolver.FixGroundClip(localPlayer); } } } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } internal static class ShieldSledVisual { private struct ShieldTransformBackup { internal Transform Parent; internal Vector3 LocalPosition; internal Quaternion LocalRotation; internal Vector3 LocalScale; } private struct TransformBackup { internal Transform Transform; internal Vector3 LocalPosition; internal Quaternion LocalRotation; internal Vector3 LocalScale; } private struct ColliderBackup { internal Collider Collider; internal bool Enabled; } private struct RigidbodyBackup { internal Rigidbody Body; internal bool DetectCollisions; } private const string FeetAttachName = "ShieldSledding_FeetAttach"; private const string LocalParticlesName = "ShieldSledding_LocalParticles"; private static Transform _feetAttach; private static Transform _shieldTransform; private static ShieldTransformBackup _shieldBackup; private static Player _ownerPlayer; private static bool _backupValid; private static bool _visualUpdateInProgress; private static Transform _physicsStrippedFor; private static readonly List _colliderBackups = new List(); private static readonly List _rigidbodyBackups = new List(); private static readonly List _hierarchyBackups = new List(); internal static void DestroyAllOrphans() { GameObject[] array = Object.FindObjectsByType((FindObjectsSortMode)0); foreach (GameObject val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.GetComponent() != (Object)null)) { string name = ((Object)val).name; if (name == "ShieldSledding_FeetAttach" || name == "ShieldSledding_LocalParticles") { Object.Destroy((Object)(object)val); } else if (name.StartsWith("ShieldSledding_")) { Object.Destroy((Object)(object)val); } } } _feetAttach = null; _shieldTransform = null; _ownerPlayer = null; _backupValid = false; RestoreShieldPhysics(); _hierarchyBackups.Clear(); } internal static void EnsureReadyForSledding(Player player, ItemData shield) { if (!((Object)(object)player == (Object)null) && shield != null && !Utility.IsDedicatedServer()) { if ((Object)(object)_ownerPlayer == (Object)(object)player && (Object)(object)_feetAttach != (Object)null && (Object)(object)_shieldTransform != (Object)null) { RefreshFeetShieldTransform(player); } else { Show(player, shield); } } } internal static void Show(Player player, ItemData shield) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && shield != null && !Utility.IsDedicatedServer()) { if ((Object)(object)_ownerPlayer != (Object)null && (Object)(object)_ownerPlayer != (Object)(object)player) { Hide(_ownerPlayer); } Hide(player); Transform equippedShieldTransform = GetEquippedShieldTransform(player); if ((Object)(object)equippedShieldTransform == (Object)null) { Plugin.Log.LogWarning((object)("Shield Sledding: no equipped shield mesh for " + Utility.GetShieldPrefabName(shield) + ".")); return; } _ownerPlayer = player; _backupValid = true; _shieldBackup = CaptureTransform(equippedShieldTransform); _shieldTransform = equippedShieldTransform; CaptureHierarchyBackup(equippedShieldTransform); _feetAttach = new GameObject("ShieldSledding_FeetAttach").transform; _feetAttach.SetParent(((Component)player).transform, false); RefreshFeetShieldTransform(player); ReparentShieldToFeet(); Plugin.Log.LogInfo((object)("Shield Sledding: moved " + ((Object)equippedShieldTransform).name + " visual to feet.")); } } internal static Transform GetFeetAttach(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)_feetAttach == (Object)null || (Object)(object)_ownerPlayer != (Object)(object)player) { return null; } return _feetAttach; } internal static void Hide(Player player) { Player player2 = _ownerPlayer ?? player; RestoreShieldTransform(); RefreshEquipmentVisuals(player2); if ((Object)(object)_feetAttach != (Object)null) { Object.Destroy((Object)(object)((Component)_feetAttach).gameObject); _feetAttach = null; } if ((Object)(object)player == (Object)null || (Object)(object)player == (Object)(object)_ownerPlayer) { _ownerPlayer = null; } } internal static void OnPlayerDestroyed(Player player) { if (!((Object)(object)player == (Object)null)) { if ((Object)(object)player == (Object)(object)_ownerPlayer) { _feetAttach = null; _shieldTransform = null; _ownerPlayer = null; _backupValid = false; RestoreShieldPhysics(); _hierarchyBackups.Clear(); } else { Hide(player); } } } internal static void Update(Player player, bool active, bool sledding) { if (active && !((Object)(object)player == (Object)null) && !((Object)(object)_feetAttach == (Object)null) && !((Object)(object)player != (Object)(object)_ownerPlayer)) { RunVisualUpdate(player); } } internal static void LateUpdate(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)_feetAttach == (Object)null) && !((Object)(object)player != (Object)(object)_ownerPlayer)) { RunVisualUpdate(player); } } private static void RunVisualUpdate(Player player) { if (_visualUpdateInProgress) { return; } _visualUpdateInProgress = true; try { if (RefreshShieldReference(player)) { RefreshFeetShieldTransform(player); EnsureShieldOnFeet(); ApplyFeetShieldPose(); } } finally { _visualUpdateInProgress = false; } } private static bool RefreshShieldReference(Player player) { ShieldSledController instance = ShieldSledController.Instance; if (instance != null && instance.IsSledding) { return (Object)(object)_shieldTransform != (Object)null; } Transform equippedShieldTransform = GetEquippedShieldTransform(player); if ((Object)(object)equippedShieldTransform == (Object)null) { return false; } if ((Object)(object)equippedShieldTransform != (Object)(object)_shieldTransform) { RestoreShieldPhysics(); _shieldTransform = equippedShieldTransform; } return (Object)(object)_shieldTransform != (Object)null; } private static void ReparentShieldToFeet() { if (!((Object)(object)_shieldTransform == (Object)null) && !((Object)(object)_feetAttach == (Object)null)) { _shieldTransform.SetParent(_feetAttach, true); DisableShieldPhysics(_shieldTransform); ApplyFeetShieldPose(); } } private static void EnsureShieldOnFeet() { if (!((Object)(object)_shieldTransform == (Object)null) && !((Object)(object)_feetAttach == (Object)null) && (Object)(object)_shieldTransform.parent != (Object)(object)_feetAttach) { _shieldTransform.SetParent(_feetAttach, true); DisableShieldPhysics(_shieldTransform); } } private static void ApplyFeetShieldPose() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_003e: 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_0067: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_shieldTransform == (Object)null) && !((Object)(object)_feetAttach == (Object)null)) { Vector3 localScale = (_backupValid ? _shieldBackup.LocalScale : _shieldTransform.localScale); _shieldTransform.localScale = localScale; _shieldTransform.localPosition = Vector3.zero; _shieldTransform.localRotation = Quaternion.Euler(90f, 0f, 0f); ResetAttachChildOffsets(_shieldTransform); } } private static void ResetAttachChildOffsets(Transform root) { //IL_002d: 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) if ((Object)(object)root == (Object)null) { return; } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)root)) { val.localPosition = Vector3.zero; val.localRotation = Quaternion.identity; } } } private static void DisableShieldPhysics(Transform root) { if ((Object)(object)root == (Object)null || (Object)(object)root == (Object)(object)_physicsStrippedFor) { return; } RestoreShieldPhysics(); Collider[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { _colliderBackups.Add(new ColliderBackup { Collider = val, Enabled = val.enabled }); val.enabled = false; } } Rigidbody[] componentsInChildren2 = ((Component)root).GetComponentsInChildren(true); foreach (Rigidbody val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null)) { _rigidbodyBackups.Add(new RigidbodyBackup { Body = val2, DetectCollisions = val2.detectCollisions }); val2.detectCollisions = false; } } _physicsStrippedFor = root; } private static void RestoreShieldPhysics() { for (int i = 0; i < _colliderBackups.Count; i++) { ColliderBackup colliderBackup = _colliderBackups[i]; if ((Object)(object)colliderBackup.Collider != (Object)null) { colliderBackup.Collider.enabled = colliderBackup.Enabled; } } for (int j = 0; j < _rigidbodyBackups.Count; j++) { RigidbodyBackup rigidbodyBackup = _rigidbodyBackups[j]; if ((Object)(object)rigidbodyBackup.Body != (Object)null) { rigidbodyBackup.Body.detectCollisions = rigidbodyBackup.DetectCollisions; } } _colliderBackups.Clear(); _rigidbodyBackups.Clear(); _physicsStrippedFor = null; } private static void RestoreShieldTransform() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) RestoreShieldPhysics(); if ((Object)(object)_shieldTransform == (Object)null) { _hierarchyBackups.Clear(); return; } if (_backupValid && (Object)(object)_shieldBackup.Parent != (Object)null) { RestoreHierarchyBackup(); _shieldTransform.SetParent(_shieldBackup.Parent, false); _shieldTransform.localPosition = _shieldBackup.LocalPosition; _shieldTransform.localRotation = _shieldBackup.LocalRotation; _shieldTransform.localScale = _shieldBackup.LocalScale; } _shieldTransform = null; _backupValid = false; _hierarchyBackups.Clear(); } private static void CaptureHierarchyBackup(Transform root) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) _hierarchyBackups.Clear(); if ((Object)(object)root == (Object)null) { return; } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)root)) { _hierarchyBackups.Add(new TransformBackup { Transform = val, LocalPosition = val.localPosition, LocalRotation = val.localRotation, LocalScale = val.localScale }); } } } private static void RestoreHierarchyBackup() { //IL_0025: 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_0047: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _hierarchyBackups.Count; i++) { TransformBackup transformBackup = _hierarchyBackups[i]; if (!((Object)(object)transformBackup.Transform == (Object)null)) { transformBackup.Transform.localPosition = transformBackup.LocalPosition; transformBackup.Transform.localRotation = transformBackup.LocalRotation; transformBackup.Transform.localScale = transformBackup.LocalScale; } } } private static void RefreshEquipmentVisuals(Player player) { if (!((Object)(object)player == (Object)null)) { VisEquipment visEquipment = ((Humanoid)player).m_visEquipment; if (!((Object)(object)visEquipment == (Object)null)) { visEquipment.UpdateEquipmentVisuals(); } } } private static ShieldTransformBackup CaptureTransform(Transform transform) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //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) return new ShieldTransformBackup { Parent = transform.parent, LocalPosition = transform.localPosition, LocalRotation = transform.localRotation, LocalScale = transform.localScale }; } private static void RefreshFeetShieldTransform(Player player) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_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_004a: 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_0065: 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_0076: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_feetAttach == (Object)null) { return; } float rootToFeetOffset = Utility.GetRootToFeetOffset(player); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, 0f - rootToFeetOffset + 0.02f, 0.15f); _feetAttach.localPosition = val; Vector3 val2 = Utility.Flatten(((Component)player).transform.forward); Vector3 val3 = Vector3.up; if (Utility.TryProbeGroundBelow(player, 1.5f, out var sample)) { val2 = Vector3.ProjectOnPlane(((Component)player).transform.forward, sample.Normal); if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = ((((Vector3)(ref sample.Downhill)).sqrMagnitude > 0.0001f) ? sample.Downhill : ((Component)player).transform.forward); } ((Vector3)(ref val2)).Normalize(); val3 = sample.Normal; } else { if (!(((Vector3)(ref val2)).sqrMagnitude > 0.0001f)) { _feetAttach.localRotation = Quaternion.identity; return; } ((Vector3)(ref val2)).Normalize(); } Vector3 position = ((Component)player).transform.TransformPoint(val); _feetAttach.position = position; _feetAttach.rotation = Quaternion.LookRotation(val2, val3); } private static Transform GetEquippedShieldTransform(Player player) { GameObject equippedShieldObject = GetEquippedShieldObject(player); if (!((Object)(object)equippedShieldObject != (Object)null)) { return null; } return equippedShieldObject.transform; } private static GameObject GetEquippedShieldObject(Player player) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Invalid comparison between Unknown and I4 VisEquipment visEquipment = ((Humanoid)player).m_visEquipment; if ((Object)(object)visEquipment == (Object)null) { return null; } if (((Humanoid)player).m_leftItem != null) { SharedData shared = ((Humanoid)player).m_leftItem.m_shared; if (shared != null && (int)shared.m_itemType == 5 && (Object)(object)visEquipment.m_leftItemInstance != (Object)null) { return visEquipment.m_leftItemInstance; } } if (((Humanoid)player).m_rightItem != null) { SharedData shared2 = ((Humanoid)player).m_rightItem.m_shared; if (shared2 != null && (int)shared2.m_itemType == 5 && (Object)(object)visEquipment.m_rightItemInstance != (Object)null) { return visEquipment.m_rightItemInstance; } } if (!((Object)(object)visEquipment.m_leftItemInstance != (Object)null)) { return visEquipment.m_rightItemInstance; } return visEquipment.m_leftItemInstance; } } internal static class ShieldSpeedRegistry { internal static readonly string[] VanillaShieldPrefabs = new string[17] { "ShieldWood", "ShieldWoodTower", "ShieldBoneTower", "ShieldKnight", "ShieldBronzeBuckler", "ShieldBanded", "ShieldIronBuckler", "ShieldIronSquare", "ShieldIronTower", "ShieldSerpentscale", "ShieldSilver", "ShieldBlackmetal", "ShieldBlackmetalTower", "ShieldCarapace", "ShieldCarapaceBuckler", "ShieldFlametal", "ShieldFlametalTower" }; private static readonly Dictionary WearByPrefab = new Dictionary(); private static readonly Dictionary TokenToPrefab = new Dictionary(); private static bool _initialized; internal static void Init() { if (!_initialized) { _initialized = true; Rebuild(); } } internal static void Rebuild() { WearByPrefab.Clear(); for (int i = 0; i < VanillaShieldPrefabs.Length; i++) { string text = VanillaShieldPrefabs[i]; WearByPrefab[text] = ShieldWearConfig.GetWear(text); } ShieldWearConfig.ApplyCustomWear(WearByPrefab); BuildTokenCache(); Plugin.Log.LogInfo((object)$"Shield Sledding: registered {VanillaShieldPrefabs.Length} vanilla shields (uniform speed, tier wear)."); } internal static string ResolveShieldPrefab(ItemData shield) { if (shield?.m_shared == null) { return string.Empty; } if ((Object)(object)shield.m_dropPrefab != (Object)null) { return ((Object)shield.m_dropPrefab).name; } string name = shield.m_shared.m_name; if (!string.IsNullOrEmpty(name) && TokenToPrefab.TryGetValue(name, out var value)) { return value; } if ((Object)(object)ObjectDB.instance != (Object)null && !string.IsNullOrEmpty(name)) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(name); if ((Object)(object)itemPrefab != (Object)null) { return ((Object)itemPrefab).name; } } return string.Empty; } internal static float EstimateNaturalSpeed(in GroundSample ground) { //IL_0031: 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_003a: Unknown result type (might be due to invalid IL or missing references) if (ground.SlopeAngle < 0.5f) { return 0f; } float num = Mathf.Sin(ground.SlopeAngle * ((float)Math.PI / 180f)); float num2 = ConfigManager.FrictionMultiplier.Value; if ((int)ground.Biome != 0) { num2 *= Utility.GetBiomeFriction(ground.Biome); } num2 = Mathf.Max(0.05f, num2); return Mathf.Abs(Physics.gravity.y) * ConfigManager.GravityMultiplier.Value * (ConfigManager.BaseAcceleration.Value / 9.81f) * num / num2; } internal static float GetMaxSpeed(Player player, ItemData shield) { Player val = player ?? Player.m_localPlayer; if ((Object)(object)val != (Object)null && Utility.TrySampleGround(val, out var sample)) { return EstimateNaturalSpeed(in sample); } if (!(ConfigManager.MaximumSpeed.Value > 0f)) { return 12f; } return ConfigManager.MaximumSpeed.Value; } internal static float GetWearMultiplier(ItemData shield) { string text = ResolveShieldPrefab(shield); if (string.IsNullOrEmpty(text)) { Plugin.Log.LogWarning((object)"Shield Sledding: could not resolve shield prefab for wear lookup — using DefaultModdedWear."); return ShieldWearConfig.DefaultModdedWear?.Value ?? 1f; } if (WearByPrefab.TryGetValue(text, out var value)) { return value; } return ShieldWearConfig.DefaultModdedWear?.Value ?? 1f; } internal static float GetSpeedMultiplier(Player player, ItemData shield) { return 1f; } internal static float GetBlockSkillMultiplier(Player player, ItemData shield) { if ((Object)(object)player == (Object)null) { return 1f; } float skillFactor = ((Character)player).GetSkillFactor((SkillType)6); return Mathf.Lerp(ConfigManager.MinBlockSkillSpeedScale?.Value ?? 0.8f, 1f, skillFactor); } internal static float GetSteeringMultiplier(ItemData shield) { if (shield?.m_shared == null) { return 1f; } string text = ResolveShieldPrefab(shield); if (!string.IsNullOrEmpty(text) && text.IndexOf("Tower", StringComparison.OrdinalIgnoreCase) >= 0) { return 0.85f; } string name = shield.m_shared.m_name; if (!string.IsNullOrEmpty(name) && name.IndexOf("tower", StringComparison.OrdinalIgnoreCase) >= 0) { return 0.85f; } return 1f; } internal static float GetEffectiveBlockPower(Player player, ItemData shield) { if (shield == null || (Object)(object)player == (Object)null) { return 0f; } return shield.GetBlockPower(((Character)player).GetSkillFactor((SkillType)6)); } internal static void RegisterUnknownShields() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Invalid comparison between Unknown and I4 if ((Object)(object)ObjectDB.instance == (Object)null) { return; } List items = ObjectDB.instance.m_items; if (items == null || items.Count == 0) { return; } int num = 0; int num2 = 0; float value = ShieldWearConfig.DefaultModdedWear?.Value ?? 1f; for (int i = 0; i < items.Count; i++) { GameObject val = items[i]; if ((Object)(object)val == (Object)null) { continue; } ItemDrop component = val.GetComponent(); if (component?.m_itemData?.m_shared != null && (int)component.m_itemData.m_shared.m_itemType == 5) { num++; string name = ((Object)val).name; if (!WearByPrefab.ContainsKey(name)) { WearByPrefab[name] = value; num2++; Plugin.Log.LogInfo((object)("Shield Sledding: auto-registered modded shield '" + name + "' at default wear.")); } } } BuildTokenCache(); Plugin.Log.LogInfo((object)$"Shield Sledding: ObjectDB has {num} shields ({num2} modded auto-registered)."); } private static void BuildTokenCache() { TokenToPrefab.Clear(); if ((Object)(object)ObjectDB.instance == (Object)null) { return; } for (int i = 0; i < VanillaShieldPrefabs.Length; i++) { string text = VanillaShieldPrefabs[i]; TokenToPrefab[text] = text; GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text); if (!((Object)(object)itemPrefab == (Object)null)) { string text2 = itemPrefab.GetComponent()?.m_itemData?.m_shared?.m_name; if (!string.IsNullOrEmpty(text2)) { TokenToPrefab[text2] = text; } } } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] internal static class ObjectDbShieldRegistryPatch { private static void Postfix() { ShieldSpeedRegistry.Rebuild(); ShieldSpeedRegistry.RegisterUnknownShields(); } } internal static class ShieldWearConfig { private static readonly Dictionary> Entries = new Dictionary>(); internal static ConfigEntry DefaultModdedWear; internal static ConfigEntry CustomModdedWear; internal static void Init(ConfigFile config) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown Entries.Clear(); for (int i = 0; i < ShieldSpeedRegistry.VanillaShieldPrefabs.Length; i++) { string text = ShieldSpeedRegistry.VanillaShieldPrefabs[i]; float defaultWear = GetDefaultWear(text); Entries[text] = config.Bind("ShieldWear", text, defaultWear, new ConfigDescription("Durability wear vs Banded (1.0). Higher = wears faster while sledding. Speed is the same for all shields.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 5f), Array.Empty())); } DefaultModdedWear = config.Bind("ShieldWear", "DefaultModdedWear", 1f, new ConfigDescription("Wear multiplier for modded shields not listed above.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 5f), Array.Empty())); CustomModdedWear = config.Bind("ShieldWear", "CustomModdedWear", string.Empty, "Extra modded shields as PrefabName:Wear pairs. Example: MyShield:1.2,OtherShield:0.8"); } internal static float GetWear(string prefabName) { if (!string.IsNullOrEmpty(prefabName) && Entries.TryGetValue(prefabName, out var value)) { return value.Value; } if (DefaultModdedWear == null) { return 1f; } return DefaultModdedWear.Value; } internal static void ApplyCustomWear(Dictionary target) { Utility.ParseCustomShieldSpeeds(CustomModdedWear?.Value ?? string.Empty, target); } internal static void MigrateLegacyWearDefaults(ConfigFile config) { for (int i = 0; i < ShieldSpeedRegistry.VanillaShieldPrefabs.Length; i++) { string text = ShieldSpeedRegistry.VanillaShieldPrefabs[i]; float defaultWear = GetDefaultWear(text); float legacyDefaultWear = GetLegacyDefaultWear(text); ConfigEntry val = config.Bind("ShieldWear", text, defaultWear, (ConfigDescription)null); if (Mathf.Approximately(val.Value, legacyDefaultWear)) { val.Value = defaultWear; } } } private static float GetLegacyDefaultWear(string prefab) { return prefab switch { "ShieldWood" => 2.25f, "ShieldWoodTower" => 2.4f, "ShieldBoneTower" => 1.85f, "ShieldKnight" => 1.55f, "ShieldBronzeBuckler" => 1.55f, "ShieldBanded" => 1f, "ShieldIronBuckler" => 0.85f, "ShieldIronSquare" => 0.9f, "ShieldIronTower" => 0.95f, "ShieldSerpentscale" => 0.75f, "ShieldSilver" => 0.7f, "ShieldBlackmetal" => 0.6f, "ShieldBlackmetalTower" => 0.65f, "ShieldCarapace" => 0.5f, "ShieldCarapaceBuckler" => 0.45f, "ShieldFlametal" => 0.4f, "ShieldFlametalTower" => 0.45f, _ => 1f, }; } private static float GetDefaultWear(string prefab) { return prefab switch { "ShieldWood" => 3f, "ShieldWoodTower" => 3.2f, "ShieldBoneTower" => 2.25f, "ShieldKnight" => 1.85f, "ShieldBronzeBuckler" => 1.75f, "ShieldBanded" => 1f, "ShieldIronBuckler" => 0.8f, "ShieldIronSquare" => 0.85f, "ShieldIronTower" => 0.9f, "ShieldSerpentscale" => 0.7f, "ShieldSilver" => 0.65f, "ShieldBlackmetal" => 0.55f, "ShieldBlackmetalTower" => 0.58f, "ShieldCarapace" => 0.45f, "ShieldCarapaceBuckler" => 0.4f, "ShieldFlametal" => 0.35f, "ShieldFlametalTower" => 0.38f, _ => 1f, }; } } internal static class SledGroundSolver { internal static void SeparateFromGround(Player player) { FixGroundClip(player); } internal static bool FixGroundClip(Player player) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00ae: 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_00ce: 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) if ((Object)(object)player == (Object)null || !Utility.TryGetSledGround(player, out var ground)) { return false; } if (ground.IsWaterSurface) { return false; } float feetHeightAboveGround = Utility.GetFeetHeightAboveGround(player, ground); if (feetHeightAboveGround < -0.04f) { float num = Mathf.Min(0.06f, 0f - feetHeightAboveGround); ShieldSledController instance = ShieldSledController.Instance; if (instance != null && instance.StartupBlend > 0.001f) { num *= Mathf.Lerp(0.45f, 1f, 1f - instance.StartupBlend); } Rigidbody body = Utility.GetBody(player); Vector3 val = (((Object)(object)body != (Object)null) ? body.position : ((Component)player).transform.position); val += ground.Normal * num; if ((Object)(object)body != (Object)null) { body.position = val; } ((Component)player).transform.position = val; } return true; } internal static void SnapToGroundOnSledStart(Player player, float seedSpeed = 0f) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_011b: 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_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_016c: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: 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_00dd: 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_0140: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (!Utility.TrySampleGround(player, out var sample) && !Utility.TryProbeGroundBelow(player, 2f, out sample))) { return; } ((Character)player).m_lastGroundPoint = sample.Point; ((Character)player).m_lastGroundNormal = sample.Normal; ((Character)player).m_lastGroundCollider = sample.Collider; ((Character)player).m_groundContact = true; if (seedSpeed > 1.25f) { Vector3 velocity = ((ShieldSledController.Instance != null) ? ShieldSledController.Instance.SimulatedVelocity : Vector3.zero); SyncCharacterMotionState((Character)(object)player, velocity, grounded: true); return; } float targetFeetClearance = GetTargetFeetClearance(); float feetHeightAboveGround = Utility.GetFeetHeightAboveGround(player, sample); Rigidbody body = Utility.GetBody(player); if (Mathf.Abs(feetHeightAboveGround - targetFeetClearance) > 0.08f) { Vector3 rootPositionForFeetOnGround = Utility.GetRootPositionForFeetOnGround(player, sample, targetFeetClearance); Vector3 position = Vector3.Lerp(((Object)(object)body != (Object)null) ? body.position : ((Component)player).transform.position, rootPositionForFeetOnGround, 0.55f); if ((Object)(object)body != (Object)null) { body.position = position; } ((Component)player).transform.position = position; } else if (Mathf.Abs(feetHeightAboveGround - targetFeetClearance) > 0.025f) { Vector3 rootPositionForFeetOnGround2 = Utility.GetRootPositionForFeetOnGround(player, sample, targetFeetClearance); Vector3 position2 = Vector3.Lerp(((Object)(object)body != (Object)null) ? body.position : ((Component)player).transform.position, rootPositionForFeetOnGround2, 0.35f); if ((Object)(object)body != (Object)null) { body.position = position2; } ((Component)player).transform.position = position2; } Vector3 velocity2 = ((ShieldSledController.Instance != null) ? ShieldSledController.Instance.SimulatedVelocity : Vector3.zero); SyncCharacterMotionState((Character)(object)player, velocity2, grounded: true); } private static float GetTargetFeetClearance() { return Mathf.Clamp(ConfigManager.SledGroundClearance.Value, 0f, 0.6f); } internal static void SyncCharacterMotionState(Character character, Vector3 velocity, bool grounded) { //IL_0024: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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)character == (Object)null)) { Vector3 val = ((((Vector3)(ref character.m_lastGroundNormal)).sqrMagnitude > 0.01f) ? character.m_lastGroundNormal : Vector3.up); Vector3 currentVel = Vector3.ProjectOnPlane(velocity, val); bool flag = ShieldSledController.Instance?.IsSledding ?? false; character.m_currentVel = currentVel; character.m_running = false; character.m_walk = false; character.m_sliding = ((!flag) ? (grounded && ((Vector3)(ref currentVel)).magnitude > 0.5f) : (grounded && ((Vector3)(ref currentVel)).magnitude > 0.25f)); if (flag && grounded) { character.m_groundContact = true; } } } } internal sealed class SpeedometerHud : MonoBehaviour { private GUIStyle _style; private void OnGUI() { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!ConfigManager.EnableSpeedometer.Value) { return; } ShieldSledController instance = ShieldSledController.Instance; if (instance != null && instance.IsSledding) { if (_style == null) { _style = new GUIStyle(GUI.skin.label) { fontSize = 18, fontStyle = (FontStyle)1, alignment = (TextAnchor)8 }; _style.normal.textColor = Color.white; } float currentSpeed = instance.CurrentSpeed; string text = $"{currentSpeed:F1} m/s"; GUI.Label(new Rect((float)Screen.width - 180f, (float)Screen.height - 80f, 160f, 60f), text, _style); } } } internal sealed class StatsTracker { private Vector3 _lastPos; private bool _trackingAir; internal void Begin(Player player) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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) _lastPos = (((Object)(object)player != (Object)null) ? ((Component)player).transform.position : Vector3.zero); _trackingAir = false; } internal void Update(Player player, float speed) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } _lastPos = ((Component)player).transform.position; if (!((Character)player).IsOnGround()) { if (!_trackingAir) { _trackingAir = true; } } else if (_trackingAir) { _trackingAir = false; } GhostReplaySystem.RecordFrame(player); } internal void OnJump(Player player) { if (!((Object)(object)player == (Object)null)) { _trackingAir = true; } } internal void OnLanding(Player player, float impact) { if (!((Object)(object)player == (Object)null) && _trackingAir) { _trackingAir = false; } } internal void End(Player player) { } } internal static class Utility { internal const int GroundLayerMask = 224495617; private static int _resolvedGroundMask; internal const float SledGroundContactMax = 0.38f; internal const float SledJumpFeetMax = 0.34f; internal const float SledAirborneSeparation = 0.45f; internal const float FeetBelowRoot = 0.92f; internal static int GetGroundLayerMask() { if (_resolvedGroundMask != 0) { return _resolvedGroundMask; } _resolvedGroundMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "blocker" }); if (_resolvedGroundMask == 0) { _resolvedGroundMask = 224495617; } return _resolvedGroundMask; } internal static bool IsSeparatingFromGround(Vector3 velocity, in GroundSample ground, float threshold = 0.45f) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0021: 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) Vector3 normal = ground.Normal; if (((Vector3)(ref normal)).sqrMagnitude < 0.01f) { return velocity.y > threshold; } return Vector3.Dot(velocity, ground.Normal) > threshold; } internal static bool IsSledGrounded(Player player) { if ((Object)(object)player == (Object)null) { return false; } ShieldSledController instance = ShieldSledController.Instance; GroundSample sample; if (instance != null && instance.IsSledding) { return TryGetSledGround(player, out sample); } if (!((Character)player).IsOnGround()) { return false; } if (GetVerticalSpeed(player) > 0.5f) { return false; } return TrySampleGround(player, out sample); } internal static float GetVerticalSpeed(Player player) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return 0f; } ShieldSledController instance = ShieldSledController.Instance; if (instance != null && instance.IsSledding) { return instance.SimulatedVelocity.y; } Rigidbody body = GetBody(player); if ((Object)(object)body != (Object)null) { return body.linearVelocity.y; } return ((Character)player).GetVelocity().y; } internal static bool IsDedicatedServer() { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.IsDedicated(); } return false; } internal static bool IsLocalPlayer(Player player) { if ((Object)(object)player != (Object)null) { return (Object)(object)player == (Object)(object)Player.m_localPlayer; } return false; } internal static Rigidbody GetBody(Player player) { if ((Object)(object)player == (Object)null) { return null; } return ((Character)player).m_body; } internal static Rigidbody GetBody(Character character) { if ((Object)(object)character == (Object)null) { return null; } return character.m_body; } internal static ZDO GetPlayerZdo(Player player) { if ((Object)(object)player == (Object)null) { return null; } ZNetView component = ((Component)player).GetComponent(); if (!((Object)(object)component != (Object)null) || !component.IsValid()) { return null; } return component.GetZDO(); } internal static string GetCharacterPrefabToken(Character character) { if ((Object)(object)character == (Object)null) { return string.Empty; } ZNetView component = ((Component)character).GetComponent(); if ((Object)(object)component != (Object)null && component.IsValid()) { ZDO zDO = component.GetZDO(); if (zDO != null && (Object)(object)ZNetScene.instance != (Object)null) { GameObject prefab = ZNetScene.instance.GetPrefab(zDO.GetPrefab()); if ((Object)(object)prefab != (Object)null) { return ((Object)prefab).name; } } } return ((Object)((Component)character).gameObject).name.Replace("(Clone)", string.Empty).Trim(); } internal static ItemData GetHandShield(Player player) { if ((Object)(object)player == (Object)null) { return null; } if (IsShieldItem(((Humanoid)player).m_leftItem)) { return ((Humanoid)player).m_leftItem; } if (IsShieldItem(((Humanoid)player).m_rightItem)) { return ((Humanoid)player).m_rightItem; } return null; } internal static ItemData GetEquippedShield(Player player) { return GetHandShield(player); } private static bool IsShieldItem(ItemData item) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if (item?.m_shared != null) { return (int)item.m_shared.m_itemType == 5; } return false; } internal static bool HasUsableShield(Player player) { ItemData handShield = GetHandShield(player); if (handShield != null) { return handShield.m_durability > 0f; } return false; } internal static string GetShieldPrefabName(ItemData shield) { return ShieldSpeedRegistry.ResolveShieldPrefab(shield); } internal static bool IsAirborne(Player player) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } if (!((Character)player).IsOnGround()) { return true; } ShieldSledController instance = ShieldSledController.Instance; GroundSample ground; if (instance != null && instance.IsSledding) { return !TryGetSledGround(player, out ground); } Rigidbody body = GetBody(player); if ((Object)(object)body != (Object)null) { return body.linearVelocity.y > 0.75f; } return false; } internal static Vector3 GetFeetPosition(Player player) { //IL_0009: 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_005c: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0045: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return Vector3.zero; } CapsuleCollider collider = ((Character)player).m_collider; if ((Object)(object)collider != (Object)null) { Vector3 position = ((Component)player).transform.position; Bounds bounds = ((Collider)collider).bounds; position.y = ((Bounds)(ref bounds)).min.y; return position; } return ((Component)player).transform.position - Vector3.up * 0.92f; } internal static float GetRootToFeetOffset(Player player) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return 0.92f; } CapsuleCollider collider = ((Character)player).m_collider; if ((Object)(object)collider != (Object)null) { float y = ((Component)player).transform.position.y; Bounds bounds = ((Collider)collider).bounds; return y - ((Bounds)(ref bounds)).min.y; } return 0.92f; } internal static Vector3 GetRootPositionForFeetOnGround(Player player, GroundSample ground, float feetClearance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0041: 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) Vector3 val = (((Object)(object)player != (Object)null) ? ((Component)player).transform.position : ground.Point); Vector3 val2 = GetFeetPosition(player) - val; return ground.Point + ground.Normal * feetClearance - val2; } internal static float GetFeetHeightAboveGround(Player player, GroundSample ground) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (ground.IsWaterSurface) { return GetFeetPosition(player).y - ground.WaterSurfaceY; } return Vector3.Dot(GetFeetPosition(player) - ground.Point, ground.Normal); } internal static bool IsPhysicallyGrounded(Player player) { return IsSledGrounded(player); } internal static bool WasActivationPressed() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = ConfigManager.ActivationKey.Value; if (!((KeyboardShortcut)(ref value)).IsPressed() && !ZInput.GetKeyDown((KeyCode)103, true)) { return Input.GetKeyDown((KeyCode)103); } return true; } internal static bool WasJumpPressed() { if (!ZInput.GetButtonDown("Jump") && !Input.GetKeyDown((KeyCode)32)) { return ZInput.GetKeyDown((KeyCode)32, true); } return true; } internal static bool IsInDeepWater(Player player) { if ((Object)(object)player == (Object)null) { return false; } if (((Character)player).InWater()) { return ((Character)player).IsSwimming(); } return false; } internal static bool IsUiBlockingInput() { if ((Object)(object)Console.instance != (Object)null && Console.IsVisible()) { return true; } if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) { return true; } if (TextInput.IsVisible()) { return true; } if (Menu.IsVisible()) { return true; } if (InventoryGui.IsVisible()) { return true; } return false; } internal static void ShowHint(string message) { } internal static bool IsSlopeValidForSledding(GroundSample ground, Vector3 velocity) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) float value = ConfigManager.MinimumSlope.Value; if (ground.SlopeAngle >= value) { return true; } if (ground.SlopeAngle >= value * 0.5f && HorizontalSpeed(velocity) >= 2f) { return true; } return false; } internal static float HorizontalSpeed(Vector3 velocity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Vector3 val = new Vector3(velocity.x, 0f, velocity.z); return ((Vector3)(ref val)).magnitude; } internal static Vector3 Flatten(Vector3 v) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) v.y = 0f; return v; } internal static bool TryProbeGroundBelow(Player player, float maxDistance, out GroundSample sample) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_00ec: 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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) sample = default(GroundSample); if ((Object)(object)player == (Object)null) { return false; } Vector3 val = GetFeetPosition(player) + Vector3.up * 0.5f; float num = 0.5f + Mathf.Max(0.1f, maxDistance); int groundLayerMask = GetGroundLayerMask(); RaycastHit val2 = default(RaycastHit); if (!Physics.Raycast(val, Vector3.down, ref val2, num, groundLayerMask) && !Physics.SphereCast(val, 0.18f, Vector3.down, ref val2, num, groundLayerMask)) { return false; } sample.Point = ((RaycastHit)(ref val2)).point; sample.Normal = ((RaycastHit)(ref val2)).normal; sample.Collider = ((RaycastHit)(ref val2)).collider; sample.SlopeAngle = Vector3.Angle(((RaycastHit)(ref val2)).normal, Vector3.up); sample.SlopeDown = Vector3.ProjectOnPlane(Vector3.down, ((RaycastHit)(ref val2)).normal); if (((Vector3)(ref sample.SlopeDown)).sqrMagnitude > 0.0001f) { ((Vector3)(ref sample.SlopeDown)).Normalize(); } sample.Downhill = Flatten(sample.SlopeDown); if (((Vector3)(ref sample.Downhill)).sqrMagnitude > 0.0001f) { ((Vector3)(ref sample.Downhill)).Normalize(); } sample.Biome = ResolveBiome(((RaycastHit)(ref val2)).point); return true; } internal static bool TryGetSledGround(Player player, out GroundSample ground, float contactThreshold = 0.38f) { //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) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_00a4: Unknown result type (might be due to invalid IL or missing references) ground = default(GroundSample); if ((Object)(object)player == (Object)null) { return false; } Rigidbody body = GetBody(player); ShieldSledController instance = ShieldSledController.Instance; Vector3 velocity = Vector3.zero; float speed = 0f; if (instance != null && instance.IsSledding) { velocity = instance.SimulatedVelocity; speed = instance.CurrentSpeed; } else if ((Object)(object)body != (Object)null) { velocity = body.linearVelocity; speed = HorizontalSpeed(velocity); } if (instance != null && instance.IsSledding && WaterSledHelper.TryGetWaterSledGround(player, speed, out ground)) { return true; } if (TryProbeGroundBelow(player, 1.5f, out ground) && GetFeetHeightAboveGround(player, ground) <= contactThreshold && (instance == null || !instance.IsSledding || instance.IsInStartupGrace || !IsSeparatingFromGround(velocity, in ground))) { return true; } return false; } internal static bool TrySampleGround(Player player, out GroundSample sample) { //IL_00e1: 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_00f0: 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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0192: 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_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_013d: 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_0039: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_007d: 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_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) sample = default(GroundSample); if ((Object)(object)player == (Object)null) { return false; } if (((Character)player).IsOnGround() && ((Vector3)(ref ((Character)player).m_lastGroundNormal)).sqrMagnitude > 0.01f) { sample.Point = ((Character)player).m_lastGroundPoint; sample.Normal = ((Character)player).m_lastGroundNormal; sample.Collider = ((Character)player).m_lastGroundCollider; sample.SlopeAngle = Vector3.Angle(sample.Normal, Vector3.up); sample.SlopeDown = Vector3.ProjectOnPlane(Vector3.down, sample.Normal); if (((Vector3)(ref sample.SlopeDown)).sqrMagnitude > 0.0001f) { ((Vector3)(ref sample.SlopeDown)).Normalize(); } sample.Downhill = Flatten(sample.SlopeDown); if (((Vector3)(ref sample.Downhill)).sqrMagnitude > 0.0001f) { ((Vector3)(ref sample.Downhill)).Normalize(); } sample.Biome = ResolveBiome(sample.Point); return true; } Vector3 val = GetFeetPosition(player) + Vector3.up * 0.35f; int groundLayerMask = GetGroundLayerMask(); RaycastHit val2 = default(RaycastHit); if (!Physics.SphereCast(val, 0.28f, Vector3.down, ref val2, 2.5f, groundLayerMask) && !Physics.SphereCast(((Component)player).transform.position + Vector3.up * 0.5f, 0.28f, Vector3.down, ref val2, 3.5f, groundLayerMask)) { return false; } sample.Point = ((RaycastHit)(ref val2)).point; sample.Normal = ((RaycastHit)(ref val2)).normal; sample.Collider = ((RaycastHit)(ref val2)).collider; sample.SlopeAngle = Vector3.Angle(((RaycastHit)(ref val2)).normal, Vector3.up); sample.SlopeDown = Vector3.ProjectOnPlane(Vector3.down, ((RaycastHit)(ref val2)).normal); if (((Vector3)(ref sample.SlopeDown)).sqrMagnitude > 0.0001f) { ((Vector3)(ref sample.SlopeDown)).Normalize(); } sample.Downhill = Flatten(sample.SlopeDown); if (((Vector3)(ref sample.Downhill)).sqrMagnitude > 0.0001f) { ((Vector3)(ref sample.Downhill)).Normalize(); } sample.Biome = ResolveBiome(((RaycastHit)(ref val2)).point); return true; } internal static bool TryRaycastGround(Player player, out GroundSample sample) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0088: 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_0095: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_0128: 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) sample = default(GroundSample); if ((Object)(object)player == (Object)null) { return false; } Vector3 val = GetFeetPosition(player) + Vector3.up * 0.35f; int groundLayerMask = GetGroundLayerMask(); RaycastHit val2 = default(RaycastHit); if (!Physics.SphereCast(val, 0.28f, Vector3.down, ref val2, 3f, groundLayerMask) && !Physics.SphereCast(((Component)player).transform.position + Vector3.up * 0.5f, 0.28f, Vector3.down, ref val2, 4f, groundLayerMask)) { return false; } sample.Point = ((RaycastHit)(ref val2)).point; sample.Normal = ((RaycastHit)(ref val2)).normal; sample.Collider = ((RaycastHit)(ref val2)).collider; sample.SlopeAngle = Vector3.Angle(((RaycastHit)(ref val2)).normal, Vector3.up); sample.SlopeDown = Vector3.ProjectOnPlane(Vector3.down, ((RaycastHit)(ref val2)).normal); if (((Vector3)(ref sample.SlopeDown)).sqrMagnitude > 0.0001f) { ((Vector3)(ref sample.SlopeDown)).Normalize(); } sample.Downhill = Flatten(sample.SlopeDown); if (((Vector3)(ref sample.Downhill)).sqrMagnitude > 0.0001f) { ((Vector3)(ref sample.Downhill)).Normalize(); } sample.Biome = ResolveBiome(((RaycastHit)(ref val2)).point); return true; } internal static Biome ResolveBiome(Vector3 worldPos) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (WorldGenerator.instance == null) { return (Biome)1; } return WorldGenerator.instance.GetBiome(worldPos.x, worldPos.z, 0.02f, false); } internal static float GetBiomeFriction(Biome biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0005: 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_001d: Expected I4, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 if ((int)biome <= 16) { switch (biome - 1) { default: if ((int)biome != 8) { if ((int)biome != 16) { break; } return ConfigManager.GrassFriction.Value; } return ConfigManager.BlackForestFriction.Value; case 0: return ConfigManager.MeadowsFriction.Value; case 1: return ConfigManager.SwampFriction.Value; case 3: return ConfigManager.MountainFriction.Value; case 2: break; } } else if ((int)biome <= 64) { if ((int)biome == 32) { return ConfigManager.AshlandsFriction.Value; } if ((int)biome == 64) { return ConfigManager.DeepNorthFriction.Value; } } else { if ((int)biome == 256) { return ConfigManager.OceanFriction.Value; } if ((int)biome == 512) { return ConfigManager.MistlandsFriction.Value; } } return ConfigManager.GrassFriction.Value; } internal static bool IsSnowBiome(Biome biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)biome != 4) { return (int)biome == 64; } return true; } internal static bool TryGetShieldSurfFriction(Collider collider, out float friction) { friction = ConfigManager.ShieldSurfFriction.Value; if (!ConfigManager.EnableShieldSurf.Value || (Object)(object)collider == (Object)null) { return false; } WearNTear componentInParent = ((Component)collider).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null) { return false; } if (((object)Unsafe.As(ref componentInParent.m_materialType)/*cast due to .constrained prefix*/).ToString().IndexOf("wood", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } Piece componentInParent2 = ((Component)collider).GetComponentInParent(); if ((Object)(object)componentInParent2 != (Object)null && componentInParent2.m_name.IndexOf("wood", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } return false; } internal static float GetDurabilityWearBiomeMultiplier(Biome biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)biome != 32) { return 1f; } return ConfigManager.AshlandsDurabilityWearMultiplier.Value; } internal static void ParseCustomShieldSpeeds(string raw, Dictionary target) { if (string.IsNullOrWhiteSpace(raw)) { return; } string[] array = raw.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { ':' }); if (array2.Length == 2) { string key = array2[0].Trim(); if (float.TryParse(array2[1].Trim(), out var result)) { target[key] = result; } } } } } internal struct GroundSample { public Vector3 Point; public Vector3 Normal; public Collider Collider; public float SlopeAngle; public Vector3 Downhill; public Vector3 SlopeDown; public Biome Biome; public bool IsWaterSurface; public float WaterSurfaceY; } internal static class WaterSledHelper { private static float _smoothedSurfaceY; private static bool _hasSmoothedSurface; internal static bool CanWaterSled(float speed) { if (ConfigManager.EnableWaterSledding.Value) { return speed >= ConfigManager.WaterSledMinSpeed.Value; } return false; } internal static bool IsWaterSledding(Player player, float speed) { if ((Object)(object)player != (Object)null && CanWaterSled(speed)) { return ((Character)player).InWater(); } return false; } internal static bool IsOverWater(Player player) { float surfaceY; if ((Object)(object)player != (Object)null && ((Character)player).InWater()) { return TryGetWaterSurface(player, out surfaceY); } return false; } internal static void ResetSurfaceSmoothing() { _hasSmoothedSurface = false; } internal static bool TryGetWaterSurface(Player player, out float surfaceY) { //IL_002c: 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) surfaceY = 0f; if ((Object)(object)player == (Object)null || !((Character)player).InWater()) { _hasSmoothedSurface = false; return false; } float num = ((!(((Character)player).m_liquidLevel > ((Component)player).transform.position.y - 5f)) ? (Utility.GetFeetPosition(player).y + 0.55f) : ((Character)player).m_liquidLevel); if (!_hasSmoothedSurface) { _smoothedSurfaceY = num; _hasSmoothedSurface = true; } else { _smoothedSurfaceY = Mathf.Lerp(_smoothedSurfaceY, num, 0.18f); } surfaceY = _smoothedSurfaceY; return true; } internal static bool TryBuildWaterGround(Player player, out GroundSample ground) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_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) //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_007e: 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_008e: Unknown result type (might be due to invalid IL or missing references) ground = default(GroundSample); if ((Object)(object)player == (Object)null || !TryGetWaterSurface(player, out var surfaceY)) { return false; } Vector3 feetPosition = Utility.GetFeetPosition(player); float num = Mathf.Clamp(ConfigManager.SledGroundClearance.Value, 0f, 0.6f); ground.Point = new Vector3(feetPosition.x, surfaceY, feetPosition.z); ground.Normal = Vector3.up; ground.Collider = null; ground.SlopeAngle = 0f; ground.SlopeDown = Vector3.zero; ground.Downhill = Vector3.zero; ground.Biome = (Biome)256; ground.IsWaterSurface = true; ground.WaterSurfaceY = surfaceY + num; return true; } internal static bool TryGetWaterSledGround(Player player, float speed, out GroundSample ground) { ground = default(GroundSample); if (!IsWaterSledding(player, speed)) { return false; } return TryBuildWaterGround(player, out ground); } internal static void MaintainWaterSurface(Player player, in GroundSample waterGround, float dt) { //IL_0019: 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_0078: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || !waterGround.IsWaterSurface) { return; } float waterSurfaceY = waterGround.WaterSurfaceY; float y = Utility.GetFeetPosition(player).y; float num = waterSurfaceY - y; if (!(Mathf.Abs(num) < 0.025f)) { float num2 = Mathf.Max(0.04f, 2.5f * dt); float num3 = Mathf.Clamp(num, 0f - num2, num2); if (Mathf.Abs(num) > 0.35f) { num3 = num; } Rigidbody body = Utility.GetBody(player); Vector3 position = (((Object)(object)body != (Object)null) ? body.position : ((Component)player).transform.position); position.y += num3; if ((Object)(object)body != (Object)null) { body.position = position; } ((Component)player).transform.position = position; ((Character)player).m_lastGroundPoint = waterGround.Point; ((Character)player).m_lastGroundNormal = Vector3.up; ((Character)player).m_groundContact = true; } } } internal static class WildlifeImpact { private static readonly string[] KillPrefabTokens = new string[9] { "Boar", "Deer", "Greyling", "Neck", "Crow", "Gull", "Seagull", "Hare", "AshCrow" }; private static readonly Dictionary RecentHits = new Dictionary(); internal static void TryRam(Player player, ItemData shield, PhysicsResult result) { //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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_00fd: 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_0128: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_0140: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017c: 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) if ((Object)(object)player == (Object)null || !ConfigManager.EnableWildlifeImpactKill.Value) { return; } float horizontalSpeed = result.HorizontalSpeed; if (horizontalSpeed < ConfigManager.CollisionSpeedThreshold.Value) { return; } CleanupRecent(); Vector3 val = Utility.Flatten(result.Velocity); if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Utility.Flatten(((Component)player).transform.forward); } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { return; } ((Vector3)(ref val)).Normalize(); Vector3 val2 = ((Component)player).transform.position + Vector3.up * 0.75f; float num = 0.72f; float num2 = Mathf.Clamp(horizontalSpeed * 0.14f, 1f, 2.4f); RaycastHit[] array = Physics.SphereCastAll(val2, num, val, num2, -1); for (int i = 0; i < array.Length; i++) { TryHitCollider(player, shield, ((RaycastHit)(ref array[i])).collider, ((RaycastHit)(ref array[i])).point, val, horizontalSpeed); } Collider[] array2 = Physics.OverlapSphere(val2 + val * (num * 0.5f), num, -1); foreach (Collider val3 in array2) { if (!((Object)(object)val3 == (Object)null)) { Bounds bounds = val3.bounds; Vector3 v = ((Bounds)(ref bounds)).center - val2; Vector3 val4 = Utility.Flatten(v); if (!(Vector3.Dot(((Vector3)(ref val4)).normalized, val) < 0.25f) && !(((Vector3)(ref v)).sqrMagnitude > (num2 + num) * (num2 + num))) { bounds = val3.bounds; TryHitCollider(player, shield, val3, ((Bounds)(ref bounds)).center, val, horizontalSpeed); } } } } private static void TryHitCollider(Player player, ItemData shield, Collider collider, Vector3 point, Vector3 dir, float speed) { //IL_0048: 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) if ((Object)(object)collider == (Object)null) { return; } Character componentInParent = ((Component)collider).GetComponentInParent(); if (IsKillTarget(componentInParent)) { int instanceID = ((Object)componentInParent).GetInstanceID(); if (!RecentHits.ContainsKey(instanceID)) { RecentHits[instanceID] = Time.time + 1.5f; ApplyKill(player, shield, componentInParent, point, dir, speed); } } } private static bool IsKillTarget(Character character) { if ((Object)(object)character == (Object)null || character.IsDead() || character is Player) { return false; } if (character.m_tamed) { return false; } string characterPrefabToken = Utility.GetCharacterPrefabToken(character); if (string.IsNullOrEmpty(characterPrefabToken)) { return false; } for (int i = 0; i < KillPrefabTokens.Length; i++) { if (characterPrefabToken.IndexOf(KillPrefabTokens[i], StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } private static void ApplyKill(Player player, ItemData shield, Character character, Vector3 point, Vector3 dir, float speed) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //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) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0063: 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) //IL_00b5: 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_00db: Unknown result type (might be due to invalid IL or missing references) HitData val = new HitData(); val.m_damage.m_blunt = Mathf.Max(character.GetMaxHealth() * 2f, 200f); val.m_point = point; val.m_dir = dir; val.m_pushForce = speed * 0.75f; ZNetView component = ((Component)player).GetComponent(); if ((Object)(object)component != (Object)null && component.IsValid()) { val.m_attacker = component.GetZDO().m_uid; } val.m_skill = (SkillType)3; val.m_skillLevel = ((Character)player).GetSkillLevel((SkillType)3); character.Damage(val); float impact = speed * ConfigManager.CollisionSpeedDamageScale.Value; ShieldSledController.Instance?.ReportCollisionWear(player, shield, impact); EffectController.Instance?.OnWildlifeImpact(player, point, dir, impact); AudioController.Instance?.PlayImpact(player, impact); MultiplayerSync.Instance?.SendImpactEvent(player, point, impact); } private static void CleanupRecent() { if (RecentHits.Count == 0) { return; } float time = Time.time; List list = null; foreach (KeyValuePair recentHit in RecentHits) { if (!(recentHit.Value > time)) { if (list == null) { list = new List(); } list.Add(recentHit.Key); } } if (list != null) { for (int i = 0; i < list.Count; i++) { RecentHits.Remove(list[i]); } } } } } namespace ShieldSledding.Patches { [HarmonyPatch(typeof(ZNetView), "Awake")] internal static class ZNetViewAwakePatch { private static void Postfix(ZNetView __instance) { if ((Object)(object)((Component)__instance).GetComponent() != (Object)null) { MultiplayerSync.EnsureRegistered(__instance); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }