Decompiled source of PassageDude v1.0.0

PassageDude/PassageDude.dll

Decompiled 6 days ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("PassageDude")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PassageDude")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("15108900-c39d-42b4-8330-bbeec3ab577e")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace PassageDude;

[BepInPlugin("pr0skynesis.passagedude", "Passage Dude", "1.0.0")]
public class PassageDudeMain : BaseUnityPlugin
{
	public const string pluginGuid = "pr0skynesis.passagedude";

	public const string pluginName = "Passage Dude";

	public const string pluginVersion = "1.0.0";

	public static ConfigEntry<float> localPriceMultiplierConfig;

	public static ConfigEntry<float> worldPriceMultiplierConfig;

	private static AssetBundle bundle;

	private static string assetPath;

	public static GameObject[] dudesPrefab = (GameObject[])(object)new GameObject[33];

	public static GameObject smallUI;

	public static GameObject largeUI;

	public static Texture oceanMap;

	public static Texture alAnkhMap;

	public static Texture emeraldMap;

	public static Texture aestrinMap;

	public static Texture lagoonMap;

	private void Start()
	{
		assetPath = Paths.PluginPath + "\\PassageDude\\passagedude";
		bundle = AssetBundle.LoadFromFile(assetPath);
		if ((Object)(object)bundle == (Object)null)
		{
			Debug.LogError((object)"PassageDude: Bundle not loaded! Did you place it in the correct folder?");
		}
	}

	public void Awake()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Expected O, but got Unknown
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Expected O, but got Unknown
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Expected O, but got Unknown
		SceneManager.sceneLoaded += SceneLoaded;
		Harmony val = new Harmony("pr0skynesis.passagedude");
		MethodInfo methodInfo = AccessTools.Method(typeof(IslandStreetlightsManager), "Awake", (Type[])null, (Type[])null);
		MethodInfo methodInfo2 = AccessTools.Method(typeof(PassageDudePatches), "Awake_Patch", (Type[])null, (Type[])null);
		MethodInfo methodInfo3 = AccessTools.Method(typeof(IslandHorizon), "RegisterLoadingFinished", (Type[])null, (Type[])null);
		MethodInfo methodInfo4 = AccessTools.Method(typeof(PassageDudePatches), "LoadIsland", (Type[])null, (Type[])null);
		MethodInfo methodInfo5 = AccessTools.Method(typeof(IslandHorizon), "DoUnloadScene", (Type[])null, (Type[])null);
		MethodInfo methodInfo6 = AccessTools.Method(typeof(PassageDudePatches), "UnloadIsland", (Type[])null, (Type[])null);
		localPriceMultiplierConfig = ((BaseUnityPlugin)this).Config.Bind<float>("A) Price Multipliers", "localPriceMultiplier", 1f, "Adjusts how expensive local passages are. Default is 1.0, set to less than 1 for cheaper passages, set to more than 1 for more expensive passages. E.g.: 0.6 will make passages cost 60% of the original price");
		worldPriceMultiplierConfig = ((BaseUnityPlugin)this).Config.Bind<float>("A) Price Multipliers", "worldPriceMultiplier", 1f, "Adjusts how expensive world passages are. Default is 1.0, set to less than 1 for cheaper passages, set to more than 1 for more expensive passages. E.g.: 0.6 will make passages cost 60% of the original price");
		val.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)methodInfo3, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)methodInfo5, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	private static void SceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
	{
		if (((Scene)(ref scene)).name == "the ocean")
		{
			SetupThings();
		}
	}

	private static void SetupThings()
	{
		if ((Object)(object)bundle != (Object)null)
		{
			for (int i = 0; i < dudesPrefab.Length; i++)
			{
				string text = $"Assets/PassageDude/passageDude_{i}.prefab";
				if (bundle.Contains(text))
				{
					dudesPrefab[i] = bundle.LoadAsset<GameObject>(text);
				}
				else
				{
					dudesPrefab[i] = null;
				}
			}
			smallUI = bundle.LoadAsset<GameObject>("Assets/PassageDude/Prefabs/ferry_hire_UI.prefab");
			if ((Object)(object)smallUI == (Object)null)
			{
				Debug.LogError((object)"PassageDude: smallUI NOT loaded correctly.");
			}
			largeUI = bundle.LoadAsset<GameObject>("Assets/PassageDude/Prefabs/largeUIAnchor.prefab");
			if ((Object)(object)largeUI == (Object)null)
			{
				Debug.LogError((object)"PassageDude: largeUI NOT loaded correctly.");
			}
			oceanMap = bundle.LoadAsset<Texture>("Assets/PassageDude/Textures/oceanMap.png");
			alAnkhMap = bundle.LoadAsset<Texture>("Assets/PassageDude/Textures/alAnkhMap.png");
			emeraldMap = bundle.LoadAsset<Texture>("Assets/PassageDude/Textures/emeraldMap.png");
			aestrinMap = bundle.LoadAsset<Texture>("Assets/PassageDude/Textures/aestrinMap.png");
			lagoonMap = bundle.LoadAsset<Texture>("Assets/PassageDude/Textures/lagoonMap.png");
		}
		else
		{
			Debug.LogError((object)"PassageDude: Bundle not loaded correctly.");
		}
	}
}
public class PassageDudePatches
{
	private static bool[] loadedIslands = new bool[Refs.islands.Length];

	private static bool[] dudeSpawned = new bool[Refs.islands.Length];

	public static bool[] hasDude = new bool[33]
	{
		false, true, true, true, true, false, false, false, false, true,
		false, true, true, true, false, true, true, true, true, true,
		true, true, false, false, false, false, true, true, false, false,
		false, false, false
	};

	public static bool justTeleported;

	private static GameObject[] dudes = (GameObject[])(object)new GameObject[Refs.islands.Length];

	[HarmonyPostfix]
	public static void LoadIsland(IslandHorizon __instance)
	{
		int islandIndex = __instance.islandIndex;
		if (!GameState.playing && !GameState.currentlyLoading && !GameState.sleeping)
		{
			return;
		}
		for (int i = 0; i < Refs.islands.Length; i++)
		{
			if ((Object)(object)Refs.islands[i] != (Object)null)
			{
				if (i == islandIndex)
				{
					loadedIslands[i] = true;
				}
				else if (!dudeSpawned[i] && islandIndex != 31)
				{
					loadedIslands[i] = false;
				}
			}
		}
	}

	[HarmonyPrefix]
	public static void UnloadIsland(IslandHorizon __instance)
	{
		int islandIndex = __instance.islandIndex;
		if (!GameState.playing && !GameState.currentlyLoading && !GameState.sleeping)
		{
			return;
		}
		for (int i = 0; i < Refs.islands.Length; i++)
		{
			if ((Object)(object)Refs.islands[i] != (Object)null && i == islandIndex)
			{
				DespawnDude(islandIndex);
				loadedIslands[i] = false;
			}
		}
	}

	[HarmonyPostfix]
	public static void Awake_Patch(IslandStreetlightsManager __instance)
	{
		IslandSceneryScene component = ((Component)((Component)__instance).transform).GetComponent<IslandSceneryScene>();
		int parentIslandIndex = component.parentIslandIndex;
		if ((Object)(object)component != (Object)null && !dudeSpawned[parentIslandIndex] && loadedIslands[parentIslandIndex])
		{
			SpawnDude(((Component)__instance).transform, parentIslandIndex);
			dudeSpawned[parentIslandIndex] = true;
		}
	}

	public static void SpawnDude(Transform position, int index)
	{
		if (hasDude[index])
		{
			dudes[index] = Object.Instantiate<GameObject>(PassageDudeMain.dudesPrefab[index], position);
			if ((Object)(object)dudes[index] != (Object)null)
			{
				SmallUI.passageIndex = index;
				SmallUI.dudeTransform = dudes[index].transform;
				dudes[index].AddComponent<SmallUI>();
				Transform child = dudes[index].transform.GetChild(2).GetChild(0).GetChild(0)
					.GetChild(0);
				if ((Object)(object)child != (Object)null)
				{
					((Component)child).gameObject.AddComponent<GPButtonBook>();
					((Component)child).GetComponent<GPButtonBook>().dudeTransform = dudes[index].transform;
					((GoPointerButton)((Component)child).GetComponent<GPButtonBook>()).description = "Open passage offers";
					if (!((Object)(object)((Component)child).GetComponent<GPButtonBook>() == (Object)null))
					{
					}
				}
			}
		}
		if (justTeleported && GameState.recovering)
		{
			GameState.recovering = false;
			justTeleported = false;
		}
	}

	public static void DespawnDude(int index)
	{
		if (loadedIslands[index] && dudeSpawned[index])
		{
			Object.Destroy((Object)(object)dudes[index]);
			dudeSpawned[index] = false;
		}
	}
}
public class SmallUI : MonoBehaviour
{
	public static GameObject smallUI;

	public static GameObject largeUI;

	public static Transform dudeTransform;

	public static int passageIndex;

	public static bool instantiatedUI;

	private void Awake()
	{
		if (!instantiatedUI)
		{
			InstantiateUI();
			instantiatedUI = true;
		}
	}

	private static void InstantiateUI()
	{
		Transform shiftingWorld = Refs.shiftingWorld;
		smallUI = Object.Instantiate<GameObject>(PassageDudeMain.smallUI, shiftingWorld);
		((Component)smallUI.transform.GetChild(0).GetChild(0).GetChild(0)).gameObject.AddComponent<SmallUIButton>();
		largeUI = Object.Instantiate<GameObject>(PassageDudeMain.largeUI, shiftingWorld);
		largeUI.AddComponent<LargeUI>();
		LargeUI.AddButtonComponents();
		if ((Object)(object)smallUI != (Object)null && (Object)(object)largeUI != (Object)null)
		{
			largeUI.SetActive(false);
			smallUI.SetActive(false);
		}
		else
		{
			Debug.LogError((object)"PassageDude: smallUI or LargeUI not instantiated correctly");
		}
	}

	public static void ShowSmallUI(Transform passageDude)
	{
		//IL_0018: 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)
		smallUI.SetActive(true);
		smallUI.transform.position = passageDude.position;
		smallUI.transform.rotation = passageDude.rotation;
		UISoundPlayer.instance.PlayUISound((UISounds)6, 0.75f, 1f);
	}

	public static void HideSmallUI()
	{
		smallUI.SetActive(false);
	}

	public static void OpenBook()
	{
		LargeUI.passageIndex = passageIndex;
		LargeUI.OpenLargeUI();
	}

	public void OnTriggerExit(Collider other)
	{
		if (((Component)other).CompareTag("Player") && instantiatedUI)
		{
			HideSmallUI();
		}
	}
}
public class LargeUI : MonoBehaviour
{
	public static int passageIndex;

	private static int portIndex;

	private static TextMesh[] allText;

	private static TextMesh originPort;

	private static TextMesh destinationPort;

	private static TextMesh cost;

	private static TextMesh time;

	private static TextMesh risk;

	private static TextMesh distance;

	private static TextMesh passageName;

	private static TextMesh notEnough;

	private static TextMesh passage0text;

	private static TextMesh passage1text;

	private static TextMesh passage2text;

	private static TextMesh passage3text;

	private static TextMesh passage4text;

	private static TextMesh portName;

	private static TextMesh approximateLocation;

	private static TextMesh noGlobalPassages;

	public static GameObject largeUI;

	public static bool localOffers = true;

	public static int selectedPassage;

	private static Transform player;

	private static Vector3 mapZoomedPos = new Vector3(0.6f, 0.1f, 2.2f);

	private static Vector3 mapPos;

	public static Material activeMat;

	public static Material inactiveMat;

	public static bool generatedPassages;

	public static FerryPassage[] passages = new FerryPassage[10];

	public static string[] truncatedCodes = new string[10];

	public static string[] passageCodes = new string[10];

	public static ModDataManager modDataManager = new ModDataManager("pr0skynesis.passagedude");

	private static bool isMajor;

	private void Awake()
	{
		largeUI = SmallUI.largeUI;
		passageIndex = SmallUI.passageIndex;
		FerryIndexToPortIndex();
		if (portIndex == 0 || portIndex == 9 || portIndex == 15 || portIndex == 23 || portIndex == 6 || portIndex == 20)
		{
			isMajor = true;
		}
		else
		{
			isMajor = false;
		}
		InitialiseText();
		player = Refs.ovrCameraRig;
		for (int i = 0; i < passages.Length; i++)
		{
			passages[i] = new FerryPassage();
		}
		LoadPassagesData();
	}

	private static void GetAvailablePassages(bool noLocal, bool noGlobal)
	{
		int num = 2;
		int num2 = 3;
		int maxAttempts = 8;
		float num3 = 0.3f;
		if (isMajor)
		{
			num++;
			num2 += 2;
			maxAttempts = 12;
			num3 += 0.2f;
		}
		else
		{
			for (int i = 0; i < 5; i++)
			{
				passages[9 - i] = null;
			}
		}
		if (!generatedPassages)
		{
			if (isMajor && !noGlobal)
			{
				int num4 = 5;
				int num5 = 0;
				for (int j = 0; j < num2; j++)
				{
					if (j < num || Random.value < num3)
					{
						string text = UniquePassage(num4, 1, maxAttempts);
						if (text != null)
						{
							PassageFromCode(text);
							num4++;
						}
						else
						{
							num5++;
						}
					}
					else
					{
						num5++;
					}
				}
				for (int k = 0; k < num5; k++)
				{
					passages[9 - k] = null;
				}
			}
			if (!noLocal)
			{
				int num6 = 0;
				int num7 = 0;
				for (int l = 0; l < num2; l++)
				{
					if (l < num || Random.value < num3)
					{
						string text = UniquePassage(num6, 0, maxAttempts);
						if (text != null)
						{
							PassageFromCode(text);
							num6++;
						}
						else
						{
							num7++;
						}
					}
					else
					{
						num7++;
					}
				}
				if (portIndex == 6 || portIndex == 20)
				{
					num6 = 0;
				}
				for (int m = 0; m < 5 - num6; m++)
				{
					passages[4 - m] = null;
				}
			}
			modDataManager.SavePassagesData(passageCodes);
			generatedPassages = true;
		}
		else
		{
			if (passages[0] != null && passages[0].expirationDay < GameState.day)
			{
				ResetPassages(onlyLocal: true);
				RefreshPassages(noLocal: false, noGlobal: true);
			}
			else if (passages[5] != null && passages[5].expirationDay < GameState.day && isMajor)
			{
				ResetPassages(onlyLocal: false);
				RefreshPassages(noLocal: true, noGlobal: false);
			}
			modDataManager.SavePassagesData(passageCodes);
		}
		selectedPassage = 0;
		localOffers = true;
		if (portIndex == 6 || portIndex == 20)
		{
			selectedPassage = 5;
			localOffers = false;
		}
		RefreshText();
		RefreshOffersButton();
	}

	private static string UniquePassage(int offerNumber, int isGlobal, int maxAttempts)
	{
		for (int i = 0; i < maxAttempts; i++)
		{
			string text = GeneratePassage(offerNumber, isGlobal);
			string text2 = text.Split(new char[1] { 'e' })[1];
			if (!truncatedCodes.Contains(text2))
			{
				passageCodes[offerNumber] = text;
				truncatedCodes[offerNumber] = text2;
				return text;
			}
		}
		return null;
	}

	private static string GeneratePassage(int offerNumber, int isGlobal)
	{
		string text = $"{offerNumber}#";
		text += $"{GenerateExpirationDate(isGlobal)}e";
		text += $"{portIndex}o";
		int region = GetRegion(portIndex);
		int num = 0;
		int[] ports = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
		float[] weights = new float[7] { 1.5f, 0.8f, 0.8f, 0.4f, 0f, 0f, 0f };
		int[] ports2 = new int[6] { 9, 10, 11, 12, 13, 14 };
		float[] weights2 = new float[6] { 1.5f, 0f, 0.6f, 0.6f, 0.6f, 0f };
		int[] ports3 = new int[6] { 15, 16, 17, 18, 19, 20 };
		float[] weights3 = new float[6] { 1.5f, 0.2f, 0.6f, 0.6f, 0.6f, 0f };
		int[] ports4 = new int[4] { 22, 23, 24, 25 };
		float[] weights4 = new float[4] { 0.8f, 1f, 0f, 0f };
		int[] ports5 = new int[6] { 0, 9, 15, 23, 6, 20 };
		float[] weights5 = new float[6] { 0f, 1f, 1f, 0.5f, 1f, 0.3f };
		float[] weights6 = new float[6] { 1f, 0f, 1f, 1f, 0.1f, 0.8f };
		float[] weights7 = new float[6] { 1f, 1f, 0f, 0f, 0.3f, 0.8f };
		float[] weights8 = new float[6] { 0.7f, 1f, 0f, 0f, 0f, 0f };
		float[] weights9 = new float[6] { 1f, 0.5f, 0.6f, 0f, 0f, 0.6f };
		float[] weights10 = new float[6] { 0.2f, 1f, 1f, 0f, 0.1f, 0f };
		if (isGlobal == 1)
		{
			if (portIndex == 0)
			{
				num = GenerateDestination(ports5, weights5);
			}
			else if (portIndex == 9)
			{
				num = GenerateDestination(ports5, weights6);
			}
			else if (portIndex == 15)
			{
				num = GenerateDestination(ports5, weights7);
			}
			else if (portIndex == 23)
			{
				num = GenerateDestination(ports5, weights8);
			}
			else if (portIndex == 6)
			{
				num = GenerateDestination(ports5, weights9);
			}
			else if (portIndex == 20)
			{
				num = GenerateDestination(ports5, weights10);
			}
		}
		else
		{
			switch (region)
			{
			case 0:
				if (portIndex == 6)
				{
					float[] weights12 = new float[7] { 1f, 0.2f, 0.2f, 0.1f, 0f, 0f, 0f };
					num = GenerateDestination(ports, weights12);
				}
				else
				{
					num = GenerateDestination(ports, weights);
				}
				break;
			case 1:
				num = GenerateDestination(ports2, weights2);
				break;
			case 2:
				if (portIndex == 20)
				{
					float[] weights11 = new float[6] { 1f, 0.1f, 0.2f, 0.2f, 0.1f, 0f };
					num = GenerateDestination(ports3, weights11);
				}
				else
				{
					num = GenerateDestination(ports3, weights3);
				}
				break;
			default:
				num = GenerateDestination(ports4, weights4);
				break;
			}
		}
		text += $"{num}d";
		int num2 = GenerateBoat(isGlobal);
		text += $"{num2}b";
		return text + $"{isGlobal}g";
	}

	private static void PassageFromCode(string passageCode)
	{
		if (passageCode == "" || passageCode == null)
		{
			Debug.LogError((object)"PassageDude: SavePassageFromCode was given an empty or null code, aborting...");
			return;
		}
		string[] array = passageCode.Split(new char[6] { '#', 'e', 'o', 'd', 'b', 'g' }, StringSplitOptions.RemoveEmptyEntries);
		int num = int.Parse(array[0]);
		int expirationDay = int.Parse(array[1]);
		int num2 = int.Parse(array[3]);
		int num3 = int.Parse(array[4]);
		int num4 = int.Parse(array[5]);
		int region = GetRegion(portIndex);
		int region2 = GetRegion(num2);
		int num5 = Mathf.RoundToInt(Mission.GetDistance(Port.ports[portIndex], Port.ports[num2]));
		int[] array2 = new int[6] { 4, 6, 5, 7, 3, 5 };
		int[] array3 = new int[6] { 7, 9, 8, 10, 6, 8 };
		float num6 = (float)num5 / ((float)array3[num3] / 1.555f);
		float num7 = (float)num5 / ((float)array2[num3] / 1.555f);
		if (region != region2 && ((region == 0 && region2 != 2) || (region == 1 && (region2 != 0 || region2 != 3)) || (region == 2 && (region2 != 1 || region2 != 3)) || (region == 3 && (region2 != 0 || region2 != 1))))
		{
			num6 *= 1.05f;
			num7 *= 1.1f;
		}
		float[] array4 = new float[6] { 0.3f, 0.1f, 0.4f, 0.15f, 0.2f, 0.05f };
		float[] array5 = new float[4] { 0.1f, 0.2f, 0.15f, 0.25f };
		float num8 = (array5[region] + array5[region2]) / 2f;
		float num9 = (float)num5 / 3000f;
		float num10 = array4[num3] + num8 + num9;
		int[] array6 = new int[6] { 15, 40, 20, 50, 10, 60 };
		float num11 = ((num4 != 1) ? Mathf.Abs(PassageDudeMain.localPriceMultiplierConfig.Value) : Mathf.Abs(PassageDudeMain.worldPriceMultiplierConfig.Value));
		float num12 = 1f + Random.Range(-0.2f, 0.2f);
		int num13 = Mathf.RoundToInt((float)(num5 * array6[num3]) * GetExchangeRate(region) * num11 * num12);
		string passageCode2 = num + "#" + expirationDay + "e" + portIndex + "o" + num2 + "d" + num3 + "b" + num4 + "g";
		passages[num].offerNumber = num;
		passages[num].passageCode = passageCode2;
		passages[num].originPort = portIndex;
		passages[num].destinationIndex = num2;
		passages[num].boat = num3;
		passages[num].distance = num5;
		passages[num].risk = num10;
		passages[num].cost = num13;
		passages[num].minTime = num6;
		passages[num].maxTime = num7;
		passages[num].isGlobal = num4;
		passages[num].expirationDay = expirationDay;
	}

	private static int GenerateExpirationDate(int isGlobal)
	{
		if (isGlobal == 1)
		{
			return GameState.day + 2;
		}
		return GameState.day + 1;
	}

	private static void ResetPassages(bool onlyLocal)
	{
		if (onlyLocal)
		{
			for (int i = 0; i < 5; i++)
			{
				truncatedCodes[i] = "";
				passageCodes[i] = "";
				passages[i] = new FerryPassage();
			}
		}
		else
		{
			for (int j = 5; j < 10; j++)
			{
				truncatedCodes[j] = "";
				passageCodes[j] = "";
				passages[j] = new FerryPassage();
			}
		}
		generatedPassages = false;
	}

	private static void RefreshPassages(bool noLocal, bool noGlobal)
	{
		GetAvailablePassages(noLocal, noGlobal);
		RefreshText();
		RefreshOffersButton();
	}

	private static void LoadPassagesData()
	{
		if (!modDataManager.HasValidData(portIndex))
		{
			return;
		}
		passageCodes = modDataManager.LoadPassagesData();
		for (int i = 0; i < passageCodes.Length; i++)
		{
			if (passageCodes[i] != "")
			{
				if (int.Parse(passageCodes[i].Split('#', 'e', 'o')[2]) == portIndex)
				{
					PassageFromCode(passageCodes[i]);
				}
				else
				{
					passages[i] = null;
				}
			}
			else
			{
				passages[i] = null;
			}
		}
		generatedPassages = true;
	}

	public static void OpenLargeUI()
	{
		FerryIndexToPortIndex();
		MouseLook.ToggleMouseLookAndCursor(false);
		Refs.SetPlayerControl(false);
		if ((Object)(object)largeUI != (Object)null)
		{
			largeUI.SetActive(true);
		}
		else
		{
			Debug.LogError((object)"PassageDude: largeUI is null!");
		}
		PositionUI();
		if (isMajor)
		{
			GetAvailablePassages(noLocal: false, noGlobal: false);
		}
		else
		{
			GetAvailablePassages(noLocal: false, noGlobal: true);
		}
		localOffers = true;
		selectedPassage = 0;
		if (portIndex == 6 || portIndex == 20)
		{
			selectedPassage = 5;
			localOffers = false;
		}
		DrawOnMap();
		UISoundPlayer.instance.PlayOpenSound();
	}

	public static void CloseLargeUI()
	{
		largeUI.SetActive(false);
		MouseLook.ToggleMouseLookAndCursor(true);
		Refs.SetPlayerControl(true);
		UISoundPlayer.instance.PlayCloseSound();
	}

	private static void PositionUI()
	{
		//IL_000b: 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)
		//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_0023: 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_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		Vector3 forward = ((Component)player).transform.forward;
		float num = 0.02f;
		Vector3 position = player.position + forward * num;
		largeUI.transform.position = position;
		largeUI.transform.parent = player;
		largeUI.transform.LookAt(player);
		largeUI.transform.Translate(0f, -0.425f, 0f);
	}

	private static void InitialiseText()
	{
		allText = largeUI.GetComponentsInChildren<TextMesh>();
		originPort = allText[2];
		destinationPort = allText[4];
		cost = allText[6];
		time = allText[7];
		risk = allText[8];
		distance = allText[10];
		passageName = allText[11];
		notEnough = allText[12];
		passage0text = allText[13];
		passage1text = allText[14];
		passage2text = allText[15];
		passage3text = allText[16];
		passage4text = allText[17];
		portName = allText[21];
		approximateLocation = allText[23];
		noGlobalPassages = allText[24];
	}

	public static void RefreshText()
	{
		originPort.text = Port.ports[portIndex].GetPortName();
		destinationPort.text = Port.ports[passages[selectedPassage].destinationIndex].GetPortName();
		cost.text = $"{passages[selectedPassage].cost}";
		time.text = GetTime(Mathf.RoundToInt(passages[selectedPassage].minTime)) + " /\n" + GetTime(Mathf.RoundToInt(passages[selectedPassage].maxTime));
		risk.text = $"{Mathf.Round(passages[selectedPassage].risk * 100f)}%";
		distance.text = $"{passages[selectedPassage].distance} miles";
		passageName.text = GetBoatFromIndex(passages[selectedPassage].boat) + " to " + Port.ports[passages[selectedPassage].destinationIndex].GetPortName();
		if (PlayerGold.currency[GetLocalCurrency(GetRegion(portIndex))] < passages[selectedPassage].cost)
		{
			notEnough.text = "You don't have enough money!\nLocal currency only!";
		}
		else
		{
			notEnough.text = "";
		}
		if (localOffers)
		{
			if (portIndex == 6 || portIndex == 20)
			{
				noGlobalPassages.text = "No passages to other minor islands\nin the archipelago are available\nhere. You should travel to a capital\nfirst...";
			}
			else
			{
				noGlobalPassages.text = "";
			}
			if (passages[0] == null)
			{
				((Component)((Component)passage0text).transform.parent).gameObject.SetActive(false);
			}
			else
			{
				((Component)((Component)passage0text).transform.parent).gameObject.SetActive(true);
				passage0text.text = GetBoatFromIndex(passages[0].boat) + " to " + Port.ports[passages[0].destinationIndex].GetPortName();
			}
			if (passages[1] == null)
			{
				((Component)((Component)passage1text).transform.parent).gameObject.SetActive(false);
			}
			else
			{
				((Component)((Component)passage1text).transform.parent).gameObject.SetActive(true);
				passage1text.text = GetBoatFromIndex(passages[1].boat) + " to " + Port.ports[passages[1].destinationIndex].GetPortName();
			}
			if (passages[2] == null)
			{
				((Component)((Component)passage2text).transform.parent).gameObject.SetActive(false);
			}
			else
			{
				((Component)((Component)passage2text).transform.parent).gameObject.SetActive(true);
				passage2text.text = GetBoatFromIndex(passages[2].boat) + " to " + Port.ports[passages[2].destinationIndex].GetPortName();
			}
			if (passages[3] == null)
			{
				((Component)((Component)passage3text).transform.parent).gameObject.SetActive(false);
			}
			else
			{
				((Component)((Component)passage3text).transform.parent).gameObject.SetActive(true);
				passage3text.text = GetBoatFromIndex(passages[3].boat) + " to " + Port.ports[passages[3].destinationIndex].GetPortName();
			}
			if (passages[4] == null)
			{
				((Component)((Component)passage4text).transform.parent).gameObject.SetActive(false);
			}
			else
			{
				((Component)((Component)passage4text).transform.parent).gameObject.SetActive(true);
				passage4text.text = GetBoatFromIndex(passages[4].boat) + " to " + Port.ports[passages[4].destinationIndex].GetPortName();
			}
		}
		else
		{
			if (!isMajor)
			{
				noGlobalPassages.text = "No passages to other archipelagos\nare available here. You should travel\nto a major port first...";
			}
			else
			{
				noGlobalPassages.text = "";
			}
			if (passages[5] == null)
			{
				((Component)((Component)passage0text).transform.parent).gameObject.SetActive(false);
			}
			else
			{
				((Component)((Component)passage0text).transform.parent).gameObject.SetActive(true);
				passage0text.text = GetBoatFromIndex(passages[5].boat) + " to " + Port.ports[passages[5].destinationIndex].GetPortName();
			}
			if (passages[6] == null)
			{
				((Component)((Component)passage1text).transform.parent).gameObject.SetActive(false);
			}
			else
			{
				((Component)((Component)passage1text).transform.parent).gameObject.SetActive(true);
				passage1text.text = GetBoatFromIndex(passages[6].boat) + " to " + Port.ports[passages[6].destinationIndex].GetPortName();
			}
			if (passages[7] == null)
			{
				((Component)((Component)passage2text).transform.parent).gameObject.SetActive(false);
			}
			else
			{
				((Component)((Component)passage2text).transform.parent).gameObject.SetActive(true);
				passage2text.text = GetBoatFromIndex(passages[7].boat) + " to " + Port.ports[passages[7].destinationIndex].GetPortName();
			}
			if (passages[8] == null)
			{
				((Component)((Component)passage3text).transform.parent).gameObject.SetActive(false);
			}
			else
			{
				((Component)((Component)passage3text).transform.parent).gameObject.SetActive(true);
				passage3text.text = GetBoatFromIndex(passages[8].boat) + " to " + Port.ports[passages[8].destinationIndex].GetPortName();
			}
			if (passages[9] == null)
			{
				((Component)((Component)passage4text).transform.parent).gameObject.SetActive(false);
			}
			else
			{
				((Component)((Component)passage4text).transform.parent).gameObject.SetActive(true);
				passage4text.text = GetBoatFromIndex(passages[9].boat) + " to " + Port.ports[passages[9].destinationIndex].GetPortName();
			}
		}
		portName.text = Port.ports[portIndex].GetPortName();
		if ((GetRegion(portIndex) != 3 && passages[selectedPassage].destinationIndex == 23) || (GetRegion(portIndex) == 3 && GetRegion(passages[selectedPassage].destinationIndex) != 3))
		{
			approximateLocation.text = "Map unavailable,\ntrust the captain!";
			((Component)DrawMap.mapRenderer).gameObject.SetActive(false);
		}
		else
		{
			approximateLocation.text = "";
			((Component)DrawMap.mapRenderer).gameObject.SetActive(true);
		}
		LargeUIBuyPassageButton.instance.destination = Port.ports[passages[selectedPassage].destinationIndex];
		LargeUIBuyPassageButton.instance.maxTime = passages[selectedPassage].maxTime;
		LargeUIBuyPassageButton.instance.minTime = passages[selectedPassage].minTime;
		LargeUIBuyPassageButton.instance.risk = passages[selectedPassage].risk;
		LargeUIBuyPassageButton.instance.cost = passages[selectedPassage].cost;
		LargeUIBuyPassageButton.instance.currency = GetLocalCurrency(GetRegion(portIndex));
	}

	public static void AddButtonComponents()
	{
		//IL_0410: Unknown result type (might be due to invalid IL or missing references)
		//IL_0415: Unknown result type (might be due to invalid IL or missing references)
		((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(5)
			.GetChild(0)
			.GetChild(0)).gameObject.AddComponent<LargeUICloseButton>();
		((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(5)
			.GetChild(2)
			.GetChild(0)).gameObject.AddComponent<LargeUILocalButton>();
		((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(5)
			.GetChild(1)
			.GetChild(0)).gameObject.AddComponent<LargeUIWorldButton>();
		((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(0)
			.GetChild(0)).gameObject.AddComponent<LargeUIPassageButton>();
		((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(1)
			.GetChild(0)).gameObject.AddComponent<LargeUIPassageButton>();
		((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(2)
			.GetChild(0)).gameObject.AddComponent<LargeUIPassageButton>();
		((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(3)
			.GetChild(0)).gameObject.AddComponent<LargeUIPassageButton>();
		((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(4)
			.GetChild(0)).gameObject.AddComponent<LargeUIPassageButton>();
		if (localOffers)
		{
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(0)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 0;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(1)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 1;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(2)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 2;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(3)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 3;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(4)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 4;
		}
		else
		{
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(0)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 5;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(1)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 6;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(2)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 7;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(3)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 8;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(4)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 9;
		}
		activeMat = ((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(5)
			.GetChild(2)
			.GetChild(0)).GetComponent<Renderer>().material;
		inactiveMat = ((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(5)
			.GetChild(1)
			.GetChild(0)).GetComponent<Renderer>().material;
		((Component)largeUI.transform.GetChild(0).GetChild(0).GetChild(0)
			.GetChild(1)).gameObject.AddComponent<LargeUIMapButton>();
		mapPos = largeUI.transform.GetChild(0).GetChild(0).GetChild(0)
			.GetChild(1)
			.localPosition;
		((Component)largeUI.transform.GetChild(0).GetChild(0).GetChild(0)
			.GetChild(1)).gameObject.AddComponent<DrawMap>();
		DrawMap.routeLine = ((Component)largeUI.transform.GetChild(0).GetChild(0).GetChild(0)
			.GetChild(1)
			.GetChild(6)).gameObject.GetComponent<LineRenderer>();
		((Renderer)DrawMap.routeLine).material.renderQueue = 3001;
		DrawMap.destinationMarker = ((Component)largeUI.transform.GetChild(0).GetChild(0).GetChild(0)
			.GetChild(1)
			.GetChild(7)).gameObject.GetComponent<Transform>();
		((Component)DrawMap.destinationMarker).gameObject.GetComponent<Renderer>().material.renderQueue = 3001;
		DrawMap.mapRenderer = ((Component)largeUI.transform.GetChild(0).GetChild(0).GetChild(0)
			.GetChild(1)).gameObject.GetComponent<Renderer>();
		DrawMap.oceanMap = PassageDudeMain.oceanMap;
		DrawMap.alAnkhMap = PassageDudeMain.alAnkhMap;
		DrawMap.emeraldMap = PassageDudeMain.emeraldMap;
		DrawMap.aestrinMap = PassageDudeMain.aestrinMap;
		DrawMap.lagoonMap = PassageDudeMain.lagoonMap;
		((Component)largeUI.transform.GetChild(0).GetChild(0).GetChild(0)
			.GetChild(0)
			.GetChild(0)).gameObject.AddComponent<LargeUIBuyPassageButton>();
		LargeUIBuyPassageButton.instance.destination = Port.ports[passages[selectedPassage].destinationIndex];
		LargeUIBuyPassageButton.instance.maxTime = passages[selectedPassage].maxTime;
		LargeUIBuyPassageButton.instance.minTime = passages[selectedPassage].minTime;
		LargeUIBuyPassageButton.instance.risk = passages[selectedPassage].risk;
		LargeUIBuyPassageButton.instance.cost = passages[selectedPassage].cost;
	}

	public static void RefreshOffersButton()
	{
		if (localOffers)
		{
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(0)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 0;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(1)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 1;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(2)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 2;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(3)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 3;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(4)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 4;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(5)
				.GetChild(2)
				.GetChild(0)).GetComponent<Renderer>().material = activeMat;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(5)
				.GetChild(1)
				.GetChild(0)).GetComponent<Renderer>().material = inactiveMat;
		}
		else
		{
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(0)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 5;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(1)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 6;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(2)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 7;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(3)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 8;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(4)
				.GetChild(0)).GetComponent<LargeUIPassageButton>().offerNumber = 9;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(5)
				.GetChild(2)
				.GetChild(0)).GetComponent<Renderer>().material = inactiveMat;
			((Component)largeUI.transform.GetChild(0).GetChild(1).GetChild(5)
				.GetChild(1)
				.GetChild(0)).GetComponent<Renderer>().material = activeMat;
		}
	}

	public static void ZoomMap(bool zoomed)
	{
		//IL_0099: 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)
		if (!zoomed)
		{
			largeUI.transform.GetChild(0).GetChild(0).GetChild(0)
				.GetChild(1)
				.localPosition = mapZoomedPos;
			((Component)largeUI.transform.GetChild(0).GetChild(0).GetChild(0)
				.GetChild(1)).gameObject.GetComponent<Renderer>().material.renderQueue = 3001;
		}
		else
		{
			largeUI.transform.GetChild(0).GetChild(0).GetChild(0)
				.GetChild(1)
				.localPosition = mapPos;
			((Component)largeUI.transform.GetChild(0).GetChild(0).GetChild(0)
				.GetChild(1)).gameObject.GetComponent<Renderer>().material.renderQueue = 2450;
		}
	}

	public static void DrawOnMap()
	{
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: 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)
		bool flag = false;
		if (passages[selectedPassage].isGlobal == 1 || portIndex == 6 || portIndex == 20)
		{
			flag = true;
		}
		if (flag)
		{
			if (passages[selectedPassage].destinationIndex != 23 && GetRegion(portIndex) != 3)
			{
				SetMapTexture(DrawMap.oceanMap);
				DrawMap.routeLine.SetPosition(0, Port.ports[portIndex].oceanMapLocation.localPosition);
				DrawMap.routeLine.SetPosition(1, Port.ports[passages[selectedPassage].destinationIndex].oceanMapLocation.localPosition);
				DrawMap.destinationMarker.localPosition = Port.ports[passages[selectedPassage].destinationIndex].oceanMapLocation.localPosition;
			}
			return;
		}
		if (GetRegion(portIndex) == 0)
		{
			SetMapTexture(DrawMap.alAnkhMap);
		}
		else if (GetRegion(portIndex) == 1)
		{
			SetMapTexture(DrawMap.emeraldMap);
		}
		else if (GetRegion(portIndex) == 2)
		{
			SetMapTexture(DrawMap.aestrinMap);
		}
		else if (GetRegion(portIndex) == 3)
		{
			SetMapTexture(DrawMap.lagoonMap);
		}
		DrawMap.routeLine.SetPosition(0, Port.ports[portIndex].localMapLocation.localPosition);
		DrawMap.routeLine.SetPosition(1, Port.ports[passages[selectedPassage].destinationIndex].localMapLocation.localPosition);
		DrawMap.destinationMarker.localPosition = Port.ports[passages[selectedPassage].destinationIndex].localMapLocation.localPosition;
	}

	private static void SetMapTexture(Texture tex)
	{
		DrawMap.mapRenderer.material.SetTexture("_EmissionMap", tex);
		DrawMap.mapRenderer.material.SetTexture("_MainTex", tex);
	}

	private static void FerryIndexToPortIndex()
	{
		switch (passageIndex)
		{
		case 1:
			portIndex = 0;
			break;
		case 2:
			portIndex = 1;
			break;
		case 3:
			portIndex = 2;
			break;
		case 4:
			portIndex = 3;
			break;
		case 7:
			portIndex = 4;
			break;
		case 8:
			portIndex = 5;
			break;
		case 20:
			portIndex = 6;
			break;
		case 9:
			portIndex = 9;
			break;
		case 10:
			portIndex = 10;
			break;
		case 11:
			portIndex = 11;
			break;
		case 12:
			portIndex = 12;
			break;
		case 13:
			portIndex = 13;
			break;
		case 22:
			portIndex = 14;
			break;
		case 15:
			portIndex = 15;
			break;
		case 16:
			portIndex = 16;
			break;
		case 17:
			portIndex = 17;
			break;
		case 18:
			portIndex = 20;
			break;
		case 19:
			portIndex = 19;
			break;
		case 21:
			portIndex = 18;
			break;
		case 26:
			portIndex = 23;
			break;
		case 27:
			portIndex = 22;
			break;
		case 28:
			portIndex = 25;
			break;
		case 29:
			portIndex = 24;
			break;
		case 5:
		case 6:
		case 14:
		case 23:
		case 24:
		case 25:
			break;
		}
	}

	private static int GetRegion(int portIndex)
	{
		if (portIndex >= 0 && portIndex <= 6)
		{
			return 0;
		}
		if (portIndex >= 9 && portIndex <= 14)
		{
			return 1;
		}
		if (portIndex >= 15 && portIndex <= 20)
		{
			return 2;
		}
		if (portIndex >= 22)
		{
			return 3;
		}
		return 0;
	}

	private static int GenerateDestination(int[] ports, float[] weights)
	{
		int[] array = ports.Where((int value, int index) => value != portIndex).ToArray();
		float[] source = weights.Where((float weight, int index) => ports[index] != portIndex).ToArray();
		float totalWeight = source.Sum();
		float[] array2 = source.Select((float weight) => weight / totalWeight).ToArray();
		float value2 = Random.value;
		float num = 0f;
		for (int i = 0; i < array.Length; i++)
		{
			num += array2[i];
			if (value2 < num)
			{
				return array[i];
			}
		}
		return array.Last();
	}

	private static int GenerateBoat(int isGlobal)
	{
		int region = GetRegion(portIndex);
		float value = Random.value;
		float num = 0.8f;
		if (isGlobal == 1)
		{
			if (value <= 0.33f)
			{
				return 1;
			}
			if (value <= 0.66f)
			{
				return 3;
			}
			return 5;
		}
		if (portIndex == 0 || portIndex == 9 || portIndex == 15 || portIndex == 23 || portIndex == 6 || portIndex == 20)
		{
			num = 0.6f;
		}
		if (value > num)
		{
			switch (region)
			{
			case 0:
				return 1;
			default:
				if (region != 3)
				{
					return 5;
				}
				goto case 1;
			case 1:
				return 3;
			}
		}
		switch (region)
		{
		case 0:
			return 0;
		default:
			if (region != 3)
			{
				return 4;
			}
			goto case 1;
		case 1:
			return 2;
		}
	}

	private static string GetBoatFromIndex(int boatIndex)
	{
		string[] array = new string[6] { "Dhow", "Sanbuq", "Kakam", "Junk", "Cog", "Brig" };
		return array[boatIndex];
	}

	private static int GetLocalCurrency(int region)
	{
		int[] array = new int[4] { 0, 1, 2, 1 };
		return array[region];
	}

	private static string GetTime(int hours)
	{
		int num = hours / 24;
		int num2 = hours % 24;
		if (num > 0)
		{
			if (num2 > 0)
			{
				return $"{num} days, {num2} hours";
			}
			return $"{num} days";
		}
		return $"{num2} hours";
	}

	private static float GetExchangeRate(int region)
	{
		int localCurrency = GetLocalCurrency(region);
		if (localCurrency == 0)
		{
			return 1f;
		}
		return CurrencyMarket.instance.GetExchangeRate(0, localCurrency, false);
	}
}
public class FerryPassage
{
	public int offerNumber;

	public string passageCode;

	public int originPort;

	public int destinationIndex;

	public int boat;

	public int distance;

	public float risk;

	public int cost;

	public float minTime;

	public float maxTime;

	public int isGlobal;

	public int expirationDay;
}
public class DrawMap : MonoBehaviour
{
	public static Texture oceanMap;

	public static Texture alAnkhMap;

	public static Texture emeraldMap;

	public static Texture aestrinMap;

	public static Texture lagoonMap;

	public static Renderer mapRenderer;

	public static LineRenderer routeLine;

	public static Transform destinationMarker;
}
public class ModDataManager
{
	private string modName;

	private const char delimiter = ';';

	public ModDataManager(string modName)
	{
		this.modName = modName;
	}

	public void SavePassagesData(string[] codes)
	{
		string value = string.Join(';'.ToString(), codes);
		GameState.modData[modName] = value;
	}

	public string[] LoadPassagesData()
	{
		if (GameState.modData.TryGetValue(modName, out var value))
		{
			return value.Split(new char[1] { ';' });
		}
		Debug.LogError((object)"PassageDude: returning null from ModDataManager.LoadPassageData()");
		return null;
	}

	public bool HasValidData(int portIndex)
	{
		if (GameState.modData.ContainsKey(modName))
		{
			GameState.modData.TryGetValue(modName, out var value);
			string[] array = value.Split(new char[1] { ';' });
			if (array.Length != 0)
			{
				if (array[0].Contains("#"))
				{
					if (int.Parse(array[0].Split('#', 'e', 'o')[2]) == portIndex)
					{
						return true;
					}
					return false;
				}
				return false;
			}
			return false;
		}
		return false;
	}
}
public class FerryTravel : MonoBehaviour
{
	public Port destination;

	public float maxTime;

	public float minTime;

	public float risk;

	public int cost;

	public int currency;

	public static FerryTravel instance;

	private readonly int msToWait = 1000;

	private readonly int fadeTime = 200;

	private void Awake()
	{
		instance = this;
	}

	public void Travel()
	{
		MouseLook.ToggleMouseLookAndCursor(false);
		Refs.SetPlayerControl(false);
		GameState.recovering = true;
		PassageDudePatches.justTeleported = true;
		DestroyUI();
		TeleportPlayer();
		AdvanceTime(TimeToPass());
		PayForPassage();
		FillNeeds();
	}

	private void TeleportPlayer()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		((Component)Refs.charController).transform.position = GetDestinationCoordinates(destination);
	}

	private void PayForPassage()
	{
		PlayerGold.currency[currency] -= cost;
	}

	private void FillNeeds()
	{
		PlayerNeeds.water = 100f;
		PlayerNeeds.food = 100f;
		PlayerNeeds.foodDebt = 100f;
		PlayerNeeds.sleepDebt = 100f;
		PlayerNeeds.sleep = 100f;
	}

	private void AdvanceTime(float timeToPass)
	{
		float num = Sun.sun.globalTime + timeToPass;
		int num2 = (int)num / 24;
		float globalTime = num % 24f;
		WaitAndFadeOut(msToWait);
		for (int i = 0; i < num2; i++)
		{
			GameState.day++;
			DayLogs.instance.NewDaySheets();
		}
		Sun.sun.globalTime = globalTime;
	}

	private string LoadingBar(float currentValue, float finalValue)
	{
		int num = 1000;
		int num2 = (int)(currentValue * (float)num / finalValue);
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < num; i++)
		{
			if (i < num2)
			{
				stringBuilder.Append("█");
			}
			else
			{
				stringBuilder.Append("░");
			}
		}
		return $"<size=1%><color=orange>{stringBuilder}</color></size>";
	}

	private float TimeToPass()
	{
		float num = 0.5f;
		if (Random.value < risk)
		{
			num = Mathf.Lerp(num, 1f, risk);
			if (Random.value < risk / 10f)
			{
				return maxTime;
			}
		}
		else
		{
			num = Mathf.Lerp(0f, num, 1f - risk);
			if (Random.value < (1f - risk) / 10f)
			{
				return minTime;
			}
		}
		return Mathf.Lerp(minTime, maxTime, num);
	}

	private Vector3 GetDestinationCoordinates(Port destination)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: 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_0029: 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_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: 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_007a: 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_0095: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_0268: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
		Vector3 outCurrentOffset = FloatingOriginManager.instance.outCurrentOffset;
		Vector3[] array = (Vector3[])(object)new Vector3[26]
		{
			new Vector3(-43658.69f, 2.54f, -44098.2f),
			new Vector3(-49041.69f, 2.24f, -42950.55f),
			new Vector3(-48901.4f, 2.32f, -45948.3f),
			new Vector3(-40476.52f, 2.328f, -46683.57f),
			new Vector3(0f, 0f, 0f),
			new Vector3(0f, 0f, 0f),
			new Vector3(-45682.41f, 2.27f, -29275.72f),
			new Vector3(0f, 0f, 0f),
			new Vector3(0f, 0f, 0f),
			new Vector3(42911.99f, 2.263f, -41884.92f),
			new Vector3(0f, 0f, 0f),
			new Vector3(43986.49f, 2.71f, -38776.6f),
			new Vector3(42676.61f, 2.063255f, -35027.15f),
			new Vector3(40584.6f, 2.26f, -45942.49f),
			new Vector3(39620.4f, 2.39f, -37914.31f),
			new Vector3(5707.44f, 3.254f, 38992.54f),
			new Vector3(8423.06f, 2.9f, 102874f / (float)Math.E),
			new Vector3(10462.4f, 2.34f, 35428.92f),
			new Vector3(5216.674f, 2.36f, 42785.71f),
			new Vector3(1981.471f, 2.088894f, 44142.91f),
			new Vector3(32231.65f, 4.37f, -5742.877f),
			new Vector3(0f, 0f, 0f),
			new Vector3(26031.74f, 2.508f, -70995.01f),
			new Vector3(28401.27f, 2.18f, -70677.51f),
			new Vector3(0f, 0f, 0f),
			new Vector3(0f, 0f, 0f)
		};
		return array[destination.portIndex] + outCurrentOffset;
	}

	private void DestroyUI()
	{
		Object.Destroy((Object)(object)LargeUI.largeUI);
		Object.Destroy((Object)(object)SmallUI.largeUI);
		Object.Destroy((Object)(object)SmallUI.smallUI);
		SmallUI.instantiatedUI = false;
		LargeUI.generatedPassages = false;
	}

	private async Task WaitAndFadeOut(int milliseconds)
	{
		while (milliseconds > 0)
		{
			if (milliseconds == msToWait)
			{
				((Component)Camera.main).GetComponent<OVRScreenFade>().SetFadeLevel(1f);
			}
			await Task.Delay(1);
			Sleep.instance.recoveryText.text = "<size=40%>Travelling to</size>\n" + destination.GetPortName() + "\n" + LoadingBar(msToWait - milliseconds, msToWait);
			milliseconds--;
			if (milliseconds == 0)
			{
				Sleep.instance.recoveryText.text = "";
				FadeIn(fadeTime);
				MouseLook.ToggleMouseLookAndCursor(true);
				Refs.SetPlayerControl(true);
			}
		}
	}

	private async Task FadeIn(int milliseconds)
	{
		float targetAlpha = 0f;
		OVRScreenFade fade = ((Component)Camera.main).GetComponent<OVRScreenFade>();
		float initialAlpha = fade.currentAlpha;
		if (milliseconds == fadeTime)
		{
		}
		while (milliseconds > 0)
		{
			float fadeLevel = Mathf.Lerp(initialAlpha, targetAlpha, (float)(fadeTime - milliseconds) / 100f);
			await Task.Delay(1);
			fade.SetFadeLevel(fadeLevel);
			milliseconds--;
		}
		if (milliseconds == 0)
		{
			fade.SetFadeLevel(0f);
		}
	}
}
public class GPButtonBook : GoPointerButton
{
	public Transform dudeTransform;

	public override void OnActivate()
	{
		SmallUI.ShowSmallUI(dudeTransform);
		((GoPointerButton)this).ForceUnlook();
	}
}
public class SmallUIButton : GoPointerButton
{
	public override void OnActivate()
	{
		SmallUI.HideSmallUI();
		SmallUI.OpenBook();
		((GoPointerButton)this).ForceUnlook();
	}
}
public class LargeUICloseButton : GoPointerButton
{
	public override void OnActivate()
	{
		LargeUI.CloseLargeUI();
		((GoPointerButton)this).ForceUnlook();
	}
}
public class LargeUILocalButton : GoPointerButton
{
	public override void OnActivate()
	{
		LargeUI.localOffers = true;
		UISoundPlayer.instance.PlayUISound((UISounds)0, 0.5f, 1f);
		LargeUI.RefreshText();
		LargeUI.DrawOnMap();
		LargeUI.RefreshOffersButton();
		((GoPointerButton)this).ForceUnlook();
	}
}
public class LargeUIWorldButton : GoPointerButton
{
	public override void OnActivate()
	{
		LargeUI.localOffers = false;
		UISoundPlayer.instance.PlayUISound((UISounds)0, 0.5f, 1f);
		LargeUI.RefreshText();
		LargeUI.DrawOnMap();
		LargeUI.RefreshOffersButton();
		((GoPointerButton)this).ForceUnlook();
	}
}
public class LargeUIPassageButton : GoPointerButton
{
	public int offerNumber;

	public override void OnActivate()
	{
		LargeUI.selectedPassage = offerNumber;
		UISoundPlayer.instance.PlayUISound((UISounds)0, 0.5f, 1f);
		LargeUI.RefreshText();
		LargeUI.DrawOnMap();
		((GoPointerButton)this).ForceUnlook();
	}
}
public class LargeUIMapButton : GoPointerButton
{
	private static bool zoomed;

	public override void OnActivate()
	{
		UISoundPlayer.instance.PlayUISound((UISounds)0, 0.5f, 1f);
		LargeUI.ZoomMap(zoomed);
		zoomed = !zoomed;
		((GoPointerButton)this).ForceUnlook();
	}
}
public class LargeUIBuyPassageButton : GoPointerButton
{
	public Port destination;

	public float maxTime;

	public float minTime;

	public float risk;

	public int cost;

	public int currency;

	public static LargeUIBuyPassageButton instance;

	private void Awake()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		instance = this;
		GameObject val = new GameObject();
		val.AddComponent<FerryTravel>();
	}

	public override void OnActivate()
	{
		if (PlayerGold.currency[currency] > cost)
		{
			UISoundPlayer.instance.PlayGoldSound();
			LargeUI.CloseLargeUI();
			FerryTravel.instance.destination = instance.destination;
			FerryTravel.instance.maxTime = instance.maxTime;
			FerryTravel.instance.minTime = instance.minTime;
			FerryTravel.instance.risk = instance.risk;
			FerryTravel.instance.cost = instance.cost;
			FerryTravel.instance.currency = instance.currency;
			FerryTravel.instance.Travel();
			((GoPointerButton)this).ForceUnlook();
		}
		else
		{
			UISoundPlayer.instance.PlayUISound((UISounds)0, 0.5f, 1f);
			((GoPointerButton)this).ForceUnlook();
		}
	}
}