Decompiled source of FoundationPainter v0.3.2

ExcelDsp.Painter.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExcelDsp.Painter.Extensions;
using ExcelDsp.Painter.Grids;
using ExcelDsp.Painter.Grids.Ranges;
using ExcelDsp.Painter.Tools;
using ExcelDsp.Painter.Utility;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ExcelDsp.Painter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("DSP plugin to easily paint foundations")]
[assembly: AssemblyFileVersion("0.3.2.0")]
[assembly: AssemblyInformationalVersion("0.3.2+96d0c9ab65fd255a48b8bb17e689ac54c090edc8")]
[assembly: AssemblyProduct("ExcelDsp.Painter")]
[assembly: AssemblyTitle("ExcelDsp.Painter")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.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 ExcelDsp.Painter
{
	[BepInPlugin("ExcelDsp.Painter", "Foundation Painter", "0.3.2")]
	public class PainterPlugin : BaseUnityPlugin
	{
		private Harmony? _harmony;

		private ConfigEntry<KeyboardShortcut>? _enableKey;

		private ConfigEntry<KeyboardShortcut>? _shortestPathKey;

		public const string Name = "Foundation Painter";

		public const string Id = "ExcelDsp.Painter";

		public void Awake()
		{
			//IL_0031: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			Shared.Logger = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Foundation Painter v0.3.2 loaded");
			_enableKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keyboard Shortcuts", "EnableKey", KeyboardShortcut.Deserialize("D + LeftControl"), "Keyboard shortcut to enable/disable foundation painting");
			_shortestPathKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keyboard Shortcuts", "ShortestPathKey", KeyboardShortcut.Deserialize("P + LeftControl"), "Keyboard shortcut to toggle between the shortest or longest path");
			_harmony = new Harmony("ExcelDsp.Painter");
			_harmony.PatchAll(typeof(PainterPlugin).Assembly);
			_harmony = null;
		}

		public void Update()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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)
			KeyboardShortcut value;
			if (_enableKey != null)
			{
				value = _enableKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					FoundationDrawer.IsEnabled = !FoundationDrawer.IsEnabled;
					string text = (FoundationDrawer.IsEnabled ? "Enabled" : "Disabled");
					((BaseUnityPlugin)this).Logger.LogInfo((object)text);
				}
			}
			if (_shortestPathKey != null)
			{
				value = _shortestPathKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					FoundationDrawer.UseShortestPath = !FoundationDrawer.UseShortestPath;
					string text2 = (FoundationDrawer.UseShortestPath ? "shortest" : "longest");
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Using " + text2 + " path"));
				}
			}
		}
	}
	public static class Shared
	{
		public const string Version = "0.3.2";

		public static ManualLogSource? Logger { get; set; }
	}
}
namespace ExcelDsp.Painter.Utility
{
	internal static class Localized
	{
		public static string LackOfItem => Localization.Translate("物品不足");

		public static string NotEnoughSoilPile => Localization.Translate("沙土不足");
	}
}
namespace ExcelDsp.Painter.Tools
{
	internal static class FoundationDrawer
	{
		private static Vector3? _start;

		private static readonly Bounds _tileBounds;

		private static readonly GridRectangle _rect;

		public static bool IsEnabled { get; set; }

		public static bool UseShortestPath { get; set; }

		static FoundationDrawer()
		{
			//IL_0026: 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_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)
			_rect = new GridRectangle();
			UseShortestPath = true;
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0.33f, 0.08000001f, 0.33f);
			_tileBounds = new Bounds(Vector3.zero, val);
		}

		public static void UpdateRaycast(BuildTool_Reform reformTool)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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)
			reformTool.brushSize = 1;
			reformTool.cursorValid = Raycast(((BuildTool)reformTool).mouseRay, out var target);
			SelectRange(reformTool, target, target, useShortestPath: true);
			PlayerController controller = ((BuildTool)reformTool).controller;
			CommandState cmd = ((BuildTool)reformTool).controller.cmd;
			cmd.test = target;
			cmd.target = reformTool.cursorTarget;
			cmd.state = (reformTool.cursorValid ? 1 : 0);
			controller.cmd = cmd;
		}

		public static void UpdateAction(BuildTool_Reform reformTool)
		{
			//IL_002a: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			if (VFInput.onGUIOperate)
			{
				return;
			}
			UICursor.SetCursor((ECursor)(reformTool.cursorValid ? 8 : 6));
			string text = null;
			if (_start.HasValue)
			{
				if (VFInput.rtsCancel.onDown)
				{
					Reset(reformTool);
					VFInput.UseMouseRight();
				}
				else if (reformTool.cursorValid)
				{
					SelectRange(reformTool, _start.Value, reformTool.cursorTarget, UseShortestPath);
					if (VFInput._buildConfirm.onDown)
					{
						ApplyReform(reformTool);
					}
					else
					{
						int num = reformTool.cursorIndices.Count((int i) => i > 0);
						text = $"Selected area: {num}";
					}
				}
			}
			else if (reformTool.cursorValid && VFInput._buildConfirm.onDown)
			{
				_start = reformTool.cursorTarget;
			}
			else
			{
				text = "Select starting point";
			}
			if (text != null)
			{
				((BuildTool)reformTool).actionBuild.model.cursorText = text;
			}
		}

		public static void Reset(BuildTool_Reform reformTool)
		{
			_start = null;
			UseShortestPath = true;
			Array.Resize(ref reformTool.cursorPoints, 100);
			Array.Resize(ref reformTool.cursorIndices, 100);
		}

		private static void SelectRange(BuildTool_Reform reformTool, Vector3 start, Vector3 end, bool useShortestPath)
		{
			//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_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)
			_rect.Calculate(((BuildTool)reformTool).planet, start, end, useShortestPath);
			_rect.Export(ref reformTool.cursorIndices, ref reformTool.cursorPoints, out reformTool.cursorPointCount, out reformTool.cursorTarget);
			reformTool.reformCenterPoint = reformTool.cursorTarget;
		}

		private static bool Raycast(Ray ray, out Vector3 target)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			target = Vector3.zero;
			if (VFInput.onGUIOperate || !VFInput.inScreen)
			{
				return false;
			}
			RaycastHit val = default(RaycastHit);
			bool flag = Physics.Raycast(ray, ref val, 400f, 528, (QueryTriggerInteraction)2);
			if (!flag)
			{
				flag = Physics.Raycast(new Ray(((Ray)(ref ray)).GetPoint(200f), -((Ray)(ref ray)).direction), ref val, 200f, 528, (QueryTriggerInteraction)2);
			}
			if (!flag)
			{
				return false;
			}
			target = ((RaycastHit)(ref val)).point;
			return true;
		}

		private static void ApplyReform(BuildTool_Reform reformTool)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			int neededSand = ComputeFlattenTerrain(reformTool);
			if (CanApplyReform(reformTool, neededSand))
			{
				VFAudio.Create("reform-terrain", (Transform)null, reformTool.reformCenterPoint, true, 4, -1, -1L);
				ConsumeFoundation(reformTool);
				ConsumeSand(reformTool, neededSand);
				EndFlattenTerrain(reformTool);
				SetReformProps(reformTool);
				Reset(reformTool);
			}
		}

		private static int ComputeFlattenTerrain(BuildTool_Reform reformTool)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			PlanetFactory factory = ((BuildTool)reformTool).factory;
			factory.BeginFlattenTerrain();
			for (int i = 0; i < reformTool.cursorPointCount; i++)
			{
				Vector3 val = reformTool.cursorPoints[i];
				factory.FlattenTerrain(val, Quaternion.identity, _tileBounds, 3f, 1f, false, true, true, false, default(Bounds));
			}
			if (GameMain.data.history.HasFeatureKey(1100001) && GameMain.sandboxToolsEnabled)
			{
				return 0;
			}
			int num = factory.EndComputeFlattenTerrain();
			return reformTool.GetNeedSandCountByInc(((Proto)reformTool.handItem).ID, reformTool.cursorPointCount, num);
		}

		private static bool CanApplyReform(BuildTool_Reform reformTool, int neededSand)
		{
			Player player = ((BuildTool)reformTool).player;
			int num = player.package.GetItemCount(((Proto)reformTool.handItem).ID) + player.inhandItemCount;
			int cursorPointCount = reformTool.cursorPointCount;
			if (num < cursorPointCount)
			{
				UIRealtimeTip.Popup(Localized.LackOfItem, true, 1);
				return false;
			}
			if ((!GameMain.data.history.HasFeatureKey(1100001) || !GameMain.sandboxToolsEnabled) && player.sandCount < neededSand)
			{
				UIRealtimeTip.Popup(Localized.NotEnoughSoilPile, true, 0);
				return false;
			}
			return true;
		}

		private static void ConsumeFoundation(BuildTool_Reform reformTool)
		{
			Player player = ((BuildTool)reformTool).player;
			int iD = ((Proto)reformTool.handItem).ID;
			int num = reformTool.cursorPointCount;
			GameMain.statistics.production.factoryStatPool[((BuildTool)reformTool).factory.index].consumeRegister[iD] += num;
			GameScenarioLogic gameScenario = GameMain.gameScenario;
			if (gameScenario != null)
			{
				gameScenario.NotifyOnBuild(((BuildTool)reformTool).planet.id, iD, 0);
			}
			GameMain.history.MarkItemBuilt(iD, num);
			int num3 = default(int);
			if (player.inhandItemCount > 0)
			{
				int num2 = Math.Min(num, player.inhandItemCount);
				player.UseHandItems(num2, ref num3);
				num -= num2;
			}
			player.package.TakeTailItems(ref iD, ref num, ref num3, false);
		}

		private static void ConsumeSand(BuildTool_Reform reformTool, int neededSand)
		{
			Player player = ((BuildTool)reformTool).player;
			long sandCount = player.sandCount - neededSand;
			player.SetSandCount(sandCount);
			reformTool.SetHistorySandGotFeature(-neededSand);
		}

		private static void EndFlattenTerrain(BuildTool_Reform reformTool)
		{
			((BuildTool)reformTool).factory.EndFlattenTerrain(true);
		}

		private static void SetReformProps(BuildTool_Reform reformTool)
		{
			PlatformSystem platformSystem = ((BuildTool)reformTool).factory.platformSystem;
			int[] cursorIndices = reformTool.cursorIndices;
			foreach (int num in cursorIndices)
			{
				if (num >= 0)
				{
					int reformType = platformSystem.GetReformType(num);
					int reformColor = platformSystem.GetReformColor(num);
					if (reformType != reformTool.brushType || reformColor != reformTool.brushColor)
					{
						platformSystem.SetReformType(num, reformTool.brushType);
						platformSystem.SetReformColor(num, reformTool.brushColor);
					}
				}
			}
		}
	}
}
namespace ExcelDsp.Painter.Patches
{
	[HarmonyPatch(typeof(BuildTool_Reform))]
	internal static class BuildTool_Reform_Patch
	{
		[HarmonyPrefix]
		[HarmonyPatch("UpdateRaycast")]
		public static bool UpdateRaycast_Prefix(BuildTool_Reform __instance)
		{
			for (int i = 0; i < __instance.cursorIndices.Length; i++)
			{
				__instance.cursorIndices[i] = -1;
			}
			if (!FoundationDrawer.IsEnabled)
			{
				return true;
			}
			FoundationDrawer.UpdateRaycast(__instance);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("ReformAction")]
		public static bool ReformAction_Prefix(BuildTool_Reform __instance)
		{
			if (!FoundationDrawer.IsEnabled)
			{
				return true;
			}
			FoundationDrawer.UpdateAction(__instance);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("_OnClose")]
		public static void OnClose_Prefix(BuildTool_Reform __instance)
		{
			FoundationDrawer.Reset(__instance);
		}
	}
	[HarmonyPatch(typeof(UIBuildingGrid))]
	internal class UIBuildingGrid_Patch
	{
		[HarmonyTranspiler]
		[HarmonyPatch("Update")]
		public static IEnumerable<CodeInstruction> Update_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			FieldInfo brushSize = AccessTools.Field(typeof(BuildTool_Reform), "brushSize");
			FieldInfo fieldInfo = AccessTools.Field(typeof(BuildTool_Reform), "cursorIndices");
			CodeMatcher obj = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[4]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && (FieldInfo)i.operand == brushSize), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && (FieldInfo)i.operand == brushSize), (string)null),
				new CodeMatch((OpCode?)OpCodes.Mul, (object)null, (string)null)
			});
			if (!obj.IsValid)
			{
				throw new InvalidOperationException("Failed to find patch target");
			}
			return obj.RemoveInstructions(4).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
			{
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo),
				new CodeInstruction(OpCodes.Ldlen, (object)null)
			}).InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(UIBuildMenu))]
	internal static class UIBuildMenu_Patch
	{
	}
}
namespace ExcelDsp.Painter.Grids
{
	internal class GridRectangle
	{
		private readonly List<GridTile> _tiles = new List<GridTile>();

		private PlanetData? _planet;

		public void Export(ref int[] indices, ref Vector3[] points, out int pointCount, out Vector3 centerPoint)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			if (_planet == null)
			{
				throw new InvalidOperationException("Must calculate first");
			}
			EnsureSize(ref points, _tiles.Count);
			EnsureSize(ref indices, _tiles.Count);
			PlatformSystem platformSystem = _planet.factory.platformSystem;
			float num = _planet.radius + 0.2f;
			pointCount = 0;
			if (_tiles.Count == 0)
			{
				centerPoint = Vector3.zero;
				return;
			}
			int index = _tiles.Count / 2;
			GridTile gridTile = _tiles[index];
			centerPoint = gridTile.CalculatePosition() * num;
			for (int i = 0; i < _tiles.Count; i++)
			{
				GridTile gridTile2 = _tiles[i];
				int reformIndexForSegment = platformSystem.GetReformIndexForSegment(gridTile2.Latitude.Segment, gridTile2.Longitude.Segment);
				indices[i] = reformIndexForSegment;
				int reformType = platformSystem.GetReformType(reformIndexForSegment);
				if (!platformSystem.IsTerrainReformed(reformType))
				{
					points[pointCount++] = gridTile2.CalculatePosition() * num;
				}
			}
		}

		public void Calculate(PlanetData planet, Vector3 startPos, Vector3 endPos, bool useShortestPath)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			_planet = planet;
			_tiles.Clear();
			PlanetGrid mainGrid = planet.aux.mainGrid;
			PlatformSystem platformSystem = planet.factory.platformSystem;
			platformSystem.EnsureReformData();
			float latSegmentMax = platformSystem.latitudeCount / 10;
			GridTile gridTile = GridTile.FromPosition(mainGrid, startPos);
			GridTile gridTile2 = GridTile.FromPosition(mainGrid, endPos);
			if (!gridTile2.Longitude.IsValid || !gridTile2.LatitudeRow.IsValid(latSegmentMax))
			{
				gridTile2 = gridTile;
			}
			SimpleRange simpleRange = SimpleRange.Create(gridTile.Latitude.Element, gridTile2.Latitude.Element);
			bool invert = CalculatePath(end: GridTile.FromLongitudeAngle(gridTile.LatitudeRow, gridTile2.Longitude.Angle), row: gridTile.LatitudeRow, start: gridTile, useShortestPath: useShortestPath);
			foreach (int item in simpleRange)
			{
				GridRow gridRow = GridRow.FromLatitudeElement(mainGrid, item);
				if (gridRow.IsValid(latSegmentMax))
				{
					AddRow(gridRow, gridTile, gridTile2, invert);
				}
			}
		}

		private void AddRow(GridRow row, GridTile start, GridTile end, bool invert)
		{
			GridTile gridTile = GridTile.FromLongitudeAngle(row, start.Longitude.Angle);
			SimpleRange simpleRange = SimpleRange.Create(b: GridTile.FromLongitudeAngle(row, end.Longitude.Angle).Longitude.Element, a: gridTile.Longitude.Element);
			ExcelDsp.Painter.Grids.Ranges.Range range = simpleRange;
			if (invert)
			{
				SimpleRange elementRange = PolarCoordinate.GetElementRange(row.LongitudeSegments);
				range = simpleRange.Invert(elementRange);
			}
			foreach (int item in range)
			{
				GridTile gridTile2 = GridTile.FromLongitudeElement(row, item);
				if (gridTile2.Longitude.IsValid)
				{
					_tiles.Add(gridTile2);
				}
			}
		}

		private static bool CalculatePath(GridRow row, GridTile start, GridTile end, bool useShortestPath)
		{
			GridTile gridTile = GridTile.FromLongitudeAngle(row, start.Longitude.Angle);
			SimpleRange obj = SimpleRange.Create(b: GridTile.FromLongitudeAngle(row, end.Longitude.Angle).Longitude.Element, a: gridTile.Longitude.Element);
			int num = PolarCoordinate.GetElementRange(row.LongitudeSegments).Count / 2;
			return obj.Count > num == useShortestPath;
		}

		private static void EnsureSize<T>(ref T[] array, int size)
		{
			if (array.Length < size)
			{
				Array.Resize(ref array, size);
			}
		}
	}
	internal class GridRow
	{
		public readonly PolarCoordinate Latitude;

		public readonly int LongitudeSegments;

		public GridRow(PlanetGrid grid, PolarCoordinate latitude)
		{
			Latitude = latitude;
			LongitudeSegments = grid.CalculateLongitudeSegments(latitude.Segment);
			base..ctor();
		}

		public static GridRow FromLatitudeAngle(PlanetGrid grid, float latAngle)
		{
			return new GridRow(grid, PolarCoordinate.FromAngle(latAngle, grid.segment));
		}

		public static GridRow FromLatitudeElement(PlanetGrid grid, int latElement)
		{
			return new GridRow(grid, PolarCoordinate.FromElement(latElement, grid.segment));
		}

		public bool IsValid(float latSegmentMax)
		{
			if (Latitude.IsValid && Latitude.Segment < latSegmentMax)
			{
				return Latitude.Segment > 0f - latSegmentMax;
			}
			return false;
		}
	}
	internal class GridTile
	{
		public readonly GridRow LatitudeRow;

		public readonly PolarCoordinate Longitude;

		public PolarCoordinate Latitude => LatitudeRow.Latitude;

		public GridTile(GridRow row, PolarCoordinate longitude)
		{
			LatitudeRow = row;
			Longitude = longitude;
			base..ctor();
		}

		public static GridTile FromLongitudeAngle(GridRow row, float longAngle)
		{
			return new GridTile(row, PolarCoordinate.FromAngle(longAngle, row.LongitudeSegments));
		}

		public static GridTile FromLongitudeElement(GridRow row, int longElement)
		{
			return new GridTile(row, PolarCoordinate.FromElement(longElement, row.LongitudeSegments));
		}

		public static GridTile FromPosition(PlanetGrid grid, Vector3 position)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 normalized = ((Vector3)(ref position)).normalized;
			float latAngle = Mathf.Asin(normalized.y);
			float longAngle = Mathf.Atan2(normalized.x, 0f - normalized.z);
			return FromLongitudeAngle(GridRow.FromLatitudeAngle(grid, latAngle), longAngle);
		}

		public Vector3 CalculatePosition()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Sin(Latitude.Angle);
			float num2 = Mathf.Cos(Latitude.Angle);
			float num3 = Mathf.Sin(Longitude.Angle);
			float num4 = Mathf.Cos(Longitude.Angle);
			return new Vector3(num2 * num3, num, num2 * (0f - num4));
		}

		public override string ToString()
		{
			return $"({Latitude.Element},{Longitude.Element})";
		}
	}
	internal readonly struct PolarCoordinate
	{
		private const int ElementsPerSegment = 5;

		private const float SegmentOffset = -0.1f;

		private const float Pi2 = (float)Math.PI * 2f;

		public readonly float Angle;

		public readonly float Segment;

		public readonly int Element;

		public bool IsValid => Element != 0;

		public PolarCoordinate(float angle, int element)
		{
			Angle = angle;
			Segment = ElementToSegment(element);
			Element = element;
		}

		public static PolarCoordinate FromAngle(float angle, int segments)
		{
			int element = AngleToElement(angle, segments);
			return new PolarCoordinate(angle, element);
		}

		public static PolarCoordinate FromElement(int element, int segments)
		{
			return new PolarCoordinate(SegmentToAngle(ElementToSegment(element), segments), element);
		}

		public static SimpleRange GetElementRange(int segments)
		{
			int num = segments / 2 * 5;
			return new SimpleRange(-num, num);
		}

		private static int AngleToElement(float angle, int segments)
		{
			return SegmentToElement(angle / ((float)Math.PI * 2f) * (float)segments);
		}

		private static float SegmentToAngle(float segment, int segments)
		{
			return segment / (float)segments * ((float)Math.PI * 2f);
		}

		private static int SegmentToElement(float segment)
		{
			float num = segment * 5f;
			if (num > 0f)
			{
				return Mathf.CeilToInt(num);
			}
			return Mathf.FloorToInt(num);
		}

		private static float ElementToSegment(int element)
		{
			float num = (float)element / 5f;
			float num2 = ((num > 0f) ? (-0.1f) : 0.1f);
			return num + num2;
		}
	}
}
namespace ExcelDsp.Painter.Grids.Ranges
{
	internal class CompoundRange : Range
	{
		private readonly Range[] _ranges;

		public override int Count => _ranges.Sum((Range r) => r.Count);

		public CompoundRange(params Range[] ranges)
		{
			_ranges = ranges;
			base..ctor();
		}

		public override IEnumerator<int> GetEnumerator()
		{
			return _ranges.SelectMany((Range r) => r).GetEnumerator();
		}
	}
	internal abstract class Range : IEnumerable<int>, IEnumerable
	{
		public abstract int Count { get; }

		public abstract IEnumerator<int> GetEnumerator();

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	internal class SimpleRange : Range
	{
		private readonly int _min;

		private readonly int _max;

		public override int Count => _max - _min;

		public SimpleRange(int min, int max)
		{
			_min = min;
			_max = max;
			base..ctor();
		}

		public CompoundRange Invert(SimpleRange fullRange)
		{
			SimpleRange simpleRange = new SimpleRange(_max, fullRange._max);
			SimpleRange simpleRange2 = new SimpleRange(fullRange._min, _min);
			return new CompoundRange(simpleRange, simpleRange2);
		}

		public override IEnumerator<int> GetEnumerator()
		{
			for (int i = _min; i <= _max; i++)
			{
				yield return i;
			}
		}

		public static SimpleRange Create(int a, int b)
		{
			if (a < b)
			{
				return new SimpleRange(a, b);
			}
			return new SimpleRange(b, a);
		}
	}
}
namespace ExcelDsp.Painter.Extensions
{
	internal static class PlanetFactoryExtensions
	{
		public static int EndComputeFlattenTerrain(this PlanetFactory factory)
		{
			PlanetData planet = factory.planet;
			PlanetRawData data = planet.data;
			int num = 0;
			foreach (KeyValuePair<int, int> tmp_levelChange in factory.tmp_levelChanges)
			{
				int key = tmp_levelChange.Key;
				int value = tmp_levelChange.Value;
				int modLevel = data.GetModLevel(key);
				int num2 = value - modLevel;
				float num3 = (float)(int)data.heightData[key] * 0.01f;
				float num4 = planet.realRadius + 0.2f - num3;
				if (num4 < 0f)
				{
					num4 *= 2f;
				}
				float num5 = 100f * (float)num2 * num4 * 0.3333333f;
				num += Mathf.FloorToInt(num5);
			}
			return num;
		}
	}
	internal static class PlanetGridExtensions
	{
		public static int CalculateLongitudeSegments(this PlanetGrid grid, float latSegment)
		{
			return PlanetGrid.DetermineLongitudeSegmentCount(Mathf.FloorToInt(Mathf.Abs(latSegment)), grid.segment);
		}
	}
}