Decompiled source of Runic Bow v1.0.0

RunicBow.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SideLoader;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("RunicBow")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RunicBow")]
[assembly: AssemblyTitle("RunicBow")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RunicBow
{
	public static class RunicBowManager
	{
		[HarmonyPatch(typeof(WeaponLoadoutItem), "ShootItemFromLoadout")]
		public class WeaponLoadoutItem_ShootItemFromLoadout
		{
			[HarmonyPrefix]
			public static void Prefix(ProjectileItem _projItem)
			{
				if (!((Object)(object)_projItem == (Object)null) && !((Component)_projItem).gameObject.activeSelf)
				{
					((Component)_projItem).gameObject.SetActive(true);
				}
			}
		}

		[HarmonyPatch(typeof(ProjectileItem), "AssignVisual")]
		public class ProjectileItem_AssignVisual
		{
			[HarmonyPrefix]
			public static void Prefix(ref Projectile ___m_projectile, ProjectileItem __instance)
			{
				___m_projectile = ((Component)__instance).GetComponent<Projectile>();
			}
		}

		[HarmonyPatch(typeof(PlayerCharacterStats), "OnUpdateStats")]
		public class PlayerStats_Update
		{
			[HarmonyFinalizer]
			public static Exception Finalizer(PlayerCharacterStats __instance)
			{
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Invalid comparison between Unknown and I4
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Expected O, but got Unknown
				Character component = ((Component)__instance).GetComponent<Character>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					return null;
				}
				if (!CharChargingAttack.Invoke(component) || !CharBowDrawn.Invoke(component))
				{
					return null;
				}
				if (Object.op_Implicit((Object)(object)component.CurrentWeapon) && (int)component.CurrentWeapon.Type == 200)
				{
					WeaponCharger val = (WeaponCharger)((Item)component.CurrentWeapon).GetExtension("WeaponCharger");
					if (!val.ChargeStarted && val.StartChargeTime < 0.0)
					{
						CharChargingAttack.Invoke(component) = false;
						CharBowDrawn.Invoke(component) = false;
					}
				}
				return null;
			}
		}

		[HarmonyPatch(typeof(EffectSynchronizer), "RegisterEffectReference")]
		public class EffectSynchronizer_RegisterEffectReference
		{
			[HarmonyPrefix]
			public static void Prefix(EffectSynchronizer __instance, ref List<string>[] ___m_categoryEffects)
			{
				if (___m_categoryEffects == null)
				{
					___m_categoryEffects = new List<string>[EffectSynchronizer.EffectCategoriesCount];
					for (int i = 0; i < ___m_categoryEffects.Length; i++)
					{
						___m_categoryEffects[i] = new List<string>();
					}
				}
			}
		}

		[HarmonyPatch(typeof(ProjectileWeapon), "UpdateProcessing")]
		public class ProjectileWeapon_UpdateProcessing
		{
			[HarmonyPostfix]
			public static void Postfix(ProjectileWeapon __instance, ref bool ___m_fullyBent)
			{
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				if (IsRunicBow((Item)(object)__instance) & ___m_fullyBent)
				{
					Character ownerCharacter = ((EffectSynchronizer)__instance).OwnerCharacter;
					if (!Object.op_Implicit((Object)(object)ownerCharacter.Inventory.Equipment.GetEquippedItem((EquipmentSlotIDs)8)))
					{
						___m_fullyBent = false;
						CharChargingAttack.Invoke(ownerCharacter) = false;
						ownerCharacter.BowRelease();
						((WeaponCharger)((Item)__instance).GetExtension("WeaponCharger")).ResetCharging();
					}
				}
			}
		}

		[HarmonyPatch(typeof(ProjectileItem), "ForceReturn")]
		public class ProjectileItem_ForceReturn
		{
			[HarmonyFinalizer]
			public static Exception Finalizer()
			{
				return null;
			}
		}

		[HarmonyPatch(typeof(WeaponLoadout), "CanBeLoaded")]
		public class WeaponLoadout_CanBeLoaded
		{
			[HarmonyPrefix]
			public static bool Prefix(WeaponLoadout __instance, ref bool __result)
			{
				Item item = ((ItemExtension)__instance).Item;
				if (IsRunicBow(item))
				{
					__result = CanBeLoaded(item);
					return false;
				}
				return true;
			}

			public static bool CanBeLoaded(Item item)
			{
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				Character ownerCharacter = ((EffectSynchronizer)item).OwnerCharacter;
				if (!Object.op_Implicit((Object)(object)ownerCharacter))
				{
					Debug.Log((object)"Runic bow has no owner!");
					return false;
				}
				float currentMana = ownerCharacter.Stats.CurrentMana;
				float finalManaConsumption = ownerCharacter.Stats.GetFinalManaConsumption((Tag[])null, 5f);
				if (currentMana - finalManaConsumption < 0f)
				{
					ownerCharacter.CharacterUI.ShowInfoNotificationLoc("Notification_Skill_NotEnoughtMana");
					return false;
				}
				if (!ownerCharacter.Inventory.HasEquipped(-88001))
				{
					((Item)((!ownerCharacter.Inventory.OwnsItem(-88001)) ? ((object)/*isinst with value type is only supported in some contexts*/) : ((object)(Ammunition)ownerCharacter.Inventory.GetOwnedItems(-88001)[0]))).ChangeParent(ownerCharacter.Inventory.Equipment.GetMatchingEquipmentSlotTransform((EquipmentSlotIDs)8));
				}
				return true;
			}
		}

		[HarmonyPatch]
		public class WeaponLoadout_ReduceShotAmount
		{
			[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
			[HarmonyPatch(typeof(WeaponLoadout), "ReduceShotAmount")]
			public static void ReversePatch(object instance, bool _destroyOnEmpty)
			{
				throw new NotImplementedException("WeaponLoadoutRP.ReduceShotAmount");
			}

			[HarmonyPrefix]
			[HarmonyPatch(typeof(WeaponLoadout), "ReduceShotAmount")]
			[HarmonyPatch(typeof(WeaponLoadoutItem), "ReduceShotAmount")]
			[HarmonyBefore(new string[] { "com.SpicerXD.RaidMode" })]
			public static bool Prefix(WeaponLoadout __instance, bool _destroyOnEmpty)
			{
				//IL_0187: Unknown result type (might be due to invalid IL or missing references)
				Item item = ((ItemExtension)__instance).Item;
				if (IsRunicBow(item))
				{
					float finalManaConsumption = ((EffectSynchronizer)item).OwnerCharacter.Stats.GetFinalManaConsumption((Tag[])null, 5f);
					((EffectSynchronizer)item).OwnerCharacter.Stats.UseMana((Tag[])null, finalManaConsumption);
					RemainingShots.Invoke(__instance)--;
					if (RemainingShots.Invoke(__instance) < 0)
					{
						RemainingShots.Invoke(__instance) = 0;
					}
					if (RemainingShots.Invoke(__instance) == 0)
					{
						__instance.Unload();
					}
					Item equippedItem = ((EffectSynchronizer)((ItemExtension)__instance).Item).OwnerCharacter.Inventory.Equipment.GetEquippedItem((EquipmentSlotIDs)8);
					Ammunition val = (Ammunition)(object)((equippedItem is Ammunition) ? equippedItem : null);
					((EffectSynchronizer)((ItemExtension)__instance).Item).OwnerCharacter.Inventory.Equipment.UnequipItem((Equipment)(object)val, false, (ItemContainer)null);
					((Component)val).transform.SetParent((Transform)null);
					UnityEngineExtensions.ResetLocal(((Component)val).transform, true);
					SetHasChanged((ItemExtension)(object)__instance);
					return false;
				}
				WeaponLoadoutItem val2 = (WeaponLoadoutItem)(object)((__instance is WeaponLoadoutItem) ? __instance : null);
				if (val2 != null)
				{
					if (!val2.ReduceAmmunitionOnLoad)
					{
						Ammunition val3 = LoadedAmmunition.Invoke(val2);
						if ((Object)(object)val3 != (Object)null && ((EffectSynchronizer)((ItemExtension)__instance).Item).OwnerCharacter.IsLocalPlayer)
						{
							Global.RPCManager.SendSkillUseItem(((Item)val3).UID, 1);
							if (PhotonNetwork.isNonMasterClientInRoom && ((Item)val3).RemainingAmount < 1)
							{
								int remainingAmount = ((Item)val3).RemainingAmount;
								((Item)val3).RemainingAmount = remainingAmount - 1;
							}
						}
						if (_destroyOnEmpty)
						{
							LoadedAmmunition.Invoke(val2) = null;
						}
						else if ((Object)(object)val3 == (Object)null || ((Item)val3).RemainingAmount == 0)
						{
							if (Object.op_Implicit((Object)(object)val3))
							{
								((Item)val3).SaveType = (SaveTypes)2;
							}
							List<Item> list = LastLoadedItems.Invoke(val2);
							if (list.Count > 0)
							{
								list.RemoveAt(0);
							}
							if (list.Count > 0)
							{
								ref Ammunition reference = ref LoadedAmmunition.Invoke(val2);
								Item obj = list[0];
								reference = (Ammunition)(object)((obj is Ammunition) ? obj : null);
							}
						}
					}
					ReversePatch(__instance, _destroyOnEmpty);
					if (val2.ReduceAmmunitionOnLoad)
					{
						((ItemExtension)__instance).DataSynced();
					}
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(AttackSkill), "OwnerHasAllRequiredItems")]
		public class AttackSkill_OwnerHasAllRequiredItems
		{
			[HarmonyPrefix]
			public static bool Prefix(AttackSkill __instance, bool _TryingToActivate, ref bool __result)
			{
				if (!(__instance is RangeAttackSkill))
				{
					return true;
				}
				if (Object.op_Implicit((Object)(object)((EffectSynchronizer)__instance).OwnerCharacter))
				{
					Weapon currentWeapon = ((EffectSynchronizer)__instance).OwnerCharacter.CurrentWeapon;
					ProjectileWeapon val = (ProjectileWeapon)(object)((currentWeapon is ProjectileWeapon) ? currentWeapon : null);
					if (val != null && IsRunicBow((Item)(object)val))
					{
						__result = WeaponLoadout_CanBeLoaded.CanBeLoaded((Item)(object)val);
						return false;
					}
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(UseLoadoutAmunition), "TryTriggerConditions")]
		public class UseLoadoutAmmunition_TryTriggerConditions
		{
			[HarmonyPrefix]
			public static bool Prefix(UseLoadoutAmunition __instance, ref bool __result)
			{
				if (__instance.MainHand)
				{
					Weapon currentWeapon = ((Effect)__instance).OwnerCharacter.CurrentWeapon;
					ProjectileWeapon val = (ProjectileWeapon)(object)((currentWeapon is ProjectileWeapon) ? currentWeapon : null);
					if (val != null && IsRunicBow((Item)(object)val))
					{
						__result = true;
						return false;
					}
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(UseLoadoutAmunition), "ActivateLocally")]
		public class UseLoadoutAmmunition_ActivateLocally
		{
			[HarmonyPrefix]
			public static bool Prefix(UseLoadoutAmunition __instance, Character _affectedCharacter, object[] _infos)
			{
				if (__instance.MainHand)
				{
					Weapon currentWeapon = _affectedCharacter.CurrentWeapon;
					ProjectileWeapon val = (ProjectileWeapon)(object)((currentWeapon is ProjectileWeapon) ? currentWeapon : null);
					if (val != null && IsRunicBow((Item)(object)val))
					{
						WeaponLoadout_ReduceShotAmount.Prefix(((Component)val).GetComponent<WeaponLoadout>(), __instance.DestroyOnEmpty);
						return false;
					}
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(CharacterInventory), "PlayEquipSFX")]
		public class CharacterInventory_PlayEquipSFX
		{
			[HarmonyPrefix]
			public static bool Prefix(CharacterInventory __instance, Equipment _equipment)
			{
				return ((Item)_equipment).ItemID != -88001;
			}
		}

		[HarmonyPatch(typeof(CharacterInventory), "PlayUnequipSFX")]
		public class CharacterInventory_PlayUnequipSFX
		{
			[HarmonyPrefix]
			public static bool Prefix(CharacterInventory __instance, Equipment _equipment)
			{
				return ((Item)_equipment).ItemID != -88001;
			}
		}

		private const string RunicBowTagString = "RunicBow";

		public const int RunicArrowID = -88001;

		public const float RunicBowCost = 5f;

		public const float RunicBowHoldCost = 0.1f;

		public static Tag RunicBowTag;

		private static readonly FieldRef<Character, bool> CharChargingAttack = AccessTools.FieldRefAccess<Character, bool>("m_currentlyChargingAttack");

		private static readonly FieldRef<Character, bool> CharBowDrawn = AccessTools.FieldRefAccess<Character, bool>("m_bowDrawn");

		private static readonly FieldRef<CharacterEquipment, Character> EquipmentOwner = AccessTools.FieldRefAccess<CharacterEquipment, Character>("m_character");

		private static readonly FieldRef<ProjectileItem, int> ProjectileItemID = AccessTools.FieldRefAccess<ProjectileItem, int>("m_itemID");

		private static readonly FieldRef<ProjectileItem, Item> ProjectileItemPrefab = AccessTools.FieldRefAccess<ProjectileItem, Item>("m_item");

		private static readonly FieldRef<WeaponLoadout, int> RemainingShots = AccessTools.FieldRefAccess<WeaponLoadout, int>("m_remainingShots");

		private static readonly FieldRef<WeaponLoadoutItem, Ammunition> LoadedAmmunition = AccessTools.FieldRefAccess<WeaponLoadoutItem, Ammunition>("m_loadedAmmunition");

		private static readonly FieldRef<WeaponLoadoutItem, List<Item>> LastLoadedItems = AccessTools.FieldRefAccess<WeaponLoadoutItem, List<Item>>("m_lastLoadedItems");

		private static readonly Action<ItemExtension> SetHasChanged = AccessTools.MethodDelegate<Action<ItemExtension>>(AccessTools.Method(typeof(ItemExtension), "SetHasChanged", (Type[])null, (Type[])null), (object)null, true);

		public static bool IsRunicBow(Item item)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)item))
			{
				return item.HasTag(RunicBowTag);
			}
			return false;
		}

		public static void BeforePacksLoaded()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			RunicBowTag = CustomTags.CreateTag("RunicBow");
			Type typeByName = At.GetTypeByName("RaidMode.CharacterEquipment_Update");
			if (typeByName != null)
			{
				MethodInfo method = typeByName.GetMethod("Postfix", BindingFlags.Static | BindingFlags.Public);
				RunicBowPlugin.harmony.Patch((MethodBase)method, new HarmonyMethod(typeof(RunicBowManager), "FixRaidModePatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		public static bool FixRaidModePatch(CharacterEquipment __0)
		{
			return !IsRunicBow((Item)(object)EquipmentOwner.Invoke(__0).CurrentWeapon);
		}

		public static void OnPacksLoaded()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(-88001);
			Ammunition val = (Ammunition)(object)((itemPrefab is Ammunition) ? itemPrefab : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Debug.LogError((object)("[Runic Bow] Could not find the Runic Arrow prefab (ID " + -88001 + "). Check that SideLoader/Items/-88001_RunicArrow is present and its New_ItemID matches."));
				return;
			}
			ItemVisualsLink orAddVisualLink = CustomItemVisuals.GetOrAddVisualLink((Item)(object)val);
			orAddVisualLink.ItemSpecialVisuals = new GameObject("RunicQuiverDummy").transform;
			Object.DontDestroyOnLoad((Object)(object)((Component)orAddVisualLink.ItemSpecialVisuals).gameObject);
			GameObject gameObject = ((Component)val.ProjectileFXPrefab).gameObject;
			gameObject.SetActive(false);
			val.ProjectileFXPrefab = Object.Instantiate<GameObject>(gameObject).transform;
			gameObject.SetActive(true);
			Object.DontDestroyOnLoad((Object)(object)((Component)val.ProjectileFXPrefab).gameObject);
			ProjectileItem component = ((Component)val.ProjectileFXPrefab).GetComponent<ProjectileItem>();
			component.CollisionBehavior = (CollisionBehaviorTypes)2;
			component.EphemeralProjectile = true;
			ProjectileItemID.Invoke(component) = -88001;
			ProjectileItemPrefab.Invoke(component) = ResourcesPrefabManager.Instance.GetItemPrefab(-88001);
			RaycastProjectile component2 = ((Component)component).GetComponent<RaycastProjectile>();
			((Projectile)component2).ProjectileVisualsToDisable = ((Component)component).gameObject;
			((Projectile)component2).ImpactSoundMaterial = (EquipmentSoundMaterials)0;
			((MonoBehaviour)RunicBowPlugin.Instance).StartCoroutine(LateFix());
		}

		private static IEnumerator LateFix()
		{
			yield return (object)new WaitForSeconds(1f);
			foreach (int item in new List<int> { 8200100, 8200101, 8200102, 8200103, 2502001, 8200310 })
			{
				Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(item);
				AttackSkill val = (AttackSkill)(object)((itemPrefab is AttackSkill) ? itemPrefab : null);
				if (val != null && !val.RequiredWeaponTypes.Contains((WeaponType)200))
				{
					val.RequiredWeaponTypes.Add((WeaponType)200);
				}
			}
		}
	}
	[BepInPlugin("com.wrango.runicbow", "Runic Bow", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class RunicBowPlugin : BaseUnityPlugin
	{
		public const string GUID = "com.wrango.runicbow";

		public const string NAME = "Runic Bow";

		public const string VERSION = "1.0.0";

		public static RunicBowPlugin Instance;

		public static Harmony harmony;

		internal static ManualLogSource Log;

		internal void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			harmony = new Harmony("com.wrango.runicbow");
			harmony.PatchAll();
			SL.BeforePacksLoaded += RunicBowManager.BeforePacksLoaded;
			SL.OnPacksLoaded += RunicBowManager.OnPacksLoaded;
		}
	}
}