Decompiled source of VacationPlanner v2.1.2

com.github.strangebasis.VacationPlanner.dll

Decompiled 2 days 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 BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using VacationPlanner.Patches;
using Zorro.ControllerSupport;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.strangebasis.VacationPlanner")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.1.2.0")]
[assembly: AssemblyInformationalVersion("2.1.2+35d274e1f216a39d97bd95e1d44e4bd89529439e")]
[assembly: AssemblyProduct("com.github.strangebasis.VacationPlanner")]
[assembly: AssemblyTitle("VacationPlanner")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.2.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace VacationPlanner
{
	public class BiomeController : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <SpawnKioskAndUICoroutine>d__21 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public BiomeController <>4__this;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				//IL_0171: Unknown result type (might be due to invalid IL or missing references)
				//IL_0178: Expected O, but got Unknown
				//IL_0185: Unknown result type (might be due to invalid IL or missing references)
				//IL_0190: Unknown result type (might be due to invalid IL or missing references)
				//IL_019a: Unknown result type (might be due to invalid IL or missing references)
				//IL_019f: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
				//IL_021e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0242: Unknown result type (might be due to invalid IL or missing references)
				//IL_025d: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c1: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				BiomeController biomeController = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					BiomeVotingMenu.Create();
					AirportCheckInKiosk val = Object.FindAnyObjectByType<AirportCheckInKiosk>();
					AirportInviteFriendsKiosk val2 = Object.FindAnyObjectByType<AirportInviteFriendsKiosk>();
					if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
					{
						if (!_materialSearchComplete)
						{
							biomeController.FindAndCacheSignMaterial(((Component)val2).gameObject, "Add Player Kiosk@4x");
							_materialSearchComplete = true;
						}
						GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject);
						((Object)val3).name = "BiomeVotingKiosk";
						val3.transform.position = ((Component)val).transform.position + ((Component)val).transform.up * 2.262f;
						val3.transform.rotation = ((Component)val).transform.rotation;
						val3.transform.localScale = ((Component)val2).transform.localScale * 2.2f;
						if ((Object)(object)_cachedSignMaterial != (Object)null)
						{
							biomeController.ReplaceTextureOnClone(val3);
						}
						AirportInviteFriendsKiosk component = val3.GetComponent<AirportInviteFriendsKiosk>();
						if ((Object)(object)component != (Object)null)
						{
							Object.Destroy((Object)(object)component);
						}
						val3.AddComponent<BiomeVotingKiosk>();
						_spawnedKiosk = val3;
						Plugin.Log.LogInfo((object)"BiomeVotingKiosk spawned in Airport (scaled 2.3x)!");
						biomeController.DisplayWorldSpaceOverlay();
					}
					else if ((Object)(object)val != (Object)null)
					{
						GameObject val4 = new GameObject("BiomeVotingKiosk");
						val4.transform.position = ((Component)val).transform.position - ((Component)val).transform.forward * 3f;
						val4.transform.rotation = ((Component)val).transform.rotation;
						GameObject val5 = GameObject.CreatePrimitive((PrimitiveType)3);
						((Object)val5).name = "KioskMesh";
						val5.transform.SetParent(val4.transform, false);
						val5.transform.localScale = new Vector3(2f, 4f, 1f);
						val5.transform.localPosition = new Vector3(0f, 2f, 0f);
						BoxCollider val6 = val4.AddComponent<BoxCollider>();
						val6.center = new Vector3(0f, 2f, 0f);
						val6.size = new Vector3(3f, 5f, 2f);
						val4.AddComponent<BiomeVotingKiosk>();
						_spawnedKiosk = val4;
						Plugin.Log.LogInfo((object)"BiomeVotingKiosk spawned (fallback cube, scaled 2x)!");
					}
					else
					{
						Plugin.Log.LogError((object)"Could not find kiosks for positioning reference!");
					}
					return false;
				}
				}
			}

			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 static string? _defaultBiomeId;

		private static int _defaultLevelIndex = -1;

		private static GameObject? _spawnedKiosk;

		private static Material? _cachedSignMaterial = null;

		private static bool _materialSearchComplete = false;

		private static Texture2D? _cachedCustomTexture = null;

		private static Vector3 _lastLoggedHitPoint = Vector3.zero;

		private static Vector3 _lastLoggedHitNormal = Vector3.up;

		private static bool _hasLoggedPosition = false;

		private static string? _cachedTexturePropertyName = null;

		public static string? DefaultBiomeId => _defaultBiomeId;

		public static string? SelectedBiome2
		{
			get
			{
				return LevelOverridePatch.DesiredBiome2;
			}
			set
			{
				LevelOverridePatch.DesiredBiome2 = value;
			}
		}

		public static string? SelectedBiome3
		{
			get
			{
				return LevelOverridePatch.DesiredBiome3;
			}
			set
			{
				LevelOverridePatch.DesiredBiome3 = value;
			}
		}

		private void OnEnable()
		{
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnDisable()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		private void Update()
		{
			UpdateDefaultBiomeInfo();
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (((Scene)(ref scene)).name == "Airport")
			{
				((MonoBehaviour)this).StartCoroutine(SpawnKioskAndUICoroutine());
			}
		}

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

		private void UpdateDefaultBiomeInfo()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (_defaultBiomeId != null)
			{
				return;
			}
			try
			{
				MapBaker instance = SingletonAsset<MapBaker>.Instance;
				NextLevelService service = GameHandler.GetService<NextLevelService>();
				if ((Object)(object)instance != (Object)null && service != null && service.Data.IsSome)
				{
					_defaultLevelIndex = service.Data.Value.CurrentLevelIndex + NextLevelService.debugLevelIndexOffset;
					_defaultBiomeId = instance.GetBiomeID(_defaultLevelIndex);
					Plugin.Log.LogInfo((object)$"Default biome for today: {_defaultBiomeId} (Level {_defaultLevelIndex})");
				}
			}
			catch
			{
			}
		}

		public static string BiomeIdToFriendly(string? biomeId)
		{
			if (string.IsNullOrEmpty(biomeId))
			{
				return "Loading...";
			}
			string text = (biomeId.Contains('T') ? "Tropics" : "Roots");
			string text2 = (biomeId.Contains('A') ? "Alpine" : "Mesa");
			return text + " + " + text2;
		}

		public static string GetDefaultBiome2()
		{
			if (_defaultBiomeId == null)
			{
				return "T";
			}
			if (!_defaultBiomeId.Contains('T'))
			{
				return "R";
			}
			return "T";
		}

		public static string GetDefaultBiome3()
		{
			if (_defaultBiomeId == null)
			{
				return "M";
			}
			if (!_defaultBiomeId.Contains('A'))
			{
				return "M";
			}
			return "A";
		}

		public static void UpdateWorldSpaceOverlay()
		{
			GameObject val = GameObject.Find("BiomeWorldOverlay");
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			MeshRenderer component = val.GetComponent<MeshRenderer>();
			if ((Object)(object)component != (Object)null)
			{
				Texture2D val2 = LoadOverlayTexture();
				if ((Object)(object)val2 != (Object)null)
				{
					((Renderer)component).material.mainTexture = (Texture)(object)val2;
					((Renderer)component).material.SetTexture("_BaseMap", (Texture)(object)val2);
					Plugin.Log.LogInfo((object)"Updated overlay texture to reflect new biome selection");
				}
			}
		}

		private void FindAndCacheSignMaterial(GameObject originalKiosk, string targetTextureName)
		{
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Invalid comparison between Unknown and I4
			Plugin.Log.LogInfo((object)"Searching for sign material (one-time discovery)...");
			MeshRenderer[] componentsInChildren = originalKiosk.GetComponentsInChildren<MeshRenderer>();
			Plugin.Log.LogInfo((object)$"Found {componentsInChildren.Length} renderers in kiosk");
			MeshRenderer[] array = componentsInChildren;
			foreach (MeshRenderer val in array)
			{
				Plugin.Log.LogInfo((object)$"Renderer: {((Object)val).name} has {((Renderer)val).sharedMaterials.Length} materials");
				Material[] sharedMaterials = ((Renderer)val).sharedMaterials;
				foreach (Material val2 in sharedMaterials)
				{
					if (!((Object)(object)val2 != (Object)null))
					{
						continue;
					}
					Plugin.Log.LogInfo((object)("  Material: " + ((Object)val2).name + ", Shader: " + ((Object)val2.shader).name));
					ManualLogSource log = Plugin.Log;
					Texture mainTexture = val2.mainTexture;
					log.LogInfo((object)("    mainTexture: " + (((mainTexture != null) ? ((Object)mainTexture).name : null) ?? "null")));
					Shader shader = val2.shader;
					int propertyCount = shader.GetPropertyCount();
					for (int k = 0; k < propertyCount; k++)
					{
						ShaderPropertyType propertyType = shader.GetPropertyType(k);
						if ((int)propertyType == 4)
						{
							string propertyName = shader.GetPropertyName(k);
							Texture texture = val2.GetTexture(propertyName);
							Plugin.Log.LogInfo((object)("    [" + propertyName + "]: " + (((texture != null) ? ((Object)texture).name : null) ?? "null")));
							if ((Object)(object)texture != (Object)null && ((Object)texture).name == targetTextureName)
							{
								_cachedSignMaterial = val2;
								_cachedTexturePropertyName = propertyName;
								Plugin.Log.LogInfo((object)("✓ FOUND: Material '" + ((Object)val2).name + "' property '" + propertyName + "' = '" + targetTextureName + "'"));
								return;
							}
						}
					}
				}
			}
			Plugin.Log.LogWarning((object)("Could not find material with texture '" + targetTextureName + "'"));
		}

		private void ReplaceTextureOnClone(GameObject clonedKiosk)
		{
			if ((Object)(object)_cachedSignMaterial == (Object)null || _cachedTexturePropertyName == null)
			{
				return;
			}
			MeshRenderer[] componentsInChildren = clonedKiosk.GetComponentsInChildren<MeshRenderer>();
			MeshRenderer[] array = componentsInChildren;
			foreach (MeshRenderer val in array)
			{
				for (int j = 0; j < ((Renderer)val).materials.Length; j++)
				{
					if ((Object)(object)((Renderer)val).materials[j].shader == (Object)(object)_cachedSignMaterial.shader && ((Object)((Renderer)val).materials[j]).name.Contains(((Object)_cachedSignMaterial).name.Replace(" (Instance)", "")))
					{
						Texture2D val2 = LoadCustomTexture();
						if ((Object)(object)val2 != (Object)null)
						{
							((Renderer)val).materials[j].SetTexture(_cachedTexturePropertyName, (Texture)(object)val2);
							Plugin.Log.LogInfo((object)("Texture replaced on clone (property: " + _cachedTexturePropertyName + ")!"));
						}
						return;
					}
				}
			}
		}

		private Texture2D? LoadCustomTexture()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			if ((Object)(object)_cachedCustomTexture != (Object)null)
			{
				return _cachedCustomTexture;
			}
			string text = Path.Combine(Paths.PluginPath, "strangebasisdevs-VacationPlanner", "kiosk_texture.png");
			if (File.Exists(text))
			{
				byte[] array = File.ReadAllBytes(text);
				_cachedCustomTexture = new Texture2D(2, 2);
				ImageConversion.LoadImage(_cachedCustomTexture, array);
				Plugin.Log.LogInfo((object)("Custom texture loaded and cached from " + text));
				return _cachedCustomTexture;
			}
			Plugin.Log.LogError((object)("Could not find custom texture at " + text));
			return null;
		}

		private void DumpAllSceneTextures()
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Invalid comparison between Unknown and I4
			Plugin.Log.LogInfo((object)"=== DUMPING ALL SCENE TEXTURES ===");
			MeshRenderer[] array = Object.FindObjectsByType<MeshRenderer>((FindObjectsSortMode)0);
			Plugin.Log.LogInfo((object)$"Found {array.Length} renderers in scene");
			MeshRenderer[] array2 = array;
			foreach (MeshRenderer val in array2)
			{
				Plugin.Log.LogInfo((object)("\nGameObject: " + GetFullPath(((Component)val).gameObject)));
				Material[] sharedMaterials = ((Renderer)val).sharedMaterials;
				foreach (Material val2 in sharedMaterials)
				{
					if (!((Object)(object)val2 != (Object)null))
					{
						continue;
					}
					Plugin.Log.LogInfo((object)("  Material: " + ((Object)val2).name));
					Plugin.Log.LogInfo((object)("    Shader: " + ((Object)val2.shader).name));
					Shader shader = val2.shader;
					for (int k = 0; k < shader.GetPropertyCount(); k++)
					{
						if ((int)shader.GetPropertyType(k) == 4)
						{
							string propertyName = shader.GetPropertyName(k);
							Texture texture = val2.GetTexture(propertyName);
							if ((Object)(object)texture != (Object)null)
							{
								Plugin.Log.LogInfo((object)$"      [{propertyName}]: {((Object)texture).name} ({texture.width}x{texture.height})");
							}
						}
					}
				}
			}
			Plugin.Log.LogInfo((object)"=== DUMP COMPLETE ===");
		}

		private string GetFullPath(GameObject obj)
		{
			string text = ((Object)obj).name;
			Transform parent = obj.transform.parent;
			while ((Object)(object)parent != (Object)null)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}

		private void LogScreenPositionForOverlay()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			Vector3 mousePosition = Input.mousePosition;
			Vector3 val = Camera.main.ScreenToViewportPoint(mousePosition);
			Plugin.Log.LogInfo((object)"=== SCREEN POSITION LOG ===");
			Plugin.Log.LogInfo((object)$"Mouse Screen Position: {mousePosition.x:F0}, {mousePosition.y:F0}");
			Plugin.Log.LogInfo((object)$"Viewport Position: {val.x:F3}, {val.y:F3}");
			Plugin.Log.LogInfo((object)$"Screen Resolution: {Screen.width}x{Screen.height}");
			Plugin.Log.LogInfo((object)"For overlay rectangle, use viewport coordinates:");
			Plugin.Log.LogInfo((object)$"  new Rect({val.x:F3}f, {val.y:F3}f, width, height)");
			Plugin.Log.LogInfo((object)"===========================");
			LogWorldPlacementInfo();
		}

		private void LogWorldPlacementInfo()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			Ray val = Camera.main.ScreenPointToRay(Input.mousePosition);
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, ref val2, 100f))
			{
				_lastLoggedHitPoint = ((RaycastHit)(ref val2)).point;
				_lastLoggedHitNormal = ((RaycastHit)(ref val2)).normal;
				_hasLoggedPosition = true;
				Plugin.Log.LogInfo((object)"=== WORLD PLACEMENT INFO ===");
				Plugin.Log.LogInfo((object)$"Hit Point: ({((RaycastHit)(ref val2)).point.x:F3}, {((RaycastHit)(ref val2)).point.y:F3}, {((RaycastHit)(ref val2)).point.z:F3})");
				Plugin.Log.LogInfo((object)$"Hit Normal: ({((RaycastHit)(ref val2)).normal.x:F3}, {((RaycastHit)(ref val2)).normal.y:F3}, {((RaycastHit)(ref val2)).normal.z:F3})");
				Plugin.Log.LogInfo((object)$"Hit Distance: {((RaycastHit)(ref val2)).distance:F3}");
				Plugin.Log.LogInfo((object)("Hit GameObject: " + GetFullPath(((Component)((RaycastHit)(ref val2)).collider).gameObject)));
				ManualLogSource log = Plugin.Log;
				Collider collider = ((RaycastHit)(ref val2)).collider;
				object obj;
				if (collider == null)
				{
					obj = null;
				}
				else
				{
					Renderer component = ((Component)collider).GetComponent<Renderer>();
					if (component == null)
					{
						obj = null;
					}
					else
					{
						Material material = component.material;
						obj = ((material != null) ? ((Object)material).name : null);
					}
				}
				if (obj == null)
				{
					obj = "N/A";
				}
				log.LogInfo((object)("Hit Material: " + (string?)obj));
				Quaternion val3 = Quaternion.LookRotation(-((RaycastHit)(ref val2)).normal);
				Plugin.Log.LogInfo((object)$"Suggested Rotation (faces surface): ({((Quaternion)(ref val3)).eulerAngles.x:F1}, {((Quaternion)(ref val3)).eulerAngles.y:F1}, {((Quaternion)(ref val3)).eulerAngles.z:F1})");
				Vector3 val4 = ((Component)Camera.main).transform.position - ((RaycastHit)(ref val2)).point;
				Quaternion val5 = Quaternion.LookRotation(-((Vector3)(ref val4)).normalized);
				Plugin.Log.LogInfo((object)$"Suggested Rotation (faces camera): ({((Quaternion)(ref val5)).eulerAngles.x:F1}, {((Quaternion)(ref val5)).eulerAngles.y:F1}, {((Quaternion)(ref val5)).eulerAngles.z:F1})");
				Plugin.Log.LogInfo((object)"=== SUGGESTED CODE ===");
				Plugin.Log.LogInfo((object)$"transform.position = new Vector3({((RaycastHit)(ref val2)).point.x:F3}f, {((RaycastHit)(ref val2)).point.y:F3}f, {((RaycastHit)(ref val2)).point.z:F3}f);");
				Plugin.Log.LogInfo((object)$"transform.rotation = Quaternion.Euler({((Quaternion)(ref val3)).eulerAngles.x:F1}f, {((Quaternion)(ref val3)).eulerAngles.y:F1}f, {((Quaternion)(ref val3)).eulerAngles.z:F1}f);");
				Plugin.Log.LogInfo((object)"// Or for camera-facing:");
				Plugin.Log.LogInfo((object)$"transform.rotation = Quaternion.Euler({((Quaternion)(ref val5)).eulerAngles.x:F1}f, {((Quaternion)(ref val5)).eulerAngles.y:F1}f, {((Quaternion)(ref val5)).eulerAngles.z:F1}f);");
				Plugin.Log.LogInfo((object)"Press NUMPAD1 to place overlay at this position!");
				Plugin.Log.LogInfo((object)"===========================");
			}
			else
			{
				Plugin.Log.LogInfo((object)"No world hit detected - raycast didn't hit anything");
			}
		}

		private void DisplayWorldSpaceOverlay()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			GameObject val = GameObject.Find("BiomeWorldOverlay");
			bool flag = (Object)(object)val != (Object)null;
			if ((Object)(object)val == (Object)null)
			{
				val = GameObject.CreatePrimitive((PrimitiveType)5);
				((Object)val).name = "BiomeWorldOverlay";
				Collider component = val.GetComponent<Collider>();
				if ((Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)component);
				}
			}
			val.transform.position = new Vector3(1.807f, 5.136f, 103.626f);
			val.transform.rotation = Quaternion.Euler(0f, 90f, 0f);
			val.transform.localScale = new Vector3(5.7f, 0.75f, 1f);
			MeshRenderer component2 = val.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				Texture2D val2 = LoadOverlayTexture();
				if ((Object)(object)val2 != (Object)null)
				{
					if (flag)
					{
						((Renderer)component2).material.mainTexture = (Texture)(object)val2;
						((Renderer)component2).material.SetTexture("_BaseMap", (Texture)(object)val2);
						Plugin.Log.LogInfo((object)"Updated existing overlay texture");
					}
					else
					{
						Material val3 = new Material(Shader.Find("Universal Render Pipeline/Lit"));
						val3.mainTexture = (Texture)(object)val2;
						val3.SetTexture("_BaseMap", (Texture)(object)val2);
						val3.SetFloat("_Surface", 0f);
						val3.SetFloat("_Blend", 0f);
						((Renderer)component2).material = val3;
					}
				}
				else
				{
					Material val4 = new Material(Shader.Find("Universal Render Pipeline/Lit"));
					val4.color = new Color(1f, 0.5f, 0f, 0.9f);
					((Renderer)component2).material = val4;
				}
			}
			Plugin.Log.LogInfo((object)$"World space overlay created covering airport sign at {val.transform.position}");
		}

		private static Texture2D? LoadOverlayTexture()
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			string text = LevelOverridePatch.DesiredBiome2?.ToUpper() ?? GetDefaultBiome2();
			string text2 = LevelOverridePatch.DesiredBiome3?.ToUpper() ?? GetDefaultBiome3();
			string text3 = ((text == "T") ? "tropics" : "roots");
			string text4 = ((text2 == "A") ? "alpine" : "mesa");
			string path = text3 + "_" + text4 + "_sign.png";
			string text5 = Path.Combine(Paths.PluginPath, "strangebasisdevs-VacationPlanner", path);
			if (File.Exists(text5))
			{
				byte[] array = File.ReadAllBytes(text5);
				Texture2D val = new Texture2D(2, 2);
				ImageConversion.LoadImage(val, array);
				Plugin.Log.LogInfo((object)("Overlay texture loaded from " + text5));
				return val;
			}
			Plugin.Log.LogWarning((object)("Could not find overlay texture at " + text5));
			return null;
		}

		private void PlaceOverlayAtLoggedPosition(string overlayName)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			if (!_hasLoggedPosition)
			{
				Plugin.Log.LogWarning((object)"No logged position available. Press NUMPAD0 first to log a position.");
				return;
			}
			GameObject val = GameObject.Find(overlayName);
			if ((Object)(object)val == (Object)null)
			{
				val = GameObject.CreatePrimitive((PrimitiveType)5);
				((Object)val).name = overlayName;
				Collider component = val.GetComponent<Collider>();
				if ((Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)component);
				}
			}
			val.transform.position = _lastLoggedHitPoint + _lastLoggedHitNormal * 0.01f;
			val.transform.rotation = Quaternion.LookRotation(-_lastLoggedHitNormal);
			val.transform.localScale = new Vector3(1f, 1f, 1f);
			MeshRenderer component2 = val.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				Texture2D val2 = LoadOverlayTexture();
				if ((Object)(object)val2 != (Object)null)
				{
					Material val3 = new Material(Shader.Find("Universal Render Pipeline/Lit"));
					val3.mainTexture = (Texture)(object)val2;
					val3.SetTexture("_BaseMap", (Texture)(object)val2);
					val3.SetFloat("_Surface", 0f);
					val3.SetFloat("_Blend", 0f);
					((Renderer)component2).material = val3;
				}
				else
				{
					Material val4 = new Material(Shader.Find("Universal Render Pipeline/Lit"));
					val4.color = new Color(1f, 0.5f, 0f, 0.9f);
					((Renderer)component2).material = val4;
				}
			}
			Plugin.Log.LogInfo((object)$"Overlay '{overlayName}' placed at logged position: {_lastLoggedHitPoint}, normal: {_lastLoggedHitNormal}");
			LogCurrentOverlayTransform(val.transform);
		}

		private void AdjustOverlayScale(string overlayName, float widthDelta, float heightDelta)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.Find(overlayName);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)("No overlay '" + overlayName + "' to adjust. Place one first with NUMPAD1."));
				return;
			}
			Vector3 localScale = val.transform.localScale;
			Vector3 localScale2 = default(Vector3);
			((Vector3)(ref localScale2))..ctor(Mathf.Max(0.1f, localScale.x + widthDelta), Mathf.Max(0.1f, localScale.y + heightDelta), localScale.z);
			val.transform.localScale = localScale2;
			LogCurrentOverlayTransform(val.transform);
		}

		private void AdjustOverlayPosition(string overlayName, float deltaX, float deltaY, float deltaZ)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.Find(overlayName);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)("No overlay '" + overlayName + "' to adjust. Place one first with NUMPAD1."));
				return;
			}
			Vector3 position = val.transform.position;
			Vector3 position2 = position + new Vector3(deltaX, deltaY, deltaZ);
			val.transform.position = position2;
			LogCurrentOverlayTransform(val.transform);
		}

		private void LogCurrentOverlayTransform(Transform transform)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: 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_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogInfo((object)"=== OVERLAY TRANSFORM ===");
			Plugin.Log.LogInfo((object)$"Position: ({transform.position.x:F3}, {transform.position.y:F3}, {transform.position.z:F3})");
			ManualLogSource log = Plugin.Log;
			Quaternion rotation = transform.rotation;
			object arg = ((Quaternion)(ref rotation)).eulerAngles.x;
			rotation = transform.rotation;
			object arg2 = ((Quaternion)(ref rotation)).eulerAngles.y;
			rotation = transform.rotation;
			log.LogInfo((object)$"Rotation: ({arg:F1}, {arg2:F1}, {((Quaternion)(ref rotation)).eulerAngles.z:F1})");
			Plugin.Log.LogInfo((object)$"Scale: ({transform.localScale.x:F3}, {transform.localScale.y:F3}, {transform.localScale.z:F3})");
			Plugin.Log.LogInfo((object)"=== READY-TO-USE CODE ===");
			Plugin.Log.LogInfo((object)$"overlayGO.transform.position = new Vector3({transform.position.x:F3}f, {transform.position.y:F3}f, {transform.position.z:F3}f);");
			ManualLogSource log2 = Plugin.Log;
			rotation = transform.rotation;
			object arg3 = ((Quaternion)(ref rotation)).eulerAngles.x;
			rotation = transform.rotation;
			object arg4 = ((Quaternion)(ref rotation)).eulerAngles.y;
			rotation = transform.rotation;
			log2.LogInfo((object)$"overlayGO.transform.rotation = Quaternion.Euler({arg3:F1}f, {arg4:F1}f, {((Quaternion)(ref rotation)).eulerAngles.z:F1}f);");
			Plugin.Log.LogInfo((object)$"overlayGO.transform.localScale = new Vector3({transform.localScale.x:F3}f, {transform.localScale.y:F3}f, {transform.localScale.z:F3}f);");
			Plugin.Log.LogInfo((object)"===========================");
		}
	}
	public class BiomeVotingKiosk : MonoBehaviour, IInteractible
	{
		private MaterialPropertyBlock? mpb;

		private MeshRenderer[]? _mr;

		private MeshRenderer[] meshRenderers
		{
			get
			{
				if (_mr == null)
				{
					_mr = ((Component)this).GetComponentsInChildren<MeshRenderer>();
				}
				return _mr;
			}
		}

		public void Awake()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			mpb = new MaterialPropertyBlock();
		}

		public bool IsInteractible(Character interactor)
		{
			return true;
		}

		public void Interact(Character interactor)
		{
			Plugin.Log.LogInfo((object)$"BiomeVotingKiosk Interact - Menu exists: {(Object)(object)BiomeVotingMenu.Instance != (Object)null}");
			if ((Object)(object)BiomeVotingMenu.Instance != (Object)null)
			{
				if (((MenuWindow)BiomeVotingMenu.Instance).isOpen)
				{
					((MenuWindow)BiomeVotingMenu.Instance).Close();
				}
				else
				{
					((MenuWindow)BiomeVotingMenu.Instance).Open();
				}
			}
			else
			{
				Plugin.Log.LogError((object)"BiomeVotingMenu.Instance is null!");
			}
		}

		public void HoverEnter()
		{
			if (mpb == null)
			{
				return;
			}
			mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 1f);
			MeshRenderer[] array = meshRenderers;
			foreach (MeshRenderer val in array)
			{
				if (val != null)
				{
					((Renderer)val).SetPropertyBlock(mpb);
				}
			}
		}

		public void HoverExit()
		{
			if (mpb == null)
			{
				return;
			}
			mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 0f);
			MeshRenderer[] array = meshRenderers;
			foreach (MeshRenderer val in array)
			{
				if (val != null)
				{
					((Renderer)val).SetPropertyBlock(mpb);
				}
			}
		}

		public Vector3 Center()
		{
			//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_0010: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)this).transform.position + Vector3.up;
		}

		public Transform GetTransform()
		{
			return ((Component)this).transform;
		}

		public string GetInteractionText()
		{
			return "SELECT DESTINATION";
		}

		public string GetName()
		{
			return "DESTINATION KIOSK";
		}
	}
	public class BiomeVotingMenu : MenuWindow
	{
		private GUIStyle? _boxStyle;

		private GUIStyle? _labelStyle;

		private GUIStyle? _headerStyle;

		private GUIStyle? _buttonStyle;

		private GUIStyle? _selectedButtonStyle;

		private GUIStyle? _voteStyle;

		private GUIStyle? _winnerStyle;

		private Texture2D? _borderTexture;

		private int _selectedRow;

		private int _selectedCol;

		private float _navigationCooldown;

		private const float NavigationDelay = 0.15f;

		private InputScheme _currentInputScheme;

		public static BiomeVotingMenu? Instance { get; private set; }

		public override bool openOnStart => false;

		public override bool selectOnOpen => false;

		public override bool closeOnPause => true;

		public override bool closeOnUICancel => true;

		public override bool autoHideOnClose => true;

		public override bool blocksPlayerInput => true;

		public override bool showCursorWhileOpen => true;

		public static BiomeVotingMenu Create()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if ((Object)(object)Instance != (Object)null)
			{
				return Instance;
			}
			GameObject val = new GameObject("BiomeVotingMenu");
			BiomeVotingMenu biomeVotingMenu2 = (Instance = val.AddComponent<BiomeVotingMenu>());
			((MenuWindow)biomeVotingMenu2).StartClosed();
			Plugin.Log.LogInfo((object)"BiomeVotingMenu created");
			return biomeVotingMenu2;
		}

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			_currentInputScheme = InputHandler.GetCurrentUsedInputScheme();
			InputHandler instance = RetrievableResourceSingleton<InputHandler>.Instance;
			instance.InputSchemeChanged = (Action<InputScheme>)Delegate.Combine(instance.InputSchemeChanged, new Action<InputScheme>(OnInputSchemeChanged));
		}

		public override void OnOpen()
		{
			Plugin.Log.LogInfo((object)"BiomeVotingMenu OnOpen - cursor should show now");
			_selectedRow = 0;
			_selectedCol = 0;
			_navigationCooldown = 0f;
		}

		public override void OnClose()
		{
			Plugin.Log.LogInfo((object)"BiomeVotingMenu OnClose");
		}

		private void Update()
		{
			((MenuWindow)this).Update();
			if (((MenuWindow)this).isOpen && ((MenuWindow)this).inputActive)
			{
				HandleControllerInput();
			}
		}

		private void HandleControllerInput()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			UIInputHandler instance = Singleton<UIInputHandler>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			Vector2 wheelNavigationVector = instance.wheelNavigationVector;
			_navigationCooldown -= Time.deltaTime;
			if (_navigationCooldown <= 0f && wheelNavigationVector != Vector2.zero)
			{
				if (Mathf.Abs(wheelNavigationVector.x) > Mathf.Abs(wheelNavigationVector.y))
				{
					if (wheelNavigationVector.x > 0.5f)
					{
						_selectedCol = (_selectedCol + 1) % 2;
						_navigationCooldown = 0.15f;
					}
					else if (wheelNavigationVector.x < -0.5f)
					{
						_selectedCol = (_selectedCol - 1 + 2) % 2;
						_navigationCooldown = 0.15f;
					}
				}
				else if (wheelNavigationVector.y > 0.5f)
				{
					_selectedRow = Mathf.Max(0, _selectedRow - 1);
					_navigationCooldown = 0.15f;
				}
				else if (wheelNavigationVector.y < -0.5f)
				{
					_selectedRow = Mathf.Min(2, _selectedRow + 1);
					_navigationCooldown = 0.15f;
				}
			}
			if (instance.confirmWasPressed)
			{
				ExecuteSelectedButton();
				instance.confirmWasPressed = false;
			}
		}

		private void ExecuteSelectedButton()
		{
			bool inRoom = PhotonNetwork.InRoom;
			switch (_selectedRow)
			{
			case 0:
				if (_selectedCol == 0)
				{
					if (inRoom)
					{
						NetworkSync.VoteForBiome2("T");
						break;
					}
					BiomeController.SelectedBiome2 = "T";
					BiomeController.UpdateWorldSpaceOverlay();
				}
				else if (inRoom)
				{
					NetworkSync.VoteForBiome2("R");
				}
				else
				{
					BiomeController.SelectedBiome2 = "R";
					BiomeController.UpdateWorldSpaceOverlay();
				}
				break;
			case 1:
				if (_selectedCol == 0)
				{
					if (inRoom)
					{
						NetworkSync.VoteForBiome3("A");
						break;
					}
					BiomeController.SelectedBiome3 = "A";
					BiomeController.UpdateWorldSpaceOverlay();
				}
				else if (inRoom)
				{
					NetworkSync.VoteForBiome3("M");
				}
				else
				{
					BiomeController.SelectedBiome3 = "M";
					BiomeController.UpdateWorldSpaceOverlay();
				}
				break;
			case 2:
				if (_selectedCol == 0)
				{
					if (inRoom)
					{
						NetworkSync.ClearMyVotes();
						break;
					}
					LevelOverridePatch.ClearOverrides();
					BiomeController.UpdateWorldSpaceOverlay();
				}
				else
				{
					((MenuWindow)this).Close();
				}
				break;
			}
		}

		private GUIStyle GetButtonStyle(bool isVoted)
		{
			if (!isVoted)
			{
				return _buttonStyle;
			}
			return _selectedButtonStyle;
		}

		private void OnInputSchemeChanged(InputScheme scheme)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			_currentInputScheme = scheme;
		}

		private void OnDestroy()
		{
			((MenuWindow)this).OnDestroy();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
			InputHandler instance = RetrievableResourceSingleton<InputHandler>.Instance;
			instance.InputSchemeChanged = (Action<InputScheme>)Delegate.Remove(instance.InputSchemeChanged, new Action<InputScheme>(OnInputSchemeChanged));
		}

		private void OnGUI()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Invalid comparison between Unknown and I4
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Invalid comparison between Unknown and I4
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_040b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Invalid comparison between Unknown and I4
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Invalid comparison between Unknown and I4
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f2: Invalid comparison between Unknown and I4
			//IL_0512: Unknown result type (might be due to invalid IL or missing references)
			//IL_0613: Unknown result type (might be due to invalid IL or missing references)
			//IL_0620: Unknown result type (might be due to invalid IL or missing references)
			//IL_063c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0642: Invalid comparison between Unknown and I4
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_0685: Unknown result type (might be due to invalid IL or missing references)
			if (!((MenuWindow)this).isOpen)
			{
				return;
			}
			InitStyles();
			bool inRoom = PhotonNetwork.InRoom;
			float num = 400f;
			float num2 = (inRoom ? 380 : 280);
			float num3 = ((float)Screen.width - num) / 2f;
			float num4 = ((float)Screen.height - num2) / 2f;
			GUI.Box(new Rect(num3, num4, num, num2), "", _boxStyle);
			float num5 = num3 + 15f;
			float num6 = num4 + 15f;
			float num7 = num - 30f;
			GUI.Label(new Rect(num5, num6, num7, 30f), "DESTINATION SELECTION", _headerStyle);
			num6 += 40f;
			string text = BiomeController.BiomeIdToFriendly(BiomeController.DefaultBiomeId);
			GUI.Label(new Rect(num5, num6, num7, 20f), "Today's Default: " + text, _labelStyle);
			num6 += 35f;
			GUI.Label(new Rect(num5, num6, num7, 20f), "JUNGLE REGION:", _labelStyle);
			num6 += 25f;
			string text2 = (inRoom ? NetworkSync.MyVoteBiome2 : BiomeController.SelectedBiome2);
			bool flag = text2 == "T";
			bool flag2 = text2 == "R";
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(num5, num6, 150f, 35f);
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(num5 + 160f, num6, 150f, 35f);
			bool flag3 = ((Rect)(ref val)).Contains(Event.current.mousePosition);
			bool flag4 = ((Rect)(ref val2)).Contains(Event.current.mousePosition);
			if (GUI.Button(val, "TROPICS", GetButtonStyle(flag)))
			{
				if (inRoom)
				{
					NetworkSync.VoteForBiome2("T");
				}
				else
				{
					BiomeController.SelectedBiome2 = "T";
					BiomeController.UpdateWorldSpaceOverlay();
				}
			}
			if (((int)_currentInputScheme == 1 && _selectedRow == 0 && _selectedCol == 0) || (flag3 && !flag))
			{
				GUI.DrawTexture(val, (Texture)(object)_borderTexture);
			}
			if (GUI.Button(val2, "ROOTS", GetButtonStyle(flag2)))
			{
				if (inRoom)
				{
					NetworkSync.VoteForBiome2("R");
				}
				else
				{
					BiomeController.SelectedBiome2 = "R";
					BiomeController.UpdateWorldSpaceOverlay();
				}
			}
			if (((int)_currentInputScheme == 1 && _selectedRow == 0 && _selectedCol == 1) || (flag4 && !flag2))
			{
				GUI.DrawTexture(val2, (Texture)(object)_borderTexture);
			}
			num6 += 40f;
			if (inRoom)
			{
				int votesTropics = NetworkSync.VotesTropics;
				int votesRoots = NetworkSync.VotesRoots;
				string defaultBiome = BiomeController.GetDefaultBiome2();
				bool flag5 = votesTropics > votesRoots || (votesTropics == votesRoots && defaultBiome == "T");
				string arg = (flag5 ? "Tropics" : "Roots");
				GUI.Label(new Rect(num5, num6, num7, 20f), $"  Votes: Tropics {votesTropics} | Roots {votesRoots}  →  Winner: {arg}", ((flag5 && votesTropics > 0) || (!flag5 && votesRoots > 0)) ? _winnerStyle : _voteStyle);
				num6 += 25f;
			}
			else
			{
				num6 += 15f;
			}
			GUI.Label(new Rect(num5, num6, num7, 20f), "MOUNTAIN REGION:", _labelStyle);
			num6 += 25f;
			string text3 = (inRoom ? NetworkSync.MyVoteBiome3 : BiomeController.SelectedBiome3);
			bool flag6 = text3 == "A";
			bool flag7 = text3 == "M";
			Rect val3 = default(Rect);
			((Rect)(ref val3))..ctor(num5, num6, 150f, 35f);
			Rect val4 = default(Rect);
			((Rect)(ref val4))..ctor(num5 + 160f, num6, 150f, 35f);
			bool flag8 = ((Rect)(ref val3)).Contains(Event.current.mousePosition);
			bool flag9 = ((Rect)(ref val4)).Contains(Event.current.mousePosition);
			if (GUI.Button(val3, "ALPINE", GetButtonStyle(flag6)))
			{
				if (inRoom)
				{
					NetworkSync.VoteForBiome3("A");
				}
				else
				{
					BiomeController.SelectedBiome3 = "A";
					BiomeController.UpdateWorldSpaceOverlay();
				}
			}
			if (((int)_currentInputScheme == 1 && _selectedRow == 1 && _selectedCol == 0) || (flag8 && !flag6))
			{
				GUI.DrawTexture(val3, (Texture)(object)_borderTexture);
			}
			if (GUI.Button(val4, "MESA", GetButtonStyle(flag7)))
			{
				if (inRoom)
				{
					NetworkSync.VoteForBiome3("M");
				}
				else
				{
					BiomeController.SelectedBiome3 = "M";
					BiomeController.UpdateWorldSpaceOverlay();
				}
			}
			if (((int)_currentInputScheme == 1 && _selectedRow == 1 && _selectedCol == 1) || (flag9 && !flag7))
			{
				GUI.DrawTexture(val4, (Texture)(object)_borderTexture);
			}
			num6 += 40f;
			if (inRoom)
			{
				int votesAlpine = NetworkSync.VotesAlpine;
				int votesMesa = NetworkSync.VotesMesa;
				string defaultBiome2 = BiomeController.GetDefaultBiome3();
				bool flag10 = votesAlpine > votesMesa || (votesAlpine == votesMesa && defaultBiome2 == "A");
				string arg2 = (flag10 ? "Alpine" : "Mesa");
				GUI.Label(new Rect(num5, num6, num7, 20f), $"  Votes: Alpine {votesAlpine} | Mesa {votesMesa}  →  Winner: {arg2}", ((flag10 && votesAlpine > 0) || (!flag10 && votesMesa > 0)) ? _winnerStyle : _voteStyle);
				num6 += 25f;
			}
			else
			{
				num6 += 15f;
			}
			Rect val5 = default(Rect);
			((Rect)(ref val5))..ctor(num5, num6, 150f, 30f);
			Rect val6 = default(Rect);
			((Rect)(ref val6))..ctor(num5 + 160f, num6, 150f, 30f);
			bool flag11 = ((Rect)(ref val5)).Contains(Event.current.mousePosition);
			bool flag12 = ((Rect)(ref val6)).Contains(Event.current.mousePosition);
			if (GUI.Button(val5, "CLEAR", GetButtonStyle(isVoted: false)))
			{
				if (inRoom)
				{
					NetworkSync.ClearMyVotes();
				}
				else
				{
					LevelOverridePatch.ClearOverrides();
					BiomeController.UpdateWorldSpaceOverlay();
				}
			}
			if (((int)_currentInputScheme == 1 && _selectedRow == 2 && _selectedCol == 0) || flag11)
			{
				GUI.DrawTexture(val5, (Texture)(object)_borderTexture);
			}
			if (GUI.Button(val6, "CLOSE", GetButtonStyle(isVoted: false)))
			{
				((MenuWindow)this).Close();
			}
			if (((int)_currentInputScheme == 1 && _selectedRow == 2 && _selectedCol == 1) || flag12)
			{
				GUI.DrawTexture(val6, (Texture)(object)_borderTexture);
			}
			num6 += 35f;
			GUI.Label(new Rect(num5, num6, num7, 20f), "Press ESC to close", _voteStyle);
		}

		private void InitStyles()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Expected O, but got Unknown
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Expected O, but got Unknown
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Expected O, but got Unknown
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			if (_boxStyle == null)
			{
				_boxStyle = new GUIStyle(GUI.skin.box);
				_boxStyle.normal.background = MakeTex(2, 2, new Color(0.08f, 0.06f, 0.04f, 0.95f));
				_labelStyle = new GUIStyle(GUI.skin.label);
				_labelStyle.normal.textColor = Color.white;
				_labelStyle.fontSize = 16;
				_headerStyle = new GUIStyle(_labelStyle);
				_headerStyle.fontStyle = (FontStyle)1;
				_headerStyle.fontSize = 22;
				_headerStyle.normal.textColor = new Color(1f, 0.85f, 0.4f);
				_headerStyle.alignment = (TextAnchor)4;
				_buttonStyle = new GUIStyle(GUI.skin.button);
				_buttonStyle.fontSize = 16;
				_buttonStyle.fontStyle = (FontStyle)1;
				_buttonStyle.normal.textColor = Color.white;
				_buttonStyle.hover.background = _buttonStyle.normal.background;
				_buttonStyle.active.background = _buttonStyle.normal.background;
				_selectedButtonStyle = new GUIStyle(_buttonStyle);
				_selectedButtonStyle.normal.background = MakeTex(2, 2, new Color(0.2f, 0.5f, 0.2f, 1f));
				_selectedButtonStyle.hover.background = _selectedButtonStyle.normal.background;
				_selectedButtonStyle.active.background = _selectedButtonStyle.normal.background;
				_selectedButtonStyle.normal.textColor = Color.yellow;
				_borderTexture = MakeBorderTex(4, 4, new Color(0.5f, 0.8f, 1f, 0.6f));
				_voteStyle = new GUIStyle(_labelStyle);
				_voteStyle.fontSize = 14;
				_voteStyle.normal.textColor = new Color(0.7f, 0.7f, 0.7f);
				_winnerStyle = new GUIStyle(_labelStyle);
				_winnerStyle.fontSize = 14;
				_winnerStyle.fontStyle = (FontStyle)1;
				_winnerStyle.normal.textColor = new Color(1f, 0.84f, 0f);
			}
		}

		private static Texture2D MakeTex(int width, int height, Color col)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = col;
			}
			Texture2D val = new Texture2D(width, height);
			val.SetPixels(array);
			val.Apply();
			return val;
		}

		private static Texture2D MakeBorderTex(int width, int height, Color borderCol)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				int num = i % width;
				int num2 = i / width;
				bool flag = num == 0 || num == width - 1 || num2 == 0 || num2 == height - 1;
				array[i] = (flag ? borderCol : Color.clear);
			}
			Texture2D val = new Texture2D(width, height);
			val.SetPixels(array);
			val.Apply();
			return val;
		}
	}
	public class NetworkSync : MonoBehaviourPunCallbacks
	{
		private const string VOTE_PREFIX_B2 = "VP_V2_";

		private const string VOTE_PREFIX_B3 = "VP_V3_";

		private static NetworkSync? _instance;

		private static bool _initialized;

		public static int VotesTropics { get; private set; }

		public static int VotesRoots { get; private set; }

		public static int VotesAlpine { get; private set; }

		public static int VotesMesa { get; private set; }

		public static string? MyVoteBiome2 { get; private set; }

		public static string? MyVoteBiome3 { get; private set; }

		public static bool IsAvailable
		{
			get
			{
				if (_initialized)
				{
					return PhotonNetwork.InRoom;
				}
				return false;
			}
		}

		public static bool IsMasterClient => PhotonNetwork.IsMasterClient;

		private void Awake()
		{
			if ((Object)(object)_instance != (Object)null && (Object)(object)_instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			_instance = this;
			_initialized = true;
			MyVoteBiome2 = null;
			MyVoteBiome3 = null;
			Plugin.Log.LogInfo((object)"NetworkSync initialized (Continuous Voting System)");
		}

		public override void OnEnable()
		{
			((MonoBehaviourPunCallbacks)this).OnEnable();
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		public override void OnDisable()
		{
			((MonoBehaviourPunCallbacks)this).OnDisable();
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (((Scene)(ref scene)).name == "Airport")
			{
				Plugin.Log.LogInfo((object)"[NetworkSync] Returned to Airport - Clearing votes");
				MyVoteBiome2 = null;
				MyVoteBiome3 = null;
				if (PhotonNetwork.InRoom)
				{
					ClearMyVotes();
				}
				LevelOverridePatch.ClearOverrides();
			}
		}

		public static void VoteForBiome2(string vote)
		{
			//IL_0046: 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_0053: Expected O, but got Unknown
			//IL_0054: Expected O, but got Unknown
			if (PhotonNetwork.InRoom && (!(vote != "T") || !(vote != "R")))
			{
				MyVoteBiome2 = vote;
				string key = "VP_V2_" + PhotonNetwork.LocalPlayer.ActorNumber;
				Hashtable val = new Hashtable();
				((Dictionary<object, object>)val).Add((object)key, (object)vote);
				Hashtable val2 = val;
				PhotonNetwork.CurrentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null);
				Plugin.Log.LogInfo((object)("[VOTE] Biome2 vote submitted: " + vote));
			}
		}

		public static void VoteForBiome3(string vote)
		{
			//IL_0046: 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_0053: Expected O, but got Unknown
			//IL_0054: Expected O, but got Unknown
			if (PhotonNetwork.InRoom && (!(vote != "A") || !(vote != "M")))
			{
				MyVoteBiome3 = vote;
				string key = "VP_V3_" + PhotonNetwork.LocalPlayer.ActorNumber;
				Hashtable val = new Hashtable();
				((Dictionary<object, object>)val).Add((object)key, (object)vote);
				Hashtable val2 = val;
				PhotonNetwork.CurrentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null);
				Plugin.Log.LogInfo((object)("[VOTE] Biome3 vote submitted: " + vote));
			}
		}

		public static void ClearMyVotes()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_006c: Expected O, but got Unknown
			if (PhotonNetwork.InRoom)
			{
				MyVoteBiome2 = null;
				MyVoteBiome3 = null;
				string key = "VP_V2_" + PhotonNetwork.LocalPlayer.ActorNumber;
				string key2 = "VP_V3_" + PhotonNetwork.LocalPlayer.ActorNumber;
				Hashtable val = new Hashtable();
				((Dictionary<object, object>)val).Add((object)key, (object)"");
				((Dictionary<object, object>)val).Add((object)key2, (object)"");
				Hashtable val2 = val;
				PhotonNetwork.CurrentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null);
				Plugin.Log.LogInfo((object)"[VOTE] Cleared my votes");
			}
		}

		public static void CountVotesAndUpdateOverride()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			VotesTropics = 0;
			VotesRoots = 0;
			VotesAlpine = 0;
			VotesMesa = 0;
			if (!PhotonNetwork.InRoom)
			{
				return;
			}
			Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties;
			DictionaryEntryEnumerator enumerator = customProperties.GetEnumerator();
			try
			{
				while (((DictionaryEntryEnumerator)(ref enumerator)).MoveNext())
				{
					DictionaryEntry current = ((DictionaryEntryEnumerator)(ref enumerator)).Current;
					string text = (current.Key as string) ?? "";
					string text2 = (current.Value as string) ?? "";
					if (string.IsNullOrEmpty(text2))
					{
						continue;
					}
					if (text.StartsWith("VP_V2_"))
					{
						if (text2 == "T")
						{
							VotesTropics++;
						}
						else if (text2 == "R")
						{
							VotesRoots++;
						}
					}
					else if (text.StartsWith("VP_V3_"))
					{
						if (text2 == "A")
						{
							VotesAlpine++;
						}
						else if (text2 == "M")
						{
							VotesMesa++;
						}
					}
				}
			}
			finally
			{
				((IDisposable)(DictionaryEntryEnumerator)(ref enumerator)).Dispose();
			}
			string text3 = null;
			if (VotesTropics > VotesRoots)
			{
				text3 = "T";
			}
			else if (VotesRoots > VotesTropics)
			{
				text3 = "R";
			}
			string text4 = null;
			if (VotesAlpine > VotesMesa)
			{
				text4 = "A";
			}
			else if (VotesMesa > VotesAlpine)
			{
				text4 = "M";
			}
			LevelOverridePatch.DesiredBiome2 = text3;
			LevelOverridePatch.DesiredBiome3 = text4;
			BiomeController.UpdateWorldSpaceOverlay();
			Plugin.Log.LogInfo((object)string.Format("[VOTE] Tally Updated: T:{0} R:{1} (Winner: {2}) | A:{3} M:{4} (Winner: {5})", VotesTropics, VotesRoots, text3 ?? "Default", VotesAlpine, VotesMesa, text4 ?? "Default"));
		}

		public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
		{
			CountVotesAndUpdateOverride();
		}

		public override void OnJoinedRoom()
		{
			Plugin.Log.LogInfo((object)$"[CALLBACK] OnJoinedRoom - IsMasterClient={PhotonNetwork.IsMasterClient}");
			LevelOverridePatch.ClearOverrides();
			CountVotesAndUpdateOverride();
			Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties;
			string key = "VP_V2_" + PhotonNetwork.LocalPlayer.ActorNumber;
			string key2 = "VP_V3_" + PhotonNetwork.LocalPlayer.ActorNumber;
			if (((Dictionary<object, object>)(object)customProperties).TryGetValue((object)key, out object value) && value is string text && !string.IsNullOrEmpty(text))
			{
				MyVoteBiome2 = text;
			}
			if (((Dictionary<object, object>)(object)customProperties).TryGetValue((object)key2, out object value2) && value2 is string text2 && !string.IsNullOrEmpty(text2))
			{
				MyVoteBiome3 = text2;
			}
		}
	}
	[BepInPlugin("com.github.strangebasis.VacationPlanner", "VacationPlanner", "2.1.2")]
	public class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("com.github.strangebasis.VacationPlanner");

		public const string Id = "com.github.strangebasis.VacationPlanner";

		internal static ManualLogSource Log { get; private set; }

		public static string Name => "VacationPlanner";

		public static string Version => "2.1.2";

		private void Awake()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			GameObject val = new GameObject("VacationPlanner_Controller");
			val.AddComponent<BiomeController>();
			val.AddComponent<NetworkSync>();
			Object.DontDestroyOnLoad((Object)(object)val);
			Log.LogInfo((object)"BiomeController and NetworkSync initialized");
		}
	}
}
namespace VacationPlanner.Patches
{
	[HarmonyPatch]
	public static class GameStartPatch
	{
		[HarmonyPatch(typeof(AirportCheckInKiosk), "LoadIslandMaster")]
		[HarmonyPrefix]
		public static void LoadIslandMaster_Prefix()
		{
			Plugin.Log.LogInfo((object)"[GameStartPatch] LoadIslandMaster starting...");
			Plugin.Log.LogInfo((object)("[GameStartPatch] Overrides active: B2=" + (LevelOverridePatch.DesiredBiome2 ?? "Default") + ", B3=" + (LevelOverridePatch.DesiredBiome3 ?? "Default")));
		}
	}
	[HarmonyPatch(typeof(MapBaker))]
	public static class LevelOverridePatch
	{
		private static readonly Dictionary<string, int[]> BiomeToLevels = new Dictionary<string, int[]>
		{
			{
				"STMV",
				new int[7] { 0, 3, 5, 8, 11, 14, 17 }
			},
			{
				"STAV",
				new int[5] { 1, 9, 13, 16, 20 }
			},
			{
				"SRMV",
				new int[4] { 2, 7, 10, 18 }
			},
			{
				"SRAV",
				new int[5] { 4, 6, 12, 15, 19 }
			}
		};

		public static string? DesiredBiome2 { get; set; } = null;


		public static string? DesiredBiome3 { get; set; } = null;


		public static void ClearOverrides()
		{
			DesiredBiome2 = null;
			DesiredBiome3 = null;
			Plugin.Log.LogInfo((object)"Biome overrides cleared");
		}

		public static string GetSelectionSummary()
		{
			string desiredBiome = DesiredBiome2;
			string text = ((desiredBiome == "T") ? "Tropics" : ((!(desiredBiome == "R")) ? "Default" : "Roots"));
			string text2 = text;
			string desiredBiome2 = DesiredBiome3;
			text = ((desiredBiome2 == "A") ? "Alpine" : ((!(desiredBiome2 == "M")) ? "Default" : "Mesa"));
			string text3 = text;
			return "Biome2: " + text2 + ", Biome3: " + text3;
		}

		[HarmonyPatch("GetLevel")]
		[HarmonyPrefix]
		public static void GetLevel_Prefix(MapBaker __instance, ref int levelIndex)
		{
			if (DesiredBiome2 != null || DesiredBiome3 != null)
			{
				int num = levelIndex;
				string biomeIdForLevel = GetBiomeIdForLevel(__instance, levelIndex);
				string text = DesiredBiome2?.ToUpper() ?? (biomeIdForLevel.Contains("T") ? "T" : "R");
				string text2 = DesiredBiome3?.ToUpper() ?? (biomeIdForLevel.Contains("A") ? "A" : "M");
				string text3 = "S" + text + text2 + "V";
				int[] value;
				if (biomeIdForLevel == text3)
				{
					Plugin.Log.LogInfo((object)$"[LevelOverride] Level {levelIndex} already has {text3}");
				}
				else if (BiomeToLevels.TryGetValue(text3, out value))
				{
					int num2 = value[num % value.Length];
					Plugin.Log.LogInfo((object)$"[LevelOverride] Redirecting level {num} ({biomeIdForLevel}) -> {num2} ({text3})");
					levelIndex = num2;
				}
				else
				{
					Plugin.Log.LogWarning((object)("[LevelOverride] Unknown biome combo: " + text3));
				}
			}
		}

		[HarmonyPatch("GetBiomeID")]
		[HarmonyPostfix]
		public static void GetBiomeID_Postfix(MapBaker __instance, int levelIndex, ref string __result)
		{
			if (DesiredBiome2 != null || DesiredBiome3 != null)
			{
				string text = DesiredBiome2?.ToUpper() ?? (__result.Contains("T") ? "T" : "R");
				string text2 = DesiredBiome3?.ToUpper() ?? (__result.Contains("A") ? "A" : "M");
				string text3 = "S" + text + text2 + "V";
				if (__result != text3)
				{
					Plugin.Log.LogInfo((object)("[LevelOverride] BiomeID override: " + __result + " -> " + text3));
					__result = text3;
				}
			}
		}

		private static string GetBiomeIdForLevel(MapBaker baker, int levelIndex)
		{
			if (baker.BiomeIDs == null || baker.BiomeIDs.Count == 0)
			{
				return "STMV";
			}
			return baker.BiomeIDs[levelIndex % baker.BiomeIDs.Count];
		}
	}
	[HarmonyPatch(typeof(MapBaker))]
	public static class MapBakerDebugPatch
	{
		private static bool _hasDumped;

		[HarmonyPatch("GetLevel")]
		[HarmonyPostfix]
		public static void GetLevel_Postfix(MapBaker __instance, int levelIndex, string __result)
		{
			if (!_hasDumped)
			{
				_hasDumped = true;
				DumpMapBakerData(__instance);
			}
			Plugin.Log.LogInfo((object)$"[GetLevel] levelIndex={levelIndex} => result=\"{__result}\"");
		}

		[HarmonyPatch("GetBiomeID")]
		[HarmonyPostfix]
		public static void GetBiomeID_Postfix(MapBaker __instance, int levelIndex, string __result)
		{
			int num = levelIndex % __instance.BiomeIDs.Count;
			Plugin.Log.LogInfo((object)$"[GetBiomeID] levelIndex={levelIndex} (actual={num}) => biomeID=\"{__result}\"");
		}

		private static void DumpMapBakerData(MapBaker baker)
		{
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogInfo((object)"=== MapBaker Data Dump ===");
			ManualLogSource log = Plugin.Log;
			string[] allLevels = baker.AllLevels;
			log.LogInfo((object)$"AllLevels.Length = {((allLevels != null) ? allLevels.Length : 0)}");
			if (baker.AllLevels != null)
			{
				for (int i = 0; i < baker.AllLevels.Length; i++)
				{
					Plugin.Log.LogInfo((object)$"  AllLevels[{i}] = \"{baker.AllLevels[i]}\"");
				}
			}
			Plugin.Log.LogInfo((object)"");
			Plugin.Log.LogInfo((object)$"BiomeIDs.Count = {baker.BiomeIDs?.Count ?? 0}");
			if (baker.BiomeIDs != null)
			{
				for (int j = 0; j < baker.BiomeIDs.Count; j++)
				{
					string text = baker.BiomeIDs[j];
					string arg = DecodeBiomeID(text);
					Plugin.Log.LogInfo((object)$"  BiomeIDs[{j}] = \"{text}\" ({arg})");
				}
			}
			Plugin.Log.LogInfo((object)"");
			Plugin.Log.LogInfo((object)$"selectedBiomes.Count = {baker.selectedBiomes?.Count ?? 0}");
			if (baker.selectedBiomes != null)
			{
				for (int k = 0; k < baker.selectedBiomes.Count; k++)
				{
					BiomeResult val = baker.selectedBiomes[k];
					string arg2 = string.Join(", ", val.selectedBiomes);
					Plugin.Log.LogInfo((object)$"  selectedBiomes[{k}] = [{arg2}] => \"{val}\"");
				}
			}
			Plugin.Log.LogInfo((object)"");
			Plugin.Log.LogInfo((object)$"biomeSelection.Count = {baker.biomeSelection?.Count ?? 0}");
			if (baker.biomeSelection != null)
			{
				for (int l = 0; l < baker.biomeSelection.Count; l++)
				{
					BiomeSelection val2 = baker.biomeSelection[l];
					Plugin.Log.LogInfo((object)$"  biomeSelection[{l}] options:");
					foreach (BiomeSelectionOption biomeOption in val2.biomeOptions)
					{
						Plugin.Log.LogInfo((object)$"    - {biomeOption.biome} (weight={biomeOption.weight}, maxInRow={biomeOption.preventMoreThanXInARow})");
					}
				}
			}
			Plugin.Log.LogInfo((object)"");
			Plugin.Log.LogInfo((object)"=== Level/Biome Correlation ===");
			string[] allLevels2 = baker.AllLevels;
			int num = ((allLevels2 != null) ? allLevels2.Length : 0);
			int num2 = baker.BiomeIDs?.Count ?? 0;
			Plugin.Log.LogInfo((object)$"AllLevels has {num} entries, BiomeIDs has {num2} entries");
			if (num > 0 && num2 > 0)
			{
				Plugin.Log.LogInfo((object)$"Ratio: {(float)num2 / (float)num:F2} biomes per level");
				Plugin.Log.LogInfo((object)("Are they 1:1? " + ((num == num2) ? "YES" : "NO")));
			}
			Plugin.Log.LogInfo((object)"=== End MapBaker Data Dump ===");
		}

		private static string DecodeBiomeID(string biomeId)
		{
			if (string.IsNullOrEmpty(biomeId))
			{
				return "empty";
			}
			List<string> list = new List<string>();
			foreach (char c in biomeId)
			{
				string text;
				switch (c)
				{
				case 'S':
					text = "Shore";
					break;
				case 'T':
					text = "Tropics";
					break;
				case 'R':
					text = "Roots";
					break;
				case 'A':
					text = "Alpine";
					break;
				case 'M':
					text = "Mesa";
					break;
				case 'K':
				case 'V':
					text = "Kiln/Volcano";
					break;
				case 'P':
					text = "Peak";
					break;
				default:
					text = $"Unknown({c})";
					break;
				}
				string item = text;
				list.Add(item);
			}
			return string.Join(" + ", list);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}