Decompiled source of AdvancedTreeChop v1.0.0

BepInEx/plugins/AdvancedTreeChop.dll

Decompiled 4 days ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("AdvancedTreeChop")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AdvancedTreeChop")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("33474395-a0a6-499b-8b7d-43808ac9bab9")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("hadegs.valheim.advancedtreechop", "AdvancedTreeChop", "1.0.0")]
public class AdvancedTreeChop : BaseUnityPlugin
{
	[HarmonyPatch(typeof(TreeBase), "Damage")]
	private class TreeBasePatch
	{
		private static void Postfix(TreeBase __instance, HitData hit)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Character attacker = hit.GetAttacker();
			Player val = (Player)(object)((attacker is Player) ? attacker : null);
			if (!((Object)(object)val == (Object)null))
			{
				DoTreeChop(((Component)__instance).transform.position, hit, GetTreeRadius(val));
			}
		}
	}

	[HarmonyPatch(typeof(TreeLog), "Damage")]
	private class TreeLogPatch
	{
		private static void Postfix(TreeLog __instance, HitData hit)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Character attacker = hit.GetAttacker();
			Player val = (Player)(object)((attacker is Player) ? attacker : null);
			if (!((Object)(object)val == (Object)null))
			{
				DoTreeChop(((Component)__instance).transform.position, hit, GetTreeRadius(val));
			}
		}
	}

	internal static ConfigEntry<bool> modEnabled;

	internal static ConfigEntry<bool> toggleMode;

	internal static ConfigEntry<KeyCode> modifierKey;

	internal static ConfigEntry<float> baseTreeRadius;

	internal static ConfigEntry<bool> progressiveRadius;

	internal static ConfigEntry<float> skillRadiusMultiplier;

	internal static ConfigEntry<bool> useStamina;

	internal static ConfigEntry<bool> useDurability;

	private const float MAX_RADIUS = 40f;

	private const int MAX_TREE_NODES = 15;

	private static bool toggleActive;

	private static bool isProcessing;

	private void Awake()
	{
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Expected O, but got Unknown
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable AdvancedTreeChop");
		toggleMode = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ToggleMode", false, "Toggle instead of holding key");
		modifierKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ModifierKey", (KeyCode)308, "Tree chop key");
		baseTreeRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Radius", "TreeRadius", 5f, new ConfigDescription("Base radius for trees", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 15f), Array.Empty<object>()));
		progressiveRadius = ((BaseUnityPlugin)this).Config.Bind<bool>("Progression", "EnableProgressiveRadius", true, "Scale radius with Woodcutting skill");
		skillRadiusMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Progression", "SkillRadiusMultiplier", 0.05f, "Radius increase per Woodcutting skill level");
		useStamina = ((BaseUnityPlugin)this).Config.Bind<bool>("Balance", "UseStamina", true, "Consume stamina for extra tree hits");
		useDurability = ((BaseUnityPlugin)this).Config.Bind<bool>("Balance", "UseDurability", true, "Consume durability for extra tree hits");
		new Harmony("hadegs.valheim.advancedtreechop").PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"AdvancedTreeChop 1.0.0 loaded");
	}

	private void Update()
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		if (modEnabled.Value && toggleMode.Value && Input.GetKeyDown(modifierKey.Value))
		{
			toggleActive = !toggleActive;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("AdvancedTreeChop " + (toggleActive ? "ON" : "OFF")));
		}
	}

	private static bool TreeChopActive()
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		if (!modEnabled.Value)
		{
			return false;
		}
		return toggleMode.Value ? toggleActive : Input.GetKey(modifierKey.Value);
	}

	private static float GetTreeRadius(Player player)
	{
		float num = baseTreeRadius.Value;
		if (progressiveRadius.Value)
		{
			float skillLevel = ((Character)player).GetSkillLevel((SkillType)13);
			num += skillLevel * skillRadiusMultiplier.Value;
		}
		return Mathf.Min(num, 40f);
	}

	private static bool CanApplyExtraHit(Player player, ItemData tool)
	{
		if (useStamina.Value && player.GetStamina() <= 0f)
		{
			return false;
		}
		if (useDurability.Value && tool.m_durability <= 0f)
		{
			return false;
		}
		return true;
	}

	private static void DoTreeChop(Vector3 center, HitData hit, float radius)
	{
		//IL_004d: 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)
		if (isProcessing || !TreeChopActive())
		{
			return;
		}
		Character attacker = hit.GetAttacker();
		Player val = (Player)(object)((attacker is Player) ? attacker : null);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon();
		if (currentWeapon == null || currentWeapon.GetDamage().m_chop <= 0f)
		{
			return;
		}
		isProcessing = true;
		int num = 0;
		Collider[] array = Physics.OverlapSphere(center, radius);
		Collider[] array2 = array;
		foreach (Collider val2 in array2)
		{
			if (num >= 15)
			{
				break;
			}
			IDestructible componentInParent = ((Component)val2).GetComponentInParent<IDestructible>();
			if (componentInParent != null)
			{
				if (!CanApplyExtraHit(val, currentWeapon))
				{
					break;
				}
				HitData val3 = hit.Clone();
				componentInParent.Damage(val3);
				num++;
			}
		}
		isProcessing = false;
	}
}