Decompiled source of ErenshorQuestHelper v1.0.1

Drizzlx.Erenshor.QuestHelper.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using Microsoft.CodeAnalysis;
using UnityEngine;
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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Drizzlx.Erenshor.QuestHelper")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+f4c94759e6c5ec1856f43860cf9513e7204085f1")]
[assembly: AssemblyProduct("QuestHelper")]
[assembly: AssemblyTitle("Drizzlx.Erenshor.QuestHelper")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Erenshor_QuestHelper
{
	[BepInPlugin("Drizzlx.Erenshor.QuestHelper", "QuestHelper", "1.0.1")]
	public class QuestHelperPlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <UpdateQuestMarkersCoroutine>d__11 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public QuestHelperPlugin <>4__this;

			private Collider[] <hitColliders>5__1;

			private Collider[] <>s__2;

			private int <>s__3;

			private Collider <collider>5__4;

			private Character <character>5__5;

			private QuestManager <questManager>5__6;

			private NPCDialogManager <npcDialogManager>5__7;

			private bool <showQuestAvailableMarker>5__8;

			private Transform <questMarkerWorldUI>5__9;

			private bool <showQuestTurnInMarker>5__10;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <UpdateQuestMarkersCoroutine>d__11(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<hitColliders>5__1 = null;
				<>s__2 = null;
				<collider>5__4 = null;
				<character>5__5 = null;
				<questManager>5__6 = null;
				<npcDialogManager>5__7 = null;
				<questMarkerWorldUI>5__9 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d1: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>4__this._updatingQuestMarkers = true;
					<hitColliders>5__1 = Physics.OverlapSphere(((Component)GameData.PlayerControl).transform.position, 70f);
					<>s__2 = <hitColliders>5__1;
					<>s__3 = 0;
					goto IL_02a1;
				case 1:
					<>1__state = -1;
					<character>5__5 = null;
					<questManager>5__6 = null;
					<npcDialogManager>5__7 = null;
					<questMarkerWorldUI>5__9 = null;
					<collider>5__4 = null;
					goto IL_0293;
				case 2:
					{
						<>1__state = -1;
						<>4__this._updatingQuestMarkers = false;
						return false;
					}
					IL_02a1:
					if (<>s__3 < <>s__2.Length)
					{
						<collider>5__4 = <>s__2[<>s__3];
						if (!((Object)(object)<collider>5__4 == (Object)null))
						{
							<character>5__5 = ((Component)<collider>5__4).GetComponent<Character>();
							if (!((Object)(object)<character>5__5 == (Object)null))
							{
								<questManager>5__6 = ((Component)<character>5__5).GetComponent<QuestManager>();
								<npcDialogManager>5__7 = ((Component)<character>5__5).GetComponent<NPCDialogManager>();
								if ((!((Object)(object)<questManager>5__6 == (Object)null) || !((Object)(object)<npcDialogManager>5__7 == (Object)null)) && <character>5__5.isNPC && !<character>5__5.MiningNode && !((Object)(object)((Component)<character>5__5).transform == (Object)null) && !((Object)(object)<character>5__5.MyNPC == (Object)null) && !<character>5__5.MyNPC.SimPlayer && !(((Object)((Component)<character>5__5).transform).name == "Player"))
								{
									if ((Object)(object)<questManager>5__6 != (Object)null)
									{
										<showQuestTurnInMarker>5__10 = <>4__this.ShowQuestTurnInMarker(<questManager>5__6);
										if (<showQuestTurnInMarker>5__10)
										{
											<>4__this.AttachMarkerToCharacter(<character>5__5, <>4__this._questTurnInTexture);
											goto IL_0293;
										}
									}
									<showQuestAvailableMarker>5__8 = <>4__this.ShowQuestAvailableMarker(<character>5__5);
									if (!<showQuestAvailableMarker>5__8)
									{
										<questMarkerWorldUI>5__9 = ((Component)<character>5__5).transform.Find("QuestMarkerWorldUI");
										if ((Object)(object)<questMarkerWorldUI>5__9 != (Object)null)
										{
											Object.Destroy((Object)(object)((Component)<questMarkerWorldUI>5__9).gameObject);
										}
										<>2__current = null;
										<>1__state = 1;
										return true;
									}
									<>4__this.AttachMarkerToCharacter(<character>5__5, <>4__this._questAvailableTexture);
								}
							}
						}
						goto IL_0293;
					}
					<>s__2 = null;
					<>2__current = (object)new WaitForSeconds(<>4__this._questMarkerUpdateInterval);
					<>1__state = 2;
					return true;
					IL_0293:
					<>s__3++;
					goto IL_02a1;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private Texture2D _questAvailableTexture;

		private Texture2D _questTurnInTexture;

		public const float QuestMarkerRadius = 70f;

		private static readonly string[] _bankNpcs = new string[4] { "Prestigio Valusha", "Validus Greencent", "Comstock Retalio", "Summoned: Pocket Rift" };

		private static readonly string[] _otherNpcs = new string[2] { "Thella Steepleton", "Goldie Retalio" };

		private float _questMarkerUpdateInterval = 0.5f;

		private bool _updatingQuestMarkers = false;

		private void Awake()
		{
			LoadTextures();
		}

		private void OnDestroy()
		{
			try
			{
				Character[] array = Object.FindObjectsOfType<Character>();
				Character[] array2 = array;
				foreach (Character val in array2)
				{
					Transform val2 = ((Component)val).transform.Find("QuestMarkerWorldUI");
					if ((Object)(object)val2 != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)val2).gameObject);
					}
				}
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Error cleaning up quest markers: {arg}");
			}
		}

		private void LoadTextures()
		{
			string text = Path.Combine(Paths.PluginPath, "drizzlx-ErenshorQuestHelper");
			string assetPath = Path.Combine(text, "quest-available.png");
			string assetPath2 = Path.Combine(text, "quest-complete.png");
			if (Directory.Exists(text))
			{
				_questAvailableTexture = LoadImage(assetPath);
				_questTurnInTexture = LoadImage(assetPath2);
			}
		}

		private void OnGUI()
		{
			if (!((Object)(object)GameData.PlayerControl == (Object)null) && !GameData.InCharSelect && !GameData.Zoning && !_updatingQuestMarkers)
			{
				((MonoBehaviour)this).StartCoroutine(UpdateQuestMarkersCoroutine());
			}
		}

		[IteratorStateMachine(typeof(<UpdateQuestMarkersCoroutine>d__11))]
		private IEnumerator UpdateQuestMarkersCoroutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <UpdateQuestMarkersCoroutine>d__11(0)
			{
				<>4__this = this
			};
		}

		private void AttachMarkerToCharacter(Character character, Texture2D texture)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)character).transform.Find("QuestMarkerWorldUI");
			if ((Object)(object)val != (Object)null)
			{
				QuestMarker component = ((Component)val).GetComponent<QuestMarker>();
				if (!((Object)(object)component != (Object)null) || ((component.markerType != 0 || !((Object)(object)texture == (Object)(object)_questAvailableTexture)) && (component.markerType != QuestMarker.Type.TurnIn || !((Object)(object)texture == (Object)(object)_questTurnInTexture))))
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
				return;
			}
			Collider component2 = ((Component)character).GetComponent<Collider>();
			float num;
			if (component2 == null)
			{
				num = 2.5f;
			}
			else
			{
				Bounds bounds = component2.bounds;
				num = ((Bounds)(ref bounds)).size.y;
			}
			float num2 = num;
			num2 = Mathf.Clamp(num2, 3f, 3f);
			GameObject val2 = CreateWorldMarker(texture);
			((Object)val2).name = "QuestMarkerWorldUI";
			val2.transform.SetParent(((Component)character).transform);
			val2.transform.localPosition = new Vector3(0f, num2 + 0.1f, 0f);
			val2.transform.rotation = Quaternion.identity;
			BillboardToCamera billboardToCamera = val2.AddComponent<BillboardToCamera>();
			((Behaviour)billboardToCamera).enabled = true;
			val2.SetActive(true);
			QuestMarker questMarker = val2.AddComponent<QuestMarker>();
			if ((Object)(object)texture == (Object)(object)_questAvailableTexture)
			{
				questMarker.markerType = QuestMarker.Type.Available;
			}
			else
			{
				questMarker.markerType = QuestMarker.Type.TurnIn;
			}
		}

		private GameObject CreateWorldMarker(Texture2D texture)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0035: 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_004b: 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_0061: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("QuestMarkerWorldUI");
			Canvas val2 = val.AddComponent<Canvas>();
			val2.renderMode = (RenderMode)2;
			val2.sortingOrder = 0;
			RectTransform component = ((Component)val2).GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(1f, 1f);
			((Transform)component).localScale = Vector3.one * 0.02f;
			GameObject val3 = new GameObject("Icon");
			val3.transform.SetParent(val.transform, false);
			RawImage val4 = val3.AddComponent<RawImage>();
			val4.texture = (Texture)(object)texture;
			((Graphic)val4).raycastTarget = false;
			RectTransform component2 = ((Component)val4).GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(64f, 64f);
			return val;
		}

		private bool ShowQuestAvailableMarker(Character character)
		{
			NPCDialogManager component = ((Component)character).GetComponent<NPCDialogManager>();
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			if (component.SpecificClass.Count == 0 || component.SpecificClass.Contains(GameData.PlayerStats.CharacterClass))
			{
				NPCDialog[] myDialogOptions = component.MyDialogOptions;
				foreach (NPCDialog val in myDialogOptions)
				{
					Quest questToAssign = val.QuestToAssign;
					if (!((Object)(object)questToAssign == (Object)null) && !GameData.HasQuest.Contains(questToAssign.DBName))
					{
						if (!GameData.IsQuestDone(questToAssign.DBName))
						{
							return true;
						}
						if (GameData.IsQuestDone(questToAssign.DBName) && questToAssign.repeatable)
						{
							return true;
						}
					}
				}
			}
			return false;
		}

		private bool ShowQuestTurnInMarker(QuestManager questManager)
		{
			foreach (Quest nPCQuest in questManager.NPCQuests)
			{
				if ((Object)(object)nPCQuest == (Object)null || !GameData.HasQuest.Contains(nPCQuest.QuestName) || (GameData.CompletedQuests.Contains(nPCQuest.QuestName) && !nPCQuest.repeatable))
				{
					continue;
				}
				List<Item> requiredItems = nPCQuest.RequiredItems;
				foreach (Item item in requiredItems)
				{
					if ((Object)(object)item == (Object)null || (Object)(object)GameData.PlayerInv == (Object)null || GameData.PlayerInv.HasItem(item, false))
					{
						continue;
					}
					if (GameData.PlayerInv.mouseSlot?.MyItem?.ItemName == item.ItemName)
					{
						return true;
					}
					if (GameData.TradeWindow?.LootSlots != null)
					{
						foreach (ItemIcon lootSlot in GameData.TradeWindow.LootSlots)
						{
							if ((Object)(object)lootSlot.MyItem != (Object)null && lootSlot.MyItem.ItemName == item.ItemName)
							{
								return true;
							}
						}
					}
					return false;
				}
				return true;
			}
			return false;
		}

		private Texture2D LoadImage(string assetPath)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (File.Exists(assetPath))
			{
				byte[] array = File.ReadAllBytes(assetPath);
				Texture2D val = new Texture2D(4, 4, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(val, array))
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load texture from " + assetPath));
				}
				return val;
			}
			((BaseUnityPlugin)this).Logger.LogError((object)("Texture not found at " + assetPath));
			return null;
		}
	}
	public class BillboardToCamera : MonoBehaviour
	{
		private Camera _cam;

		private Transform _player;

		private void Start()
		{
			_cam = GameData.PlayerControl?.camera;
			PlayerControl playerControl = GameData.PlayerControl;
			_player = ((playerControl != null) ? ((Component)playerControl).transform : null);
		}

		private void LateUpdate()
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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)
			if ((Object)(object)_cam == (Object)null)
			{
				_cam = GameData.PlayerControl?.camera;
			}
			if ((Object)(object)_player == (Object)null)
			{
				PlayerControl playerControl = GameData.PlayerControl;
				_player = ((playerControl != null) ? ((Component)playerControl).transform : null);
			}
			if (!((Object)(object)_cam == (Object)null) && !((Object)(object)_player == (Object)null))
			{
				((Component)this).transform.rotation = Quaternion.LookRotation(((Component)this).transform.position - ((Component)_cam).transform.position);
				float num = Vector3.Distance(((Component)this).transform.position, _player.position);
				if (num > 80f)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}
		}
	}
	public class QuestMarker : MonoBehaviour
	{
		public enum Type
		{
			Available,
			TurnIn
		}

		public Type markerType;
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Drizzlx.Erenshor.QuestHelper";

		public const string PLUGIN_NAME = "QuestHelper";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}