Decompiled source of MapMaker v0.13.0
MapMaker.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Burst2Flame; using Burst2Flame.Observable; using HarmonyLib; using HexMapTools; using MapNodeSystem; using Microsoft.CodeAnalysis; using ModNet; using ModsMenu; using Newtonsoft.Json; using StolenRealmModAPI; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MapMaker")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e541341b423e7e02f062bf9975ad907cb3f30935")] [assembly: AssemblyProduct("MapMaker")] [assembly: AssemblyTitle("MapMaker")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 MapMaker { internal static class Icons { internal const int TileSize = 48; internal const int PropSize = 96; private const int Layer = 31; private const float Crop = 0.55f; private const float Pitch = 35f; private const float Turn = 30f; private static readonly Color TileBack = new Color(0.1f, 0.1f, 0.1f, 1f); private static readonly Color PropBack = new Color(0.17f, 0.18f, 0.2f, 1f); private static readonly Vector3 At = new Vector3(0f, -2000f, 0f); private static readonly Dictionary<Object, Texture2D> Done = new Dictionary<Object, Texture2D>(); private static readonly List<Object> Wanted = new List<Object>(); private static readonly Dictionary<GameObject, PropCatalog.Prop> Props = new Dictionary<GameObject, PropCatalog.Prop>(); internal static readonly Texture2D NoPicture = new Texture2D(1, 1) { name = "MapMaker no picture", hideFlags = (HideFlags)61 }; internal static Texture2D Tile(Material material) { return Get((Object)(object)material); } internal static Texture2D Prop(PropCatalog.Prop prop) { if ((Object)(object)prop?.Source == (Object)null) { return null; } Props[prop.Source] = prop; return Get((Object)(object)prop.Source); } private static Texture2D Get(Object key) { if (key == (Object)null) { return null; } if (Done.TryGetValue(key, out var value)) { return value; } if (!Wanted.Contains(key)) { Wanted.Add(key); } return null; } internal static void Tick() { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown if (Wanted.Count == 0) { return; } HexCell hex = ((IEnumerable<HexCell>)MapBuilder.Cells).FirstOrDefault((Func<HexCell, bool>)delegate(HexCell c) { if ((Object)(object)c != (Object)null) { MeshFilter component = ((Component)c).GetComponent<MeshFilter>(); return (Object)(object)((component != null) ? component.sharedMesh : null) != (Object)null; } return false; }); foreach (Object item in Wanted.Where((Object k) => (Object)(object)hex != (Object)null || !(k is Material)).Take(4).ToList()) { Wanted.Remove(item); Texture2D val = null; if (item != (Object)null) { try { Material val2 = (Material)(object)((item is Material) ? item : null); val = ((val2 != null) ? RenderTile(((Component)hex).transform, ((Component)hex).GetComponent<MeshFilter>().sharedMesh, val2) : RenderProp(Props[(GameObject)item])); } catch (Exception ex) { Plugin.ModLog.LogWarning((object)("MapMaker: no picture of '" + item.name + "': " + ex.Message)); } } Done[item] = (((Object)(object)val != (Object)null || item is Material) ? val : NoPicture); } } private static Texture2D RenderTile(Transform model, Mesh mesh, Material material) { //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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("MapMaker tile icon") { layer = 31, hideFlags = (HideFlags)61 }; try { val.transform.SetPositionAndRotation(At, model.rotation); val.transform.localScale = model.lossyScale; Bounds val2 = Show(val, mesh, (Material[])(object)new Material[1] { material }); Quaternion look = Quaternion.Euler(90f, 0f, 0f); return Snap(new Vector3(((Bounds)(ref val2)).center.x, ((Bounds)(ref val2)).max.y + 2f, ((Bounds)(ref val2)).center.z), look, Mathf.Min(((Bounds)(ref val2)).extents.x, ((Bounds)(ref val2)).extents.z) * 0.55f, 10f, 48, TileBack, "MapMaker tile " + ((Object)material).name); } finally { Object.DestroyImmediate((Object)(object)val); } } private static Texture2D RenderProp(PropCatalog.Prop prop) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0161: 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_018b: Expected O, but got Unknown //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024e: 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_027b: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) GameObject source = prop.Source; HashSet<Renderer> hashSet = new HashSet<Renderer>(); LODGroup[] componentsInChildren = source.GetComponentsInChildren<LODGroup>(true); for (int i = 0; i < componentsInChildren.Length; i++) { foreach (LOD item4 in componentsInChildren[i].GetLODs().Skip(1)) { Renderer[] renderers = item4.renderers; foreach (Renderer val in renderers) { if ((Object)(object)val != (Object)null) { hashSet.Add(val); } } } } GameObject val2 = new GameObject("MapMaker prop icon") { hideFlags = (HideFlags)61 }; try { Bounds? val3 = null; foreach (MeshFilter item5 in MapBuilder.ShownMeshes(source)) { MeshRenderer component = ((Component)item5).GetComponent<MeshRenderer>(); if (!((Object)(object)component == (Object)null) && ((Renderer)component).enabled && !hashSet.Contains((Renderer)(object)component)) { GameObject val4 = new GameObject(((Object)item5).name) { layer = 31, hideFlags = (HideFlags)61 }; val4.transform.SetParent(val2.transform, false); val4.transform.SetPositionAndRotation(At + ((Component)item5).transform.position - source.transform.position, ((Component)item5).transform.rotation); val4.transform.localScale = ((Component)item5).transform.lossyScale; Bounds val5 = Show(val4, item5.sharedMesh, ((Renderer)component).sharedMaterials); if (!val3.HasValue) { val3 = val5; continue; } Bounds value = val3.Value; ((Bounds)(ref value)).Encapsulate(val5); val3 = value; } } if (!val3.HasValue) { return null; } (float length, float width, int axis) tuple = PropCatalog.Footprint(source); float item = tuple.length; float item2 = tuple.width; int item3 = tuple.axis; int num = PropCatalog.Front(prop, item, item2, item3); Quaternion val6 = Quaternion.Euler(35f, ((num >= 0) ? ((float)num + 180f) : 0f) + 30f, 0f); Bounds value2 = val3.Value; Quaternion val7 = Quaternion.Inverse(val6); Vector2 val8 = default(Vector2); ((Vector2)(ref val8))..ctor(float.MaxValue, float.MaxValue); Vector2 val9 = default(Vector2); ((Vector2)(ref val9))..ctor(float.MinValue, float.MinValue); for (int k = 0; k < 8; k++) { Vector3 val10 = val7 * Vector3.Scale(((Bounds)(ref value2)).extents, new Vector3((float)(((k & 1) != 0) ? 1 : (-1)), (float)(((k & 2) != 0) ? 1 : (-1)), (float)(((k & 4) != 0) ? 1 : (-1)))); val8 = Vector2.Min(val8, Vector2.op_Implicit(val10)); val9 = Vector2.Max(val9, Vector2.op_Implicit(val10)); } Vector2 val11 = (val8 + val9) / 2f; float num2 = Mathf.Max(val9.x - val8.x, val9.y - val8.y) / 2f * 1.06f; Vector3 extents = ((Bounds)(ref value2)).extents; float num3 = ((Vector3)(ref extents)).magnitude + 1f; return Snap(((Bounds)(ref value2)).center + val6 * new Vector3(val11.x, val11.y, 0f - num3), val6, Mathf.Max(num2, 0.05f), num3 * 2f, 96, PropBack, "MapMaker prop " + prop.Key); } finally { Object.DestroyImmediate((Object)(object)val2); } } private static Bounds Show(GameObject go, Mesh mesh, Material[] materials) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) go.AddComponent<MeshFilter>().sharedMesh = mesh; MeshRenderer obj = go.AddComponent<MeshRenderer>(); ((Renderer)obj).sharedMaterials = materials; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; return ((Renderer)obj).bounds; } private static Texture2D Snap(Vector3 eye, Quaternion look, float half, float far, int size, Color background, string name) { //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_0013: Expected O, but got Unknown //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_0026: Expected O, but got Unknown //IL_0078: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown GameObject val = new GameObject("MapMaker icon camera") { hideFlags = (HideFlags)61 }; GameObject val2 = new GameObject("MapMaker icon light") { hideFlags = (HideFlags)61 }; RenderTexture temporary = RenderTexture.GetTemporary(size, size, 16, (RenderTextureFormat)0, (RenderTextureReadWrite)0); RenderTexture active = RenderTexture.active; try { Light obj = val2.AddComponent<Light>(); obj.type = (LightType)1; obj.cullingMask = int.MinValue; obj.intensity = 1.1f; obj.shadows = (LightShadows)0; val2.transform.rotation = Quaternion.Euler(60f, 30f, 0f); Camera obj2 = val.AddComponent<Camera>(); ((Behaviour)obj2).enabled = false; obj2.cullingMask = int.MinValue; obj2.clearFlags = (CameraClearFlags)2; obj2.backgroundColor = background; obj2.orthographic = true; obj2.orthographicSize = half; obj2.nearClipPlane = 0.01f; obj2.farClipPlane = far; obj2.allowHDR = false; obj2.allowMSAA = false; val.transform.SetPositionAndRotation(eye, look); obj2.targetTexture = temporary; obj2.Render(); RenderTexture.active = temporary; Texture2D val3 = new Texture2D(size, size, (TextureFormat)3, false) { name = name, hideFlags = (HideFlags)61 }; val3.ReadPixels(new Rect(0f, 0f, (float)size, (float)size), 0, 0); val3.Apply(false, true); return val3; } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); Object.DestroyImmediate((Object)(object)val); Object.DestroyImmediate((Object)(object)val2); } } } internal static class MapAdventure { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<int> FixedChance; private static readonly Random Rand = new Random(); public static string Trial = null; public static readonly Queue<NodeType> TrialRooms = new Queue<NodeType>(); public static string StartTrial(string map) { MapFile.Load(MapBuilder.PathOf(map)); Trial = map; TrialRooms.Clear(); TrialRooms.Enqueue((NodeType)7); TrialRooms.Enqueue((NodeType)4); TrialRooms.Enqueue((NodeType)0); Plugin.ModLog.LogInfo((object)("MapMaker: trial of '" + map + "': the next rooms are an Event, a Shop and a fight, each on this map.")); return "trial of '" + map + "': Event, Shop, fight"; } internal static List<NodeType> TrialCircle() { //IL_001f: 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_002f: 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) if (string.IsNullOrEmpty(Trial) || TrialRooms.Count == 0) { return null; } NodeType val = TrialRooms.Dequeue(); Plugin.ModLog.LogInfo((object)$"MapMaker: trial: the next circle offers only {val} ({TrialRooms.Count} trial rooms after it)."); return new List<NodeType> { val }; } internal static bool InPool(MapFile file) { if (file.adventure && file.party.Length != 0) { return file.enemies.Length != 0; } return false; } internal static List<MapFile> Candidates(string terrain) { List<MapFile> list = new List<MapFile>(); foreach (string item in MapBuilder.Maps()) { try { MapFile mapFile = MapFile.Load(MapBuilder.PathOf(item)); if (InPool(mapFile) && string.Equals(mapFile.terrain, terrain, StringComparison.OrdinalIgnoreCase) && MapPool.IsOn(item)) { list.Add(mapFile); } } catch (Exception ex) { Plugin.ModLog.LogWarning((object)("MapMaker: map '" + item + "' can't be read: " + ex.Message)); } } return list; } internal static MapFile Pick(string terrain, NodeType room) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(Trial)) { try { MapFile mapFile = MapFile.Load(MapBuilder.PathOf(Trial)); Plugin.ModLog.LogInfo((object)$"MapMaker: trial map '{mapFile.name}' takes the next {room} room."); return mapFile; } catch (Exception ex) { Plugin.ModLog.LogWarning((object)("MapMaker: trial map '" + Trial + "' can't be read (" + ex.Message + "); the room stays as the game made it.")); return null; } } List<MapFile> list = Candidates(terrain); if (list.Count == 0) { Plugin.ModLog.LogInfo((object)("MapMaker: no adventure map for " + terrain + " (\"adventure\": true, with party and enemy spots); the room stays as the game made it.")); return null; } int num = Layouts(terrain); bool num2 = ((FixedChance.Value > 0) ? (Rand.Next(100) < FixedChance.Value) : (Rand.Next(list.Count + num) < list.Count)); string arg = Odds(list.Count, num); if (!num2) { Plugin.ModLog.LogInfo((object)$"MapMaker: the roll ({arg}) keeps the next {room} room as the game made it."); return null; } MapFile mapFile2 = list[Rand.Next(list.Count)]; Plugin.ModLog.LogInfo((object)$"MapMaker: the roll ({arg}) gives the next {room} room to '{mapFile2.name}'."); return mapFile2; } internal static int Layouts(string terrain) { return MapPool.LayoutsOn(terrain); } private static string Odds(int maps, int layouts) { if (FixedChance.Value <= 0) { return string.Format("{0} in {1}: {2} map{3}, {4} of the game's rooms", maps, maps + layouts, maps, (maps == 1) ? "" : "s", layouts); } return $"{FixedChance.Value}%"; } public static string Odds(string terrain) { return Odds(Candidates(terrain).Count, Layouts(terrain)); } private static string Vanilla(PortalManager portals, BattleInfo battle, BattleOverrideInfo over) { //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Invalid comparison between Unknown and I4 NetworkingManager instance = NetworkingManager.Instance; if ((Object)(object)instance == (Object)null || !instance.IsServer || (Object)(object)GameLogic.instance == (Object)null) { return ""; } if (MapBattle.Active) { return "a map battle is on"; } if ((Object)(object)battle == (Object)null) { return "no battle info"; } if (battle.IsFinalBattle) { return "the final battle"; } if (!string.IsNullOrEmpty(battle.bossName) && ((battle.enemies != null && battle.enemies.Any((CharacterInfo e) => (Object)(object)e != (Object)null && ((Object)e).name == battle.bossName)) || (battle.guaranteedEnemies != null && battle.guaranteedEnemies.Any((CharacterInfo e) => (Object)(object)e != (Object)null && ((Object)e).name == battle.bossName)) || Mathf.Abs((float)battle.CalculatedBattlePointValue - battle.CalculatedBattlePointValueWithoutBoss) > 0.5f)) { return "a boss battle"; } if (battle.isTownBattle) { return "a town battle"; } if ((Object)(object)battle.nextBattle != (Object)null) { return "a chained battle"; } if ((battle.battleOverrideInfo != null && battle.battleOverrideInfo.ForceMap) || (over != null && over.ForceMap)) { return "the battle brings its own map"; } if ((Object)(object)portals.CurrentIsland == (Object)null || portals.OpeningIsland) { return "no island"; } if ((Object)(object)GUIManager.instance == (Object)null || (int)GUIManager.instance.CurrentGuiState == 2) { return "a battle is on"; } return MapNet.CannotShare(); } internal static bool OnBattleNode(PortalManager portals, Vector3 cellPos, BattleInfo battle, BattleOverrideInfo over) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) HexCellManager val = (((Object)(object)portals.CurrentIsland != (Object)null) ? portals.CurrentIsland.HexCellManager : null); if (!MapRoom.Holds(((Object)(object)val != (Object)null) ? val.GetHexCellFromPos(cellPos) : null)) { return true; } string text = Vanilla(portals, battle, over); if (text != null) { if (text.Length > 0) { Plugin.ModLog.LogInfo((object)("MapMaker: this encounter on '" + MapBuilder.Current.name + "' is fought the game's way: " + text + ".")); } return true; } try { MapBattle.BeginAdventure(MapBuilder.Current); } catch (Exception ex) { Plugin.ModLog.LogWarning((object)("MapMaker: '" + MapBuilder.Current.name + "' can't take this encounter (" + ex.Message + "); the game places everyone.")); MapBattle.Abandon(); } return true; } } [HarmonyPatch(typeof(PortalManager), "BattleNodeActivate")] internal static class MapAdventurePatch { private static bool Prefix(PortalManager __instance, Vector3 cellPos, BattleInfo battleInfo, BattleOverrideInfo battleOverrideInfo) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) try { return MapAdventure.OnBattleNode(__instance, cellPos, battleInfo, battleOverrideInfo); } catch (Exception arg) { Plugin.ModLog.LogError((object)$"MapMaker: adventure map failed; the encounter stays on the island: {arg}"); MapBattle.Abandon(); return true; } } private static void Postfix() { MapBattle.AfterBattleNode(); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class MapTrialCirclePatch { private static void Postfix(ref List<NodeType> __result, ref PartyEvent forcedEvent) { try { if (__result != null && !__result.Contains((NodeType)5)) { List<NodeType> list = MapAdventure.TrialCircle(); if (list != null) { __result = list; forcedEvent = null; } } } catch (Exception arg) { Plugin.ModLog.LogError((object)$"MapMaker: trial circle failed; the game's options stay: {arg}"); } } } public static class MapBattle { internal static bool Armed; internal static bool QuietSetup; private static readonly Dictionary<Character, HexCell> ReturnTo = new Dictionary<Character, HexCell>(); private static readonly List<Character> SetAside = new List<Character>(); private static Character _battleObject; private static bool _seenInBattle; private static float _overSince = -1f; private static object _island; private static bool _eventSwapped; private static HexCell _previousEvent; private static Character _movedEncounter; private static HexCell _movedFrom; private static int _reservedSpot = -1; private static readonly Dictionary<Character, HexCell> HeroSpots = new Dictionary<Character, HexCell>(); private static readonly HashSet<HexCell> SpotsTaken = new HashSet<HexCell>(); private static int _enemiesSpawned; public static bool Active { get; private set; } public static string Status { get; private set; } = ""; internal static bool Adventure { get; private set; } public static string CannotStart() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Invalid comparison between Unknown and I4 NetworkingManager instance = NetworkingManager.Instance; if ((Object)(object)GameLogic.instance == (Object)null || ((instance == null) ? null : ((Observer<Root>)(object)instance.NetworkManager)?.Root) == null) { return "Load a game first."; } PortalManager instance2 = PortalManager.Instance; if ((Object)(object)((instance2 != null) ? instance2.CurrentIsland : null) == (Object)null || PortalManager.Instance.OpeningIsland) { return "Go on an adventure first: maps are fought next to a quest island."; } if (Active || (int)GUIManager.instance.CurrentGuiState == 2) { return "A battle is already on."; } if ((int)GUIManager.instance.CurrentGuiState != 3) { return "Only while exploring an island."; } if (!instance.IsServer) { return "Only the host can start a map battle."; } if (MapRoom.Placed) { return MapRoom.Busy + "."; } return MapNet.CannotShare(); } public static IEnumerator Fight(string map = null, bool skipPlacement = false, bool hard = false) { string text = CannotStart(); if (text != null) { throw new InvalidOperationException(text); } if (map != null) { Status = "Building '" + map + "'..."; IEnumerator share = MapNet.BuildEverywhere(MapFile.Load(MapBuilder.PathOf(map))); while (share.MoveNext()) { yield return share.Current; } } if (!MapBuilder.Ready) { throw new InvalidOperationException("no map built"); } MapFile current = MapBuilder.Current; if (current.enemies.Length == 0) { throw new InvalidOperationException("map '" + current.name + "' has no enemy spots"); } GameLogic instance = GameLogic.instance; Root root = ((Observer<Root>)(object)NetworkingManager.Instance.NetworkManager).Root; BattleInfo val = GlobalSettingsManager.instance.globalSettings.testBattle ?? throw new InvalidOperationException("GlobalSettings.testBattle is null"); val.enemies = RollEnemies(current, hard); val.guaranteedEnemies = new List<CharacterInfo>(); val.dontFillOutBattlePoints = true; val.enemyMods = new Dictionary<int, List<EnemyMod>>(); instance.CurrentBattle = val; instance.CurrentBattleObjectEnemyIndex = -1; ReturnTo.Clear(); foreach (Character partyCharacter in NetworkingManager.Instance.PartyCharacters) { if (partyCharacter != null && (Object)(object)partyCharacter.Cell != (Object)null && MapBuilder.Where(partyCharacter) == null) { ReturnTo[partyCharacter] = partyCharacter.Cell; } } _island = PortalManager.Instance.CurrentIsland; PortalManager portals = PortalManager.Instance; HexCell previousEvent = portals.currentEventHex; portals.currentEventHex = PartyCentre(current) ?? MapBuilder.Cell(0, 0) ?? MapBuilder.Cells.First((HexCell c) => c.IsWalkable); _battleObject = root.BattleObjectCharacter; root.BattleObjectCharacter = null; SetAside.Clear(); SetAsideStrays(root); Armed = true; Active = true; _seenInBattle = false; _overSince = -1f; Status = "Fighting on '" + current.name + "'."; try { root.SendOpenBattle(); IEnumerator share = Follow(current, skipPlacement); while (share.MoveNext()) { yield return share.Current; } } finally { Armed = false; portals.currentEventHex = previousEvent; } } private static IEnumerator Follow(MapFile file, bool skipPlacement) { GameLogic logic = GameLogic.instance; Root root = ((Observer<Root>)(object)NetworkingManager.Instance.NetworkManager).Root; float until = Time.realtimeSinceStartup + 60f; while (Armed || (!logic.CurrentlyPlacingCharacters && !logic.GameStarted)) { if (!Active) { yield break; } if (Time.realtimeSinceStartup > until) { if (!Adventure) { throw new TimeoutException("the placement phase didn't begin"); } Plugin.ModLog.LogWarning((object)("MapMaker: the battle on '" + file.name + "' didn't begin in 60 s; back to the island.")); Finish(); yield break; } yield return null; } SetAsideStrays(root); List<string> list = PlaceSpawns(root, file, party: true); Plugin.ModLog.LogInfo((object)("MapMaker: battle on '" + file.name + "': " + string.Join("; ", Who()))); if (list.Count > 0) { Plugin.ModLog.LogWarning((object)("MapMaker: moved after they appeared: " + string.Join("; ", list))); } if (skipPlacement) { foreach (Character item in NetworkingManager.Instance.MyPartyCharacters.ToList()) { if ((Object)(object)((item != null) ? item.PlayerMovement : null) != (Object)null && !item.EndedTurn) { item.PlayerMovement.EndTurn(); } } } until = Time.realtimeSinceStartup + 900f; while ((int)GUIManager.instance.CurrentGuiState != 2 || !logic.GameStarted) { if (!Active) { yield break; } if (Time.realtimeSinceStartup > until) { if (!Adventure) { throw new TimeoutException("the battle didn't start"); } yield break; } yield return null; } List<string> list2 = PlaceSpawns(root, file, party: false); if (list2.Count > 0) { Plugin.ModLog.LogInfo((object)("MapMaker: placed late: " + string.Join("; ", list2))); } } internal static void BeginAdventure(MapFile file) { //IL_0203: Unknown result type (might be due to invalid IL or missing references) if (!MapBuilder.Ready || MapBuilder.Current != file) { throw new InvalidOperationException("the map isn't built"); } if (file.party.Length == 0 || file.enemies.Length == 0) { throw new InvalidOperationException("the map needs party and enemy spots"); } NetworkingManager instance = NetworkingManager.Instance; Root root = ((Observer<Root>)(object)instance.NetworkManager).Root; GameLogic instance2 = GameLogic.instance; PortalManager instance3 = PortalManager.Instance; HeroSpots.Clear(); SpotsTaken.Clear(); ReturnTo.Clear(); if (!MapRoom.Placed) { foreach (Character partyCharacter in instance.PartyCharacters) { if (partyCharacter != null && (Object)(object)partyCharacter.Cell != (Object)null && MapBuilder.Where(partyCharacter) == null) { ReturnTo[partyCharacter] = partyCharacter.Cell; } } } _island = instance3.CurrentIsland; _reservedSpot = -1; _movedEncounter = null; Character battleObjectCharacter = root.BattleObjectCharacter; int num; if (battleObjectCharacter != null) { (int, int)? tuple = MapBuilder.QR(battleObjectCharacter); if (tuple.HasValue) { (int, int) valueOrDefault = tuple.GetValueOrDefault(); int bq = valueOrDefault.Item1; int br = valueOrDefault.Item2; num = Array.FindIndex(file.enemies, (Spot e) => e.q == bq && e.r == br); goto IL_0156; } } num = -1; goto IL_0156; IL_0156: int num2 = num; if (battleObjectCharacter != null && !battleObjectCharacter.IsDead && num2 >= 0) { SpotsTaken.Add(battleObjectCharacter.Cell); _reservedSpot = num2; } else if (battleObjectCharacter != null && !battleObjectCharacter.IsDead) { int num3 = Mathf.Clamp(instance2.CurrentBattleObjectEnemyIndex, 0, file.enemies.Length - 1); HexCell val = Claim(file.enemies[num3].q, file.enemies[num3].r, battleObjectCharacter) ?? throw new InvalidOperationException("no free enemy spot"); _movedEncounter = battleObjectCharacter; _movedFrom = battleObjectCharacter.Cell; battleObjectCharacter.WarpToDestination(((Component)val).transform.position, false, false, false); if (MapBuilder.Where(battleObjectCharacter) == null) { throw new InvalidOperationException("the encounter's enemy didn't reach the map"); } _reservedSpot = num3; } else { _previousEvent = instance3.currentEventHex; instance3.currentEventHex = PartyCentre(file) ?? MapBuilder.Cells.First((HexCell c) => (Object)(object)c != (Object)null && c.IsValid && c.IsWalkable); _eventSwapped = true; } SetAside.Clear(); SetAsideStrays(root); Adventure = true; Armed = true; Active = true; _seenInBattle = false; _overSince = -1f; Status = "Fighting on '" + file.name + "'."; Plugin.ModLog.LogInfo((object)("MapMaker: adventure battle on '" + file.name + "' (" + file.terrain + "; " + ((battleObjectCharacter == null) ? "no enemy stood on the island" : ((num2 >= 0) ? $"{battleObjectCharacter.CharacterName} waits on enemy spot {num2}" : $"{battleObjectCharacter.CharacterName} moved to enemy spot {_reservedSpot}")) + ").")); Plugin.Run(Follow(file, skipPlacement: false), "adventure battle", quiet: true); } internal static void Abandon() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (_movedEncounter != null && (Object)(object)_movedFrom != (Object)null && MapBuilder.Where(_movedEncounter) != null) { _movedEncounter.WarpToDestination(((Component)_movedFrom).transform.position, false, false, false); } _movedEncounter = null; _movedFrom = null; AfterBattleNode(); foreach (Character item in SetAside) { if (item != null && !item.IsDead) { item.SelectedForBattle = true; } } SetAside.Clear(); ReturnTo.Clear(); Adventure = false; Armed = false; Active = false; _reservedSpot = -1; if (!MapRoom.Placed) { MapNet.RemoveEverywhere(); } } internal static void AfterBattleNode() { if (_eventSwapped) { _eventSwapped = false; if ((Object)(object)PortalManager.Instance != (Object)null) { PortalManager.Instance.currentEventHex = _previousEvent; } _previousEvent = null; } } internal static List<HexCell> ObjectCells() { MapFile current = MapBuilder.Current; HashSet<HexCell> spots = new HashSet<HexCell>(from c in current.party.Select((Spot s) => MapBuilder.Cell(s.q, s.r)).Concat(current.enemies.Select((Spot s) => MapBuilder.Cell(s.q, s.r))).Concat((current.lesserEvents ?? new Spot[0]).Select((Spot s) => MapBuilder.Cell(s.q, s.r))) where (Object)(object)c != (Object)null select c); return MapBuilder.Cells.Where((HexCell c) => (Object)(object)c != (Object)null && c.IsValid && c.IsWalkable && c.IsEmpty && !spots.Contains(c)).ToList(); } internal static HexCell PartyCentre(MapFile file) { if (file.party.Length == 0) { return null; } float q = (float)file.party.Average((Spot s) => s.q); float r = (float)file.party.Average((Spot s) => s.r); return MapBuilder.Cells.Where((HexCell c) => (Object)(object)c != (Object)null && c.IsValid && c.IsWalkable).OrderBy(delegate(HexCell c) { (int, int) value = MapBuilder.QR(c).Value; return Mathf.Abs((float)value.Item1 - q) + Mathf.Abs((float)value.Item2 - r) + Mathf.Abs((float)(value.Item1 + value.Item2) - q - r); }).FirstOrDefault(); } internal static HexCell NextEnemyHex() { MapFile current = MapBuilder.Current; if (current == null) { return null; } int num = _enemiesSpawned++; if (num == _reservedSpot) { num = _enemiesSpawned++; } if (current.enemies.Length == 0) { return null; } Spot spot = current.enemies[num % current.enemies.Length]; return Claim(spot.q, spot.r, null); } internal static HexCell HeroHex(Character hero, Vector3 pos) { //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) MapFile current = MapBuilder.Current; GameLogic instance = GameLogic.instance; if (current == null || current.party.Length == 0 || hero == null || hero.TeamIndex != 0 || HeroSpots.ContainsKey(hero)) { return null; } if ((Object)(object)instance == (Object)null || instance.CurrentlyPlacingCharacters || instance.GameStarted) { return null; } if (!MapBuilder.Cells.Any(delegate(HexCell c) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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) if ((Object)(object)c != (Object)null) { Vector3 val2 = ((Component)c).transform.position - pos; return ((Vector3)(ref val2)).sqrMagnitude < 0.01f; } return false; })) { return null; } Spot spot = current.party[Mathf.Min(HeroSpots.Count, current.party.Length - 1)]; return HeroSpots[hero] = Claim(spot.q, spot.r, hero); } private static HexCell Claim(int q, int r, Character who) { HexCell val = MapBuilder.Cell(q, r); if (!Free(val)) { val = MapBuilder.Cells.Where(Free).OrderBy(delegate(HexCell c) { (int, int) value = MapBuilder.QR(c).Value; return MapBuilder.Distance(value.Item1, value.Item2, q, r); }).FirstOrDefault(); } if ((Object)(object)val != (Object)null) { SpotsTaken.Add(val); } return val; bool Free(HexCell c) { if ((Object)(object)c != (Object)null && c.IsValid && c.IsWalkable && !SpotsTaken.Contains(c)) { if (c.Player != null) { return c.Player == who; } return true; } return false; } } private static List<string> PlaceSpawns(Root root, MapFile map, bool party) { //IL_0219: 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) List<Character> source = root.CharactersInBattle.Where((Character c) => c != null && !c.IsDead && IsFighter(c) && MapBuilder.Where(c) != null).ToList(); List<Character> who = source.Where((Character c) => c.TeamIndex == 0).ToList(); List<Character> who2 = source.Where((Character c) => c.TeamIndex != 0).ToList(); List<(Character, HexCell)> list = new List<(Character, HexCell)>(); HashSet<HexCell> taken = new HashSet<HexCell>(); List<(int, int)> spots = map.party.Select((Spot s) => (q: s.q, r: s.r)).ToList(); List<(int, int)> spots2 = map.enemies.Select((Spot s) => (q: s.q, r: s.r)).ToList(); KeepOnSpots(who, spots, taken); KeepOnSpots(who2, spots2, taken); if (party) { Assign(who, spots, list, taken); } Assign(who2, spots2, list, taken); List<string> list2 = new List<string>(); foreach (var item in list) { var (val, to) = item; if (to.Player != null && to.Player != val && list.All<(Character, HexCell)>(((Character who, HexCell to) m) => m.who != to.Player)) { HexCell val2 = ((IEnumerable<HexCell>)MapBuilder.Cells).FirstOrDefault((Func<HexCell, bool>)((HexCell c) => (Object)(object)c != (Object)null && c.IsValid && c.IsWalkable && c.IsEmpty && !taken.Contains(c))); if ((Object)(object)val2 != (Object)null) { taken.Add(val2); to.Player.WarpToDestination(((Component)val2).transform.position, false, false, false); } } val.WarpToDestination(((Component)to).transform.position, false, false, false); list2.Add($"{val.CharacterName} (team {val.TeamIndex}) at {MapBuilder.Where(to)}"); } return list2; } private static void KeepOnSpots(List<Character> who, List<(int q, int r)> spots, HashSet<HexCell> taken) { foreach (Character item in who.ToList()) { (int, int)? tuple = MapBuilder.QR(item); if (!tuple.HasValue) { continue; } var (q, r) = tuple.GetValueOrDefault(); if (spots.Any(((int q, int r) s) => s.q == q && s.r == r)) { who.Remove(item); spots.RemoveAll(((int q, int r) s) => s.q == q && s.r == r); taken.Add(item.Cell); } } } private static void Assign(List<Character> who, List<(int q, int r)> spots, List<(Character, HexCell)> moves, HashSet<HexCell> taken) { List<Character> list = who.ToList(); foreach (var spot in spots) { HexCell val = MapBuilder.Cell(spot.q, spot.r); if (!((Object)(object)val == (Object)null) && val.IsValid && val.IsWalkable && !taken.Contains(val) && list.Count != 0) { Character val2 = list[0]; list.Remove(val2); taken.Add(val); moves.Add((val2, val)); } } if (list.Count == 0 || spots.Count == 0) { return; } foreach (Character c in list) { HexCell val3 = (from x in MapBuilder.Cells where (Object)(object)x != (Object)null && x.IsValid && x.IsWalkable && !taken.Contains(x) && (x.IsEmpty || x.Player == c) orderby spots.Min(delegate((int q, int r) s) { (int, int) value = MapBuilder.QR(x).Value; return MapBuilder.Distance(value.Item1, value.Item2, s.q, s.r); }) select x).FirstOrDefault(); if ((Object)(object)val3 == (Object)null) { break; } taken.Add(val3); moves.Add((c, val3)); } } private static void SetAsideStrays(Root root) { foreach (Character item in root.CharactersInBattle.ToList()) { if (item != null && item.TeamIndex != 0 && !item.IsDead && IsFighter(item) && MapBuilder.Where(item) == null) { item.SelectedForBattle = false; if (!SetAside.Contains(item)) { SetAside.Add(item); } } } } internal static void Tick() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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) //IL_004f: Invalid comparison between Unknown and I4 //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Invalid comparison between Unknown and I4 if (!Active) { return; } PortalManager instance = PortalManager.Instance; Island val = ((instance != null) ? instance.CurrentIsland : null); if ((Object)(object)val == (Object)null || val != _island) { Plugin.ModLog.LogInfo((object)"MapMaker: the island changed during a map battle; the map is gone with it."); Finish(warp: false); return; } GUIState currentGuiState = GUIManager.instance.CurrentGuiState; if ((int)currentGuiState == 2) { _seenInBattle = true; _overSince = -1f; } else if (_seenInBattle && !Armed) { bool flag = PostBattleManager.IsNotNullAndIsActive || ((Object)(object)BattleFailureWindow.instance != (Object)null && (Object)(object)BattleFailureWindow.instance.Content != (Object)null && BattleFailureWindow.instance.Content.activeInHierarchy); if ((int)currentGuiState != 3 || flag) { _overSince = -1f; } else if (_overSince < 0f) { _overSince = Time.realtimeSinceStartup; } else if (!(Time.realtimeSinceStartup - _overSince < 1f)) { Finish(); } } } public static string Finish(bool warp = true) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) List<string> list = new List<string>(); if (warp) { HashSet<HexCell> hashSet = new HashSet<HexCell>(); foreach (KeyValuePair<Character, HexCell> item in ReturnTo) { Character key = item.Key; if (key == null || MapBuilder.Where(key) == null) { continue; } HexCell val = item.Value; if (!((Object)(object)val == (Object)null)) { if ((val.Player != null && val.Player != key) || hashSet.Contains(val)) { val = val.ValidEmptyNeighbor ?? val; } hashSet.Add(val); key.WarpToDestination(((Component)val).transform.position, false, false, false); list.Add(key.CharacterName); } } } foreach (Character item2 in SetAside) { if (item2 != null && !item2.IsDead) { item2.SelectedForBattle = true; } } NetworkingManager instance = NetworkingManager.Instance; Root val2 = ((instance == null) ? null : ((Observer<Root>)(object)instance.NetworkManager)?.Root); if (val2 != null && _battleObject != null && val2.BattleObjectCharacter == null) { val2.BattleObjectCharacter = _battleObject; } SetAside.Clear(); ReturnTo.Clear(); _battleObject = null; _movedEncounter = null; _movedFrom = null; _reservedSpot = -1; AfterBattleNode(); Adventure = false; Active = false; Armed = false; if (!MapRoom.Placed) { MapNet.RemoveEverywhere(warp); if (warp) { CameraController instance2 = CameraController.instance; if (instance2 != null) { instance2.SnapToCurrentlySelectedCharacter(); } } } Status = ((list.Count > 0) ? ("Back on the island: " + string.Join(", ", list) + ".") : "Map battle over."); Plugin.ModLog.LogInfo((object)("MapMaker: " + Status)); return Status; } private static bool IsFighter(Character c) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 return (int)c.CharacterType == 0; } public static List<CharacterInfo> RollEnemies(MapFile file, bool hard = false) { //IL_0028: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) GlobalSettings globalSettings = GlobalSettingsManager.instance.globalSettings; Game instance = Game.Instance; TerrainType result; TerrainType val = (Enum.TryParse<TerrainType>(file.terrain, out result) ? result : instance.CurrentRoomTerrainType); int currentActiveGameLevel = instance.CurrentActiveGameLevel; List<EnemyGroup> possibleEnemyGroups = globalSettings.GetPossibleEnemyGroups(val, instance.CurrentRoomTimeOfDay, currentActiveGameLevel); if (possibleEnemyGroups == null || possibleEnemyGroups.Count == 0) { throw new InvalidOperationException($"no enemy factions for {val}"); } int generatedBattlePointTotal = globalSettings.GeneratedBattlePointTotal; int num = (int)((float)(generatedBattlePointTotal + (hard ? globalSettings.HardBattlePointAdder : 0)) + (float)(generatedBattlePointTotal * GameLogic.instance.CurrentDifficulty.AdditionalBattlePointsPerc) / 100f) + Random.Range(-globalSettings.GeneratedBattlePointVariance, globalSettings.GeneratedBattlePointVariance + 1) + Math.Max(0, NetworkingManager.Instance.PartyCharacters.Count - 1) * globalSettings.AdditionalBattlePointsPerPlayer; List<EnemyGroup> list = possibleEnemyGroups.OrderBy((EnemyGroup _) => Random.value).ToList(); bool flag = list.Count > 1 && Random.value < globalSettings.MixedEnemyGroupBattleChance / 100f; List<CharacterInfo> list2 = new List<CharacterInfo>(); foreach (EnemyGroup item in list.Take((!flag) ? 1 : 2)) { list2.AddRange(GameLogic.GetEnemiesByGroupAndPoints(new List<EnemyGroup> { item }, (float)(flag ? (num / 2) : num), currentActiveGameLevel)); } if (list2.Count == 0) { throw new InvalidOperationException($"no enemies drawn for {val} at level {currentActiveGameLevel}"); } Plugin.ModLog.LogInfo((object)(string.Format("MapMaker: test fight: {0} island fight of {1}, {2}, ", hard ? "a hard" : "an", val, string.Join(" + ", list.Take((!flag) ? 1 : 2))) + string.Format("{0} points: {1} enemies on {2} spots ({3})", num, list2.Count, file.enemies.Length, string.Join(", ", list2.Select((CharacterInfo e) => ((Object)e).name))))); return list2; } public static List<string> Who() { NetworkingManager instance = NetworkingManager.Instance; Root val = ((instance == null) ? null : ((Observer<Root>)(object)instance.NetworkManager)?.Root); if (val == null) { return new List<string>(); } return (from c in (IEnumerable<Character>)val.AllCharacters where c != null && MapBuilder.Where(c) != null select string.Format("{0} team {1} at {2}{3}", c.CharacterName, c.TeamIndex, MapBuilder.Where(c), c.IsDead ? " (dead)" : "")).ToList(); } internal static IEnumerator Quietly(IEnumerator setup) { HeroSpots.Clear(); SpotsTaken.Clear(); _enemiesSpawned = 0; QuietSetup = true; try { while (setup.MoveNext()) { yield return setup.Current; } } finally { QuietSetup = false; } } } [HarmonyPatch(typeof(GameLogic), "StartCurrentBattle")] internal static class MapStartBattlePatch { private static readonly FieldRef<GameLogic, Coroutine> SetupCoroutine = AccessTools.FieldRefAccess<GameLogic, Coroutine>("setupGameCoroutine"); private static bool Prefix(GameLogic __instance) { if ((!MapBattle.Armed && !MapBattle.Active) || !MapBuilder.Ready) { return true; } MapBattle.Armed = false; List<HexCell> list = MapBuilder.Cells.Where((HexCell c) => (Object)(object)c != (Object)null && c.IsValid && c.IsWalkable).ToList(); if (list.Count == 0) { Plugin.ModLog.LogError((object)"MapMaker: no walkable map hex; the battle runs on the island instead."); return true; } SetupCoroutine.Invoke(__instance) = ((MonoBehaviour)__instance).StartCoroutine(MapBattle.Quietly(__instance.SetupGame(__instance.CurrentBattle, list))); return false; } } [HarmonyPatch(typeof(GameLogic), "GetSpawnPoint")] internal static class MapEnemySpotPatch { private static void Postfix(ref HexCell __result) { if (MapBattle.QuietSetup && MapBuilder.Ready) { __result = MapBattle.NextEnemyHex() ?? __result; } } } [HarmonyPatch(typeof(Character), "WarpToDestination")] internal static class MapHeroSpotPatch { private static void Prefix(Character __instance, ref Vector3 pos) { //IL_0011: 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) if (MapBattle.QuietSetup && MapBuilder.Ready) { HexCell val = MapBattle.HeroHex(__instance, pos); if ((Object)(object)val != (Object)null) { pos = ((Component)val).transform.position; } } } } [HarmonyPatch(typeof(Root), "StartSpawnPlacementForAll")] internal static class MapPlacementOriginPatch { private static void Prefix(Root __instance) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (MapBattle.Active && MapBuilder.Ready) { HexCell val = MapBattle.PartyCentre(MapBuilder.Current); if ((Object)(object)val != (Object)null) { __instance.SpawnPlacementOrigin = ((Component)val).transform.position; } } } } [HarmonyPatch] internal static class MapNoRandomObjectsPatch { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(GameLogic), "SpawnShrines", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(GameLogic), "SpawnDestructables", (Type[])null, (Type[])null); } private static bool Prefix(ref IEnumerator __result, ref List<HexCell> possibleSpawns) { if (!MapBattle.QuietSetup) { return true; } if (MapBattle.Adventure && MapBuilder.Ready) { possibleSpawns = MapBattle.ObjectCells(); return true; } __result = Enumerable.Empty<object>().GetEnumerator(); return false; } } public static class MapBuilder { private sealed class HexView { public HexEntry Entry; public HexCell Cell; public GameObject Side; public float Height; } private sealed class PropView { public PropEntry Entry; public GameObject Go; } private const float Margin = 40f; private const float DefaultDepth = 1.2f; public static readonly List<HexCell> Cells = new List<HexCell>(); private static readonly Dictionary<long, HexView> Views = new Dictionary<long, HexView>(); private static readonly List<PropView> PropViews = new List<PropView>(); private static HexCoordinates _origin; private static HexCell _anchor; private static Vector3 _anchorPos; private static HexCalculator _calc; private static PropCatalog.Terrain _terrain; private static Material _defaultTile; private static GameObject _decor; private static GameObject _staging; private static float _bottom; private static float _lift; private const float BlockedShade = 0.45f; private static readonly Dictionary<Material, Material> _blocked = new Dictionary<Material, Material>(); private static readonly string[] OverlayObjects = new string[3] { "overlay", "overlayBorderObj", "_AreaIndicator" }; private static readonly string[] OverlayRefs = new string[5] { "overlayHighlight", "overlayBorderHighlight", "overlayBorderObjMaterial", "_AreaIndicatorRenderer", "overlayLight" }; private const float CarryLift = 0.35f; private static GameObject _carried; private const float TrunkWidth = 1.4f; private const float WideBlocker = 2.2f; private static readonly string[] Plants = new string[4] { "Tree", "Bush", "Hedge", "Plant" }; public static MapFile Current { get; private set; } public static HexCellManager Grid { get; private set; } public static (int x, int y) Anchor { get { if (!((Object)(object)_anchor != (Object)null)) { return (x: 0, y: 0); } return (x: ((HexCoordinates)(ref _anchor.Coordinates)).X, y: ((HexCoordinates)(ref _anchor.Coordinates)).Y); } } public static (int x, int y) Origin => (x: ((HexCoordinates)(ref _origin)).X, y: ((HexCoordinates)(ref _origin)).Y); internal static GameObject Decor => _decor; internal static float Lift => _lift; public static bool Ready { get { if ((Object)(object)Grid != (Object)null && Cells.Count > 0) { return (Object)(object)Cells[0] != (Object)null; } return false; } } public static string MapsFolder => Path.Combine(Plugin.Folder, "maps"); internal static Material DefaultTile => _defaultTile; public static List<string> Maps() { if (!Directory.Exists(MapsFolder)) { return new List<string>(); } return (from n in Directory.GetFiles(MapsFolder, "*.json").Select(Path.GetFileNameWithoutExtension) orderby n select n).ToList(); } public static string PathOf(string map) { if (!File.Exists(map)) { return Path.Combine(MapsFolder, map + ".json"); } return map; } public static string Build(string map) { string path = PathOf(map); if (!File.Exists(path)) { throw new FileNotFoundException("no map '" + map + "' (maps: " + string.Join(", ", Maps()) + ")"); } return Build(MapFile.Load(path)); } public static HexCellManager GridHere() { Island val = (((Object)(object)PortalManager.Instance != (Object)null) ? PortalManager.Instance.CurrentIsland : null); if (!((Object)(object)val != (Object)null)) { return HexCellManager.instance; } return val.HexCellManager; } public static string Build(MapFile file, (int x, int y)? anchor = null, (int x, int y)? origin = null, float lift = 0f, bool room = false) { //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Expected O, but got Unknown //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Expected O, but got Unknown //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0566: Unknown result type (might be due to invalid IL or missing references) Island val = (((Object)(object)PortalManager.Instance != (Object)null) ? PortalManager.Instance.CurrentIsland : null); HexCellManager val2 = GridHere(); if ((Object)(object)val2 == (Object)null) { throw new InvalidOperationException("no hex grid: a map hangs off the town's or a quest island's grid"); } if (!room && MapRoom.Placed) { throw new InvalidOperationException(MapRoom.Busy); } Discard(); PropCatalog.Terrain terrain = PropCatalog.Of(file); Dictionary<(int, int), HexEntry> dictionary = file.Layout(); if (dictionary.Count == 0) { throw new InvalidOperationException("map '" + file.name + "' has no hexes"); } HexCell anchor2; if (anchor.HasValue) { (int, int) valueOrDefault = anchor.GetValueOrDefault(); int ax = valueOrDefault.Item1; int ay = valueOrDefault.Item2; anchor2 = ((IEnumerable<HexCell>)val2.FastCells).FirstOrDefault((Func<HexCell, bool>)((HexCell c) => (Object)(object)c != (Object)null && ((HexCoordinates)(ref c.Coordinates)).X == ax && ((HexCoordinates)(ref c.Coordinates)).Y == ay)); } else { anchor2 = PickAnchor(val2); } _anchor = anchor2; if ((Object)(object)_anchor == (Object)null) { throw new InvalidOperationException(anchor.HasValue ? $"no island hex at {anchor} to copy (is everyone on the same island?)" : "no flat walkable hex here to copy"); } _calc = ((HexGrid)AccessTools.Field(typeof(HexCellManager), "hexGrid").GetValue(val2)).HexCalculator; _anchorPos = _calc.HexToPosition(_anchor.Coordinates); _lift = lift; _terrain = terrain; object obj = TileMaterial(file.tile); if (obj == null) { MeshRenderer component = ((Component)_anchor).GetComponent<MeshRenderer>(); obj = ((component != null) ? ((Renderer)component).sharedMaterial : null) ?? TileMaterial((from kv in PropCatalog.For(file.terrain).TileUse orderby kv.Value descending select kv.Key).FirstOrDefault()); } _defaultTile = (Material)obj; if (origin.HasValue) { (int x, int y) valueOrDefault2 = origin.GetValueOrDefault(); int item = valueOrDefault2.x; int item2 = valueOrDefault2.y; _origin = new HexCoordinates(item, item2, 0f); } else { int num = dictionary.Keys.Max<(int, int)>(((int q, int r) k) => Distance(k.q, k.r, 0, 0)); Vector3 val3 = _calc.HexToPosition(new HexCoordinates(((HexCoordinates)(ref _anchor.Coordinates)).X + 1, ((HexCoordinates)(ref _anchor.Coordinates)).Y, 0f)) - _anchorPos; val3.y = 0f; float num2 = 0f; foreach (HexCell item3 in ((val != null) ? val.AllHexes : null) ?? val2.FastCells) { if ((Object)(object)item3 != (Object)null) { num2 = Mathf.Max(num2, Vector3.Dot(((Component)item3).transform.position - ((Component)_anchor).transform.position, ((Vector3)(ref val3)).normalized)); } } int num3 = Mathf.CeilToInt((num2 + 40f) / ((Vector3)(ref val3)).magnitude) + num; _origin = new HexCoordinates(((HexCoordinates)(ref _anchor.Coordinates)).X + num3, ((HexCoordinates)(ref _anchor.Coordinates)).Y, 0f); } _decor = new GameObject("MapMaker " + file.name); _decor.transform.SetParent(((Component)val2).transform, false); _staging = new GameObject("staging"); _staging.SetActive(false); _staging.transform.SetParent(_decor.transform, false); Grid = val2; Current = file; _bottom = Bottom(dictionary.Values); foreach (HexEntry value in dictionary.Values) { MakeHex(value); } val2.AddCells(Cells); foreach (HexCell cell in Cells) { SetHeight(cell); } val2.SetCameraBounds(); int num4 = 0; List<string> list = new List<string>(); PropEntry[] props = file.props; for (int num5 = 0; num5 < props.Length; num5++) { if ((Object)(object)AddProp(props[num5], out var why) != (Object)null) { num4++; } else { list.Add(why); } } if (list.Count > 0) { Plugin.ModLog.LogWarning((object)("MapMaker: '" + file.name + "': not placed: " + string.Join(", ", list))); } string text = $"'{file.name}' ({file.terrain}): {Cells.Count} hexes ({Cells.Count((HexCell c) => !c.IsWalkable)} impassable), " + $"{num4}/{file.props.Length} props, centre {WorldOf(0, 0, 0f)}"; Plugin.ModLog.LogInfo((object)("MapMaker: built " + text)); string text2 = file.CutOffNote(); if (text2 != "") { Plugin.ModLog.LogWarning((object)("MapMaker: '" + file.name + "': " + text2)); } return text; } internal static HexCell PickAnchor(HexCellManager grid) { IEnumerable<HexCell> source = grid.FastCells.Where((HexCell c) => (Object)(object)c != (Object)null && c.IsValid && c.IsWalkable && ((Behaviour)c).enabled && Mathf.Abs(((Component)c).transform.localPosition.z) < 0.01f); return source.FirstOrDefault((Func<HexCell, bool>)Bare) ?? source.FirstOrDefault(); } private static bool Bare(HexCell c) { if (c.isEvent || (Object)(object)c.eventObj != (Object)null || (Object)(object)((Component)c).GetComponent<NavigationHex>() != (Object)null) { return false; } for (int i = 0; i < ((Component)c).transform.childCount; i++) { if (((Object)((Component)c).transform.GetChild(i)).name.EndsWith("(Clone)")) { return false; } } return true; } internal static List<(Transform t, Vector3 at)> Parts() { return (from t in (from v in Views.Values where (Object)(object)v.Cell != (Object)null select ((Component)v.Cell).transform).Append(_decor.transform) select (t: t, position: t.position)).ToList(); } private static IEnumerator Glide(List<(Transform t, Vector3 at)> parts, Func<bool> still, Action done) { WorldMapGenerator instance = WorldMapGenerator.instance; float speed = (((Object)(object)instance != (Object)null && instance.riseSpeed > 0f) ? instance.riseSpeed : 4f); float snap = (((Object)(object)instance != (Object)null && instance.riseSnapDistance > 0f) ? instance.riseSnapDistance : 0.005f); while (still()) { bool flag = false; foreach (var (val, val2) in parts) { if (!((Object)(object)val == (Object)null)) { Vector3 val3 = Vector3.Lerp(val.position, val2, Time.deltaTime * speed); Vector3 val4 = val3 - val2; if (((Vector3)(ref val4)).sqrMagnitude <= snap * snap) { val3 = val2; } else { flag = true; } val.position = val3; } } if (!flag) { break; } yield return null; } done(); } public static void Remove(bool sink = false) { if (MapRoom.Placed) { Plugin.ModLog.LogWarning((object)("MapMaker: not removed: " + MapRoom.Busy)); } else { Discard(sink); } } internal static void Discard(bool sink = false) { MapRoom.Forget(); if (sink && (Object)(object)Grid != (Object)null && (Object)(object)_decor != (Object)null) { foreach (HexCell cell in Cells) { Unregister(cell); } List<(Transform, Vector3)> list = Parts(); foreach (var item2 in list) { Collider[] componentsInChildren = ((Component)item2.Item1).GetComponentsInChildren<Collider>(); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } } WorldMapGenerator instance = WorldMapGenerator.instance; float drop = (((Object)(object)instance != (Object)null && instance.fallDropY > 0f) ? instance.fallDropY : 30f); List<(Transform t, Vector3)> down = list.Select<(Transform, Vector3), (Transform, Vector3)>(((Transform t, Vector3 at) p) => (t: p.t, p.at + Vector3.down * drop)).ToList(); Plugin.Run(Glide(down, () => true, delegate { foreach (var item3 in down) { Transform item = item3.t; if ((Object)(object)item != (Object)null) { Object.Destroy((Object)(object)((Component)item).gameObject); } } }), "map sink", quiet: true); } else { if ((Object)(object)Grid != (Object)null) { foreach (HexCell cell2 in Cells) { Unregister(cell2); } foreach (HexView value in Views.Values) { if ((Object)(object)value.Cell != (Object)null) { Object.Destroy((Object)(object)((Component)value.Cell).gameObject); } } } if ((Object)(object)_decor != (Object)null) { Object.Destroy((Object)(object)_decor); } } Reset(); } internal static GameObject Detach() { GameObject decor = _decor; Reset(); return decor; } private static void Reset() { _decor = null; Cells.Clear(); Views.Clear(); PropViews.Clear(); _carried = null; Grid = null; Current = null; _anchor = null; _lift = 0f; } public static HexCell SetHex(HexEntry h) { //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) if (!Ready) { throw new InvalidOperationException("no map built"); } h.height = Mathf.Clamp(h.height, -0.9f, 4f); float num = Bottom((from v in Views.Values select v.Entry into e where e.q != h.q || e.r != h.r select e).Append(h)); if (Views.TryGetValue(Key(h.q, h.r), out var value)) { float num2 = h.height - value.Height; value.Entry = h; if (Mathf.Abs(num2) > 0.0001f) { foreach (PropView item in PropViews.Where((PropView p) => p.Entry.q == h.q && p.Entry.r == h.r && (Object)(object)p.Go != (Object)null)) { Transform transform = item.Go.transform; transform.position += Vector3.up * num2; } } Apply(value); } else { value = MakeHex(h); Grid.AddCells(new List<HexCell> { value.Cell }); Grid.SetCameraBounds(); } SetHeight(value.Cell); if (Mathf.Abs(num - _bottom) > 0.0001f) { _bottom = num; foreach (HexView value2 in Views.Values) { Side(value2); } } return value.Cell; } public static bool RemoveHex(int q, int r) { if (!Views.TryGetValue(Key(q, r), out var value)) { return false; } foreach (PropView item in PropViews.Where((PropView p) => p.Entry.q == q && p.Entry.r == r).ToList()) { RemoveProp(item.Entry); } Unregister(value.Cell); Cells.Remove(value.Cell); Views.Remove(Key(q, r)); if ((Object)(object)value.Cell != (Object)null) { Object.Destroy((Object)(object)((Component)value.Cell).gameObject); } if ((Object)(object)value.Side != (Object)null) { Object.Destroy((Object)(object)value.Side); } return true; } public static HexEntry HexAt(int q, int r) { if (!Views.TryGetValue(Key(q, r), out var value)) { return null; } return value.Entry; } private static HexView MakeHex(HexEntry h) { //IL_0094: 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) h.height = Mathf.Clamp(h.height, -0.9f, 4f); GameObject obj = Object.Instantiate<GameObject>(((Component)_anchor).gameObject, ((Component)Grid).transform); StripRuntimeAdditions(obj); ((Object)obj).name = $"Map Hex {h.q},{h.r}"; EnsureVisible(obj); HexCell component = obj.GetComponent<HexCell>(); component.Coordinates = new HexCoordinates(((HexCoordinates)(ref _origin)).X + h.q, ((HexCoordinates)(ref _origin)).Y + h.r, 0f); component.isEventHexNeighbor = (component.isEvent = (component.isJob = (component.eventCompleted = false))); component.spawnPointTeam1 = (component.spawnPointTeam2 = (component.shrineSpawn = false)); component.eventObj = null; StripRuntimeOverlays(component); HexView hexView = new HexView { Entry = h, Cell = component }; Views[Key(h.q, h.r)] = hexView; Cells.Add(component); Apply(hexView); return hexView; } private static void EnsureVisible(GameObject go) { if (!((Object)(object)go.GetComponent<MeshRenderer>() != (Object)null)) { MeshCollider component = go.GetComponent<MeshCollider>(); Mesh val = ((component != null) ? component.sharedMesh : null); if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("the hexes here have no mesh to copy"); } if ((Object)(object)go.GetComponent<MeshFilter>() == (Object)null) { go.AddComponent<MeshFilter>().sharedMesh = val; } go.AddComponent<MeshRenderer>(); } } private static void Apply(HexView view) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) HexEntry entry = view.Entry; HexCell cell = view.Cell; GameObject gameObject = ((Component)cell).gameObject; gameObject.transform.position = WorldOf(entry.q, entry.r, entry.height); view.Height = entry.height; Material val = TileMaterial(entry.tile) ?? _defaultTile; ((Renderer)gameObject.GetComponent<MeshRenderer>()).sharedMaterial = (entry.Impassable ? Blocked(val) : val); cell.islandHexType = (IslandHexType)(entry.Impassable ? 1 : 0); ((Behaviour)cell).enabled = true; gameObject.SetActive(true); cell.ProcessWalkable(); Side(view); } private static Material Blocked(Material tile) { //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_0042: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_008a: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tile == (Object)null) { return null; } if (_blocked.TryGetValue(tile, out var value) && (Object)(object)value != (Object)null) { return value; } value = new Material(tile) { name = ((Object)tile).name + " (impassable)" }; string[] array = new string[3] { "_Color", "_BaseColor", "_Tint" }; foreach (string text in array) { if (value.HasProperty(text)) { Color color = value.GetColor(text); value.SetColor(text, new Color(color.r * 0.45f, color.g * 0.45f, color.b * 0.45f, color.a)); } } _blocked[tile] = value; return value; } private static void SetHeight(HexCell cell) { //IL_0002: 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) cell.Coordinates = HexUtility.SetHeightValue(cell.Coordinates, Grid); } private static void StripRuntimeAdditions(GameObject go) { Component[] components = go.GetComponents<Component>(); foreach (Component val in components) { if (val is NavigationHex || val is EventClicker) { Object.DestroyImmediate((Object)(object)val); } } for (int num = go.transform.childCount - 1; num >= 0; num--) { Transform child = go.transform.GetChild(num); if (((Object)child).name.EndsWith("(Clone)") || (Object)(object)((Component)child).GetComponentInChildren<EventClicker>(true) != (Object)null) { Object.DestroyImmediate((Object)(object)((Component)child).gameObject); } } } private static void StripRuntimeOverlays(HexCell cell) { string[] overlayObjects = OverlayObjects; foreach (string text in overlayObjects) { FieldInfo fieldInfo = AccessTools.Field(typeof(HexCell), text); if (!(fieldInfo == null)) { object? value = fieldInfo.GetValue(cell); GameObject val = (GameObject)((value is GameObject) ? value : null); if (val != null && (Object)(object)val != (Object)null && val.transform.IsChildOf(((Component)cell).transform)) { Object.DestroyImmediate((Object)(object)val); } fieldInfo.SetValue(cell, null); } } overlayObjects = OverlayRefs; foreach (string text2 in overlayObjects) { FieldInfo fieldInfo2 = AccessTools.Field(typeof(HexCell), text2); if (!(fieldInfo2 == null)) { object? value2 = fieldInfo2.GetValue(cell); Component val2 = (Component)((value2 is Component) ? value2 : null); if (val2 == null || !((Object)(object)val2 != (Object)null) || !val2.transform.IsChildOf(((Component)cell).transform)) { fieldInfo2.SetValue(cell, null); } } } AccessTools.Field(typeof(HexCell), "overlayMarkersSet")?.SetValue(cell, false); } internal static void Unregister(HexCell c) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)c == (Object)null) && !((Object)(object)Grid == (Object)null)) { ((HexContainer<HexCell>)AccessTools.Field(typeof(HexCellManager), "cells").GetValue(Grid))?.Remove(c.Coordinates); Grid.FastCells.Remove(c); } } private static float Bottom(IEnumerable<HexEntry> hexes) { float num = Mathf.Min(0f, hexes.Select((HexEntry e) => e.height).DefaultIfEmpty(0f).Min()); MapFile current = Current; return num - ((current != null && current.depth > 0f) ? Current.depth : 1.2f); } private static Material TileMaterial(string name) { if (string.IsNullOrEmpty(name) || _terrain == null) { return null; } if (_terrain.Tiles.TryGetValue(name, out var value)) { return value; } Plugin.ModLog.LogWarning((object)("MapMaker: no tile material '" + name + "' in " + Where(_terrain))); return null; } private static string Where(PropCatalog.Terrain t) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (t != null) { if (!t.Mixed) { return $"{t.Type}'s rooms"; } return "any terrain's rooms"; } return "no terrain"; } private static void Side(HexView view) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017d: 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_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)view.Side != (Object)null) { Object.Destroy((Object)(object)view.Side); } GameObject gameObject = ((Component)view.Cell).gameObject; GameObject val = new GameObject("Map Hex Side"); val.transform.SetParent(_decor.transform, false); val.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity); GameObject val2 = new GameObject("tile"); val2.transform.SetParent(val.transform, false); val2.transform.SetPositionAndRotation(gameObject.transform.position, gameObject.transform.rotation); val2.transform.localScale = gameObject.transform.localScale; val2.AddComponent<MeshFilter>().sharedMesh = gameObject.GetComponent<MeshFilter>().sharedMesh; ((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterials = ((Renderer)gameObject.GetComponent<MeshRenderer>()).sharedMaterials; Bounds val3 = Bounds(val2); Transform transform = val2.transform; transform.position -= new Vector3(((Bounds)(ref val3)).center.x, ((Bounds)(ref val3)).max.y, ((Bounds)(ref val3)).center.z); float num = ((Bounds)(ref val3)).max.y - (((Component)_anchor).transform.position.y + _lift + _bottom); val.transform.position = new Vector3(((Bounds)(ref val3)).center.x, ((Bounds)(ref val3)).max.y - 0.005f, ((Bounds)(ref val3)).center.z); val.transform.localScale = new Vector3(1f, Mathf.Max(num, ((Bounds)(ref val3)).size.y) / Mathf.Max(((Bounds)(ref val3)).size.y, 0.01f), 1f); view.Side = val; } public static GameObject AddProp(PropEntry p, out string why) { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) why = null; PropCatalog.Prop prop = PropCatalog.Find(_terrain, p.name); if (prop == null) { why = p.name + " (not in " + Where(_terrain) + ")"; return null; } if (!Views.TryGetValue(Key(p.q, p.r), out var value)) { why = $"{p.name}@{p.q},{p.r} (no hex)"; return null; } float num = ((p.scale > 0f) ? p.scale : 1f); Quaternion val = Quaternion.AngleAxis(p.rot, Vector3.up); GameObject val2 = Copy(prop, ((Component)value.Cell).transform.position - val * prop.Offset * num + new Vector3(p.dx, 0f, p.dz), val * prop.Source.transform.rotation, prop.Source.transform.lossyScale * num, ((Component)value.Cell).transform.position.y); PropViews.Add(new PropView { Entry = p, Go = val2 }); return val2; } public static bool RemoveProp(PropEntry p) { PropView propView = PropViews.FirstOrDefault((PropView v) => v.Entry == p); if (propView == null) { return false; } if ((Object)(object)propView.Go != (Object)null) { Object.Destroy((Object)(object)propView.Go); } PropViews.Remove(propView); return true; } public static bool Carry(PropEntry p, int q, int r, out string why) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0091: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_00f6: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0166: 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) why = null; if (!Ready) { why = "no map built"; return false; } PropCatalog.Prop prop = PropCatalog.Find(_terrain, p.name); if (prop == null) { why = p.name + " (not in " + Where(_terrain) + ")"; return false; } float num = ((p.scale > 0f) ? p.scale : 1f); Quaternion val = Quaternion.AngleAxis(p.rot, Vector3.up); float num2 = HexAt(q, r)?.height ?? 0f; Vector3 val2 = WorldOf(q, r, num2) - val * prop.Offset * num + new Vector3(p.dx, 0.35f, p.dz); if ((Object)(object)_carried == (Object)null || ((Object)_carried).name != prop.Key) { Drop(); _carried = Copy(prop, val2, val * prop.Source.transform.rotation, prop.Source.transform.lossyScale * num, num2); Collider[] componentsInChildren = _carried.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } } else { _carried.transform.SetPositionAndRotation(val2, val * prop.Source.transform.rotation); } return true; } public static void Drop() { if ((Object)(object)_carried != (Object)null) { Object.Destroy((Object)(object)_carried); } _carried = null; } private static GameObject Copy(PropCatalog.Prop prop, Vector3 position, Quaternion rotation, Vector3 scale, float ground) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0166: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(prop.Source, position, rotation, _staging.transform); ((Object)val).name = prop.Key; val.transform.localScale = scale; MaterialsByQualityObject[] componentsInChildren = val.GetComponentsInChildren<MaterialsByQualityObject>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } bool flag = Plants.Any((string word) => prop.Key.IndexOf(word, StringComparison.OrdinalIgnoreCase) >= 0); LOSBlocker[] componentsInChildren2 = val.GetComponentsInChildren<LOSBlocker>(true); foreach (LOSBlocker val2 in componentsInChildren2) { List<Bounds> list = new List<Bounds>(); MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) { list.Add(component.sharedMesh.bounds); } Collider[] components = ((Component)val2).GetComponents<Collider>(); if (components.Length != 0) { if (!flag) { continue; } bool flag2 = false; Collider[] array = components; foreach (Collider val3 in array) { if (Shape(val3, out var shape)) { list.Add(shape); if (Wide(((Component)val2).transform, shape)) { val3.enabled = false; flag2 = true; } } } if (!flag2) { continue; } } if (list.Count == 0) { continue; } Bounds val4 = list[0]; foreach (Bounds item in list) { ((Bounds)(ref val4)).Encapsulate(item); } BoxCollider val5 = ((Component)val2).gameObject.AddComponent<BoxCollider>(); val5.center = ((Bounds)(ref val4)).center; val5.size = ((Bounds)(ref val4)).size; if (flag) { Trunk(val5, ground); } } val.SetActive(true); val.transform.SetParent(_decor.transform, true); return val; } private static int Vertical(Transform t) { //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_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_0017: 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_004b: 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_002f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = t.InverseTransformDirection(Vector3.up); if (!(Mathf.Abs(val.x) > Mathf.Abs(val.y))) { if (!(Mathf.Abs(val.y) > Mathf.Abs(val.z))) { return 2; } return 1; } if (!(Mathf.Abs(val.x) > Mathf.Abs(val.z))) { return 2; } return 0; } private static bool Wide(Transform t, Bounds shape) { //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_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) int num = Vertical(t); for (int i = 0; i < 3; i++) { if (i != num) { Vector3 val = ((Bounds)(ref shape)).size; float num2 = ((Vector3)(ref val))[i]; val = t.lossyScale; if (num2 * Mathf.Abs(((Vector3)(ref val))[i]) > 2.2f) { return true; } } } return false; } private static bool Shape(Collider collider, out Bounds shape) { //IL_0001: 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_0044: 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_004e: Unknown result type (might be due to invalid IL or missing references) //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) shape = default(Bounds); MeshCollider val = (MeshCollider)(object)((collider is MeshCollider) ? collider : null); if (val != null && (Object)(object)val.sharedMesh != (Object)null) { shape = val.sharedMesh.bounds; } else { BoxCollider val2 = (BoxCollider)(object)((collider is BoxCollider) ? collider : null); if (val2 == null) { return false; } shape = new Bounds(val2.center, val2.size); } return true; } private static void Trunk(BoxCollider box, float ground) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0014: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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) //IL_0052: 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) Transform transform = ((Component)box).transform; Vector3 lossyScale = transform.lossyScale; Vector3 center = box.center; Vector3 size = box.size; int num = Vertical(transform); for (int i = 0; i < 3; i++) { if (i == num) { Vector3 val = transform.InverseTransformPoint(new Vector3(transform.position.x, ground, transform.position.z)); float num2 = ((Vector3)(ref val))[i]; float num3 = Mathf.Min(((Vector3)(ref center))[i] - ((Vector3)(ref size))[i] / 2f, num2); float num4 = Mathf.Max(((Vector3)(ref center))[i] + ((Vector3)(ref size))[i] / 2f, num2); ((Vector3)(ref center))[i] = (num3 + num4) / 2f; ((Vector3)(ref size))[i] = num4 - num3; } else { float num5 = 1.4f / Mathf.Max(Mathf.Abs(((Vector3)(ref lossyScale))[i]), 0.01f); if (!(((Vector3)(ref size))[i] <= num5)) { float num6 = (((Vector3)(ref size))[i] - num5) / 2f; ((Vector3)(ref center))[i] = Mathf.Clamp(0f, ((Vector3)(ref center))[i] - num6, ((Vector3)(ref center))[i] + num6); ((Vector3)(ref size))[i] = num5; } } } box.center = center; box.size = size; } internal static IEnumerable<MeshFilter> ShownMeshes(GameObject go) { MeshFilter[] componentsInChildren = go.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { if ((Object)(object)val.sharedMesh == (Object)null) { continue; } bool flag = true; Transform val2 = ((Component)val).transform; while ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)go.transform) { if (!((Component)val2).gameObject.activeSelf) { flag = false; break; } val2 = val2.parent; } if (flag) { yield return val; } } } internal static Bounds Bounds(GameObject go) { //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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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) //IL_0073: 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_007d: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) Bounds? val = null; foreach (MeshFilter item in ShownMeshes(go)) { Bounds bounds = item.sharedMesh.bounds; for (int i = 0; i < 8; i++) { Vector3 val2 = ((Component)item).transform.TransformPoint(((Bounds)(ref bounds)).center + Vector3.Scale(((B