Decompiled source of RunescapeMagic v1.0.6

RunescapeMagicValheim.dll

Decompiled 15 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("RunescapeMagicValheim")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Магия Runescape в Valheim")]
[assembly: AssemblyFileVersion("1.0.6.0")]
[assembly: AssemblyInformationalVersion("1.0.6+463d6903e6784e96bd582361b3e07941b94ed0f3")]
[assembly: AssemblyProduct("RunescapeMagicValheim")]
[assembly: AssemblyTitle("RunescapeMagicValheim")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.6.0")]
[module: UnverifiableCode]
[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 RunescapeMagicValheim
{
	[HarmonyPatch]
	public static class MagicWandItem
	{
		private static GameObject _wandPrefab;

		private static GameObject _prefabContainer;

		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		[HarmonyPostfix]
		public static void OnZNetSceneAwakePostfix(ZNetScene __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)_wandPrefab == (Object)null)
				{
					_wandPrefab = CreateWandPrefab(__instance);
				}
				if ((Object)(object)_wandPrefab != (Object)null && !__instance.m_prefabs.Contains(_wandPrefab))
				{
					__instance.m_prefabs.Add(_wandPrefab);
					__instance.m_namedPrefabs[StringExtensionMethods.GetStableHashCode(((Object)_wandPrefab).name)] = _wandPrefab;
				}
				SpellMechanics.IndexTreeStubs(__instance);
			}
			catch (Exception arg)
			{
				RunescapeMagicPlugin.Log.LogError((object)$"[MagicWandItem] Ошибка инициализации префаба в ZNetScene: {arg}");
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		[HarmonyPostfix]
		public static void OnObjectDBAwakePostfix(ObjectDB __instance)
		{
			try
			{
				RegisterItemAndRecipe(__instance);
			}
			catch (Exception arg)
			{
				RunescapeMagicPlugin.Log.LogError((object)$"[MagicWandItem] Ошибка регистрации в ObjectDB.Awake: {arg}");
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
		[HarmonyPostfix]
		public static void OnObjectDBCopyPostfix(ObjectDB __instance)
		{
			try
			{
				RegisterItemAndRecipe(__instance);
			}
			catch (Exception arg)
			{
				RunescapeMagicPlugin.Log.LogError((object)$"[MagicWandItem] Ошибка регистрации в ObjectDB.CopyOtherDB: {arg}");
			}
		}

		[HarmonyPatch(typeof(Player), "OnSpawned")]
		[HarmonyPostfix]
		public static void OnPlayerSpawnedPostfix(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)ObjectDB.instance == (Object)null))
			{
				string recipeName = "Recipe_RunescapeMagicWand";
				Recipe val = ObjectDB.instance.m_recipes?.Find((Recipe r) => (Object)(object)r != (Object)null && ((Object)r).name == recipeName);
				if ((Object)(object)val != (Object)null && !__instance.IsRecipeKnown(val.m_item.m_itemData.m_shared.m_name))
				{
					__instance.AddKnownRecipe(val);
				}
			}
		}

		private static GameObject CreateWandPrefab(ZNetScene znet)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0080: 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_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0525: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_0118: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: 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_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = znet.GetPrefab("Club");
			if ((Object)(object)prefab == (Object)null)
			{
				return null;
			}
			if ((Object)(object)_prefabContainer == (Object)null)
			{
				_prefabContainer = new GameObject("RunescapeMagicPrefabContainer");
				Object.DontDestroyOnLoad((Object)(object)_prefabContainer);
				_prefabContainer.SetActive(false);
			}
			GameObject val = Object.Instantiate<GameObject>(prefab, _prefabContainer.transform);
			((Object)val).name = "RunescapeMagicWand";
			Material baseMat = null;
			MeshRenderer componentInChildren = val.GetComponentInChildren<MeshRenderer>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).transform.localRotation = Quaternion.identity;
				((Component)componentInChildren).transform.localScale = new Vector3(0.4f, 0.4f, 0.5f);
				try
				{
					MeshFilter component = ((Component)componentInChildren).GetComponent<MeshFilter>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null)
					{
						Mesh val2 = Object.Instantiate<Mesh>(component.sharedMesh);
						Vector3[] vertices = val2.vertices;
						Vector3[] normals = val2.normals;
						if (vertices != null && vertices.Length != 0)
						{
							Vector3 val3 = vertices[0];
							Vector3 val4 = vertices[0];
							for (int i = 1; i < vertices.Length; i++)
							{
								val3 = Vector3.Min(val3, vertices[i]);
								val4 = Vector3.Max(val4, vertices[i]);
							}
							Vector3 val5 = val4 - val3;
							if (val5.z >= val5.x && val5.z >= val5.y)
							{
								float num = val3.z + val4.z;
								float num2 = val3.x + val4.x;
								for (int j = 0; j < vertices.Length; j++)
								{
									vertices[j].z = num - vertices[j].z;
									vertices[j].x = num2 - vertices[j].x;
									if (normals != null && j < normals.Length)
									{
										normals[j].z = 0f - normals[j].z;
										normals[j].x = 0f - normals[j].x;
									}
								}
							}
							else if (val5.y >= val5.x && val5.y >= val5.z)
							{
								float num3 = val3.y + val4.y;
								float num4 = val3.x + val4.x;
								for (int k = 0; k < vertices.Length; k++)
								{
									vertices[k].y = num3 - vertices[k].y;
									vertices[k].x = num4 - vertices[k].x;
									if (normals != null && k < normals.Length)
									{
										normals[k].y = 0f - normals[k].y;
										normals[k].x = 0f - normals[k].x;
									}
								}
							}
							else
							{
								float num5 = val3.x + val4.x;
								float num6 = val3.z + val4.z;
								for (int l = 0; l < vertices.Length; l++)
								{
									vertices[l].x = num5 - vertices[l].x;
									vertices[l].z = num6 - vertices[l].z;
									if (normals != null && l < normals.Length)
									{
										normals[l].x = 0f - normals[l].x;
										normals[l].z = 0f - normals[l].z;
									}
								}
							}
							val2.vertices = vertices;
							if (normals != null && normals.Length == vertices.Length)
							{
								val2.normals = normals;
							}
							val2.RecalculateBounds();
							component.sharedMesh = val2;
						}
					}
				}
				catch (Exception arg)
				{
					RunescapeMagicPlugin.Log.LogWarning((object)$"[MagicWandItem] Ошибка разворота меша: {arg}");
				}
				if (((Renderer)componentInChildren).materials != null && ((Renderer)componentInChildren).materials.Length != 0)
				{
					baseMat = ((Renderer)componentInChildren).materials[0];
					Material[] materials = ((Renderer)componentInChildren).materials;
					foreach (Material val6 in materials)
					{
						if ((Object)(object)val6 != (Object)null)
						{
							val6.color = new Color(0.24f, 0.18f, 0.32f);
						}
					}
				}
			}
			AddMagicalTipEffect(val.transform, componentInChildren, baseMat);
			ItemDrop component2 = val.GetComponent<ItemDrop>();
			if ((Object)(object)component2 != (Object)null && component2.m_itemData != null && component2.m_itemData.m_shared != null)
			{
				SharedData shared = component2.m_itemData.m_shared;
				shared.m_itemType = (ItemType)3;
				shared.m_name = "Волшебная палочка";
				shared.m_description = "<color=#ffd700>Бытовая магия</color>\nПКМ — выбор заклинания\nЛКМ — сотворение магии";
				shared.m_weight = 0.5f;
				shared.m_maxQuality = 1;
				shared.m_useDurability = false;
				shared.m_damages = default(DamageTypes);
				shared.m_timedBlockBonus = 0f;
				shared.m_deflectionForce = 0f;
				shared.m_blockPower = 0f;
				if (shared.m_attack != null)
				{
					shared.m_attack.m_attackStamina = 0f;
				}
				Sprite customSprite = SpellRadialMenu.GetCustomSprite("magic_wand.png");
				if ((Object)(object)customSprite != (Object)null)
				{
					shared.m_icons = (Sprite[])(object)new Sprite[1] { customSprite };
				}
				else
				{
					GameObject val7 = znet.GetPrefab("Torch") ?? znet.GetPrefab("Club");
					ItemDrop val8 = default(ItemDrop);
					if ((Object)(object)val7 != (Object)null && val7.TryGetComponent<ItemDrop>(ref val8))
					{
						shared.m_icons = val8.m_itemData.m_shared.m_icons;
					}
				}
			}
			return val;
		}

		private static void AddMagicalTipEffect(Transform wandRoot, MeshRenderer wandMr, Material baseMat)
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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)
			Transform val = wandRoot.Find("attach") ?? wandRoot;
			GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)0);
			((Object)val2).name = "MagicCoreOrb";
			Object.DestroyImmediate((Object)(object)val2.GetComponent<Collider>());
			val2.transform.SetParent(val, false);
			Vector3 localPosition = default(Vector3);
			((Vector3)(ref localPosition))..ctor(0f, 0f, 0.48f);
			if ((Object)(object)wandMr != (Object)null)
			{
				MeshFilter component = ((Component)wandMr).GetComponent<MeshFilter>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null)
				{
					float num = 0f;
					Vector3[] vertices = component.sharedMesh.vertices;
					for (int i = 0; i < vertices.Length; i++)
					{
						Vector3 val3 = ((Component)wandMr).transform.TransformPoint(vertices[i]);
						Vector3 val4 = val.InverseTransformPoint(val3);
						float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
						if (sqrMagnitude > num)
						{
							num = sqrMagnitude;
							localPosition = val4;
						}
					}
				}
			}
			val2.transform.localPosition = localPosition;
			val2.transform.localScale = new Vector3(0.08f, 0.08f, 0.08f);
			MeshRenderer component2 = val2.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				Material val5 = (((Object)(object)baseMat != (Object)null) ? new Material(baseMat) : new Material(((Renderer)component2).material));
				val5.color = new Color(0.2f, 1f, 0.85f);
				if (val5.HasProperty("_EmissionColor"))
				{
					val5.EnableKeyword("_EMISSION");
					val5.SetColor("_EmissionColor", new Color(0.2f, 1f, 0.85f) * 2.5f);
				}
				((Renderer)component2).material = val5;
			}
			Light obj = val2.AddComponent<Light>();
			obj.type = (LightType)2;
			obj.color = new Color(0.2f, 0.95f, 0.8f);
			obj.range = 3f;
			obj.intensity = 1.3f;
			obj.shadows = (LightShadows)0;
		}

		private static void RegisterItemAndRecipe(ObjectDB odb)
		{
			if ((Object)(object)odb == (Object)null || odb.m_items == null || odb.m_items.Count == 0 || (Object)(object)_wandPrefab == (Object)null)
			{
				return;
			}
			if ((Object)(object)odb.GetItemPrefab("RunescapeMagicWand") == (Object)null)
			{
				odb.m_items.Add(_wandPrefab);
				if (odb.m_itemByHash != null)
				{
					odb.m_itemByHash[StringExtensionMethods.GetStableHashCode(((Object)_wandPrefab).name)] = _wandPrefab;
				}
			}
			string recipeName = "Recipe_RunescapeMagicWand";
			if (odb.m_recipes != null && odb.m_recipes.Exists((Recipe r) => (Object)(object)r != (Object)null && ((Object)r).name == recipeName))
			{
				return;
			}
			ItemDrop component = _wandPrefab.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			Sprite customSprite = SpellRadialMenu.GetCustomSprite("magic_wand.png");
			if ((Object)(object)customSprite != (Object)null && component.m_itemData?.m_shared != null)
			{
				component.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { customSprite };
			}
			Recipe val = ScriptableObject.CreateInstance<Recipe>();
			((Object)val).name = recipeName;
			val.m_item = component;
			val.m_amount = 1;
			val.m_enabled = true;
			val.m_minStationLevel = 1;
			if ((Object)(object)val.m_craftingStation == (Object)null)
			{
				Recipe val2 = odb.m_recipes?.Find((Recipe r) => (Object)(object)r != (Object)null && (Object)(object)r.m_craftingStation != (Object)null && ((Object)r.m_craftingStation).name == "piece_workbench");
				if ((Object)(object)val2 != (Object)null)
				{
					val.m_craftingStation = val2.m_craftingStation;
				}
				else
				{
					GameObject itemPrefab = odb.GetItemPrefab("Hammer");
					ItemDrop val3 = default(ItemDrop);
					if ((Object)(object)itemPrefab != (Object)null && itemPrefab.TryGetComponent<ItemDrop>(ref val3) && val3.m_itemData != null && val3.m_itemData.m_shared != null)
					{
						PieceTable buildPieces = val3.m_itemData.m_shared.m_buildPieces;
						if ((Object)(object)buildPieces != (Object)null && buildPieces.m_pieces != null)
						{
							GameObject val4 = buildPieces.m_pieces.Find((GameObject p) => (Object)(object)p != (Object)null && ((Object)p).name == "piece_workbench");
							if ((Object)(object)val4 != (Object)null)
							{
								val.m_craftingStation = val4.GetComponent<CraftingStation>();
							}
						}
					}
				}
			}
			List<Requirement> list = new List<Requirement>();
			AddRequirement(odb, list, "Wood", 10);
			AddRequirement(odb, list, "Resin", 4);
			AddRequirement(odb, list, "GreydwarfEye", 1);
			val.m_resources = list.ToArray();
			if (odb.m_recipes != null)
			{
				odb.m_recipes.Add(val);
			}
			RunescapeMagicPlugin.Log.LogInfo((object)"Волшебная палочка и рецепт на верстаке успешно зарегистрированы! Стоимость: 10 Дерева, 4 Смолы, 1 Глаз грейдворфа.");
		}

		private static void AddRequirement(ObjectDB odb, List<Requirement> list, string resName, int amount)
		{
			//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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			GameObject itemPrefab = odb.GetItemPrefab(resName);
			ItemDrop resItem = default(ItemDrop);
			if ((Object)(object)itemPrefab != (Object)null && itemPrefab.TryGetComponent<ItemDrop>(ref resItem))
			{
				list.Add(new Requirement
				{
					m_resItem = resItem,
					m_amount = amount,
					m_amountPerLevel = amount,
					m_recover = true
				});
			}
		}

		[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(int) })]
		[HarmonyPostfix]
		public static void OnItemGetTooltipPostfix(ItemData __instance, ref string __result)
		{
			if (__instance == null || __instance.m_shared == null)
			{
				return;
			}
			if (!(__instance.m_shared.m_name == "Волшебная палочка"))
			{
				GameObject dropPrefab = __instance.m_dropPrefab;
				if (!(((dropPrefab != null) ? ((Object)dropPrefab).name : null) == "RunescapeMagicWand"))
				{
					return;
				}
			}
			__result = $"<color=#ffd700>Бытовая магия</color>\n\n<color=#ffffff>ПКМ</color> — выбор заклинания\n<color=#ffffff>ЛКМ</color> — сотворение магии\n\nВес: {__instance.m_shared.m_weight:0.0}";
		}

		[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(bool),
			typeof(float),
			typeof(int),
			typeof(bool)
		})]
		[HarmonyPostfix]
		public static void OnStaticGetTooltipPostfix(ItemData item, ref string __result)
		{
			if (item == null || item.m_shared == null)
			{
				return;
			}
			if (!(item.m_shared.m_name == "Волшебная палочка"))
			{
				GameObject dropPrefab = item.m_dropPrefab;
				if (!(((dropPrefab != null) ? ((Object)dropPrefab).name : null) == "RunescapeMagicWand"))
				{
					return;
				}
			}
			__result = $"<color=#ffd700>Бытовая магия</color>\n\n<color=#ffffff>ПКМ</color> — выбор заклинания\n<color=#ffffff>ЛКМ</color> — сотворение магии\n\nВес: {item.m_shared.m_weight:0.0}";
		}
	}
	public enum SpellType
	{
		SpectralAxe,
		Splinter,
		OreBlast,
		AreaHarvest,
		InstantGrow,
		InventoryRepair,
		PieceRepair,
		Overdrive
	}
	[BepInPlugin("com.custom.runescapemagicvalheim", "Runescape Magic in Valheim", "1.0.6")]
	public class RunescapeMagicPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.custom.runescapemagicvalheim";

		public const string PluginName = "Runescape Magic in Valheim";

		public const string PluginVersion = "1.0.6";

		internal static ManualLogSource Log;

		internal static RunescapeMagicPlugin Instance;

		private readonly Harmony _harmony = new Harmony("com.custom.runescapemagicvalheim");

		public static SpellType CurrentSpell;

		public const string WandPrefabName = "RunescapeMagicWand";

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			try
			{
				_harmony.PatchAll(Assembly.GetExecutingAssembly());
				TryPatchSeedBedMod(_harmony);
				Log.LogInfo((object)"Runescape Magic in Valheim v1.0.6 успешно загружен!");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"[RunescapeMagic] Ошибка при инициализации Harmony: {arg}");
			}
		}

		private static void TryPatchSeedBedMod(Harmony harmony)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			try
			{
				Type type = AccessTools.TypeByName("SeedBed.Functions.Germination");
				if (!(type == null))
				{
					MethodInfo methodInfo = AccessTools.Method(type, "GetGerminationTime", (Type[])null, (Type[])null);
					if (methodInfo != null)
					{
						harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(SeedBedDynamicPatches), "GetGerminationTimePrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					}
					MethodInfo methodInfo2 = AccessTools.Method(type, "RPC_Tap", (Type[])null, (Type[])null);
					if (methodInfo2 != null)
					{
						harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(AccessTools.Method(typeof(SeedBedDynamicPatches), "RpcTapPrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					}
					MethodInfo methodInfo3 = AccessTools.Method(type, "RPC_AddItem", (Type[])null, (Type[])null);
					if (methodInfo3 != null)
					{
						harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(AccessTools.Method(typeof(SeedBedDynamicPatches), "RpcAddItemPrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					}
					Log.LogInfo((object)"[RunescapeMagic] Интеграция с модом SeedBed успешно подключена.");
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[RunescapeMagic] Не удалось подключить патч к SeedBed: " + ex.Message));
			}
		}

		private void OnDestroy()
		{
			_harmony.UnpatchSelf();
		}

		public static float GetEffectiveSkillLevel(Player player, SkillType skillType)
		{
			//IL_0015: 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)
			if ((Object)(object)player == (Object)null)
			{
				return 0f;
			}
			float level = ((Character)player).GetSkills().GetSkill(skillType).m_level;
			((Character)player).GetSEMan().ModifySkillLevel(skillType, ref level);
			return Mathf.Floor(level);
		}

		public static bool HasResources(Player player, float staminaCost, float healthCost = 0f)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if (staminaCost > 0f && !((Character)player).HaveStamina(staminaCost))
			{
				((Character)player).Message((MessageType)2, "$msg_notenoughstamina", 0, (Sprite)null, false);
				return false;
			}
			if (healthCost > 0f && ((Character)player).GetHealth() <= healthCost)
			{
				((Character)player).Message((MessageType)2, "Недостаточно здоровья для сотворения заклинания!", 0, (Sprite)null, false);
				return false;
			}
			return true;
		}

		public static bool TryConsumeResources(Player player, float staminaCost, float healthCost = 0f)
		{
			if (!HasResources(player, staminaCost, healthCost))
			{
				return false;
			}
			if (staminaCost > 0f)
			{
				((Character)player).UseStamina(staminaCost);
			}
			if (healthCost > 0f)
			{
				((Character)player).SetHealth(((Character)player).GetHealth() - healthCost);
			}
			return true;
		}
	}
	[HarmonyPatch]
	public static class WandInputPatches
	{
		private static float _lastCastTime;

		private const float CastCooldown = 0.65f;

		public static bool IsHoldingMagicWand(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			ItemData rightItem = ((Humanoid)player).GetRightItem();
			if (rightItem != null)
			{
				if ((Object)(object)rightItem.m_dropPrefab != (Object)null && ((Object)rightItem.m_dropPrefab).name == "RunescapeMagicWand")
				{
					return true;
				}
				if (rightItem.m_shared != null && rightItem.m_shared.m_name == "Волшебная палочка")
				{
					return true;
				}
			}
			ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon();
			if (currentWeapon != null)
			{
				if ((Object)(object)currentWeapon.m_dropPrefab != (Object)null && ((Object)currentWeapon.m_dropPrefab).name == "RunescapeMagicWand")
				{
					return true;
				}
				if (currentWeapon.m_shared != null && currentWeapon.m_shared.m_name == "Волшебная палочка")
				{
					return true;
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(Humanoid), "IsBlocking")]
		[HarmonyPrefix]
		public static bool OnIsBlockingPrefix(Humanoid __instance, ref bool __result)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && IsHoldingMagicWand((Player)__instance))
			{
				__result = false;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(Humanoid), "StartAttack")]
		[HarmonyPrefix]
		public static bool OnPrimaryAttackPrefix(Humanoid __instance, Character target, bool secondaryAttack, ref bool __result)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || secondaryAttack)
			{
				return true;
			}
			Player val = (Player)__instance;
			if (!IsHoldingMagicWand(val))
			{
				return true;
			}
			if (SpellRadialMenu.IsVisible)
			{
				__result = false;
				return false;
			}
			if (Time.time - _lastCastTime < 0.65f)
			{
				__result = false;
				return false;
			}
			_lastCastTime = Time.time;
			((Character)val).m_attack = false;
			((Character)val).m_attackHold = false;
			val.m_queuedAttackTimer = 0f;
			if ((Object)(object)((Character)val).m_zanim != (Object)null)
			{
				((Character)val).m_zanim.SetTrigger("swing_club");
			}
			CastSelectedSpell(val, RunescapeMagicPlugin.CurrentSpell);
			__result = true;
			return false;
		}

		[HarmonyPatch(typeof(Player), "Update")]
		[HarmonyPostfix]
		public static void OnPlayerUpdatePostfix(Player __instance)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if (!IsHoldingMagicWand(__instance) || !((Character)__instance).TakeInput())
			{
				if (SpellRadialMenu.IsVisible)
				{
					SpellRadialMenu.Instance.Hide(__instance);
				}
				return;
			}
			((Character)__instance).m_blocking = false;
			if (Input.GetMouseButtonDown(1))
			{
				SpellRadialMenu.Instance?.Show(__instance);
			}
			else if (Input.GetMouseButtonUp(1) && SpellRadialMenu.IsVisible)
			{
				SpellRadialMenu.Instance?.Hide(__instance);
			}
		}

		private static void CastSelectedSpell(Player player, SpellType spell)
		{
			switch (spell)
			{
			case SpellType.SpectralAxe:
				SpellMechanics.CastSpectralAxe(player);
				break;
			case SpellType.Splinter:
				SpellMechanics.CastSplinter(player);
				break;
			case SpellType.OreBlast:
				SpellMechanics.CastOreBlast(player);
				break;
			case SpellType.AreaHarvest:
				SpellMechanics.CastAreaHarvest(player);
				break;
			case SpellType.InstantGrow:
				SpellMechanics.CastInstantGrow(player);
				break;
			case SpellType.InventoryRepair:
				SpellMechanics.CastInventoryRepair(player);
				break;
			case SpellType.PieceRepair:
				SpellMechanics.CastPieceRepair(player);
				break;
			case SpellType.Overdrive:
				SpellMechanics.CastOverdrive(player);
				break;
			}
		}
	}
	public static class SpellMechanics
	{
		private class BlastChunk
		{
			public float Distance;

			public float XpGain;

			public Action DestroyAction;
		}

		public static readonly Dictionary<string, GameObject> StubToTreePrefab = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase);

		private static readonly MethodInfo _mr5UpdateMeshMethod = typeof(MineRock5).GetMethod("UpdateMesh", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		public const float MaxProjectileRange = 35f;

		public static void IndexTreeStubs(ZNetScene znet)
		{
			if ((Object)(object)znet == (Object)null || znet.m_prefabs == null)
			{
				return;
			}
			TreeBase val = default(TreeBase);
			foreach (GameObject prefab in znet.m_prefabs)
			{
				if (!((Object)(object)prefab == (Object)null) && prefab.TryGetComponent<TreeBase>(ref val) && (Object)(object)val.m_stubPrefab != (Object)null)
				{
					string key = ((Object)val.m_stubPrefab).name.ToLowerInvariant();
					if (!StubToTreePrefab.ContainsKey(key))
					{
						StubToTreePrefab[key] = prefab;
					}
				}
			}
		}

		public static GameObject ResolveTreePrefabForStub(string stubPrefabName, ZNetScene znet)
		{
			if (string.IsNullOrEmpty(stubPrefabName) || (Object)(object)znet == (Object)null)
			{
				return null;
			}
			string text = stubPrefabName.ToLowerInvariant();
			if (StubToTreePrefab.TryGetValue(text, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			try
			{
				Type type = Type.GetType("Advize_StumpsRegrow.StumpsRegrow, Advize_StumpsRegrow");
				if (type != null)
				{
					FieldInfo field = type.GetField("TreesPerStump", BindingFlags.Static | BindingFlags.Public);
					if (field != null && field.GetValue(null) is Dictionary<string, List<GameObject>> dictionary && dictionary.TryGetValue(stubPrefabName, out var value2) && value2 != null && value2.Count > 0)
					{
						return value2[Random.Range(0, value2.Count)];
					}
				}
			}
			catch
			{
			}
			if (text.Contains("beech"))
			{
				return znet.GetPrefab("Beech1") ?? znet.GetPrefab("Beech_sapling");
			}
			if (text.Contains("birch"))
			{
				return znet.GetPrefab("Birch1_aut") ?? znet.GetPrefab("Birch2_aut") ?? znet.GetPrefab("Birch1");
			}
			if (text.Contains("oak"))
			{
				return znet.GetPrefab("Oak1");
			}
			if (text.Contains("pine"))
			{
				return znet.GetPrefab("PineTree");
			}
			if (text.Contains("fir"))
			{
				return znet.GetPrefab("FirTree");
			}
			if (text.Contains("swamp"))
			{
				return znet.GetPrefab("SwampTree1");
			}
			if (text.Contains("yggdrasil"))
			{
				return znet.GetPrefab("YggdrasilTree1");
			}
			if (text.Contains("ash"))
			{
				return znet.GetPrefab("AshTree1");
			}
			return null;
		}

		public static string GetPickaxeTierName(int tier)
		{
			return tier switch
			{
				0 => "Оленья кирка (или любая другая)", 
				1 => "Бронзовая кирка или лучше", 
				2 => "Железная кирка или лучше", 
				3 => "Кирка из черного металла или лучше", 
				4 => "Пепловая кирка из огнеметалла", 
				_ => $"Кирка тира {tier} или выше", 
			};
		}

		public static string GetAxeTierName(int tier)
		{
			return tier switch
			{
				0 => "Каменный или кремниевый топор", 
				1 => "Бронзовый топор или лучше", 
				2 => "Железный топор или лучше", 
				3 => "Топор из черного металла или лучше", 
				4 => "Топор из огнеметалла / пепловый", 
				_ => $"Топор тира {tier} или выше", 
			};
		}

		public static bool HasPickaxe(Player player, int minToolTier, out string failReason)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Invalid comparison between Unknown and I4
			failReason = null;
			if ((Object)(object)player == (Object)null || ((Humanoid)player).GetInventory() == null)
			{
				failReason = "Инвентарь недоступен";
				return false;
			}
			int num = -1;
			string text = null;
			bool flag = false;
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if (allItem == null || allItem.m_shared == null || ((int)allItem.m_shared.m_skillType != 12 && !(allItem.m_shared.m_damages.m_pickaxe > 0f)))
				{
					continue;
				}
				if (allItem.m_shared.m_useDurability && allItem.m_durability <= 0f)
				{
					if (allItem.m_shared.m_toolTier >= minToolTier)
					{
						flag = true;
					}
				}
				else if (allItem.m_shared.m_toolTier > num)
				{
					num = allItem.m_shared.m_toolTier;
					text = ((Localization.instance != null) ? Localization.instance.Localize(allItem.m_shared.m_name) : allItem.m_shared.m_name);
				}
			}
			if (num == -1)
			{
				if (flag)
				{
					failReason = "Кирка в инвентаре сломана!";
				}
				else
				{
					failReason = "В инвентаре нет кирки!";
				}
				return false;
			}
			if (num < minToolTier)
			{
				failReason = "Требуется " + GetPickaxeTierName(minToolTier) + " (в инвентаре: " + text + ")";
				return false;
			}
			return true;
		}

		public static bool HasAxe(Player player, int minToolTier, out string failReason)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Invalid comparison between Unknown and I4
			failReason = null;
			if ((Object)(object)player == (Object)null || ((Humanoid)player).GetInventory() == null)
			{
				failReason = "Инвентарь недоступен";
				return false;
			}
			int num = -1;
			string text = null;
			bool flag = false;
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if (allItem == null || allItem.m_shared == null || ((int)allItem.m_shared.m_skillType != 7 && !(allItem.m_shared.m_damages.m_chop > 0f)) || !(allItem.m_shared.m_damages.m_pickaxe <= 0f))
				{
					continue;
				}
				if (allItem.m_shared.m_useDurability && allItem.m_durability <= 0f)
				{
					if (allItem.m_shared.m_toolTier >= minToolTier)
					{
						flag = true;
					}
				}
				else if (allItem.m_shared.m_toolTier > num)
				{
					num = allItem.m_shared.m_toolTier;
					text = ((Localization.instance != null) ? Localization.instance.Localize(allItem.m_shared.m_name) : allItem.m_shared.m_name);
				}
			}
			if (num == -1)
			{
				if (flag)
				{
					failReason = "Топор в инвентаре сломан!";
				}
				else
				{
					failReason = "В инвентаре нет топора!";
				}
				return false;
			}
			if (num < minToolTier)
			{
				failReason = "Требуется " + GetAxeTierName(minToolTier) + " (в инвентаре: " + text + ")";
				return false;
			}
			return true;
		}

		public static float GetMinAxeChopDamage(int toolTier)
		{
			return toolTier switch
			{
				0 => 20f, 
				1 => 40f, 
				2 => 50f, 
				3 => 60f, 
				_ => 70f, 
			};
		}

		public static float GetMinPickaxeDamage(int toolTier)
		{
			return toolTier switch
			{
				0 => 18f, 
				1 => 25f, 
				2 => 33f, 
				3 => 42f, 
				_ => 55f, 
			};
		}

		public static void CastSpectralAxe(Player player)
		{
			if (!HasAxe(player, 0, out var failReason))
			{
				((Character)player).Message((MessageType)2, failReason, 0, (Sprite)null, false);
				return;
			}
			float effectiveSkillLevel = RunescapeMagicPlugin.GetEffectiveSkillLevel(player, (SkillType)13);
			if (effectiveSkillLevel < 10f)
			{
				((Character)player).Message((MessageType)2, $"Требуется 10 ур. Рубки леса (текущий: {effectiveSkillLevel})", 0, (Sprite)null, false);
				return;
			}
			float staminaCost = ((effectiveSkillLevel >= 75f) ? 5f : ((effectiveSkillLevel >= 35f) ? 15f : 25f));
			float radius = ((effectiveSkillLevel >= 55f) ? 10f : 5f);
			if (RunescapeMagicPlugin.HasResources(player, staminaCost))
			{
				((MonoBehaviour)RunescapeMagicPlugin.Instance).StartCoroutine(SpectralAxeProjectileRoutine(player, radius, staminaCost));
			}
		}

		private static IEnumerator SpectralAxeProjectileRoutine(Player player, float radius, float staminaCost)
		{
			Transform val = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform : ((Component)player).transform);
			Vector3 currentPos = ((Character)player).GetEyePoint() + val.forward * 1.2f;
			Vector3 direction = val.forward;
			direction.y = 0f;
			if (((Vector3)(ref direction)).sqrMagnitude < 0.01f)
			{
				direction = ((Component)player).transform.forward;
			}
			((Vector3)(ref direction)).Normalize();
			float num = default(float);
			if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(currentPos, ref num))
			{
				currentPos.y = num + 1.4f;
			}
			float speed = 12f;
			float maxDistance = 15f;
			float traveled = 0f;
			HashSet<TreeBase> hitTrees = new HashSet<TreeBase>();
			bool resourcesConsumed = false;
			GameObject visualAxe = CreateSpectralAxeVisual(currentPos);
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab("sfx_axe_swing");
				if ((Object)(object)prefab != (Object)null)
				{
					Object.Instantiate<GameObject>(prefab, currentPos, Quaternion.identity);
				}
			}
			float num3 = default(float);
			while (traveled < maxDistance)
			{
				float num2 = speed * Time.deltaTime;
				currentPos += direction * num2;
				traveled += num2;
				if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(currentPos, ref num3))
				{
					currentPos.y = Mathf.Lerp(currentPos.y, num3 + 1.4f, Time.deltaTime * 10f);
				}
				if ((Object)(object)visualAxe != (Object)null)
				{
					visualAxe.transform.position = currentPos;
					visualAxe.transform.Rotate(Vector3.up, 900f * Time.deltaTime, (Space)0);
				}
				Collider[] array = Physics.OverlapSphere(currentPos, radius);
				foreach (Collider val2 in array)
				{
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					TreeBase componentInParent = ((Component)val2).GetComponentInParent<TreeBase>();
					if ((Object)(object)componentInParent != (Object)null && !hitTrees.Contains(componentInParent) && HasAxe(player, componentInParent.m_minToolTier, out var _))
					{
						if (!resourcesConsumed)
						{
							resourcesConsumed = true;
							RunescapeMagicPlugin.TryConsumeResources(player, staminaCost);
						}
						hitTrees.Add(componentInParent);
						HitData val3 = new HitData();
						val3.m_damage.m_chop = 999f;
						Bounds bounds = val2.bounds;
						val3.m_point = ((Bounds)(ref bounds)).center;
						val3.m_toolTier = 10;
						val3.SetAttacker((Character)(object)player);
						float num4 = Mathf.Max(1f, componentInParent.m_health / GetMinAxeChopDamage(componentInParent.m_minToolTier));
						componentInParent.Damage(val3);
						((Character)player).RaiseSkill((SkillType)13, num4);
					}
				}
				yield return null;
			}
			if ((Object)(object)visualAxe != (Object)null)
			{
				Object.Destroy((Object)(object)visualAxe);
			}
			if (hitTrees.Count == 0 && (Object)(object)player != (Object)null)
			{
				((Character)player).Message((MessageType)2, "Призрачный топор не поразил ни одного дерева!", 0, (Sprite)null, false);
			}
		}

		private static GameObject CreateSpectralAxeVisual(Vector3 startPos)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0011: 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_086c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Expected O, but got Unknown
			//IL_0611: Unknown result type (might be due to invalid IL or missing references)
			//IL_0634: Unknown result type (might be due to invalid IL or missing references)
			//IL_0657: Unknown result type (might be due to invalid IL or missing references)
			//IL_0667: Unknown result type (might be due to invalid IL or missing references)
			//IL_0677: Unknown result type (might be due to invalid IL or missing references)
			//IL_067e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0787: Unknown result type (might be due to invalid IL or missing references)
			//IL_078c: Unknown result type (might be due to invalid IL or missing references)
			//IL_079e: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_082c: Unknown result type (might be due to invalid IL or missing references)
			//IL_084c: Unknown result type (might be due to invalid IL or missing references)
			//IL_080c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0816: Expected O, but got Unknown
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_070d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0714: Expected O, but got Unknown
			//IL_0716: Unknown result type (might be due to invalid IL or missing references)
			//IL_073f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0749: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_0513: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_0526: Unknown result type (might be due to invalid IL or missing references)
			//IL_052f: Unknown result type (might be due to invalid IL or missing references)
			//IL_053d: Unknown result type (might be due to invalid IL or missing references)
			//IL_053f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0543: Unknown result type (might be due to invalid IL or missing references)
			//IL_0548: Unknown result type (might be due to invalid IL or missing references)
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_0580: Unknown result type (might be due to invalid IL or missing references)
			//IL_0590: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05da: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("SpectralAxeProjectile");
			val.transform.position = startPos;
			val.transform.rotation = Quaternion.identity;
			GameObject val2 = (((Object)(object)ObjectDB.instance != (Object)null) ? (ObjectDB.instance.GetItemPrefab("BattleaxeCrystal") ?? ObjectDB.instance.GetItemPrefab("AxeBronze")) : null);
			if ((Object)(object)val2 != (Object)null)
			{
				Transform val3 = val2.transform.Find("attach");
				GameObject val4 = Object.Instantiate<GameObject>(((Object)(object)val3 != (Object)null) ? ((Component)val3).gameObject : val2);
				val4.SetActive(true);
				Collider[] componentsInChildren = val4.GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
				}
				Rigidbody val5 = default(Rigidbody);
				if (val4.TryGetComponent<Rigidbody>(ref val5))
				{
					Object.DestroyImmediate((Object)(object)val5);
				}
				ItemDrop val6 = default(ItemDrop);
				if (val4.TryGetComponent<ItemDrop>(ref val6))
				{
					Object.DestroyImmediate((Object)(object)val6);
				}
				ZNetView val7 = default(ZNetView);
				if (val4.TryGetComponent<ZNetView>(ref val7))
				{
					Object.DestroyImmediate((Object)(object)val7);
				}
				List<Vector3> list = new List<Vector3>();
				MeshFilter[] componentsInChildren2 = val4.GetComponentsInChildren<MeshFilter>(true);
				foreach (MeshFilter val8 in componentsInChildren2)
				{
					if ((Object)(object)val8 != (Object)null && (Object)(object)val8.sharedMesh != (Object)null)
					{
						Vector3[] vertices = val8.sharedMesh.vertices;
						Transform transform = ((Component)val8).transform;
						for (int j = 0; j < vertices.Length; j++)
						{
							Vector3 val9 = transform.TransformPoint(vertices[j]);
							Vector3 item = val4.transform.InverseTransformPoint(val9);
							list.Add(item);
						}
					}
				}
				SkinnedMeshRenderer[] componentsInChildren3 = val4.GetComponentsInChildren<SkinnedMeshRenderer>(true);
				foreach (SkinnedMeshRenderer val10 in componentsInChildren3)
				{
					if ((Object)(object)val10 != (Object)null && (Object)(object)val10.sharedMesh != (Object)null)
					{
						Vector3[] vertices2 = val10.sharedMesh.vertices;
						Transform transform2 = ((Component)val10).transform;
						for (int k = 0; k < vertices2.Length; k++)
						{
							Vector3 val11 = transform2.TransformPoint(vertices2[k]);
							Vector3 item2 = val4.transform.InverseTransformPoint(val11);
							list.Add(item2);
						}
					}
				}
				GameObject val12 = new GameObject("ModelHolder");
				val12.transform.SetParent(val.transform, false);
				float num = 2.5f;
				Vector3 localPosition = default(Vector3);
				((Vector3)(ref localPosition))..ctor(0.5f, 0f, 0f);
				if (list.Count > 0)
				{
					Vector3 val13 = default(Vector3);
					((Vector3)(ref val13))..ctor(float.MaxValue, float.MaxValue, float.MaxValue);
					Vector3 val14 = default(Vector3);
					((Vector3)(ref val14))..ctor(float.MinValue, float.MinValue, float.MinValue);
					for (int l = 0; l < list.Count; l++)
					{
						val13 = Vector3.Min(val13, list[l]);
						val14 = Vector3.Max(val14, list[l]);
					}
					Vector3 val15 = val14 - val13;
					int num2 = 0;
					if (val15.y > val15.x && val15.y >= val15.z)
					{
						num2 = 1;
					}
					else if (val15.z > val15.x && val15.z > val15.y)
					{
						num2 = 2;
					}
					int num3 = 0;
					if (val15.y < val15.x && val15.y <= val15.z)
					{
						num3 = 1;
					}
					else if (val15.z < val15.x && val15.z < val15.y)
					{
						num3 = 2;
					}
					int num4 = 3 - num2 - num3;
					float num5 = (((Vector3)(ref val13))[num2] + ((Vector3)(ref val14))[num2]) * 0.5f;
					float num6 = (((Vector3)(ref val13))[num3] + ((Vector3)(ref val14))[num3]) * 0.5f;
					float num7 = ((Vector3)(ref val13))[num2] + ((Vector3)(ref val15))[num2] * 0.45f;
					float num8 = 0f;
					int num9 = 0;
					for (int m = 0; m < list.Count; m++)
					{
						Vector3 val16 = list[m];
						if (num2 switch
						{
							1 => val16.y, 
							0 => val16.x, 
							_ => val16.z, 
						} <= num7)
						{
							num8 += num4 switch
							{
								1 => val16.y, 
								0 => val16.x, 
								_ => val16.z, 
							};
							num9++;
						}
					}
					num8 = ((num9 <= 0) ? ((((Vector3)(ref val13))[num4] + ((Vector3)(ref val14))[num4]) * 0.5f) : (num8 / (float)num9));
					Vector3 zero = Vector3.zero;
					switch (num2)
					{
					case 0:
						zero.x = num5;
						break;
					case 1:
						zero.y = num5;
						break;
					default:
						zero.z = num5;
						break;
					}
					switch (num3)
					{
					case 0:
						zero.x = num6;
						break;
					case 1:
						zero.y = num6;
						break;
					default:
						zero.z = num6;
						break;
					}
					switch (num4)
					{
					case 0:
						zero.x = num8;
						break;
					case 1:
						zero.y = num8;
						break;
					default:
						zero.z = num8;
						break;
					}
					Vector3 zero2 = Vector3.zero;
					Quaternion val17 = Quaternion.FromToRotation((Vector3)(num3 switch
					{
						0 => Vector3.right, 
						1 => Vector3.up, 
						_ => Vector3.forward, 
					}), Vector3.up);
					val12.transform.localRotation = val17;
					val12.transform.localPosition = -(val17 * (zero * num));
					val4.transform.SetParent(val12.transform, false);
					val4.transform.localPosition = Vector3.zero;
					val4.transform.localRotation = Quaternion.identity;
					val4.transform.localScale = Vector3.one * num;
					float num10 = 0f;
					Vector3 val18 = zero;
					for (int n = 0; n < list.Count; n++)
					{
						Vector3 val19 = list[n] - zero;
						float sqrMagnitude = ((Vector3)(ref val19)).sqrMagnitude;
						if (sqrMagnitude > num10)
						{
							num10 = sqrMagnitude;
							val18 = list[n];
						}
					}
					localPosition = val18;
				}
				else
				{
					val12.transform.localRotation = Quaternion.Euler(0f, 0f, 90f);
					val12.transform.localPosition = new Vector3(0f, 0f, -0.4f * num);
					val4.transform.SetParent(val12.transform, false);
					val4.transform.localPosition = Vector3.zero;
					val4.transform.localRotation = Quaternion.identity;
					val4.transform.localScale = Vector3.one * num;
				}
				Shader val20 = Shader.Find("Legacy Shaders/Transparent/Specular") ?? Shader.Find("Standard") ?? Shader.Find("Custom/Lit");
				Color color = default(Color);
				((Color)(ref color))..ctor(0.2f, 1f, 0.85f, 0.65f);
				MeshRenderer[] componentsInChildren4 = val4.GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val21 in componentsInChildren4)
				{
					Material[] array = (Material[])(object)new Material[((Renderer)val21).materials.Length];
					for (int num11 = 0; num11 < array.Length; num11++)
					{
						Material val22 = new Material(val20 ?? ((Renderer)val21).materials[num11].shader);
						val22.color = color;
						val22.EnableKeyword("_EMISSION");
						val22.SetColor("_EmissionColor", new Color(0.15f, 0.85f, 0.7f) * 2.2f);
						array[num11] = val22;
					}
					((Renderer)val21).materials = array;
				}
				GameObject val23 = new GameObject("BladeTrail");
				val23.transform.SetParent(val4.transform, false);
				val23.transform.localPosition = localPosition;
				TrailRenderer val24 = val23.AddComponent<TrailRenderer>();
				val24.time = 0.25f;
				val24.startWidth = 0.4f;
				val24.endWidth = 0f;
				Shader val25 = Shader.Find("Sprites/Default") ?? Shader.Find("Particles/Standard Unlit") ?? Shader.Find("Legacy Shaders/Particles/Alpha Blended Premultiply");
				if ((Object)(object)val25 != (Object)null)
				{
					((Renderer)val24).material = new Material(val25);
				}
				val24.startColor = new Color(0.2f, 1f, 0.85f, 0.8f);
				val24.endColor = new Color(0.1f, 0.5f, 1f, 0f);
			}
			Light obj = val.AddComponent<Light>();
			obj.color = new Color(0.2f, 1f, 0.85f);
			obj.range = 7f;
			obj.intensity = 2.2f;
			obj.shadows = (LightShadows)0;
			return val;
		}

		public static void CastSplinter(Player player)
		{
			if (!HasAxe(player, 0, out var failReason))
			{
				((Character)player).Message((MessageType)2, failReason, 0, (Sprite)null, false);
				return;
			}
			float effectiveSkillLevel = RunescapeMagicPlugin.GetEffectiveSkillLevel(player, (SkillType)13);
			if (effectiveSkillLevel < 25f)
			{
				((Character)player).Message((MessageType)2, $"Требуется 25 ур. Рубки леса (текущий: {effectiveSkillLevel})", 0, (Sprite)null, false);
				return;
			}
			float radius = ((effectiveSkillLevel >= 90f) ? 25f : ((effectiveSkillLevel >= 35f) ? 15f : 10f));
			float staminaCost = ((effectiveSkillLevel >= 75f) ? 15f : 25f);
			float healthCost = ((effectiveSkillLevel >= 55f) ? 0f : 10f);
			if (RunescapeMagicPlugin.HasResources(player, staminaCost, healthCost))
			{
				LaunchMagicProjectile(player, 35f, delegate(Vector3 impactPoint, Collider hitCol)
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					((MonoBehaviour)RunescapeMagicPlugin.Instance).StartCoroutine(SplinterRoutine(player, impactPoint, radius, staminaCost, healthCost));
				});
			}
		}

		private static IEnumerator SplinterRoutine(Player player, Vector3 center, float radius, float staminaCost, float healthCost)
		{
			//IL_000e: 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)
			bool resourcesConsumed = false;
			int logsHit = DamageLogsInRadius(player, center, radius, staminaCost, healthCost, ref resourcesConsumed);
			yield return (object)new WaitForSeconds(1f);
			DamageLogsInRadius(player, center, radius + 2f, staminaCost, healthCost, ref resourcesConsumed);
			if (logsHit == 0 && !resourcesConsumed && (Object)(object)player != (Object)null)
			{
				((Character)player).Message((MessageType)2, "В выбранной зоне нет упавших бревен!", 0, (Sprite)null, false);
			}
		}

		private static int DamageLogsInRadius(Player player, Vector3 center, float radius, float staminaCost, float healthCost, ref bool resourcesConsumed)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(center, radius);
			HashSet<TreeLog> hashSet = new HashSet<TreeLog>();
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				TreeLog componentInParent = ((Component)val).GetComponentInParent<TreeLog>();
				if ((Object)(object)componentInParent != (Object)null && !hashSet.Contains(componentInParent) && HasAxe(player, componentInParent.m_minToolTier, out var _))
				{
					if (!resourcesConsumed)
					{
						resourcesConsumed = true;
						RunescapeMagicPlugin.TryConsumeResources(player, staminaCost, healthCost);
					}
					hashSet.Add(componentInParent);
					HitData val2 = new HitData();
					val2.m_damage.m_chop = 999f;
					Bounds bounds = val.bounds;
					val2.m_point = ((Bounds)(ref bounds)).center;
					val2.m_toolTier = 10;
					val2.SetAttacker((Character)(object)player);
					float num = Mathf.Max(1f, componentInParent.m_health / GetMinAxeChopDamage(componentInParent.m_minToolTier));
					componentInParent.Damage(val2);
					((Character)player).RaiseSkill((SkillType)13, num);
				}
			}
			return hashSet.Count;
		}

		public static void ForceUpdateMineRock5(MineRock5 mineRock5)
		{
			if ((Object)(object)mineRock5 == (Object)null)
			{
				return;
			}
			try
			{
				_mr5UpdateMeshMethod?.Invoke(mineRock5, null);
			}
			catch (Exception arg)
			{
				RunescapeMagicPlugin.Log.LogWarning((object)$"[MineRock5] Ошибка принудительного обновления меша: {arg}");
			}
		}

		private static void SpawnExplosionEffect(Vector3 center, float radius)
		{
			//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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject val = new GameObject("OreBlastFlash");
				val.transform.position = center;
				Light obj = val.AddComponent<Light>();
				obj.color = new Color(1f, 0.65f, 0.2f);
				obj.intensity = 4.5f;
				obj.range = Mathf.Max(radius * 1.5f, 8f);
				Object.Destroy((Object)val, 0.35f);
				if ((Object)(object)ZNetScene.instance != (Object)null)
				{
					GameObject val2 = ZNetScene.instance.GetPrefab("vfx_rock_destroyed") ?? ZNetScene.instance.GetPrefab("vfx_stone_destroyed");
					if ((Object)(object)val2 != (Object)null)
					{
						Object.Instantiate<GameObject>(val2, center, Quaternion.identity);
					}
					GameObject val3 = ZNetScene.instance.GetPrefab("sfx_rock_destroyed") ?? ZNetScene.instance.GetPrefab("sfx_stone_destroyed");
					if ((Object)(object)val3 != (Object)null)
					{
						Object.Instantiate<GameObject>(val3, center, Quaternion.identity);
					}
				}
			}
			catch
			{
			}
		}

		public static void CastOreBlast(Player player)
		{
			if (!HasPickaxe(player, 0, out var failReason))
			{
				((Character)player).Message((MessageType)2, failReason, 0, (Sprite)null, false);
				return;
			}
			float level = RunescapeMagicPlugin.GetEffectiveSkillLevel(player, (SkillType)12);
			float radius = ((level >= 75f) ? 6f : ((level >= 35f) ? 4f : 2f));
			float staminaCost = ((level >= 55f) ? 10f : 25f);
			if (RunescapeMagicPlugin.HasResources(player, staminaCost))
			{
				LaunchMagicProjectile(player, 35f, delegate(Vector3 impactPoint, Collider hitCol)
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					((MonoBehaviour)RunescapeMagicPlugin.Instance).StartCoroutine(OreBlastWaveRoutine(player, impactPoint, radius, level, hitCol, staminaCost));
				});
			}
		}

		private static bool IsVegetation(IDestructible destructible, GameObject rootObj, string prefabName)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			if (destructible != null && (int)destructible.GetDestructibleType() == 2)
			{
				return true;
			}
			if (string.IsNullOrEmpty(prefabName))
			{
				return false;
			}
			if (!prefabName.Contains("bush") && !prefabName.Contains("shrub") && !prefabName.Contains("berry") && !prefabName.Contains("flower") && !prefabName.Contains("grass") && !prefabName.Contains("plant") && !prefabName.Contains("stub") && !prefabName.Contains("branch") && !prefabName.Contains("tree") && !prefabName.Contains("vine") && !prefabName.Contains("reed") && !prefabName.Contains("carrot") && !prefabName.Contains("turnip") && !prefabName.Contains("onion") && !prefabName.Contains("barley") && !prefabName.Contains("flax") && !prefabName.Contains("dandelion") && !prefabName.Contains("mushroom") && !prefabName.Contains("cloudberry") && !prefabName.Contains("blueberry") && !prefabName.Contains("raspberry") && !prefabName.Contains("sapling"))
			{
				return prefabName.Contains("vines");
			}
			return true;
		}

		private static IEnumerator OreBlastWaveRoutine(Player player, Vector3 center, float radius, float skillLevel, Collider directHitCol, float staminaCost)
		{
			//IL_000e: 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)
			List<Collider> list = new List<Collider>(Physics.OverlapSphere(center, radius));
			if ((Object)(object)directHitCol != (Object)null && !list.Contains(directHitCol))
			{
				list.Add(directHitCol);
			}
			List<BlastChunk> list2 = new List<BlastChunk>();
			HashSet<Destructible> hashSet = new HashSet<Destructible>();
			HashSet<MineRock5> processedMineRock5 = new HashSet<MineRock5>();
			HashSet<MineRock> hashSet2 = new HashSet<MineRock>();
			int rocksCount = 0;
			foreach (Collider col in list)
			{
				if ((Object)(object)col == (Object)null || (Object)(object)((Component)col).GetComponentInParent<Character>() != (Object)null || (Object)(object)((Component)col).GetComponentInParent<BaseAI>() != (Object)null || (Object)(object)((Component)col).GetComponentInParent<MonsterAI>() != (Object)null || (Object)(object)((Component)col).GetComponentInParent<AnimalAI>() != (Object)null || (Object)(object)((Component)col).GetComponentInParent<Tameable>() != (Object)null)
				{
					continue;
				}
				IDestructible componentInParent = ((Component)col).GetComponentInParent<IDestructible>();
				if (componentInParent == null || componentInParent is Character)
				{
					continue;
				}
				try
				{
					if ((int)componentInParent.GetDestructibleType() == 4)
					{
						continue;
					}
				}
				catch
				{
				}
				GameObject gameObject = ((Component)(MonoBehaviour)componentInParent).gameObject;
				string prefabName = Utils.GetPrefabName(gameObject).ToLowerInvariant();
				if (IsVegetation(componentInParent, gameObject, prefabName))
				{
					continue;
				}
				if (!CanMineOre(prefabName, skillLevel, player, componentInParent, out var reason))
				{
					if ((Object)(object)col == (Object)(object)directHitCol && !string.IsNullOrEmpty(reason))
					{
						((Character)player).Message((MessageType)2, reason, 0, (Sprite)null, false);
					}
					continue;
				}
				MineRock5 mineRock5 = (MineRock5)(object)((componentInParent is MineRock5) ? componentInParent : null);
				Bounds bounds;
				if (mineRock5 != null)
				{
					if (processedMineRock5.Contains(mineRock5))
					{
						continue;
					}
					processedMineRock5.Add(mineRock5);
					rocksCount++;
					if (mineRock5.m_hitAreas == null)
					{
						continue;
					}
					for (int i = 0; i < mineRock5.m_hitAreas.Count; i++)
					{
						HitArea area = mineRock5.GetHitArea(i);
						if (area == null || area.m_health <= 0f)
						{
							continue;
						}
						Collider chunkCol = area.m_collider;
						Vector3 val;
						if (!((Object)(object)chunkCol != (Object)null))
						{
							val = ((Component)mineRock5).transform.position + area.m_bound.m_pos;
						}
						else
						{
							bounds = chunkCol.bounds;
							val = ((Bounds)(ref bounds)).center;
						}
						Vector3 val2 = val;
						float num = Vector3.Distance(center, val2);
						if (!(num <= radius + 0.8f) && (!((Object)(object)chunkCol != (Object)null) || (!((Object)(object)chunkCol == (Object)(object)directHitCol) && !list.Contains(chunkCol))))
						{
							continue;
						}
						int chunkIndex = i;
						Vector3 hitPos = val2;
						float num2 = ((mineRock5.m_health > 0f) ? mineRock5.m_health : 50f);
						float xpGain = Mathf.Max(1f, num2 / GetMinPickaxeDamage(mineRock5.m_minToolTier));
						list2.Add(new BlastChunk
						{
							Distance = num,
							XpGain = xpGain,
							DestroyAction = delegate
							{
								//IL_0046: Unknown result type (might be due to invalid IL or missing references)
								//IL_0130: Unknown result type (might be due to invalid IL or missing references)
								//IL_0135: Unknown result type (might be due to invalid IL or missing references)
								//IL_0143: Unknown result type (might be due to invalid IL or missing references)
								//IL_0149: Unknown result type (might be due to invalid IL or missing references)
								//IL_018a: Unknown result type (might be due to invalid IL or missing references)
								//IL_018f: Unknown result type (might be due to invalid IL or missing references)
								//IL_0199: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
								//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
								//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
								//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
								//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
								if (!((Object)(object)mineRock5 == (Object)null) && !mineRock5.m_allDestroyed && !(area.m_health <= 0f))
								{
									DamageText instance = DamageText.instance;
									if (instance != null)
									{
										instance.ShowText((DamageModifier)0, hitPos, 9999f, false);
									}
									area.m_health = 0f;
									if ((Object)(object)mineRock5.m_nview != (Object)null && mineRock5.m_nview.IsValid())
									{
										mineRock5.m_nview.ClaimOwnership();
										mineRock5.SaveHealth();
										mineRock5.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SetAreaHealth", new object[2] { chunkIndex, 0f });
									}
									if ((Object)(object)chunkCol != (Object)null)
									{
										((Component)chunkCol).gameObject.SetActive(false);
									}
									EffectList destroyedEffect = mineRock5.m_destroyedEffect;
									if (destroyedEffect != null)
									{
										destroyedEffect.Create(hitPos, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
									}
									if (mineRock5.m_dropItems != null)
									{
										foreach (GameObject drop in mineRock5.m_dropItems.GetDropList())
										{
											Vector3 val3 = hitPos + Vector3.up * 0.2f + Random.insideUnitSphere * 0.3f;
											GameObject obj2 = Object.Instantiate<GameObject>(drop, val3, Quaternion.identity);
											ItemDrop val4 = ((obj2 != null) ? obj2.GetComponent<ItemDrop>() : null);
											if ((Object)(object)val4 != (Object)null)
											{
												ItemDrop.OnCreateNew(((Component)val4).gameObject, false);
											}
										}
									}
									mineRock5.UpdateMesh();
									if (mineRock5.m_supportCheck)
									{
										mineRock5.CheckSupport();
									}
									if (mineRock5.AllDestroyed())
									{
										mineRock5.m_allDestroyed = true;
										if ((Object)(object)mineRock5.m_nview != (Object)null && mineRock5.m_nview.IsValid())
										{
											mineRock5.m_nview.Destroy();
										}
										else
										{
											Object.Destroy((Object)(object)((Component)mineRock5).gameObject);
										}
									}
								}
							}
						});
					}
					continue;
				}
				MineRock mineRock6 = (MineRock)(object)((componentInParent is MineRock) ? componentInParent : null);
				if (mineRock6 != null)
				{
					if (hashSet2.Contains(mineRock6))
					{
						continue;
					}
					hashSet2.Add(mineRock6);
					rocksCount++;
					if (mineRock6.m_hitAreas == null)
					{
						continue;
					}
					for (int num3 = 0; num3 < mineRock6.m_hitAreas.Length; num3++)
					{
						Collider areaCol = mineRock6.m_hitAreas[num3];
						if ((Object)(object)areaCol == (Object)null)
						{
							continue;
						}
						bounds = areaCol.bounds;
						Vector3 center2 = ((Bounds)(ref bounds)).center;
						float num4 = Vector3.Distance(center, center2);
						if (!(num4 <= radius + 0.8f) && !((Object)(object)areaCol == (Object)(object)directHitCol) && !list.Contains(areaCol))
						{
							continue;
						}
						int chunkIdx = num3;
						Vector3 hitPos2 = center2;
						float num5 = ((mineRock6.m_health > 0f) ? mineRock6.m_health : 50f);
						float xpGain2 = Mathf.Max(1f, num5 / GetMinPickaxeDamage(mineRock6.m_minToolTier));
						list2.Add(new BlastChunk
						{
							Distance = num4,
							XpGain = xpGain2,
							DestroyAction = delegate
							{
								//IL_0021: Unknown result type (might be due to invalid IL or missing references)
								//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
								//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
								//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
								//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
								//IL_0226: Unknown result type (might be due to invalid IL or missing references)
								//IL_022b: Unknown result type (might be due to invalid IL or missing references)
								//IL_0235: Unknown result type (might be due to invalid IL or missing references)
								//IL_023a: Unknown result type (might be due to invalid IL or missing references)
								//IL_023f: Unknown result type (might be due to invalid IL or missing references)
								//IL_0249: 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)
								//IL_0253: Unknown result type (might be due to invalid IL or missing references)
								//IL_0255: Unknown result type (might be due to invalid IL or missing references)
								//IL_0257: Unknown result type (might be due to invalid IL or missing references)
								if (!((Object)(object)mineRock6 == (Object)null))
								{
									DamageText instance = DamageText.instance;
									if (instance != null)
									{
										instance.ShowText((DamageModifier)0, hitPos2, 9999f, false);
									}
									if ((Object)(object)mineRock6.m_nview != (Object)null && mineRock6.m_nview.IsValid())
									{
										mineRock6.m_nview.ClaimOwnership();
										ZDO zDO = mineRock6.m_nview.GetZDO();
										if (zDO != null)
										{
											zDO.Set("Health" + chunkIdx, 0f);
										}
										mineRock6.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_Hide", new object[1] { chunkIdx });
									}
									if ((Object)(object)areaCol != (Object)null)
									{
										((Component)areaCol).gameObject.SetActive(false);
									}
									if ((Object)(object)mineRock6.m_baseModel != (Object)null && mineRock6.m_baseModel.activeSelf)
									{
										mineRock6.m_baseModel.SetActive(false);
										if (mineRock6.m_areaMeshes != null)
										{
											MeshRenderer[][] areaMeshes = mineRock6.m_areaMeshes;
											foreach (MeshRenderer[] array in areaMeshes)
											{
												if (array != null)
												{
													MeshRenderer[] array2 = array;
													foreach (MeshRenderer val3 in array2)
													{
														if ((Object)(object)val3 != (Object)null)
														{
															((Renderer)val3).enabled = true;
														}
													}
												}
											}
										}
									}
									EffectList destroyedEffect = mineRock6.m_destroyedEffect;
									if (destroyedEffect != null)
									{
										destroyedEffect.Create(hitPos2, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
									}
									if (mineRock6.m_dropItems != null)
									{
										foreach (GameObject drop2 in mineRock6.m_dropItems.GetDropList())
										{
											Vector3 val4 = hitPos2 + Vector3.up * 0.2f + Random.insideUnitSphere * 0.3f;
											GameObject obj2 = Object.Instantiate<GameObject>(drop2, val4, Quaternion.identity);
											ItemDrop val5 = ((obj2 != null) ? obj2.GetComponent<ItemDrop>() : null);
											if ((Object)(object)val5 != (Object)null)
											{
												ItemDrop.OnCreateNew(((Component)val5).gameObject, false);
											}
										}
									}
									if (mineRock6.m_removeWhenDestroyed && mineRock6.AllDestroyed())
									{
										if ((Object)(object)mineRock6.m_nview != (Object)null && mineRock6.m_nview.IsValid())
										{
											mineRock6.m_nview.Destroy();
										}
										else
										{
											Object.Destroy((Object)(object)((Component)mineRock6).gameObject);
										}
									}
								}
							}
						});
					}
					continue;
				}
				Destructible dest = (Destructible)(object)((componentInParent is Destructible) ? componentInParent : null);
				if (dest == null || hashSet.Contains(dest) || (int)dest.m_damages.m_pickaxe == 4 || (int)dest.m_damages.m_pickaxe == 3)
				{
					continue;
				}
				hashSet.Add(dest);
				rocksCount++;
				bounds = col.bounds;
				float distance = Vector3.Distance(center, ((Bounds)(ref bounds)).center);
				float num6 = ((dest.m_health > 0f) ? dest.m_health : 40f);
				float xpGain3 = Mathf.Max(1f, num6 / GetMinPickaxeDamage(dest.m_minToolTier));
				list2.Add(new BlastChunk
				{
					Distance = distance,
					XpGain = xpGain3,
					DestroyAction = delegate
					{
						//IL_0044: Unknown result type (might be due to invalid IL or missing references)
						//IL_004a: Expected O, but got Unknown
						//IL_006b: Unknown result type (might be due to invalid IL or missing references)
						//IL_0070: Unknown result type (might be due to invalid IL or missing references)
						//IL_0073: Unknown result type (might be due to invalid IL or missing references)
						//IL_0078: Unknown result type (might be due to invalid IL or missing references)
						if (!((Object)(object)dest == (Object)null))
						{
							if ((Object)(object)dest.m_nview != (Object)null && dest.m_nview.IsValid())
							{
								dest.m_nview.ClaimOwnership();
							}
							HitData val3 = new HitData();
							val3.m_damage.m_pickaxe = 9999f;
							Bounds bounds2 = col.bounds;
							val3.m_point = ((Bounds)(ref bounds2)).center;
							val3.m_hitCollider = col;
							val3.m_toolTier = 10;
							val3.SetAttacker((Character)(object)player);
							dest.Damage(val3);
						}
					}
				});
			}
			if (list2.Count == 0)
			{
				if ((Object)(object)player != (Object)null)
				{
					((Character)player).Message((MessageType)2, "В этой зоне нет доступной породы или руды!", 0, (Sprite)null, false);
				}
			}
			else
			{
				if (!RunescapeMagicPlugin.TryConsumeResources(player, staminaCost))
				{
					yield break;
				}
				SpawnExplosionEffect(center, radius);
				list2.Sort((BlastChunk a, BlastChunk b) => a.Distance.CompareTo(b.Distance));
				float totalMiningXp = 0f;
				int countInBatch = 0;
				foreach (BlastChunk item in list2)
				{
					item.DestroyAction?.Invoke();
					totalMiningXp += item.XpGain;
					countInBatch++;
					if (countInBatch >= 4)
					{
						countInBatch = 0;
						yield return (object)new WaitForSeconds(0.02f);
					}
				}
				foreach (MineRock5 item2 in processedMineRock5)
				{
					if ((Object)(object)item2 != (Object)null && !item2.m_allDestroyed)
					{
						item2.UpdateMesh();
						if (item2.m_supportCheck)
						{
							item2.CheckSupport();
						}
					}
				}
				if (rocksCount > 0 && totalMiningXp > 0f)
				{
					((Character)player).RaiseSkill((SkillType)12, totalMiningXp);
					((Character)player).Message((MessageType)2, $"Разрушено залежей/камней: {rocksCount}", 0, (Sprite)null, false);
				}
			}
		}

		private static bool CanMineOre(string prefabName, float level, Player player, IDestructible destructible, out string reason)
		{
			reason = null;
			int num = 0;
			MineRock5 val = (MineRock5)(object)((destructible is MineRock5) ? destructible : null);
			if (val != null)
			{
				num = Mathf.Max(num, val.m_minToolTier);
			}
			else
			{
				MineRock val2 = (MineRock)(object)((destructible is MineRock) ? destructible : null);
				if (val2 != null)
				{
					num = Mathf.Max(num, val2.m_minToolTier);
				}
				else
				{
					Destructible val3 = (Destructible)(object)((destructible is Destructible) ? destructible : null);
					if (val3 != null)
					{
						num = Mathf.Max(num, val3.m_minToolTier);
					}
				}
			}
			if (prefabName.Contains("tin") || prefabName.Contains("copper"))
			{
				if (level < 10f)
				{
					reason = "Требуется 10 ур. Шахтера для меди и олова";
					return false;
				}
				num = Mathf.Max(num, 0);
			}
			else if (prefabName.Contains("mudpile") || prefabName.Contains("iron"))
			{
				if (level < 20f)
				{
					reason = "Требуется 20 ур. Шахтера для железа";
					return false;
				}
				num = Mathf.Max(num, 1);
			}
			else if (prefabName.Contains("silver") || prefabName.Contains("obsidian"))
			{
				if (level < 30f)
				{
					reason = "Требуется 30 ур. Шахтера для серебра";
					return false;
				}
				num = Mathf.Max(num, 2);
			}
			else if (prefabName.Contains("blackmarble") || prefabName.Contains("giant_") || prefabName.Contains("softtissue"))
			{
				if (level < 40f)
				{
					reason = "Требуется 40 ур. Шахтера для черного мрамора";
					return false;
				}
				num = Mathf.Max(num, 3);
			}
			else if (prefabName.Contains("flametal") || prefabName.Contains("mine_flametal"))
			{
				if (level < 50f)
				{
					reason = "Требуется 50 ур. Шахтера для огнеметалла";
					return false;
				}
				num = Mathf.Max(num, 4);
			}
			else if (prefabName.Contains("ice") || prefabName.Contains("bloodstone") || prefabName.Contains("bloodgold"))
			{
				if (level < 60f)
				{
					reason = "Требуется 60 ур. Шахтера для редких руд";
					return false;
				}
				num = Mathf.Max(num, 4);
			}
			if (!HasPickaxe(player, num, out var failReason))
			{
				reason = failReason;
				return false;
			}
			return true;
		}

		public static void CastAreaHarvest(Player player)
		{
			float effectiveSkillLevel = RunescapeMagicPlugin.GetEffectiveSkillLevel(player, (SkillType)106);
			float radius = ((effectiveSkillLevel >= 75f) ? 15f : ((effectiveSkillLevel >= 20f) ? 10f : 5f));
			float staminaCost = ((effectiveSkillLevel >= 75f) ? 5f : ((effectiveSkillLevel >= 35f) ? 10f : 15f));
			bool autoPickup = effectiveSkillLevel >= 50f;
			if (RunescapeMagicPlugin.HasResources(player, staminaCost))
			{
				LaunchMagicProjectile(player, 35f, delegate(Vector3 impactPoint, Collider hitCol)
				{
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					AreaHarvestAtPoint(player, impactPoint, radius, autoPickup, staminaCost);
				});
			}
		}

		private static void AreaHarvestAtPoint(Player player, Vector3 center, float radius, bool autoPickup, float staminaCost)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: 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_0245: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(center, radius);
			HashSet<Pickable> hashSet = new HashSet<Pickable>();
			HashSet<PickableItem> hashSet2 = new HashSet<PickableItem>();
			HashSet<GameObject> hashSet3 = new HashSet<GameObject>();
			int num = 0;
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Pickable componentInParent = ((Component)val).GetComponentInParent<Pickable>();
				if ((Object)(object)componentInParent != (Object)null && (Object)(object)((Component)val).GetComponentInParent<Fish>() == (Object)null && !hashSet.Contains(componentInParent) && componentInParent.CanBePicked())
				{
					hashSet.Add(componentInParent);
					componentInParent.Interact((Humanoid)(object)player, false, false);
					num++;
				}
				PickableItem componentInParent2 = ((Component)val).GetComponentInParent<PickableItem>();
				if ((Object)(object)componentInParent2 != (Object)null && (Object)(object)((Component)val).GetComponentInParent<Fish>() == (Object)null && !hashSet2.Contains(componentInParent2))
				{
					hashSet2.Add(componentInParent2);
					componentInParent2.Interact((Humanoid)(object)player, false, false);
					num++;
				}
				GameObject gameObject = ((Component)((Component)val).transform.root).gameObject;
				if (hashSet3.Contains(gameObject))
				{
					continue;
				}
				MonoBehaviour[] componentsInChildren = gameObject.GetComponentsInChildren<MonoBehaviour>();
				foreach (MonoBehaviour val2 in componentsInChildren)
				{
					if (!((Object)(object)val2 != (Object)null) || !(((object)val2).GetType().Name == "Germination"))
					{
						continue;
					}
					hashSet3.Add(gameObject);
					MethodInfo method = ((object)val2).GetType().GetMethod("GetStatus", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (method != null)
					{
						object obj = method.Invoke(val2, null);
						if (obj != null && obj.ToString() == "Ready")
						{
							((object)val2).GetType().GetMethod("Interact", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val2, new object[3] { player, false, false });
							num++;
							break;
						}
					}
				}
			}
			int num2 = 0;
			if (autoPickup && ItemDrop.s_instances != null)
			{
				foreach (ItemDrop s_instance in ItemDrop.s_instances)
				{
					if (!((Object)(object)s_instance == (Object)null) && s_instance.m_itemData != null && !((Object)(object)s_instance.m_nview == (Object)null) && s_instance.m_nview.IsValid() && !IsFish(s_instance) && Vector3.Distance(center, ((Component)s_instance).transform.position) <= radius + 2f)
					{
						num2++;
					}
				}
			}
			if (num > 0 || num2 > 0)
			{
				RunescapeMagicPlugin.TryConsumeResources(player, staminaCost);
				float num3 = ((num > 0) ? ((float)num * 0.5f) : Mathf.Clamp((float)num2 * 0.2f, 0.5f, 2.5f));
				((Character)player).RaiseSkill((SkillType)106, num3);
				if (num > 0)
				{
					((Character)player).Message((MessageType)2, $"Собрано растений/ресурсов: {num}", 0, (Sprite)null, false);
				}
				else
				{
					((Character)player).Message((MessageType)2, $"Сбор предметов с земли: {num2}", 0, (Sprite)null, false);
				}
				if (autoPickup)
				{
					((MonoBehaviour)RunescapeMagicPlugin.Instance).StartCoroutine(AutoPickupRoutine(player, center, radius + 3f));
				}
			}
			else if (autoPickup)
			{
				((Character)player).Message((MessageType)2, "В радиусе нет растений или предметов для сбора!", 0, (Sprite)null, false);
			}
			else
			{
				((Character)player).Message((MessageType)2, "В радиусе нет спелых растений для сбора!", 0, (Sprite)null, false);
			}
		}

		private static bool IsFish(ItemDrop itemDrop)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Invalid comparison between Unknown and I4
			if ((Object)(object)itemDrop == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)itemDrop).GetComponentInParent<Fish>() != (Object)null || (Object)(object)((Component)itemDrop).GetComponent<Fish>() != (Object)null)
			{
				return true;
			}
			if (itemDrop.m_itemData != null && itemDrop.m_itemData.m_shared != null && (int)itemDrop.m_itemData.m_shared.m_itemType == 21)
			{
				return true;
			}
			return false;
		}

		private static IEnumerator AutoPickupRoutine(Player player, Vector3 center, float radius)
		{
			//IL_000e: 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)
			HashSet<ItemDrop> collectedDrops = new HashSet<ItemDrop>();
			for (int pass = 0; pass < 8; pass++)
			{
				yield return (object)new WaitForSeconds(0.35f);
				if ((Object)(object)player == (Object)null || ((Humanoid)player).GetInventory() == null)
				{
					break;
				}
				if (ItemDrop.s_instances != null)
				{
					for (int num = ItemDrop.s_instances.Count - 1; num >= 0; num--)
					{
						if (num < ItemDrop.s_instances.Count)
						{
							ItemDrop val = ItemDrop.s_instances[num];
							if (!((Object)(object)val == (Object)null) && !collectedDrops.Contains(val) && !IsFish(val) && !(Vector3.Distance(center, ((Component)val).transform.position) > radius) && val.m_itemData != null && !((Object)(object)val.m_nview == (Object)null) && val.m_nview.IsValid())
							{
								ItemData itemData = val.m_itemData;
								if (((Humanoid)player).GetInventory().CanAddItem(itemData, -1))
								{
									collectedDrops.Add(val);
									int stack = itemData.m_stack;
									if (((Humanoid)player).GetInventory().AddItem(itemData))
									{
										val.m_nview.ClaimOwnership();
										ZNetScene.instance.Destroy(((Component)val).gameObject);
										((Character)player).ShowPickupMessage(itemData, stack);
									}
								}
							}
						}
					}
				}
				Collider[] array = Physics.OverlapSphere(center, radius);
				foreach (Collider val2 in array)
				{
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					ItemDrop componentInParent = ((Component)val2).GetComponentInParent<ItemDrop>();
					if ((Object)(object)componentInParent == (Object)null || collectedDrops.Contains(componentInParent) || IsFish(componentInParent) || componentInParent.m_itemData == null || (Object)(object)componentInParent.m_nview == (Object)null || !componentInParent.m_nview.IsValid())
					{
						continue;
					}
					ItemData itemData2 = componentInParent.m_itemData;
					if (((Humanoid)player).GetInventory().CanAddItem(itemData2, -1))
					{
						collectedDrops.Add(componentInParent);
						int stack2 = itemData2.m_stack;
						if (((Humanoid)player).GetInventory().AddItem(itemData2))
						{
							componentInParent.m_nview.ClaimOwnership();
							ZNetScene.instance.Destroy(((Component)componentInParent).gameObject);
							((Character)player).ShowPickupMessage(itemData2, stack2);
						}
					}
				}
			}
		}

		public static void CastInstantGrow(Player player)
		{
			float level = RunescapeMagicPlugin.GetEffectiveSkillLevel(player, (SkillType)106);
			if (level < 25f)
			{
				((Character)player).Message((MessageType)2, $"Требуется 25 ур. Земледелия (текущий: {level})", 0, (Sprite)null, false);
				return;
			}
			float radius = ((level >= 90f) ? 15f : ((level >= 50f) ? 10f : 6f));
			float staminaCost = ((level >= 75f) ? 15f : 30f);
			float healthCost = ((level >= 90f) ? 0f : ((level >= 75f) ? 5f : 15f));
			if (RunescapeMagicPlugin.HasResources(player, staminaCost, healthCost))
			{
				LaunchMagicProjectile(player, 35f, delegate(Vector3 impactPoint, Collider hitCol)
				{
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					InstantGrowAtPoint(player, impactPoint, radius, level, staminaCost, healthCost);
				});
			}
		}

		private static void InstantGrowAtPoint(Player player, Vector3 center, float radius, float level, float staminaCost, float healthCost)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Invalid comparison between Unknown and I4
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(center, radius);
			HashSet<GameObject> hashSet = new HashSet<GameObject>();
			int num = 0;
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				GameObject gameObject = ((Component)((Component)val).transform.root).gameObject;
				if (hashSet.Contains(gameObject))
				{
					continue;
				}
				Plant componentInParent = ((Component)val).GetComponentInParent<Plant>();
				if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent.m_nview != (Object)null && componentInParent.m_nview.IsValid() && CanGrowPlant(Utils.GetPrefabName(((Component)componentInParent).gameObject).ToLowerInvariant(), level))
				{
					hashSet.Add(gameObject);
					componentInParent.m_nview.ClaimOwnership();
					componentInParent.m_status = (Status)0;
					componentInParent.m_nview.GetZDO().Set(ZDOVars.s_plantTime, 0L);
					if ((Object)(object)componentInParent.Grow() != (Object)null || (int)componentInParent.m_status == 0)
					{
						num++;
					}
					continue;
				}
				Pickable componentInParent2 = ((Component)val).GetComponentInParent<Pickable>();
				if ((Object)(object)componentInParent2 != (Object)null && (Object)(object)componentInParent2.m_nview != (Object)null && componentInParent2.m_nview.IsValid() && componentInParent2.m_picked)
				{
					hashSet.Add(gameObject);
					componentInParent2.m_nview.ClaimOwnership();
					componentInParent2.m_nview.GetZDO().Set(ZDOVars.s_pickedTime, 0L);
					componentInParent2.SetPicked(false);
					num++;
					continue;
				}
				Destructible componentInParent3 = ((Component)val).GetComponentInParent<Destructible>();
				string text = Utils.GetPrefabName(gameObject).ToLowerInvariant();
				string text2 = (((Object)(object)componentInParent3 != (Object)null) ? Utils.GetPrefabName(((Component)componentInParent3).gameObject).ToLowerInvariant() : "");
				if (text.Contains("stub") || text2.Contains("stub") || ((Object)(object)componentInParent3 != (Object)null && (int)componentInParent3.GetDestructibleType() == 2))
				{
					GameObject val2 = ResolveTreePrefabForStub(Utils.GetPrefabName(((Object)(object)componentInParent3 != (Object)null) ? ((Component)componentInParent3).gameObject : gameObject), ZNetScene.instance);
					if ((Object)(object)val2 != (Object)null)
					{
						hashSet.Add(gameObject);
						Transform obj = (((Object)(object)componentInParent3 != (Object)null) ? ((Component)componentInParent3).transform : gameObject.transform);
						Vector3 position = obj.position;
						Quaternion rotation = obj.rotation;
						Vector3 localScale = obj.localScale;
						ZNetView val3 = (((Object)(object)componentInParent3 != (Object)null) ? componentInParent3.m_nview : gameObject.GetComponent<ZNetView>());
						if ((Object)(object)val3 != (Object)null && val3.IsValid())
						{
							val3.ClaimOwnership();
							val3.Destroy();
						}
						else
						{
							Object.Destroy((Object)(object)gameObject);
						}
						GameObject val4 = Object.Instantiate<GameObject>(val2, position, rotation);
						if ((Object)(object)val4 != (Object)null)
						{
							ZNetView component = val4.GetComponent<ZNetView>();
							if ((Object)(object)component != (Object)null && component.IsValid())
							{
								component.SetLocalScale(localScale);
							}
							TreeBase component2 = val4.GetComponent<TreeBase>();
							if ((Object)(object)component2 != (Object)null)
							{
								component2.Grow();
							}
						}
						num++;
						continue;
					}
				}
				MonoBehaviour[] componentsInChildren = gameObject.GetComponentsInChildren<MonoBehaviour>();
				bool flag = false;
				MonoBehaviour[] array3 = componentsInChildren;
				foreach (MonoBehaviour val5 in array3)
				{
					if ((Object)(object)val5 == (Object)null)
					{
						continue;
					}
					string name = ((object)val5).GetType().Name;
					if (name == "Germination")
					{
						hashSet.Add(gameObject);
						object obj2 = ((object)val5).GetType().GetMethod("GetStatus", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val5, null);
						if (((obj2 != null) ? Convert.ToInt32(obj2) : (-1)) == 1 || (obj2 != null && obj2.ToString() == "Germinating"))
						{
							ZNetView val6 = ((Component)val5).GetComponent<ZNetView>() ?? gameObject.GetComponent<ZNetView>();
							if ((Object)(object)val6 != (Object)null && val6.IsValid())
							{
								val6.ClaimOwnership();
								val6.GetZDO().Set("RSM_InstantGrown", true);
								long ticks = ZNet.instance.GetTime().Ticks;
								long num2 = Math.Max(1L, ticks - 36000000000L);
								val6.GetZDO().Set(ZDOVars.s_startTime, num2);
							}
							((object)val5).GetType().GetField("m_germinationDuration", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(val5, 0f);
							((object)val5).GetType().GetMethod("SlowUpdate", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val5, null);
							((object)val5).GetType().GetMethod("ReapplyVisuals", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val5, null);
							num++;
							flag = true;
							break;
						}
					}
					else if (name == "StumpGrower")
					{
						hashSet.Add(gameObject);
						((object)val5).GetType().GetMethod("RegrowStump", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val5, null);
						val5.StartCoroutine("RemoveStump");
						num++;
						flag = true;
						break;
					}
				}
			}
			if (num > 0)
			{
				RunescapeMagicPlugin.TryConsumeResources(player, staminaCost, healthCost);
				((Character)player).RaiseSkill((SkillType)106, (float)num * 1f);
				((Character)player).Message((MessageType)2, $"Выращено культур/растений: {num}", 0, (Sprite)null, false);
			}