Decompiled source of ExtraWeaponCustomization v2.14.2
ExtraWeaponCustomization.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using AIGraph; using AK; using Agents; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Hook; using BepInEx.Unity.IL2CPP.Utils.Collections; using CharacterDestruction; using CullingSystem; using EWC.API; using EWC.CustomWeapon; using EWC.CustomWeapon.KillTracker; using EWC.CustomWeapon.ObjectWrappers; using EWC.CustomWeapon.Properties; using EWC.CustomWeapon.Properties.Effects; using EWC.CustomWeapon.Properties.Effects.Heal; using EWC.CustomWeapon.Properties.Effects.Hit.DOT; using EWC.CustomWeapon.Properties.Effects.Hit.DOT.DOTGlowFX; using EWC.CustomWeapon.Properties.Effects.Hit.Explosion; using EWC.CustomWeapon.Properties.Effects.Hit.Explosion.EEC_ExplosionFX; using EWC.CustomWeapon.Properties.Effects.Hit.Explosion.EEC_ExplosionFX.Handlers; using EWC.CustomWeapon.Properties.Effects.Triggers; using EWC.CustomWeapon.Properties.Traits; using EWC.CustomWeapon.Properties.Traits.CustomProjectile; using EWC.CustomWeapon.Properties.Traits.CustomProjectile.Components; using EWC.CustomWeapon.Properties.Traits.CustomProjectile.Managers; using EWC.CustomWeapon.WeaponContext; using EWC.CustomWeapon.WeaponContext.Contexts; using EWC.CustomWeapon.WeaponContext.Contexts.Triggers; using EWC.Dependencies; using EWC.JSON; using EWC.JSON.Converters; using EWC.Networking; using EWC.Networking.Structs; using EWC.Patches; using EWC.Patches.Melee; using EWC.Patches.Native; using EWC.Utils; using EWC.Utils.Log; using EndskApi.Api; using EndskApi.Enums.EnemyKill; using EndskApi.Information.EnemyKill; using Enemies; using ExtraRecoilData.API; using ExtraRecoilData.CustomRecoil; using FX_EffectSystem; using FirstPersonItem; using GTFO.API; using GTFO.API.JSON.Converters; using GTFO.API.Utilities; using GTFuckingXP.Extensions; using GTFuckingXP.Information.Level; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppInterop.Runtime.Runtime; using Il2CppSystem; using Il2CppSystem.Collections; using Il2CppSystem.Collections.Generic; using KillIndicatorFix; using LevelGeneration; using LevelGeneration.Core; using MTFO.API; using Microsoft.CodeAnalysis; using Player; using SNetwork; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("ExtraWeaponCustomization")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+c1bfd060f8e017f5c81a1db4b46697bb9494347e")] [assembly: AssemblyProduct("ExtraWeaponCustomization")] [assembly: AssemblyTitle("ExtraWeaponCustomization")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] 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; } } } namespace EWC { internal static class Configuration { private static readonly ConfigFile configFile; private static ConfigEntry<bool> ForceCreateTemplate { get; set; } public static bool ShowExplosionEffect { get; set; } public static bool PlayExplosionSFX { get; set; } public static float ExplosionSFXCooldown { get; set; } public static int ExplosionSFXShotOverride { get; set; } public static float AutoAimTickDelay { get; set; } public static float HomingTickDelay { get; set; } static Configuration() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown ShowExplosionEffect = true; PlayExplosionSFX = true; ExplosionSFXCooldown = 0.08f; ExplosionSFXShotOverride = 8; AutoAimTickDelay = 0.1f; HomingTickDelay = 0.1f; configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "ExtraWeaponCustomization.cfg"), true); BindAll(configFile); } internal static void Init() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown LiveEdit.CreateListener(Paths.ConfigPath, "ExtraWeaponCustomization.cfg", false).FileChanged += new LiveEditEventHandler(OnFileChanged); } private static void OnFileChanged(LiveEditEventArgs _) { configFile.Reload(); string text = "Auto Aim Settings"; AutoAimTickDelay = (float)configFile[text, "Search Cooldown"].BoxedValue; text = "Explosion Settings"; ShowExplosionEffect = (bool)configFile[text, "Show Effect"].BoxedValue; PlayExplosionSFX = (bool)configFile[text, "Play Sound"].BoxedValue; ExplosionSFXCooldown = (float)configFile[text, "SFX Cooldown"].BoxedValue; ExplosionSFXShotOverride = (int)configFile[text, "Shots to Override SFX Cooldown"].BoxedValue; text = "Projectile Settings"; HomingTickDelay = (float)configFile[text, "Homing Search Cooldown"].BoxedValue; CheckAndRefreshTemplate(); } [MemberNotNull("ForceCreateTemplate")] private static void BindAll(ConfigFile config) { string text = "Auto Aim Settings"; AutoAimTickDelay = config.Bind<float>(text, "Search Cooldown", AutoAimTickDelay, "Time between attempted searches to acquire targets.").Value; text = "Explosion Settings"; ShowExplosionEffect = config.Bind<bool>(text, "Show Effect", ShowExplosionEffect, "Enables explosion visual FX.").Value; PlayExplosionSFX = config.Bind<bool>(text, "Play Sound", PlayExplosionSFX, "Enables explosion sound FX.").Value; ExplosionSFXCooldown = config.Bind<float>(text, "SFX Cooldown", ExplosionSFXCooldown, "Minimum time between explosion sound effects, to prevent obnoxiously loud sounds.").Value; ExplosionSFXShotOverride = config.Bind<int>(text, "Shots to Override SFX Cooldown", ExplosionSFXShotOverride, "Amount of shots fired before another explosion sound effect is forced, regardless of cooldown.\nSmaller numbers let fast-firing weapons and shotguns make more sounds in a short span of time.").Value; text = "Projectile Settings"; HomingTickDelay = config.Bind<float>(text, "Homing Search Cooldown", HomingTickDelay, "Minimum time between attempted searches to acquire a new target.").Value; text = "Tools"; ForceCreateTemplate = config.Bind<bool>(text, "Force Create Template", false, "Creates the template file again."); } private static void CheckAndRefreshTemplate() { if (ForceCreateTemplate.Value) { ForceCreateTemplate.Value = false; CustomWeaponManager.Current.CreateTemplate(); configFile.Save(); } } } [BepInPlugin("Dinorush.ExtraWeaponCustomization", "ExtraWeaponCustomization", "2.14.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal sealed class EntryPoint : BasePlugin { public const string MODNAME = "ExtraWeaponCustomization"; public static bool Loaded { get; private set; } public override void Load() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) EWCLogger.Log("Loading ExtraWeaponCustomization"); if (!MTFOAPIWrapper.HasCustomContent) { EWCLogger.Error("No MTFO datablocks detected. Not loading EWC..."); return; } Loaded = true; new Harmony("ExtraWeaponCustomization").PatchAll(); EnemyDetectionPatches.ApplyNativePatch(); Configuration.Init(); LevelAPI.OnLevelCleanup += LevelAPI_OnLevelCleanup; LevelAPI.OnEnterLevel += LevelAPI_OnLevelEnter; AssetAPI.OnStartupAssetsLoaded += AssetAPI_OnStartupAssetsLoaded; EWCLogger.Log("Loaded ExtraWeaponCustomization"); } private void LevelAPI_OnLevelCleanup() { CustomWeaponManager.Current.ResetCWCs(activate: false); EWCProjectileManager.Reset(); DOTDamageManager.Reset(); } private void LevelAPI_OnLevelEnter() { CustomWeaponManager.Current.ActivateCWCs(); } private void AssetAPI_OnStartupAssetsLoaded() { ClassInjector.RegisterTypeInIl2Cpp<DOTGlowHandler>(); ClassInjector.RegisterTypeInIl2Cpp<ExplosionEffectHandler>(); ClassInjector.RegisterTypeInIl2Cpp<CustomWeaponComponent>(); ClassInjector.RegisterTypeInIl2Cpp<EWCProjectileComponentBase>(); ClassInjector.RegisterTypeInIl2Cpp<EWCProjectileComponentShooter>(); LayerUtil.Init(); ExplosionManager.Init(); DOTDamageManager.Init(); HealManager.Init(); TriggerManager.Init(); KillAPIWrapper.Init(); EWCProjectileManager.Init(); CustomWeaponManager.Current.GetCustomGunData(0u); } } } namespace EWC.Utils { internal static class DamageableUtil { private static IntPtr _cachedExpedition = default(IntPtr); private static float _cachedHealth = 15f; public static float LockHealth { get { if (RundownManager.ActiveExpedition != null && ((Il2CppObjectBase)RundownManager.ActiveExpedition).Pointer != _cachedExpedition) { _cachedExpedition = ((Il2CppObjectBase)RundownManager.ActiveExpedition).Pointer; _cachedHealth = RundownManager.ActiveExpeditionBalanceData.WeakDoorLockHealth; } return _cachedHealth; } } public static IDamageable? GetDamageableFromRayHit(RaycastHit rayHit) { if (!((Object)(object)((RaycastHit)(ref rayHit)).collider == (Object)null)) { return GetDamageableFromCollider(((RaycastHit)(ref rayHit)).collider); } return null; } public static IDamageable? GetDamageableFromCollider(Collider? collider) { if (!((Object)(object)collider == (Object)null)) { return GetDamageableFromGO(((Component)collider).gameObject); } return null; } public static IDamageable? GetDamageableFromGO(GameObject? go) { if ((Object)(object)go == (Object)null) { return null; } ColliderMaterial component = go.GetComponent<ColliderMaterial>(); IDamageable val = ((component != null) ? component.Damageable : null); if (val != null) { return val; } return go.GetComponent<IDamageable>(); } } public sealed class DelayedCallback { private readonly Func<float> _getDelay; private readonly Action? _onStart; private readonly Action? _onRefresh; private readonly Action? _onEnd; private float _endTime; private Coroutine? _routine; public DelayedCallback(Func<float> getDelay, Action? onEnd) { _getDelay = getDelay; _onEnd = onEnd; } public DelayedCallback(Func<float> getDelay, Action? onStart, Action? onEnd) { _getDelay = getDelay; _onStart = onStart; _onEnd = onEnd; } public DelayedCallback(Func<float> getDelay, Action? onStart, Action? onRefresh, Action? onEnd) { _getDelay = getDelay; _onStart = onStart; _onRefresh = onRefresh; _onEnd = onEnd; } public void Start() { _endTime = Clock.Time + _getDelay(); _onRefresh?.Invoke(); if (_routine == null) { _routine = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Update()), (Action)null); } } public IEnumerator Update() { _onStart?.Invoke(); while (_endTime > Clock.Time) { yield return (object)new WaitForSeconds(_endTime - Clock.Time); } _routine = null; _onEnd?.Invoke(); } public void Stop() { if (_routine != null) { CoroutineManager.StopCoroutine(_routine); _routine = null; _onEnd?.Invoke(); } } public void Cancel() { if (_routine != null) { CoroutineManager.StopCoroutine(_routine); _routine = null; } } } internal static class DictExtensions { public static bool TryGetValueAs<Key, Value, ValueAs>(this IDictionary<Key, Value> dict, Key key, [MaybeNullWhen(false)] out ValueAs valueAs) where Key : notnull where ValueAs : Value { if (dict.TryGetValue(key, out Value value)) { valueAs = (ValueAs)(object)value; return true; } valueAs = default(ValueAs); return false; } } public sealed class HitData { public float damage; public Vector2 damageFalloff; public float falloff; public float precisionMulti; public float staggerMulti; public float maxRayDist; public PlayerAgent owner; public Vector3 fireDir; public Vector3 hitPos; public IDamageable? damageable; private RaycastHit _rayHit; private WeaponHitData? _weaponHitData; private MeleeWeaponFirstPerson? _meleeWeapon; public RaycastHit RayHit { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return _rayHit; } set { //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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) _rayHit = value; hitPos = ((RaycastHit)(ref _rayHit)).point; damageable = DamageableUtil.GetDamageableFromRayHit(_rayHit); } } public HitData(WeaponHitData hitData, float additionalDist = 0f) { Setup(hitData, additionalDist); } public HitData(MeleeWeaponFirstPerson melee, MeleeWeaponDamageData hitData) { Setup(melee, hitData); } public HitData() { } public void Setup(WeaponHitData hitData, float additionalDist = 0f) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_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_0064: Unknown result type (might be due to invalid IL or missing references) _weaponHitData = hitData; _meleeWeapon = null; damage = hitData.damage; damageFalloff = hitData.damageFalloff; precisionMulti = hitData.precisionMulti; staggerMulti = hitData.staggerMulti; owner = hitData.owner; fireDir = hitData.fireDir; maxRayDist = hitData.maxRayDist; RayHit = hitData.rayHit; SetFalloff(additionalDist); } public void Setup(MeleeWeaponFirstPerson melee, MeleeWeaponDamageData hitData) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) _weaponHitData = null; _meleeWeapon = melee; damage = melee.m_damageToDeal; precisionMulti = melee.m_precisionMultiToDeal; staggerMulti = melee.m_staggerMultiToDeal; falloff = 1f; fireDir = hitData.hitPos - hitData.sourcePos; hitPos = hitData.hitPos; damageable = DamageableUtil.GetDamageableFromGO(hitData.damageGO); } public void Apply() { if (_weaponHitData != null) { Apply(_weaponHitData); } else if ((Object)(object)_meleeWeapon != (Object)null) { Apply(_meleeWeapon); } } public WeaponHitData Apply(WeaponHitData hitData) { //IL_0032: 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) hitData.owner = owner; hitData.damage = damage; hitData.precisionMulti = precisionMulti; hitData.staggerMulti = staggerMulti; hitData.rayHit = RayHit; hitData.fireDir = fireDir; hitData.maxRayDist = maxRayDist; return hitData; } public MeleeWeaponFirstPerson Apply(MeleeWeaponFirstPerson melee) { melee.m_damageToDeal = damage; melee.m_precisionMultiToDeal = precisionMulti; melee.m_staggerMultiToDeal = staggerMulti; return melee; } public void SetFalloff(float additionalDist = 0f) { //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) RaycastHit rayHit = RayHit; falloff = (((RaycastHit)(ref rayHit)).distance + additionalDist).Map(damageFalloff.x, damageFalloff.y, 1f, BulletWeapon.s_falloffMin); } public WeaponHitData ToWeaponHitData() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0035: 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_0043: 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_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_0066: Expected O, but got Unknown return new WeaponHitData { damage = damage, damageFalloff = damageFalloff, precisionMulti = precisionMulti, staggerMulti = staggerMulti, owner = owner, rayHit = RayHit, fireDir = fireDir, maxRayDist = maxRayDist }; } } public static class LayerUtil { public static int MaskDynamic { get; private set; } public static int MaskEntityAndWorld { get; private set; } public static int MaskEntityAndWorld3P { get; private set; } public static int MaskWorld { get; private set; } public static int MaskWorldExcProj { get; private set; } public static int MaskDecalValid { get; private set; } public static int MaskEntityDynamic3P { get; private set; } public static int MaskEntity { get; private set; } public static int MaskEntity3P { get; private set; } public static int MaskOwner { get; private set; } public static int MaskFriendly { get; private set; } public static int MaskEnemy { get; private set; } public static int MaskEnemyDynamic { get; private set; } internal static void Init() { MaskOwner = LayerMask.GetMask(new string[1] { "PlayerMover" }); MaskFriendly = LayerMask.GetMask(new string[1] { "PlayerSynced" }); MaskEnemy = LayerMask.GetMask(new string[1] { "EnemyDamagable" }); MaskDynamic = LayerMask.GetMask(new string[1] { "Dynamic" }); MaskEnemyDynamic = MaskEnemy | MaskDynamic; MaskEntity3P = MaskFriendly | MaskEnemy; MaskEntity = MaskOwner | MaskEntity3P; MaskDecalValid = LayerMask.GetMask(new string[3] { "Default", "Default_NoGraph", "Default_BlockGraph" }); MaskWorldExcProj = MaskDecalValid | MaskDynamic; MaskWorld = MaskWorldExcProj | LayerMask.GetMask(new string[1] { "ProjectileBlocker" }); MaskEntityAndWorld = MaskEntity | MaskWorld; MaskEntityDynamic3P = MaskEntity3P | MaskDynamic; MaskEntityAndWorld3P = MaskEntity3P | MaskWorld; } } internal static class NumExtensions { public static float Map(this float orig, float fromMin, float fromMax, float toMin, float toMax, float exponent = 1f) { if (fromMin == fromMax) { if (!(orig < fromMin)) { return toMax; } return toMin; } orig = Math.Clamp(orig, fromMin, fromMax); if (exponent != 1f) { return (float)Math.Pow((orig - fromMin) / (fromMax - fromMin), exponent) * (toMax - toMin) + toMin; } return (orig - fromMin) / (fromMax - fromMin) * (toMax - toMin) + toMin; } public static float MapInverted(this float orig, float fromMin, float fromMax, float toMax, float toMin, float exponent = 1f) { if (fromMin == fromMax) { if (!(orig < fromMin)) { return toMin; } return toMax; } orig = Math.Clamp(orig, fromMin, fromMax); if (exponent != 1f) { return (float)Math.Pow((fromMax - orig) / (fromMax - fromMin), exponent) * (toMax - toMin) + toMin; } return (fromMax - orig) / (fromMax - fromMin) * (toMax - toMin) + toMin; } public static float Lerp(this float t, float min, float max) { return (max - min) * Math.Clamp(t, 0f, 1f) + min; } public static float Lerp(this double t, float min, float max) { return (max - min) * (float)Math.Clamp(t, 0.0, 1.0) + min; } } [Flags] internal enum SearchSetting { None = 0, Alloc = 1, CacheHit = 2, CheckLOS = 4, CheckDoors = 8, CheckOwner = 0x10, CheckFriendly = 0x20, IgnoreDupes = 0x40 } internal static class SearchUtil { private static readonly List<EnemyAgent> s_enemyCache = new List<EnemyAgent>(); private static readonly List<(EnemyAgent, RaycastHit)> s_combinedCache = new List<(EnemyAgent, RaycastHit)>(); private static readonly List<(PlayerAgent, RaycastHit)> s_combinedCachePlayer = new List<(PlayerAgent, RaycastHit)>(); private static readonly Queue<AIG_CourseNode> s_nodeQueue = new Queue<AIG_CourseNode>(); private static readonly List<RaycastHit> s_lockCache = new List<RaycastHit>(); public static HashSet<IntPtr>? DupeCheckSet; public static int SightBlockLayer = 0; public const float WeakspotBufferDist = 0.1f; private static Ray s_ray; private static RaycastHit s_rayHit; private const float Epsilon = 1E-05f; private static Vector3 ClosestPointOnBounds(Bounds bounds, Vector3 point) { //IL_0000: 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_0014: 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_002b: 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_0046: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) return new Vector3(Math.Clamp(point.x, ((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).max.x), Math.Clamp(point.y, ((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).max.y), Math.Clamp(point.z, ((Bounds)(ref bounds)).min.z, ((Bounds)(ref bounds)).max.z)); } private static bool PortalInRange(Ray ray, float range, float angle, AIG_CoursePortal portal) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_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_0043: 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_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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_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_0098: 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_00a4: 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_0120: 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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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) Bounds portalBounds = portal.m_cullPortal.m_portalBounds; Vector3 val = ClosestPointOnBounds(portalBounds, ((Ray)(ref ray)).origin); Vector3 val2 = ((Ray)(ref ray)).origin - val; if (((Vector3)(ref val2)).sqrMagnitude > range * range) { return false; } if (angle >= 180f || ((Bounds)(ref portalBounds)).Contains(((Ray)(ref ray)).origin)) { return true; } Vector3 val3 = portal.m_cullPortal.m_center - ((Ray)(ref ray)).origin; float num = Vector3.Dot(val3, ((Ray)(ref ray)).direction); if (angle == 90f) { return num >= 0f; } val = Vector3.Project(val3, ((Ray)(ref ray)).direction); Bounds portalBounds2 = portal.m_cullPortal.m_portalBounds; val2 = ((Bounds)(ref portalBounds2)).extents; float magnitude = ((Vector3)(ref val2)).magnitude; float num2 = ((Vector3)(ref val)).magnitude * (float)Math.Tan(angle * (MathF.PI / 180f)); if (num2 < 0f) { if (num >= 0f) { return true; } num2 = Math.Max(0f, num2 + magnitude); val2 = val3 - val; return ((Vector3)(ref val2)).sqrMagnitude >= num2 * num2; } if (num <= 0f) { return false; } num2 += magnitude; val2 = val3 - val; return ((Vector3)(ref val2)).sqrMagnitude <= num2 * num2; } private static bool RaycastEnsured(Collider collider, Vector3 backupOrigin, float range, out RaycastHit hit) { //IL_0001: 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_0013: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_0073: 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_007f: Unknown result type (might be due to invalid IL or missing references) if (collider.Raycast(s_ray, ref hit, range)) { return true; } Vector3 val = collider.ClosestPoint(backupOrigin); Bounds bounds = collider.bounds; Vector3 val2 = val - ((Bounds)(ref bounds)).center; Vector3 normalized = ((Vector3)(ref val2)).normalized; bounds = collider.bounds; ((Ray)(ref s_ray)).origin = ((Bounds)(ref bounds)).center + val2 + normalized * Math.Min(0.1f, range / 2f); ((Ray)(ref s_ray)).direction = -normalized; return collider.Raycast(s_ray, ref hit, range); } private static bool TryGetClosestHit(Ray ray, float range, float angle, Agent agent, out RaycastHit hit, SearchSetting settings) { //IL_0002: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_005f: 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: Invalid comparison between Unknown and I4 //IL_00f2: 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_010e: 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_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_0123: 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_013e: Invalid comparison between Unknown and I4 //IL_016a: 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_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022a: 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_023d: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) hit = default(RaycastHit); if ((Object)(object)agent == (Object)null || !agent.Alive) { return false; } if (settings.HasFlag(SearchSetting.IgnoreDupes)) { if ((int)agent.Type == 1) { HashSet<IntPtr>? dupeCheckSet = DupeCheckSet; if (dupeCheckSet != null && dupeCheckSet.Contains(((Il2CppObjectBase)((Il2CppObjectBase)agent).Cast<EnemyAgent>().Damage).Pointer)) { return false; } } if ((int)agent.Type == 0) { HashSet<IntPtr>? dupeCheckSet2 = DupeCheckSet; if (dupeCheckSet2 != null && dupeCheckSet2.Contains(((Il2CppObjectBase)((Il2CppObjectBase)agent).Cast<PlayerAgent>().Damage).Pointer)) { return false; } } } ((Ray)(ref s_ray)).origin = ((Ray)(ref ray)).origin; float num = range * range; float num2 = num; Collider val = null; bool flag = false; foreach (Collider componentsInChild in ((Component)agent).GetComponentsInChildren<Collider>()) { Dam_EnemyDamageLimb val2 = null; if ((int)agent.Type == 1) { val2 = ((Component)componentsInChild).GetComponent<Dam_EnemyDamageLimb>(); if ((Object)(object)val2 == (Object)null || val2.IsDestroyed) { continue; } } else if ((int)agent.Type == 0 && ((Component)componentsInChild).GetComponent<IDamageable>() == null) { continue; } Vector3 val3 = componentsInChild.ClosestPoint(((Ray)(ref ray)).origin); Vector3 direction = val3 - ((Ray)(ref ray)).origin; float num3 = ((Vector3)(ref direction)).sqrMagnitude; float num4 = num3; if (val2 != null && (int)val2.m_type == 1 && num3 < num) { float num5 = Math.Max(((Vector3)(ref direction)).magnitude - 0.1f, 0f); num3 = num5 * num5; } if (!(num3 < num2) || !(Vector3.Angle(((Ray)(ref ray)).direction, val3 - ((Ray)(ref ray)).origin) <= angle) || (settings.HasFlag(SearchSetting.CheckLOS) && Physics.Linecast(((Ray)(ref ray)).origin, val3, SightBlockLayer))) { continue; } num2 = num3; val = componentsInChild; if (!settings.HasFlag(SearchSetting.CacheHit)) { break; } if (num2 < 1E-05f) { if (!(num4 > 1E-05f)) { ((Ray)(ref s_ray)).origin = ((Ray)(ref s_ray)).origin - ((Ray)(ref ray)).direction * Math.Min(0.1f, range / 2f); ((Ray)(ref s_ray)).direction = val3 - ((Ray)(ref s_ray)).origin; if (RaycastEnsured(componentsInChild, ((Ray)(ref ray)).origin, range, out hit)) { ((RaycastHit)(ref hit)).point = val3; ((RaycastHit)(ref hit)).distance = 0f; flag = true; } else { val = null; } } break; } ((Ray)(ref s_ray)).direction = direction; } if ((Object)(object)val == (Object)null) { return false; } if (settings.HasFlag(SearchSetting.CacheHit) && !flag && !RaycastEnsured(val, ((Ray)(ref ray)).origin, range, out hit)) { return false; } return true; } private static void CacheEnemiesInRange(Ray ray, float range, float angle, AIG_CourseNode origin, SearchSetting settings) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: 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_010b: 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_0121: 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) AIG_SearchID.IncrementSearchID(); ushort searchID = AIG_SearchID.SearchID; float num = range * range; s_nodeQueue.Enqueue(origin); ((AIG_CourseGraphMember)origin).m_searchID = searchID; s_combinedCache.Clear(); AIG_CourseNode result; while (s_nodeQueue.TryDequeue(out result)) { Enumerator<AIG_CoursePortal> enumerator = result.m_portals.GetEnumerator(); while (enumerator.MoveNext()) { AIG_CoursePortal current = enumerator.Current; AIG_CourseNode oppositeNode = current.GetOppositeNode(result); if ((!settings.HasFlag(SearchSetting.CheckDoors) || current.IsTraversable) && ((AIG_CourseGraphMember)oppositeNode).m_searchID != searchID && PortalInRange(ray, range, angle, current)) { ((AIG_CourseGraphMember)oppositeNode).m_searchID = searchID; s_nodeQueue.Enqueue(oppositeNode); } } Enumerator<EnemyAgent> enumerator2 = result.m_enemiesInNode.GetEnumerator(); while (enumerator2.MoveNext()) { EnemyAgent current2 = enumerator2.Current; if (!((Object)(object)current2 == (Object)null) && ((Agent)current2).Alive && !(((Dam_SyncedDamageBase)current2.Damage).Health <= 0f)) { Vector3 val = ClosestPointOnBounds(((C_Cullable)current2.MovingCuller.Culler).Bounds, ((Ray)(ref ray)).origin) - ((Ray)(ref ray)).origin; if (!(((Vector3)(ref val)).sqrMagnitude > num) && TryGetClosestHit(ray, range, angle, (Agent)(object)current2, out s_rayHit, settings)) { s_combinedCache.Add((current2, s_rayHit)); } } } } } public static List<EnemyAgent> GetEnemiesInRange(Ray ray, float range, float angle, AIG_CourseNode origin, SearchSetting settings = SearchSetting.None) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) s_enemyCache.Clear(); if (range == 0f || angle == 0f) { if (!settings.HasFlag(SearchSetting.Alloc)) { return s_enemyCache; } return new List<EnemyAgent>(); } CacheEnemiesInRange(ray, range, angle, origin, settings); if (settings.HasFlag(SearchSetting.Alloc)) { return s_combinedCache.ConvertAll(((EnemyAgent, RaycastHit) pair) => pair.Item1); } foreach (var item2 in s_combinedCache) { EnemyAgent item = item2.Item1; s_enemyCache.Add(item); } return s_enemyCache; } public static List<(EnemyAgent enemy, RaycastHit hit)> GetEnemyHitsInRange(Ray ray, float range, float angle, AIG_CourseNode origin, SearchSetting settings = SearchSetting.CacheHit) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (range == 0f || angle == 0f) { s_combinedCache.Clear(); if (!settings.HasFlag(SearchSetting.Alloc)) { return s_combinedCache; } return new List<(EnemyAgent, RaycastHit)>(); } settings |= SearchSetting.CacheHit; CacheEnemiesInRange(ray, range, angle, origin, settings); if (settings.HasFlag(SearchSetting.Alloc)) { return new List<(EnemyAgent, RaycastHit)>(s_combinedCache); } return s_combinedCache; } public static List<RaycastHit> GetLockHitsInRange(Ray ray, float range, float angle, SearchSetting settings = SearchSetting.None) { //IL_003b: 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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011c: 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_00c5: 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) //IL_013f: Unknown result type (might be due to invalid IL or missing references) s_lockCache.Clear(); if (range == 0f || angle == 0f) { if (!settings.HasFlag(SearchSetting.Alloc)) { return s_lockCache; } return new List<RaycastHit>(); } Collider[] array = Il2CppArrayBase<Collider>.op_Implicit((Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(((Ray)(ref ray)).origin, range, LayerUtil.MaskDynamic)); Vector3 direction = ((Ray)(ref ray)).direction; Collider[] array2 = array; foreach (Collider val in array2) { IDamageable damageableFromCollider = DamageableUtil.GetDamageableFromCollider(val); if (damageableFromCollider == null) { continue; } if (settings.HasFlag(SearchSetting.IgnoreDupes)) { HashSet<IntPtr>? dupeCheckSet = DupeCheckSet; if (dupeCheckSet != null && dupeCheckSet.Contains(((Il2CppObjectBase)damageableFromCollider.GetBaseDamagable()).Pointer)) { continue; } } if (!settings.HasFlag(SearchSetting.CheckLOS) || !Physics.Linecast(((Ray)(ref ray)).origin, damageableFromCollider.DamageTargetPos, ref s_rayHit, SightBlockLayer) || !(((Il2CppObjectBase)((Component)((RaycastHit)(ref s_rayHit)).collider).gameObject).Pointer != ((Il2CppObjectBase)((Component)val).gameObject).Pointer)) { ((Ray)(ref ray)).direction = damageableFromCollider.DamageTargetPos - ((Ray)(ref ray)).origin; if (val.Raycast(ray, ref s_rayHit, range) && Vector3.Angle(((Ray)(ref ray)).direction, direction) < angle) { s_lockCache.Add(s_rayHit); } } } if (settings.HasFlag(SearchSetting.Alloc)) { return new List<RaycastHit>(s_lockCache); } return s_lockCache; } public static List<(PlayerAgent, RaycastHit)> GetPlayerHitsInRange(Ray ray, float range, float angle, SearchSetting settings = SearchSetting.CheckOwner | SearchSetting.CheckFriendly) { //IL_0076: 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_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_0153: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_016a: 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_012c: Unknown result type (might be due to invalid IL or missing references) s_combinedCachePlayer.Clear(); if (range == 0f || angle == 0f) { if (!settings.HasFlag(SearchSetting.Alloc)) { return s_combinedCachePlayer; } return new List<(PlayerAgent, RaycastHit)>(); } float num = range * range; Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if ((Object)(object)current == (Object)null || !((Agent)current).Alive) { continue; } Vector3 val = ClosestPointOnBounds(((C_Cullable)current.m_movingCuller.Culler).Bounds, ((Ray)(ref ray)).origin) - ((Ray)(ref ray)).origin; if (((Vector3)(ref val)).sqrMagnitude > num) { continue; } if (((Agent)current).IsLocallyOwned) { if (!settings.HasFlag(SearchSetting.CheckOwner)) { continue; } ((Ray)(ref s_ray)).origin = ((Ray)(ref ray)).origin; ((Ray)(ref s_ray)).direction = ((Dam_SyncedDamageBase)current.Damage).DamageTargetPos - ((Ray)(ref ray)).origin; if (!((Component)current).GetComponent<Collider>().Raycast(s_ray, ref s_rayHit, range) || (settings.HasFlag(SearchSetting.CheckLOS) && Physics.Linecast(((Ray)(ref ray)).origin, ((RaycastHit)(ref s_rayHit)).point, SightBlockLayer))) { continue; } } else if (!settings.HasFlag(SearchSetting.CheckFriendly) || !TryGetClosestHit(ray, range, angle, (Agent)(object)current, out s_rayHit, settings)) { continue; } s_combinedCachePlayer.Add((current, s_rayHit)); } if (settings.HasFlag(SearchSetting.Alloc)) { return new List<(PlayerAgent, RaycastHit)>(s_combinedCachePlayer); } return s_combinedCachePlayer; } private static bool HasCluster(AIG_VoxelNodePillar pillar) { Enumerator<AIG_VoxelNode> enumerator = pillar.m_nodes.GetEnumerator(); AIG_NodeCluster val = default(AIG_NodeCluster); while (enumerator.MoveNext()) { AIG_VoxelNode current = enumerator.Current; if (current.ClusterID != 0 && AIG_NodeCluster.TryGetNodeCluster(current.ClusterID, ref val)) { return true; } } return false; } public static AIG_CourseNode GetCourseNode(Vector3 position, Agent agent) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_003e: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_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_0071: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) Vector3 position2 = agent.Position; if (TryGetGeomorphVolumeSilent(Dimension.GetDimensionFromPos(position).DimensionIndex, position, out AIG_GeomorphNodeVolume resultingGeoVolume)) { position.y = ((AIG_NodeVolume)resultingGeoVolume).Position.y; position2.y = position.y; Vector3 val = position2 - position; Vector3 normalized = ((Vector3)(ref val)).normalized; AIG_VoxelNodePillar val2 = null; for (int i = 0; i < 10; i++) { if (((AIG_NodeVolume)resultingGeoVolume).m_voxelNodeVolume.TryGetPillar(position, ref val2) && HasCluster(val2)) { break; } position += normalized; } if (val2 == null) { return agent.CourseNode; } Enumerator<AIG_VoxelNode> enumerator = val2.m_nodes.GetEnumerator(); AIG_NodeCluster val3 = default(AIG_NodeCluster); while (enumerator.MoveNext()) { AIG_VoxelNode current = enumerator.Current; if (current.ClusterID != 0 && AIG_NodeCluster.TryGetNodeCluster(current.ClusterID, ref val3) && val3.CourseNode != null) { return val3.CourseNode; } } } return agent.CourseNode; } private static bool TryGetGeomorphVolumeSilent(eDimensionIndex dimensionIndex, Vector3 pos, [MaybeNullWhen(false)] out AIG_GeomorphNodeVolume resultingGeoVolume) { //IL_001a: 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) resultingGeoVolume = null; LG_Floor currentFloor = Builder.Current.m_currentFloor; if ((Object)(object)currentFloor == (Object)null) { return false; } Dimension val = default(Dimension); if (!currentFloor.GetDimension(dimensionIndex, ref val)) { return false; } if (val.Grid == null || !TryGetCell(val.Grid, pos, out LG_Cell cell)) { return false; } if (((CellBase<LG_Tile, LG_Cell>)(object)cell).m_grouping == null || (Object)(object)((CellBase<LG_Tile, LG_Cell>)(object)cell).m_grouping.m_geoRoot == (Object)null) { return false; } resultingGeoVolume = ((Il2CppObjectBase)((CellBase<LG_Tile, LG_Cell>)(object)cell).m_grouping.m_geoRoot.m_nodeVolume).TryCast<AIG_GeomorphNodeVolume>(); return (Object)(object)resultingGeoVolume != (Object)null; } private static bool TryGetCell(LG_Grid grid, Vector3 pos, [MaybeNullWhen(false)] out LG_Cell cell) { //IL_0000: 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_000e: 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) pos -= ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_gridPosition; int num = (int)Math.Round((pos.x - ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_cellDimHalf) / ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_cellDim); int num2 = (int)Math.Round((pos.z - ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_cellDimHalf) / ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_cellDim); if (num < 0 || num2 < 0 || num >= ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_sizeX || num2 >= ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_sizeZ) { cell = null; return false; } cell = ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).GetCell(num, num2); return true; } } internal static class SortUtil { private static List<(RaycastHit hit, float distance)> s_limbCache = new List<(RaycastHit, float)>(); private static List<(EnemyAgent enemy, float value)> s_enemyTupleCache = new List<(EnemyAgent, float)>(); public static int Rayhit(RaycastHit x, RaycastHit y) { if (((RaycastHit)(ref x)).distance == ((RaycastHit)(ref y)).distance) { return 0; } if (!(((RaycastHit)(ref x)).distance < ((RaycastHit)(ref y)).distance)) { return 1; } return -1; } public static int EnemyRayhit((EnemyAgent, RaycastHit hit) x, (EnemyAgent, RaycastHit hit) y) { if (((RaycastHit)(ref x.hit)).distance == ((RaycastHit)(ref y.hit)).distance) { return 0; } if (!(((RaycastHit)(ref x.hit)).distance < ((RaycastHit)(ref y.hit)).distance)) { return 1; } return -1; } public static void SortWithWeakspotBuffer(IList<RaycastHit> list) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0059: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) foreach (RaycastHit item in list) { RaycastHit current = item; IDamageable? damageableFromRayHit = DamageableUtil.GetDamageableFromRayHit(current); int num; if (damageableFromRayHit == null) { num = 0; } else { Dam_EnemyDamageLimb obj = ((Il2CppObjectBase)damageableFromRayHit).TryCast<Dam_EnemyDamageLimb>(); num = ((((obj != null) ? new eLimbDamageType?(obj.m_type) : null) == (eLimbDamageType?)1) ? 1 : 0); } bool flag = (byte)num != 0; s_limbCache.Add((current, flag ? Math.Max(((RaycastHit)(ref current)).distance - 0.1f, 0f) : ((RaycastHit)(ref current)).distance)); } s_limbCache.Sort(FloatTuple); CopySortedList(s_limbCache, list); s_limbCache.Clear(); } public static void CopySortedList<T>(IList<(T, float)> sortedList, IList<T> list) { for (int i = 0; i < list.Count; i++) { list[i] = sortedList[i].Item1; } } public static void CopySortedList<T>(IList<(T, float, float)> sortedList, IList<T> list) { for (int i = 0; i < list.Count; i++) { list[i] = sortedList[i].Item1; } } public static int FloatTuple<T>((T, float val) x, (T, float val) y) { if (x.val == y.val) { return 0; } if (!(x.val < y.val)) { return 1; } return -1; } public static int FloatTuple<T>((T, float val1, float val2) x, (T, float val1, float val2) y) { if (x.val1 == y.val1) { if (x.val2 == y.val2) { return 0; } if (!(x.val2 < y.val2)) { return 1; } return -1; } if (!(x.val1 < y.val1)) { return 1; } return -1; } } internal static class StringExtensions { public static T ToEnum<T>(this string? value, T defaultValue) where T : struct { if (string.IsNullOrEmpty(value)) { return defaultValue; } if (!Enum.TryParse<T>(value.Replace(" ", null), ignoreCase: true, out var result)) { return defaultValue; } return result; } } } namespace EWC.Utils.Log { internal static class EWCLogger { private static ManualLogSource logger = Logger.CreateLogSource("ExtraWeaponCustomization"); public static void Log(string format, params object[] args) { Log(string.Format(format, args)); } public static void Log(string str) { if (logger != null) { logger.Log((LogLevel)8, (object)str); } } public static void Warning(string format, params object[] args) { Warning(string.Format(format, args)); } public static void Warning(string str) { if (logger != null) { logger.Log((LogLevel)4, (object)str); } } public static void Error(string format, params object[] args) { Error(string.Format(format, args)); } public static void Error(string str) { if (logger != null) { logger.Log((LogLevel)2, (object)str); } } public static void Debug(string format, params object[] args) { Debug(string.Format(format, args)); } public static void Debug(string str) { if (logger != null) { logger.Log((LogLevel)32, (object)str); } } } } namespace EWC.Patches { [HarmonyPatch] internal static class EnemyLimbPatches { private static float _cachedArmor; [HarmonyPatch(typeof(Dam_EnemyDamageLimb), "BulletDamage")] [HarmonyPatch(typeof(Dam_EnemyDamageLimb), "MeleeDamage")] [HarmonyWrapSafe] [HarmonyPrefix] private static void Pre_Damage(Dam_EnemyDamageLimb __instance) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 ContextController cachedHitCC = WeaponPatches.CachedHitCC; if (cachedHitCC != null && (int)__instance.m_type == 2) { _cachedArmor = __instance.m_armorDamageMulti; __instance.m_armorDamageMulti = cachedHitCC.Invoke(new WeaponArmorContext(_cachedArmor)).ArmorMulti; } } [HarmonyPatch(typeof(Dam_EnemyDamageLimb), "BulletDamage")] [HarmonyPatch(typeof(Dam_EnemyDamageLimb), "MeleeDamage")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_Damage(Dam_EnemyDamageLimb __instance) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 if (WeaponPatches.CachedHitCC != null && (int)__instance.m_type == 2) { __instance.m_armorDamageMulti = _cachedArmor; } } [HarmonyPatch(typeof(Dam_EnemyDamageLimb_Custom), "ApplyWeakspotAndArmorModifiers")] [HarmonyWrapSafe] [HarmonyPrefix] private static bool Pre_WeakspotModifiers(Dam_EnemyDamageLimb_Custom __instance, float dam, float precisionMulti, ref float __result) { if (!WeaponPatches.CachedBypassTumorCap) { return true; } __result = dam * Math.Max(((Dam_EnemyDamageLimb)__instance).m_weakspotDamageMulti * precisionMulti, 1f) * ((Dam_EnemyDamageLimb)__instance).m_armorDamageMulti; return false; } } [HarmonyPatch] internal static class FPISPatches { private static CustomWeaponComponent? _cachedCWC; [HarmonyPatch(typeof(FPIS_Aim), "Enter")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_AimEnter(FPIS_Aim __instance) { _cachedCWC = ((Component)((FPItemState)__instance).Holder.WieldedItem).GetComponent<CustomWeaponComponent>(); if (!((Object)(object)_cachedCWC == (Object)null)) { _cachedCWC.Invoke(StaticContext<WeaponAimContext>.Instance); } } [HarmonyPatch(typeof(FPIS_Aim), "Exit")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_AimExit() { if (!((Object)(object)_cachedCWC == (Object)null)) { _cachedCWC.Invoke(StaticContext<WeaponAimEndContext>.Instance); } } } [HarmonyPatch] internal static class PlayerInventoryPatches { private static bool _allowReload = true; [HarmonyPatch(typeof(PUI_Inventory), "SetSlotAmmo")] [HarmonyWrapSafe] [HarmonyPrefix] private static void SetAmmoUICallback(PUI_Inventory __instance, InventorySlot slot, ref int clipAbs, ref int inPackAbs, ref float inPackRel) { //IL_0000: 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) if ((int)slot == 0) { return; } SNet_Player owner = __instance.m_owner; object obj; if (owner == null) { obj = null; } else { SNet_IPlayerAgent playerAgent = owner.PlayerAgent; if (playerAgent == null) { obj = null; } else { PlayerAgent obj2 = ((Il2CppObjectBase)playerAgent).TryCast<PlayerAgent>(); if (obj2 == null) { obj = null; } else { FirstPersonItemHolder fPItemHolder = obj2.FPItemHolder; if (fPItemHolder == null) { obj = null; } else { ItemEquippable wieldedItem = fPItemHolder.WieldedItem; if (wieldedItem == null) { obj = null; } else { BulletWeapon obj3 = ((Il2CppObjectBase)wieldedItem).TryCast<BulletWeapon>(); obj = ((obj3 != null) ? ((Component)obj3).GetComponent<CustomWeaponComponent>() : null); } } } } } CustomWeaponComponent customWeaponComponent = (CustomWeaponComponent)obj; if (!((Object)(object)customWeaponComponent == (Object)null)) { PUI_InventoryItem val = __instance.m_inventorySlots[slot]; WeaponPreAmmoUIContext weaponPreAmmoUIContext = new WeaponPreAmmoUIContext(clipAbs, inPackAbs, inPackRel, val.ShowAmmoClip, val.ShowAmmoPack, val.ShowAmmoTotalRel, val.ShowAmmoInfinite); customWeaponComponent.Invoke(weaponPreAmmoUIContext); clipAbs = weaponPreAmmoUIContext.Clip; inPackAbs = weaponPreAmmoUIContext.Reserve; inPackRel = weaponPreAmmoUIContext.TotalRel; val.ShowAmmoClip = weaponPreAmmoUIContext.ShowClip; val.ShowAmmoPack = weaponPreAmmoUIContext.ShowReserve; val.ShowAmmoTotalRel = weaponPreAmmoUIContext.ShowRel; val.ShowAmmoInfinite = weaponPreAmmoUIContext.ShowInfinite; } } private static InventorySlot AmmoToSlot(AmmoType ammo) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected I4, but got Unknown //IL_0015: 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_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_0021: Unknown result type (might be due to invalid IL or missing references) return (InventorySlot)((int)ammo switch { 0 => 1, 1 => 2, 2 => 3, _ => 0, }); } [HarmonyPatch(typeof(PlayerAmmoStorage), "PickupAmmo")] [HarmonyWrapSafe] [HarmonyPrefix] private static void AmmoPackCallback(PlayerAmmoStorage __instance, AmmoType ammoType, ref float ammoAmount) { //IL_0006: 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) BackpackItem val = default(BackpackItem); if (__instance.m_playerBackpack.TryGetBackpackItem(AmmoToSlot(ammoType), ref val)) { Item instance = val.Instance; CustomWeaponComponent customWeaponComponent = ((instance != null) ? ((Component)instance).GetComponent<CustomWeaponComponent>() : null); if ((Object)(object)customWeaponComponent != (Object)null) { ammoAmount = customWeaponComponent.Invoke(new WeaponPreAmmoPackContext(ammoAmount)).AmmoAmount; } } } [HarmonyPatch(typeof(PlayerAmmoStorage), "PickupAmmo")] [HarmonyWrapSafe] [HarmonyPostfix] private static void PostAmmoPackCallback(PlayerAmmoStorage __instance, AmmoType ammoType) { //IL_0006: 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) BackpackItem val = default(BackpackItem); if (__instance.m_playerBackpack.TryGetBackpackItem(AmmoToSlot(ammoType), ref val)) { Item instance = val.Instance; ((instance != null) ? ((Component)instance).GetComponent<CustomWeaponComponent>() : null)?.Invoke(new WeaponPostAmmoPackContext(__instance)); } } [HarmonyPatch(typeof(PlayerInventoryLocal), "DoReload")] [HarmonyPatch(typeof(PlayerInventoryBase), "DoReload")] [HarmonyWrapSafe] [HarmonyPostfix] private static void ReloadCallback(PlayerInventoryBase __instance) { ItemEquippable wieldedItem = __instance.m_wieldedItem; CustomWeaponComponent customWeaponComponent = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null); if (!((Object)(object)customWeaponComponent == (Object)null)) { customWeaponComponent.Invoke(StaticContext<WeaponPostReloadContext>.Instance); } } [HarmonyPatch(typeof(PlayerInventoryLocal), "TriggerReload")] [HarmonyWrapSafe] [HarmonyPrefix] private static bool ReloadPreStartCallback(PlayerInventoryLocal __instance) { _allowReload = true; ItemEquippable wieldedItem = ((PlayerInventoryBase)__instance).m_wieldedItem; CustomWeaponComponent customWeaponComponent = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null); if ((Object)(object)customWeaponComponent == (Object)null) { return true; } _allowReload = customWeaponComponent.Invoke(new WeaponPreReloadContext()).Allow; return _allowReload; } [HarmonyPatch(typeof(PlayerInventoryLocal), "TriggerReload")] [HarmonyWrapSafe] [HarmonyPostfix] private static void ReloadStartCallback(PlayerInventoryLocal __instance) { if (_allowReload) { ItemEquippable wieldedItem = ((PlayerInventoryBase)__instance).m_wieldedItem; CustomWeaponComponent customWeaponComponent = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null); if (!((Object)(object)customWeaponComponent == (Object)null) && customWeaponComponent.Weapon.IsReloading) { customWeaponComponent.Invoke(StaticContext<WeaponReloadStartContext>.Instance); } } } [HarmonyPatch(typeof(PlayerAmmoStorage), "FillAllClips")] [HarmonyWrapSafe] [HarmonyPostfix] private static void PostFillAllClipsCallback(PlayerAmmoStorage __instance) { BackpackItem val = default(BackpackItem); if (__instance.m_playerBackpack.TryGetBackpackItem((InventorySlot)1, ref val)) { Item instance = val.Instance; ((instance != null) ? ((Component)instance).GetComponent<CustomWeaponComponent>() : null)?.Invoke(new WeaponPostAmmoInitContext(__instance, __instance.StandardAmmo)); } BackpackItem val2 = default(BackpackItem); if (__instance.m_playerBackpack.TryGetBackpackItem((InventorySlot)2, ref val2)) { Item instance2 = val2.Instance; ((instance2 != null) ? ((Component)instance2).GetComponent<CustomWeaponComponent>() : null)?.Invoke(new WeaponPostAmmoInitContext(__instance, __instance.SpecialAmmo)); } } } [HarmonyPatch] internal static class ShotgunPatches { [HarmonyPatch(typeof(Shotgun), "Fire")] [HarmonyWrapSafe] [HarmonyPrefix] private static void Pre_Fire(Shotgun __instance) { WeaponRayPatches.CachedWeapon = (BulletWeapon?)(object)__instance; } [HarmonyPatch(typeof(Shotgun), "Fire")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_Fire(Shotgun __instance) { WeaponRayPatches.CachedWeapon = null; } } [HarmonyPatch] internal static class WeaponArchetypePatches { [HarmonyPatch(typeof(BulletWeaponArchetype), "SetOwner")] [HarmonyWrapSafe] [HarmonyPostfix] private static void SetupCallback(BulletWeaponArchetype __instance, PlayerAgent owner) { if (!((Object)(object)owner == (Object)null)) { CustomWeaponComponent component = ((Component)__instance.m_weapon).GetComponent<CustomWeaponComponent>(); if (!((Object)(object)component == (Object)null)) { component.OwnerInit(); } } } [HarmonyPatch(typeof(BWA_Burst), "OnStartFiring")] [HarmonyPatch(typeof(BWA_Auto), "OnStartFiring")] [HarmonyPatch(typeof(BulletWeaponArchetype), "OnStartFiring")] [HarmonyWrapSafe] [HarmonyPrefix] private static bool StartFireCallback(BulletWeaponArchetype __instance) { BulletWeapon weapon = __instance.m_weapon; CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null); if ((Object)(object)customWeaponComponent == (Object)null) { return true; } customWeaponComponent.CancelShot = false; WeaponPreStartFireContext weaponPreStartFireContext = new WeaponPreStartFireContext(); customWeaponComponent.Invoke(weaponPreStartFireContext); customWeaponComponent.UpdateStoredFireRate(); if (!weaponPreStartFireContext.Allow) { customWeaponComponent.StoreCancelShot(); } return weaponPreStartFireContext.Allow; } [HarmonyPatch(typeof(BWA_Burst), "OnStartFiring")] [HarmonyPatch(typeof(BWA_Auto), "OnStartFiring")] [HarmonyPatch(typeof(BulletWeaponArchetype), "OnStartFiring")] [HarmonyWrapSafe] [HarmonyPostfix] private static void PostStartFireCallback(BulletWeaponArchetype __instance) { BulletWeapon weapon = __instance.m_weapon; CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null); if (!((Object)(object)customWeaponComponent == (Object)null)) { if (customWeaponComponent.ResetShotIfCancel(__instance)) { customWeaponComponent.CancelShot = false; __instance.m_readyToFire = false; } else { customWeaponComponent.Invoke(StaticContext<WeaponPostStartFireContext>.Instance); } } } [HarmonyPatch(typeof(BWA_Auto), "OnFireShot")] [HarmonyPatch(typeof(BWA_Burst), "OnFireShot")] [HarmonyPatch(typeof(BWA_Semi), "OnFireShot")] [HarmonyWrapSafe] [HarmonyPrefix] private static bool PreFireCallback(BulletWeaponArchetype __instance) { BulletWeapon weapon = __instance.m_weapon; CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null); if ((Object)(object)customWeaponComponent == (Object)null) { return true; } if (customWeaponComponent.CancelShot) { return false; } WeaponFireCancelContext weaponFireCancelContext = new WeaponFireCancelContext(); customWeaponComponent.Invoke(weaponFireCancelContext); if (!weaponFireCancelContext.Allow) { customWeaponComponent.StoreCancelShot(); } else { customWeaponComponent.Invoke(StaticContext<WeaponPreFireContext>.Instance); } return weaponFireCancelContext.Allow; } [HarmonyPatch(typeof(BWA_Auto), "OnFireShot")] [HarmonyPatch(typeof(BWA_Burst), "OnFireShot")] [HarmonyPatch(typeof(BWA_Semi), "OnFireShot")] [HarmonyWrapSafe] [HarmonyPostfix] private static void PostFireCallback(BulletWeaponArchetype __instance) { BulletWeapon weapon = __instance.m_weapon; CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null); if (!((Object)(object)customWeaponComponent == (Object)null) && !customWeaponComponent.CancelShot) { customWeaponComponent.Invoke(StaticContext<WeaponPostFireContext>.Instance); } } [HarmonyPatch(typeof(BulletWeaponArchetype), "PostFireCheck")] [HarmonyWrapSafe] [HarmonyPrefix] private static void PrePostFireCallback(BulletWeaponArchetype __instance) { BulletWeapon weapon = __instance.m_weapon; CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null); if (!((Object)(object)customWeaponComponent == (Object)null)) { customWeaponComponent.ResetShotIfCancel(__instance); } } [HarmonyPatch(typeof(BulletWeaponArchetype), "PostFireCheck")] [HarmonyWrapSafe] [HarmonyPostfix] private static void PostPostFireCallback(BulletWeaponArchetype __instance) { BulletWeapon weapon = __instance.m_weapon; CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null); if (!((Object)(object)customWeaponComponent == (Object)null)) { if (customWeaponComponent.CancelShot) { customWeaponComponent.CancelShot = false; return; } customWeaponComponent.UpdateStoredFireRate(); customWeaponComponent.ModifyFireRate(); } } [HarmonyPatch(typeof(BWA_Burst), "OnStopFiring")] [HarmonyPatch(typeof(BWA_Auto), "OnStopFiring")] [HarmonyPatch(typeof(BulletWeaponArchetype), "OnStopFiring")] [HarmonyWrapSafe] [HarmonyPostfix] private static void StopFiringCallback(BulletWeaponArchetype __instance) { BulletWeapon weapon = __instance.m_weapon; CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null); if (!((Object)(object)customWeaponComponent == (Object)null)) { customWeaponComponent.Invoke(StaticContext<WeaponPostStopFiringContext>.Instance); } } } [HarmonyPatch] internal static class WeaponPatches { private static uint s_lastSearchID = 0u; private static float s_origHitDamage = 0f; private static float s_origHitPrecision = 0f; private static readonly HitData s_hitData = new HitData(); private static ContextController? _cachedHitCC = null; public static ContextController? CachedHitCC { get { return _cachedHitCC; } set { _cachedHitCC = value; CachedBypassTumorCap = false; } } public static bool CachedBypassTumorCap { get; private set; } = false; [HarmonyPatch(typeof(BulletWeapon), "OnGearSpawnComplete")] [HarmonyWrapSafe] [HarmonyPostfix] private static void SetupCallback(BulletWeapon __instance) { CustomWeaponManager.Current.AddWeaponListener((ItemEquippable)(object)__instance); CustomWeaponData customGunData = CustomWeaponManager.Current.GetCustomGunData(((GameDataBlockBase<ArchetypeDataBlock>)(object)((ItemEquippable)__instance).ArchetypeData).persistentID); if (customGunData != null && !((Object)(object)((Component)__instance).gameObject.GetComponent<CustomWeaponComponent>() != (Object)null)) { ((Component)__instance).gameObject.AddComponent<CustomWeaponComponent>().Register(customGunData); } } [HarmonyPatch(typeof(BulletWeapon), "OnWield")] [HarmonyWrapSafe] [HarmonyPostfix] private static void UpdateCurrentWeapon(BulletWeapon __instance) { CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>(); if (!((Object)(object)component == (Object)null)) { component.Invoke(StaticContext<WeaponWieldContext>.Instance); component.RefreshSoundDelay(); s_lastSearchID = 0u; } } [HarmonyPatch(typeof(BulletWeapon), "OnUnWield")] [HarmonyWrapSafe] [HarmonyPostfix] private static void UpdateWeaponUnwielded(BulletWeapon __instance) { CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>(); if (!((Object)(object)component == (Object)null)) { component.Invoke(StaticContext<WeaponUnWieldContext>.Instance); } } [HarmonyPatch(typeof(BulletWeapon), "BulletHit")] [HarmonyWrapSafe] [HarmonyPrefix] private static void HitCallback(ref WeaponHitData weaponRayData, bool doDamage, float additionalDis, uint damageSearchID, ref bool allowDirectionalBonus) { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Invalid comparison between Unknown and I4 CachedHitCC = null; if (!allowDirectionalBonus || weaponRayData.vfxBulletHit != null || !doDamage || (!((Agent)weaponRayData.owner).IsLocallyOwned && (!SNet.IsMaster || !weaponRayData.owner.Owner.IsBot))) { return; } s_hitData.Setup(weaponRayData, additionalDis); IDamageable damageable = s_hitData.damageable; IDamageable val = ((damageable != null) ? damageable.GetBaseDamagable() : damageable); if ((val != null && val.GetHealthRel() <= 0f) || (damageSearchID != 0 && val != null && val.TempSearchID == damageSearchID)) { return; } ItemEquippable wieldedItem = s_hitData.owner.Inventory.WieldedItem; CustomWeaponComponent customWeaponComponent = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null); if ((Object)(object)customWeaponComponent == (Object)null) { Agent val2 = ((damageable != null) ? damageable.GetBaseAgent() : null); if ((Object)(object)val2 != (Object)null && (int)val2.Type == 1 && val2.Alive) { KillTrackerManager.ClearHit(((Il2CppObjectBase)val2).TryCast<EnemyAgent>()); } return; } if (damageable != null && damageSearchID != 0) { if (s_lastSearchID != damageSearchID) { s_lastSearchID = damageSearchID; s_origHitDamage = s_hitData.damage; s_origHitPrecision = s_hitData.precisionMulti; } s_hitData.damage = s_origHitDamage; s_hitData.precisionMulti = s_origHitPrecision; } ApplyEWCHit(customWeaponComponent, s_hitData, damageSearchID != 0, ref s_origHitDamage, out allowDirectionalBonus); } public static void ApplyEWCHit(CustomWeaponComponent cwc, HitData hitData, bool pierce, ref float pierceDamage, out bool doBackstab, bool triggerHit = true) { ApplyEWCHit(cwc.GetContextController(), cwc.Weapon, hitData, pierce, ref pierceDamage, out doBackstab, triggerHit); } public static void ApplyEWCHit(ContextController cc, ItemEquippable weapon, HitData hitData, bool pierce, ref float pierceDamage, out bool doBackstab, bool triggerHit = true) { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Invalid comparison between Unknown and I4 //IL_00de: 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) doBackstab = true; CachedHitCC = cc; IDamageable damageable = hitData.damageable; if (damageable != null && damageable.GetBaseDamagable().GetHealthRel() > 0f) { if (triggerHit) { cc.Invoke(new WeaponPreHitDamageableContext(hitData, DamageType.Bullet)); } WeaponDamageContext weaponDamageContext = new WeaponDamageContext(hitData.damage, hitData.precisionMulti, damageable); cc.Invoke(weaponDamageContext); hitData.damage = weaponDamageContext.Damage.Value; hitData.precisionMulti = weaponDamageContext.Precision.Value; CachedBypassTumorCap = weaponDamageContext.BypassTumorCap; if (pierce) { WeaponPierceContext weaponPierceContext = new WeaponPierceContext(pierceDamage, damageable); cc.Invoke(weaponPierceContext); pierceDamage = weaponPierceContext.Value; } Agent baseAgent = damageable.GetBaseAgent(); if ((Object)(object)baseAgent != (Object)null && baseAgent.Alive && (int)baseAgent.Type == 1) { Dam_EnemyDamageLimb val = ((Il2CppObjectBase)damageable).Cast<Dam_EnemyDamageLimb>(); float num = val.ApplyDamageFromBehindBonus(1f, hitData.hitPos, ((Vector3)(ref hitData.fireDir)).normalized, 1f); float num2 = num.Map(1f, 2f, 1f, cc.Invoke(new WeaponBackstabContext()).Value); WeaponHitDamageableContext weaponHitDamageableContext = new WeaponHitDamageableContext(hitData, CachedBypassTumorCap, num2, val, DamageType.Bullet); if (triggerHit) { cc.Invoke(weaponHitDamageableContext); } KillTrackerManager.RegisterHit(weapon, weaponHitDamageableContext); if (num2 > 1f) { hitData.damage *= num2 / num; } else { doBackstab = false; } } else if (triggerHit) { cc.Invoke(new WeaponHitDamageableContext(hitData, DamageType.Bullet)); } } if (triggerHit) { cc.Invoke(new WeaponHitContext(hitData)); } hitData.Apply(); } } [HarmonyPatch] internal static class WeaponRayPatches { public static BulletWeapon? CachedWeapon = null; private static HitData s_hitData = new HitData(); private static CustomWeaponComponent? _cachedCWC = null; private static IntPtr _cachedData = IntPtr.Zero; [HarmonyTargetMethod] private static MethodBase FindWeaponRayFunc(Harmony harmony) { return AccessTools.Method(typeof(Weapon), "CastWeaponRay", new Type[4] { typeof(Transform), typeof(WeaponHitData).MakeByRefType(), typeof(Vector3), typeof(int) }, (Type[])null); } [HarmonyWrapSafe] [HarmonyPrefix] private static void PreRayCallback(ref WeaponHitData weaponRayData, Vector3 originPos, int altRayCastMask) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) if (altRayCastMask != -1 || _cachedData == ((Il2CppObjectBase)weaponRayData).Pointer) { return; } _cachedData = ((Il2CppObjectBase)weaponRayData).Pointer; if ((Object)(object)CachedWeapon != (Object)null) { _cachedCWC = ((Component)CachedWeapon).GetComponent<CustomWeaponComponent>(); } else { PlayerAgent owner = weaponRayData.owner; object cachedCWC; if (owner == null) { cachedCWC = null; } else { ItemEquippable wieldedItem = owner.Inventory.WieldedItem; cachedCWC = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null); } _cachedCWC = (CustomWeaponComponent?)cachedCWC; } if (!((Object)(object)_cachedCWC == (Object)null)) { s_hitData.Setup(weaponRayData); _cachedCWC.Invoke(new WeaponPreRayContext(s_hitData, originPos)); s_hitData.Apply(); } } [HarmonyWrapSafe] [HarmonyPostfix] private static void PostRayCallback(ref WeaponHitData weaponRayData, Vector3 originPos, int altRayCastMask, ref bool __result) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_cachedCWC == (Object)null)) { s_hitData.Setup(weaponRayData); if (!_cachedCWC.Invoke(new WeaponCancelRayContext(s_hitData, originPos)).Result) { __result = false; return; } __result = _cachedCWC.Invoke(new WeaponPostRayContext(s_hitData, originPos, __result, (IntPtr)0)).Result; s_hitData.Apply(); _cachedCWC = null; } } } [HarmonyPatch] internal static class WeaponRecoilPatches { private static BulletWeapon? _cachedWeapon; private static CustomWeaponComponent? _cachedComponent; [HarmonyPatch(typeof(BulletWeapon), "OnWield")] [HarmonyWrapSafe] [HarmonyPostfix] private static void UpdateCurrentWeapon(BulletWeapon __instance) { PlayerAgent owner = ((Item)__instance).Owner; if (owner != null && ((Agent)owner).IsLocallyOwned) { _cachedWeapon = __instance; _cachedComponent = ((Component)__instance).GetComponent<CustomWeaponComponent>(); } } [HarmonyAfter(new string[] { "Dinorush.ExtraRecoilData" })] [HarmonyPatch(typeof(FPS_RecoilSystem), "ApplyRecoil")] [HarmonyWrapSafe] [HarmonyPostfix] private static void PostApplyRecoilCallback(FPS_RecoilSystem __instance, bool resetSimilarity, RecoilDataBlock recoilData) { //IL_0031: 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_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_0075: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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) if (!((Object)(object)_cachedComponent == (Object)null)) { WeaponRecoilContext weaponRecoilContext = new WeaponRecoilContext(); _cachedComponent.Invoke(weaponRecoilContext); if (weaponRecoilContext.Value != 1f) { Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(__instance.recoilDir.x * (weaponRecoilContext.Value - 1f), __instance.recoilDir.y * (weaponRecoilContext.Value - 1f)); Vector2 currentRecoilForce = __instance.currentRecoilForce; currentRecoilForce.x -= val.x * (1f - recoilData.worldToViewSpaceBlendVertical); currentRecoilForce.y -= val.y * (1f - recoilData.worldToViewSpaceBlendHorizontal); Vector2 currentRecoilForceVP = __instance.currentRecoilForceVP; currentRecoilForceVP.x -= val.x * recoilData.worldToViewSpaceBlendVertical; currentRecoilForceVP.y -= val.y * recoilData.worldToViewSpaceBlendHorizontal; Vector2 recoilDir = __instance.recoilDir; ((Vector2)(ref recoilDir)).Set(__instance.recoilDir.x * weaponRecoilContext.Value, __instance.recoilDir.y * weaponRecoilContext.Value); __instance.currentRecoilForce = currentRecoilForce; __instance.currentRecoilForceVP = currentRecoilForceVP; } } } } [HarmonyPatch] internal static class WeaponSyncPatches { [HarmonyPatch(typeof(BulletWeaponSynced), "OnGearSpawnComplete")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_SetupSynced(BulletWeaponSynced __instance) { CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>(); if (!((Object)(object)component == (Object)null)) { component.SetToSync(); } } [HarmonyPatch(typeof(ShotgunSynced), "Fire")] [HarmonyPatch(typeof(BulletWeaponSynced), "Fire")] [HarmonyWrapSafe] [HarmonyPrefix] private static void Pre_FireSynced(BulletWeaponSynced __instance) { CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>(); if (!((Object)(object)component == (Object)null)) { component.Invoke(StaticContext<WeaponPreFireContextSync>.Instance); } } [HarmonyPatch(typeof(ShotgunSynced), "Fire")] [HarmonyPatch(typeof(BulletWeaponSynced), "Fire")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_FireSynced(BulletWeaponSynced __instance) { CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>(); if (!((Object)(object)component == (Object)null)) { component.UpdateStoredFireRate(); component.ModifyFireRateSynced(__instance); component.Invoke(StaticContext<WeaponPostFireContextSync>.Instance); } } } [HarmonyPatch] internal static class PlayerLocalPatches { [HarmonyPatch(typeof(PUI_LocalPlayerStatus), "UpdateHealth")] [HarmonyWrapSafe] [HarmonyPrefix] private static void UpdateHealth(PUI_LocalPlayerStatus __instance, float health, bool meleeBuffActive) { if (__instance.m_lastHealthVal <= 0.14f && health > 0.14f && __instance.m_warningRoutine != null) { __instance.m_healthWarningLooping = true; } } } } namespace EWC.Patches.Native { internal static class EnemyDetectionPatches { private unsafe delegate void d_DetectOnNoise(IntPtr _this, IntPtr agentTarget, float movementDetectionDistance, float shootDetectionDistance, float delta, out float output, Il2CppMethodInfo* methodInfo); private struct CWCHolder { public CustomWeaponComponent? primary; public bool hasPrimary; public CustomWeaponComponent? special; public bool hasSpecial; public readonly bool IsValid { get { if ((Object)(object)primary != (Object)null == hasPrimary) { return (Object)(object)special != (Object)null == hasSpecial; } return false; } } } private static INativeDetour? DetectOnNoiseDetour; private static d_DetectOnNoise? orig_DetectOnNoise; private static readonly Dictionary<int, CWCHolder> s_cachedCWCs = new Dictionary<int, CWCHolder>(); internal unsafe static void ApplyNativePatch() { DetectOnNoiseDetour = INativeDetour.CreateAndApply<d_DetectOnNoise>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<EnemyDetection>("DetectOnNoiseDistance_Conditional_AnimatedWindow", typeof(void).Name, false, new string[5] { "AgentTarget", typeof(float).Name, typeof(float).Name, typeof(float).Name, typeof(float).MakeByRefType().Name }), (d_DetectOnNoise)DetectOnNoisePatch, ref orig_DetectOnNoise); NativePatchAPI.AddDetectPostfix(Post_DetectAgentNoise); } private unsafe static void DetectOnNoisePatch(IntPtr _this, IntPtr agentTarget, float movementDetectionDistance, float shootDetectionDistance, float delta, out float output, Il2CppMethodInfo* methodInfo) { //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_0015: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0044: Expected O, but got Unknown output = 0f; EnemyDetection val = new EnemyDetection(_this); AgentTarget agentTarget2 = new AgentTarget(agentTarget); if (NativePatchAPI.RunDetectPrefix(val, agentTarget2, movementDetectionDistance, shootDetectionDistance, delta, ref output)) { orig_DetectOnNoise(_this, agentTarget, movementDetectionDistance, shootDetectionDistance, delta, out output, methodInfo); } NativePatchAPI.RunDetectPostfix(val, agentTarget2, movementDetectionDistance, shootDetectionDistance, delta, ref output); } private static void UpdateCache() { if (s_cachedCWCs.Count == PlayerManager.PlayerAgentsInLevel.Count && !s_cachedCWCs.Values.Any((CWCHolder holder) => !holder.IsValid)) { return; } s_cachedCWCs.Clear(); Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); PlayerBackpack val = default(PlayerBackpack); BackpackItem val2 = default(BackpackItem); BackpackItem val3 = default(BackpackItem); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (PlayerBackpackManager.TryGetBackpack(current.Owner, ref val) && val.TryGetBackpackItem((InventorySlot)1, ref val2) && val.TryGetBackpackItem((InventorySlot)2, ref val3)) { Item instance = val2.Instance; CustomWeaponComponent customWeaponComponent = ((instance != null) ? ((Component)instance).GetComponent<CustomWeaponComponent>() : null); Item instance2 = val3.Instance; CustomWeaponComponent customWeaponComponent2 = ((instance2 != null) ? ((Component)instance2).GetComponent<CustomWeaponComponent>() : null); s_cachedCWCs.Add(((Agent)current).GlobalID, new CWCHolder { primary = customWeaponComponent, hasPrimary = ((Object)(object)customWeaponComponent != (Object)null), special = customWeaponComponent2, hasSpecial = ((Object)(object)customWeaponComponent2 != (Object)null) }); } } } private static void Post_DetectAgentNoise(EnemyDetection __instance, AgentTarget agentTarget, float _mv, float _wp, float _delta, ref float output) { UpdateCache(); if (s_cachedCWCs.TryGetValue(agentTarget.m_globalID, out var value) && (value.hasPrimary || value.hasSpecial)) { WeaponStealthUpdateContext weaponStealthUpdateContext = new WeaponStealthUpdateContext(__instance.m_ai.m_enemyAgent, __instance.m_noiseDetectionOn, output); value.primary?.Invoke(weaponStealthUpdateContext); value.special?.Invoke(weaponStealthUpdateContext); output = weaponStealthUpdateContext.Output; } } } } namespace EWC.Patches.Melee { [HarmonyPatch] internal static class MeleePatches { private static readonly HitData s_hitData = new HitData(); private static float s_origHitDamage = 0f; private static float s_origHitPrecision = 0f; public static float CachedCharge { get; private set; } = 0f; [HarmonyPatch(typeof(MeleeWeaponFirstPerson), "SetupMeleeAnimations")] [HarmonyWrapSafe] [HarmonyPostfix] private static void SetupCallback(MeleeWeaponFirstPerson __instance) { CachedCharge = 0f; CustomWeaponManager.Current.AddWeaponListener((ItemEquippable)(object)__instance); CustomWeaponData customMeleeData = CustomWeaponManager.Current.GetCustomMeleeData(((GameDataBlockBase<MeleeArchetypeDataBlock>)(object)((ItemEquippable)__instance).MeleeArchetypeData).persistentID); if (customMeleeData != null && !((Object)(object)((Component)__instance).gameObject.GetComponent<CustomWeaponComponent>() != (Object)null)) { ((Component)__instance).gameObject.AddComponent<CustomWeaponComponent>().Register(customMeleeData); } } [HarmonyPatch(typeof(MeleeWeaponFirstPerson), "OnWield")] [HarmonyWrapSafe] [HarmonyPostfix] private static void UpdateCurrentWeapon(MeleeWeaponFirstPerson __instance) { CachedCharge = 0f; CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>(); if (!((Object)(object)component == (Object)null)) { component.Invoke(StaticContext<WeaponWieldContext>.Instance); } } [HarmonyPatch(typeof(MeleeWeaponFirstPerson), "OnUnWield")] [HarmonyWrapSafe] [HarmonyPostfix] private static void ClearCharge(MeleeWeaponFirstPerson __instance) { CachedCharge = 0f; CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>(); if (!((Object)(object)component == (Object)null)) { component.Invoke(StaticContext<WeaponUnWieldContext>.Instance); } } [HarmonyPatch(typeof(MeleeWeaponFirstPerson), "SetNextDamageToDeal")] [HarmonyWrapSafe] [HarmonyPostfix] private static void SetDamageCallback(MeleeWeaponFirstPerson __instance, eMeleeWeaponDamage dam, float scale) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 s_origHitDamage = __instance.m_damageToDeal; s_origHitPrecision = __instance.m_precisionMultiToDeal; CachedCharge = (((int)dam == 2) ? ((float)Math.Cbrt(scale)) : 0f); } [HarmonyPatch(typeof(MeleeWeaponFirstPerson), "DoAttackDamage")] [HarmonyWrapSafe] [HarmonyPrefix] private static void HitCallback(MeleeWeaponFirstPerson __instance, MeleeWeaponDamageData data, bool isPush) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 if (isPush) { return; } s_hitData.Setup(__instance, data); IDamageable damageable = s_hitData.damageable; IDamageable val = ((damageable != null) ? damageable.GetBaseDamagable() : null); if (val != null && val.GetHealthRel() <= 0f) { return; } CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>(); if ((Object)(object)component == (Object)null) { Agent val2 = ((damageable != null) ? damageable.GetBaseAgent() : null); if ((Object)(object)val2 != (Object)null && (int)val2.Type == 1 && val2.Alive) { KillTrackerManager.ClearHit(((Il2CppObjectBase)val2).TryCast<EnemyAgent>()); } WeaponPatches.CachedHitCC = null; } else { s_hitData.damage = s_origHitDamage; s_hitData.precisionMulti = s_origHitPrecision; WeaponPatches.ApplyEWCHit(component, s_hitData, pierce: false, ref s_origHitDamage, out var _); } } } [HarmonyPatch] internal static class MWSPatches { [HarmonyPatch(typeof(MWS_ChargeUp), "Enter")] [HarmonyWrapSafe] [HarmonyPostfix] private static void ChargeCallback(MWS_ChargeUp __instance) { CustomWeaponComponent component = ((Component)((MWS_Base)__instance).m_weapon).GetComponent<CustomWeaponComponent>(); if (!((Object)(object)component == (Object)null)) { WeaponFireRateContext weaponFireRateContext = new WeaponFireRateContext(1f); component.Invoke(weaponFireRateContext); __instance.m_maxDamageTime /= weaponFireRateContext.Value; } } [HarmonyPatch(typeof(MWS_Push), "Enter")] [HarmonyWrapSafe] [HarmonyPostfix] private static void PushCallback(MWS_Push __instance) { CustomWeaponComponent component = ((Component)((MWS_Base)__instance).m_weapon).GetComponent<CustomWeaponComponent>(); if (!((Object)(object)component == (Object)null)) { WeaponFireRateContext weaponFireRateContext = new WeaponFireRateContext(1f); component.Invoke(weaponFireRateContext); Animator weaponAnimator = ((MWS_Base)__instance).m_weapon.WeaponAnimator; weaponAnimator.speed *= weaponFireRateContext.Value; } } [HarmonyPatch(typeof(MWS_AttackSwingBase), "Enter")] [HarmonyWrapSafe] [HarmonyPostfix] private static void PreSwingCallback(MWS_AttackSwingBase __instance) { CustomWeaponComponent component = ((Component)((MWS_Base)__instance).m_weapon).GetComponent<CustomWeaponComponent>(); if (!((Object)(object)component == (Object)null)) { component.Invoke(StaticContext<WeaponPreFireContext>.Instance); } } [HarmonyPatch(typeof(MWS_AttackSwingBase), "Exit")] [HarmonyWrapSafe] [HarmonyPostfix] private static void PostSwingCallback(MWS_AttackSwingBase __instance) { CustomWeaponComponent component = ((Component)((MWS_Base)__instance).m_weapon).GetComponent<CustomWeaponComponent>(); if (!((Object)(object)component == (Object)null)) { component.Invoke(StaticContext<WeaponPostFireContext>.Instance); } } } } namespace EWC.Networking { public abstract class SyncedEvent<T> where T : struct { public delegate void ReceiveHandler(T packet); private bool _isSetup; public abstract string GUID { get; } public bool IsSetup => _isSetup; public string EventName { get; private set; } = string.Empty; public event ReceiveHandler? OnReceive; public event ReceiveHandler? OnReceiveLocal; public void Setup() { if (!_isSetup) { EventName = "EWC" + GUID; NetworkAPI.RegisterEvent<T>(EventName, (Action<ulong, T>)ReceiveClient_Callback); _isSetup = true; } } public void Send(T packetData, SNet_Player? target = null, SNet_ChannelType priority = 4) { //IL_0020: 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) if ((Object)(object)target != (Object)null) { NetworkAPI.InvokeEvent<T>(EventName, packetData, target, priority); } else { NetworkAPI.InvokeEvent<T>(EventName, packetData, priority); } ReceiveLocal_Callback(packetData); } private void ReceiveLocal_Callback(T packet) { ReceiveLocal(packet); this.OnReceiveLocal?.Invoke(packet); } private void ReceiveClient_Callback(ulong sender, T packet) { Receive(packet); this.OnReceive?.Invoke(packet); } protected virtual void ReceiveLocal(T packet) { } protected virtual void Receive(T packet) { } } public abstract class SyncedEventMasterOnly<T> : SyncedEvent<T> where T : struct { public void Send(T packet, SNet_ChannelType priority = 4) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster) { Send(packet, SNet.Master, priority); } else { Receive(packet); } } } } namespace EWC.Networking.Structs { public struct LowResColor { public byte r; public byte g; public byte b; public byte a; private static Color s_color = Color.black; public static implicit operator Color(LowResColor lowResColor) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) s_color.r = (float)(int)lowResColor.r / 255f; s_color.g = (float)(int)lowResColor.g / 255f; s_color.b = (float)(int)lowResColor.b / 255f; s_color.a = (float)(int)lowResColor.a / 255f; return s_color; } public static implicit operator LowResColor(Color color) { //IL_000a: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) LowResColor result = default(LowResColor); result.r = (byte)(color.r * 255f); result.g = (byte)(color.g * 255f); result.b = (byte)(color.b * 255f); result.a = (byte)(color.a * 255f); return result; } } } namespace EWC.JSON { internal static class CustomWeaponTemplate { internal static CustomWeaponData CreateTemplate() { return new CustomWeaponData { ArchetypeID = 0u, Name = "Example", Properties = new PropertyList(new List<WeaponPropertyBase> { new ReferenceProperty(), new AmmoMod(), new AmmoRegen(), new DamageMod(), new DamageModPerTarget(), new DamageOverTime(), new Explosive(), new FireRateMod(), new FireShot(), new HealthMod(), new RecoilM