Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RunescapeMagic v1.0.6
RunescapeMagicValheim.dll
Decompiled 15 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.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); }