using System;
using System.Collections;
using System.Collections.Generic;
using Pathfinding;
using UnityEngine;

// Token: 0x02000019 RID: 25
public class Boro : MonoBehaviour
{
	// Token: 0x060002C1 RID: 705 RVA: 0x00038B3F File Offset: 0x00036D3F
	private void Start()
	{
	}

	// Token: 0x060002C2 RID: 706 RVA: 0x00038B41 File Offset: 0x00036D41
	public void Setup()
	{
		this.character = base.gameObject.GetComponent<Character>();
		this.party = Links.x.portraitOrder;
	}

	// Token: 0x060002C3 RID: 707 RVA: 0x00038B64 File Offset: 0x00036D64
	private void OnDisable()
	{
		this.Stop();
	}

	// Token: 0x060002C4 RID: 708 RVA: 0x00038B6C File Offset: 0x00036D6C
	public void Call(Character callingParty)
	{
		if (this.corout == null && Links.x.gaia.pathfindingReady)
		{
			if (this.leaveCoroutine != null)
			{
				base.StopCoroutine(this.leaveCoroutine);
				this.leaveCoroutine = null;
			}
			if (this.attempt == 0)
			{
				string text = "Calling " + Records.x.boroName + "...";
				Links.x.gameFeed.AddFeed(text);
			}
			this.corout = this.FindSpot(callingParty, true);
			base.StartCoroutine(this.corout);
		}
	}

	// Token: 0x060002C5 RID: 709 RVA: 0x00038BFC File Offset: 0x00036DFC
	public void Move(Character callingParty)
	{
		if (this.corout != null)
		{
			base.StopCoroutine(this.corout);
			this.corout = null;
		}
		if (this.corout == null && Links.x.gaia.pathfindingReady)
		{
			this.corout = this.FindSpot(callingParty, true);
			base.StartCoroutine(this.corout);
		}
	}

	// Token: 0x060002C6 RID: 710 RVA: 0x00038C58 File Offset: 0x00036E58
	private IEnumerator FindSpot(Character callingParty, bool instant)
	{
		float radius = 12f;
		ConstantPath constPath = ConstantPath.ConstructFast(callingParty.node, Records.x.GetConstantPathRadius((int)radius), null);
		this.SetNodeConstraint(null, false);
		this.nodeConstraint.constrainWalkability = false;
		constPath.nnConstraint = this.nodeConstraint;
		AstarPath.StartPath(constPath, false);
		yield return base.StartCoroutine(constPath.WaitForPath());
		constPath.Claim(this);
		this.allNodes = constPath.allNodes;
		int num = this.allNodes.Count;
		int num2 = num - 1;
		this.SetNodeConstraint(this.character, true);
		this.suitableNodes.Clear();
		this.edgeNodes.Clear();
		this.nearNodes.Clear();
		radius *= Records.x.nodeSize;
		for (int i = num2; i >= 0; i--)
		{
			GraphNode graphNode = this.allNodes[i];
			if (((Vector3)graphNode.position - (Vector3)callingParty.node.position).sqrMagnitude < radius * radius && this.nodeConstraint.Suitable(graphNode))
			{
				this.suitableNodes.Add(graphNode);
			}
		}
		constPath.Release(this, false);
		num = this.suitableNodes.Count;
		Vector3 position = callingParty.tr.position;
		this.added.Clear();
		for (int j = 0; j < num; j++)
		{
			this.added.Add(false);
		}
		for (int k = 0; k < 15; k++)
		{
			float num3 = float.PositiveInfinity;
			int num4 = -1;
			for (int l = 0; l < num; l++)
			{
				if (!this.added[l])
				{
					float sqrMagnitude = this.SubtractVectors(position, (Vector3)this.suitableNodes[l].position).sqrMagnitude;
					if (sqrMagnitude < num3)
					{
						num3 = sqrMagnitude;
						num4 = l;
					}
				}
			}
			if (num4 > -1)
			{
				this.added[num4] = true;
				this.edgeNodes.Add(this.suitableNodes[num4]);
			}
		}
		if (this.edgeNodes.Count > 0)
		{
			this.character.SetMeshState(false);
			Links.x.gaia.boro.body.SetMeshState(false, true);
			if (Links.x.gaia.boro.circleTr)
			{
				Links.x.gaia.boro.circleTr.gameObject.SetActive(false);
			}
			float num5 = Vector3.Distance(this.character.tr.position, callingParty.tr.position);
			num5 *= 0.05f;
			if (num5 < 1f)
			{
				num5 = 1f;
			}
			if (this.attempt == 0 && !instant)
			{
				yield return new WaitForSeconds(num5);
			}
			else if (this.attempt == 0 && instant)
			{
				yield return new WaitForSeconds(0.5f);
			}
			GraphNode graphNode2 = this.edgeNodes[this.edgeNodes.Count - 1];
			int num6 = this.edgeNodes.Count - 1;
			this.attempt = 0;
			if (this.character.inactive)
			{
				this.character.TurnScriptsOn();
			}
			this.boroInvisible = false;
			Records.x.boroInvisible = this.boroInvisible;
			this.character.tr.position = (Vector3)this.edgeNodes[num6].position;
			this.character.SetRotation(Quaternion.LookRotation(callingParty.tr.position - this.character.tr.position), false, true);
			this.character.FirstPosition(this.edgeNodes[num6]);
			this.character.SetMeshState(true);
			Links.x.gaia.boro.body.SetMeshState(true, true);
			if (Links.x.gaia.boro.circleTr)
			{
				Links.x.gaia.boro.circleTr.gameObject.SetActive(true);
			}
			Links.x.gaia.boro.body.SeeThroughColliders(true);
			Links.x.gaia.boro.thisCollider.enabled = true;
			this.character.PlaySoundFX(0, 6);
			Links.x.hudControl.ToggleBoroButtonSprite();
		}
		else if (this.attempt < 5)
		{
			this.attempt++;
			yield return new WaitForSeconds(0.5f);
			this.corout = null;
			this.Call(callingParty);
		}
		else
		{
			Links.x.hudControl.ToggleBoroButtonSprite();
			Links.x.gameFeed.AddFeed("Boro cannot stand here");
			Links.x.gameFeed.ShowNotice("Boro cannot find a place to stand here");
		}
		this.corout = null;
		yield return new WaitForSeconds(0.1f);
		yield break;
	}

	// Token: 0x060002C7 RID: 711 RVA: 0x00038C78 File Offset: 0x00036E78
	public bool BoroNearby()
	{
		return this.character.sailing || (!this.boroInvisible && (Links.x.hasMain && (Links.x.main.currentPosition - this.character.tr.position).sqrMagnitude < 900f));
	}

	// Token: 0x060002C8 RID: 712 RVA: 0x00038CE0 File Offset: 0x00036EE0
	public void StartLeaveWait()
	{
		if (this.leaveCoroutine == null)
		{
			this.leaveCoroutine = this.WaitToLeave(false);
			base.StartCoroutine(this.leaveCoroutine);
		}
	}

	// Token: 0x060002C9 RID: 713 RVA: 0x00038D04 File Offset: 0x00036F04
	private IEnumerator WaitToLeave(bool fromButton)
	{
		Links.x.hudControl.ToggleBoroButtonSprite();
		float timeToLerp = 3f;
		float percentage = 0f;
		float startTime = Time.time;
		if (fromButton)
		{
			timeToLerp = 1f;
			this.character.Flee(Links.x.main.node, false, Links.x.gameplay.seconds, 10f);
		}
		if (!Links.x.gaia.sceneLoaded)
		{
			timeToLerp = 0.0001f;
			fromButton = true;
		}
		while (percentage < 1f && (!this.BoroNearby() || fromButton))
		{
			percentage = (Time.time - startTime) / timeToLerp;
			yield return null;
		}
		if (!this.BoroNearby() || fromButton)
		{
			bool sceneLoaded = Links.x.gaia.sceneLoaded;
			this.character.SetMeshState(false);
			this.character.body.SetMeshState(false, sceneLoaded);
			this.boroInvisible = true;
			Records.x.boroInvisible = this.boroInvisible;
			Links.x.gaia.boro.body.SeeThroughColliders(false);
			Links.x.gaia.boro.thisCollider.enabled = false;
			yield return new WaitForSeconds(0.5f);
			this.character.RemoveLastNode(true);
			this.character.TurnScriptsOff();
		}
		Links.x.hudControl.ToggleBoroButtonSprite();
		this.leaveCoroutine = null;
		yield break;
	}

	// Token: 0x060002CA RID: 714 RVA: 0x00038D1C File Offset: 0x00036F1C
	public void Leave()
	{
		if (Records.x.partySailing)
		{
			return;
		}
		if (this.leaveCoroutine != null)
		{
			base.StopCoroutine(this.leaveCoroutine);
			this.leaveCoroutine = null;
		}
		this.leaveCoroutine = this.WaitToLeave(true);
		base.StartCoroutine(this.leaveCoroutine);
	}

	// Token: 0x060002CB RID: 715 RVA: 0x00038D6C File Offset: 0x00036F6C
	public void BackToBeach()
	{
		if (this.coroutBack == null && Records.x.boroLastBeachPoint != Vector3.zero)
		{
			this.coroutBack = this.Back();
			base.StartCoroutine(this.coroutBack);
			return;
		}
		Links.x.gameFeed.AddFeed("Boro is busy");
	}

	// Token: 0x060002CC RID: 716 RVA: 0x00038DC5 File Offset: 0x00036FC5
	private IEnumerator Back()
	{
		this.SetNodeConstraint(this.character, true);
		GraphNode beachNode = this.character.NearNode(Records.x.boroLastBeachPoint, true, 0, -1, 0);
		bool flag;
		if (beachNode == null)
		{
			flag = false;
			Links.x.gameFeed.AddFeed("Boro cannot find a place on beach");
			Links.x.gameFeed.ShowNotice("Boro cannot find a place to stand");
		}
		else
		{
			flag = true;
		}
		if (flag)
		{
			this.character.SetMeshState(false);
			Links.x.gaia.boro.body.SetMeshState(false, true);
			if (Links.x.gaia.boro.circleTr)
			{
				Links.x.gaia.boro.circleTr.gameObject.SetActive(false);
			}
			float t = 0.5f;
			yield return new WaitForSeconds(t);
			this.character.tr.position = (Vector3)beachNode.position;
			this.character.FirstPosition(beachNode);
			yield return new WaitForSeconds(t);
			this.character.SetMeshState(true);
			Links.x.gaia.boro.body.SetMeshState(true, true);
			if (Links.x.gaia.boro.circleTr)
			{
				Links.x.gaia.boro.circleTr.gameObject.SetActive(true);
			}
			this.character.PlaySoundFX(0, 6);
		}
		this.coroutBack = null;
		yield break;
	}

	// Token: 0x060002CD RID: 717 RVA: 0x00038DD4 File Offset: 0x00036FD4
	public void LeavingForCombat()
	{
		if (this.boroInvisible)
		{
			return;
		}
		if (this.character.sailing)
		{
			return;
		}
		if (this.coroutCombat != null)
		{
			base.StopCoroutine(this.coroutCombat);
			this.coroutCombat = null;
		}
		if (this.coroutCombat == null && !this.boroInvisible)
		{
			this.savedNode = this.character.node;
			this.coroutCombat = this.FindCombatRetreat(false, true);
			base.StartCoroutine(this.coroutCombat);
		}
	}

	// Token: 0x060002CE RID: 718 RVA: 0x00038E50 File Offset: 0x00037050
	public void ComingBackFromCombat()
	{
		if (this.character.sailing)
		{
			return;
		}
		if (!Links.x.gaia.pathfindingReady)
		{
			return;
		}
		if (this.boroInvisible)
		{
			return;
		}
		if (this.coroutCombat != null)
		{
			base.StopCoroutine(this.coroutCombat);
			this.coroutCombat = null;
		}
		if (this.coroutCombat == null && this.character.node == null)
		{
			this.coroutCombat = this.FindCombatRetreat(true, true);
			base.StartCoroutine(this.coroutCombat);
			return;
		}
		if (this.character.node != null)
		{
			this.character.TurnScriptsOn();
			this.boroInvisible = false;
			Records.x.boroInvisible = this.boroInvisible;
			Links.x.gaia.boro.body.SetMeshState(true, true);
			this.character.EndPath();
			Links.x.gaia.boro.body.SeeThroughColliders(true);
			Links.x.gaia.boro.thisCollider.enabled = true;
		}
	}

	// Token: 0x060002CF RID: 719 RVA: 0x00038F5B File Offset: 0x0003715B
	private IEnumerator FindCombatRetreat(bool state, bool instant)
	{
		bool enoughNodes = false;
		float radius = 12f;
		if (!state)
		{
			this.character.CircleAnimation("");
		}
		GraphNode centerNode = this.character.node;
		if (state)
		{
			this.character.TurnScriptsOn();
			this.character.FindCurrentNode(true);
		}
		if (this.character.node == null && Links.x.diorama.playerStartBoatDefault)
		{
			this.character.tr.position = Links.x.diorama.playerStartBoatDefault.position;
			this.character.FirstPosition(null);
		}
		if (this.character.node == null)
		{
			Debug.Log("Sheep node is null");
			this.character.SetMeshState(state);
			Links.x.gaia.boro.body.SetMeshState(state, true);
			if (!state)
			{
				this.boroInvisible = true;
			}
			else
			{
				this.boroInvisible = false;
			}
			Records.x.boroInvisible = this.boroInvisible;
			if (this.boroInvisible)
			{
				Links.x.gaia.boro.body.SeeThroughColliders(false);
				Links.x.gaia.boro.thisCollider.enabled = false;
			}
			else
			{
				Links.x.gaia.boro.body.SeeThroughColliders(true);
				Links.x.gaia.boro.thisCollider.enabled = true;
			}
		}
		else
		{
			if (state)
			{
				this.character.tr.position = (Vector3)this.character.node.position;
				centerNode = this.savedNode;
			}
			ConstantPath constPath = ConstantPath.ConstructFast(centerNode, Records.x.GetConstantPathRadius((int)radius), null);
			this.SetNodeConstraint(null, true);
			this.nodeConstraint.constrainWalkability = false;
			constPath.nnConstraint = this.nodeConstraint;
			AstarPath.StartPath(constPath, false);
			yield return base.StartCoroutine(constPath.WaitForPath());
			constPath.Claim(this);
			this.allNodes = constPath.allNodes;
			int num = this.allNodes.Count;
			int num2 = num - 1;
			Vector3 zero = Vector3.zero;
			Vector3 zero2 = Vector3.zero;
			Vector3 zero3 = Vector3.zero;
			Vector3 zero4 = Vector3.zero;
			Vector3 forward = Vector3.forward;
			Vector3 zero5 = Vector3.zero;
			Vector3 zero6 = Vector3.zero;
			this.SetNodeConstraint(this.character, true);
			this.suitableNodes.Clear();
			this.edgeNodes.Clear();
			this.nearNodes.Clear();
			radius *= Records.x.nodeSize;
			if (!state)
			{
				for (int j = num2; j >= 0; j--)
				{
					GraphNode graphNode = this.allNodes[j];
					if (((Vector3)graphNode.position - (Vector3)centerNode.position).sqrMagnitude < radius * radius && this.nodeConstraint.Suitable(graphNode))
					{
						this.suitableNodes.Add(graphNode);
					}
				}
			}
			else
			{
				for (int k = 0; k < num; k++)
				{
					GraphNode graphNode = this.allNodes[k];
					if (((Vector3)graphNode.position - (Vector3)centerNode.position).sqrMagnitude < radius * radius && this.nodeConstraint.Suitable(graphNode))
					{
						this.suitableNodes.Add(graphNode);
					}
				}
			}
			num = this.suitableNodes.Count;
			num2 = num - 1;
			Vector3 position = this.character.tr.position;
			for (int l = 0; l < num; l++)
			{
				if (!enoughNodes)
				{
					GraphNode graphNode = this.suitableNodes[l];
					this.edgeNodes.Add(graphNode);
					if (this.edgeNodes.Count >= 100)
					{
						enoughNodes = true;
						break;
					}
				}
			}
			constPath.Release(this, false);
			this.character.PlaySoundFX(0, 6);
			int nodeIndex = -1;
			if (this.edgeNodes.Count > 0)
			{
				bool foundPath = false;
				int num3;
				for (int i = 0; i < this.edgeNodes.Count; i = num3 + 1)
				{
					if (!foundPath)
					{
						ABPath p = ABPath.ConstructFast(this.character.node, this.edgeNodes[i], null);
						p.nnConstraint = this.nodeConstraint;
						AstarPath.StartPath(p, false);
						yield return base.StartCoroutine(p.WaitForPath());
						p.Claim(this);
						if (!p.error)
						{
							foundPath = true;
							nodeIndex = i;
						}
						p.Release(this, false);
						p = null;
					}
					num3 = i;
				}
			}
			GraphNode graphNode2 = null;
			if (nodeIndex > -1)
			{
				graphNode2 = this.edgeNodes[nodeIndex];
			}
			if (graphNode2 == null || instant)
			{
				this.character.SetMeshState(state);
				Links.x.gaia.boro.body.SetMeshState(state, true);
				if (!state)
				{
					this.boroInvisible = true;
				}
				else
				{
					this.boroInvisible = false;
				}
				Records.x.boroInvisible = this.boroInvisible;
				if (this.boroInvisible)
				{
					Links.x.gaia.boro.body.SeeThroughColliders(false);
					Links.x.gaia.boro.thisCollider.enabled = false;
				}
				else
				{
					Links.x.gaia.boro.body.SeeThroughColliders(true);
					Links.x.gaia.boro.thisCollider.enabled = true;
				}
			}
			else
			{
				bool flag = true;
				if (state)
				{
					flag = false;
				}
				this.character.MakePath(this.edgeNodes[nodeIndex], 10, false, flag, true);
				yield return new WaitForSecondsRealtime(2f);
				this.character.SetMeshState(state);
				Links.x.gaia.boro.body.SetMeshState(state, true);
				if (state)
				{
					this.character.CircleAnimation("");
				}
				if (!state)
				{
					this.boroInvisible = true;
				}
				else
				{
					this.boroInvisible = false;
				}
				Records.x.boroInvisible = this.boroInvisible;
				if (this.boroInvisible)
				{
					Links.x.gaia.boro.body.SeeThroughColliders(false);
					Links.x.gaia.boro.thisCollider.enabled = false;
				}
				else
				{
					Links.x.gaia.boro.body.SeeThroughColliders(true);
					Links.x.gaia.boro.thisCollider.enabled = true;
				}
				if (!state)
				{
					yield return new WaitForSecondsRealtime(2f);
					this.character.TargetReached();
					this.character.RemoveLastNode(true);
					this.character.TurnScriptsOff();
				}
			}
			constPath = null;
		}
		Links.x.hudControl.ToggleBoroButtonSprite();
		this.coroutCombat = null;
		yield break;
	}

	// Token: 0x060002D0 RID: 720 RVA: 0x00038F78 File Offset: 0x00037178
	private GraphNode GetSuitableNode()
	{
		for (int i = 0; i < this.edgeNodes.Count; i++)
		{
			if (this.nodeConstraint.Suitable(this.edgeNodes[i]))
			{
				return this.edgeNodes[i];
			}
		}
		return null;
	}

	// Token: 0x060002D1 RID: 721 RVA: 0x00038FC2 File Offset: 0x000371C2
	public void Stop()
	{
		this.attempt = 0;
		if (this.corout != null)
		{
			base.StopCoroutine(this.corout);
			this.corout = null;
		}
		if (this.coroutCombat != null)
		{
			base.StopCoroutine(this.coroutCombat);
			this.coroutCombat = null;
		}
	}

	// Token: 0x060002D2 RID: 722 RVA: 0x00039001 File Offset: 0x00037201
	public void Sail()
	{
	}

	// Token: 0x060002D3 RID: 723 RVA: 0x00039003 File Offset: 0x00037203
	public void LevelUp()
	{
	}

	// Token: 0x060002D4 RID: 724 RVA: 0x00039008 File Offset: 0x00037208
	public void SetNodeConstraint(Character pathfinder, bool constrainTags)
	{
		this.nodeConstraint.constrainWalkability = true;
		this.nodeConstraint.walkable = true;
		this.nodeConstraint.constrainTags = constrainTags;
		this.nodeConstraint.checkCircleID = 0;
		if (!pathfinder)
		{
			this.nodeConstraint.passID = 0;
			this.nodeConstraint.passID2 = 0;
			this.nodeConstraint.checkConnections = 0;
			this.nodeConstraint.constrainPenalty = 0;
		}
		else
		{
			this.nodeConstraint.passID = pathfinder.nodeStationaryID;
			this.nodeConstraint.passID2 = pathfinder.nodeMovingID;
			this.nodeConstraint.checkConnections = pathfinder.ConnectionNumber();
			this.nodeConstraint.constrainPenalty = 0;
		}
		this.nodeConstraint.constrainToArea = -1;
	}

	// Token: 0x060002D5 RID: 725 RVA: 0x000390CC File Offset: 0x000372CC
	public Vector3 CustomNormalize(Vector3 v)
	{
		double num = Math.Sqrt((double)(v.x * v.x + v.y * v.y + v.z * v.z));
		if (num > 9.99999974737875E-06)
		{
			float num2 = (float)num;
			v.x /= num2;
			v.y /= num2;
			v.z /= num2;
			return v;
		}
		return Vector3.zero;
	}

	// Token: 0x060002D6 RID: 726 RVA: 0x00039143 File Offset: 0x00037343
	public float GetDot(Vector3 vector1, Vector3 vector2)
	{
		return vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z;
	}

	// Token: 0x060002D7 RID: 727 RVA: 0x00039170 File Offset: 0x00037370
	public Vector3 SubtractVectors(Vector3 a, Vector3 b)
	{
		Vector3 vector;
		vector.x = a.x - b.x;
		vector.y = a.y - b.y;
		vector.z = a.z - b.z;
		return vector;
	}

	// Token: 0x040004EE RID: 1262
	private IEnumerator corout;

	// Token: 0x040004EF RID: 1263
	private IEnumerator coroutCombat;

	// Token: 0x040004F0 RID: 1264
	private IEnumerator coroutBack;

	// Token: 0x040004F1 RID: 1265
	private NNConstraint nodeConstraint = new NNConstraint();

	// Token: 0x040004F2 RID: 1266
	private List<GraphNode> allNodes;

	// Token: 0x040004F3 RID: 1267
	private Character character;

	// Token: 0x040004F4 RID: 1268
	private List<GraphNode> suitableNodes = new List<GraphNode>();

	// Token: 0x040004F5 RID: 1269
	private List<GraphNode> edgeNodes = new List<GraphNode>();

	// Token: 0x040004F6 RID: 1270
	private List<GraphNode> nearNodes = new List<GraphNode>();

	// Token: 0x040004F7 RID: 1271
	public int attempt;

	// Token: 0x040004F8 RID: 1272
	public bool nearbyDuringCombat;

	// Token: 0x040004F9 RID: 1273
	private List<Character> party;

	// Token: 0x040004FA RID: 1274
	private GraphNode savedNode;

	// Token: 0x040004FB RID: 1275
	public Vector3 lastBeachPoint;

	// Token: 0x040004FC RID: 1276
	public bool boroInvisible;

	// Token: 0x040004FD RID: 1277
	private List<bool> added = new List<bool>();

	// Token: 0x040004FE RID: 1278
	private IEnumerator leaveCoroutine;
}
