Decompiled source of Chainbound v0.2.16
plugins\patchnote.Chainbound.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using BepInEx; using BepInEx.Configuration; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Peak.Afflictions; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Chainbound { public static class ChainboundAPI { public static bool HostHasChainbound => ChainboundPlugin.Instance?.ApiHostHasChainbound ?? false; public static bool Enabled => ChainboundPlugin.Instance?.ApiEnabled ?? false; public static event Action<IReadOnlyList<IReadOnlyList<ChainboundGroupMember>>>? GroupsChanged; public static IReadOnlyList<IReadOnlyList<ChainboundGroupMember>> GetGroups() { return ChainboundPlugin.Instance?.GetApiGroupsSnapshot() ?? Array.Empty<IReadOnlyList<ChainboundGroupMember>>(); } public static bool TryGetGroupForActor(int actorNumber, out IReadOnlyList<ChainboundGroupMember> group) { foreach (IReadOnlyList<ChainboundGroupMember> group2 in GetGroups()) { if (group2.Any((ChainboundGroupMember member) => member.ActorNumber == actorNumber)) { group = group2; return true; } } group = Array.Empty<ChainboundGroupMember>(); return false; } internal static void NotifyGroupsChanged(IReadOnlyList<IReadOnlyList<ChainboundGroupMember>> groups) { Action<IReadOnlyList<IReadOnlyList<ChainboundGroupMember>>> groupsChanged = ChainboundAPI.GroupsChanged; if (groupsChanged == null) { return; } Delegate[] invocationList = groupsChanged.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action<IReadOnlyList<IReadOnlyList<ChainboundGroupMember>>> action = (Action<IReadOnlyList<IReadOnlyList<ChainboundGroupMember>>>)invocationList[i]; try { action(groups); } catch (Exception arg) { Debug.LogError((object)$"ChainboundAPI.GroupsChanged subscriber failed: {arg}"); } } } } public sealed class ChainboundGroupMember { public int ActorNumber { get; } public string DisplayName { get; } public string StableKey { get; } public bool IsLocal { get; } public bool IsAlive { get; } public Character? Character { get; } internal ChainboundGroupMember(int actorNumber, string displayName, string stableKey, bool isLocal, bool isAlive, Character? character) { ActorNumber = actorNumber; DisplayName = displayName; StableKey = stableKey; IsLocal = isLocal; IsAlive = isAlive; Character = character; } } [BepInPlugin("patchnote.chainbound", "Chainbound", "0.2.16")] public sealed class ChainboundPlugin : BaseUnityPlugin { private sealed class ChainState { internal readonly List<ChainLink> Links = new List<ChainLink>(); internal readonly List<ChainLink> LocalLinks = new List<ChainLink>(); internal readonly HashSet<Character> ObservedCharacters = new HashSet<Character>(); internal readonly List<Player> MissingMod = new List<Player>(); internal readonly List<Player> VersionMismatches = new List<Player>(); internal List<Character> LocalLivingChunk = new List<Character>(); internal List<ChainMember> LocalMembers = new List<ChainMember>(); internal List<ChainMember?> LocalChunkSlots = new List<ChainMember>(); internal int LocalSlotIndex = -1; internal bool LocalHasStrongAnchor; } private sealed class FallVelocitySample { private const int SampleCount = 8; private readonly float[] _downSpeeds = new float[8]; private int _nextIndex; internal Vector3 LastCenter { get; set; } internal float LastTime { get; set; } internal int Count { get; private set; } internal FallVelocitySample(Vector3 center, float time) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) LastCenter = center; LastTime = time; } internal void AddDownSpeed(float downSpeed) { _downSpeeds[_nextIndex] = downSpeed; _nextIndex = (_nextIndex + 1) % _downSpeeds.Length; Count = Mathf.Min(Count + 1, _downSpeeds.Length); } internal float[] GetSortedSpeeds() { float[] array = new float[Count]; Array.Copy(_downSpeeds, array, Count); Array.Sort(array); return array; } } private sealed class ProxyBody { internal GameObject GameObject { get; } internal Rigidbody Body { get; } internal int WarmupSteps { get; set; } internal ProxyBody(GameObject gameObject, Rigidbody body) { GameObject = gameObject; Body = body; } } private readonly struct ProxyCorrectionResult { internal Vector3 Acceleration { get; } internal int LocalProxyCount { get; } internal bool HasUpperAnchorTension { get; } internal ProxyCorrectionResult(Vector3 acceleration, int localProxyCount, bool hasUpperAnchorTension) { //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) Acceleration = acceleration; LocalProxyCount = localProxyCount; HasUpperAnchorTension = hasUpperAnchorTension; } } private sealed class ChainMember { internal Player Player { get; } internal string StableKey { get; } internal Character? Character { get; } internal Character? ForceTarget { get; } internal int ActorNumber => Player.ActorNumber; internal ChainMember(Player player, string stableKey, Character? character, Character? forceTarget) { Player = player; StableKey = stableKey; Character = character; ForceTarget = forceTarget; } } private readonly struct ChainLink { internal ChainMember Left { get; } internal ChainMember Right { get; } internal string Key { get { if (Left.ActorNumber >= Right.ActorNumber) { return $"{Right.ActorNumber}:{Left.ActorNumber}"; } return $"{Left.ActorNumber}:{Right.ActorNumber}"; } } internal ChainLink(ChainMember left, ChainMember right) { Left = left; Right = right; } } [HarmonyPatch(typeof(Character), "AddForce", new Type[] { typeof(Vector3), typeof(float), typeof(float) })] private static class CharacterAddForcePatch { private static void Prefix(Character __instance, Vector3 move) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) RecordExternalAcceleration(__instance, move); } } [HarmonyPatch(typeof(Character), "RPCA_AddForceAtPosition")] private static class CharacterAddForceAtPositionPatch { private static void Prefix(Character __instance, ref Vector3 force) { //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_000d: 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) force = ScaleExternalImpulse(__instance, force); RecordExternalAcceleration(__instance, force); } } [HarmonyPatch(typeof(CharacterGrabbing), "RPCA_Kick")] private static class CharacterGrabbingKickPatch { private static bool Prefix(CharacterGrabbing __instance) { ChainboundPlugin instance = _instance; if (!((Object)(object)instance == (Object)null)) { return !instance.TryPunishKick(__instance); } return true; } } [HarmonyPatch(typeof(Action_LaunchPlayer), "RunAction")] private static class ActionLaunchPlayerPatch { private static bool Prefix(Action_LaunchPlayer __instance) { ChainboundPlugin instance = _instance; if (!((Object)(object)instance == (Object)null)) { return !instance.TryPunishCookedLaunch(__instance); } return true; } } [HarmonyPatch(typeof(CookingBehavior_RunActions), "TriggerBehaviour")] private static class CookingBehaviorRunActionsPatch { private static bool Prefix(CookingBehavior_RunActions __instance) { ChainboundPlugin instance = _instance; if (!((Object)(object)instance == (Object)null)) { return !instance.TryPunishCookedRunActions(__instance); } return true; } } [HarmonyPatch(typeof(Action_RandomMushroomEffect), "RunAction")] private static class ActionRandomMushroomEffectPatch { private static bool Prefix(Action_RandomMushroomEffect __instance) { ChainboundPlugin instance = _instance; if (!((Object)(object)instance == (Object)null)) { return !instance.TryBlockFartShroom(__instance); } return true; } } [HarmonyPatch(typeof(CharacterAfflictions), "AddStatus", new Type[] { typeof(STATUSTYPE), typeof(float), typeof(bool), typeof(bool), typeof(bool) })] private static class CharacterAfflictionsAddStatusPatch { private static void Prefix(CharacterAfflictions __instance, STATUSTYPE statusType, out DamageLogState? __state) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) __state = null; ChainboundPlugin instance = _instance; if (!((Object)(object)instance == (Object)null) && (int)statusType == 0) { Character component = ((Component)__instance).GetComponent<Character>(); if (instance.ShouldLogDamageFor(component)) { __state = new DamageLogState { InjuryBefore = __instance.GetCurrentStatus((STATUSTYPE)0) }; } } } private static void Postfix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount, bool fromRPC, bool playEffects, bool notify, bool __result, DamageLogState? __state) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) ChainboundPlugin instance = _instance; if (!((Object)(object)instance == (Object)null) && (int)statusType == 0) { instance.LogInjuryDamageApplied(__instance, amount, fromRPC, playEffects, notify, __result, __state); } } } [HarmonyPatch(typeof(CharacterMovement), "CheckFallDamage")] private static class CharacterMovementCheckFallDamagePatch { private static bool Prefix(CharacterMovement __instance) { ChainboundPlugin instance = _instance; if ((Object)(object)instance == (Object)null || (Object)(object)__instance == (Object)null) { return true; } Character component = ((Component)__instance).GetComponent<Character>(); if (instance.ShouldSuppressChainLandingDamage(component)) { return false; } if (!instance.ShouldUseSpeedBasedFallDamage(component)) { return true; } instance.ApplySpeedBasedFallDamage(component, 0f, "landing"); return false; } } [HarmonyPatch(typeof(CharacterMovement), "UpdateVariables")] private static class CharacterMovementUpdateVariablesPatch { private static void Postfix(CharacterMovement __instance) { ChainboundPlugin instance = _instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)__instance == (Object)null)) { instance.RecordFallVelocitySample(((Component)__instance).GetComponent<Character>()); } } } [HarmonyPatch(typeof(CharacterClimbing), "CheckFallDamage")] private static class CharacterClimbingCheckFallDamagePatch { private static bool Prefix(CharacterClimbing __instance, RaycastHit hit) { //IL_008b: 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_0090: 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_0099: 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) ChainboundPlugin instance = _instance; if ((Object)(object)instance == (Object)null || (Object)(object)__instance == (Object)null) { return true; } Character component = ((Component)__instance).GetComponent<Character>(); if ((Object)(object)component == (Object)null) { return true; } if (instance.ShouldSuppressClimbFallDamage(component)) { return false; } if (!instance.ShouldUseSpeedBasedFallDamage(component)) { return true; } float extraImpactSpeed = 0f; if ((Object)(object)component.data != (Object)null) { Vector3 val = ((((Vector3)(ref component.data.avarageLastFrameVelocity)).sqrMagnitude > ((Vector3)(ref component.data.avarageVelocity)).sqrMagnitude) ? component.data.avarageLastFrameVelocity : component.data.avarageVelocity); extraImpactSpeed = Mathf.Max(0f, Vector3.Dot(val, -((RaycastHit)(ref hit)).normal)); } instance.ApplySpeedBasedFallDamage(component, extraImpactSpeed, "climb"); return false; } } [HarmonyPatch(typeof(Campfire), "Light_Rpc")] private static class CampfireLightRpcPatch { private static void Postfix(object[] __args) { bool flag = default(bool); int num; if (__args.Length != 0) { object obj = __args[0]; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { _instance?.HandleCampfireSegmentAdvanced(); } } } private sealed class DamageLogState { internal float InjuryBefore; } private sealed class ChainboundCallbacks : MonoBehaviourPunCallbacks { private ChainboundPlugin? _plugin; internal void Init(ChainboundPlugin plugin) { _plugin = plugin; } public override void OnJoinedRoom() { _plugin?.HandleJoinedRoom(); } public override void OnLeftRoom() { _plugin?.HandleLeftRoom(); } public override void OnPlayerEnteredRoom(Player newPlayer) { _plugin?.HandlePlayerListOrPropertiesChanged(); } public override void OnPlayerLeftRoom(Player otherPlayer) { _plugin?.HandlePlayerListOrPropertiesChanged(); } public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { _plugin?.HandlePlayerListOrPropertiesChanged(); } public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { _plugin?.HandleRoomPropertiesChanged(); } public override void OnMasterClientSwitched(Player newMasterClient) { if ((Object)(object)_plugin != (Object)null) { _plugin._settingsDirty = true; _plugin._chainOrderDirty = true; _plugin._nextRoomPropertyPublish = 0f; } } } internal const string PluginGuid = "patchnote.chainbound"; internal const string PluginName = "Chainbound"; internal const string PluginVersion = "0.2.16"; private const string PlayerVersionKey = "pn.cb.ver"; private const string PlayerEnabledKey = "pn.cb.on"; private const string PlayerPullInKey = "pn.cb.pull"; private const string PlayerPullTargetKey = "pn.cb.ptgt"; private const string RoomEnabledKey = "pn.cb.r.on"; private const string RoomMaxGroupSizeKey = "pn.cb.r.max"; private const string RoomLinkLengthKey = "pn.cb.r.len"; private const string RoomMaxPullAccelerationKey = "pn.cb.r.acc"; private const string RoomFallClampKey = "pn.cb.r.fall"; private const string RoomBreakDistanceKey = "pn.cb.r.brk"; private const string RoomChainGravityKey = "pn.cb.r.grv"; private const string RoomAirbornePullKey = "pn.cb.r.air"; private const string RoomBalloonPullKey = "pn.cb.r.bal"; private const string RoomDownedAnchorKey = "pn.cb.r.down"; private const string RoomExternalPropagationKey = "pn.cb.r.ext"; private const string RoomExternalThresholdKey = "pn.cb.r.exth"; private const string RoomExternalMaxKey = "pn.cb.r.extm"; private const string RoomStuckBreakKey = "pn.cb.r.stuk"; private const string RoomProxyTrackKey = "pn.cb.r.ptrk"; private const string RoomProxyCorrectionKey = "pn.cb.r.pcor"; private const string RoomProxyDampingKey = "pn.cb.r.pdmp"; private const string RoomPullInAccelKey = "pn.cb.r.pacc"; private const string RoomPullInTargetKey = "pn.cb.r.ptrg"; private const string RoomPullInStaminaKey = "pn.cb.r.psta"; private const string RoomDanglingStaminaKey = "pn.cb.r.dsta"; private const string RoomClimberLoadKey = "pn.cb.r.clmb"; private const string RoomGroundAnchorDownKey = "pn.cb.r.ganc"; private const string RoomBalloonExternalKey = "pn.cb.r.bext"; private const string RoomSwingGravityKey = "pn.cb.r.swng"; private const string RoomHangingStaminaKey = "pn.cb.r.hstm"; private const string RoomSpeedDamageKey = "pn.cb.r.sbd"; private const string RoomSpeedDamageMinKey = "pn.cb.r.sdmi"; private const string RoomSpeedDamageMaxKey = "pn.cb.r.sdma"; private const string RoomSpeedDamageScaleKey = "pn.cb.r.sdsc"; private const string RoomPunishTKKey = "pn.cb.r.ptk"; private const string RoomChainOrderKey = "pn.cb.r.order"; private const string EmptyChainSlotPrefix = "empty:"; private const float OpenParasolAnchorStrength = 0.9f; private const float OpenParasolProxyMass = 7f; private const float OpenParasolProxyDrive = 2.35f; private const float OpenParasolLiftBase = 14f; private const float OpenParasolLiftPerDownSpeed = 8f; private static ChainboundPlugin? _instance; private readonly Dictionary<string, LineRenderer> _chainLines = new Dictionary<string, LineRenderer>(StringComparer.Ordinal); private readonly Dictionary<int, Vector3> _lastObservedVelocities = new Dictionary<int, Vector3>(); private readonly Dictionary<int, Vector3> _recordedExternalAccelerations = new Dictionary<int, Vector3>(); private readonly Dictionary<int, FallVelocitySample> _fallVelocitySamples = new Dictionary<int, FallVelocitySample>(); private readonly Dictionary<int, ProxyBody> _proxyBodies = new Dictionary<int, ProxyBody>(); private readonly Dictionary<string, ConfigurableJoint> _proxyJoints = new Dictionary<string, ConfigurableJoint>(StringComparer.Ordinal); private readonly List<string> _roomChainOrder = new List<string>(); private Material? _lineMaterial; private GUIStyle? _lobbyBoxStyle; private GUIStyle? _lobbyHeaderStyle; private GUIStyle? _lobbyTextStyle; private Texture2D? _lobbyBoxTexture; private IReadOnlyList<IReadOnlyList<ChainboundGroupMember>> _apiGroups = Array.Empty<IReadOnlyList<ChainboundGroupMember>>(); private string _apiGroupSignature = string.Empty; private ChainboundCallbacks? _callbacks; private float _nextPlayerPropertyPublish; private float _nextRoomPropertyPublish; private float _nextPullInPropertyPublish; private bool _lastPublishedEnabled; private bool _localPullInHeld; private int _localPullInTargetActor; private bool _localPullPreviewActive; private int _localPullPreviewTargetActor; private bool _lastPublishedPullIn; private int _lastPublishedPullInTargetActor; private bool _settingsDirty = true; private bool _chainOrderDirty = true; private bool _shuffleKeyWasDown; private float _lastCampfireShuffleTime = float.NegativeInfinity; private bool _roomHasChainboundHost; private bool _roomEnabled; private int _roomMaxGroupSize; private float _roomLinkLength; private float _roomMaxPullAcceleration; private float _roomFallClampSeconds; private float _roomLinkBreakDistance; private float _roomChainGravity; private float _roomAirbornePullMultiplier; private float _roomBalloonPullMultiplier; private float _roomDownedAnchorMultiplier; private float _roomExternalForcePropagation; private float _roomExternalForceThreshold; private float _roomExternalForceMaxAcceleration; private float _roomStuckBreakAcceleration; private float _roomProxyTrackStrength; private float _roomProxyCorrectionStrength; private float _roomProxyCorrectionDamping; private float _roomPullInAcceleration; private float _roomPullInTargetLengthMultiplier; private float _roomPullInStaminaPerSecond; private float _roomDanglingStaminaPerPlayer; private float _roomClimberLoadMultiplier; private float _roomGroundAnchorMaxDownAcceleration; private float _roomBalloonExternalForceMultiplier; private float _roomSwingGravityMultiplier; private float _roomHangingStaminaRegenMultiplier; private bool _roomSpeedBasedFallDamage; private float _roomFallDamageMinSpeed; private float _roomFallDamageMaxSpeed; private float _roomFallDamageMultiplier; private bool _roomPunishTK; private int _localCharacterViewId; private float _localCharacterSpawnTime; private float _chainFallProtectedUntil; private float _chainClimbDamageProtectedUntil; private float _lastCatchUpTime = float.NegativeInfinity; private int _catchUpAttemptsForCharacter; private ConfigEntry<bool> _enabled; private ConfigEntry<int> _maxGroupSize; private ConfigEntry<bool> _drawChain; private ConfigEntry<bool> _showLobbyStatus; private ConfigEntry<bool> _showInGameStatus; private ConfigEntry<bool> _showLobbyStatusToEveryone; private ConfigEntry<bool> _requireExactVersion; private ConfigEntry<float> _linkLength; private ConfigEntry<float> _maxPullAcceleration; private ConfigEntry<float> _maxTotalAccelerationMultiplier; private ConfigEntry<float> _anchorMaxDownAcceleration; private ConfigEntry<float> _fallClampSeconds; private ConfigEntry<float> _fallProtectionAfterPullSeconds; private ConfigEntry<float> _spawnGraceSeconds; private ConfigEntry<float> _linkBreakDistance; private ConfigEntry<float> _chainGravity; private ConfigEntry<float> _airbornePullMultiplier; private ConfigEntry<float> _balloonPullMultiplier; private ConfigEntry<float> _downedAnchorMultiplier; private ConfigEntry<float> _externalForcePropagation; private ConfigEntry<float> _externalForceThreshold; private ConfigEntry<float> _externalForceMaxAcceleration; private ConfigEntry<float> _stuckBreakAcceleration; private ConfigEntry<float> _proxyTrackStrength; private ConfigEntry<float> _proxyCorrectionStrength; private ConfigEntry<float> _proxyCorrectionDamping; private ConfigEntry<float> _pullInAcceleration; private ConfigEntry<float> _pullInTargetLengthMultiplier; private ConfigEntry<float> _pullInStaminaPerSecond; private ConfigEntry<float> _danglingStaminaPerPlayer; private ConfigEntry<float> _climberLoadMultiplier; private ConfigEntry<float> _groundAnchorMaxDownAcceleration; private ConfigEntry<float> _balloonExternalForceMultiplier; private ConfigEntry<float> _swingGravityMultiplier; private ConfigEntry<float> _hangingStaminaRegenMultiplier; private ConfigEntry<bool> _speedBasedFallDamage; private ConfigEntry<float> _fallDamageMinSpeed; private ConfigEntry<float> _fallDamageMaxSpeed; private ConfigEntry<float> _fallDamageMultiplier; private ConfigEntry<bool> _autoCatchUpEnabled; private ConfigEntry<float> _autoCatchUpDistance; private ConfigEntry<float> _autoCatchUpWindowSeconds; private ConfigEntry<float> _autoCatchUpCooldownSeconds; private ConfigEntry<KeyCode> _pullInKeyboardKey; private ConfigEntry<KeyCode> _pullInGamepadButton; private ConfigEntry<float> _pullInAimAngleDegrees; private ConfigEntry<bool> _shuffleAtCampfires; private ConfigEntry<KeyCode> _shuffleKeyboardKey; private ConfigEntry<bool> _punishTK; private ConfigEntry<bool> _debugLogging; private ConfigEntry<bool> _damageLogging; private Harmony? _harmony; internal static ChainboundPlugin? Instance => _instance; internal bool ApiHostHasChainbound => _roomHasChainboundHost; internal bool ApiEnabled => ShouldRunHostEnabledGameplay(); private void Awake() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown _instance = this; BindConfig(); RefreshRoomSettingsFromLocalConfig(); _harmony = new Harmony("patchnote.chainbound"); _harmony.PatchAll(typeof(ChainboundPlugin).Assembly); _callbacks = ((Component)this).gameObject.AddComponent<ChainboundCallbacks>(); _callbacks.Init(this); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded Chainbound."); } private void OnDestroy() { Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; ClearChainLines(); ClearProxyChain(); ClearApiGroups(); if ((Object)(object)_callbacks != (Object)null) { Object.Destroy((Object)(object)_callbacks); _callbacks = null; } if ((Object)(object)_lineMaterial != (Object)null) { Object.Destroy((Object)(object)_lineMaterial); _lineMaterial = null; } if ((Object)(object)_lobbyBoxTexture != (Object)null) { Object.Destroy((Object)(object)_lobbyBoxTexture); _lobbyBoxTexture = null; } if (_instance == this) { _instance = null; } } private void BindConfig() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Expected O, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Expected O, but got Unknown //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Expected O, but got Unknown //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Expected O, but got Unknown //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Expected O, but got Unknown //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Expected O, but got Unknown //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Expected O, but got Unknown //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Expected O, but got Unknown //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Expected O, but got Unknown //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Expected O, but got Unknown //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Expected O, but got Unknown //IL_046e: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Expected O, but got Unknown //IL_04ac: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Expected O, but got Unknown //IL_04ea: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Expected O, but got Unknown //IL_0528: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Expected O, but got Unknown //IL_0566: Unknown result type (might be due to invalid IL or missing references) //IL_0570: Expected O, but got Unknown //IL_05a4: Unknown result type (might be due to invalid IL or missing references) //IL_05ae: Expected O, but got Unknown //IL_05e2: Unknown result type (might be due to invalid IL or missing references) //IL_05ec: Expected O, but got Unknown //IL_0620: Unknown result type (might be due to invalid IL or missing references) //IL_062a: Expected O, but got Unknown //IL_065e: Unknown result type (might be due to invalid IL or missing references) //IL_0668: Expected O, but got Unknown //IL_069c: Unknown result type (might be due to invalid IL or missing references) //IL_06a6: Expected O, but got Unknown //IL_06da: Unknown result type (might be due to invalid IL or missing references) //IL_06e4: Expected O, but got Unknown //IL_0718: Unknown result type (might be due to invalid IL or missing references) //IL_0722: Expected O, but got Unknown //IL_0756: Unknown result type (might be due to invalid IL or missing references) //IL_0760: Expected O, but got Unknown //IL_0794: Unknown result type (might be due to invalid IL or missing references) //IL_079e: Expected O, but got Unknown //IL_07d2: Unknown result type (might be due to invalid IL or missing references) //IL_07dc: Expected O, but got Unknown //IL_0831: Unknown result type (might be due to invalid IL or missing references) //IL_083b: Expected O, but got Unknown //IL_086f: Unknown result type (might be due to invalid IL or missing references) //IL_0879: Expected O, but got Unknown //IL_08ad: Unknown result type (might be due to invalid IL or missing references) //IL_08b7: Expected O, but got Unknown //IL_090c: Unknown result type (might be due to invalid IL or missing references) //IL_0916: Expected O, but got Unknown //IL_094a: Unknown result type (might be due to invalid IL or missing references) //IL_0954: Expected O, but got Unknown //IL_0988: Unknown result type (might be due to invalid IL or missing references) //IL_0992: Expected O, but got Unknown //IL_0a0d: Unknown result type (might be due to invalid IL or missing references) //IL_0a17: Expected O, but got Unknown _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable the chain mod. The host's value is synced to the room."); _maxGroupSize = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxGroupSize", 0, new ConfigDescription("Host setting. 0 chains everyone together; 2 creates pairs; 3 creates trios.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 8), Array.Empty<object>())); _drawChain = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DrawChain", true, "Draw local chain links between living players."); _shuffleAtCampfires = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShuffleAtCampfires", true, "Host setting. Shuffle the chain order automatically when a campfire advances to the next segment."); _showLobbyStatus = ((BaseUnityPlugin)this).Config.Bind<bool>("Lobby", "ShowLobbyStatus", true, "Show an airport lobby overlay listing players who are missing or using a different version of the mod."); _showInGameStatus = ((BaseUnityPlugin)this).Config.Bind<bool>("Lobby", "ShowInGameStatus", true, "Show an in-run overlay when players are missing Chainbound or using a different version."); _showLobbyStatusToEveryone = ((BaseUnityPlugin)this).Config.Bind<bool>("Lobby", "ShowLobbyStatusToEveryone", false, "Show Chainbound status overlays on non-host clients too."); _requireExactVersion = ((BaseUnityPlugin)this).Config.Bind<bool>("Lobby", "RequireExactVersion", true, "Treat players with a different Chainbound version as not ready in the lobby status overlay."); _linkLength = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "LinkLength", 7f, new ConfigDescription("Host setting. Maximum distance between proxy bodies before a joint limit becomes taut.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 30f), Array.Empty<object>())); _maxPullAcceleration = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "MaxPullAcceleration", 85f, new ConfigDescription("Host setting. Maximum acceleration the solved proxy chain can apply to a real local player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 250f), Array.Empty<object>())); _maxTotalAccelerationMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "MaxTotalAccelerationMultiplier", 1.6f, new ConfigDescription("Multiplier for the local acceleration cap when one body is affected by multiple proxy links.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 4f), Array.Empty<object>())); _anchorMaxDownAcceleration = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "AnchorMaxDownAcceleration", 14f, new ConfigDescription("Local safety cap for downward acceleration on grounded/climbing anchors.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 80f), Array.Empty<object>())); _fallClampSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "FallClampSeconds", 0.45f, new ConfigDescription("Host setting. Maximum since-grounded/since-jump timer while chain protection is active, reducing chain-caused fall damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1.5f), Array.Empty<object>())); _fallProtectionAfterPullSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "FallProtectionAfterPullSeconds", 0.8f, new ConfigDescription("Local extra fall-damage protection after a chain pull stops.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>())); _spawnGraceSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "SpawnGraceSeconds", 5f, new ConfigDescription("Seconds after spawning/warping before normal chain forces start.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>())); _linkBreakDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "LinkBreakDistance", 80f, new ConfigDescription("Host setting. Links farther than this are treated as disconnected until players get close again. Prevents checkpoint and revive warps from pulling across the map.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(15f, 300f), Array.Empty<object>())); _chainGravity = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "ChainGravity", 18f, new ConfigDescription("Host setting. Extra pendulum gravity along taut or nearly-taut chain links so dangling players sag and swing instead of walking sideways at the same height.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>())); _airbornePullMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "AirbornePullMultiplier", 0.35f, new ConfigDescription("Host setting. How strongly an unsupported airborne player anchors the chain compared to a grounded/climbing player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); _balloonPullMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "BalloonPullMultiplier", 0.2f, new ConfigDescription("Host setting. How strongly a balloon-floating player anchors the chain compared to a grounded/climbing player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); _downedAnchorMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "DownedAnchorMultiplier", 0.12f, new ConfigDescription("Host setting. How strongly a passed-out player anchors and resists the chain. Lower values make downed players easier to drag.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); _externalForcePropagation = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "ExternalForcePropagation", 0.65f, new ConfigDescription("Host setting. Portion of sudden neighbor acceleration that propagates through taut links, helping roots wind and similar forces move the chain together.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1.5f), Array.Empty<object>())); _externalForceThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "ExternalForceThreshold", 10f, new ConfigDescription("Host setting. Sudden acceleration below this is ignored by force propagation.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 80f), Array.Empty<object>())); _externalForceMaxAcceleration = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "ExternalForceMaxAcceleration", 70f, new ConfigDescription("Host setting. Maximum acceleration added by external force propagation per link.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>())); _stuckBreakAcceleration = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "StuckBreakAcceleration", 55f, new ConfigDescription("Host setting. Chain acceleration needed to pull the local player out of cactus/sticky joints.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>())); _proxyTrackStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "ProxyTrackStrength", 45f, new ConfigDescription("Host setting. Acceleration per meter used to keep proxy bodies near the real players they represent. Strong anchors are tracked harder; airborne players are tracked softer.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 160f), Array.Empty<object>())); _proxyCorrectionStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "ProxyCorrectionStrength", 28f, new ConfigDescription("Host setting. Acceleration per meter used to pull the local real ragdoll toward its solved proxy body.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 120f), Array.Empty<object>())); _proxyCorrectionDamping = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "ProxyCorrectionDamping", 5f, new ConfigDescription("Host setting. Velocity damping used when pulling the local real ragdoll toward its solved proxy body.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 40f), Array.Empty<object>())); _pullInAcceleration = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "PullInAcceleration", 100f, new ConfigDescription("Host setting. Acceleration used when a player holds the pull-in key to winch the looked-at chain link shorter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 250f), Array.Empty<object>())); _pullInTargetLengthMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "PullInTargetLengthMultiplier", 0.25f, new ConfigDescription("Host setting. Target chain-link length while pulling, as a multiplier of LinkLength.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.15f, 1f), Array.Empty<object>())); _pullInStaminaPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "PullInStaminaPerSecond", 0.15f, new ConfigDescription("Host setting. Stamina drained per second from the player actively winching a chain link.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); _danglingStaminaPerPlayer = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "DanglingStaminaPerPlayer", 0.05f, new ConfigDescription("Host setting. Extra stamina drained per second for each unsupported player tautly hanging from you while you are on a rope, vine, or climb chain. Load is split between supports.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.3f), Array.Empty<object>())); _climberLoadMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "ClimberLoadMultiplier", 0.1f, new ConfigDescription("Host setting. Multiplier for chain load fed into PEAK's climbing drag hook. Lower values let climbers resist the chain more.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); _groundAnchorMaxDownAcceleration = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "GroundAnchorMaxDownAcceleration", 3.5f, new ConfigDescription("Host setting. Downward acceleration cap for grounded anchors holding a lower unsupported player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 80f), Array.Empty<object>())); _balloonExternalForceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "BalloonExternalForceMultiplier", 0.25f, new ConfigDescription("Host setting. Multiplier for external impulse forces, such as roots wind, on balloon-floating chained players.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); _swingGravityMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "SwingGravityMultiplier", 2.8f, new ConfigDescription("Host setting. Multiplier for tangential gravity when dangling from an upper anchor. Higher values make ledge swings feel faster.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 6f), Array.Empty<object>())); _hangingStaminaRegenMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "HangingStaminaRegenMultiplier", 1f, new ConfigDescription("Host setting. Multiplier for normal stamina regen while the chain is holding an unsupported player from above. 1 is PEAK's grounded regen rate.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>())); _speedBasedFallDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("Damage", "SpeedBasedFallDamage", false, "Host setting. Replace PEAK's airtime-based landing and wall-grab damage with speed-based damage."); _fallDamageMinSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "FallDamageMinSpeed", 11f, new ConfigDescription("Host setting. Downward impact speed in m/s where speed-based fall damage starts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 40f), Array.Empty<object>())); _fallDamageMaxSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "FallDamageMaxSpeed", 23f, new ConfigDescription("Host setting. Downward impact speed in m/s that reaches full speed-based fall damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 60f), Array.Empty<object>())); _fallDamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "FallDamageMultiplier", 1f, new ConfigDescription("Host setting. Multiplier applied to speed-based fall damage after speed is converted to injury.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>())); _autoCatchUpEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("CatchUp", "AutoCatchUpEnabled", true, "Warp a newly spawned local player near their chain group if they spawned far away after joining late."); _autoCatchUpDistance = ((BaseUnityPlugin)this).Config.Bind<float>("CatchUp", "AutoCatchUpDistance", 55f, new ConfigDescription("Distance from the nearest living group member before a fresh local spawn is caught up.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(15f, 300f), Array.Empty<object>())); _autoCatchUpWindowSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("CatchUp", "AutoCatchUpWindowSeconds", 35f, new ConfigDescription("Only auto catch-up during this many seconds after the local character spawns.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 180f), Array.Empty<object>())); _autoCatchUpCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("CatchUp", "AutoCatchUpCooldownSeconds", 20f, new ConfigDescription("Minimum time between automatic catch-up warps.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 180f), Array.Empty<object>())); _pullInKeyboardKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Input", "PullInKeyboardKey", (KeyCode)121, "Keyboard key used to pull in the chain link the local player is looking toward. Set to None to disable."); _pullInGamepadButton = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Input", "PullInGamepadButton", (KeyCode)335, "Gamepad button used to pull in the chain link the local player is looking toward. Xbox RB / PlayStation R1 is usually JoystickButton5. Set to None to disable."); _pullInAimAngleDegrees = ((BaseUnityPlugin)this).Config.Bind<float>("Input", "PullInAimAngleDegrees", 20f, new ConfigDescription("Maximum angle from your look direction for choosing an adjacent chain link to pull. Lower values require more precise aim.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 75f), Array.Empty<object>())); _shuffleKeyboardKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Input", "ShuffleKeyboardKey", (KeyCode)289, "Host-only keyboard key used to shuffle the chain order immediately. Set to None to disable."); _punishTK = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PunishTK", true, "When chained, punish dangerous team-kill actions. Kicking or drinking cooked launch items kills the user; fart shroom launch is blocked."); _debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLogging", false, "Write Chainbound debug messages to the BepInEx log."); _damageLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DamageLogging", true, "Write a BepInEx log line whenever the local player actually gains injury damage."); RefreshPullInTuningDefaults(); ((BaseUnityPlugin)this).Config.SettingChanged += delegate { _settingsDirty = true; _chainOrderDirty = true; _nextPlayerPropertyPublish = 0f; _nextRoomPropertyPublish = 0f; }; } private void RefreshPullInTuningDefaults() { if (Mathf.Approximately(_pullInAcceleration.Value, 85f)) { _pullInAcceleration.Value = 165f; } if (Mathf.Approximately(_pullInTargetLengthMultiplier.Value, 0.45f)) { _pullInTargetLengthMultiplier.Value = 0.25f; } } private void Update() { if (_settingsDirty) { RefreshRoomSettings(); _settingsDirty = false; } UpdatePullInInputState(); if (PhotonNetwork.InRoom) { PublishPlayerPropertiesIfNeeded(force: false); MaintainHostChainOrderIfNeeded(force: false); UpdateHostShuffleInput(); PublishPullInPropertiesIfNeeded(force: false); PublishRoomPropertiesIfNeeded(force: false); RefreshApiGroups(); } else { _shuffleKeyWasDown = false; ClearApiGroups(); } TrackLocalCharacterSpawn(); UpdateChainVisuals(); } private void UpdateHostShuffleInput() { //IL_0014: 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) bool flag = PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient && (int)_shuffleKeyboardKey.Value != 0 && !IsInputBlocked() && IsKeyboardKeyPressed(_shuffleKeyboardKey.Value); if (flag && !_shuffleKeyWasDown) { ShuffleChainOrder("host key"); } _shuffleKeyWasDown = flag; } private void UpdatePullInInputState() { _localPullInHeld = false; _localPullInTargetActor = 0; _localPullPreviewActive = false; _localPullPreviewTargetActor = 0; if (ShouldApplyChainPhysics(out Character localCharacter) && !((Object)(object)localCharacter == (Object)null) && IsPlayerOptedIntoChain(PhotonNetwork.LocalPlayer) && CanUseChainPull(localCharacter) && IsVanillaPullUpInputActive(localCharacter) && TryFindPullInTargetActor(localCharacter, out var targetActor)) { _localPullPreviewActive = true; _localPullPreviewTargetActor = targetActor; if (IsPullInInputPressed(localCharacter) && TrySpendPullInStamina(localCharacter)) { _localPullInHeld = true; _localPullInTargetActor = targetActor; } } } private static bool CanUseChainPull(Character character) { CharacterData data = character.data; if ((Object)(object)data == (Object)null || !data.fullyConscious) { return false; } if ((Object)(object)data.currentItem != (Object)null) { return false; } if (Time.time - data.lastConsumedItem < 0.5f) { return false; } if (data.isClimbing || data.isRopeClimbing || data.isVineClimbing || (Object)(object)data.currentClimbHandle != (Object)null) { return false; } return true; } private static bool IsVanillaPullUpInputActive(Character localCharacter) { if ((Object)(object)localCharacter.input != (Object)null) { return localCharacter.input.useSecondaryIsPressed; } return false; } private bool TrySpendPullInStamina(Character localCharacter) { float num = _roomPullInStaminaPerSecond * Time.deltaTime; if (num <= 0f) { return true; } CharacterData data = localCharacter.data; if ((Object)(object)data == (Object)null) { return false; } num *= Ascents.climbStaminaMultiplier; if (num <= 0f) { return true; } float totalStamina = localCharacter.GetTotalStamina(); if (totalStamina <= num || totalStamina <= 0.005f) { return false; } if (data.currentStamina <= 0f) { if (data.extraStamina <= 0f) { return false; } data.extraStamina = Mathf.Clamp(data.extraStamina - num, 0f, 1f); data.sinceUseStamina = 0f; GUIManager.instance.bar.ChangeBar(); return data.extraStamina > 0f; } data.currentStamina -= num; data.sinceUseStamina = 0f; GUIManager.instance.bar.ChangeBar(); if (data.currentStamina <= 0f) { localCharacter.ClampStamina(); return data.extraStamina > 0f; } return true; } private bool IsPullInInputPressed(Character localCharacter) { //IL_001d: 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_003d: 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) if ((Object)(object)localCharacter.data == (Object)null || IsInputBlocked()) { return false; } bool num = (int)_pullInKeyboardKey.Value != 0 && IsKeyboardKeyPressed(_pullInKeyboardKey.Value); bool flag = (int)_pullInGamepadButton.Value != 0 && IsGamepadButtonPressed(_pullInGamepadButton.Value); return num || flag; } private static bool IsKeyboardKeyPressed(KeyCode key) { //IL_003c: 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: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 Keyboard current = Keyboard.current; if (current != null) { if ((int)key == 103) { return ((ButtonControl)current.gKey).isPressed; } if ((int)key == 116) { return ((ButtonControl)current.tKey).isPressed; } if ((int)key == 121) { return ((ButtonControl)current.yKey).isPressed; } } return TryGetLegacyKey(key); } private static bool IsGamepadButtonPressed(KeyCode key) { //IL_00ba: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected I4, but got Unknown Gamepad current = Gamepad.current; if (current != null) { switch (key - 330) { case 0: return current.buttonSouth.isPressed; case 1: return current.buttonEast.isPressed; case 2: return current.buttonWest.isPressed; case 3: return current.buttonNorth.isPressed; case 4: return current.leftShoulder.isPressed; case 5: return current.rightShoulder.isPressed; case 6: return current.selectButton.isPressed; case 7: return current.startButton.isPressed; case 8: return current.leftStickButton.isPressed; case 9: return current.rightStickButton.isPressed; } } return TryGetLegacyKey(key); } private static bool TryGetLegacyKey(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) try { return Input.GetKey(key); } catch { return false; } } private static bool IsInputBlocked() { try { return (Object)(object)GUIManager.instance != (Object)null && (GUIManager.instance.windowBlockingInput || GUIManager.instance.wheelActive); } catch { return false; } } private bool TryFindPullInTargetActor(Character localCharacter, out int targetActor) { //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_003c: 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_005e: 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_0120: 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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) targetActor = 0; if (PhotonNetwork.LocalPlayer == null || (Object)(object)localCharacter.data == (Object)null) { return false; } ChainState chainState = BuildChainState(); if (chainState.LocalLinks.Count == 0) { return false; } Vector3 val = localCharacter.data.lookDirection; if (!IsFinite(val) || ((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = localCharacter.data.lookDirection_Flat; } if (!IsFinite(val) || ((Vector3)(ref val)).sqrMagnitude < 0.01f) { return false; } ((Vector3)(ref val)).Normalize(); int actorNumber = PhotonNetwork.LocalPlayer.ActorNumber; float num = Mathf.Cos(Mathf.Clamp(_pullInAimAngleDegrees.Value, 10f, 75f) * ((float)Math.PI / 180f)); ChainMember chainMember = null; foreach (ChainLink localLink in chainState.LocalLinks) { ChainMember chainMember2 = null; if (localLink.Left.ActorNumber == actorNumber) { chainMember2 = localLink.Right; } else if (localLink.Right.ActorNumber == actorNumber) { chainMember2 = localLink.Left; } if ((Object)(object)chainMember2?.Character == (Object)null) { continue; } Vector3 vector = GetProxyTargetPosition(chainMember2) - localCharacter.Center; if (IsFinite(vector) && !(((Vector3)(ref vector)).sqrMagnitude < 0.01f)) { float num2 = Vector3.Dot(val, ((Vector3)(ref vector)).normalized); if (num2 > num) { num = num2; chainMember = chainMember2; } } } if (chainMember == null) { return false; } targetActor = chainMember.ActorNumber; return true; } private void FixedUpdate() { if (!ShouldApplyChainPhysics(out Character localCharacter) || (Object)(object)localCharacter == (Object)null) { ClearProxyChain(); return; } ChainState chainState = BuildChainState(); if (IsPlayerOptedIntoChain(PhotonNetwork.LocalPlayer) && TryAutoCatchUp(localCharacter, chainState)) { UpdateObservedVelocities(chainState.ObservedCharacters); return; } if (chainState.LocalLinks.Count == 0) { ClearProxyChain(); UpdateObservedVelocities(chainState.ObservedCharacters); return; } if (IsRecentlyWarped(localCharacter)) { ClearProxyChain(); UpdateObservedVelocities(chainState.ObservedCharacters); return; } if (Time.realtimeSinceStartup - _localCharacterSpawnTime < _spawnGraceSeconds.Value) { ClearProxyChain(); UpdateObservedVelocities(chainState.ObservedCharacters); return; } if (!RunProxyChainSimulation(localCharacter, chainState)) { ClearProxyChain(); } UpdateObservedVelocities(chainState.ObservedCharacters); } private bool ShouldApplyChainPhysics(out Character? localCharacter) { localCharacter = null; if (!ShouldRunHostEnabledGameplay() || IsLobbyScene()) { return false; } localCharacter = Character.localCharacter; if (!IsChainAlive(localCharacter) || (Object)(object)((MonoBehaviourPun)localCharacter).photonView == (Object)null || !((MonoBehaviourPun)localCharacter).photonView.IsMine) { return false; } if (localCharacter.warping || localCharacter.data.isCarried || (Object)(object)localCharacter.data.carrier != (Object)null) { return false; } return true; } private bool ShouldRunHostEnabledGameplay() { if (PhotonNetwork.InRoom && _roomHasChainboundHost) { return _roomEnabled; } return false; } private void TryBreakStuckJoint(Character character, Vector3 acceleration) { if (!(_roomStuckBreakAcceleration <= 0f) && !(((Vector3)(ref acceleration)).sqrMagnitude < _roomStuckBreakAcceleration * _roomStuckBreakAcceleration)) { bool flag; try { flag = character.IsStuck(); } catch { return; } if (flag && !((Object)(object)character.refs?.view == (Object)null) && character.refs.view.IsMine) { DebugLog($"Breaking stuck joint with chain acceleration={((Vector3)(ref acceleration)).magnitude:0.0}"); character.refs.view.RPC("RPCA_Unstick", (RpcTarget)0, Array.Empty<object>()); } } } private void ApplyAcceleration(Character character, Vector3 acceleration) { //IL_0000: 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) if (!IsFinite(acceleration) || ((Vector3)(ref acceleration)).sqrMagnitude < 0.0001f || character.refs?.ragdoll?.partList == null) { return; } foreach (Bodypart part in character.refs.ragdoll.partList) { Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null); if ((Object)(object)val != (Object)null && !val.isKinematic) { val.AddForce(acceleration, (ForceMode)5); } } } private void ApplyClimberLoad(Character character, Vector3 acceleration) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) CharacterData data = character.data; if ((Object)(object)data == (Object)null || ((Vector3)(ref acceleration)).sqrMagnitude < 9f || (!data.isClimbing && !data.isRopeClimbing && !data.isVineClimbing && (Object)(object)data.currentClimbHandle == (Object)null)) { return; } float magnitude = ((Vector3)(ref acceleration)).magnitude; float num = magnitude * _roomClimberLoadMultiplier; if (num < 3f) { return; } Vector3 val = acceleration / Mathf.Max(magnitude, 0.001f); try { character.dragTowardsAction?.Invoke(character.Center + val, Mathf.Min(num, _roomMaxPullAcceleration)); if ((Object)(object)character.refs?.climbing != (Object)null) { character.refs.climbing.climbingStamMinimumMultiplier = Mathf.Max(character.refs.climbing.climbingStamMinimumMultiplier, 1f + Mathf.Clamp01(num / 80f) * 0.7f); } } catch (Exception ex) { DebugLog("ApplyClimberLoad failed: " + ex.Message); } ProtectFromChainFall(character); _chainClimbDamageProtectedUntil = Time.time + _fallProtectionAfterPullSeconds.Value; } private bool RunProxyChainSimulation(Character localCharacter, ChainState state) { //IL_0047: 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_005f: 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_007b: Unknown result type (might be due to invalid IL or missing references) if (state.LocalMembers.Count <= 1 || state.LocalLinks.Count == 0) { ClearProxyChain(); return false; } EnsureProxyChain(state); ProxyCorrectionResult proxyCorrectionResult = ComputeLocalProxyCorrection(localCharacter, state); PrepareProxyStep(state); if (proxyCorrectionResult.LocalProxyCount == 0) { return false; } Vector3 acceleration = proxyCorrectionResult.Acceleration; if (((Vector3)(ref acceleration)).sqrMagnitude > 0.0001f) { TryBreakStuckJoint(localCharacter, proxyCorrectionResult.Acceleration); ApplyAcceleration(localCharacter, proxyCorrectionResult.Acceleration); ApplyClimberLoad(localCharacter, proxyCorrectionResult.Acceleration); } if (proxyCorrectionResult.HasUpperAnchorTension || HasUpperChainSupportForStamina(localCharacter, state)) { ProtectFromChainFall(localCharacter); ApplyHangingStaminaRegen(localCharacter); _chainFallProtectedUntil = Time.time + _fallProtectionAfterPullSeconds.Value; _chainClimbDamageProtectedUntil = Time.time + _fallProtectionAfterPullSeconds.Value; } ApplyDanglingSupportStaminaDrain(localCharacter, state); return true; } private void ApplyDanglingSupportStaminaDrain(Character localCharacter, ChainState state) { float danglingSupportLoad = GetDanglingSupportLoad(localCharacter, state); if (!(danglingSupportLoad <= 0f)) { float num = danglingSupportLoad * _roomDanglingStaminaPerPlayer * Time.fixedDeltaTime; if (!(num <= 0f)) { DrainLocalStamina(localCharacter, num); } } } private static void DrainLocalStamina(Character character, float cost) { CharacterData data = character.data; if ((Object)(object)data == (Object)null || cost <= 0f) { return; } cost *= Ascents.climbStaminaMultiplier; if (cost <= 0f) { return; } if (data.currentStamina <= 0f) { if (!(data.extraStamina <= 0f)) { data.extraStamina = Mathf.Clamp(data.extraStamina - cost, 0f, 1f); data.sinceUseStamina = 0f; GUIManager.instance.bar.ChangeBar(); } } else { data.currentStamina -= cost; data.sinceUseStamina = 0f; character.ClampStamina(); GUIManager.instance.bar.ChangeBar(); } } private float GetDanglingSupportLoad(Character localCharacter, ChainState state) { Character localCharacter2 = localCharacter; if (_roomDanglingStaminaPerPlayer <= 0f || !IsRopeVineOrChainSupported(localCharacter2) || state.LocalMembers.Count <= 1) { return 0f; } int num = state.LocalMembers.FindIndex((ChainMember member) => (Object)(object)member.ForceTarget == (Object)(object)localCharacter2 || (Object)(object)member.Character == (Object)(object)localCharacter2); if (num < 0) { return 0f; } float num2 = 0f; for (int i = 0; i < state.LocalMembers.Count; i++) { if (i == num) { continue; } Character val = state.LocalMembers[i].ForceTarget ?? state.LocalMembers[i].Character; if (!((Object)(object)val == (Object)null) && IsUnsupported(val)) { List<int> list = new List<int>(); int num3 = FindNearestTautSupportIndex(state, i, -1); int num4 = FindNearestTautSupportIndex(state, i, 1); if (num3 >= 0) { list.Add(num3); } if (num4 >= 0 && num4 != num3) { list.Add(num4); } if (list.Count > 0 && list.Contains(num)) { num2 += 1f / (float)list.Count; } } } return num2; } private int FindNearestTautSupportIndex(ChainState state, int startIndex, int step) { for (int i = startIndex + step; i >= 0 && i < state.LocalMembers.Count; i += step) { if (!AreAdjacentMembersTautForLoad(state.LocalMembers[i - ((step > 0) ? 1 : 0)], state.LocalMembers[i + ((step < 0) ? 1 : 0)])) { return -1; } Character val = state.LocalMembers[i].ForceTarget ?? state.LocalMembers[i].Character; if ((Object)(object)val == (Object)null) { return -1; } if (IsLoadStoppingSupport(val)) { return i; } } return -1; } private bool AreAdjacentMembersTautForLoad(ChainMember left, ChainMember right) { //IL_0069: 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) Character val = left.ForceTarget ?? left.Character; Character val2 = right.ForceTarget ?? right.Character; if ((Object)(object)left.Character == (Object)null || (Object)(object)right.Character == (Object)null || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return false; } if (!CanLinkConnect(left.Character, right.Character)) { return false; } return Vector3.Distance(val.Center, val2.Center) >= _roomLinkLength * 0.88f; } private static bool IsRopeVineOrChainSupported(Character character) { CharacterData data = character.data; if ((Object)(object)data != (Object)null) { if (!data.isRopeClimbing && !data.isVineClimbing) { return (Object)(object)data.currentClimbHandle != (Object)null; } return true; } return false; } private bool IsLoadStoppingSupport(Character character) { return IsSupported(character); } private void ApplyHangingStaminaRegen(Character character) { CharacterData data = character.data; if (!(_roomHangingStaminaRegenMultiplier <= 0f) && !((Object)(object)data == (Object)null) && ((MonoBehaviourPun)character).photonView.IsMine && data.fullyConscious && !data.isGrounded && !data.isClimbing && !data.isRopeClimbing && !data.isVineClimbing && !((Object)(object)data.currentClimbHandle != (Object)null)) { float num = ((data.currentStamina > 0f) ? 1f : 2f); if (!(data.sinceUseStamina < num) && !(character.GetTotalStamina() >= character.GetMaxStamina())) { character.AddStamina(Time.fixedDeltaTime * 0.2f * _roomHangingStaminaRegenMultiplier); } } } private bool HasUpperChainSupportForStamina(Character localCharacter, ChainState state) { //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_00d9: 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_00e0: 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_00f5: 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_010b: 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) if ((Object)(object)localCharacter.data == (Object)null || !IsUnsupported(localCharacter)) { return false; } int num = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : (-1)); Vector3 center = localCharacter.Center; foreach (ChainLink localLink in state.LocalLinks) { ChainMember chainMember = null; if (localLink.Left.ActorNumber == num || (Object)(object)localLink.Left.ForceTarget == (Object)(object)localCharacter) { chainMember = localLink.Right; } else if (localLink.Right.ActorNumber == num || (Object)(object)localLink.Right.ForceTarget == (Object)(object)localCharacter) { chainMember = localLink.Left; } if (chainMember == null) { continue; } Character val = chainMember.ForceTarget ?? chainMember.Character; if (!((Object)(object)val == (Object)null) && IsChainAlive(val)) { Vector3 proxyTargetPosition = GetProxyTargetPosition(chainMember); if (proxyTargetPosition.y > center.y + 0.75f && Vector3.Distance(center, proxyTargetPosition) > _roomLinkLength * 0.55f && Vector3.Distance(center, proxyTargetPosition) <= _roomLinkBreakDistance) { return true; } } } return false; } private ProxyCorrectionResult ComputeLocalProxyCorrection(Character localCharacter, ChainState state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_05be: Unknown result type (might be due to invalid IL or missing references) //IL_05c6: Unknown result type (might be due to invalid IL or missing references) //IL_05cb: 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_0073: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0625: Unknown result type (might be due to invalid IL or missing references) //IL_0628: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: 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_031b: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_04e2: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) //IL_04a5: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_04b5: Unknown result type (might be due to invalid IL or missing references) //IL_04b7: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04be: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_04c7: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0455: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_046f: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_04f6: Unknown result type (might be due to invalid IL or missing references) //IL_0501: Unknown result type (might be due to invalid IL or missing references) //IL_056e: Unknown result type (might be due to invalid IL or missing references) //IL_056f: Unknown result type (might be due to invalid IL or missing references) //IL_0573: Unknown result type (might be due to invalid IL or missing references) //IL_0578: Unknown result type (might be due to invalid IL or missing references) //IL_057d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.zero; int num = 0; int num2 = 0; bool hasUpperAnchorTension = false; bool flag = false; bool flag2 = false; foreach (ChainMember localMember in state.LocalMembers) { if ((Object)(object)localMember.ForceTarget != (Object)(object)localCharacter || !_proxyBodies.TryGetValue(localMember.ActorNumber, out ProxyBody value)) { continue; } num++; if (value.WarmupSteps > 0) { continue; } Vector3 proxyTargetPosition = GetProxyTargetPosition(localMember); if (!IsFinite(proxyTargetPosition) || !IsFinite(value.Body.position) || Vector3.Distance(value.Body.position, proxyTargetPosition) > _roomLinkBreakDistance * 0.5f) { ResetProxyBody(value, localMember, 2); continue; } Vector3 proxyTargetVelocity = GetProxyTargetVelocity(localMember); Vector3 val2 = (value.Body.position - proxyTargetPosition) * _roomProxyCorrectionStrength + (value.Body.linearVelocity - proxyTargetVelocity) * _roomProxyCorrectionDamping; foreach (ChainLink localLink in state.LocalLinks) { if (!TryGetOtherMember(localLink, localMember, out ChainMember other) || other == null || !_proxyBodies.TryGetValue(other.ActorNumber, out ProxyBody value2)) { continue; } Vector3 proxyTargetPosition2 = GetProxyTargetPosition(other); Vector3 val3 = proxyTargetPosition2 - proxyTargetPosition; float magnitude = ((Vector3)(ref val3)).magnitude; if (magnitude <= 0.001f || magnitude > _roomLinkBreakDistance) { continue; } Vector3 val4 = val3 / magnitude; float num3 = magnitude - _roomLinkLength; float num4 = Vector3.Distance(value.Body.position, value2.Body.position); bool flag3 = num3 > 0f || num4 > _roomLinkLength * 0.92f; bool flag4 = HasStrongAnchor(other) && proxyTargetPosition2.y > proxyTargetPosition.y + 0.75f; bool flag5 = HasOpenParasol(other.ForceTarget ?? other.Character) && proxyTargetPosition2.y > proxyTargetPosition.y + 0.75f; bool flag6 = IsPlayerPullingLink(localMember, other); bool flag7 = IsPlayerPullingLink(other, localMember); float pullInTargetLength = GetPullInTargetLength(); bool flag8 = (flag6 || flag7) && magnitude > pullInTargetLength; if (!flag3 && !flag4 && !flag5 && !flag8) { continue; } Vector3 val5 = Vector3.zero; Vector3 proxyTargetVelocity2 = GetProxyTargetVelocity(other); if (flag8) { float num5 = magnitude - pullInTargetLength; float num6 = Mathf.Min(_roomPullInAcceleration, num5 * _roomProxyTrackStrength * 2.4f + _roomPullInAcceleration * 0.55f); float anchorStrength = GetAnchorStrength(localCharacter); float num7 = 0f; if (flag7) { num7 += Mathf.Lerp(1f, GetPullInAnchorScale(localCharacter), anchorStrength); } if (flag6) { num7 += Mathf.Lerp(1f, GetPullInAnchorScale(localCharacter) * 0.5f, anchorStrength); } if (num7 > 0f) { val5 += val4 * num6 * Mathf.Clamp01(num7); flag = true; } } if (flag3) { float num8 = Mathf.Max(0f, Vector3.Dot(val2, val4)); float num9 = Mathf.Max(0f, Vector3.Dot(proxyTargetVelocity2 - proxyTargetVelocity, val4)); float num10 = Mathf.Max(0f, num3) * _roomProxyTrackStrength * 1.6f + num9 * _roomProxyCorrectionDamping * 1.35f; val5 += val4 * Mathf.Max(num8, num10); } if (flag5 && magnitude > _roomLinkLength * 0.82f && IsUnsupported(localCharacter)) { float num11 = Mathf.Max(0f, 0f - proxyTargetVelocity.y); float num12 = Mathf.Max(0f, 0f - proxyTargetVelocity2.y); float num13 = Mathf.Max(0f, num11 - num12); float num14 = Mathf.Max(0f, magnitude - _roomLinkLength * 0.82f); float num15 = num13 * _roomProxyCorrectionDamping * 2.5f + num14 * _roomProxyTrackStrength * 2f; if (num15 > 0f) { val5 += val4 * Mathf.Min(num15, _roomMaxPullAcceleration * 2.4f); hasUpperAnchorTension = true; flag2 = true; } } if (flag4 && magnitude > _roomLinkLength * 0.55f && IsUnsupported(localCharacter)) { hasUpperAnchorTension = true; Vector3 val6 = Vector3.ProjectOnPlane(Vector3.down * _roomChainGravity * _roomSwingGravityMultiplier, val4); val5 += val6; } if (!(((Vector3)(ref val5)).sqrMagnitude <= 0.0001f)) { if (IsSupported(localCharacter) && val5.y < 0f) { float supportedDownAccelerationCap = GetSupportedDownAccelerationCap(localCharacter, other, proxyTargetPosition, proxyTargetPosition2); val5.y = Mathf.Max(val5.y, 0f - supportedDownAccelerationCap); } float num16 = Mathf.Max(new float[4] { _roomMaxPullAcceleration, _roomMaxPullAcceleration * _maxTotalAccelerationMultiplier.Value, flag8 ? _roomPullInAcceleration : 0f, flag2 ? (_roomMaxPullAcceleration * 2.4f) : 0f }); val += Vector3.ClampMagnitude(val5, num16); num2++; } } } if (num2 > 1) { val /= Mathf.Sqrt((float)num2); } float num17 = Mathf.Max(new float[4] { _roomMaxPullAcceleration, _roomMaxPullAcceleration * _maxTotalAccelerationMultiplier.Value, flag ? _roomPullInAcceleration : 0f, flag2 ? (_roomMaxPullAcceleration * 2.4f) : 0f }); return new ProxyCorrectionResult(Vector3.ClampMagnitude(val, num17), num, hasUpperAnchorTension); } private static bool TryGetOtherMember(ChainLink link, ChainMember member, out ChainMember? other) { if (link.Left.ActorNumber == member.ActorNumber) { other = link.Right; return true; } if (link.Right.ActorNumber == member.ActorNumber) { other = link.Left; return true; } other = null; return false; } private bool IsPlayerPullingLink(ChainMember puller, ChainMember target) { if (PhotonNetwork.LocalPlayer != null && puller.ActorNumber == PhotonNetwork.LocalPlayer.ActorNumber) { if (_localPullInHeld) { return _localPullInTargetActor == target.ActorNumber; } return false; } if (!TryReadBool(puller.Player.CustomProperties, "pn.cb.pull", out var value) || !value) { return false; } if (TryReadInt(puller.Player.CustomProperties, "pn.cb.ptgt", out var value2)) { return value2 == target.ActorNumber; } return false; } private bool IsLinkBeingPulledIn(ChainLink link) { if (!IsPlayerPullingLink(link.Left, link.Right)) { return IsPlayerPullingLink(link.Right, link.Left); } return true; } private float GetPullInTargetLength() { return Mathf.Clamp(_roomLinkLength * _roomPullInTargetLengthMultiplier, 0.75f, _roomLinkLength); } private static float GetPullInAnchorScale(Character character) { CharacterData data = character.data; if ((Object)(object)data == (Object)null) { return 0.25f; } if (data.isGrounded && data.sinceGrounded < 0.4f) { return 0.18f; } if (data.isClimbing || data.isRopeClimbing || data.isVineClimbing || (Object)(object)data.currentClimbHandle != (Object)null) { return 0.28f; } return 0.4f; } private float GetSupportedDownAccelerationCap(Character localCharacter, ChainMember neighbor, Vector3 localPosition, Vector3 neighborPosition) { //IL_0023: 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) Character val = neighbor.ForceTarget ?? neighbor.Character; bool flag = (Object)(object)val != (Object)null && IsUnsupported(val) && neighborPosition.y < localPosition.y - 0.75f; if ((Object)(object)localCharacter.data != (Object)null && localCharacter.data.isGrounded && localCharacter.data.sinceGrounded < 0.4f && flag) { return Mathf.Min(_anchorMaxDownAcceleration.Value, _roomGroundAnchorMaxDownAcceleration); } if ((Object)(object)localCharacter.data != (Object)null && (localCharacter.data.isClimbing || localCharacter.data.isRopeClimbing || localCharacter.data.isVineClimbing || (Object)(object)localCharacter.data.currentClimbHandle != (Object)null)) { return Mathf.Min(_anchorMaxDownAcceleration.Value, Mathf.Max(_roomGroundAnchorMaxDownAcceleration, _roomMaxPullAcceleration * _roomClimberLoadMultiplier)); } return _anchorMaxDownAcceleration.Value; } private void EnsureProxyChain(ChainState state) { HashSet<int> liveBodies = new HashSet<int>(); foreach (ChainMember localMember in state.LocalMembers) { liveBodies.Add(localMember.ActorNumber); EnsureProxyBody(localMember); } foreach (int item in _proxyBodies.Keys.Where((int key) => !liveBodies.Contains(key)).ToList()) { DestroyProxyBody(item); } HashSet<string> liveLinks = new HashSet<string>(StringComparer.Ordinal); foreach (ChainLink localLink in state.LocalLinks) { liveLinks.Add(localLink.Key); EnsureProxyJoint(localLink); if (_proxyJoints.TryGetValue(localLink.Key, out ConfigurableJoint value) && (Object)(object)value != (Object)null) { ConfigureProxyJoint(value, IsLinkBeingPulledIn(localLink)); } } foreach (string item2 in _proxyJoints.Keys.Where((string key) => !liveLinks.Contains(key)).ToList()) { if ((Object)(object)_proxyJoints[item2] != (Object)null) { Object.Destroy((Object)(object)_proxyJoints[item2]); } _proxyJoints.Remove(item2); } } private void EnsureProxyBody(ChainMember member) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_0062: 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_00b5: 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_00cc: Expected O, but got Unknown //IL_0113: 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) Vector3 proxyTargetPosition = GetProxyTargetPosition(member); Vector3 proxyTargetVelocity = GetProxyTargetVelocity(member); if (!_proxyBodies.TryGetValue(member.ActorNumber, out ProxyBody value) || (Object)(object)value.Body == (Object)null) { GameObject val = new GameObject("Chainbound Proxy " + member.ActorNumber) { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); Rigidbody val2 = val.AddComponent<Rigidbody>(); val2.useGravity = true; val2.detectCollisions = false; val2.isKinematic = false; val2.interpolation = (RigidbodyInterpolation)0; val2.collisionDetectionMode = (CollisionDetectionMode)0; val2.linearDamping = 0f; val2.angularDamping = 2f; val2.maxLinearVelocity = 80f; val2.position = proxyTargetPosition; val2.rotation = Quaternion.identity; val2.linearVelocity = proxyTargetVelocity; value = new ProxyBody(val, val2) { WarmupSteps = 2 }; _proxyBodies[member.ActorNumber] = value; } else if ((Object)(object)member.Character != (Object)null && IsRecentlyWarped(member.Character)) { ResetProxyBody(value, member, 2); } else if (!IsFinite(value.Body.position) || Vector3.Distance(value.Body.position, proxyTargetPosition) > _roomLinkBreakDistance * 0.75f) { ResetProxyBody(value, member, 2); } } private void EnsureProxyJoint(ChainLink link) { //IL_007b: 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 (_proxyBodies.TryGetValue(link.Left.ActorNumber, out ProxyBody value) && _proxyBodies.TryGetValue(link.Right.ActorNumber, out ProxyBody value2)) { if (!_proxyJoints.TryGetValue(link.Key, out ConfigurableJoint value3) || (Object)(object)value3 == (Object)null) { value3 = ((Component)value.Body).gameObject.AddComponent<ConfigurableJoint>(); ((Joint)value3).connectedBody = value2.Body; ((Joint)value3).autoConfigureConnectedAnchor = false; ((Joint)value3).anchor = Vector3.zero; ((Joint)value3).connectedAnchor = Vector3.zero; _proxyJoints[link.Key] = value3; } ConfigureProxyJoint(value3, pullInActive: false); } } private void ConfigureProxyJoint(ConfigurableJoint joint, bool pullInActive) { //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_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_0109: Unknown result type (might be due to invalid IL or missing references) joint.xMotion = (ConfigurableJointMotion)1; joint.yMotion = (ConfigurableJointMotion)1; joint.zMotion = (ConfigurableJointMotion)1; joint.angularXMotion = (ConfigurableJointMotion)2; joint.angularYMotion = (ConfigurableJointMotion)2; joint.angularZMotion = (ConfigurableJointMotion)2; ((Joint)joint).enableCollision = false; ((Joint)joint).enablePreprocessing = false; ((Joint)joint).breakForce = float.PositiveInfinity; ((Joint)joint).breakTorque = float.PositiveInfinity; joint.projectionMode = (JointProjectionMode)1; joint.projectionDistance = 0.75f; joint.projectionAngle = 180f; SoftJointLimit linearLimit = joint.linearLimit; ((SoftJointLimit)(ref linearLimit)).limit = Mathf.Max(0.1f, pullInActive ? GetPullInTargetLength() : _roomLinkLength); ((SoftJointLimit)(ref linearLimit)).bounciness = 0f; ((SoftJointLimit)(ref linearLimit)).contactDistance = 0.15f; joint.linearLimit = linearLimit; SoftJointLimitSpring linearLimitSpring = joint.linearLimitSpring; ((SoftJointLimitSpring)(ref linearLimitSpring)).spring = (pullInActive ? Mathf.Max(0f, _roomPullInAcceleration * 0.35f) : 0f); ((SoftJointLimitSpring)(ref linearLimitSpring)).damper = (pullInActive ? Mathf.Max(0f, _roomProxyCorrectionDamping * 2f) : 0f); joint.linearLimitSpring = linearLimitSpring; } private void PrepareProxyStep(ChainState state) { //IL_00c7: 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_00db: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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_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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: 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) foreach (ChainMember localMember in state.LocalMembers) { if (!_proxyBodies.TryGetValue(localMember.ActorNumber, out ProxyBody value) || (Object)(object)value.Body == (Object)null) { continue; } Character val = localMember.ForceTarget ?? localMember.Character; if (!((Object)(object)val == (Object)null) && !((Object)(object)val.data == (Object)null)) { float anchorStrength = GetAnchorStrength(val); value.Body.mass = GetProxyMass(val, anchorStrength); value.Body.useGravity = true; value.Body.linearDamping = Mathf.Lerp(0f, 0.25f, anchorStrength); value.Body.angularDamping = 2f; Vector3 proxyTargetPosition = GetProxyTargetPosition(localMember); Vector3 proxyTargetVelocity = GetProxyTargetVelocity(localMember); Vector3 val2 = proxyTargetPosition - value.Body.position; Vector3 val3 = proxyTargetVelocity - value.Body.linearVelocity; float proxyDriveMultiplier = GetProxyDriveMultiplier(val, anchorStrength); float num = _roomProxyCorrectionDamping * Mathf.Lerp(0.02f, 1f, anchorStrength); Vector3 val4 = val2 * _roomProxyTrackStrength * proxyDriveMultiplier + val3 * num * proxyDriveMultiplier; float num2 = Mathf.Max(_roomMaxPullAcceleration, _roomProxyTrackStrength * 2f); value.Body.AddForce(Vector3.ClampMagnitude(val4, num2), (ForceMode)5); if (state.LocalHasStrongAnchor && IsUnsupported(val)) { float num3 = Mathf.Lerp(1f, 0.2f, anchorStrength); float num4 = Mathf.Max(0f, _roomChainGravity - Mathf.Abs(Physics.gravity.y)); value.Body.AddForce(Vector3.down * num4 * num3, (ForceMode)5); } Vector3 proxyExternalAcceleration = GetProxyExternalAcceleration(localMember); if (((Vector3)(ref proxyExternalAcceleration)).sqrMagnitude > _roomExternalForceThreshold * _roomExternalForceThreshold) { Vector3 val5 = Vector3.ClampMagnitude(proxyExternalAcceleration, _roomExternalForceMaxAcceleration); value.Body.AddForce(val5 * _roomExternalForcePropagation, (ForceMode)5); } if (value.WarmupSteps > 0) { value.WarmupSteps--; } } } } private float GetProxyMass(Character target, float anchorStrength) { if (IsDowned(target)) { return 0.8f; } if (HasOpenParasol(target)) { return 7f; } if ((Object)(object)target.data != (Object)null && (target.data.isClimbing || target.data.isRopeClimbing || target.data.isVineClimbing || (Object)(object)target.data.currentClimbHandle != (Object)null)) { return 12f; } try { if (target.IsStuck()) { return 10f; } } catch { } if ((Object)(object)target.data != (Object)null && target.data.isGrounded && target.data.sinceGrounded < 0.4f) { return 6f; } return Mathf.Lerp(0.75f, 4f, anchorStrength); } private float GetProxyDriveMultiplier(Character target, float anchorStrength) { if (IsDowned(target)) { return 0.05f; } if (HasOpenParasol(target)) { return 2.35f; } if ((Object)(object)target.data != (Object)null && (target.data.isClimbing || target.data.isRopeClimbing || target.data.isVineClimbing || (Object)(object)target.data.currentClimbHandle != (Object)null)) { return 2.4f; } try { if (target.IsStuck()) { return 2f; } } catch { } if ((Object)(object)target.data != (Object)null && target.data.isGrounded && target.data.sinceGrounded < 0.4f) { return 1.55f; } if (GetBalloonCount(target) > 0) { return 0.04f; } return Mathf.Lerp(0.08f, 1.2f, anchorStrength); } private Vector3 GetProxyTargetPosition(ChainMember member) { //IL_0021: 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) Character val = member.ForceTarget ?? member.Character; if (!((Object)(object)val != (Object)null)) { return Vector3.zero; } return val.Center; } private Vector3 GetProxyTargetVelocity(ChainMember member) { //IL_0031: 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) Character val = member.ForceTarget ?? member.Character; if (!((Object)(object)val?.data != (Object)null)) { return Vector3.zero; } return val.data.avarageVelocity; } private Vector3 GetProxyExternalAcceleration(ChainMember member) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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: 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) //IL_0099: 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_00c2: 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_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_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_00b8: 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_00d7: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.zero; if ((Object)(object)member.Character != (Object)null) { val += GetRecordedExternalAcceleration(mem