using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("koku")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("RepoWallClimb")] [assembly: AssemblyTitle("RepoWallClimb")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.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] [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] [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 RepoWallClimb { internal static class FarClip { internal enum User { Sense, Web } private static Camera? _cam; private static float _saved; private static readonly float[] _want = new float[2]; internal static bool Extended => (Object)(object)_cam != (Object)null; internal static float Current { get { Camera main = Camera.main; return ((Object)(object)main != (Object)null) ? main.farClipPlane : 0f; } } internal static void Request(User who, float distance) { _want[(int)who] = Mathf.Max(0f, distance); Apply(); } internal static void Release(User who) { _want[(int)who] = 0f; Apply(); } private static void Apply() { float num = Mathf.Max(_want[0], _want[1]); Camera main = Camera.main; if (num <= 0f || (Object)(object)main == (Object)null) { Restore(); return; } if ((Object)(object)_cam != (Object)(object)main) { Restore(); _cam = main; _saved = main.farClipPlane; } main.farClipPlane = Mathf.Max(_saved, num); } internal static void Restore() { if (!((Object)(object)_cam == (Object)null)) { _cam.farClipPlane = _saved; _cam = null; } } } [BepInPlugin("koku.RepoWallClimb", "RepoWallClimb", "1.0")] public class RepoWallClimb : BaseUnityPlugin { internal static RepoWallClimb Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Patch(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } internal void Patch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { } } public enum ClimbCameraMode { Off, WallUp } public enum ClimbJumpMode { Detach, SurfaceLeap } public enum ClimbLeapMode { Normal, WorldUp, Custom } public enum DetachReason { surface_lost, stood_up, crouched, web, release_key, jump, tumble, disabled } [HarmonyPatch(typeof(PlayerController))] internal static class WallClimbPatch2 { internal static ConfigEntry Enabled; internal static ConfigEntry ToggleKey; internal static ConfigEntry ReleaseKey; internal static ConfigEntry RequireCrouch; internal static ConfigEntry HoldRequiresCrouch; internal static ConfigEntry BlockWhenCrouching; internal static ConfigEntry RequireIntent; internal static ConfigEntry IntentDot; internal static ConfigEntry CastRadius; internal static ConfigEntry CastBackOff; internal static ConfigEntry AttachRange; internal static ConfigEntry HoldRange; internal static ConfigEntry HoldRayOffset; internal static ConfigEntry HoldMinDot; internal static ConfigEntry FollowMaxAngle; internal static ConfigEntry MinSteepness; internal static ConfigEntry EyeHeight; internal static ConfigEntry DetachCooldown; internal static ConfigEntry RequireFullBody; internal static ConfigEntry BodyLow; internal static ConfigEntry BodyHigh; internal static ConfigEntry BodyWidth; internal static ConfigEntry SwitchMinAngle; internal static ConfigEntry SwitchMaxAngle; internal static ConfigEntry SwitchRange; internal static ConfigEntry SwitchCooldown; internal static ConfigEntry SwitchRevertWindow; internal static ConfigEntry SwitchMaxFloorDot; internal static ConfigEntry EdgeWrap; internal static ConfigEntry EdgeReach; internal static ConfigEntry EdgeDepth; internal static ConfigEntry EdgeWindow; internal static ConfigEntry EdgeAssist; internal static ConfigEntry NormalBlendSpeed; internal static ConfigEntry CarryVelocity; internal static ConfigEntry GraceSeconds; internal static ConfigEntry UseContacts; internal static ConfigEntry UseNearProbe; internal static ConfigEntry StickTouchScale; internal static ConfigEntry CancelGravity; internal static ConfigEntry UseAntiGravity; internal static ConfigEntry GravityCancelScale; internal static ConfigEntry ClimbAccel; internal static ConfigEntry ClimbMaxSpeed; internal static ConfigEntry ClimbDrag; internal static ConfigEntry StickForce; internal static ConfigEntry JumpMode; internal static ConfigEntry LeapMode; internal static ConfigEntry WallJumpForce; internal static ConfigEntry LeapForce; internal static ConfigEntry LeapOutward; internal static ConfigEntry LeapWindow; internal static ConfigEntry LeapCooldown; internal static ConfigEntry MoveRelativeToCamera; internal static ConfigEntry InvertRight; internal static ConfigEntry CameraMode; internal static ConfigEntry RotateVisuals; internal static ConfigEntry VisualRestoreSpeed; internal static ConfigEntry RotateBody; internal static ConfigEntry BodyRotationSpeed; internal static ConfigEntry CameraRotationSpeed; internal static ConfigEntry LargeTiltSlowdown; internal static ConfigEntry OverrideTime; internal static ConfigEntry HeroLanding; internal static ConfigEntry ClimbDebug; private static bool _done; internal static WallClimb? Climb; private static void Setup() { if (!_done) { _done = true; ConfigFile config = ((BaseUnityPlugin)RepoWallClimb.Instance).Config; Enabled = config.Bind("Climb", "Enabled", true, "壁登りを使う。"); ToggleKey = config.Bind("Climb", "ToggleKey", (KeyCode)118, "機能のオン/オフ。"); ReleaseKey = config.Bind("Climb", "ReleaseKey", (KeyCode)99, "壁から剥がれる。"); RequireCrouch = config.Bind("Climb", "RequireCrouch", false, "★既定 false(課題15)★ しゃがんでいる時だけ吸着する。true にすると壁登りとしゃがみが結びつき、乗り換えのたびに姿勢を切り替える必要が出て操作が分断される。誤発動の抑制は RequireIntent / RequireFullBody / MinSteepness が担う。"); HoldRequiresCrouch = config.Bind("Climb", "HoldRequiresCrouch", false, "張り付いた後もしゃがみ続けないと剥がれるようにする。false なら張り付いている間の姿勢は一切問わない。"); BlockWhenCrouching = config.Bind("Climb", "BlockWhenCrouching", true, "★課題19★ しゃがんでいる間は壁に張り付かない。張り付いている最中にしゃがんだら剥がれる。しゃがみを高速移動専用にして、壁沿いを速く走り抜けたい時に壁へ吸われないようにするための設定。RequireCrouch=true の時は矛盾するのでこちらは無視される。"); RequireIntent = config.Bind("Climb", "RequireIntent", true, "★しゃがみの代わりの誤発動対策(課題15-C)★ 壁へ向かう入力があるか、接地していない時だけ吸着する。壁に沿って歩いただけでは吸い付かない。姿勢は問わない。"); IntentDot = config.Bind("Climb", "IntentDot", 0.25f, "「壁へ向かっている」とみなす一致度。1 で正面から真っ直ぐ向かった時だけ。下げるほど吸着しやすい。"); CastRadius = config.Bind("ClimbDetect", "CastRadius", 0.3f, "判定球の半径。"); CastBackOff = config.Bind("ClimbDetect", "CastBackOff", 0.5f, "★重要★ キャストを撃つ前に進行方向の逆へ下げる距離。SphereCast は開始位置で重なっている Collider を検出しないため、壁に吸い付いた状態では 0 だと判定が丸ごと失敗する。"); AttachRange = config.Bind("ClimbDetect", "AttachRange", 0.6f, "吸着する距離。"); HoldRange = config.Bind("ClimbDetect", "HoldRange", 1.4f, "吸着を維持できる距離。"); HoldRayOffset = config.Bind("ClimbDetect", "HoldRayOffset", 0.45f, "維持キャストを上下左右へ振る量。壁の継ぎ目や端で1 本外れても、他が当たれば維持できる。0 で中央 1 本だけ。"); HoldMinDot = config.Bind("ClimbDetect", "HoldMinDot", 0.3f, "維持キャストが当たった面を「同じ壁」とみなす一致度。"); FollowMaxAngle = config.Bind("ClimbDetect", "FollowMaxAngle", 25f, "曲面へなめらかに追従する上限角。これを超える差は乗り換え扱い。"); MinSteepness = config.Bind("ClimbDetect", "MinSteepness", 0.6f, "どれだけ急な面に吸着できるか。1 で完全な垂直のみ。★吸着のみに掛かる。維持と乗り換えには掛からない。"); EyeHeight = config.Bind("ClimbDetect", "EyeHeight", 0.9f, "主レイの高さ。"); DetachCooldown = config.Bind("ClimbDetect", "DetachCooldown", 0.8f, "剥がれてから再吸着までの秒数。"); RequireFullBody = config.Bind("ClimbDetect", "RequireFullBody", true, "体全体が接する面だけを壁とみなす。柱やテーブルを除外。"); BodyLow = config.Bind("ClimbDetect", "BodyLow", 0.35f, "体の下端の高さ。"); BodyHigh = config.Bind("ClimbDetect", "BodyHigh", 1.6f, "体の上端の高さ。"); BodyWidth = config.Bind("ClimbDetect", "BodyWidth", 0.4f, "体の幅の半分。"); SwitchMinAngle = config.Bind("ClimbSwitch", "MinAngle", 20f, "これ未満の角度差は乗り換えではなく追従で処理する。"); SwitchMaxAngle = config.Bind("ClimbSwitch", "MaxAngle", 100f, "今の壁から何度まで離れた面へ乗り移れるか。"); SwitchRange = config.Bind("ClimbSwitch", "Range", 0.9f, "壁を掴んだまま乗り換え先を探す距離。「角に達した」と言える近さにしておく。大きくすると遠くの壁を見ただけで移ってしまう。壁を見失っている時だけは AttachRange の 2 倍まで探す。"); SwitchCooldown = config.Bind("ClimbSwitch", "Cooldown", 0.5f, "壁を乗り換えてから次までの秒数。内角ではこの 2 倍待つ。"); SwitchRevertWindow = config.Bind("ClimbSwitch", "RevertWindow", 0.7f, "乗り換えてからこの秒数の間に新しい面を見失ったら、剥がれる前に元の面へ戻して維持を試す。内角では使わない。"); SwitchMaxFloorDot = config.Bind("ClimbSwitch", "MaxFloorDot", 0.5f, "乗り換え先として許す面の上向き度の上限。天井やオーバーハングは許し、上を向いた床だけを弾く。"); EdgeWrap = config.Bind("ClimbEdge", "Enabled", true, "★課題16★ 面が途切れた縁で、その穴に隣接する面へ回り込む。ドアの開口部に達したら枠の内壁へ、壁の上端に達したら天面へ張り付いて這い進む。穴を渡るのではなく、穴の形をなぞる。"); EdgeReach = config.Bind("ClimbEdge", "Reach", 0.55f, "進行方向のどれだけ先を見て「面が途切れている」と判断するか。小さいと縁に着いてから気付くので回り込みが間に合わない。大きいと手前で反応しすぎる。"); EdgeDepth = config.Bind("ClimbEdge", "Depth", 0.5f, "回り込み先を探す時、今の面よりどれだけ奥へ入った位置から撃つか。ドア枠の内壁は壁の厚みの中にあるので、面より奥に入らないと当たらない。"); EdgeWindow = config.Bind("ClimbEdge", "Window", 0.35f, "縁を回り込んでいる間、維持判定と壁への吸着を止める秒数。回り込んだ直後はまだ新しい面の裏側にいるため、吸着を掛けると逆向きに押されてしまう。"); EdgeAssist = config.Bind("ClimbEdge", "Assist", 3f, "回り込む時に進行方向へ足す速度(m/s)。縁を乗り越えるきっかけになる。0 で慣性だけに任せる。"); NormalBlendSpeed = config.Bind("ClimbSwitch", "NormalBlendSpeed", 10f, "確定した法線へ、実際に使う法線が追いつく速さ。小さいほど乗り換えが滑らかになるが、反応が鈍くなる。0 で補間なし(即座に切り替わる)。"); CarryVelocity = config.Bind("ClimbSwitch", "CarryVelocity", true, "乗り換え時に速度を新しい面へ回して引き継ぐ。角を曲がる時に勢いが途切れなくなる。"); GraceSeconds = config.Bind("ClimbSwitch", "GraceSeconds", 0.35f, "今の壁を見失ってから剥がれるまでの猶予(秒)。★v7 でフレーム数から秒へ変更した。旧 GraceFrames=12 は 144fps だと 0.08 秒しかなく、一瞬の判定漏れで剥がれていた。フレームレートに左右されないよう秒で持つ。"); UseContacts = config.Bind("ClimbDetect", "UseContacts", true, "★推奨 true★ 実際の接触点(OnCollisionStay)を維持判定の主軸にする。接触法線は判定球の食い込みと無関係に正しい値を返すので、SphereCast が空振りしても壁を見失わない。"); UseNearProbe = config.Bind("ClimbDetect", "UseNearProbe", true, "接触もキャストも取れない時、周囲の Collider の最近接点から面を推定する最後の手段を使う。"); StickTouchScale = config.Bind("ClimbMove", "StickTouchScale", 0.35f, "既に壁へ接触している時に StickForce へ掛ける倍率。1 未満にすると壁へ押し込む力が減り、判定球が埋まりにくくなる。"); CancelGravity = config.Bind("ClimbMove", "CancelGravity", true, "★重要★ 張り付き中に REPO の重力を打ち消す。REPO は rb.useGravity ではなく PlayerController.FixedUpdate 内の AddForce(0, -CustomGravity*dt, 0, Impulse) で重力を掛けている。useGravity=false では止まらないため、張り付いていても毎秒ずるずる落ちていた。"); UseAntiGravity = config.Bind("ClimbMove", "UseAntiGravity", false, "REPO 自身の PlayerController.AntiGravity(float) を呼ぶ。★既定 false★ v7 で試したところ CustomGravity は 30 のままで、期待した「CustomGravity を 0 にする」動作ではなかった。何をしているか確認できていない API を呼び続ける必要はないので切ってある。CancelGravity 側の打ち消しだけで成立している。"); GravityCancelScale = config.Bind("ClimbMove", "GravityCancelScale", 1f, "重力の打ち消し量。1 で完全に打ち消す。0.9 などにすると、わずかに下へ流れる挙動を残せる。"); ClimbAccel = config.Bind("ClimbMove", "Accel", 60f, "壁面での加速。"); ClimbMaxSpeed = config.Bind("ClimbMove", "MaxSpeed", 4.5f, "壁面での最高速度。"); ClimbDrag = config.Bind("ClimbMove", "Drag", 14f, "壁面での減速。"); StickForce = config.Bind("ClimbMove", "StickForce", 30f, "壁へ引き寄せる力。壁抜けするなら下げる。"); JumpMode = config.Bind("ClimbMove", "JumpMode", ClimbJumpMode.SurfaceLeap, "張り付き中に Space を押した時の挙動。 SurfaceLeap : 剥がれずに壁面を跳ぶ。 Detach : 剥がれて壁を蹴って飛ぶ(従来)。"); LeapMode = config.Bind("ClimbMove", "LeapMode", ClimbLeapMode.Normal, "跳躍の方向(課題17)。 Normal : 壁に対して垂直。法線方向へまっすぐ飛び出す(既定)。面方向の成分はゼロになるので LeapForce は使われない。 WorldUp : ワールドの垂直。真上へ飛ぶ。 Custom : LeapForce(面方向)と LeapOutward(法線方向)を混ぜる。入力方向へ跳ぶ従来の挙動。"); WallJumpForce = config.Bind("ClimbMove", "WallJumpForce", 7f, "JumpMode=Detach の時に壁を蹴る力。0 で Space を無視する。"); LeapForce = config.Bind("ClimbMove", "LeapForce", 5f, "JumpMode=SurfaceLeap の時、壁面に沿って跳ぶ力(m/s)。入力があればその方向、無ければ壁面の上へ跳ぶ。★用途で振り分ける(課題14-C)★ 素早く高所へ登りたい → こちらを上げる(12〜15)。壁から壁へ飛び移りたい → LeapOutward を上げる。回避に使いたい → 両方 4〜6 で短く速く。"); LeapOutward = config.Bind("ClimbMove", "LeapOutward", 9f, "跳躍時に壁から離れる速度(m/s)。StickForce で引き戻される。★見え方の目安★ 離れる距離はおよそ LeapOutward^2 / (2 * StickForce) [m]。既定(9, StickForce=30) で約 1.35m。v8 から跳躍中は維持判定を止めているので、HoldRange(1.4) を超えても剥がれない。0 にすると壁に貼り付いたまま加速するだけになる。"); LeapWindow = config.Bind("ClimbMove", "LeapWindow", 0.5f, "跳躍の勢いを保つ秒数。この間は加速・減速と法線方向の速度打ち消しを止める。短いとすぐ通常制御に戻され、勢いが消える。"); LeapCooldown = config.Bind("ClimbMove", "LeapCooldown", 0.5f, "次に跳べるようになるまでの秒数。跳躍らしさのために LeapWindow 以上にしておく。"); MoveRelativeToCamera = config.Bind("ClimbMove", "RelativeToCamera", true, "true: W が「画面の前」になる(カメラを壁面へ投影)。false: W が常に「壁面の上」。切り分け用。"); InvertRight = config.Bind("ClimbMove", "InvertRight", false, "D で左へ動く場合だけ true にする。右方向を反転する。"); CameraMode = config.Bind("ClimbCamera", "Mode", ClimbCameraMode.WallUp, "Off : Frame を動かさない。移動だけを切り分けて確認する時用。 WallUp : カメラの上方向を壁の法線へ倒す(壁に立っている視点)。 どちらでも Aim(Yaw/Pitch) には一切触らない。"); RotateVisuals = config.Bind("ClimbCamera", "RotateVisuals", true, "★課題11-D★ 見た目(PlayerAvatarVisuals.meshParent)だけを壁の向きへ倒す。コライダーも物理も一切変えないので、剥がれた後の着地は通常どおり。REPO 自身が visualFollowLerp で見た目を遅延追従させている以上、見た目と本体の姿勢がズレること自体は想定内の設計。"); VisualRestoreSpeed = config.Bind("ClimbCamera", "VisualRestoreSpeed", 14f, "剥がれた後に見た目が縦へ戻る速さ(課題11-C)。カメラより速くしておくと、落下中に傾いたまま着地しにくい。"); RotateBody = config.Bind("ClimbCamera", "RotateBody", false, "身体(コライダー)そのものを壁の向きへ倒す。★既定 false のまま★ 物理姿勢が変わるので着地位置が乱れる。見た目だけで足りるなら RotateVisuals を使うこと。"); BodyRotationSpeed = config.Bind("ClimbCamera", "BodyRotationSpeed", 15f, "身体が回る速度。RotateBody=true の時のみ有効。"); CameraRotationSpeed = config.Bind("ClimbCamera", "CameraRotationSpeed", 8f, "カメラ Pivot が壁の向きへ倒れる速度。"); LargeTiltSlowdown = config.Bind("ClimbCamera", "LargeTiltSlowdown", 0.45f, "傾きが大きい時に回転速度へ掛ける倍率。天井への 180 度近い反転をゆっくりにして酔いを抑える。1 で可変なし。"); OverrideTime = config.Bind("ClimbCamera", "OverrideTime", 0.1f, "OverrideTurnRotation に渡す追従時間。"); HeroLanding = config.Bind("HeroLanding", "Enabled", true, "落下によるタンブルを無効化する。攻撃によるタンブルは残る。"); ClimbDebug = config.Bind("Climb", "Debug", false, "壁登りのログを出す。"); } } [HarmonyPostfix] [HarmonyPatch("Start")] private static void Start_Post(PlayerController __instance) { Setup(); if ((Object)(object)((Component)__instance).gameObject.GetComponent() == (Object)null) { Climb = ((Component)__instance).gameObject.AddComponent(); RepoWallClimb.Logger.LogInfo((object)"WallClimb v10 attached. (V=toggle)"); } } [HarmonyPostfix] [HarmonyPatch("Update")] private static void Update_Post(PlayerController __instance) { if ((Object)(object)Climb != (Object)null) { Climb.Tick(__instance); } } [HarmonyPostfix] [HarmonyPatch("FixedUpdate")] private static void Fixed_Post(PlayerController __instance) { if (HeroLanding != null && HeroLanding.Value && (Object)(object)__instance.CollisionController != (Object)null) { __instance.CollisionController.fallDistance = 0f; } if ((Object)(object)Climb != (Object)null) { Climb.Physics(__instance); } } } public class WallClimb : MonoBehaviour { private struct WallBasis { public Vector3 normal; public Vector3 up; public Vector3 right; public Vector3 forward; } private enum SurfaceUse { Attach, Switch, Hold } private const string FrameName = "WallClimbCameraFrame"; private PlayerController? _pc; private Rigidbody? _rb; private Collider? _col; private LayerMask _mask; private bool _enabled = true; private bool _on; private Vector3 _normal = Vector3.up; private Vector3 _viewNormal = Vector3.up; private WallBasis _basis; private float _blockUntil; private float _switchUntil; private float _lostSince = -1f; private Vector2 _input; private bool _wantJump; private float _moveLogAt; private Vector3 _contactNormal; private float _contactStamp = -999f; private int _contactHits; private float _contactBestDot; private float _touchStamp = -999f; private Vector3 _altNormal; private float _altStamp = -999f; private int _altHits; private float _altBestAng = 999f; private readonly Collider[] _overlap = (Collider[])(object)new Collider[16]; private float _surfaceDist = 1f; private Vector3 _prevNormal; private bool _hasPrev; private float _revertUntil; private Vector3 _leftNormal; private float _noReturnUntil; private bool _hasCarry; private Quaternion _carry = Quaternion.identity; private bool _wantLeap; private float _leapUntil; private float _leapReadyAt; private float _lastLeapAt = -99f; private bool _edgeWrapped; private float _edgeUntil; private Vector3 _edgeDir; private bool _edgeAssistPending; private string _holdInfo = "-"; private readonly Vector3[] _holdOrigins = (Vector3[])(object)new Vector3[5]; private Transform? _frame; private Transform? _aimParent; private bool _frameOwned; private Quaternion _currentBody = Quaternion.identity; private Quaternion _tilt = Quaternion.identity; private bool _restoring; private Transform? _mesh; private Quaternion _visualTilt = Quaternion.identity; private Quaternion _visualBase = Quaternion.identity; private Quaternion _lastVisualWrite = Quaternion.identity; private bool _hasVisualWrite; private CollisionDetectionMode _savedCdm; private bool _cdmChanged; private PhysicMaterial? _savedMat; private PhysicMaterial? _slipMat; private bool _matChanged; private readonly Vector3[] _switchDirs = (Vector3[])(object)new Vector3[3]; private float _switchLogAt; private Vector3 Eye => ((Component)this).transform.position + Vector3.up * WallClimbPatch2.EyeHeight.Value; public bool Attached => _on; private void Awake() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) ((Component)this).TryGetComponent(ref _pc); ((Component)this).TryGetComponent(ref _rb); _col = ((Component)this).GetComponent(); _mask = LayerMask.op_Implicit(LayerMask.GetMask(new string[3] { "Default", "Environment", "NavmeshOnly" })); _slipMat = new PhysicMaterial("WallClimbSlip") { dynamicFriction = 0f, staticFriction = 0f, bounciness = 0f, frictionCombine = (PhysicMaterialCombine)2, bounceCombine = (PhysicMaterialCombine)2 }; _basis = BuildBasis(Vector3.up); } private void Log(string m) { if (WallClimbPatch2.ClimbDebug.Value) { RepoWallClimb.Logger.LogInfo((object)("[Climb] " + m)); } } private static string Fmt(Vector3 v) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) return $"({v.x:F2},{v.y:F2},{v.z:F2})"; } private WallBasis BuildBasis(Vector3 normal) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_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_0051: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) WallBasis result = new WallBasis { normal = ((Vector3)(ref normal)).normalized }; Vector3 val = Vector3.ProjectOnPlane(Vector3.up, result.normal); if (((Vector3)(ref val)).sqrMagnitude < 0.05f) { Vector3 val2 = Vector3.ProjectOnPlane(_basis.up, result.normal); if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f) { val = val2; } } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.ProjectOnPlane(((Component)this).transform.forward, result.normal); } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.ProjectOnPlane(Vector3.forward, result.normal); } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.ProjectOnPlane(Vector3.right, result.normal); } result.up = ((Vector3)(ref val)).normalized; Vector3 val3 = Vector3.Cross(result.normal, result.up); result.right = ((Vector3)(ref val3)).normalized; result.forward = -result.normal; if (WallClimbPatch2.InvertRight.Value) { result.right = -result.right; } return result; } private void UpdateView(float dt) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) float value = WallClimbPatch2.NormalBlendSpeed.Value; if (value <= 0f || Vector3.Angle(_viewNormal, _normal) < 0.05f) { _viewNormal = _normal; } else { Vector3 val = Vector3.Slerp(_viewNormal, _normal, 1f - Mathf.Exp((0f - value) * dt)); _viewNormal = ((Vector3)(ref val)).normalized; } _basis = BuildBasis(_viewNormal); } private void EnsureFrame() { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_frame != (Object)null) { return; } CameraAim instance = CameraAim.Instance; if ((Object)(object)instance == (Object)null) { return; } Transform transform = ((Component)instance).transform; Transform parent = transform.parent; if ((Object)(object)parent == (Object)null) { return; } if (((Object)parent).name == "WallClimbCameraFrame") { _frame = parent; _aimParent = parent.parent; _frameOwned = false; Log("frame reused (aim already parented)"); return; } Transform val = parent.Find("WallClimbCameraFrame"); if ((Object)(object)val != (Object)null) { _frame = val; _aimParent = parent; _frameOwned = false; transform.SetParent(_frame, false); Log("frame reused (re-parented aim)"); return; } GameObject val2 = new GameObject("WallClimbCameraFrame"); _frame = val2.transform; _frame.SetParent(parent, false); _frame.localPosition = Vector3.zero; _frame.localRotation = Quaternion.identity; _frame.localScale = Vector3.one; _frameOwned = true; _aimParent = parent; transform.SetParent(_frame, false); Log("frame inserted under " + ((Object)parent).name); } private void OnDestroy() { CameraAim instance = CameraAim.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)_aimParent != (Object)null) { ((Component)instance).transform.SetParent(_aimParent, false); } if (_frameOwned && (Object)(object)_frame != (Object)null) { Object.Destroy((Object)(object)((Component)_frame).gameObject); } } public void Tick(PlayerController pc) { //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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) if (_pc == null) { _pc = pc; } EnsureFrame(); UpdateView(Time.deltaTime); if (!WallClimbPatch2.Enabled.Value) { if (_on) { Detach(DetachReason.disabled); } return; } float num = Input.GetAxisRaw("Horizontal"); float num2 = Input.GetAxisRaw("Vertical"); if (Mathf.Abs(num) < 0.01f && Mathf.Abs(num2) < 0.01f) { if (Input.GetKey((KeyCode)97)) { num -= 1f; } if (Input.GetKey((KeyCode)100)) { num += 1f; } if (Input.GetKey((KeyCode)115)) { num2 -= 1f; } if (Input.GetKey((KeyCode)119)) { num2 += 1f; } } _input = new Vector2(num, num2); if (Input.GetKeyDown(WallClimbPatch2.ToggleKey.Value)) { _enabled = !_enabled; RepoWallClimb.Logger.LogInfo((object)(_enabled ? "WallClimb ON" : "WallClimb OFF")); if (!_enabled && _on) { Detach(DetachReason.disabled); } } if (!_enabled) { return; } Transform cam = (((Object)(object)_pc != (Object)null && (Object)(object)_pc.cameraGameObject != (Object)null) ? _pc.cameraGameObject.transform : ((Component)this).transform); if (_on) { if (Input.GetKeyDown(WallClimbPatch2.ReleaseKey.Value)) { Detach(DetachReason.release_key); return; } if (SemiFunc.InputDown((InputKey)1)) { if (WallClimbPatch2.JumpMode.Value == ClimbJumpMode.Detach) { if (WallClimbPatch2.WallJumpForce.Value > 0f) { _wantJump = true; Detach(DetachReason.jump); return; } } else if (Time.time >= _leapReadyAt) { _wantLeap = true; } } if ((Object)(object)_pc != (Object)null && (Object)(object)_pc.playerAvatarScript != (Object)null && _pc.playerAvatarScript.isTumbling) { Detach(DetachReason.tumble); } else if (WallClimbPatch2.HoldRequiresCrouch.Value && WallClimbPatch2.RequireCrouch.Value && (Object)(object)_pc != (Object)null && !_pc.Crouching) { Detach(DetachReason.stood_up); } else if (Blocked()) { Detach(DetachReason.crouched); } else if (Time.time < _leapUntil) { _lostSince = -1f; _holdInfo = "leap"; } else if (Time.time < _edgeUntil) { _lostSince = -1f; _holdInfo = "edge"; } else if (!KeepWall()) { Detach(DetachReason.surface_lost); } } else if (Time.time >= _blockUntil) { TryAttach(cam); } } private bool Cast(Vector3 origin, Vector3 dir, float range, SurfaceUse use, out RaycastHit hit) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_008d: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_00e5: Unknown result type (might be due to invalid IL or missing references) hit = default(RaycastHit); if (((Vector3)(ref dir)).sqrMagnitude < 1E-06f) { return false; } dir = ((Vector3)(ref dir)).normalized; float num = Mathf.Max(0f, WallClimbPatch2.CastBackOff.Value); if (use == SurfaceUse.Hold) { float num2 = WallClimbPatch2.CastRadius.Value + 0.2f - _surfaceDist; if (num2 > num) { num = num2; } } Vector3 val = origin - dir * num; if (!Physics.SphereCast(val, WallClimbPatch2.CastRadius.Value, dir, ref hit, range + num, LayerMask.op_Implicit(_mask), (QueryTriggerInteraction)1)) { return false; } if (use != SurfaceUse.Hold && Vector3.Dot(((RaycastHit)(ref hit)).point - origin, dir) < 0f - WallClimbPatch2.CastRadius.Value) { return false; } return Accept(hit, use); } private static bool Accept(RaycastHit hit, SurfaceUse use) { //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) Collider collider = ((RaycastHit)(ref hit)).collider; if ((Object)(object)collider == (Object)null) { return false; } if (((Component)collider).CompareTag("Player") || ((Component)collider).CompareTag("Enemy") || ((Component)collider).CompareTag("Phys Grab Object")) { return false; } float num = Vector3.Dot(((RaycastHit)(ref hit)).normal, Vector3.up); return use switch { SurfaceUse.Attach => Mathf.Abs(num) <= 1f - WallClimbPatch2.MinSteepness.Value, SurfaceUse.Switch => num <= WallClimbPatch2.SwitchMaxFloorDot.Value, _ => true, }; } private bool HoldCast(Vector3 n, Vector3 upAxis, Vector3 rightAxis, out Vector3 normal, out int hits, out int count) { //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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) normal = Vector3.zero; float value = WallClimbPatch2.HoldRayOffset.Value; _holdOrigins[0] = Eye; _holdOrigins[1] = Eye + upAxis * value; _holdOrigins[2] = Eye - upAxis * value; _holdOrigins[3] = Eye + rightAxis * value; _holdOrigins[4] = Eye - rightAxis * value; count = ((!(value > 0.01f)) ? 1 : _holdOrigins.Length); hits = 0; float num = -2f; float value2 = WallClimbPatch2.HoldMinDot.Value; float num2 = float.MaxValue; for (int i = 0; i < count; i++) { if (!Cast(_holdOrigins[i], -n, WallClimbPatch2.HoldRange.Value, SurfaceUse.Hold, out var hit)) { continue; } float num3 = Vector3.Dot(((RaycastHit)(ref hit)).normal, n); if (num3 < value2) { continue; } hits++; if (num3 > num) { num = num3; normal = ((RaycastHit)(ref hit)).normal; } if (i == 0) { float num4 = Vector3.Dot(((RaycastHit)(ref hit)).point - Eye, -n); if (num4 < num2) { num2 = num4; } } } if (num2 < float.MaxValue) { _surfaceDist = Mathf.Max(0f, num2); } return hits > 0; } private void OnCollisionStay(Collision c) { //IL_00d8: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) if (!_on || !WallClimbPatch2.UseContacts.Value) { return; } Collider collider = c.collider; if ((Object)(object)collider == (Object)null || ((1 << ((Component)collider).gameObject.layer) & ((LayerMask)(ref _mask)).value) == 0 || ((Component)collider).CompareTag("Player") || ((Component)collider).CompareTag("Enemy") || ((Component)collider).CompareTag("Phys Grab Object")) { return; } _touchStamp = Time.fixedTime; if (_contactStamp != Time.fixedTime) { _contactStamp = Time.fixedTime; _contactHits = 0; _contactBestDot = -2f; _contactNormal = Vector3.zero; _altStamp = Time.fixedTime; _altHits = 0; _altBestAng = 999f; _altNormal = Vector3.zero; } float value = WallClimbPatch2.HoldMinDot.Value; int contactCount = c.contactCount; for (int i = 0; i < contactCount; i++) { ContactPoint contact = c.GetContact(i); Vector3 normal = ((ContactPoint)(ref contact)).normal; float num = Vector3.Dot(normal, _normal); if (num >= value) { _contactHits++; if (num > _contactBestDot) { _contactBestDot = num; _contactNormal = normal; } } else { if (Vector3.Dot(normal, Vector3.up) > WallClimbPatch2.SwitchMaxFloorDot.Value) { continue; } float num2 = Vector3.Angle(normal, _normal); if (!(num2 < WallClimbPatch2.SwitchMinAngle.Value) && !(num2 > WallClimbPatch2.SwitchMaxAngle.Value)) { _altHits++; if (num2 < _altBestAng) { _altBestAng = num2; _altNormal = normal; } } } } } private bool Fresh(float stamp) { return stamp > 0f && Time.fixedTime - stamp <= Time.fixedDeltaTime * 3f; } private bool ContactHold(out Vector3 normal) { //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) normal = _contactNormal; return WallClimbPatch2.UseContacts.Value && _contactHits > 0 && Fresh(_contactStamp); } private bool NearProbe(out Vector3 normal) { //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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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_0136: Unknown result type (might be due to invalid IL or missing references) normal = Vector3.zero; if (!WallClimbPatch2.UseNearProbe.Value) { return false; } Vector3 eye = Eye; float num = WallClimbPatch2.CastRadius.Value + 0.5f; int num2 = Physics.OverlapSphereNonAlloc(eye, num, _overlap, LayerMask.op_Implicit(_mask), (QueryTriggerInteraction)1); float num3 = WallClimbPatch2.HoldMinDot.Value; bool result = false; for (int i = 0; i < num2; i++) { Collider val = _overlap[i]; if ((Object)(object)val == (Object)null || ((Component)val).transform.IsChildOf(((Component)this).transform) || ((Component)val).CompareTag("Player") || ((Component)val).CompareTag("Enemy") || ((Component)val).CompareTag("Phys Grab Object")) { continue; } Vector3 val2 = val.ClosestPoint(eye); Vector3 val3 = eye - val2; if (!(((Vector3)(ref val3)).sqrMagnitude < 1E-06f)) { Vector3 normalized = ((Vector3)(ref val3)).normalized; float num4 = Vector3.Dot(normalized, _normal); if (!(num4 <= num3)) { num3 = num4; normal = normalized; result = true; } } } return result; } private void TryAttach(Transform cam) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00c8: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0148: 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) if ((Object)(object)_pc == (Object)null || ((Object)(object)_pc.playerAvatarScript != (Object)null && _pc.playerAvatarScript.isTumbling) || SemiFunc.InputHold((InputKey)10) || (WallClimbPatch2.RequireCrouch.Value && !_pc.Crouching) || Blocked() || WebSwing.Active) { return; } Vector3 forward = cam.forward; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(forward.x, 0f, forward.z); Vector3[] array = (Vector3[])(object)new Vector3[2] { val, forward }; for (int i = 0; i < array.Length; i++) { Vector3 val2 = array[i]; if (!(((Vector3)(ref val2)).sqrMagnitude < 0.01f)) { Vector3 normalized = ((Vector3)(ref val2)).normalized; if (Cast(Eye, normalized, WallClimbPatch2.AttachRange.Value, SurfaceUse.Attach, out var hit) && FullBody(normalized) && HasIntent(cam, ((RaycastHit)(ref hit)).normal)) { Attach(((RaycastHit)(ref hit)).normal); break; } } } } private bool Blocked() { return WallClimbPatch2.BlockWhenCrouching.Value && !WallClimbPatch2.RequireCrouch.Value && (Object)(object)_pc != (Object)null && _pc.Crouching; } internal void ForceDetach() { if (_on) { Detach(DetachReason.web); } } private bool HasIntent(Transform cam, Vector3 normal) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) if (!WallClimbPatch2.RequireIntent.Value) { return true; } if ((Object)(object)_pc != (Object)null && (Object)(object)_pc.CollisionController != (Object)null && !_pc.CollisionController.Grounded) { return true; } if (((Vector2)(ref _input)).sqrMagnitude < 0.01f) { return false; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(cam.forward.x, 0f, cam.forward.z); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(cam.right.x, 0f, cam.right.z); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { return false; } Vector3 val3 = ((Vector3)(ref val)).normalized * _input.y + ((Vector3)(ref val2)).normalized * _input.x; Vector3 normalized = ((Vector3)(ref val3)).normalized; return Vector3.Dot(normalized, -normal) >= WallClimbPatch2.IntentDot.Value; } private bool KeepWall() { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) Vector3 normal; int hits; int count; bool flag = HoldCast(_normal, _basis.up, _basis.right, out normal, out hits, out count); Vector3 normal2; bool flag2 = ContactHold(out normal2); Vector3 val = (flag ? normal : normal2); bool flag3 = flag || flag2; string text = (flag ? "ray" : (flag2 ? "contact" : "-")); if (!flag3 && NearProbe(out var normal3)) { val = normal3; flag3 = true; text = "near"; } _holdInfo = $"{text} r{hits}/{count} c{(flag2 ? _contactHits : 0)}"; if (TrySwitch(!flag3)) { return true; } if (flag3) { _lostSince = -1f; float num = Vector3.Angle(_normal, val); if (num > 0.5f && num < WallClimbPatch2.FollowMaxAngle.Value) { Vector3 val2 = Vector3.Slerp(_normal, val, 0.2f); _normal = ((Vector3)(ref val2)).normalized; } return true; } if (_hasPrev && Time.time < _revertUntil) { WallBasis wallBasis = BuildBasis(_prevNormal); if (HoldCast(wallBasis.normal, wallBasis.up, wallBasis.right, out var normal4, out var hits2, out var count2)) { _hasPrev = false; _lostSince = -1f; SetNormal(normal4, $"REVERT (new wall lost, hold={hits2}/{count2})"); return true; } } if (_lostSince < 0f) { _lostSince = Time.time; } return Time.time - _lostSince <= WallClimbPatch2.GraceSeconds.Value; } private void SwitchReject(string why) { if (!(Time.time < _switchLogAt)) { _switchLogAt = Time.time + 1.5f; Log("SWITCH rejected: " + why); } } private bool SurfaceContinues(Vector3 moveDir, out float gap) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_008a: Unknown result type (might be due to invalid IL or missing references) gap = 0f; Vector3 val = Eye + moveDir * WallClimbPatch2.EdgeReach.Value; if (!Cast(val, -_normal, WallClimbPatch2.HoldRange.Value, SurfaceUse.Hold, out var hit)) { return false; } if (Vector3.Dot(((RaycastHit)(ref hit)).normal, _normal) < WallClimbPatch2.HoldMinDot.Value) { return false; } gap = Vector3.Dot(((RaycastHit)(ref hit)).point - val, -_normal); return true; } private bool EdgeWrapProbe(Vector3 moveDir, out Vector3 normal, out string what) { //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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_0127: 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) normal = Vector3.zero; what = "?"; float value = WallClimbPatch2.EdgeReach.Value; float value2 = WallClimbPatch2.EdgeDepth.Value; Vector3 origin = Eye + moveDir * (value + value2) - _normal * value2; if (Cast(origin, -moveDir, value + value2, SurfaceUse.Switch, out var hit) && Vector3.Angle(((RaycastHit)(ref hit)).normal, _normal) >= WallClimbPatch2.SwitchMinAngle.Value) { normal = ((RaycastHit)(ref hit)).normal; what = (((Object)(object)((RaycastHit)(ref hit)).collider != (Object)null) ? ((Object)((RaycastHit)(ref hit)).collider).name : "?"); return true; } Vector3 origin2 = Eye + moveDir * (value + value2); if (Cast(origin2, -_normal, value + value2, SurfaceUse.Switch, out var hit2) && Vector3.Angle(((RaycastHit)(ref hit2)).normal, _normal) >= WallClimbPatch2.SwitchMinAngle.Value) { normal = ((RaycastHit)(ref hit2)).normal; what = (((Object)(object)((RaycastHit)(ref hit2)).collider != (Object)null) ? ((Object)((RaycastHit)(ref hit2)).collider).name : "?"); return true; } return false; } private bool TrySwitch(bool lost) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: 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_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: 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_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_0320: 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_033b: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Unknown result type (might be due to invalid IL or missing references) //IL_0567: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: 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_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_05b2: Unknown result type (might be due to invalid IL or missing references) //IL_05b7: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_0677: Unknown result type (might be due to invalid IL or missing references) //IL_067a: Unknown result type (might be due to invalid IL or missing references) //IL_0691: Unknown result type (might be due to invalid IL or missing references) //IL_0696: Unknown result type (might be due to invalid IL or missing references) //IL_0699: Unknown result type (might be due to invalid IL or missing references) //IL_069b: Unknown result type (might be due to invalid IL or missing references) //IL_06a1: Unknown result type (might be due to invalid IL or missing references) //IL_06a3: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_072c: Unknown result type (might be due to invalid IL or missing references) //IL_072e: Unknown result type (might be due to invalid IL or missing references) //IL_072f: Unknown result type (might be due to invalid IL or missing references) //IL_0734: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_077d: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_044d: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_07d1: Unknown result type (might be due to invalid IL or missing references) _edgeWrapped = false; if (Time.time < _switchUntil) { if (((Vector2)(ref _input)).sqrMagnitude > 0.01f) { SwitchReject($"cooldown {_switchUntil - Time.time:F2}s remaining"); } return false; } float num = (lost ? (WallClimbPatch2.AttachRange.Value * 2f) : WallClimbPatch2.SwitchRange.Value); bool flag = false; Vector3 val = Vector3.zero; Vector3 val2 = Vector3.zero; string text = "?"; string arg = "?"; float num2; if (!((Object)(object)_rb != (Object)null)) { num2 = 0f; } else { Vector3 val3 = Vector3.ProjectOnPlane(_rb.velocity, _basis.normal); num2 = ((Vector3)(ref val3)).magnitude; } float num3 = num2; if (!(((Vector2)(ref _input)).sqrMagnitude > 0.01f) && !(num3 > 1f) && !lost) { return false; } if (WallClimbPatch2.UseContacts.Value && _altHits > 0 && Fresh(_altStamp)) { flag = true; val = _altNormal; text = "contact"; arg = "contact"; val2 = _basis.up * _input.y + _basis.right * _input.x; } if (!flag && WallClimbPatch2.EdgeWrap.Value) { Vector3 val4 = _basis.up * _input.y + _basis.right * _input.x; if (((Vector3)(ref val4)).sqrMagnitude < 0.01f && (Object)(object)_rb != (Object)null) { val4 = Vector3.ProjectOnPlane(_rb.velocity, _basis.normal); } if (((Vector3)(ref val4)).sqrMagnitude > 0.01f) { val4 = ((Vector3)(ref val4)).normalized; if (!SurfaceContinues(val4, out var _)) { if (EdgeWrapProbe(val4, out Vector3 normal, out string what)) { flag = true; val = normal; val2 = val4; text = "edge"; arg = what; _edgeDir = val4; _edgeWrapped = true; Log($"EDGE detected ahead={WallClimbPatch2.EdgeReach.Value:F2}m " + "current n=" + Fmt(_normal) + " dir=" + Fmt(val4)); } else { SwitchReject("EDGE ahead but no surface to wrap onto (dir=" + Fmt(val4) + ")"); } } } } if (!flag) { Vector3 val5 = _basis.up * _input.y + _basis.right * _input.x; Vector3 val6 = (((Object)(object)_rb != (Object)null) ? Vector3.ProjectOnPlane(_rb.velocity, _basis.normal) : Vector3.zero); _switchDirs[0] = val5; _switchDirs[1] = ((((Vector3)(ref val6)).sqrMagnitude > 1f) ? val6 : Vector3.zero); _switchDirs[2] = ((_input.y > 0.01f || lost) ? _basis.up : Vector3.zero); for (int i = 0; i < _switchDirs.Length; i++) { if (flag) { break; } Vector3 val7 = _switchDirs[i]; if (!(((Vector3)(ref val7)).sqrMagnitude < 0.01f)) { val7 = ((Vector3)(ref val7)).normalized; if (Cast(Eye, val7, num, SurfaceUse.Switch, out var hit) && !(Vector3.Dot(((RaycastHit)(ref hit)).point - Eye, val7) > num)) { flag = true; val = ((RaycastHit)(ref hit)).normal; val2 = val7; text = i switch { 1 => "velocity", 0 => "input", _ => "wallup", }; arg = (((Object)(object)((RaycastHit)(ref hit)).collider != (Object)null) ? ((Object)((RaycastHit)(ref hit)).collider).name : "?"); } } } } if (!flag) { if (((Vector2)(ref _input)).sqrMagnitude > 0.01f) { SwitchReject($"no candidate within {num:F2}m " + $"(in=({_input.x:F0},{_input.y:F0}) alt={_altHits})"); } return false; } if (Time.time < _noReturnUntil && Vector3.Angle(val, _leftNormal) < WallClimbPatch2.SwitchMinAngle.Value) { SwitchReject($"just left this face ({_noReturnUntil - Time.time:F2}s)"); return false; } float num4 = Vector3.Angle(_normal, val); if (num4 < WallClimbPatch2.SwitchMinAngle.Value) { SwitchReject($"angle={num4:F0}deg < MinAngle " + $"{WallClimbPatch2.SwitchMinAngle.Value:F0} (via {text})"); return false; } if (num4 > WallClimbPatch2.SwitchMaxAngle.Value) { SwitchReject($"angle={num4:F0}deg > MaxAngle " + $"{WallClimbPatch2.SwitchMaxAngle.Value:F0} (via {text})"); return false; } bool flag2 = ((Vector3)(ref val2)).sqrMagnitude > 0.01f && Vector3.Dot(val, ((Vector3)(ref val2)).normalized) < 0f; Vector3 val8 = (_leftNormal = (_prevNormal = _normal)); _noReturnUntil = Time.time + WallClimbPatch2.SwitchCooldown.Value * 3f; _hasPrev = true; _revertUntil = Time.time + WallClimbPatch2.SwitchRevertWindow.Value; _switchUntil = Time.time + WallClimbPatch2.SwitchCooldown.Value * (flag2 ? 2f : 1f); _lostSince = -1f; _altHits = 0; if (WallClimbPatch2.CarryVelocity.Value) { _carry = Quaternion.FromToRotation(val8, val); _hasCarry = true; } if (_edgeWrapped) { _edgeUntil = Time.time + WallClimbPatch2.EdgeWindow.Value; _edgeAssistPending = WallClimbPatch2.EdgeAssist.Value > 0f; } SetNormal(val, string.Format("SWITCH diff={0:F0}deg {1} ", num4, flag2 ? "inner" : "outer") + $"via={text} lost={lost} to '{arg}'"); if (_edgeWrapped) { Log($"EDGE wrapped to n={Fmt(val)} diff={num4:F0}deg " + (flag2 ? "concave" : "convex")); _edgeWrapped = false; } return true; } private void SetNormal(Vector3 n, string? reason) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) _normal = n; if (reason != null) { WallBasis b = BuildBasis(n); Log(reason); Log("BASIS n=" + Fmt(b.normal) + " up=" + Fmt(b.up) + " right=" + Fmt(b.right) + " fwd=" + Fmt(b.forward) + " " + $"upDotN={Vector3.Dot(b.up, b.normal):F3} " + $"rightDotN={Vector3.Dot(b.right, b.normal):F3}"); float num = Vector3.Angle(Vector3.up, TargetUpFor(b)); Log($"CAMERA mode={WallClimbPatch2.CameraMode.Value} " + $"targetUp={Fmt(TargetUpFor(b))} tilt={num:F0}deg " + $"blendFrom={Vector3.Angle(_viewNormal, n):F0}deg"); } } private bool FullBody(Vector3 dir) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) if (!WallClimbPatch2.RequireFullBody.Value) { return true; } float value = WallClimbPatch2.AttachRange.Value; float num = Mathf.Max(0f, WallClimbPatch2.CastBackOff.Value); float num2 = WallClimbPatch2.CastRadius.Value * 0.6f; Vector3 position = ((Component)this).transform.position; float[] array = new float[2] { WallClimbPatch2.BodyLow.Value, WallClimbPatch2.BodyHigh.Value }; RaycastHit val = default(RaycastHit); foreach (float num3 in array) { if (!Physics.SphereCast(position + Vector3.up * num3 - dir * num, num2, dir, ref val, value + num, LayerMask.op_Implicit(_mask), (QueryTriggerInteraction)1)) { return false; } } Vector3 val2 = Vector3.Cross(Vector3.up, dir); Vector3 normalized = ((Vector3)(ref val2)).normalized; if (((Vector3)(ref normalized)).sqrMagnitude > 0.01f) { float value2 = WallClimbPatch2.BodyWidth.Value; float[] array2 = new float[2] { 0f - value2, value2 }; foreach (float num4 in array2) { if (!Physics.SphereCast(Eye + normalized * num4 - dir * num, num2, dir, ref val, value + num, LayerMask.op_Implicit(_mask), (QueryTriggerInteraction)1)) { return false; } } } return true; } private void Attach(Vector3 n) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) _on = true; _lostSince = -1f; _hasPrev = false; _hasCarry = false; _restoring = false; _holdInfo = "-"; _leapReadyAt = 0f; _leapUntil = 0f; _edgeUntil = 0f; _edgeWrapped = false; _edgeAssistPending = false; _surfaceDist = 1f; _contactHits = 0; _contactStamp = -999f; _touchStamp = -999f; _altHits = 0; _altStamp = -999f; _noReturnUntil = 0f; _switchUntil = Time.time + WallClimbPatch2.SwitchCooldown.Value; _viewNormal = ((Vector3)(ref n)).normalized; SetNormal(n, "ATTACHED"); _basis = BuildBasis(_viewNormal); Log($"GRAVITY custom={(((Object)(object)_pc != (Object)null) ? _pc.CustomGravity : (-1f)):F1} " + $"cancel={WallClimbPatch2.CancelGravity.Value} " + $"scale={WallClimbPatch2.GravityCancelScale.Value:F2}"); if ((Object)(object)_rb != (Object)null) { _rb.useGravity = false; if (!_cdmChanged) { _savedCdm = _rb.collisionDetectionMode; _rb.collisionDetectionMode = (CollisionDetectionMode)2; _cdmChanged = true; } } if ((Object)(object)_col != (Object)null && !_matChanged) { _savedMat = _col.material; _col.material = _slipMat; _matChanged = true; } } private void Detach(DetachReason reason) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: 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_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: 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_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: 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) float num = ((_lostSince < 0f) ? 0f : (Time.time - _lostSince)); Log($"detaching reason={reason} " + $"lost={num:F2}s/{WallClimbPatch2.GraceSeconds.Value:F2}s " + $"hold={_holdInfo} dist={_surfaceDist:F2} " + $"touch={Fresh(_touchStamp)} n={Fmt(_normal)} " + $"in=({_input.x:F0},{_input.y:F0}) " + "crouch=" + (((Object)(object)_pc != (Object)null) ? _pc.Crouching.ToString() : "?")); _on = false; _lostSince = -1f; _hasPrev = false; _hasCarry = false; _wantLeap = false; _edgeUntil = 0f; _edgeWrapped = false; _edgeAssistPending = false; _blockUntil = Time.time + WallClimbPatch2.DetachCooldown.Value; _restoring = true; if ((Object)(object)_rb != (Object)null) { _rb.useGravity = true; if (_cdmChanged) { _rb.collisionDetectionMode = _savedCdm; _cdmChanged = false; } if (_wantJump) { _wantJump = false; Vector3 val = _normal + Vector3.up * 0.5f; Vector3 normalized = ((Vector3)(ref val)).normalized; _rb.AddForce(normalized * WallClimbPatch2.WallJumpForce.Value, (ForceMode)2); } } if (_matChanged && (Object)(object)_col != (Object)null) { _col.material = _savedMat; _matChanged = false; } } private void MoveAxes(Transform cam, out Vector3 axisUp, out Vector3 axisRight, out Vector3 rawF, out Vector3 rawR, out string src) { //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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00e2: Unknown result type (might be due to invalid IL or missing references) axisUp = _basis.up; axisRight = _basis.right; rawF = Vector3.zero; rawR = Vector3.zero; src = "wall"; if (!WallClimbPatch2.MoveRelativeToCamera.Value) { return; } Vector3 normal = _basis.normal; rawF = Vector3.ProjectOnPlane(cam.forward, normal); rawR = Vector3.ProjectOnPlane(cam.right, normal); Vector3 val = rawF; src = "cam"; if (((Vector3)(ref val)).sqrMagnitude < 0.05f) { float num = ((Vector3.Dot(cam.forward, normal) > 0f) ? (-1f) : 1f); val = Vector3.ProjectOnPlane(cam.up, normal) * num; src = "cam.up"; } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { axisUp = _basis.up; axisRight = _basis.right; src = "wall(fallback)"; return; } axisUp = ((Vector3)(ref val)).normalized; Vector3 val2 = Vector3.Cross(normal, axisUp); axisRight = ((Vector3)(ref val2)).normalized; if (WallClimbPatch2.InvertRight.Value) { axisRight = -axisRight; } } public void Physics(PlayerController pc) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0275: 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_04b9: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_060e: Unknown result type (might be due to invalid IL or missing references) //IL_0613: Unknown result type (might be due to invalid IL or missing references) //IL_0615: Unknown result type (might be due to invalid IL or missing references) //IL_061d: Unknown result type (might be due to invalid IL or missing references) //IL_0629: Unknown result type (might be due to invalid IL or missing references) //IL_0631: Unknown result type (might be due to invalid IL or missing references) //IL_0638: Unknown result type (might be due to invalid IL or missing references) //IL_063d: Unknown result type (might be due to invalid IL or missing references) //IL_0642: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_0564: Unknown result type (might be due to invalid IL or missing references) //IL_0576: Unknown result type (might be due to invalid IL or missing references) //IL_058d: Unknown result type (might be due to invalid IL or missing references) //IL_0595: Unknown result type (might be due to invalid IL or missing references) //IL_05e7: 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_0401: Unknown result type (might be due to invalid IL or missing references) //IL_044d: 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_0358: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_06b0: Unknown result type (might be due to invalid IL or missing references) //IL_06b2: Unknown result type (might be due to invalid IL or missing references) //IL_06c1: Unknown result type (might be due to invalid IL or missing references) //IL_06c7: Unknown result type (might be due to invalid IL or missing references) //IL_0668: Unknown result type (might be due to invalid IL or missing references) //IL_0674: Unknown result type (might be due to invalid IL or missing references) //IL_0679: Unknown result type (might be due to invalid IL or missing references) //IL_0681: Unknown result type (might be due to invalid IL or missing references) //IL_0683: Unknown result type (might be due to invalid IL or missing references) //IL_0685: Unknown result type (might be due to invalid IL or missing references) //IL_0694: Unknown result type (might be due to invalid IL or missing references) //IL_069a: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_0735: Unknown result type (might be due to invalid IL or missing references) //IL_073a: Unknown result type (might be due to invalid IL or missing references) //IL_0741: Unknown result type (might be due to invalid IL or missing references) //IL_0747: Unknown result type (might be due to invalid IL or missing references) //IL_077a: Unknown result type (might be due to invalid IL or missing references) //IL_077f: Unknown result type (might be due to invalid IL or missing references) //IL_0786: Unknown result type (might be due to invalid IL or missing references) if (_pc == null) { _pc = pc; } if ((Object)(object)_pc == (Object)null) { return; } if (WallClimbPatch2.RotateBody.Value && (_on || _restoring)) { Quaternion tgt = (_on ? Quaternion.LookRotation(_basis.forward, _basis.up) : Quaternion.Euler(0f, ((Component)this).transform.eulerAngles.y, 0f)); _currentBody = Damp(_currentBody, tgt, WallClimbPatch2.BodyRotationSpeed.Value, Time.fixedDeltaTime); _pc.OverrideTurnRotation(_currentBody, WallClimbPatch2.OverrideTime.Value); } if (_restoring && !_on && Quaternion.Angle(_tilt, Quaternion.identity) < 1f) { _restoring = false; _tilt = Quaternion.identity; _normal = Vector3.up; Log("restored"); } if (!_on || (Object)(object)_rb == (Object)null) { return; } float fixedDeltaTime = Time.fixedDeltaTime; if (WallClimbPatch2.CancelGravity.Value) { _rb.AddForce(Vector3.up * (_pc.CustomGravity * fixedDeltaTime * WallClimbPatch2.GravityCancelScale.Value), (ForceMode)1); } if (WallClimbPatch2.UseAntiGravity.Value) { _pc.AntiGravity(fixedDeltaTime * 3f); } if (_hasCarry) { _hasCarry = false; Vector3 velocity = _rb.velocity; Vector3 val = _carry * velocity; _rb.AddForce(val - velocity, (ForceMode)2); Log("CARRY vel " + Fmt(velocity) + " -> " + Fmt(val)); } Transform cam = (((Object)(object)_pc.cameraGameObject != (Object)null) ? _pc.cameraGameObject.transform : ((Component)this).transform); MoveAxes(cam, out Vector3 axisUp, out Vector3 axisRight, out Vector3 rawF, out Vector3 rawR, out string src); Vector3 val2 = axisUp * _input.y + axisRight * _input.x; if (((Vector3)(ref val2)).sqrMagnitude > 1f) { ((Vector3)(ref val2)).Normalize(); } if (_wantLeap) { _wantLeap = false; _leapReadyAt = Time.time + WallClimbPatch2.LeapCooldown.Value; _leapUntil = Time.time + WallClimbPatch2.LeapWindow.Value; Vector3 val3 = ((((Vector3)(ref val2)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val2)).normalized : _basis.up); Vector3 val4; switch (WallClimbPatch2.LeapMode.Value) { case ClimbLeapMode.Normal: val4 = _basis.normal * WallClimbPatch2.LeapOutward.Value; val3 = _basis.normal; break; case ClimbLeapMode.WorldUp: val4 = Vector3.up * WallClimbPatch2.LeapOutward.Value; val3 = Vector3.up; break; default: val4 = val3 * WallClimbPatch2.LeapForce.Value + _basis.normal * WallClimbPatch2.LeapOutward.Value; break; } _rb.AddForce(val4, (ForceMode)2); float num = WallClimbPatch2.LeapOutward.Value * WallClimbPatch2.LeapOutward.Value / Mathf.Max(0.01f, 2f * WallClimbPatch2.StickForce.Value); Log($"LEAP mode={WallClimbPatch2.LeapMode.Value} dir={Fmt(val3)} " + $"out={WallClimbPatch2.LeapOutward.Value:F1} (~{num:F2}m) " + $"since={Time.time - _lastLeapAt:F2}s " + $"normalDot={Vector3.Dot(val3, _basis.normal):F3}"); _lastLeapAt = Time.time; } bool flag = Time.time < _leapUntil; bool flag2 = Time.time < _edgeUntil; if (_edgeAssistPending) { _edgeAssistPending = false; _rb.AddForce(_edgeDir * WallClimbPatch2.EdgeAssist.Value, (ForceMode)2); } if (((Vector3)(ref val2)).sqrMagnitude > 0.01f && Time.time >= _moveLogAt) { _moveLogAt = Time.time + 0.5f; Log($"MOVE in=({_input.x:F0},{_input.y:F0}) src={src} " + "camF=" + Fmt(rawF) + " camR=" + Fmt(rawR) + " wish=" + Fmt(val2) + " " + $"normalDot={Vector3.Dot(val2, _basis.normal):F3} " + $"hold={_holdInfo} dist={_surfaceDist:F2} " + $"grav={_pc.CustomGravity:F1} vy={_rb.velocity.y:F2}"); } Vector3 velocity2 = _rb.velocity; float num2 = Vector3.Dot(velocity2, _basis.normal); Vector3 val5 = velocity2 - _basis.normal * num2; if (!flag) { if (((Vector3)(ref val2)).sqrMagnitude > 0.01f) { Vector3 val6 = val2 * WallClimbPatch2.ClimbMaxSpeed.Value; _rb.AddForce((val6 - val5) * WallClimbPatch2.ClimbAccel.Value * fixedDeltaTime, (ForceMode)2); } else { _rb.AddForce(-val5 * WallClimbPatch2.ClimbDrag.Value * fixedDeltaTime, (ForceMode)2); } } float num3 = WallClimbPatch2.StickForce.Value; if (flag2) { num3 = 0f; } else if (!flag && Fresh(_touchStamp)) { num3 *= WallClimbPatch2.StickTouchScale.Value; } if (num3 > 0f) { _rb.AddForce(-_basis.normal * num3 * fixedDeltaTime, (ForceMode)2); } if (num2 > 0f && !flag && !flag2) { _rb.AddForce(-_basis.normal * num2, (ForceMode)2); } } private static Vector3 TargetUpFor(WallBasis b) { //IL_0015: 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) return (WallClimbPatch2.CameraMode.Value == ClimbCameraMode.WallUp) ? b.normal : Vector3.up; } private void LateUpdate() { //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_00a8: 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_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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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) float deltaTime = Time.deltaTime; float value = WallClimbPatch2.CameraRotationSpeed.Value; UpdateVisualTilt(deltaTime); if ((Object)(object)_frame == (Object)null) { return; } Transform parent = _frame.parent; if ((Object)(object)parent == (Object)null) { return; } if (_on && WallClimbPatch2.CameraMode.Value == ClimbCameraMode.WallUp) { _tilt = StepTilt(_tilt, _basis.normal, value, deltaTime); } else { _tilt = Quaternion.Slerp(_tilt, Quaternion.identity, 1f - Mathf.Exp((0f - value) * deltaTime)); if (Quaternion.Angle(_tilt, Quaternion.identity) < 0.2f) { _tilt = Quaternion.identity; } } _frame.rotation = _tilt * parent.rotation; if (_frame.localPosition != Vector3.zero) { _frame.localPosition = Vector3.zero; } if (_frame.localScale != Vector3.one) { _frame.localScale = Vector3.one; } } private Quaternion StepTilt(Quaternion tilt, Vector3 targetUp, float speed, float dt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) Vector3 val = tilt * Vector3.up; float num = Vector3.Angle(val, targetUp); Quaternion val2 = ((num > 179f) ? Quaternion.AngleAxis(180f, _basis.right) : Quaternion.FromToRotation(val, targetUp)); float num2 = Mathf.Lerp(1f, WallClimbPatch2.LargeTiltSlowdown.Value, Mathf.InverseLerp(45f, 150f, num)); float num3 = 1f - Mathf.Exp((0f - speed) * num2 * dt); return Quaternion.Normalize(Quaternion.Slerp(Quaternion.identity, val2, num3) * tilt); } private Transform? MeshRoot() { if ((Object)(object)_mesh != (Object)null) { return _mesh; } PlayerAvatar val = (((Object)(object)_pc != (Object)null) ? _pc.playerAvatarScript : null); if ((Object)(object)val == (Object)null) { return null; } PlayerAvatarVisuals playerAvatarVisuals = val.playerAvatarVisuals; if ((Object)(object)playerAvatarVisuals == (Object)null) { return null; } _mesh = (((Object)(object)playerAvatarVisuals.meshParent != (Object)null) ? playerAvatarVisuals.meshParent.transform : ((Component)playerAvatarVisuals).transform); if ((Object)(object)_mesh != (Object)null) { Log("visual root: " + ((Object)_mesh).name); } return _mesh; } private void UpdateVisualTilt(float dt) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_010a: 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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) if (!WallClimbPatch2.RotateVisuals.Value) { return; } if (_on) { _visualTilt = StepTilt(_visualTilt, _basis.normal, WallClimbPatch2.CameraRotationSpeed.Value, dt); } else { _visualTilt = Quaternion.Slerp(_visualTilt, Quaternion.identity, 1f - Mathf.Exp((0f - WallClimbPatch2.VisualRestoreSpeed.Value) * dt)); if (Quaternion.Angle(_visualTilt, Quaternion.identity) < 0.3f) { _visualTilt = Quaternion.identity; } } if (Quaternion.Angle(_visualTilt, Quaternion.identity) < 0.01f) { _hasVisualWrite = false; return; } Transform val = MeshRoot(); if (!((Object)(object)val == (Object)null)) { Quaternion rotation = val.rotation; Quaternion val2 = (_visualBase = ((_hasVisualWrite && Quaternion.Angle(rotation, _lastVisualWrite) < 0.05f) ? _visualBase : rotation)); Quaternion lastVisualWrite = (val.rotation = _visualTilt * val2); _lastVisualWrite = lastVisualWrite; _hasVisualWrite = true; } } private static Quaternion Damp(Quaternion cur, Quaternion tgt, float speed, float dt) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) return Quaternion.Slerp(cur, tgt, 1f - Mathf.Exp((0f - speed) * dt)); } } [HarmonyPatch(typeof(PlayerController))] internal static class WallClimbPatch { internal static ConfigEntry EnableSense = null; internal static ConfigEntry SenseKey = null; internal static ConfigEntry HoldMode = null; internal static ConfigEntry FadeDuration = null; internal static ConfigEntry SenseRange = null; internal static ConfigEntry RefreshInterval = null; internal static ConfigEntry AllyColor = null; internal static ConfigEntry EnemyColor = null; internal static ConfigEntry SilhouetteAlpha = null; internal static ConfigEntry ShowSelf = null; internal static ConfigEntry ThroughWalls = null; internal static ConfigEntry IncludeInactive = null; internal static ConfigEntry MinVertices = null; internal static ConfigEntry TopMeshCount = null; internal static ConfigEntry ExcludeMeshNames = null; internal static ConfigEntry ExcludeObjectNames = null; internal static ConfigEntry MinScreenSize = null; internal static ConfigEntry ExtendFarClip = null; internal static ConfigEntry FarClipMargin = null; internal static ConfigEntry InspectTargets = null; internal static ConfigEntry EnableFastCrouch = null; internal static ConfigEntry CrouchSpeedMultiplier = null; internal static ConfigEntry KeepCrouchOnSteps = null; internal static ConfigEntry Debug = null; private static bool _done; internal static SpiderSense? Sense; internal static float OriginalCrouchSpeed = -1f; private static void Setup() { if (!_done) { _done = true; ConfigFile config = ((BaseUnityPlugin)RepoWallClimb.Instance).Config; EnableSense = config.Bind("Sense", "Enabled", true, "スパイダーセンスを使う。"); SenseKey = config.Bind("Sense", "Key", (KeyCode)120, "発動キー。"); HoldMode = config.Bind("Sense", "HoldMode", true, "true なら押しっぱなしの間だけ表示。"); FadeDuration = config.Bind("Sense", "FadeDuration", 2f, "浮かび上がるまでの秒数。"); SenseRange = config.Bind("Sense", "Range", 0f, "表示する距離(m)。0 で無制限。"); RefreshInterval = config.Bind("Sense", "RefreshInterval", 1f, "対象を探し直す間隔(秒)。重いなら 2〜3 へ。"); AllyColor = config.Bind("Sense", "AllyColor", "0,1,0.2", "味方の色 R,G,B。"); EnemyColor = config.Bind("Sense", "EnemyColor", "1,0.1,0.1", "敵の色 R,G,B。"); SilhouetteAlpha = config.Bind("Sense", "Alpha", 0.8f, "不透明度。"); ShowSelf = config.Bind("Sense", "ShowSelf", false, "自分も表示する。"); ThroughWalls = config.Bind("Sense", "ThroughWalls", true, "壁越しに見えるようにする。"); IncludeInactive = config.Bind("Sense", "IncludeInactive", true, "非アクティブな敵も表示する。REPO は遠い敵を無効化するため、これを true にしないとマップ全体が見えない。"); MinVertices = config.Bind("Sense", "MinVertices", 0, "この頂点数未満のメッシュは無視する。0 で無効。★頂点数と重要度は無関係なので、原則 0 のまま使うこと。VacuumSphere(515) は腕(485) より頂点が多く、この値では分けられない。"); ExcludeMeshNames = config.Bind("Sense", "ExcludeMeshNames", "", "このメッシュ名を持つものは描かない(カンマ区切り・部分一致)。★最後の個別例外用。空のまま使うこと。Sphere を入れるとヘッドマンの下半分など本体を巻き込む。効果範囲の球は Trigger との複合条件で自動的に落ちる。"); ExcludeObjectNames = config.Bind("Sense", "ExcludeObjectNames", "", "このオブジェクト名を含むものは描かない(カンマ区切り・部分一致)。★最後の個別例外用。空のまま使うこと。"); TopMeshCount = config.Bind("Sense", "TopMeshCount", 0, "1体につき、頂点数の多い上位いくつのメッシュだけを描くか。0 で無効(全パーツを描く=元の形を保つ)。★0 以外にすると、パーツ数の多い敵(トラッジ等)の頭や下半身が丸ごと消える。原則 0 のまま使うこと。"); MinScreenSize = config.Bind("Sense", "MinScreenSize", 0f, "遠くの対象を大きく見せる補正。0 で無効。倍率は 距離 × この値(1 未満なら等倍)。0.02 なら 50m から効き始める。★v23 で対象の中心を基準に拡大するよう直した。以前はパーツごとにその場で拡大していたため、遠くの敵がバラバラに分解して見えていた。"); ExtendFarClip = config.Bind("Sense", "ExtendFarClip", true, "★遠くのシルエットが見えない時の対策★ センスを出している間だけカメラの遠クリップ面を伸ばす。屋内ゲームは遠クリップが短いことが多く、そこで切られていると壁抜けシェーダを使っていても遠くの対象は一切描かれない。離すと元の値へ戻す。"); FarClipMargin = config.Bind("Sense", "FarClipMargin", 30f, "遠クリップを伸ばす時、一番遠い対象からどれだけ余裕を持たせるか(m)。"); InspectTargets = config.Bind("Debug", "InspectTargets", false, "対象の Renderer 構造をログへ出す。調査用。"); EnableFastCrouch = config.Bind("FastCrouch", "Enabled", true, "しゃがみ移動を高速化する。"); CrouchSpeedMultiplier = config.Bind("FastCrouch", "SpeedMultiplier", 1.5f, "スプリント速度に対する倍率。"); KeepCrouchOnSteps = config.Bind("FastCrouch", "KeepCrouchOnSteps", true, "段差でしゃがみが解除されるのを防ぐ。"); Debug = config.Bind("Debug", "Verbose", true, "診断ログを出す。"); } } [HarmonyPostfix] [HarmonyPatch("Start")] private static void Start_Post(PlayerController __instance) { Setup(); if (OriginalCrouchSpeed < 0f) { OriginalCrouchSpeed = __instance.CrouchSpeed; } if ((Object)(object)((Component)__instance).gameObject.GetComponent() == (Object)null) { Sense = ((Component)__instance).gameObject.AddComponent(); RepoWallClimb.Logger.LogInfo((object)"SpiderSense v23 attached. Hold X."); } } [HarmonyPostfix] [HarmonyPatch("Update")] private static void Update_Post(PlayerController __instance) { if (EnableFastCrouch != null && EnableFastCrouch.Value && OriginalCrouchSpeed >= 0f) { float num = __instance.SprintSpeed * CrouchSpeedMultiplier.Value; if (!Mathf.Approximately(__instance.CrouchSpeed, num)) { __instance.CrouchSpeed = num; } } } [HarmonyPrefix] [HarmonyPatch("FixedUpdate")] private static void Fixed_Pre(PlayerController __instance) { if (KeepCrouchOnSteps != null && KeepCrouchOnSteps.Value && EnableFastCrouch.Value && (SemiFunc.InputHold((InputKey)12) || __instance.toggleCrouch) && __instance.Crouching && __instance.CrouchActiveTimer < 0.1f) { __instance.CrouchActiveTimer = 0.1f; } } } public class SpiderSense : MonoBehaviour { private class Ghost { public GameObject Root = null; public Transform Target = null; public List Sources = new List(); public List Clones = new List(); public Material Mat = null; public Renderer? Capsule; public bool BuiltActive; public PlayerAvatar? Avatar; public bool BuiltTumbling; } private enum Reject { None, Type, NoMesh, MinVerts, NameFilter, PrimTrigger, PrimDisabled, PrimOutsideVis } private PlayerController? _pc; private readonly List _ghosts = new List(); private readonly HashSet _inspected = new HashSet(); private bool _on; private float _fade; private float _refreshAt; private string _lastLog = ""; private bool _mapWasOpen; private float _farthest; private int _visibleGhosts; private Color _allyColor = Color.green; private Color _enemyColor = Color.red; private static Shader? _shader; private static bool _shaderSearched; private Transform? _enemyParent; private float _parentSearchAt; private readonly HashSet _seen = new HashSet(); private static string[]? _exMesh; private static string[]? _exObj; private static readonly string[] PrimitiveMeshes = new string[6] { "Sphere", "Cube", "Capsule", "Cylinder", "Plane", "Quad" }; private void Awake() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) ((Component)this).TryGetComponent(ref _pc); _allyColor = ParseColor(WallClimbPatch.AllyColor.Value, Color.green); _enemyColor = ParseColor(WallClimbPatch.EnemyColor.Value, Color.red); FindShader(); } private static Color ParseColor(string s, Color fallback) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) string[] array = s.Split(','); if (array.Length < 3) { return fallback; } if (float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2) && float.TryParse(array[2], out var result3)) { return new Color(result, result2, result3); } return fallback; } private void Log(string m) { RepoWallClimb.Logger.LogInfo((object)("[Sense] " + m)); } private void LogOnce(string m) { if (!(m == _lastLog)) { _lastLog = m; Log(m); } } private void FindShader() { if (_shaderSearched) { return; } _shaderSearched = true; string[] array = new string[6] { "Hidden/Internal-Colored", "Unlit/Color", "Sprites/Default", "UI/Default", "Particles/Standard Unlit", "GUI/Text Shader" }; string[] array2 = array; foreach (string text in array2) { Shader val = Shader.Find(text); if ((Object)(object)val != (Object)null) { _shader = val; break; } } Log(((Object)(object)_shader != (Object)null) ? ("shader: " + ((Object)_shader).name) : "NO shader found"); } private void Update() { //IL_0050: 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) if ((Object)(object)_pc == (Object)null || !WallClimbPatch.EnableSense.Value) { return; } bool flag; if (WallClimbPatch.HoldMode.Value) { flag = Input.GetKey(WallClimbPatch.SenseKey.Value); } else { if (Input.GetKeyDown(WallClimbPatch.SenseKey.Value)) { _on = !_on; } flag = _on; } bool flag2 = (Object)(object)MapToolController.instance != (Object)null && MapToolController.instance.Active; if (flag2 != _mapWasOpen) { _mapWasOpen = flag2; Log(flag2 ? "map opened -> sense paused" : "map closed -> sense resumed"); if (flag2) { ClearGhosts(); } } if (flag2) { _fade = 0f; return; } if (flag && _ghosts.Count > 0 && TumbleChanged()) { _refreshAt = 0f; } if (flag && _ghosts.Count == 0 && _fade <= 0.001f) { Refresh(); } float num = Mathf.Max(0.05f, WallClimbPatch.FadeDuration.Value); _fade = Mathf.MoveTowards(_fade, flag ? 1f : 0f, Time.deltaTime / num); if (_fade <= 0.001f) { if (_ghosts.Count > 0) { ClearGhosts(); } RestoreFarClip(); return; } ApplyFarClip(); if (flag && Time.time >= _refreshAt) { _refreshAt = Time.time + Mathf.Max(0.2f, WallClimbPatch.RefreshInterval.Value); try { Refresh(); } catch (Exception ex) { Log("EXCEPTION in Refresh: " + ex.GetType().Name + ": " + ex.Message + " -> all ghosts cleared"); ClearGhosts(); } } UpdateGhosts(); } private static Transform PlayerVisualRoot(PlayerAvatar a) { PlayerAvatarVisuals playerAvatarVisuals = a.playerAvatarVisuals; if ((Object)(object)playerAvatarVisuals != (Object)null) { if ((Object)(object)playerAvatarVisuals.meshParent != (Object)null) { return playerAvatarVisuals.meshParent.transform; } return ((Component)playerAvatarVisuals).transform; } return ((Component)a).transform; } private Transform? GetEnemyParent() { if ((Object)(object)_enemyParent != (Object)null) { return _enemyParent; } if (Time.time < _parentSearchAt) { return null; } _parentSearchAt = Time.time + 3f; Transform[] array = Object.FindObjectsOfType(); foreach (Transform val in array) { if (!((Object)(object)val == (Object)null) && !(((Object)val).name != "Enemies") && (Object)(object)val.parent != (Object)null && ((Object)val.parent).name.Contains("Level")) { _enemyParent = val; Log("enemy parent found: " + ((Object)val.parent).name + "/" + ((Object)val).name + " " + $"({val.childCount} children)"); return _enemyParent; } } GameObject val2 = GameObject.Find("Level Generator/Enemies"); if ((Object)(object)val2 != (Object)null) { _enemyParent = val2.transform; return _enemyParent; } return null; } private Ghost? FindGhost(Transform target) { foreach (Ghost ghost in _ghosts) { if ((Object)(object)ghost.Target == (Object)(object)target) { return ghost; } } return null; } private void DestroyGhost(Ghost g) { if ((Object)(object)g.Mat != (Object)null) { Object.Destroy((Object)(object)g.Mat); } if ((Object)(object)g.Root != (Object)null) { Object.Destroy((Object)(object)g.Root); } } private void ApplyFarClip() { if (!WallClimbPatch.ExtendFarClip.Value) { RestoreFarClip(); } else { FarClip.Request(FarClip.User.Sense, _farthest + WallClimbPatch.FarClipMargin.Value); } } private void RestoreFarClip() { FarClip.Release(FarClip.User.Sense); } private static bool IsTumbling(PlayerAvatar? a) { return (Object)(object)a != (Object)null && a.isTumbling; } private bool Want(Transform target, Color color, ref int meshed, ref int capsules, ref int reused, PlayerAvatar? avatar = null) { //IL_010e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return false; } _seen.Add(target); bool flag = IsTumbling(avatar); Ghost ghost = FindGhost(target); if (ghost != null) { bool activeInHierarchy = ((Component)target).gameObject.activeInHierarchy; if (ghost.BuiltTumbling != flag) { Log("tumble state changed: " + ((Object)target).name + " " + $"tumbling={flag} -> ghost rebuilt"); DestroyGhost(ghost); _ghosts.Remove(ghost); } else { if (ghost.BuiltActive == activeInHierarchy && (Object)(object)ghost.Root != (Object)null) { if (ghost.Clones.Count > 0) { meshed++; } else { capsules++; } reused++; return true; } DestroyGhost(ghost); _ghosts.Remove(ghost); } } if (!AddGhost(target, color, ref meshed, ref capsules)) { return false; } Ghost ghost2 = _ghosts[_ghosts.Count - 1]; ghost2.Avatar = avatar; ghost2.BuiltTumbling = flag; return true; } private bool TumbleChanged() { foreach (Ghost ghost in _ghosts) { if ((Object)(object)ghost.Avatar == (Object)null || IsTumbling(ghost.Avatar) == ghost.BuiltTumbling) { continue; } return true; } return false; } private void Refresh() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) _seen.Clear(); float value = WallClimbPatch.SenseRange.Value; Vector3 position = ((Component)this).transform.position; int num = 0; int num2 = 0; int meshed = 0; int capsules = 0; int num3 = 0; int num4 = 0; int reused = 0; float num5 = 0f; PlayerAvatar[] array = Object.FindObjectsOfType(); foreach (PlayerAvatar val in array) { if (!((Object)(object)val == (Object)null) && (!((Object)(object)_pc != (Object)null) || !((Object)(object)val == (Object)(object)_pc.playerAvatarScript) || WallClimbPatch.ShowSelf.Value)) { float num6 = Vector3.Distance(position, ((Component)val).transform.position); if (value > 0f && num6 > value) { num4++; } else if (Want(PlayerVisualRoot(val), _allyColor, ref meshed, ref capsules, ref reused, val)) { num++; } } } Transform enemyParent = GetEnemyParent(); List list = new List(); if ((Object)(object)enemyParent != (Object)null) { foreach (Transform item in enemyParent) { Transform val2 = item; if (!((Object)(object)val2 == (Object)null) && (WallClimbPatch.IncludeInactive.Value || ((Component)val2).gameObject.activeInHierarchy)) { if (!((Component)val2).gameObject.activeInHierarchy) { num3++; } list.Add(val2); } } } else { GameObject[] array2 = GameObject.FindGameObjectsWithTag("Enemy"); foreach (GameObject val3 in array2) { if ((Object)(object)val3 != (Object)null) { list.Add(val3.transform); } } } foreach (Transform item2 in list) { float num7 = Vector3.Distance(position, item2.position); if (num7 > num5) { num5 = num7; } if (value > 0f && num7 > value) { num4++; } else if (Want(item2, _enemyColor, ref meshed, ref capsules, ref reused)) { num2++; } } int num8 = 0; for (int num9 = _ghosts.Count - 1; num9 >= 0; num9--) { Ghost ghost = _ghosts[num9]; if (!((Object)(object)ghost.Target != (Object)null) || !_seen.Contains(ghost.Target)) { DestroyGhost(ghost); _ghosts.RemoveAt(num9); num8++; } } _farthest = num5; LogOnce($"enemies={num2}/{list.Count} (inactive={num3}) " + $"allies={num} mesh={meshed} capsule={capsules} " + $"reused={reused} dropped={num8} " + $"farthest={num5:F0}m " + "src=" + (((Object)(object)enemyParent != (Object)null) ? "parent" : "tag")); Camera main = Camera.main; if ((Object)(object)main != (Object)null) { int num10 = ((_ghosts.Count > 0 && (Object)(object)_ghosts[0].Root != (Object)null) ? _ghosts[0].Root.layer : 0); Log($"VIS farthest={num5:F0}m clip={main.farClipPlane:F0} " + "extended=" + (FarClip.Extended ? "yes" : "no") + " " + $"layer={LayerMask.LayerToName(num10)}({num10}) " + $"inMask={(main.cullingMask & (1 << num10)) != 0} " + $"drawn={_visibleGhosts}/{_ghosts.Count} " + $"minScreenSize={WallClimbPatch.MinScreenSize.Value:F3}"); } } private static string Path(Transform root, Transform t) { string text = ((Object)t).name; Transform parent = t.parent; int num = 0; while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root && num++ < 16) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private void Inspect(Transform target) { if (!WallClimbPatch.InspectTargets.Value || !_inspected.Add(((Object)target).name)) { return; } Renderer[] componentsInChildren = ((Component)target).GetComponentsInChildren(true); bool flag = TargetHasVisuals(componentsInChildren, target); int num = 0; Log($"--- INSPECT: {((Object)target).name} (renderers={componentsInChildren.Length} " + $"rootActive={((Component)target).gameObject.activeInHierarchy} " + $"hasVisuals={flag}) ---"); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null)) { Mesh mesh; Reject reject = Classify(target, val, flag, out mesh); if (reject == Reject.None) { num++; } string arg = (((Object)(object)mesh != (Object)null) ? ((Object)mesh).name : "?"); int num2 = (((Object)(object)mesh != (Object)null) ? mesh.vertexCount : 0); Collider component = ((Component)val).GetComponent(); string text = (((Object)(object)component == (Object)null) ? "col=none" : $"col={((object)component).GetType().Name} trigger={component.isTrigger}"); Log(" " + ((reject == Reject.None) ? "OK " : "SKIP") + " [" + ((object)val).GetType().Name + "] " + Path(target, ((Component)val).transform) + " " + $"mesh={arg} verts={num2} " + $"active={((Component)val).gameObject.activeInHierarchy} enabled={val.enabled} " + $"layer={LayerMask.LayerToName(((Component)val).gameObject.layer)}({((Component)val).gameObject.layer}) " + "tag=" + ((Component)val).gameObject.tag + " " + text + " " + $"reason={reject}"); } } Log($"--- END: draw={num}/{componentsInChildren.Length} ---"); } private bool IsExcluded(string objName, string meshName) { if (_exMesh == null) { _exMesh = Split(WallClimbPatch.ExcludeMeshNames.Value); } if (_exObj == null) { _exObj = Split(WallClimbPatch.ExcludeObjectNames.Value); } string[] exMesh = _exMesh; foreach (string value in exMesh) { if (meshName.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } string[] exObj = _exObj; foreach (string value2 in exObj) { if (objName.IndexOf(value2, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } private static string[] Split(string s) { List list = new List(); string[] array = s.Split(','); foreach (string text in array) { string text2 = text.Trim(); if (text2.Length > 0) { list.Add(text2); } } return list.ToArray(); } private static bool IsPrimitiveMesh(string meshName) { string text = meshName; int num = text.IndexOf(" Instance", StringComparison.Ordinal); if (num > 0) { text = text.Substring(0, num); } text = text.Trim(); string[] primitiveMeshes = PrimitiveMeshes; foreach (string b in primitiveMeshes) { if (string.Equals(text, b, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } private static bool IsVisualsName(string n) { return n.IndexOf("VISUAL", StringComparison.OrdinalIgnoreCase) >= 0; } private static bool InsideVisuals(Transform root, Transform t) { Transform val = t; int num = 0; while ((Object)(object)val != (Object)null && num++ < 32) { if (IsVisualsName(((Object)val).name)) { return true; } if ((Object)(object)val == (Object)(object)root) { break; } val = val.parent; } return false; } private static bool TargetHasVisuals(Renderer[] renderers, Transform root) { foreach (Renderer val in renderers) { if ((Object)(object)val != (Object)null && InsideVisuals(root, ((Component)val).transform)) { return true; } } return false; } private Reject Classify(Transform root, Renderer r, bool targetHasVisuals, out Mesh? mesh) { mesh = null; if (r is ParticleSystemRenderer || r is TrailRenderer || r is LineRenderer) { return Reject.Type; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((r is SkinnedMeshRenderer) ? r : null); if (val != null) { mesh = val.sharedMesh; } else { MeshFilter component = ((Component)r).GetComponent(); if ((Object)(object)component != (Object)null) { mesh = component.sharedMesh; } } if ((Object)(object)mesh == (Object)null) { return Reject.NoMesh; } int value = WallClimbPatch.MinVertices.Value; if (value > 0 && mesh.vertexCount < value) { return Reject.MinVerts; } if (IsExcluded(((Object)r).name, ((Object)mesh).name)) { return Reject.NameFilter; } if (IsPrimitiveMesh(((Object)mesh).name)) { Collider component2 = ((Component)r).GetComponent(); if ((Object)(object)component2 != (Object)null && component2.isTrigger) { return Reject.PrimTrigger; } if (!r.enabled) { return Reject.PrimDisabled; } if (targetHasVisuals && !InsideVisuals(root, ((Component)r).transform)) { return Reject.PrimOutsideVis; } } return Reject.None; } private bool AddGhost(Transform target, Color color, ref int meshed, ref int capsules) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown if ((Object)(object)target == (Object)null) { return false; } Inspect(target); Ghost ghost = new Ghost { Root = new GameObject("Sense_" + ((Object)target).name), Target = target, Mat = MakeMaterial(null, color) }; bool flag = (ghost.BuiltActive = ((Component)target).gameObject.activeInHierarchy); int num = 0; if (flag) { Renderer[] componentsInChildren = ((Component)target).GetComponentsInChildren(true); bool targetHasVisuals = TargetHasVisuals(componentsInChildren, target); List<(Renderer, Mesh, int)> list = new List<(Renderer, Mesh, int)>(); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null) && Classify(target, val, targetHasVisuals, out Mesh mesh) == Reject.None && !((Object)(object)mesh == (Object)null)) { list.Add((val, mesh, mesh.vertexCount)); } } int value = WallClimbPatch.TopMeshCount.Value; if (value > 0 && list.Count > value) { list.Sort(((Renderer r, Mesh mesh, int verts) x, (Renderer r, Mesh mesh, int verts) y) => y.verts.CompareTo(x.verts)); list.RemoveRange(value, list.Count - value); } foreach (var item3 in list) { Renderer item = item3.Item1; Mesh item2 = item3.Item2; GameObject val2 = new GameObject(((Object)item).name + "_g"); val2.transform.SetParent(ghost.Root.transform, false); SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((item is SkinnedMeshRenderer) ? item : null); Renderer val5; if (val3 != null) { SkinnedMeshRenderer val4 = val2.AddComponent(); val4.sharedMesh = val3.sharedMesh; val4.bones = val3.bones; val4.rootBone = val3.rootBone; val4.updateWhenOffscreen = true; val5 = (Renderer)(object)val4; } else { val2.AddComponent().sharedMesh = item2; val5 = (Renderer)(object)val2.AddComponent(); } val5.sharedMaterial = ghost.Mat; val5.shadowCastingMode = (ShadowCastingMode)0; val5.receiveShadows = false; val5.enabled = ((Component)item).gameObject.activeInHierarchy && item.enabled; ghost.Sources.Add(item); ghost.Clones.Add(val5); num++; } } GameObject val6 = GameObject.CreatePrimitive((PrimitiveType)1); Object.Destroy((Object)(object)val6.GetComponent()); val6.transform.SetParent(ghost.Root.transform, false); val6.transform.localScale = new Vector3(0.6f, 0.9f, 0.6f); MeshRenderer component = val6.GetComponent(); ((Renderer)component).sharedMaterial = ghost.Mat; ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component).receiveShadows = false; ((Renderer)component).enabled = num == 0; ghost.Capsule = (Renderer?)(object)component; if (num > 0) { meshed++; } else { capsules++; } _ghosts.Add(ghost); return true; } private Material MakeMaterial(Renderer? src, Color color) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) color.a = WallClimbPatch.SilhouetteAlpha.Value; Material val; if ((Object)(object)_shader != (Object)null) { val = new Material(_shader); } else { if (!((Object)(object)src != (Object)null) || !((Object)(object)src.sharedMaterial != (Object)null)) { return new Material(Shader.Find("Diffuse")); } val = new Material(src.sharedMaterial); if (val.HasProperty("_MainTex")) { val.SetTexture("_MainTex", (Texture)null); } } val.color = color; if (val.HasProperty("_Color")) { val.SetColor("_Color", color); } if (val.HasProperty("_BaseColor")) { val.SetColor("_BaseColor", color); } if (WallClimbPatch.ThroughWalls.Value) { val.SetInt("_ZTest", 8); val.SetInt("_ZWrite", 0); val.SetInt("_SrcBlend", 5); val.SetInt("_DstBlend", 10); val.renderQueue = 5000; } return val; } private void UpdateGhosts() { float a = WallClimbPatch.SilhouetteAlpha.Value * Fade01(); float value = WallClimbPatch.MinScreenSize.Value; Camera main = Camera.main; _visibleGhosts = 0; for (int num = _ghosts.Count - 1; num >= 0; num--) { Ghost ghost = _ghosts[num]; if ((Object)(object)ghost.Target == (Object)null || (Object)(object)ghost.Root == (Object)null) { if ((Object)(object)ghost.Root != (Object)null) { Object.Destroy((Object)(object)ghost.Root); } _ghosts.RemoveAt(num); } else { try { UpdateOne(ghost, a, value, main); } catch (Exception ex) { Log("EXCEPTION in UpdateGhosts: " + ex.GetType().Name + ": " + ex.Message + " -> ghost destroyed (" + (((Object)(object)ghost.Target != (Object)null) ? ((Object)ghost.Target).name : "?") + ")"); DestroyGhost(ghost); _ghosts.RemoveAt(num); } } } } private void UpdateOne(Ghost g, float a, float minSize, Camera? cam) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_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_033c: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) float num = 1f; if (minSize > 0f && (Object)(object)cam != (Object)null) { float num2 = Vector3.Distance(((Component)cam).transform.position, g.Target.position); num = Mathf.Max(1f, num2 * minSize); } int num3 = 0; for (int i = 0; i < g.Clones.Count; i++) { Renderer val = g.Clones[i]; if ((Object)(object)val == (Object)null) { continue; } Renderer val2 = ((i < g.Sources.Count) ? g.Sources[i] : null); if ((Object)(object)val2 == (Object)null) { val.enabled = false; } else { if (!(val.enabled = ((Component)val2).gameObject.activeInHierarchy && val2.enabled)) { continue; } num3++; if (!(val is SkinnedMeshRenderer)) { ((Component)val).transform.rotation = ((Component)val2).transform.rotation; if (num > 1.0001f) { Vector3 position = g.Target.position; ((Component)val).transform.position = position + (((Component)val2).transform.position - position) * num; ((Component)val).transform.localScale = ((Component)val2).transform.lossyScale * num; } else { ((Component)val).transform.position = ((Component)val2).transform.position; ((Component)val).transform.localScale = ((Component)val2).transform.lossyScale; } } } } if (num3 > 0 && g.Clones.Count > 0) { for (int j = 0; j < g.Clones.Count; j++) { Renderer val3 = g.Clones[j]; if (!((Object)(object)val3 == (Object)null) && val3.enabled) { if (val3.isVisible) { _visibleGhosts++; } break; } } } if ((Object)(object)g.Capsule != (Object)null) { g.Capsule.enabled = num3 == 0; if (g.Capsule.enabled) { ((Component)g.Capsule).transform.position = g.Target.position + Vector3.up * 0.9f; ((Component)g.Capsule).transform.rotation = Quaternion.identity; ((Component)g.Capsule).transform.localScale = new Vector3(0.6f, 0.9f, 0.6f) * num; } } if ((Object)(object)g.Mat != (Object)null) { Material mat = g.Mat; Color color = mat.color; color.a = a; mat.color = color; if (mat.HasProperty("_Color")) { Color color2 = mat.GetColor("_Color"); color2.a = a; mat.SetColor("_Color", color2); } } } private float Fade01() { return Mathf.SmoothStep(0f, 1f, _fade) * Mathf.Lerp(0.1f, 1f, _fade); } private void ClearGhosts() { foreach (Ghost ghost in _ghosts) { DestroyGhost(ghost); } _ghosts.Clear(); _seen.Clear(); } private void OnDestroy() { RestoreFarClip(); ClearGhosts(); } private void OnDisable() { RestoreFarClip(); } } [HarmonyPatch(typeof(PlayerController))] internal static class WebSwingPatch { internal static ConfigEntry Enabled; internal static ConfigEntry Key; internal static ConfigEntry Range; internal static ConfigEntry Spring; internal static ConfigEntry Damper; internal static ConfigEntry LengthStep; internal static ConfigEntry MinLength; internal static ConfigEntry MaxLength; internal static ConfigEntry AirControl; internal static ConfigEntry CastRadius; internal static ConfigEntry StiffRope; internal static ConfigEntry Tolerance; internal static ConfigEntry AllowFloor; internal static ConfigEntry MaxFloorDot; internal static ConfigEntry AllowMovable; internal static ConfigEntry KeyWhileGrabbing; internal static ConfigEntry KeepGrabbed; internal static ConfigEntry GrabHoldDistance; internal static ConfigEntry GrabReleaseDistance; internal static ConfigEntry BlockWhileGrabbing; internal static ConfigEntry ShowRope; internal static ConfigEntry RopeWidth; internal static ConfigEntry RopeColor; internal static ConfigEntry Debug; private static bool _done; internal static WebSwing? Swing; internal static ConfigEntry SuppressMove; private static int _patched; private static void Setup() { if (!_done) { _done = true; ConfigFile config = ((BaseUnityPlugin)RepoWallClimb.Instance).Config; Enabled = config.Bind("Web", "Enabled", true, "ウェブスイングを使う。"); Key = config.Bind("Web", "Key", (KeyCode)324, "糸を出すキー。押している間スイングする。既定は右クリック。REPO では右クリックは「掴んだ物の回転」に割り当てられているが、物を持っていない間は空いているので競合しない。"); Range = config.Bind("Web", "Range", 30f, "糸の最大射程(m)。"); SuppressMove = config.Bind("Web", "SuppressMove", true, "★課題21★ スイング中は REPO の速度制御を止める。REPO は毎ステップ AddRelativeForce(目標速度 - 現在速度, Impulse) で速度を目標値へ引き戻しており、振り子が得た勢いを消してしまう。WASD を押すと目標が歩行速度になるので、さらに強く削られる。Transpiler でその呼び出しだけを差し替える。重力には触らない。"); Spring = config.Bind("Web", "Spring", 400f, "バネの強さ。強いほど糸が硬い。v2 で 120 から上げた。糸が伸びるなら更に上げる。"); StiffRope = config.Bind("Web", "StiffRope", true, "★課題22★ 糸を伸びにくくする。長さを超えている間、アンカーから離れる向きの速度成分だけを打ち消す。接線方向(振り子の運動)は残すので、バネを極端に強くしなくても糸が張った状態を保てる。"); Tolerance = config.Bind("Web", "Tolerance", 0.002f, "SpringJoint の許容誤差。既定(0.025)より小さくすると硬くなる。"); Damper = config.Bind("Web", "Damper", 6f, "バネの減衰。大きいほど揺れが早く収まる。大きすぎると振り子にならないので控えめに。"); LengthStep = config.Bind("Web", "LengthStep", 0.5f, "ホイール1目盛りあたりの糸の長さの変化(m)。前へ回すと短く(引き寄せ)、後ろへ回すと長くなる。"); MinLength = config.Bind("Web", "MinLength", 2f, "糸の最短(m)。"); MaxLength = config.Bind("Web", "MaxLength", 30f, "糸の最長(m)。"); AirControl = config.Bind("Web", "AirControl", 0.3f, "スイング中の WASD の効き。実際の加速は この値 × 20 m/s^2。効かせすぎると振り子の物理が壊れるので軽めに。"); CastRadius = config.Bind("Web", "CastRadius", 0.15f, "糸を当てる判定球の半径。0 で完全な直線。少し太いほうが狙いやすい。"); AllowFloor = config.Bind("Web", "AllowFloor", false, "★課題23-A★ 上を向いた面(床)にも糸を張れるようにする。false だと床は対象外。真下の床へ張っても振り子にならず地面へ引き寄せられるだけなので、既定では弾く。天井(法線が下向き)はスイングに必要なので常に許可される。"); MaxFloorDot = config.Bind("Web", "MaxFloorDot", 0.5f, "「床」とみなす面の上向き度。法線と真上の内積がこれを超えたら床。"); AllowMovable = config.Bind("Web", "AllowMovable", false, "★課題23-B★ 動く物にも糸を張れるようにする。false だと非 kinematic な Rigidbody を持つ物と PhysGrabObject(持ち運べる貴重品・置物)を弾く。タグだけでは Broken Artwork Axel Bust のような置物を取りこぼしていた。"); KeyWhileGrabbing = config.Bind("Web", "KeyWhileGrabbing", (KeyCode)102, "★物を持っている間の発動キー★ 持っている間は右クリックが REPO の「掴んだ物の回転」なので、そのままでは競合する。持っている時だけこちらのキーで発動する。持っていない時は Key(右クリック)のまま。"); KeepGrabbed = config.Bind("Web", "KeepGrabbed", true, "★スイング中は絶対に物を離さない★ REPO は PhysGrabber.grabReleaseDistance を超えると物を手放す。スイングは速く動くので物が置いていかれて外れやすい。張っている間だけこの距離を極端に伸ばし、離れないようにする。糸を切れば元の値へ戻す。"); GrabHoldDistance = config.Bind("Web", "GrabHoldDistance", 1.5f, "スイング中、持っている物を体からどれだけの距離に留めるか(m)。PhysGrabber.maxDistanceFromPlayer を一時的にこの値にする。小さいほど体に密着する。"); GrabReleaseDistance = config.Bind("Web", "GrabReleaseDistance", 1000f, "スイング中の grabReleaseDistance。事実上「離さない」ための値。小さくすると、離れすぎた時に手放すようになる。"); BlockWhileGrabbing = config.Bind("Web", "BlockWhileGrabbing", false, "true にすると、物を持っている間はスイングできなくなる。既定 false(KeyWhileGrabbing で持ったままスイングできる)。"); ShowRope = config.Bind("Web", "ShowRope", true, "糸を描画する。"); RopeWidth = config.Bind("Web", "RopeWidth", 0.035f, "糸の太さ(m)。"); RopeColor = config.Bind("Web", "RopeColor", "1,1,1", "糸の色 R,G,B。"); Debug = config.Bind("Web", "Debug", true, "スイングのログを出す。"); } } [HarmonyPostfix] [HarmonyPatch("Start")] private static void Start_Post(PlayerController __instance) { Setup(); if ((Object)(object)((Component)__instance).gameObject.GetComponent() == (Object)null) { Swing = ((Component)__instance).gameObject.AddComponent(); RepoWallClimb.Logger.LogInfo((object)"WebSwing v3 attached. (RMB, or F while holding)"); } } [HarmonyPostfix] [HarmonyPatch("Update")] private static void Update_Post(PlayerController __instance) { if ((Object)(object)Swing != (Object)null) { Swing.Tick(__instance); } } [HarmonyPostfix] [HarmonyPatch("FixedUpdate")] private static void Fixed_Post(PlayerController __instance) { if ((Object)(object)Swing != (Object)null) { Swing.Physics(__instance); } } public static void RelativeForceGate(Rigidbody rb, Vector3 force, ForceMode mode) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!WebSwing.Active || SuppressMove == null || !SuppressMove.Value) { rb.AddRelativeForce(force, mode); } } public static void RelativeForceGate1(Rigidbody rb, Vector3 force) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!WebSwing.Active || SuppressMove == null || !SuppressMove.Value) { rb.AddRelativeForce(force); } } [HarmonyTranspiler] [HarmonyPatch("FixedUpdate")] private static IEnumerable Fixed_Trans(IEnumerable instructions) { MethodInfo two = AccessTools.Method(typeof(Rigidbody), "AddRelativeForce", new Type[2] { typeof(Vector3), typeof(ForceMode) }, (Type[])null); MethodInfo one = AccessTools.Method(typeof(Rigidbody), "AddRelativeForce", new Type[1] { typeof(Vector3) }, (Type[])null); MethodInfo gate2 = AccessTools.Method(typeof(WebSwingPatch), "RelativeForceGate", (Type[])null, (Type[])null); MethodInfo gate3 = AccessTools.Method(typeof(WebSwingPatch), "RelativeForceGate1", (Type[])null, (Type[])null); _patched = 0; foreach (CodeInstruction ins in instructions) { if (two != null && CodeInstructionExtensions.Calls(ins, two)) { _patched++; yield return new CodeInstruction(OpCodes.Call, (object)gate2); } else if (one != null && CodeInstructionExtensions.Calls(ins, one)) { _patched++; yield return new CodeInstruction(OpCodes.Call, (object)gate3); } else { yield return ins; } } RepoWallClimb.Logger.LogInfo((object)($"[Web] move-suppression transpiler: patched {_patched} " + "AddRelativeForce call site(s) in PlayerController.FixedUpdate")); } } public class WebSwing : MonoBehaviour { internal static bool Active; private PlayerController? _pc; private Rigidbody? _rb; private LayerMask _mask; private SpringJoint? _joint; private Vector3 _anchor; private float _length; private float _logAt; private float _peak; private KeyCode _activeKey = (KeyCode)324; private LineRenderer? _rope; private Material? _ropeMat; private bool _grabTweaked; private float _savedRelease; private float _savedMaxDist; private PhysGrabber? _tweaked; private PhysGrabber? Grabber { get { PlayerAvatar val = (((Object)(object)_pc != (Object)null) ? _pc.playerAvatarScript : null); if ((Object)(object)val == (Object)null) { return null; } return ((Object)(object)val.physGrabber != (Object)null) ? val.physGrabber : null; } } private bool Grabbing { get { PhysGrabber grabber = Grabber; return (Object)(object)grabber != (Object)null && grabber.grabbed; } } private void Awake() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) ((Component)this).TryGetComponent(ref _pc); ((Component)this).TryGetComponent(ref _rb); _mask = LayerMask.op_Implicit(LayerMask.GetMask(new string[3] { "Default", "Environment", "NavmeshOnly" })); } private void Log(string m) { if (WebSwingPatch.Debug.Value) { RepoWallClimb.Logger.LogInfo((object)("[Web] " + m)); } } private void OnDestroy() { Shutdown(); } private void OnDisable() { Shutdown(); } private void Shutdown() { Cut(); Active = false; FarClip.Release(FarClip.User.Web); RestoreGrabHold(); } public void Tick(PlayerController pc) { //IL_0061: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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) if ((Object)(object)_pc == (Object)null) { _pc = pc; } if (!WebSwingPatch.Enabled.Value) { if (Active) { Release("disabled"); } return; } KeyCode val = (Grabbing ? WebSwingPatch.KeyWhileGrabbing.Value : WebSwingPatch.Key.Value); if (Active) { val = _activeKey; } bool key = Input.GetKey(val); if (key && !Active) { Shoot(val); } else if (!key && Active) { Release("key up"); } if (!Active) { return; } float y = Input.mouseScrollDelta.y; if (Mathf.Abs(y) > 0.01f) { float length = _length; _length = Mathf.Clamp(_length - y * WebSwingPatch.LengthStep.Value, WebSwingPatch.MinLength.Value, WebSwingPatch.MaxLength.Value); if ((Object)(object)_joint != (Object)null) { _joint.maxDistance = _length; } if (!Mathf.Approximately(length, _length)) { Log($"LENGTH {length:F1} -> {_length:F1} (wheel)"); } } } private void Shoot(KeyCode key) { //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_pc == (Object)null || (Object)(object)_rb == (Object)null) { return; } if (WebSwingPatch.BlockWhileGrabbing.Value && Grabbing) { Log("BLOCKED: holding an object"); } else if ((Object)(object)_pc.playerAvatarScript != (Object)null && _pc.playerAvatarScript.isTumbling) { Log("BLOCKED: tumbling"); } else { if ((Object)(object)_pc.cameraGameObject == (Object)null) { return; } Transform transform = _pc.cameraGameObject.transform; float value = WebSwingPatch.Range.Value; float num = Mathf.Max(0f, WebSwingPatch.CastRadius.Value); RaycastHit val = default(RaycastHit); if (!((num > 0.001f) ? Physics.SphereCast(transform.position, num, transform.forward, ref val, value, LayerMask.op_Implicit(_mask), (QueryTriggerInteraction)1) : Physics.Raycast(transform.position, transform.forward, ref val, value, LayerMask.op_Implicit(_mask), (QueryTriggerInteraction)1))) { Log($"MISS: no surface within {value:F0}m"); return; } Collider collider = ((RaycastHit)(ref val)).collider; if ((Object)(object)collider == (Object)null) { return; } if (((Component)collider).CompareTag("Player") || ((Component)collider).CompareTag("Enemy")) { Log("MISS: '" + ((Object)collider).name + "' is a creature"); return; } if (!WebSwingPatch.AllowMovable.Value) { Rigidbody attachedRigidbody = collider.attachedRigidbody; if ((Object)(object)attachedRigidbody != (Object)null && !attachedRigidbody.isKinematic) { Log("MISS: '" + ((Object)collider).name + "' is movable (rigidbody)"); return; } if (((Component)collider).CompareTag("Phys Grab Object") || (Object)(object)((Component)collider).GetComponentInParent() != (Object)null) { Log("MISS: '" + ((Object)collider).name + "' is a grabbable object"); return; } } if (!WebSwingPatch.AllowFloor.Value) { float num2 = Vector3.Dot(((RaycastHit)(ref val)).normal, Vector3.up); if (num2 > WebSwingPatch.MaxFloorDot.Value) { Log($"MISS: '{((Object)collider).name}' is a floor (up={num2:F2})"); return; } } WallClimb climb = WallClimbPatch2.Climb; if ((Object)(object)climb != (Object)null && climb.Attached) { Log("detaching from wall to swing"); climb.ForceDetach(); } _anchor = ((RaycastHit)(ref val)).point; _length = Mathf.Clamp(Vector3.Distance(_rb.position, _anchor), WebSwingPatch.MinLength.Value, WebSwingPatch.MaxLength.Value); CreateJoint(); Active = true; _activeKey = key; _logAt = 0f; _peak = 0f; FarClip.Request(FarClip.User.Web, _length + 20f); Log($"SHOT hit='{((Object)collider).name}' dist={_length:F1}m anchor={Fmt(_anchor)} " + $"key={key} grabbing={Grabbing}"); } } private void CreateJoint() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) Cut(); _joint = ((Component)this).gameObject.AddComponent(); ((Joint)_joint).autoConfigureConnectedAnchor = false; ((Joint)_joint).connectedBody = null; ((Joint)_joint).anchor = Vector3.zero; ((Joint)_joint).connectedAnchor = _anchor; _joint.spring = WebSwingPatch.Spring.Value; _joint.damper = WebSwingPatch.Damper.Value; _joint.minDistance = 0f; _joint.maxDistance = _length; ((Joint)_joint).massScale = 1f; ((Joint)_joint).connectedMassScale = 1f; ((Joint)_joint).enableCollision = true; ((Joint)_joint).enablePreprocessing = false; _joint.tolerance = Mathf.Max(0f, WebSwingPatch.Tolerance.Value); EnsureRope(); } private void Cut() { if ((Object)(object)_joint != (Object)null) { Object.Destroy((Object)(object)_joint); _joint = null; } if ((Object)(object)_rope != (Object)null) { ((Renderer)_rope).enabled = false; } } private void Release(string why) { //IL_001c: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (((Object)(object)_rb != (Object)null) ? _rb.velocity : Vector3.zero); Cut(); Active = false; FarClip.Release(FarClip.User.Web); RestoreGrabHold(); Log($"RELEASE speed={((Vector3)(ref val)).magnitude:F1} peak={_peak:F1} " + "dir=" + Fmt(((Vector3)(ref val)).normalized) + " (" + why + ")"); _peak = 0f; } public void Physics(PlayerController pc) { //IL_00b9: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0275: 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_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_pc == (Object)null) { _pc = pc; } if (!Active || (Object)(object)_rb == (Object)null || (Object)(object)_pc == (Object)null) { return; } if ((Object)(object)_joint == (Object)null) { Release("joint lost"); return; } if ((Object)(object)_pc.playerAvatarScript != (Object)null && _pc.playerAvatarScript.isTumbling) { Release("tumbling"); return; } float fixedDeltaTime = Time.fixedDeltaTime; ApplyGrabHold(); Vector3 val = _anchor - _rb.position; float magnitude = ((Vector3)(ref val)).magnitude; if (WebSwingPatch.StiffRope.Value && magnitude > _length && magnitude > 0.001f) { Vector3 val2 = val / magnitude; float num = Vector3.Dot(_rb.velocity, val2); if (num < 0f) { _rb.AddForce(-val2 * num, (ForceMode)2); } } float value = WebSwingPatch.AirControl.Value; Vector3 val5; if (value > 0f && (Object)(object)_pc.cameraGameObject != (Object)null) { float num2 = Input.GetAxisRaw("Horizontal"); float num3 = Input.GetAxisRaw("Vertical"); if (Mathf.Abs(num2) < 0.01f && Mathf.Abs(num3) < 0.01f) { if (Input.GetKey((KeyCode)97)) { num2 -= 1f; } if (Input.GetKey((KeyCode)100)) { num2 += 1f; } if (Input.GetKey((KeyCode)115)) { num3 -= 1f; } if (Input.GetKey((KeyCode)119)) { num3 += 1f; } } if (Mathf.Abs(num2) > 0.01f || Mathf.Abs(num3) > 0.01f) { Transform transform = _pc.cameraGameObject.transform; Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(transform.forward.x, 0f, transform.forward.z); Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(transform.right.x, 0f, transform.right.z); if (((Vector3)(ref val3)).sqrMagnitude > 0.0001f && ((Vector3)(ref val4)).sqrMagnitude > 0.0001f) { val5 = ((Vector3)(ref val3)).normalized * num3 + ((Vector3)(ref val4)).normalized * num2; Vector3 normalized = ((Vector3)(ref val5)).normalized; _rb.AddForce(normalized * (value * 20f * fixedDeltaTime), (ForceMode)2); } } } val5 = _rb.velocity; float magnitude2 = ((Vector3)(ref val5)).magnitude; if (magnitude2 > _peak) { _peak = magnitude2; } if (Time.time >= _logAt) { _logAt = Time.time + 1f; Log($"SWING len={_length:F1} dist={magnitude:F1} stretch={magnitude - _length:+0.00;-0.00} " + $"speed={magnitude2:F1} peak={_peak:F1} vy={_rb.velocity.y:F1} " + $"suppress={WebSwingPatch.SuppressMove.Value}"); } } private void ApplyGrabHold() { if (!WebSwingPatch.KeepGrabbed.Value) { RestoreGrabHold(); return; } PhysGrabber grabber = Grabber; if ((Object)(object)grabber == (Object)null || !grabber.grabbed) { RestoreGrabHold(); return; } if (_grabTweaked && (Object)(object)_tweaked != (Object)(object)grabber) { RestoreGrabHold(); } if (!_grabTweaked) { _tweaked = grabber; _savedRelease = grabber.grabReleaseDistance; _savedMaxDist = grabber.maxDistanceFromPlayer; _grabTweaked = true; Log($"GRAB hold: releaseDistance {_savedRelease:F1} -> " + $"{WebSwingPatch.GrabReleaseDistance.Value:F0}, " + $"maxDistance {_savedMaxDist:F1} -> " + $"{WebSwingPatch.GrabHoldDistance.Value:F1}"); } grabber.grabReleaseDistance = WebSwingPatch.GrabReleaseDistance.Value; grabber.maxDistanceFromPlayer = Mathf.Max(WebSwingPatch.GrabHoldDistance.Value, grabber.minDistanceFromPlayer + 0.1f); } private void RestoreGrabHold() { if (_grabTweaked) { if ((Object)(object)_tweaked != (Object)null) { _tweaked.grabReleaseDistance = _savedRelease; _tweaked.maxDistanceFromPlayer = _savedMaxDist; Log($"GRAB hold restored (releaseDistance {_savedRelease:F1}, " + $"maxDistance {_savedMaxDist:F1})"); } _tweaked = null; _grabTweaked = false; } } private void EnsureRope() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_00b2: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) if (!WebSwingPatch.ShowRope.Value) { return; } if ((Object)(object)_rope == (Object)null) { GameObject val = new GameObject("WebRope"); val.transform.SetParent(((Component)this).transform, false); _rope = val.AddComponent(); _rope.positionCount = 2; _rope.useWorldSpace = true; ((Renderer)_rope).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)_rope).receiveShadows = false; _rope.numCapVertices = 2; Shader val2 = Shader.Find("Hidden/Internal-Colored"); _ropeMat = ((!((Object)(object)val2 != (Object)null)) ? ((Material)null) : new Material(val2)); if ((Object)(object)_ropeMat != (Object)null) { Color val3 = ParseColor(WebSwingPatch.RopeColor.Value, Color.white); _ropeMat.color = val3; if (_ropeMat.HasProperty("_Color")) { _ropeMat.SetColor("_Color", val3); } ((Renderer)_rope).sharedMaterial = _ropeMat; } } float value = WebSwingPatch.RopeWidth.Value; _rope.startWidth = value; _rope.endWidth = value; ((Renderer)_rope).enabled = true; } private void LateUpdate() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_rope == (Object)null) { return; } if (!Active || !WebSwingPatch.ShowRope.Value) { ((Renderer)_rope).enabled = false; return; } Vector3 val = ((Component)this).transform.position + Vector3.up * 1.1f; if ((Object)(object)_pc != (Object)null && (Object)(object)_pc.cameraGameObject != (Object)null) { Transform transform = _pc.cameraGameObject.transform; val = transform.position + transform.right * 0.25f - transform.up * 0.2f; } ((Renderer)_rope).enabled = true; _rope.SetPosition(0, val); _rope.SetPosition(1, _anchor); } private static string Fmt(Vector3 v) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) return $"({v.x:F2},{v.y:F2},{v.z:F2})"; } private static Color ParseColor(string s, Color fallback) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) string[] array = s.Split(','); if (array.Length < 3) { return fallback; } if (float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2) && float.TryParse(array[2], out var result3)) { return new Color(result, result2, result3); } return fallback; } } }