Decompiled source of AshValheimMod v0.0.9

BepInEx/plugins/AshValheimMod/AshValheimMod.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Xml.Serialization;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("AshValheimMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AshValheimMod")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
namespace AshValheimMod;

public class AllySummon
{
	public static GameObject CharredSpawn(string basePrefab, Vector3 position, int level)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		GameObject prefab = PrefabManager.Instance.GetPrefab(basePrefab);
		if ((Object)(object)prefab != (Object)null)
		{
			GameObject val = Object.Instantiate<GameObject>(prefab, position, Quaternion.identity);
			AshCharacters.SetCreatureStars(val, level);
			AshCharacters.ResetCharacterFaction(val, (Faction)11);
			MonsterAI component = val.GetComponent<MonsterAI>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
			}
			BaseAI component2 = val.GetComponent<BaseAI>();
			if ((Object)(object)component2 != (Object)null)
			{
				((Behaviour)component2).enabled = false;
			}
			LevelEffects component3 = val.GetComponent<LevelEffects>();
			if ((Object)(object)component3 != (Object)null)
			{
				Object.Destroy((Object)(object)component3);
			}
			val.AddComponent<AshSummonTracker>();
			val.AddComponent<AshAI>();
			Humanoid component4 = val.GetComponent<Humanoid>();
			if ((Object)(object)component4 != (Object)null)
			{
				((Character)component4).m_name = AshNameManager.GetAshName();
				((Character)component4).m_health = 1200f;
				((Character)component4).SetMaxHealth(1200f);
				((Behaviour)component4).enabled = true;
				((Character)component4).m_runSpeed = 8f;
				((Character)component4).m_runTurnSpeed = 2f;
				((Character)component4).m_speed = 7f;
				((Character)component4).m_groundTiltSpeed = 1f;
				((Character)component4).m_walkSpeed = 1f;
				((Character)component4).m_turnSpeed = 1f;
				Debug.Log((object)"Ash Weapon Stats");
				ItemData currentWeapon = component4.GetCurrentWeapon();
				Debug.Log((object)currentWeapon?.m_shared.m_name);
				Debug.Log((object)currentWeapon?.m_shared.m_aiAttackInterval);
				Debug.Log((object)"End Ash Weapon Stats");
			}
			Tameable val2 = val.GetComponent<Tameable>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = val.AddComponent<Tameable>();
			}
			if ((Object)(object)val2 != (Object)null)
			{
				val2.m_startsTamed = true;
				val2.m_unsummonDistance = 150f;
				val2.m_unsummonOnOwnerLogoutSeconds = 1f;
				if ((Object)(object)component4 != (Object)null)
				{
					((Character)component4).SetTamed(true);
				}
			}
			AddNecromancerTealEffect(val);
			ZNetView component5 = val.GetComponent<ZNetView>();
			if ((Object)(object)component5 != (Object)null)
			{
				component5.GetZDO().Set("AshSummon", true);
			}
			Logger.LogInfo((object)("Summoned " + basePrefab + "."));
			return val;
		}
		Logger.LogError((object)("Unable to retrieve " + basePrefab + " prefab."));
		return null;
	}

	private static void AddNecromancerTealEffect(GameObject skeleton)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: 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)
		LineRenderer val = skeleton.AddComponent<LineRenderer>();
		((Renderer)val).material = new Material(Shader.Find("Sprites/Default"));
		val.useWorldSpace = false;
		val.loop = true;
		val.startWidth = 0.1f;
		val.endWidth = 0.3f;
		val.positionCount = 2;
		val.startColor = AshColor.NecromancerTeal;
		val.endColor = AshColor.NecromancerTeal;
		Vector3 zero = Vector3.zero;
		val.SetPosition(0, zero + new Vector3(0f, 1.4f, 0f));
		val.SetPosition(1, zero + new Vector3(0f, 2.1f, 0f));
		Logger.LogInfo((object)"Added NecromancerTeal effect to skeleton.");
	}
}
public class AshAI : MonoBehaviour
{
	private Character characterAsh;

	private Humanoid humanoidAsh;

	private GameObject player;

	private int currentEnemyCount;

	private readonly List<Vector3> m_path = new List<Vector3>();

	private float m_lastFindPathTime;

	private Vector3 m_lastFindPathTarget;

	private bool m_lastFindPathResult;

	private Vector3 m_lastPosition;

	private float m_stuckTimer;

	private float m_getOutOfCornerTimer;

	private float m_getOutOfCornerAngle;

	private readonly HashSet<Collider> ignoredChopColliders = new HashSet<Collider>();

	private bool chopAnalysisInProgress = false;

	private string ashMode;

	public const string ASH_MODE_GUARD = "ASH_MODE_GUARD";

	public const string ASH_MODE_STOP = "ASH_MODE_STOP";

	public const string ASH_MODE_SENTINEL = "ASH_MODE_SENTINEL";

	public const string ASH_MODE_CHOP = "ASH_MODE_CHOP";

	private const float ASH_MOVE_MIN_ANGLE = 20f;

	private TreeBase currentTreeTarget = null;

	private Destructible currentStumpTarget = null;

	private TreeLog currentTreeLogTarget = null;

	private int treeTargetCounter = 0;

	private readonly Collider[] m_treeOverlapResults = (Collider[])(object)new Collider[1024];

	public string AshMode
	{
		get
		{
			return ashMode;
		}
		set
		{
			ashMode = value;
		}
	}

	protected void Awake()
	{
		characterAsh = ((Component)this).GetComponent<Character>();
		humanoidAsh = ((Component)this).GetComponent<Humanoid>();
		DisableMonsterAI();
	}

	private void Start()
	{
		player = ((Component)Player.m_localPlayer).gameObject;
		if (Object.op_Implicit((Object)(object)humanoidAsh))
		{
			humanoidAsh.EquipBestWeapon((Character)null, (StaticTarget)null, (Character)null, (Character)null);
		}
		ItemData currentWeapon = humanoidAsh.GetCurrentWeapon();
		if (currentWeapon == null)
		{
			return;
		}
		Attack attack = currentWeapon.m_shared.m_attack;
		if (attack == null)
		{
			return;
		}
		Debug.Log((object)"========== ASH BOW ATTACK ==========");
		Debug.Log((object)("Weapon: " + currentWeapon.m_shared.m_name));
		Debug.Log((object)$"Attack: {attack}");
		Debug.Log((object)$"Attack Height: {attack.m_attackHeight}");
		Debug.Log((object)$"Attack Range: {attack.m_attackRange}");
		Debug.Log((object)$"Attack Offset: {attack.m_attackOffset}");
		Debug.Log((object)$"Launch Angle: {attack.m_launchAngle}");
		Debug.Log((object)$"Projectile Velocity: {attack.m_projectileVel}");
		Debug.Log((object)$"Projectile Velocity Min: {attack.m_projectileVelMin}");
		Debug.Log((object)$"Projectile Accuracy: {attack.m_projectileAccuracy}");
		Debug.Log((object)$"Projectile Accuracy Min: {attack.m_projectileAccuracyMin}");
		Debug.Log((object)$"Bow Draw: {attack.m_bowDraw}");
		Debug.Log((object)$"Use Character Facing: {attack.m_useCharacterFacing}");
		Debug.Log((object)$"Use Character Facing Y Aim: {attack.m_useCharacterFacingYAim}");
		Debug.Log((object)"===================================");
		GameObject attackProjectile = attack.m_attackProjectile;
		if ((Object)(object)attackProjectile != (Object)null)
		{
			Projectile component = attackProjectile.GetComponent<Projectile>();
			if ((Object)(object)component != (Object)null)
			{
				Debug.Log((object)"========== ASH PROJECTILE ==========");
				Debug.Log((object)("Projectile Prefab: " + ((Object)attackProjectile).name));
				Debug.Log((object)$"Gravity: {component.m_gravity}");
				Debug.Log((object)$"Drag: {component.m_drag}");
				Debug.Log((object)$"Ray Radius: {component.m_rayRadius}");
				Debug.Log((object)$"TTL: {component.m_ttl}");
				Debug.Log((object)"====================================");
			}
			else
			{
				Debug.LogError((object)"Ash's attack projectile has no Projectile component!");
			}
		}
		else
		{
			Debug.LogError((object)"Ash's attack has no projectile prefab!");
		}
	}

	private void Update()
	{
		IsSafe();
		float deltaTime = Time.deltaTime;
		switch (AshMode)
		{
		case "ASH_MODE_GUARD":
			FollowMaster(deltaTime);
			break;
		case "ASH_MODE_SENTINEL":
		{
			AshStop();
			Character targetEnemy = SeekOutTarget();
			AttackEnemyClosestToMaster(targetEnemy);
			break;
		}
		case "ASH_MODE_CHOP":
			ChopTrees();
			break;
		default:
			AshStop();
			break;
		}
	}

	private void AshStop()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		((Character)humanoidAsh).SetMoveDir(Vector3.zero);
		((Character)humanoidAsh).SetRun(false);
		((Character)humanoidAsh).SetWalk(false);
	}

	protected void FollowMaster(float dt)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: 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)
		float num = DistanceXZ(player.transform.position, ((Component)this).transform.position);
		if (num <= 4f)
		{
			StopMoving();
			Character val = SeekOutTarget();
			if ((Object)(object)val != (Object)null)
			{
				AttackEnemyClosestToMaster(val);
			}
		}
		else
		{
			bool run = num > 8f;
			MoveTo(dt, player.transform.position, 4f, run);
		}
	}

	private List<Character> GetNearbyEnemies(float detectionRadius)
	{
		//IL_0024: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Invalid comparison between Unknown and I4
		List<Character> list = new List<Character>();
		if ((Object)(object)characterAsh == (Object)null)
		{
			return list;
		}
		Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, detectionRadius, LayerMask.GetMask(new string[1] { "character" }));
		Collider[] array2 = array;
		foreach (Collider val in array2)
		{
			Character component = ((Component)val).GetComponent<Character>();
			if (!((Object)(object)component == (Object)null) && !((Object)(object)component == (Object)(object)characterAsh) && !component.IsDead() && ((Component)component).gameObject.activeInHierarchy && component.GetFaction() != characterAsh.GetFaction() && (int)component.GetFaction() != 0)
			{
				Debug.Log((object)("Enemy nearby: " + component.m_name));
				list.Add(component);
			}
		}
		return list;
	}

	private Character SeekOutTarget()
	{
		//IL_0091: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: 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_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		List<Character> nearbyEnemies = GetNearbyEnemies(50f);
		Character result = null;
		float num = float.MaxValue;
		int num2 = 0;
		RaycastHit val4 = default(RaycastHit);
		foreach (Character item in nearbyEnemies)
		{
			if ((Object)(object)item == (Object)(object)characterAsh || (Object)(object)item == (Object)(object)((Component)Player.m_localPlayer).GetComponent<Character>() || item.IsTamed() || item.IsDead())
			{
				continue;
			}
			num2++;
			float num3 = Vector3.Distance(((Component)this).transform.position, ((Component)item).transform.position);
			if (num3 >= num)
			{
				continue;
			}
			Vector3 val = ((Component)this).transform.position + Vector3.up * 1.5f;
			Vector3 val2 = ((Component)item).transform.position + Vector3.up * 1f;
			Vector3 val3 = val2 - val;
			float magnitude = ((Vector3)(ref val3)).magnitude;
			if (Physics.Raycast(val, ((Vector3)(ref val3)).normalized, ref val4, magnitude))
			{
				Character componentInParent = ((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent<Character>();
				if ((Object)(object)componentInParent != (Object)(object)item)
				{
					Debug.Log((object)("ASH LINE OF SIGHT BLOCKED | Target: " + item.m_name + " | Obstacle: " + ((Object)((RaycastHit)(ref val4)).collider).name));
					continue;
				}
			}
			num = num3;
			result = item;
		}
		currentEnemyCount = num2;
		return result;
	}

	private void AttackEnemyClosestToMaster(Character targetEnemy)
	{
		//IL_035e: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)targetEnemy == (Object)null))
		{
			EnsureDeathWatcher(targetEnemy);
			AdjustAim(targetEnemy);
			BaseAI component = ((Component)humanoidAsh).GetComponent<BaseAI>();
			if ((Object)(object)component != (Object)null)
			{
				Character targetCreature = component.GetTargetCreature();
				Debug.Log((object)("ASH TARGET CHECK | Our Target: " + (((Object)(object)targetEnemy != (Object)null) ? targetEnemy.m_name : "NULL") + " | AI Target: " + (((Object)(object)targetCreature != (Object)null) ? targetCreature.m_name : "NULL")));
			}
			else
			{
				Debug.Log((object)"ASH TARGET CHECK | NO BASEAI COMPONENT");
			}
			if (((Character)humanoidAsh).StartAttack((Character)null, false))
			{
				string text = ((Object)targetEnemy).name ?? "";
				text = text.Replace("(Clone)", string.Empty);
				text = text.Replace("_", " ");
				string masterOrMistressTitle = GetMasterOrMistressTitle();
				string[] array = new string[25]
				{
					text + "! You dare threaten my " + masterOrMistressTitle + "?",
					text + "! You shall not touch my " + masterOrMistressTitle + "!",
					text + "! You picked the wrong " + masterOrMistressTitle + " to threaten!",
					text + "! Face me, coward! My " + masterOrMistressTitle + " demands it!",
					text + "! You will pay for striking my " + masterOrMistressTitle + "!",
					text + "! My " + masterOrMistressTitle + " shall remain unharmed!",
					text + "! I will defend my " + masterOrMistressTitle + " to the death!",
					text + "! You will regret crossing my " + masterOrMistressTitle + "!",
					text + "! My arrows fly for the glory of my " + masterOrMistressTitle + "!",
					text + "! You have earned the wrath of my " + masterOrMistressTitle + "!",
					text + "! Back away from my " + masterOrMistressTitle + "!",
					text + "! I serve my " + masterOrMistressTitle + ", and I shall destroy you!",
					text + "! Your attack upon my " + masterOrMistressTitle + " will not go unanswered!",
					text + "! My " + masterOrMistressTitle + " commands, and I obey!",
					text + "! For my " + masterOrMistressTitle + ", you shall fall!",
					text + "! I was dead once. You will be next!",
					text + "! My " + masterOrMistressTitle + " has no need for your mercy!",
					text + "! You stand between me and my " + masterOrMistressTitle + "!",
					text + "! Your blood shall be tribute to my " + masterOrMistressTitle + "!",
					text + "! I will make you regret threatening my " + masterOrMistressTitle + "!",
					text + "! My bow serves my " + masterOrMistressTitle + ". You are its next victim!",
					text + "! The dead protect their own. My " + masterOrMistressTitle + " is mine to protect!",
					text + "! You have challenged my " + masterOrMistressTitle + ". Now you face me!",
					text + "! Nothing shall harm my " + masterOrMistressTitle + " while I draw breath!",
					text + "! I shall send you screaming into the afterlife for my " + masterOrMistressTitle + "!"
				};
				string message = array[Random.Range(0, array.Length)];
				AshMessageUI.Instance.Show(message);
				Debug.Log((object)("Ash fired at " + targetEnemy.m_name + " | " + $"Aim: {((Character)humanoidAsh).GetLookDir()}"));
			}
		}
	}

	private void AdjustAim(Character targetEnemy)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)targetEnemy == (Object)null))
		{
			AdjustAim(targetEnemy.GetCenterPoint());
		}
	}

	private bool AdjustAim(TreeBase tree)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: 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_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_0258: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)tree == (Object)null)
		{
			return false;
		}
		Vector3 val = ((Component)this).transform.position + ((Component)this).transform.up * 2f + ((Component)this).transform.forward * 1f;
		for (int i = 0; i <= 5; i++)
		{
			float num = (float)i * 10f;
			Vector3 val2 = ((Component)tree).transform.position + Vector3.up * num;
			Vector3 val3 = val2 - val;
			float magnitude = ((Vector3)(ref val3)).magnitude;
			if (magnitude < 0.01f)
			{
				continue;
			}
			((Vector3)(ref val3)).Normalize();
			Debug.Log((object)("ASH CHOP AIM: TRY | Tree=" + ((Object)tree).name + " | " + $"HeightOffset={num}m | " + $"AimPoint={val2}"));
			RaycastHit[] array = Physics.RaycastAll(val, val3, magnitude);
			if (array == null || array.Length == 0)
			{
				Debug.Log((object)("ASH CHOP AIM: NO TARGET | Tree=" + ((Object)tree).name + " | " + $"HeightOffset={num}m"));
				continue;
			}
			Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
			RaycastHit[] array2 = array;
			for (int num2 = 0; num2 < array2.Length; num2++)
			{
				RaycastHit val4 = array2[num2];
				Collider collider = ((RaycastHit)(ref val4)).collider;
				if ((Object)(object)collider == (Object)null)
				{
					continue;
				}
				string text = ((Object)collider).name.ToLowerInvariant();
				if (text == "viewblock" || text == "viewblocker")
				{
					Debug.Log((object)("ASH CHOP AIM: IGNORE | Tree=" + ((Object)tree).name + " | " + $"HeightOffset={num}m | " + "Collider=" + ((Object)collider).name));
					continue;
				}
				TreeBase componentInParent = ((Component)collider).GetComponentInParent<TreeBase>();
				if ((Object)(object)componentInParent == (Object)(object)tree)
				{
					((Character)humanoidAsh).SetLookDir(val3, 0f);
					Debug.Log((object)("ASH CHOP AIM: CLEAR | Tree=" + ((Object)tree).name + " | " + $"HeightOffset={num}m | " + $"AimPoint={val2} | " + "Hit=" + ((Object)collider).name));
					return true;
				}
				Debug.Log((object)("ASH CHOP AIM: BLOCKED | Tree=" + ((Object)tree).name + " | " + $"HeightOffset={num}m | " + "BlockedBy=" + ((Object)collider).name));
				break;
			}
		}
		Collider[] componentsInChildren = ((Component)tree).GetComponentsInChildren<Collider>();
		Collider[] array3 = componentsInChildren;
		foreach (Collider val5 in array3)
		{
			if ((Object)(object)val5 != (Object)null)
			{
				ignoredChopColliders.Add(val5);
			}
		}
		Debug.Log((object)("ASH CHOP AIM: NO CLEAR SHOT | Tree=" + ((Object)tree).name + " | " + $"Temporarily ignored {componentsInChildren.Length} colliders"));
		return false;
	}

	private bool AdjustAim(TreeLog log)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//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_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)log == (Object)null)
		{
			return false;
		}
		Vector3 val = ((Component)this).transform.position + ((Component)this).transform.up * 2f + ((Component)this).transform.forward * 1f;
		for (int i = 0; i <= 5; i++)
		{
			float num = (float)i * 1f;
			Vector3 val2 = ((Component)log).transform.position + Vector3.up * num;
			Vector3 val3 = val2 - val;
			float magnitude = ((Vector3)(ref val3)).magnitude;
			if (magnitude < 0.01f)
			{
				continue;
			}
			((Vector3)(ref val3)).Normalize();
			RaycastHit[] array = Physics.RaycastAll(val, val3, magnitude);
			if (array == null || array.Length == 0)
			{
				continue;
			}
			Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
			RaycastHit[] array2 = array;
			for (int num2 = 0; num2 < array2.Length; num2++)
			{
				RaycastHit val4 = array2[num2];
				Collider collider = ((RaycastHit)(ref val4)).collider;
				if (!((Object)(object)collider == (Object)null))
				{
					TreeLog componentInParent = ((Component)collider).GetComponentInParent<TreeLog>();
					if ((Object)(object)componentInParent == (Object)(object)log)
					{
						Debug.Log((object)("ASH CHOP AIM: LOG CLEAR | Log=" + ((Object)log).name + " | " + $"HeightOffset={num}m"));
						AdjustAim(val2);
						return true;
					}
					Debug.Log((object)("ASH CHOP AIM: LOG BLOCKED | Log=" + ((Object)log).name + " | " + $"HeightOffset={num}m | " + "BlockedBy=" + ((Object)collider).name));
					break;
				}
			}
		}
		return false;
	}

	private bool AdjustAim(Destructible stump)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//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_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)stump == (Object)null)
		{
			return false;
		}
		Vector3 val = ((Component)this).transform.position + ((Component)this).transform.up * 2f + ((Component)this).transform.forward * 1f;
		for (int i = 0; i <= 5; i++)
		{
			float num = (float)i * 1f;
			Vector3 val2 = ((Component)stump).transform.position + Vector3.up * num;
			Vector3 val3 = val2 - val;
			float magnitude = ((Vector3)(ref val3)).magnitude;
			if (magnitude < 0.01f)
			{
				continue;
			}
			((Vector3)(ref val3)).Normalize();
			RaycastHit[] array = Physics.RaycastAll(val, val3, magnitude);
			if (array == null || array.Length == 0)
			{
				continue;
			}
			Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
			RaycastHit[] array2 = array;
			for (int num2 = 0; num2 < array2.Length; num2++)
			{
				RaycastHit val4 = array2[num2];
				Collider collider = ((RaycastHit)(ref val4)).collider;
				if (!((Object)(object)collider == (Object)null))
				{
					Destructible componentInParent = ((Component)collider).GetComponentInParent<Destructible>();
					if ((Object)(object)componentInParent == (Object)(object)stump)
					{
						Debug.Log((object)("ASH CHOP AIM: STUMP CLEAR | Stump=" + ((Object)stump).name + " | " + $"HeightOffset={num}m"));
						AdjustAim(val2);
						return true;
					}
					Debug.Log((object)("ASH CHOP AIM: STUMP BLOCKED | Stump=" + ((Object)stump).name + " | " + $"HeightOffset={num}m | " + "BlockedBy=" + ((Object)collider).name));
					break;
				}
			}
		}
		return false;
	}

	private void AdjustAim(Vector3 targetPoint)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//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_002c: 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_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: 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)
		Vector3 val = ((Component)this).transform.position + ((Component)this).transform.up * 2f + ((Component)this).transform.forward * 1f;
		Vector3 val2 = targetPoint - val;
		if (!(((Vector3)(ref val2)).sqrMagnitude < 0.001f))
		{
			((Vector3)(ref val2)).Normalize();
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(val2.x, 0f, val2.z);
			if (((Vector3)(ref val3)).sqrMagnitude > 0.001f)
			{
				((Vector3)(ref val3)).Normalize();
				((Component)this).transform.rotation = Quaternion.LookRotation(val3, Vector3.up);
			}
			((Character)humanoidAsh).SetLookDir(val2, 0f);
			Debug.Log((object)("Ash AdjustAim | " + $"Target: {targetPoint} | " + $"Spawn: {val} | " + $"Aim: {val2}"));
		}
	}

	private void DisableMonsterAI()
	{
		MonsterAI component = ((Component)this).GetComponent<MonsterAI>();
		if ((Object)(object)component != (Object)null)
		{
			((Behaviour)component).enabled = false;
			Debug.Log((object)"AshAI: MonsterAI disabled.");
		}
		BaseAI component2 = ((Component)this).GetComponent<BaseAI>();
		if ((Object)(object)component2 != (Object)null)
		{
			((Behaviour)component2).enabled = false;
			Debug.Log((object)"AshAI: BaseAI disabled.");
		}
	}

	private void EnsureDeathWatcher(Character target)
	{
		if (!((Object)(object)target == (Object)null))
		{
			AshDeathWatcher component = ((Component)target).GetComponent<AshDeathWatcher>();
			if ((Object)(object)component == (Object)null)
			{
				component = ((Component)target).gameObject.AddComponent<AshDeathWatcher>();
				component.Initialize(characterAsh);
			}
		}
	}

	private bool IsSafe()
	{
		if (!AshSceneUtility.IsScene(AshSceneUtility.GameScenes.Main))
		{
			return false;
		}
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			return false;
		}
		return true;
	}

	public void StopMoving()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		characterAsh.SetMoveDir(Vector3.zero);
	}

	protected bool MoveTo(float dt, Vector3 point, float dist, bool run)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		float num = (run ? 1f : 0.5f);
		if (DistanceXZ(point, ((Component)this).transform.position) < Mathf.Max(dist, num))
		{
			StopMoving();
			return true;
		}
		if (!FindPath(point))
		{
			StopMoving();
			return true;
		}
		if (m_path.Count == 0)
		{
			StopMoving();
			return true;
		}
		Vector3 val = m_path[0];
		if (DistanceXZ(val, ((Component)this).transform.position) < num)
		{
			m_path.RemoveAt(0);
			if (m_path.Count == 0)
			{
				StopMoving();
				return true;
			}
		}
		else
		{
			Vector3 val2 = val - ((Component)this).transform.position;
			Vector3 normalized = ((Vector3)(ref val2)).normalized;
			MoveTowards(normalized, run);
		}
		return false;
	}

	protected bool MoveAndAvoid(float dt, Vector3 point, float dist, bool run)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_0227: Unknown result type (might be due to invalid IL or missing references)
		//IL_022c: 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_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: 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_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: 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_028d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0292: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = point - ((Component)this).transform.position;
		if (characterAsh.IsFlying())
		{
			if (((Vector3)(ref val)).magnitude < dist)
			{
				StopMoving();
				return true;
			}
		}
		else
		{
			val.y = 0f;
			if (((Vector3)(ref val)).magnitude < dist)
			{
				StopMoving();
				return true;
			}
		}
		((Vector3)(ref val)).Normalize();
		float radius = characterAsh.GetRadius();
		float num = radius + 1f;
		if (!characterAsh.InAttack())
		{
			m_getOutOfCornerTimer -= dt;
			if (m_getOutOfCornerTimer > 0f)
			{
				Vector3 dir = Quaternion.Euler(0f, m_getOutOfCornerAngle, 0f) * -val;
				MoveTowards(dir, run);
				return false;
			}
			m_stuckTimer += Time.fixedDeltaTime;
			if (m_stuckTimer > 1.5f)
			{
				if (Vector3.Distance(((Component)this).transform.position, m_lastPosition) < 0.2f)
				{
					m_getOutOfCornerTimer = 4f;
					m_getOutOfCornerAngle = Random.Range(-20f, 20f);
					m_stuckTimer = 0f;
					return false;
				}
				m_stuckTimer = 0f;
				m_lastPosition = ((Component)this).transform.position;
			}
		}
		if (CanMove(val, radius, num))
		{
			MoveTowards(val, run);
		}
		else
		{
			Vector3 forward = ((Component)this).transform.forward;
			if (characterAsh.IsFlying())
			{
				forward.y = 0.2f;
				((Vector3)(ref forward)).Normalize();
			}
			Vector3 val2 = ((Component)this).transform.right * radius * 0.75f;
			float num2 = num * 1.5f;
			Vector3 centerPoint = characterAsh.GetCenterPoint();
			float num3 = Raycast(centerPoint - val2, forward, num2, 0.1f);
			float num4 = Raycast(centerPoint + val2, forward, num2, 0.1f);
			if (num3 >= num2 && num4 >= num2)
			{
				MoveTowards(forward, run);
			}
			else
			{
				Vector3 dir2 = Quaternion.Euler(0f, -20f, 0f) * forward;
				Vector3 dir3 = Quaternion.Euler(0f, 20f, 0f) * forward;
				if (num3 > num4)
				{
					MoveTowards(dir2, run);
				}
				else
				{
					MoveTowards(dir3, run);
				}
			}
		}
		return false;
	}

	private bool CanMove(Vector3 dir, float checkRadius, float distance)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//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_0075: Unknown result type (might be due to invalid IL or missing references)
		Vector3 centerPoint = characterAsh.GetCenterPoint();
		Vector3 right = ((Component)this).transform.right;
		if (Raycast(centerPoint, dir, distance, 0.1f) < distance)
		{
			return false;
		}
		if (Raycast(centerPoint - right * (checkRadius - 0.1f), dir, distance, 0.1f) < distance)
		{
			return false;
		}
		if (Raycast(centerPoint + right * (checkRadius - 0.1f), dir, distance, 0.1f) < distance)
		{
			return false;
		}
		return true;
	}

	public float Raycast(Vector3 p, Vector3 dir, float distance, float radius)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: 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)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		if (radius == 0f)
		{
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(p, dir, ref val, distance, -5))
			{
				return ((RaycastHit)(ref val)).distance;
			}
			return distance;
		}
		RaycastHit val2 = default(RaycastHit);
		if (Physics.SphereCast(p, radius, dir, ref val2, distance, -5))
		{
			return ((RaycastHit)(ref val2)).distance;
		}
		return distance;
	}

	private void MoveTowards(Vector3 dir, bool run)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		if (((Vector3)(ref dir)).sqrMagnitude < 0.001f)
		{
			AshStop();
			return;
		}
		((Vector3)(ref dir)).Normalize();
		LookTowards(dir);
		if (!IsLookingTowards(dir, 20f))
		{
			AshStop();
			return;
		}
		characterAsh.SetMoveDir(dir);
		characterAsh.SetRun(run);
		characterAsh.SetWalk(!run);
	}

	private void LookTowards(Vector3 dir)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		dir.y = 0f;
		if (!(((Vector3)(ref dir)).sqrMagnitude < 0.001f))
		{
			((Vector3)(ref dir)).Normalize();
			((Component)this).transform.rotation = Quaternion.LookRotation(dir, Vector3.up);
		}
	}

	private bool IsLookingTowards(Vector3 dir, float minAngle)
	{
		//IL_0031: 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)
		dir.y = 0f;
		if (((Vector3)(ref dir)).sqrMagnitude < 0.001f)
		{
			return true;
		}
		((Vector3)(ref dir)).Normalize();
		float num = Vector3.Angle(((Component)this).transform.forward, dir);
		return num <= minAngle;
	}

	protected bool FindPath(Vector3 target)
	{
		//IL_0026: 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_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: 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)
		float time = Time.time;
		float num = time - m_lastFindPathTime;
		if (num < 1f)
		{
			return m_lastFindPathResult;
		}
		if (Vector3.Distance(target, m_lastFindPathTarget) < 1f && num < 5f)
		{
			return m_lastFindPathResult;
		}
		m_lastFindPathTarget = target;
		m_lastFindPathTime = time;
		m_lastFindPathResult = Pathfinding.instance.GetPath(((Component)this).transform.position, target, m_path, (AgentType)1, false, true, false);
		return m_lastFindPathResult;
	}

	private float DistanceXZ(Vector3 a, Vector3 b)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: 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)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		float num = a.x - b.x;
		float num2 = a.z - b.z;
		return Mathf.Sqrt(num * num + num2 * num2);
	}

	private void ChopTrees()
	{
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		if (chopAnalysisInProgress)
		{
			return;
		}
		chopAnalysisInProgress = true;
		AshStop();
		if ((Object)(object)currentTreeLogTarget == (Object)null && (Object)(object)currentStumpTarget == (Object)null && (Object)(object)currentTreeTarget == (Object)null && !FindChopTarget())
		{
			chopAnalysisInProgress = false;
			return;
		}
		TreeLog val = currentTreeLogTarget;
		Destructible val2 = currentStumpTarget;
		TreeBase val3 = currentTreeTarget;
		Transform val4 = null;
		if ((Object)(object)val != (Object)null)
		{
			val4 = ((Component)val).transform;
		}
		else if ((Object)(object)val2 != (Object)null)
		{
			val4 = ((Component)val2).transform;
		}
		else
		{
			if (!((Object)(object)val3 != (Object)null))
			{
				currentTreeTarget = null;
				currentTreeLogTarget = null;
				currentStumpTarget = null;
				treeTargetCounter = 0;
				chopAnalysisInProgress = false;
				return;
			}
			val4 = ((Component)val3).transform;
		}
		Vector3 val5 = val4.position - ((Component)this).transform.position;
		val5.y = 0f;
		if (((Vector3)(ref val5)).sqrMagnitude < 0.01f)
		{
			chopAnalysisInProgress = false;
			return;
		}
		((Character)humanoidAsh).SetLookDir(((Vector3)(ref val5)).normalized, 0f);
		LookTowards(((Vector3)(ref val5)).normalized);
		if ((Object)(object)currentTreeLogTarget == (Object)null)
		{
			if ((Object)(object)currentStumpTarget != (Object)null)
			{
				if (!AdjustAim(val2))
				{
					currentStumpTarget = null;
				}
			}
			else if ((Object)(object)currentTreeTarget != (Object)null && !AdjustAim(val3))
			{
				currentTreeTarget = null;
				treeTargetCounter = 0;
				chopAnalysisInProgress = false;
				return;
			}
		}
		else if (!AdjustAim(val))
		{
			currentTreeLogTarget = null;
		}
		((Character)humanoidAsh).StartAttack((Character)null, false);
		chopAnalysisInProgress = false;
		treeTargetCounter++;
		Debug.Log((object)("ASH CHOP: Fired at " + ((Object)val4).name + " | " + $"Successful shots at target = {treeTargetCounter}/5"));
		if (treeTargetCounter >= 5)
		{
			Debug.Log((object)("ASH CHOP: 5 shots completed at " + ((Object)val4).name + " | Re-evaluating target."));
			currentTreeTarget = null;
			treeTargetCounter = 0;
			chopAnalysisInProgress = false;
		}
	}

	private bool FindChopTarget()
	{
		float[] array = new float[6] { 10f, 20f, 30f, 40f, 50f, 60f };
		float[] array2 = array;
		foreach (float num in array2)
		{
			TreeLog val = FindClosestTreeLog(num);
			if ((Object)(object)val != (Object)null)
			{
				currentTreeLogTarget = val;
				currentStumpTarget = null;
				currentTreeTarget = null;
				treeTargetCounter = 0;
				Debug.Log((object)($"ASH CHOP TARGET: TreeLog found within {num}m | " + "Target=" + ((Object)val).name));
				return true;
			}
			TreeBase val2 = FindClosestTree(num);
			if ((Object)(object)val2 != (Object)null)
			{
				currentTreeLogTarget = null;
				currentStumpTarget = null;
				currentTreeTarget = val2;
				treeTargetCounter = 0;
				Debug.Log((object)($"ASH CHOP TARGET: Tree found within {num}m | " + "Target=" + ((Object)val2).name));
				return true;
			}
		}
		currentTreeLogTarget = null;
		currentStumpTarget = null;
		currentTreeTarget = null;
		treeTargetCounter = 0;
		Debug.Log((object)"ASH CHOP TARGET: No logs or trees found within 60m.");
		return false;
	}

	private TreeBase FindClosestTree(float maxDistance)
	{
		//IL_0007: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		int num = Physics.OverlapSphereNonAlloc(((Component)this).transform.position, maxDistance, m_treeOverlapResults);
		TreeBase result = null;
		float num2 = maxDistance * maxDistance;
		for (int i = 0; i < num; i++)
		{
			Collider val = m_treeOverlapResults[i];
			if ((Object)(object)val == (Object)null || ignoredChopColliders.Contains(val))
			{
				continue;
			}
			string text = ((Object)val).name.ToLowerInvariant();
			if (text == "viewblock" || text == "viewblocker")
			{
				continue;
			}
			TreeBase componentInParent = ((Component)val).GetComponentInParent<TreeBase>();
			if (!((Object)(object)componentInParent == (Object)null))
			{
				Bounds bounds = val.bounds;
				Vector3 val2 = ((Bounds)(ref bounds)).ClosestPoint(((Component)this).transform.position);
				Vector3 val3 = val2 - ((Component)this).transform.position;
				float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
				if (sqrMagnitude < num2)
				{
					num2 = sqrMagnitude;
					result = componentInParent;
				}
			}
		}
		return result;
	}

	private TreeLog FindClosestTreeLog(float maxDistance)
	{
		//IL_0007: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		int num = Physics.OverlapSphereNonAlloc(((Component)this).transform.position, maxDistance, m_treeOverlapResults);
		TreeLog result = null;
		float num2 = maxDistance * maxDistance;
		for (int i = 0; i < num; i++)
		{
			Collider val = m_treeOverlapResults[i];
			if ((Object)(object)val == (Object)null || ignoredChopColliders.Contains(val))
			{
				continue;
			}
			string text = ((Object)val).name.ToLowerInvariant();
			if (text == "viewblock" || text == "viewblocker")
			{
				continue;
			}
			TreeLog componentInParent = ((Component)val).GetComponentInParent<TreeLog>();
			if (!((Object)(object)componentInParent == (Object)null))
			{
				Bounds bounds = val.bounds;
				Vector3 val2 = ((Bounds)(ref bounds)).ClosestPoint(((Component)this).transform.position);
				Vector3 val3 = val2 - ((Component)this).transform.position;
				float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
				if (sqrMagnitude < num2)
				{
					num2 = sqrMagnitude;
					result = componentInParent;
				}
			}
		}
		return result;
	}

	private Destructible FindClosestStump(float maxDistance)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: 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_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: 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)
		int num = Physics.OverlapSphereNonAlloc(((Component)this).transform.position, maxDistance, m_treeOverlapResults);
		Destructible result = null;
		float num2 = maxDistance * maxDistance;
		for (int i = 0; i < num; i++)
		{
			Collider val = m_treeOverlapResults[i];
			if ((Object)(object)val == (Object)null || ignoredChopColliders.Contains(val))
			{
				continue;
			}
			string text = ((Object)val).name.ToLowerInvariant();
			if (text == "viewblock" || text == "viewblocker")
			{
				continue;
			}
			Destructible componentInParent = ((Component)val).GetComponentInParent<Destructible>();
			if (!((Object)(object)componentInParent == (Object)null) && ((Object)componentInParent).name.ToLowerInvariant().Contains("stump"))
			{
				Bounds bounds = val.bounds;
				Vector3 val2 = ((Bounds)(ref bounds)).ClosestPoint(((Component)this).transform.position);
				Vector3 val3 = val2 - ((Component)this).transform.position;
				float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
				if (sqrMagnitude < num2)
				{
					num2 = sqrMagnitude;
					result = componentInParent;
				}
			}
		}
		return result;
	}

	public bool IsChopping()
	{
		return AshMode == "ASH_MODE_CHOP";
	}

	private string GetMasterOrMistressTitle()
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return "Master";
		}
		return (localPlayer.GetPlayerModel() == 1) ? "Mistress" : "Master";
	}
}
public static class AshAIHelper
{
	private static readonly FieldRef<MonsterAI, Character> TargetField = AccessTools.FieldRefAccess<MonsterAI, Character>("m_targetCreature");

	private static readonly FieldRef<MonsterAI, StaticTarget> StaticTargetField = AccessTools.FieldRefAccess<MonsterAI, StaticTarget>("m_targetStatic");

	public static void SetAshTarget(MonsterAI ai, Character target)
	{
		if (!((Object)(object)ai == (Object)null) && !((Object)(object)target == (Object)null))
		{
			TargetField.Invoke(ai) = target;
			StaticTargetField.Invoke(ai) = null;
		}
	}

	public static void ClearTarget(MonsterAI ai)
	{
		if (!((Object)(object)ai == (Object)null))
		{
			TargetField.Invoke(ai) = null;
		}
	}

	public static void TestHarmony()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		Harmony val = new Harmony("AshValheimMod.Test");
		Debug.Log((object)("Harmony loaded successfully: " + val.Id));
	}
}
public class AshButtonUI : MonoBehaviour
{
	private bool panelOpen = false;

	private const float PANEL_WIDTH = 900f;

	private const float PANEL_HEIGHT = 180f;

	private const float BUTTON_SIZE = 120f;

	private const float BUTTON_GAP = 20f;

	private readonly string[] buttonNames = new string[6] { "SUMMON", "GUARD", "SENTINEL", "CHOP", "STOP", "DISPERSE" };

	private readonly string[] resourcePaths = new string[6] { "AshValheimMod.Assets.Icons.summon.png", "AshValheimMod.Assets.Icons.guard.png", "AshValheimMod.Assets.Icons.sentinel.png", "AshValheimMod.Assets.Icons.chop.png", "AshValheimMod.Assets.Icons.stop.png", "AshValheimMod.Assets.Icons.disperse.png" };

	private GameObject panel;

	private void Update()
	{
		if (!IsSafe())
		{
			return;
		}
		if (Input.GetKey((KeyCode)308) && Input.GetKeyDown((KeyCode)121))
		{
			Debug.Log((object)"ASH BUTTON UI: ALT+Y DETECTED!");
			panelOpen = !panelOpen;
			if ((Object)(object)panel == (Object)null)
			{
				CreatePanel();
			}
			if ((Object)(object)panel != (Object)null)
			{
				panel.SetActive(panelOpen);
			}
			GUIManager.BlockInput(panelOpen);
			Debug.Log((object)("ASH BUTTON UI: Panel " + (panelOpen ? "OPENED" : "CLOSED")));
		}
		if (panelOpen && Input.GetKeyDown((KeyCode)27))
		{
			Debug.Log((object)"ASH BUTTON UI: ESC DETECTED — CLOSING PANEL!");
			panelOpen = false;
			if ((Object)(object)panel != (Object)null)
			{
				panel.SetActive(false);
			}
			GUIManager.BlockInput(false);
			Debug.Log((object)"ASH BUTTON UI: Panel CLOSED by ESC");
		}
	}

	private void CreatePanel()
	{
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		Debug.Log((object)"ASH BUTTON UI: CreatePanel()");
		if (GUIManager.Instance == null)
		{
			Debug.LogError((object)"ASH BUTTON UI: GUIManager.Instance is NULL");
			return;
		}
		if ((Object)(object)GUIManager.CustomGUIFront == (Object)null)
		{
			Debug.LogError((object)"ASH BUTTON UI: GUIManager.CustomGUIFront is NULL");
			return;
		}
		Debug.Log((object)"ASH BUTTON UI: Jotunn GUIManager is available.");
		panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 900f, 180f, true);
		if ((Object)(object)panel == (Object)null)
		{
			Debug.LogError((object)"ASH BUTTON UI: Failed to create Jotunn wood panel.");
			return;
		}
		((Object)panel).name = "AshModePanel";
		Debug.Log((object)"ASH BUTTON UI: Created Jotunn Ash Mode panel.");
		for (int i = 0; i < buttonNames.Length; i++)
		{
			CreateButton(panel.transform, buttonNames[i], resourcePaths[i], i);
		}
	}

	private void CreateButton(Transform parent, string buttonName, string resourcePath, int index)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Expected O, but got Unknown
		GameObject val = new GameObject("AshButton_" + buttonName);
		val.transform.SetParent(parent, false);
		RectTransform val2 = val.AddComponent<RectTransform>();
		val2.anchorMin = new Vector2(0.5f, 0.5f);
		val2.anchorMax = new Vector2(0.5f, 0.5f);
		val2.pivot = new Vector2(0.5f, 0.5f);
		val2.sizeDelta = new Vector2(120f, 120f);
		float num = (float)buttonNames.Length * 120f + (float)(buttonNames.Length - 1) * 20f;
		float num2 = 0f - num / 2f + 60f;
		val2.anchoredPosition = new Vector2(num2 + (float)index * 140f, 0f);
		Image val3 = val.AddComponent<Image>();
		Sprite val4 = LoadSprite(resourcePath);
		if ((Object)(object)val4 == (Object)null)
		{
			Debug.LogError((object)("ASH BUTTON UI: Failed to load sprite: " + resourcePath));
			Object.Destroy((Object)(object)val);
			return;
		}
		val3.sprite = val4;
		val3.preserveAspect = true;
		((Graphic)val3).raycastTarget = true;
		Button val5 = val.AddComponent<Button>();
		((Selectable)val5).targetGraphic = (Graphic)(object)val3;
		int capturedIndex = index;
		((UnityEvent)val5.onClick).AddListener((UnityAction)delegate
		{
			OnButtonClicked(capturedIndex);
		});
		Debug.Log((object)("ASH BUTTON UI: Created " + buttonName + " button."));
	}

	private Sprite LoadSprite(string resourcePath)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		Texture2D iconFromResourceAsTexture = AshIconHelper.GetIconFromResourceAsTexture(resourcePath);
		if ((Object)(object)iconFromResourceAsTexture == (Object)null)
		{
			Debug.LogError((object)("ASH BUTTON UI: Failed to load embedded resource: " + resourcePath));
			return null;
		}
		Sprite val = Sprite.Create(iconFromResourceAsTexture, new Rect(0f, 0f, (float)((Texture)iconFromResourceAsTexture).width, (float)((Texture)iconFromResourceAsTexture).height), new Vector2(0.5f, 0.5f));
		((Object)val).name = ((Object)iconFromResourceAsTexture).name + "_Sprite";
		return val;
	}

	private void OnButtonClicked(int index)
	{
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		switch (index)
		{
		case 0:
		{
			Debug.Log((object)"ASH BUTTON UI: SUMMON clicked.");
			if (!IsSafe())
			{
				break;
			}
			List<Character> nearbySummons = AshCharacters.GetNearbySummons();
			foreach (Character item in nearbySummons)
			{
				if (!((Object)(object)item == (Object)null) && item.IsOwner())
				{
					AshAI component = ((Component)item).GetComponent<AshAI>();
					if (!((Object)(object)component == (Object)null))
					{
						AshDeath.DeathByZNetScene(item);
					}
				}
			}
			int bloodMagicSkillFactor = GetBloodMagicSkillFactor();
			AllySummon.CharredSpawn("Charred_Archer", AshHelpers.PlayerSummoningPosition(), bloodMagicSkillFactor);
			break;
		}
		case 1:
			Debug.Log((object)"ASH BUTTON UI: GUARD clicked.");
			if (IsSafe())
			{
				SetAshAiMode("ASH_MODE_GUARD");
			}
			break;
		case 2:
			Debug.Log((object)"ASH BUTTON UI: SENTINEL clicked.");
			if (IsSafe())
			{
				SetAshAiMode("ASH_MODE_SENTINEL");
			}
			break;
		case 3:
			Debug.Log((object)"ASH BUTTON UI: CHOP clicked.");
			if (IsSafe())
			{
				SetAshAiMode("ASH_MODE_CHOP");
			}
			break;
		case 4:
			Debug.Log((object)"ASH BUTTON UI: STOP clicked.");
			if (IsSafe())
			{
				SetAshAiMode("ASH_MODE_STOP");
			}
			break;
		case 5:
			Debug.Log((object)"ASH BUTTON UI: DISPERSE clicked.");
			if (IsSafe())
			{
				AshDeath.DeleteAsh();
			}
			break;
		}
	}

	private void SetAshAiMode(string mode)
	{
		List<Character> allCharacters = Character.GetAllCharacters();
		foreach (Character item in allCharacters)
		{
			if (!((Object)(object)item == (Object)null))
			{
				AshAI component = ((Component)item).GetComponent<AshAI>();
				if (!((Object)(object)component == (Object)null) && item.IsOwner())
				{
					component.AshMode = mode;
				}
			}
		}
	}

	private bool IsSafe()
	{
		if (!AshSceneUtility.IsScene(AshSceneUtility.GameScenes.Main))
		{
			return false;
		}
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			return false;
		}
		return true;
	}

	private int GetBloodMagicSkillFactor()
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return 0;
		}
		Skills skills = ((Character)localPlayer).GetSkills();
		if ((Object)(object)skills == (Object)null)
		{
			return 0;
		}
		return Mathf.FloorToInt(skills.GetSkillLevel((SkillType)10));
	}
}
public class AshCharacters
{
	public static void ResetCharacterGroup(GameObject summonObject, string group)
	{
		Character component = summonObject.GetComponent<Character>();
		ResetCharacterGroup(component, group);
	}

	public static void ResetCharacterGroup(Character characterComponent, string group)
	{
		if ((Object)(object)characterComponent != (Object)null)
		{
			characterComponent.m_group = group;
		}
	}

	public static void ResetCharacterFaction(GameObject summonObject, Faction faction)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		Character component = summonObject.GetComponent<Character>();
		ResetCharacterFaction(component, faction);
	}

	public static void ResetCharacterFaction(Character characterComponent, Faction faction)
	{
		//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)
		if ((Object)(object)characterComponent != (Object)null)
		{
			characterComponent.m_faction = faction;
		}
	}

	public static void SetCreatureStars(GameObject summonObject, int stars)
	{
		Character component = summonObject.GetComponent<Character>();
		SetCreatureStars(component, stars);
	}

	public static void SetCreatureStars(Character creatureComponent, int stars)
	{
		if ((Object)(object)creatureComponent != (Object)null)
		{
			stars = Mathf.Clamp(stars, 0, 9);
			creatureComponent.SetLevel(stars);
		}
	}

	public static void IncreaseCreatureStars(GameObject summonObject)
	{
		Character component = summonObject.GetComponent<Character>();
		if ((Object)(object)component != (Object)null)
		{
			int level = component.GetLevel();
			SetCreatureStars(component, level + 1);
		}
	}

	public static void DecreaseCreatureStars(GameObject summonObject)
	{
		Character component = summonObject.GetComponent<Character>();
		if ((Object)(object)component != (Object)null)
		{
			int level = component.GetLevel();
			SetCreatureStars(component, level - 1);
		}
	}

	public static List<Character> GetNearbySummons()
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		List<Character> list = new List<Character>();
		Player localPlayer = Player.m_localPlayer;
		Character val = ((localPlayer != null) ? ((Component)localPlayer).GetComponent<Character>() : null);
		if ((Object)(object)val == (Object)null)
		{
			Logger.LogWarning((object)"Local player character not found.");
			return list;
		}
		Vector3 position = ((Component)val).transform.position;
		float num = 80f;
		Collider[] array = Physics.OverlapSphere(position, num, LayerMask.GetMask(new string[1] { "character" }));
		Collider[] array2 = array;
		foreach (Collider val2 in array2)
		{
			Character component = ((Component)val2).GetComponent<Character>();
			if (!((Object)(object)component == (Object)null) && !((Object)(object)component == (Object)(object)val) && ((Component)component).gameObject.activeInHierarchy && component.IsOwner())
			{
				ZDO zDO = ((Component)component).GetComponent<ZNetView>().GetZDO();
				if (zDO != null && zDO.GetBool("AshSummon", false))
				{
					list.Add(component);
				}
			}
		}
		return list;
	}

	public static Character GetCharacterWithLowestHealth()
	{
		Character result = null;
		float num = float.MaxValue;
		List<Character> nearbySummons = GetNearbySummons();
		if (nearbySummons == null || nearbySummons.Count == 0)
		{
			return null;
		}
		foreach (Character item in nearbySummons)
		{
			AshAI component = ((Component)item).GetComponent<AshAI>();
			if (!((Object)(object)component == (Object)null) && ((Character)Player.m_localPlayer).GetOwner() == item.GetOwner() && item.m_health < num)
			{
				num = item.m_health;
				result = item;
			}
		}
		return result;
	}
}
public static class AshColor
{
	public static readonly Color NecromancerTeal = HexToColor("#1DFCE1");

	public static readonly Color NecromancerPurple = HexToColor("#9B30FF");

	public static readonly Color NecromancerRed = HexToColor("#FF4500");

	public static readonly Color NecromancerGreenDark = HexToColor("#006400");

	public static readonly Color NecromancerGreen = HexToColor("#32CD32");

	public static readonly Color NecromancerBlue = HexToColor("#4682B4");

	public static readonly Color NecromancerOrange = HexToColor("#FF8C00");

	public static readonly Color NecromancerYellow = HexToColor("#FFD700");

	public static readonly Color Novice = HexToColor("#EBE298");

	public static readonly Color Apprentice = HexToColor("#FFC584");

	public static readonly Color Adept = HexToColor("#A0E689");

	public static readonly Color Proficient = HexToColor("#95E8D7");

	public static readonly Color Expert = HexToColor("#9AC6E9");

	public static readonly Color Master = HexToColor("#4A3DFF");

	public static readonly Color Grandmaster = HexToColor("#8325FF");

	public static readonly Color Legendary = HexToColor("#CF0000");

	public static readonly Color Mythic = HexToColor("#4EAC4D");

	public static readonly Color Ascendant = HexToColor("#00CFA8");

	public static readonly Color DefaultSlotColor = new Color(0.3f, 0.3f, 0.3f, 0.6f);

	public static readonly Color HoverSlotColor = new Color(0.5f, 0.5f, 0.5f, 0.6f);

	public static Color NecromancerColor { get; set; }

	public static Color HexToColor(string hex)
	{
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		hex = hex.Replace("#", "");
		byte b = Convert.ToByte(hex.Substring(0, 2), 16);
		byte b2 = Convert.ToByte(hex.Substring(2, 2), 16);
		byte b3 = Convert.ToByte(hex.Substring(4, 2), 16);
		return new Color((float)(int)b / 255f, (float)(int)b2 / 255f, (float)(int)b3 / 255f);
	}

	public static void ModifyPrefabColor(GameObject prefab, Color color)
	{
		//IL_0048: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Expected O, but got Unknown
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)prefab == (Object)null)
		{
			return;
		}
		bool flag = false;
		Renderer component = prefab.GetComponent<Renderer>();
		if ((Object)(object)component != (Object)null)
		{
			Material material = component.material;
			if ((Object)(object)material != (Object)null)
			{
				material.SetColor("_Color", color);
			}
		}
		Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
		Renderer[] array = componentsInChildren;
		foreach (Renderer val in array)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Material[] sharedMaterials = val.sharedMaterials;
			if (sharedMaterials == null)
			{
				continue;
			}
			Material[] array2 = (Material[])(object)new Material[sharedMaterials.Length];
			for (int j = 0; j < sharedMaterials.Length; j++)
			{
				Material val2 = sharedMaterials[j];
				if ((Object)(object)val2 == (Object)null)
				{
					array2[j] = null;
					continue;
				}
				Material val3 = new Material(val2)
				{
					color = color
				};
				if ((Object)(object)val3 != (Object)null)
				{
					val3.SetColor("_Color", color);
					array2[j] = val3;
				}
			}
			val.sharedMaterials = array2;
		}
	}

	public static void ModifyPrefabPrimaryColor(GameObject prefab, Color color)
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)prefab == (Object)null)
		{
			return;
		}
		Renderer[] components = prefab.GetComponents<Renderer>();
		Renderer[] array = components;
		foreach (Renderer val in array)
		{
			Material[] sharedMaterials = val.sharedMaterials;
			Material[] array2 = sharedMaterials;
			foreach (Material val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					val2.color = color;
					val2.SetColor("_Color", color);
					val2.SetColor("_BaseColor", color);
				}
			}
		}
	}

	public static Color GetColorByName(string colorName)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: 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)
		if (!(colorName == "NecromancerTeal"))
		{
			if (colorName == "NecromancerPurple")
			{
				return NecromancerPurple;
			}
			return NecromancerTeal;
		}
		return NecromancerTeal;
	}

	public static void ApplyNecromancerColorToFlames(ParticleSystem flameSystem)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: 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_000f: Unknown result type (might be due to invalid IL or missing references)
		MainModule main = flameSystem.main;
		((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(NecromancerColor);
	}
}
public static class AshDeath
{
	public static void DeleteNearbySummons()
	{
		List<Character> nearbySummons = AshCharacters.GetNearbySummons();
		foreach (Character item in nearbySummons)
		{
			DeathByZNetScene(item);
		}
		Logger.LogInfo((object)"Deleted nearby summons.");
	}

	public static void DeleteAsh()
	{
		List<Character> allCharacters = Character.GetAllCharacters();
		foreach (Character item in allCharacters)
		{
			if ((Object)(object)item == (Object)null || !item.IsOwner())
			{
				continue;
			}
			AshAI component = ((Component)item).GetComponent<AshAI>();
			if (!((Object)(object)component == (Object)null))
			{
				AshSummonTracker component2 = ((Component)item).GetComponent<AshSummonTracker>();
				if (!((Object)(object)component2 == (Object)null))
				{
					component2.WasAshDispersed = true;
					DeathByZNetScene(item);
				}
			}
		}
		Logger.LogInfo((object)"Ash Dispersed.");
	}

	public static void DeathByDamage(Character character)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: 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_007c: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)character == (Object)null) && !((Object)(object)((Component)character).gameObject == (Object)null))
		{
			AshAI component = ((Component)character).gameObject.GetComponent<AshAI>();
			if (!((Object)(object)component == (Object)null))
			{
				HitData val = new HitData();
				val.m_damage.m_blunt = float.MaxValue;
				val.m_damage.m_damage = float.MaxValue;
				val.m_point = ((Component)character).transform.position;
				val.m_dir = Vector3.up;
				Logger.LogInfo((object)("Darkbound DeathByDamage applying to " + ((Object)character).name));
				character.ApplyDamage(val, true, true, (DamageModifier)0);
			}
		}
	}

	public static void DeathByZNetScene(Character character)
	{
		Character component = ((Component)Player.m_localPlayer).GetComponent<Character>();
		if (!((Object)(object)character == (Object)(object)component))
		{
			ZNetScene.instance.Destroy(((Component)character).gameObject);
		}
	}

	public static void LowerBloodMagicOneLevel()
	{
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return;
		}
		Skills skills = ((Character)localPlayer).GetSkills();
		if (!((Object)(object)skills == (Object)null))
		{
			float skillLevel = skills.GetSkillLevel((SkillType)10);
			int num = Mathf.Max(0, Mathf.FloorToInt(skillLevel) - 1);
			Debug.Log((object)$"ASH DEATH: Blood Magic {skillLevel:0.##} -> {num}");
			skills.ResetSkill((SkillType)10);
			if (num > 0)
			{
				skills.CheatRaiseSkill(((object)(SkillType)10/*cast due to .constrained prefix*/).ToString(), (float)num, false);
			}
			float skillLevel2 = skills.GetSkillLevel((SkillType)10);
			Debug.Log((object)$"ASH DEATH: Blood Magic after reduction = {skillLevel2:0.##}");
		}
	}
}
public class AshDeathWatcher : MonoBehaviour
{
	private Character target;

	private Character ash;

	private Character lastAttacker;

	public void Initialize(Character ashCharacter)
	{
		target = ((Component)this).GetComponent<Character>();
		ash = ashCharacter;
		Debug.Log((object)("ASH DEATH WATCHER: Initialize | Target=" + target?.m_name + " | Ash=" + ash?.m_name));
		if ((Object)(object)target == (Object)null || (Object)(object)ash == (Object)null)
		{
			Debug.Log((object)"ASH DEATH WATCHER: Initialize FAILED");
			return;
		}
		Character obj = target;
		obj.m_onDamaged = (Action<float, Character>)Delegate.Combine(obj.m_onDamaged, new Action<float, Character>(OnDamaged));
		Character obj2 = target;
		obj2.m_onDeath = (Action)Delegate.Combine(obj2.m_onDeath, new Action(OnDeath));
		Debug.Log((object)("ASH DEATH WATCHER: Subscribed to " + target.m_name));
	}

	private void OnDamaged(float damage, Character attacker)
	{
		if ((Object)(object)attacker != (Object)null)
		{
			lastAttacker = attacker;
			Debug.Log((object)("ASH DEATH WATCHER: DAMAGE | Target=" + target?.m_name + " | " + $"Damage={damage:0.##} | " + "Attacker=" + attacker.m_name));
		}
		else
		{
			Debug.Log((object)("ASH DEATH WATCHER: DAMAGE | Target=" + target?.m_name + " | " + $"Damage={damage:0.##} | " + "Attacker=NULL | Keeping previous attacker=" + (lastAttacker?.m_name ?? "NULL")));
		}
	}

	private void OnDeath()
	{
		Debug.Log((object)("ASH DEATH WATCHER: DEATH | Target=" + target?.m_name + " | LastAttacker=" + (lastAttacker?.m_name ?? "NULL") + " | Ash=" + (ash?.m_name ?? "NULL")));
		if ((Object)(object)target == (Object)null || (Object)(object)ash == (Object)null)
		{
			Debug.Log((object)"ASH DEATH WATCHER: DEATH ABORTED - target or ash NULL");
			return;
		}
		if ((Object)(object)lastAttacker == (Object)null)
		{
			Debug.Log((object)"ASH DEATH WATCHER: DEATH ABORTED - no last attacker");
			return;
		}
		if ((Object)(object)lastAttacker != (Object)(object)ash)
		{
			Debug.Log((object)("ASH DEATH WATCHER: DEATH ABORTED - attacker was " + lastAttacker.m_name + ", not Ash"));
			return;
		}
		Debug.Log((object)("ASH DEATH WATCHER: *** ASH KILLED " + target.m_name + " ***"));
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			Debug.Log((object)"ASH DEATH WATCHER: No local player");
			return;
		}
		Skills skills = ((Character)localPlayer).GetSkills();
		if ((Object)(object)skills == (Object)null)
		{
			Debug.Log((object)"ASH DEATH WATCHER: Player has no Skills");
			return;
		}
		float num = CalculateBloodMagicXP(target);
		skills.RaiseSkill((SkillType)10, num);
		AshMessageUI.Instance.Show($"{num:0.#} XP gained");
		if ((Object)(object)MessageHud.instance != (Object)null)
		{
			MessageHud.instance.ShowMessage((MessageType)2, $"{num:0.#} XP gained", 0, (Sprite)null, false, true);
		}
		Debug.Log((object)("ASH DEATH WATCHER: " + target.m_name + " awarded " + $"{num:0.#} Blood Magic XP"));
	}

	private float CalculateBloodMagicXP(Character victim)
	{
		if ((Object)(object)victim == (Object)null)
		{
			return 0f;
		}
		float maxHealth = victim.GetMaxHealth();
		return Mathf.Max(1f, maxHealth * 0.05f);
	}

	private void OnDestroy()
	{
		if ((Object)(object)target != (Object)null)
		{
			Character obj = target;
			obj.m_onDamaged = (Action<float, Character>)Delegate.Remove(obj.m_onDamaged, new Action<float, Character>(OnDamaged));
			Character obj2 = target;
			obj2.m_onDeath = (Action)Delegate.Remove(obj2.m_onDeath, new Action(OnDeath));
		}
		Debug.Log((object)("ASH DEATH WATCHER: Destroyed | Target=" + target?.m_name));
	}
}
public class AshHelpers
{
	public static Vector3 PlayerSummoningPositionBehind()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: 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)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: 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_00e4: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		Vector3? obj;
		if (localPlayer == null)
		{
			obj = null;
		}
		else
		{
			Transform transform = ((Component)localPlayer).transform;
			obj = ((transform != null) ? new Vector3?(transform.position) : ((Vector3?)null));
		}
		Vector3? val = obj;
		Player localPlayer2 = Player.m_localPlayer;
		Vector3? obj2;
		if (localPlayer2 == null)
		{
			obj2 = null;
		}
		else
		{
			Transform transform2 = ((Component)localPlayer2).transform;
			Vector3? val2 = ((transform2 != null) ? new Vector3?(transform2.forward) : ((Vector3?)null));
			float num = -3f;
			obj2 = (val2.HasValue ? new Vector3?(val2.GetValueOrDefault() * num) : ((Vector3?)null));
		}
		Vector3? val3 = obj2;
		return (Vector3)(((??)((val.HasValue & val3.HasValue) ? new Vector3?(val.GetValueOrDefault() + val3.GetValueOrDefault()) : ((Vector3?)null))) ?? Vector3.zero);
	}

	public static Vector3 PlayerSummoningPosition()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		Vector3? obj;
		if (localPlayer == null)
		{
			obj = null;
		}
		else
		{
			Transform transform = ((Component)localPlayer).transform;
			obj = ((transform != null) ? new Vector3?(transform.position) : ((Vector3?)null));
		}
		Vector3? val = obj;
		Player localPlayer2 = Player.m_localPlayer;
		Vector3? obj2;
		if (localPlayer2 == null)
		{
			obj2 = null;
		}
		else
		{
			Transform transform2 = ((Component)localPlayer2).transform;
			Vector3? val2 = ((transform2 != null) ? new Vector3?(transform2.forward) : ((Vector3?)null));
			float num = 3f;
			obj2 = (val2.HasValue ? new Vector3?(val2.GetValueOrDefault() * num) : ((Vector3?)null));
		}
		Vector3? val3 = obj2;
		return (Vector3)(((??)((val.HasValue & val3.HasValue) ? new Vector3?(val.GetValueOrDefault() + val3.GetValueOrDefault()) : ((Vector3?)null))) ?? Vector3.zero);
	}

	public static Vector3 PlayerPosition()
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		Vector3? obj;
		if (localPlayer == null)
		{
			obj = null;
		}
		else
		{
			Transform transform = ((Component)localPlayer).transform;
			obj = ((transform != null) ? new Vector3?(transform.position) : ((Vector3?)null));
		}
		return (Vector3)(((??)obj) ?? Vector3.zero);
	}

	public static Vector3 PlayerHeadPosition()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		Vector3? obj;
		if (localPlayer == null)
		{
			obj = null;
		}
		else
		{
			Transform transform = ((Component)localPlayer).transform;
			obj = ((transform != null) ? new Vector3?(transform.position) : ((Vector3?)null));
		}
		Vector3? val = obj;
		Player localPlayer2 = Player.m_localPlayer;
		Vector3? obj2;
		if (localPlayer2 == null)
		{
			obj2 = null;
		}
		else
		{
			Transform transform2 = ((Component)localPlayer2).transform;
			Vector3? val2 = ((transform2 != null) ? new Vector3?(transform2.up) : ((Vector3?)null));
			float num = 2f;
			obj2 = (val2.HasValue ? new Vector3?(val2.GetValueOrDefault() * num) : ((Vector3?)null));
		}
		Vector3? val3 = obj2;
		return (Vector3)(((??)((val.HasValue & val3.HasValue) ? new Vector3?(val.GetValueOrDefault() + val3.GetValueOrDefault()) : ((Vector3?)null))) ?? Vector3.zero);
	}

	public static void ScaleHierarchy(Transform parent, float scaleMultiplier)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Expected O, but got Unknown
		parent.localScale *= scaleMultiplier;
		foreach (Transform item in parent)
		{
			Transform parent2 = item;
			ScaleHierarchy(parent2, scaleMultiplier);
		}
	}

	public static void ScaleRenderableComponents(Transform root, float scaleMultiplier)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>();
		foreach (Renderer val in componentsInChildren)
		{
			Transform transform = ((Component)val).transform;
			transform.localScale *= scaleMultiplier;
		}
	}
}
public static class AshIconHelper
{
	public static Sprite GetIconFromResourceAsSprite(string iconResourceName)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		Sprite result = null;
		Texture2D iconFromResourceAsTexture = GetIconFromResourceAsTexture(iconResourceName);
		if ((Object)(object)iconFromResourceAsTexture != (Object)null)
		{
			result = Sprite.Create(iconFromResourceAsTexture, new Rect(0f, 0f, (float)((Texture)iconFromResourceAsTexture).width, (float)((Texture)iconFromResourceAsTexture).height), new Vector2(0.5f, 0.5f));
		}
		return result;
	}

	public static Texture2D GetIconFromResourceAsTexture(string resourceName)
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Expected O, but got Unknown
		Assembly executingAssembly = Assembly.GetExecutingAssembly();
		using Stream stream = executingAssembly.GetManifestResourceStream(resourceName);
		if (stream == null)
		{
			return null;
		}
		byte[] array = new byte[stream.Length];
		stream.Read(array, 0, array.Length);
		Texture2D val = new Texture2D(2, 2);
		return AssetUtils.LoadImage(array);
	}
}
public class AshMessageUI : MonoBehaviour
{
	private TMP_Text messageText;

	private float messageTimer;

	private const float MESSAGE_DURATION = 5f;

	public static AshMessageUI Instance { get; private set; }

	private void Awake()
	{
		if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		Instance = this;
		Debug.Log((object)"ASH MESSAGE UI: Awake");
	}

	private void Start()
	{
		((MonoBehaviour)this).StartCoroutine(InitializeUI());
	}

	private IEnumerator InitializeUI()
	{
		while ((Object)(object)Hud.instance == (Object)null || (Object)(object)MessageHud.instance == (Object)null || (Object)(object)MessageHud.instance.m_messageCenterText == (Object)null)
		{
			yield return null;
		}
		Debug.Log((object)"ASH MESSAGE UI: Valheim HUD and MessageHud are ready");
		CreateMessageObject();
	}

	private void CreateMessageObject()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		TMP_Text messageCenterText = MessageHud.instance.m_messageCenterText;
		if ((Object)(object)messageCenterText == (Object)null)
		{
			Debug.LogError((object)"ASH MESSAGE UI: Could not obtain MessageHud center text.");
			return;
		}
		GameObject val = new GameObject("AshMessage");
		val.transform.SetParent(((Component)Hud.instance).transform, false);
		RectTransform val2 = val.AddComponent<RectTransform>();
		val2.anchorMin = new Vector2(0f, 0.3f);
		val2.anchorMax = new Vector2(0f, 0.3f);
		val2.pivot = new Vector2(0f, 0.5f);
		val2.anchoredPosition = new Vector2(60f, 180f);
		val2.sizeDelta = new Vector2(500f, 40f);
		messageText = (TMP_Text)(object)val.AddComponent<TextMeshProUGUI>();
		messageText.font = messageCenterText.font;
		messageText.fontMaterial = messageCenterText.fontMaterial;
		messageText.fontSize = messageCenterText.fontSize;
		messageText.fontStyle = messageCenterText.fontStyle;
		messageText.characterSpacing = messageCenterText.characterSpacing;
		messageText.wordSpacing = messageCenterText.wordSpacing;
		messageText.lineSpacing = messageCenterText.lineSpacing;
		messageText.alignment = (TextAlignmentOptions)513;
		((Graphic)messageText).color = AshColor.HexToColor("#F5651F");
		messageText.textWrappingMode = (TextWrappingModes)1;
		messageText.overflowMode = (TextOverflowModes)0;
		messageText.text = "";
		messageText.alpha = 0f;
		((Graphic)messageText).canvasRenderer.SetAlpha(0f);
		Debug.Log((object)"ASH MESSAGE UI: Created message object");
	}

	private void Update()
	{
		if (!((Object)(object)messageText == (Object)null) && !(messageTimer <= 0f))
		{
			messageTimer -= Time.unscaledDeltaTime;
			if (messageTimer <= 0f)
			{
				((Graphic)messageText).CrossFadeAlpha(0f, 1f, true);
				messageTimer = 0f;
			}
		}
	}

	public void Show(string message)
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		Debug.Log((object)("ASH MESSAGE UI: SHOW: " + message));
		if (!string.IsNullOrEmpty(message))
		{
			if ((Object)(object)messageText == (Object)null)
			{
				Debug.LogError((object)"ASH MESSAGE UI: MESSAGE TEXT NOT INITIALIZED");
				return;
			}
			messageText.text = message;
			((Graphic)messageText).color = AshColor.HexToColor("#F5651F");
			messageText.fontSize = 24f;
			messageText.alpha = 1f;
			((Graphic)messageText).canvasRenderer.SetAlpha(1f);
			messageTimer = 5f;
		}
	}

	private void OnDestroy()
	{
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}
}
public static class AshNameManager
{
	[Serializable]
	public class AshNameEntry
	{
		public string PlayerId;

		public string AshName;
	}

	private static readonly Dictionary<string, string> m_ashNames = new Dictionary<string, string>();

	private static string SavePath => Path.Combine(Paths.ConfigPath, "AshValheimMod_AshNames.xml");

	public static string GetAshName()
	{
		Logger.LogInfo((object)"AshNameManager: ================================");
		Logger.LogInfo((object)"AshNameManager: GetAshName() called.");
		string currentPlayerId = GetCurrentPlayerId();
		Logger.LogInfo((object)("AshNameManager: GetAshName() PlayerId = '" + (currentPlayerId ?? "<NULL>") + "'"));
		if (string.IsNullOrEmpty(currentPlayerId))
		{
			Logger.LogWarning((object)"AshNameManager: No valid PlayerId. Returning default name: Ash Burntwood");
			return "Ash Burntwood";
		}
		Logger.LogInfo((object)$"AshNameManager: Dictionary currently contains {m_ashNames.Count} entries.");
		foreach (KeyValuePair<string, string> ashName in m_ashNames)
		{
			Logger.LogInfo((object)("AshNameManager: Dictionary entry | PlayerId='" + ashName.Key + "' | AshName='" + ashName.Value + "'"));
		}
		if (m_ashNames.TryGetValue(currentPlayerId, out var value))
		{
			Logger.LogInfo((object)("AshNameManager: FOUND saved name for PlayerId '" + currentPlayerId + "': '" + value + "'"));
			if (!string.IsNullOrWhiteSpace(value))
			{
				Logger.LogInfo((object)("AshNameManager: Returning saved Ash name: '" + value.Trim() + "'"));
				return value.Trim();
			}
			Logger.LogWarning((object)"AshNameManager: Saved name was null/empty/whitespace.");
		}
		else
		{
			Logger.LogWarning((object)("AshNameManager: NO saved name found for PlayerId '" + currentPlayerId + "'."));
		}
		Logger.LogInfo((object)"AshNameManager: Returning default name: Ash Burntwood");
		return "Ash Burntwood";
	}

	public static void SetAshName(string name)
	{
		Logger.LogInfo((object)"AshNameManager: ================================");
		Logger.LogInfo((object)("AshNameManager: SetAshName() called with name='" + (name ?? "<NULL>") + "'"));
		string currentPlayerId = GetCurrentPlayerId();
		Logger.LogInfo((object)("AshNameManager: SetAshName() PlayerId = '" + (currentPlayerId ?? "<NULL>") + "'"));
		if (string.IsNullOrEmpty(currentPlayerId))
		{
			Logger.LogError((object)"AshNameManager: Cannot save Ash name because PlayerId is NULL/empty.");
			return;
		}
		if (string.IsNullOrWhiteSpace(name))
		{
			Logger.LogWarning((object)"AshNameManager: Cannot save Ash name because supplied name is empty.");
			return;
		}
		name = name.Trim();
		Logger.LogInfo((object)("AshNameManager: Saving name '" + name + "' for PlayerId '" + currentPlayerId + "'."));
		if (m_ashNames.ContainsKey(currentPlayerId))
		{
			Logger.LogInfo((object)("AshNameManager: Replacing existing name '" + m_ashNames[currentPlayerId] + "' for PlayerId '" + currentPlayerId + "'."));
		}
		else
		{
			Logger.LogInfo((object)("AshNameManager: Creating new name entry for PlayerId '" + currentPlayerId + "'."));
		}
		m_ashNames[currentPlayerId] = name;
		Logger.LogInfo((object)$"AshNameManager: Dictionary now contains {m_ashNames.Count} entries.");
		Save();
	}

	private static string GetCurrentPlayerId()
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			Logger.LogWarning((object)"AshNameManager: GetCurrentPlayerId() -> Player.m_localPlayer is NULL.");
			return null;
		}
		Logger.LogInfo((object)("AshNameManager: Local player found. Character name='" + ((Character)localPlayer).GetHoverName() + "'."));
		return ((Character)localPlayer).GetHoverName();
	}

	public static void Load()
	{
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Expected O, but got Unknown
		Logger.LogInfo((object)"AshNameManager: ================================");
		Logger.LogInfo((object)"AshNameManager: Load() called.");
		Logger.LogInfo((object)("AshNameManager: SavePath = '" + SavePath + "'"));
		m_ashNames.Clear();
		Logger.LogInfo((object)"AshNameManager: Dictionary cleared.");
		if (!File.Exists(SavePath))
		{
			Logger.LogWarning((object)"AshNameManager: Save file DOES NOT EXIST.");
			return;
		}
		Logger.LogInfo((object)"AshNameManager: Save file exists.");
		try
		{
			FileInfo fileInfo = new FileInfo(SavePath);
			Logger.LogInfo((object)$"AshNameManager: Save file size = {fileInfo.Length} bytes.");
			XmlSerializer val = new XmlSerializer(typeof(List<AshNameEntry>));
			using (FileStream fileStream = File.OpenRead(SavePath))
			{
				Logger.LogInfo((object)"AshNameManager: XML file opened successfully.");
				if (!(val.Deserialize((Stream)fileStream) is List<AshNameEntry> list))
				{
					Logger.LogError((object)"AshNameManager: XML deserialized to NULL.");
					return;
				}
				Logger.LogInfo((object)$"AshNameManager: XML contained {list.Count} entries.");
				foreach (AshNameEntry item in list)
				{
					Logger.LogInfo((object)("AshNameManager: XML entry | PlayerId='" + (item.PlayerId ?? "<NULL>") + "' | AshName='" + (item.AshName ?? "<NULL>") + "'"));
					if (string.IsNullOrEmpty(item.PlayerId))
					{
						Logger.LogWarning((object)"AshNameManager: Ignoring entry with empty PlayerId.");
						continue;
					}
					if (string.IsNullOrWhiteSpace(item.AshName))
					{
						Logger.LogWarning((object)("AshNameManager: Ignor