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 TerrainImpact v1.0.0
TerrainImpact.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: CompilationRelaxations(8)] [assembly: AssemblyVersion("1.0.0.0")] namespace ChorusReef.TerrainImpact; [BepInProcess("valheim.exe")] [BepInPlugin("ChorusReef.TerrainImpact", "Terrain Impact", "1.0.0")] public sealed class TerrainImpactPlugin : BaseUnityPlugin { public const string PluginGuid = "ChorusReef.TerrainImpact"; public const string PluginName = "Terrain Impact"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; internal static ConfigEntry<int> Strength; internal static ConfigEntry<float> Radius; internal static ConfigEntry<float> Cooldown; internal static ConfigEntry<bool> StoneDrops; internal static TerrainImpactPlugin Instance; private Harmony _harmony; private void Awake() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Instance = this; Strength = ((BaseUnityPlugin)this).Config.Bind<int>("Terrain Impact", "Impact Strength", 1, new ConfigDescription("Strength of one accepted impact. 1 approximates a normal pickaxe strike. Higher values lower more terrain; above 16, strength also widens the impact because Valheim limits digging depth.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 99), new object[0])); Radius = ((BaseUnityPlugin)this).Config.Bind<float>("Terrain Impact", "Impact Radius (m)", 1.5f, new ConfigDescription("Base dig radius in metres. Normal is 1.5 m. Extreme strength adds more radius on top of this value.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 40f), new object[0])); Cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Terrain Impact", "Global Cooldown (s)", 10f, new ConfigDescription("Seconds after a successful terrain edit before any creature can make another. This is shared by all qualifying creatures. 0 allows every valid attack to attempt an edit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), new object[0])); StoneDrops = ((BaseUnityPlugin)this).Config.Bind<bool>("Terrain Impact", "Stone Drops", false, new ConfigDescription("Allow the vanilla pickaxe terrain operation to spawn Stone from creature impacts. Disabled by default.", (AcceptableValueBase)null, new object[0])); _harmony = new Harmony("ChorusReef.TerrainImpact"); _harmony.PatchAll(typeof(TerrainImpactPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Terrain Impact loaded: strength=" + Strength.Value + ", baseRadius=" + Radius.Value + "m, globalCooldown=" + Cooldown.Value + "s, stoneDrops=" + StoneDrops.Value + ".")); } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); _harmony = null; } Log = null; if (object.ReferenceEquals(Instance, this)) { Instance = null; } } internal static bool IsHostReady() { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.IsServer(); } return false; } internal static string QualifyingAttack(Character character, ItemData weapon) { //IL_0096: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Invalid comparison between Unknown and I4 //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Invalid comparison between Unknown and I4 if ((Object)(object)character == (Object)null || weapon == null || weapon.m_shared == null) { return null; } if (weapon.m_shared.m_attack == null) { return null; } string text = (((Object)(object)weapon.m_dropPrefab != (Object)null) ? ((Object)weapon.m_dropPrefab).name : null); if (text == null) { return null; } if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - 7); } ZNetView component = ((Component)character).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null) ? component.GetZDO() : null); if (val == null) { return null; } int prefab = val.GetPrefab(); AttackType attackType = weapon.m_shared.m_attack.m_attackType; if ((int)attackType == 1) { if (prefab == StringExtensionMethods.GetStableHashCode("Troll") && (text == "troll_groundslam" || text == "troll_log_swing_v")) { return text; } if (prefab == StringExtensionMethods.GetStableHashCode("Troll_Summoned") && (text == "troll_summoned_groundslam" || text == "troll_summoned_log_swing_v")) { return text; } if (prefab == StringExtensionMethods.GetStableHashCode("GoblinBrute") && text == "GoblinBrute_RageAttack") { return text; } } if ((int)attackType == 4) { if (prefab == StringExtensionMethods.GetStableHashCode("Lox") && text == "lox_stomp") { return text; } if (prefab == StringExtensionMethods.GetStableHashCode("SeekerBrute") && text == "SeekerBrute_groundslam") { return text; } if (prefab == StringExtensionMethods.GetStableHashCode("Abomination") && text == "Abomination_attack3") { return text; } } return null; } internal static string Position(Vector3 point) { return $"({point.x:F1}, {point.y:F1}, {point.z:F1})"; } internal static float DigRadius() { return Radius.Value + (float)Mathf.Max(0, Strength.Value - 16) * 0.5f; } internal static float OperationRadius() { return DigRadius() + 1f; } internal static void ApplyPreset(bool maximum) { Strength.Value = ((!maximum) ? 1 : 99); Radius.Value = (maximum ? 40f : 1.5f); Cooldown.Value = (maximum ? 0f : 10f); StoneDrops.Value = false; if (maximum) { CreatureTerrainSpawnPatch.ClearCooldown(); } if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Config.Save(); } Log.LogInfo((object)("terrainimpact " + (maximum ? "max" : "min") + " applied.")); } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class TerrainImpactDevCommandPatch { private static readonly FieldInfo CommandsField = AccessTools.Field(typeof(Terminal), "commands"); [HarmonyPostfix] private static void Postfix() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown if (CommandsField == null || CommandsField.GetValue(null) == null) { TerrainImpactPlugin.Log.LogError((object)"Valheim console command registry is unavailable."); } else { if (!(CommandsField.GetValue(null) is Dictionary<string, ConsoleCommand> dictionary) || dictionary.ContainsKey("terrainimpact")) { return; } new ConsoleCommand("terrainimpact", "Set Terrain Impact configuration: terrainimpact max or terrainimpact min", (ConsoleEvent)delegate(ConsoleEventArgs args) { if (args.Args.Length != 2 || (args.Args[1] != "max" && args.Args[1] != "min")) { args.Context.AddString("Usage: terrainimpact max | terrainimpact min"); } else { bool flag = args.Args[1] == "max"; TerrainImpactPlugin.ApplyPreset(flag); args.Context.AddString("Terrain Impact: " + (flag ? "max" : "min") + " settings applied."); } }, true, false, false, false, false, true, (ConsoleOptionsFetcher)null, false, false, false); } } } [HarmonyPatch(typeof(Attack), "DoMeleeAttack")] internal static class CreatureImpactPreparePatch { private static bool _reportedMissingPickaxe; [HarmonyPrefix] private static void Prefix(Attack __instance, Humanoid ___m_character) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (!TerrainImpactPlugin.IsHostReady()) { return; } ItemData weapon = __instance.GetWeapon(); string text = TerrainImpactPlugin.QualifyingAttack((Character)(object)___m_character, weapon); if (text != null) { CreatureTerrainSpawnPatch.BeginMelee(__instance); TerrainImpactPlugin.Log.LogInfo((object)("Qualifying " + text + " triggered near " + TerrainImpactPlugin.Position(((Component)___m_character).transform.position) + ".")); if (!__instance.m_hitTerrain) { TerrainImpactPlugin.Log.LogWarning((object)(text + " has m_hitTerrain=false; no terrain operation will be attempted.")); } else { AttachPickaxeTerrain(weapon); } } } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception, Attack __instance) { CreatureTerrainSpawnPatch.EndMelee(__instance); return __exception; } internal static void AttachPickaxeTerrain(ItemData weapon) { if (!((Object)(object)weapon.m_shared.m_spawnOnHitTerrain != (Object)null)) { GameObject pickaxeTerrain = GetPickaxeTerrain(); if (!((Object)(object)pickaxeTerrain == (Object)null)) { weapon.m_shared.m_spawnOnHitTerrain = pickaxeTerrain; TerrainImpactPlugin.Log.LogInfo((object)("Attached vanilla PickaxeAntler terrain operation digg_v3 to " + (((Object)(object)weapon.m_dropPrefab != (Object)null) ? ((Object)weapon.m_dropPrefab).name : "unknown attack") + ".")); } } } internal static GameObject GetPickaxeTerrain() { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("PickaxeAntler") : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); GameObject val3 = (((Object)(object)val2 != (Object)null) ? val2.m_itemData.m_shared.m_spawnOnHitTerrain : null); if ((Object)(object)val3 == (Object)null || ((Object)val3).name != "digg_v3" || (Object)(object)val3.GetComponent<TerrainOp>() == (Object)null) { if (!_reportedMissingPickaxe) { TerrainImpactPlugin.Log.LogError((object)"Could not obtain the vanilla PickaxeAntler digg_v3 TerrainOp; creature terrain impact is disabled."); _reportedMissingPickaxe = true; } return null; } return val3; } } [HarmonyPatch(typeof(Attack), "SpawnOnHitTerrain")] internal static class CreatureTerrainSpawnPatch { private static ZNet _world; private static double _nextAllowedAt; [ThreadStatic] private static bool _tracking; [ThreadStatic] private static int _operationCalls; [ThreadStatic] private static Attack _activeMeleeAttack; [ThreadStatic] private static bool _meleeImpactConsumed; internal static void BeginMelee(Attack attack) { _activeMeleeAttack = attack; _meleeImpactConsumed = false; } internal static void ClearCooldown() { _nextAllowedAt = 0.0; } internal static void EndMelee(Attack attack) { if (object.ReferenceEquals(_activeMeleeAttack, attack)) { _activeMeleeAttack = null; _meleeImpactConsumed = false; } } [HarmonyPrefix] private static bool Prefix(Attack __instance, Vector3 hitPoint, GameObject prefab, Character character, ItemData weapon, ref GameObject __result, out bool __state) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) __state = false; if (!TerrainImpactPlugin.IsHostReady()) { return true; } string text = TerrainImpactPlugin.QualifyingAttack(character, weapon); if (text == null) { return true; } if ((Object)(object)prefab != (Object)null && ((Object)prefab).name != "digg_v3" && text.StartsWith("troll_summoned_", StringComparison.Ordinal)) { return true; } if (!object.ReferenceEquals(_world, ZNet.instance)) { _world = ZNet.instance; _nextAllowedAt = 0.0; } double timeSeconds = ZNet.instance.GetTimeSeconds(); TerrainImpactPlugin.Log.LogInfo((object)("Qualifying creature terrain contact at " + TerrainImpactPlugin.Position(hitPoint) + ".")); if (object.ReferenceEquals(_activeMeleeAttack, __instance) && _meleeImpactConsumed) { TerrainImpactPlugin.Log.LogInfo((object)"Terrain deformation rejected: this melee attack already made one dent."); __result = null; return false; } if (timeSeconds < _nextAllowedAt) { TerrainImpactPlugin.Log.LogInfo((object)$"Terrain deformation rejected: global cooldown active ({_nextAllowedAt - timeSeconds:F1}s remaining) at {TerrainImpactPlugin.Position(hitPoint)}."); __result = null; return false; } if ((Object)(object)prefab == (Object)null || ((Object)prefab).name != "digg_v3") { TerrainImpactPlugin.Log.LogWarning((object)"Creature terrain contact did not carry digg_v3; operation skipped."); __result = null; return false; } if (!PrivateArea.CheckAccess(hitPoint, TerrainImpactPlugin.OperationRadius(), true, false)) { TerrainImpactPlugin.Log.LogWarning((object)("Configured impact radius fails private-area access at " + TerrainImpactPlugin.Position(hitPoint) + ".")); __result = null; return false; } TerrainOp componentInChildren = prefab.GetComponentInChildren<TerrainOp>(); if ((Object)(object)componentInChildren != (Object)null) { bool flag = PrivateArea.CheckAccess(hitPoint, componentInChildren.GetRadius(), false, false); bool flag2 = Location.IsInsideNoBuildLocation(hitPoint); if (!flag || flag2) { TerrainImpactPlugin.Log.LogWarning((object)$"Native terrain gate at {TerrainImpactPlugin.Position(hitPoint)}: accessAllowed={flag}, noBuildLocation={flag2}; Valheim may reject this strike."); } } _operationCalls = 0; _tracking = true; __state = true; return true; } [HarmonyPostfix] private static void Postfix(Attack __instance, Vector3 hitPoint, GameObject __result, bool __state) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (!__state) { return; } _tracking = false; if (_operationCalls > 0) { if (object.ReferenceEquals(_activeMeleeAttack, __instance)) { _meleeImpactConsumed = true; } _nextAllowedAt = ZNet.instance.GetTimeSeconds() + (double)TerrainImpactPlugin.Cooldown.Value; TerrainImpactPlugin.Log.LogInfo((object)("Terrain deformation accepted at " + TerrainImpactPlugin.Position(hitPoint) + "; global cooldown started.")); TerrainImpactPlugin.Log.LogInfo((object)$"Native terrain operation invoked ({_operationCalls} overlapping terrain compiler(s))."); } else { TerrainImpactPlugin.Log.LogWarning((object)("No native terrain operation was invoked at " + TerrainImpactPlugin.Position(hitPoint) + "; nativeResult=" + (((Object)(object)__result != (Object)null) ? "created" : "null") + "; cooldown remains available.")); } _operationCalls = 0; } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception, bool __state) { if (__state) { _tracking = false; _operationCalls = 0; } return __exception; } internal static void NoteNativeOperation(TerrainOp operation) { if (_tracking && (Object)(object)operation != (Object)null && ((Object)((Component)operation).gameObject).name.StartsWith("digg_v3", StringComparison.Ordinal)) { _operationCalls++; } } internal static bool IsConfiguredCreatureOperation(Settings settings, GameObject prefab) { if (_tracking && settings != null && (Object)(object)prefab != (Object)null) { return ((Object)prefab).name.StartsWith("digg_v3", StringComparison.Ordinal); } return false; } internal static void ConfigureNativeOperation(TerrainOp operation) { if (_tracking && !((Object)(object)operation == (Object)null) && operation.m_settings != null && ((Object)((Component)operation).gameObject).name.StartsWith("digg_v3", StringComparison.Ordinal)) { float num = TerrainImpactPlugin.DigRadius(); operation.m_settings.m_raiseDelta = -0.5f * (float)TerrainImpactPlugin.Strength.Value; operation.m_settings.m_raiseRadius = num; operation.m_settings.m_paintRadius = num + 1f; if (!TerrainImpactPlugin.StoneDrops.Value) { operation.m_spawnOnPlaced = null; } TerrainImpactPlugin.Log.LogInfo((object)$"Configured creature dig: strength={TerrainImpactPlugin.Strength.Value}, targetDelta={operation.m_settings.m_raiseDelta:F1}m, digRadius={num:F1}m, stoneDrops={TerrainImpactPlugin.StoneDrops.Value}."); } } } [HarmonyPatch(typeof(Attack), "SpawnOnHitTerrain")] internal static class SummonedTrollTerrainEffectPatch { private static readonly MethodInfo SpawnOnHitTerrain = AccessTools.Method(typeof(Attack), "SpawnOnHitTerrain", (Type[])null, (Type[])null); [HarmonyPostfix] private static void Postfix(Attack __instance, Vector3 hitPoint, GameObject prefab, Character character, float __3, ItemData weapon, ItemData __5, bool __6) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) if (!TerrainImpactPlugin.IsHostReady() || (Object)(object)prefab == (Object)null || ((Object)prefab).name == "digg_v3") { return; } string text = TerrainImpactPlugin.QualifyingAttack(character, weapon); if (text == null || !text.StartsWith("troll_summoned_", StringComparison.Ordinal)) { return; } GameObject pickaxeTerrain = CreatureImpactPreparePatch.GetPickaxeTerrain(); if ((Object)(object)pickaxeTerrain == (Object)null || SpawnOnHitTerrain == null) { return; } TerrainImpactPlugin.Log.LogInfo((object)("Summoned Troll " + text + " kept native terrain-hit prefab " + ((Object)prefab).name + "; adding digg_v3 at " + TerrainImpactPlugin.Position(hitPoint) + ".")); try { SpawnOnHitTerrain.Invoke(__instance, new object[7] { hitPoint, pickaxeTerrain, character, __3, weapon, __5, __6 }); } catch (TargetInvocationException ex) { TerrainImpactPlugin.Log.LogError((object)("Summoned Troll terrain dig failed: " + ex.InnerException)); } } } [HarmonyPatch(typeof(TerrainOp), "Awake")] internal static class CreatureTerrainOperationConfigurePatch { [HarmonyPrefix] private static void Prefix(TerrainOp __instance) { CreatureTerrainSpawnPatch.ConfigureNativeOperation(__instance); } } [HarmonyPatch(typeof(Settings), "Serialize")] internal static class CreatureTerrainSettingsSerializePatch { internal const int Marker = 1414090064; [HarmonyPostfix] private static void Postfix(Settings __instance, ZPackage __0, GameObject __1) { if (CreatureTerrainSpawnPatch.IsConfiguredCreatureOperation(__instance, __1)) { __0.Write(1414090064); __0.Write(__instance.m_raiseDelta); __0.Write(__instance.m_raiseRadius); __0.Write(__instance.m_paintRadius); } } } [HarmonyPatch(typeof(Settings), "Deserialize")] internal static class CreatureTerrainSettingsDeserializePatch { private static readonly MethodInfo CloneMethod = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic); [HarmonyPostfix] private static void Postfix(ZPackage __0, ref Settings __result) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown if (__result == null || __0.Size() - __0.GetPos() < 16) { return; } int pos = __0.GetPos(); if (__0.ReadInt() != 1414090064) { __0.SetPos(pos); return; } float num = __0.ReadSingle(); float num2 = __0.ReadSingle(); float num3 = __0.ReadSingle(); if (CloneMethod == null || float.IsNaN(num) || float.IsNaN(num2) || float.IsNaN(num3) || num > -0.5f || num < -49.5f || num2 < 0.5f || num2 > 81.5f || num3 < 1.5f || num3 > 82.5f) { TerrainImpactPlugin.Log.LogError((object)"Invalid creature terrain settings in RPC; vanilla settings retained."); return; } Settings val = (Settings)CloneMethod.Invoke(__result, null); val.m_raiseDelta = num; val.m_raiseRadius = num2; val.m_paintRadius = num3; __result = val; } } [HarmonyPatch(typeof(TerrainComp), "ApplyOperation")] internal static class TerrainOperationObservedPatch { [HarmonyPostfix] private static void Postfix(TerrainOp modifier) { CreatureTerrainSpawnPatch.NoteNativeOperation(modifier); } } [HarmonyPatch(typeof(Attack), "DoAreaAttack")] internal static class CreatureAreaImpactPatch { private static readonly MethodInfo GetAttackOrigin = AccessTools.Method(typeof(Attack), "GetAttackOrigin", (Type[])null, (Type[])null); private static readonly MethodInfo SpawnOnHitTerrain = AccessTools.Method(typeof(Attack), "SpawnOnHitTerrain", (Type[])null, (Type[])null); [HarmonyPrefix] private static void Prefix(Attack __instance, Humanoid ___m_character) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (TerrainImpactPlugin.IsHostReady()) { ItemData weapon = __instance.GetWeapon(); string text = TerrainImpactPlugin.QualifyingAttack((Character)(object)___m_character, weapon); if (text != null) { CreatureImpactPreparePatch.AttachPickaxeTerrain(weapon); TerrainImpactPlugin.Log.LogInfo((object)("Qualifying " + text + " area attack triggered near " + TerrainImpactPlugin.Position(((Component)___m_character).transform.position) + ".")); } } } [HarmonyPostfix] private static void Postfix(Attack __instance, Humanoid ___m_character) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_011d: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0145: 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_0168: Unknown result type (might be due to invalid IL or missing references) if (!TerrainImpactPlugin.IsHostReady()) { return; } ItemData weapon = __instance.GetWeapon(); if (TerrainImpactPlugin.QualifyingAttack((Character)(object)___m_character, weapon) == null || (Object)(object)weapon.m_shared.m_spawnOnHitTerrain == (Object)null) { return; } if (GetAttackOrigin == null || SpawnOnHitTerrain == null) { TerrainImpactPlugin.Log.LogError((object)"Required native Attack method missing; area terrain operation skipped."); return; } Transform val = (Transform)GetAttackOrigin.Invoke(__instance, null); if ((Object)(object)val == (Object)null) { return; } Transform transform = ((Component)___m_character).transform; Vector3 val2 = val.position + Vector3.up * __instance.m_attackHeight + transform.forward * __instance.m_attackRange + transform.right * __instance.m_attackOffset; float attackRayWidth = __instance.m_attackRayWidth; RaycastHit[] array = Physics.RaycastAll(val2 + Vector3.up * attackRayWidth, Vector3.down, attackRayWidth * 2f + 0.5f); float num = float.MaxValue; Vector3 val3 = Vector3.zero; bool flag = false; RaycastHit[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit val4 = array2[i]; if (!((Object)(object)((RaycastHit)(ref val4)).collider == (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref val4)).collider).GetComponent<Heightmap>() == (Object)null)) { float num2 = Vector3.Distance(val2, ((RaycastHit)(ref val4)).point); if (!(num2 > attackRayWidth) && !(num2 >= num)) { num = num2; val3 = ((RaycastHit)(ref val4)).point; flag = true; } } } if (!flag) { TerrainImpactPlugin.Log.LogInfo((object)("Qualifying area attack had no Heightmap contact near " + TerrainImpactPlugin.Position(val2) + ".")); return; } try { SpawnOnHitTerrain.Invoke(__instance, new object[7] { val3, weapon.m_shared.m_spawnOnHitTerrain, ___m_character, __instance.m_attackHitNoise, weapon, null, false }); } catch (TargetInvocationException ex) { TerrainImpactPlugin.Log.LogError((object)("Native area terrain spawn failed: " + ex.InnerException)); } } }