Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of AttackDirectionFix v1.2.7
plugins/AttackDirectionFix/AttackDirectionFix.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using AttackDirectionFix.Patches; using AttackDirectionFix.Utils; using BepInEx; using BepInEx.Logging; using HG; using HG.Reflection; using HarmonyLib; using IL.RoR2.Projectile; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using MonoMod.Utils; using On.RoR2; using On.RoR2.Projectile; using R2API.Utils; using RoR2; using RoR2.ConVar; using RoR2.Projectile; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: NetworkCompatibility(/*Could not decode attribute arguments.*/)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("AttackDirectionFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+46bfe108fb0b4bcbaea65361c5eae62984080e3e")] [assembly: AssemblyProduct("AttackDirectionFix")] [assembly: AssemblyTitle("AttackDirectionFix")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } internal static class IsExternalInit { } } namespace AttackDirectionFix { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Gorakh.AttackDirectionFix", "AttackDirectionFix", "1.2.7")] public sealed class AttackDirectionFixPlugin : BaseUnityPlugin { public const string PluginGUID = "Gorakh.AttackDirectionFix"; public const string PluginAuthor = "Gorakh"; public const string PluginName = "AttackDirectionFix"; public const string PluginVersion = "1.2.7"; private void Awake() { Stopwatch stopwatch = Stopwatch.StartNew(); Log.Init(((BaseUnityPlugin)this).Logger); AimOriginOverridePatch.Init(); ProjectileGhostOffsetPatch.Init(); PlayerAimVisualizer.Init(); stopwatch.Stop(); Log.Info_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalSeconds:F2} seconds"); } } internal static class Log { private static readonly StringBuilder _sharedStringBuilder; private static readonly int _cachedCallerPathPrefixLength; private static ManualLogSource _logSource; static Log() { _sharedStringBuilder = new StringBuilder(256); _cachedCallerPathPrefixLength = getCallerPathPrefixLength("X:\\Git\\RoR2\\AttackDirectionFix\\AttackDirectionFix\\Log.cs"); static int getCallerPathPrefixLength([CallerFilePath] string callerPath = null) { int num = callerPath.LastIndexOf("AttackDirectionFix\\"); if (num >= 0) { return num + "AttackDirectionFix\\".Length; } Debug.LogError((object)"[AttackDirectionFix] Logger failed to determine caller path prefix length"); return 0; } } internal static void Init(ManualLogSource logSource) { _logSource = logSource; } private static StringBuilder AppendCallerPrefix(this StringBuilder stringBuilder, string callerPath, string callerMemberName, int callerLineNumber) { return stringBuilder.Append(callerPath, _cachedCallerPathPrefixLength, callerPath.Length - _cachedCallerPathPrefixLength).Append(':').Append(callerLineNumber) .Append(" (") .Append(callerMemberName) .Append("):"); } private static StringBuilder buildCallerLogString(string callerPath, string callerMemberName, int callerLineNumber, object data) { return _sharedStringBuilder.Clear().AppendCallerPrefix(callerPath, callerMemberName, callerLineNumber).Append(' ') .Append(data); } [Conditional("DEBUG")] internal static void Debug(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogDebug((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [Conditional("DEBUG")] internal static void Debug_NoCallerPrefix(object data) { _logSource.LogDebug(data); } internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogError((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Error_NoCallerPrefix(object data) { _logSource.LogError(data); } internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogFatal((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Fatal_NoCallerPrefix(object data) { _logSource.LogFatal(data); } internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogInfo((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Info_NoCallerPrefix(object data) { _logSource.LogInfo(data); } internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogMessage((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Message_NoCallerPrefix(object data) { _logSource.LogMessage(data); } internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogWarning((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Warning_NoCallerPrefix(object data) { _logSource.LogWarning(data); } internal static void LogType(LogLevel level, object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if ((level & 0x20) == 0) { _logSource.Log(level, (object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void LogType_NoCallerPrefix(LogLevel level, object data) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if ((level & 0x20) == 0) { _logSource.Log(level, data); } } } internal static class PlayerAimVisualizer { [CompilerGenerated] private static class <>O { public static SceneCameraDelegate <0>__SceneCameraPreCull; } private static GameObject _aimOriginVisualizer; private static GameObject _cameraPivotVisualizer; private static readonly BoolConVar _cvEnableAimVisualization = new BoolConVar("debug_aim_visualization", (ConVarFlags)0, "0", "Enables/Disables player aim visualization. Green=Aim Origin, Red=Camera Pivot"); public static void Init() { //IL_0034: 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_0052: 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_00a4: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown _aimOriginVisualizer = GameObject.CreatePrimitive((PrimitiveType)0); Object.DontDestroyOnLoad((Object)(object)_aimOriginVisualizer); _aimOriginVisualizer.GetComponent<Collider>().enabled = false; _aimOriginVisualizer.GetComponent<Renderer>().material.color = Color.green; _aimOriginVisualizer.transform.localScale = Vector3.one * 0.1f; _cameraPivotVisualizer = GameObject.CreatePrimitive((PrimitiveType)0); Object.DontDestroyOnLoad((Object)(object)_cameraPivotVisualizer); _cameraPivotVisualizer.GetComponent<Collider>().enabled = false; _cameraPivotVisualizer.GetComponent<Renderer>().material.color = Color.red; _cameraPivotVisualizer.transform.localScale = Vector3.one * 0.1f; object obj = <>O.<0>__SceneCameraPreCull; if (obj == null) { SceneCameraDelegate val = SceneCameraPreCull; <>O.<0>__SceneCameraPreCull = val; obj = (object)val; } SceneCamera.onSceneCameraPreCull += (SceneCameraDelegate)obj; } private static void SceneCameraPreCull(SceneCamera sceneCamera) { //IL_008a: 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) if (Object.op_Implicit((Object)(object)_aimOriginVisualizer)) { _aimOriginVisualizer.SetActive(false); } if (Object.op_Implicit((Object)(object)_cameraPivotVisualizer)) { _cameraPivotVisualizer.SetActive(false); } if (!_cvEnableAimVisualization.value) { return; } CameraRigController cameraRigController = sceneCamera.cameraRigController; if (Object.op_Implicit((Object)(object)cameraRigController) && cameraRigController.localUserViewer != null) { CharacterBody targetBody = cameraRigController.targetBody; if (Object.op_Implicit((Object)(object)targetBody) && Object.op_Implicit((Object)(object)_aimOriginVisualizer)) { _aimOriginVisualizer.SetActive(true); _aimOriginVisualizer.transform.position = targetBody.inputBank.aimOrigin; } CameraTargetParams targetParams = cameraRigController.targetParams; if (Object.op_Implicit((Object)(object)targetParams) && Object.op_Implicit((Object)(object)targetParams.cameraPivotTransform) && Object.op_Implicit((Object)(object)_cameraPivotVisualizer)) { _cameraPivotVisualizer.SetActive(true); _cameraPivotVisualizer.transform.position = targetParams.cameraPivotTransform.position; } } } } public static class ProjectileAttributes { private sealed class ProjectileMovementTracker : MonoBehaviour { private const float MovementEpsilon = 0.1f; private ProjectileController _projectileController; private Vector3 _startPosition; private bool _hasMoved; private void Awake() { _projectileController = ((Component)this).GetComponent<ProjectileController>(); } private void Start() { //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) _startPosition = ((Component)this).transform.position; } private void FixedUpdate() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (!_hasMoved) { Vector3 val = ((Component)this).transform.position - _startPosition; if (((Vector3)(ref val)).sqrMagnitude >= 0.010000001f) { _hasMoved = true; } } } private void OnDestroy() { int num = (Object.op_Implicit((Object)(object)_projectileController) ? _projectileController.catalogIndex : (-1)); if (num >= 0) { reportProjectileStationary(num, !_hasMoved); } } } private static HashSet<GameObject> _collectingProjectilePrefabsBlacklist = new HashSet<GameObject>(); private static HashSet<string> _collectingProjectileNamesBlacklist = new HashSet<string>(); private static int[] _projectileBlacklist = Array.Empty<int>(); private static bool[] _isStationaryLookup = Array.Empty<bool>(); [SystemInitializer(new Type[] { typeof(ProjectileCatalog) })] private static void Init() { if (ProjectileCatalog.projectilePrefabCount > 0) { _isStationaryLookup = new bool[ProjectileCatalog.projectilePrefabCount]; ProjectileSimple val = default(ProjectileSimple); BoomerangProjectile val2 = default(BoomerangProjectile); CleaverProjectile val3 = default(CleaverProjectile); DaggerController val4 = default(DaggerController); MissileController val5 = default(MissileController); ProjectileCharacterController val6 = default(ProjectileCharacterController); ProjectileOwnerOrbiter val7 = default(ProjectileOwnerOrbiter); SoulSearchController val8 = default(SoulSearchController); Rigidbody val9 = default(Rigidbody); for (int i = 0; i < ProjectileCatalog.projectilePrefabCount; i++) { GameObject projectilePrefab = ProjectileCatalog.GetProjectilePrefab(i); if (Object.op_Implicit((Object)(object)projectilePrefab)) { bool flag = (!projectilePrefab.TryGetComponent<ProjectileSimple>(ref val) || (!(val.desiredForwardSpeed > 0f) && !val.oscillate)) && (!projectilePrefab.TryGetComponent<BoomerangProjectile>(ref val2) || !(val2.travelSpeed > 0f)) && (!projectilePrefab.TryGetComponent<CleaverProjectile>(ref val3) || !(val3.travelSpeed > 0f)) && (!projectilePrefab.TryGetComponent<DaggerController>(ref val4) || !(val4.acceleration > 0f)) && (!projectilePrefab.TryGetComponent<MissileController>(ref val5) || (!(val5.maxVelocity > 0f) && !(val5.acceleration > 0f))) && (!projectilePrefab.TryGetComponent<ProjectileCharacterController>(ref val6) || !(val6.velocity > 0f)) && (!projectilePrefab.TryGetComponent<ProjectileOwnerOrbiter>(ref val7) || !(val7.degreesPerSecond > 0f)) && (!projectilePrefab.TryGetComponent<SoulSearchController>(ref val8) || !(val8.maxVelocity > 0f)) && (!projectilePrefab.TryGetComponent<Rigidbody>(ref val9) || val9.isKinematic); _isStationaryLookup[i] = flag; projectilePrefab.AddComponent<ProjectileMovementTracker>(); } } } BlacklistProjectile("DrifterJunkCubeProjectile"); BlacklistProjectile("JunkCubePrefab"); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(onLoad)); } private static void onLoad() { HashSet<int> hashSet = new HashSet<int>(); foreach (GameObject item in _collectingProjectilePrefabsBlacklist) { int projectileIndex = ProjectileCatalog.GetProjectileIndex(item); if (projectileIndex >= 0) { hashSet.Add(projectileIndex); } } foreach (string item2 in _collectingProjectileNamesBlacklist) { int num = ProjectileCatalog.FindProjectileIndex(item2); if (num >= 0) { hashSet.Add(num); } } if (hashSet.Count > 0) { _projectileBlacklist = hashSet.ToArray(); Array.Sort(_projectileBlacklist); } _collectingProjectilePrefabsBlacklist = null; _collectingProjectileNamesBlacklist = null; } public static void BlacklistProjectile(GameObject projectilePrefab) { if (_collectingProjectilePrefabsBlacklist == null) { throw new InvalidOperationException("Cannot add to blacklist after game has loaded"); } _collectingProjectilePrefabsBlacklist.Add(projectilePrefab); } public static void BlacklistProjectile(string projectileName) { if (_collectingProjectileNamesBlacklist == null) { throw new InvalidOperationException("Cannot add to blacklist after game has loaded"); } _collectingProjectileNamesBlacklist.Add(projectileName); } private static void reportProjectileStationary(int projectileIndex, bool stationary) { if (ArrayUtils.IsInBounds<bool>(_isStationaryLookup, projectileIndex) && _isStationaryLookup[projectileIndex] != stationary) { _isStationaryLookup[projectileIndex] = stationary; } GameObject projectilePrefab = ProjectileCatalog.GetProjectilePrefab(projectileIndex); ProjectileMovementTracker projectileMovementTracker = default(ProjectileMovementTracker); if (Object.op_Implicit((Object)(object)projectilePrefab) && projectilePrefab.TryGetComponent<ProjectileMovementTracker>(ref projectileMovementTracker)) { Object.Destroy((Object)(object)projectileMovementTracker); } } public static bool IsStationaryProjectile(int projectileIndex) { return ArrayUtils.GetSafe<bool>(_isStationaryLookup, projectileIndex); } public static bool IsProjectileBlacklisted(int projectileIndex) { return Array.BinarySearch(_projectileBlacklist, projectileIndex) >= 0; } public static bool ShouldModifyFireDirection(int projectileIndex) { if (!IsProjectileBlacklisted(projectileIndex)) { return !IsStationaryProjectile(projectileIndex); } return false; } } public sealed class ProjectileInitialOffset : MonoBehaviour { public float StartTime; public Vector3 InitialPositionOffset; public Quaternion InitialRotationOffset = Quaternion.identity; public float InterpolationTime; private float age => Time.time - StartTime; private float interpolationFraction => Mathf.Pow(Mathf.Clamp01(age / InterpolationTime), 1f / 3f); public Vector3 CurrentPositionOffset => Vector3.Lerp(InitialPositionOffset, Vector3.zero, interpolationFraction); public Quaternion CurrentRotationOffset => Quaternion.Lerp(InitialRotationOffset, Quaternion.identity, interpolationFraction); private void FixedUpdate() { if (age >= InterpolationTime) { Object.Destroy((Object)(object)this); } } } } namespace AttackDirectionFix.Utils { public static class CameraRigUtils { public static CameraRigController FindCameraRigControllerForBody(CharacterBody body) { return ((IEnumerable<CameraRigController>)CameraRigController.readOnlyInstancesList).FirstOrDefault((Func<CameraRigController, bool>)((CameraRigController c) => (Object)(object)c.targetBody == (Object)(object)body)); } } public static class VectorUtils { public static Vector3 ClosestPointAlongRay(Ray ray, Vector3 target) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_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) return ((Ray)(ref ray)).origin + ((Ray)(ref ray)).direction * Vector3.Dot(((Ray)(ref ray)).direction, target - ((Ray)(ref ray)).origin); } } } namespace AttackDirectionFix.Patches { internal static class AimOriginOverridePatch { private delegate Vector3 orig_get_aimOrigin(InputBankTest self); [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_FindBestInteractableObject <>9__1_0; internal GameObject <Init>b__1_0(orig_FindBestInteractableObject orig, InteractionDriver self) { _tempDisablePatch = true; try { return orig.Invoke(self); } finally { _tempDisablePatch = false; } } } private static bool _tempDisablePatch; public static void Init() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.DeclaredPropertyGetter(typeof(InputBankTest), "aimOrigin"); if ((object)methodInfo != null) { new Hook((MethodBase)methodInfo, (Delegate)new Func<orig_get_aimOrigin, InputBankTest, Vector3>(InputBankTest_get_aimOrigin)); } else { Log.Error_NoCallerPrefix("Unable to find InputBankTest.aimOrigin getter"); } object obj = <>c.<>9__1_0; if (obj == null) { hook_FindBestInteractableObject val = delegate(orig_FindBestInteractableObject orig, InteractionDriver self) { _tempDisablePatch = true; try { return orig.Invoke(self); } finally { _tempDisablePatch = false; } }; <>c.<>9__1_0 = val; obj = (object)val; } InteractionDriver.FindBestInteractableObject += (hook_FindBestInteractableObject)obj; } public static Vector3 GetUnalteredAimOrigin(this InputBankTest inputBankTest) { //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_0016: Unknown result type (might be due to invalid IL or missing references) _tempDisablePatch = true; try { return inputBankTest.aimOrigin; } finally { _tempDisablePatch = false; } } private static Vector3 InputBankTest_get_aimOrigin(orig_get_aimOrigin orig, InputBankTest self) { //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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) Vector3 result = orig(self); if (!_tempDisablePatch) { CameraRigController val = CameraRigUtils.FindCameraRigControllerForBody(self.characterBody); if (Object.op_Implicit((Object)(object)val)) { CameraTargetParams targetParams = val.targetParams; if (Object.op_Implicit((Object)(object)targetParams) && Object.op_Implicit((Object)(object)targetParams.cameraPivotTransform)) { Vector3 position = targetParams.cameraPivotTransform.position; CameraState currentCameraState = val.currentCameraState; return VectorUtils.ClosestPointAlongRay(new Ray(currentCameraState.position, currentCameraState.rotation * Vector3.forward), position); } } } return result; } } public sealed class ProjectileDisplacementInfoProvider : MonoBehaviour { private sealed record DisplacementData(FireProjectileInfo OriginalFireProjectileInfo) { [CompilerGenerated] private bool PrintMembers(StringBuilder builder) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) RuntimeHelpers.EnsureSufficientExecutionStack(); builder.Append("OriginalFireProjectileInfo = "); FireProjectileInfo originalFireProjectileInfo = OriginalFireProjectileInfo; builder.Append(((object)(FireProjectileInfo)(ref originalFireProjectileInfo)).ToString()); return true; } } [CompilerGenerated] private static class <>O { public static Manipulator <0>__modifyFirePositionPatch; public static <>A{00000009}<FireProjectileInfo, DisplacementData> <1>__tryModifyFireInfo; public static Action<GameObject, FireProjectileInfo, DisplacementData> <2>__handleProjectileInstantiate; } public FireProjectileInfo UnmodifiedFireProjectileInfo { get; private set; } public FireProjectileInfo ModifiedFireProjectileInfo { get; private set; } [SystemInitializer(new Type[] { })] private static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<0>__modifyFirePositionPatch; if (obj == null) { Manipulator val = modifyFirePositionPatch; <>O.<0>__modifyFirePositionPatch = val; obj = (object)val; } ProjectileManager.FireProjectileServer += (Manipulator)obj; object obj2 = <>O.<0>__modifyFirePositionPatch; if (obj2 == null) { Manipulator val2 = modifyFirePositionPatch; <>O.<0>__modifyFirePositionPatch = val2; obj2 = (object)val2; } ProjectileManager.FireProjectileClient += (Manipulator)obj2; static void handleProjectileInstantiate(GameObject projectile, FireProjectileInfo fireProjectileInfo, DisplacementData displacementData) { //IL_001a: 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 (Object.op_Implicit((Object)(object)projectile) && !(displacementData == null)) { ProjectileDisplacementInfoProvider projectileDisplacementInfoProvider = projectile.AddComponent<ProjectileDisplacementInfoProvider>(); projectileDisplacementInfoProvider.UnmodifiedFireProjectileInfo = displacementData.OriginalFireProjectileInfo; projectileDisplacementInfoProvider.ModifiedFireProjectileInfo = fireProjectileInfo; } } static void modifyFirePositionPatch(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_007e: 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_00eb: 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_0104: Unknown result type (might be due to invalid IL or missing references) ILCursor val7 = new ILCursor(il); ParameterDefinition val8 = ((IEnumerable<ParameterDefinition>)((MethodReference)il.Method).Parameters).FirstOrDefault((Func<ParameterDefinition, bool>)((ParameterDefinition p) => Extensions.Is((MemberReference)(object)((ParameterReference)p).ParameterType, (MemberInfo)typeof(FireProjectileInfo)))); if (val8 == null) { Log.Error("Failed to find FireProjectileInfo parameter", "X:\\Git\\RoR2\\AttackDirectionFix\\AttackDirectionFix\\Patches\\ProjectileDisplacementInfoProvider.cs", "Init", 30); } else { VariableDefinition val9 = new VariableDefinition(il.Import(typeof(DisplacementData))); il.Method.Body.Variables.Add(val9); val7.Emit(OpCodes.Ldarga, val8); val7.Emit(OpCodes.Ldloca, val9); val7.EmitDelegate<<>A{00000009}<FireProjectileInfo, DisplacementData>>((<>A{00000009}<FireProjectileInfo, DisplacementData>)tryModifyFireInfo); if (val7.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => Object.Instantiate<GameObject>((GameObject)null, default(Vector3), default(Quaternion))))) })) { val7.Emit(OpCodes.Dup); val7.Emit(OpCodes.Ldarg, val8); val7.Emit(OpCodes.Ldloc, val9); val7.EmitDelegate<Action<GameObject, FireProjectileInfo, DisplacementData>>((Action<GameObject, FireProjectileInfo, DisplacementData>)handleProjectileInstantiate); } else { Log.Error("Failed to find instantiate call", "X:\\Git\\RoR2\\AttackDirectionFix\\AttackDirectionFix\\Patches\\ProjectileDisplacementInfoProvider.cs", "Init", 101); } } } static void tryModifyFireInfo(ref FireProjectileInfo fireProjectileInfo, ref DisplacementData displacementData) { //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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_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_00a5: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) CharacterBody val3 = default(CharacterBody); if (Object.op_Implicit((Object)(object)fireProjectileInfo.owner) && fireProjectileInfo.owner.TryGetComponent<CharacterBody>(ref val3) && val3.isPlayerControlled && ProjectileAttributes.ShouldModifyFireDirection(ProjectileCatalog.GetProjectileIndex(fireProjectileInfo.projectilePrefab))) { InputBankTest inputBank = val3.inputBank; if (Object.op_Implicit((Object)(object)inputBank)) { Vector3 val4 = fireProjectileInfo.position; Vector3 val5 = val4 - inputBank.aimOrigin; if (((Vector3)(ref val5)).sqrMagnitude <= Mathf.Epsilon) { val4 = inputBank.GetUnalteredAimOrigin(); } float num = val3.bestFitRadius * 1.5f; float num2 = num * num; Vector3 val6 = val3.corePosition - val4; if (!(((Vector3)(ref val6)).sqrMagnitude > num2)) { FireProjectileInfo originalFireProjectileInfo = fireProjectileInfo; originalFireProjectileInfo.position = val4; displacementData = new DisplacementData(originalFireProjectileInfo); fireProjectileInfo.position = inputBank.aimOrigin; } } } } } } internal static class ProjectileGhostOffsetPatch { [CompilerGenerated] private static class <>O { public static Manipulator <0>__ProjectileController_Start; public static hook_LerpTransform <1>__ProjectileGhostController_LerpTransform; public static hook_CopyTransform <2>__ProjectileGhostController_CopyTransform; public static hook_TrySticking <3>__ProjectileStickOnImpact_TrySticking; public static <>A{00000490}<ProjectileController, bool, Vector3, Quaternion> <4>__getOffsets; public static Func<Vector3, Vector3, Vector3> <5>__getVisualPosition; public static Func<Quaternion, Quaternion, Quaternion> <6>__getVisualRotation; public static Action<ProjectileController, bool, Vector3, Quaternion> <7>__initializeGhostOffset; } private static readonly FloatConVar _cvProjectileInterpolationTime = new FloatConVar("projectile_visual_interp", (ConVarFlags)0, "0.7", "[Attack Direction Fix] How long projectile visuals should take to interpolate to their actual path"); public static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //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_005b: Expected O, but got Unknown //IL_0070: 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_007b: Expected O, but got Unknown object obj = <>O.<0>__ProjectileController_Start; if (obj == null) { Manipulator val = ProjectileController_Start; <>O.<0>__ProjectileController_Start = val; obj = (object)val; } ProjectileController.Start += (Manipulator)obj; object obj2 = <>O.<1>__ProjectileGhostController_LerpTransform; if (obj2 == null) { hook_LerpTransform val2 = ProjectileGhostController_LerpTransform; <>O.<1>__ProjectileGhostController_LerpTransform = val2; obj2 = (object)val2; } ProjectileGhostController.LerpTransform += (hook_LerpTransform)obj2; object obj3 = <>O.<2>__ProjectileGhostController_CopyTransform; if (obj3 == null) { hook_CopyTransform val3 = ProjectileGhostController_CopyTransform; <>O.<2>__ProjectileGhostController_CopyTransform = val3; obj3 = (object)val3; } ProjectileGhostController.CopyTransform += (hook_CopyTransform)obj3; object obj4 = <>O.<3>__ProjectileStickOnImpact_TrySticking; if (obj4 == null) { hook_TrySticking val4 = ProjectileStickOnImpact_TrySticking; <>O.<3>__ProjectileStickOnImpact_TrySticking = val4; obj4 = (object)val4; } ProjectileStickOnImpact.TrySticking += (hook_TrySticking)obj4; } private static void ProjectileController_Start(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_00a2: 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_00bb: 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_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); VariableDefinition val2 = new VariableDefinition(il.Import(typeof(bool))); il.Method.Body.Variables.Add(val2); VariableDefinition positionOffsetVar = new VariableDefinition(il.Import(typeof(Vector3))); il.Method.Body.Variables.Add(positionOffsetVar); VariableDefinition rotationOffsetVar = new VariableDefinition(il.Import(typeof(Quaternion))); il.Method.Body.Variables.Add(rotationOffsetVar); val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldloca, val2); val.Emit(OpCodes.Ldloca, positionOffsetVar); val.Emit(OpCodes.Ldloca, rotationOffsetVar); val.EmitDelegate<<>A{00000490}<ProjectileController, bool, Vector3, Quaternion>>((<>A{00000490}<ProjectileController, bool, Vector3, Quaternion>)getOffsets); VariableDefinition rotationTempVar = new VariableDefinition(il.Import(typeof(Quaternion))); il.Method.Body.Variables.Add(rotationTempVar); if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => Object.Instantiate<GameObject>((GameObject)null, default(Vector3), default(Quaternion))))) })) { emitPositionRotationOffset(val); } else { Log.Error("Failed to find non-pooled ghost instantiate patch location", "X:\\Git\\RoR2\\AttackDirectionFix\\AttackDirectionFix\\Patches\\ProjectileGhostOffsetPatch.cs", "ProjectileController_Start", 104); } if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => EffectManager.GetAndActivatePooledEffect((GameObject)null, default(Vector3), default(Quaternion))))) })) { emitPositionRotationOffset(val); } else { Log.Error("Failed to find pooled ghost instantiate patch location", "X:\\Git\\RoR2\\AttackDirectionFix\\AttackDirectionFix\\Patches\\ProjectileGhostOffsetPatch.cs", "ProjectileController_Start", 114); } if (val.TryGotoNext((MoveType)1, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchRet(x) })) { val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldloc, val2); val.Emit(OpCodes.Ldloc, positionOffsetVar); val.Emit(OpCodes.Ldloc, rotationOffsetVar); val.EmitDelegate<Action<ProjectileController, bool, Vector3, Quaternion>>((Action<ProjectileController, bool, Vector3, Quaternion>)initializeGhostOffset); } else { Log.Error("Failed to find ret match", "X:\\Git\\RoR2\\AttackDirectionFix\\AttackDirectionFix\\Patches\\ProjectileGhostOffsetPatch.cs", "ProjectileController_Start", 156); } void emitPositionOffset(ILCursor c) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) c.Emit(OpCodes.Ldloc, positionOffsetVar); c.EmitDelegate<Func<Vector3, Vector3, Vector3>>((Func<Vector3, Vector3, Vector3>)getVisualPosition); } void emitPositionRotationOffset(ILCursor c) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) c.Emit(OpCodes.Stloc, rotationTempVar); emitPositionOffset(c); c.Emit(OpCodes.Ldloc, rotationTempVar); emitRotationOffset(c); } void emitRotationOffset(ILCursor c) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) c.Emit(OpCodes.Ldloc, rotationOffsetVar); c.EmitDelegate<Func<Quaternion, Quaternion, Quaternion>>((Func<Quaternion, Quaternion, Quaternion>)getVisualRotation); } static void getOffsets(ProjectileController projectileController, out bool hasVisualOffset, out Vector3 positionOffset, out Quaternion rotationOffset) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) hasVisualOffset = false; positionOffset = Vector3.zero; rotationOffset = Quaternion.identity; ProjectileDisplacementInfoProvider projectileDisplacementInfoProvider = default(ProjectileDisplacementInfoProvider); if (Object.op_Implicit((Object)(object)projectileController) && ((Component)projectileController).TryGetComponent<ProjectileDisplacementInfoProvider>(ref projectileDisplacementInfoProvider)) { FireProjectileInfo unmodifiedFireProjectileInfo = projectileDisplacementInfoProvider.UnmodifiedFireProjectileInfo; FireProjectileInfo modifiedFireProjectileInfo = projectileDisplacementInfoProvider.ModifiedFireProjectileInfo; Vector3 val3 = unmodifiedFireProjectileInfo.position - modifiedFireProjectileInfo.position; hasVisualOffset = true; positionOffset = val3; } } static Vector3 getVisualPosition(Vector3 position, Vector3 offset) { //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_0002: Unknown result type (might be due to invalid IL or missing references) return position + offset; } static Quaternion getVisualRotation(Quaternion rotation, Quaternion offset) { //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_0002: Unknown result type (might be due to invalid IL or missing references) return rotation * offset; } static void initializeGhostOffset(ProjectileController projectileController, bool hasVisualOffset, Vector3 positionOffset, Quaternion rotationOffset) { //IL_0043: 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_004a: 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) if (Object.op_Implicit((Object)(object)projectileController)) { ProjectileGhostController ghost = projectileController.ghost; if (Object.op_Implicit((Object)(object)ghost)) { ProjectileInitialOffset projectileInitialOffset = ((Component)ghost).GetComponent<ProjectileInitialOffset>(); if (hasVisualOffset) { if (!Object.op_Implicit((Object)(object)projectileInitialOffset)) { projectileInitialOffset = ((Component)ghost).gameObject.AddComponent<ProjectileInitialOffset>(); } projectileInitialOffset.StartTime = Time.time; projectileInitialOffset.InitialPositionOffset = positionOffset; projectileInitialOffset.InitialRotationOffset = rotationOffset; projectileInitialOffset.InterpolationTime = _cvProjectileInterpolationTime.value; } else if (Object.op_Implicit((Object)(object)projectileInitialOffset)) { Object.Destroy((Object)(object)projectileInitialOffset); } } } } } private static void ProjectileGhostController_LerpTransform(orig_LerpTransform orig, ProjectileGhostController self, Transform a, Transform b, float t) { orig.Invoke(self, a, b, t); tryApplyOffset(self); } private static void ProjectileGhostController_CopyTransform(orig_CopyTransform orig, ProjectileGhostController self, Transform src) { orig.Invoke(self, src); tryApplyOffset(self); } private static void tryApplyOffset(ProjectileGhostController ghostController) { //IL_001a: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) ProjectileInitialOffset projectileInitialOffset = default(ProjectileInitialOffset); if (Object.op_Implicit((Object)(object)ghostController) && ((Component)ghostController).TryGetComponent<ProjectileInitialOffset>(ref projectileInitialOffset)) { Transform transform = ghostController.transform; transform.position += projectileInitialOffset.CurrentPositionOffset; transform.rotation *= projectileInitialOffset.CurrentRotationOffset; } } private static bool ProjectileStickOnImpact_TrySticking(orig_TrySticking orig, ProjectileStickOnImpact self, Collider hitCollider, Vector3 impactNormal) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) bool num = orig.Invoke(self, hitCollider, impactNormal); ProjectileController val = default(ProjectileController); if (num && Object.op_Implicit((Object)(object)self) && ((Component)self).TryGetComponent<ProjectileController>(ref val)) { ProjectileGhostController ghost = val.ghost; ProjectileInitialOffset projectileInitialOffset = default(ProjectileInitialOffset); if (Object.op_Implicit((Object)(object)ghost) && ((Component)ghost).TryGetComponent<ProjectileInitialOffset>(ref projectileInitialOffset)) { Object.Destroy((Object)(object)projectileInitialOffset); } } return num; } } }