using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using HarmonyLib;
using Steamworks;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Gnomes Only Give Spellpages")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Gnomes Only Give Spellpages")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("372add71-342e-437a-b6cf-137d8e586699")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("wilson.mapgenerationcustomization", "Map Generation Customization", "1.2.2")]
public class HexPatchPlugin : BaseUnityPlugin
{
public enum GenerationMode
{
Blacklist,
ManualPicker
}
public enum MapType
{
Small,
Large
}
public class MapSettings
{
public readonly int NumHexes;
public readonly int[] SpawnHexIndices;
public GenerationMode[] ModePresets = new GenerationMode[3];
public HashSet<int>[] Presets = new HashSet<int>[3];
public bool[] SpawnDungeonPresets = new bool[3];
public bool[] ForceUniqueHexesPresets = new bool[3];
public int[][] ManualHexSelections = new int[3][];
public MapSettings(int numHexes, int[] spawnHexIndices)
{
NumHexes = numHexes;
SpawnHexIndices = spawnHexIndices;
for (int i = 0; i < 3; i++)
{
Presets[i] = new HashSet<int>();
SpawnDungeonPresets[i] = false;
ForceUniqueHexesPresets[i] = false;
ModePresets[i] = GenerationMode.Blacklist;
ManualHexSelections[i] = new int[NumHexes];
for (int j = 0; j < NumHexes; j++)
{
ManualHexSelections[i][j] = -1;
}
}
}
}
public static MapSettings SmallMapSettings;
public static MapSettings LargeMapSettings;
public static MapType CurrentMapType = MapType.Small;
public static bool CustomPatchEnabled = true;
public static int SelectedPreset = 0;
private int _editingHexSlot = -1;
public Texture2D backgroundTexture;
private Texture2D buttonGreenTexture;
private Texture2D buttonRedTexture;
private Texture2D buttonGreyTexture;
public static readonly string[] HexNames = new string[8] { "Lava Castle", "Frog Bog", "Crystal Cavern", "Mausoleum", "Forest Hills", "Gnome Forest", "Mushroom Biome", "Misty Mountains" };
private Dictionary<string, Texture2D> _hexTextures = new Dictionary<string, Texture2D>();
private Rect windowRect = new Rect(60f, 60f, 520f, 620f);
private bool showUI;
private GUIStyle windowStyle;
private GUIStyle headerStyle;
private GUIStyle labelStyle;
private GUIStyle buttonStyle;
private bool stylesInitialized;
private Rect _editingHexRect;
private void Awake()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
SmallMapSettings = new MapSettings(7, new int[2] { 0, 6 });
LargeMapSettings = new MapSettings(9, new int[2] { 0, 8 });
new Harmony("wilson.mapgenerationcustomization").PatchAll();
LoadTextures();
LoadAll();
LoadPreset(0);
CheckAndSetCustomPatchEnabled();
}
private MapSettings GetCurrentSettings()
{
if (CurrentMapType != 0)
{
return LargeMapSettings;
}
return SmallMapSettings;
}
private void LoadTextures()
{
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Expected O, but got Unknown
string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Textures");
if (!Directory.Exists(text))
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"[HexPatch] 'Textures' folder not found. UI will use fallback colors.");
return;
}
List<string> list = new List<string>(HexNames);
list.AddRange(new string[7] { "spawn1", "spawn2", "random", "background", "Button Green", "Button Red", "Button Grey" });
foreach (string item in list)
{
string text2 = Path.Combine(text, item + ".png");
if (File.Exists(text2))
{
byte[] array = File.ReadAllBytes(text2);
Texture2D val = new Texture2D(2, 2);
if (ImageConversion.LoadImage(val, array))
{
((Object)val).hideFlags = (HideFlags)52;
switch (item)
{
case "background":
backgroundTexture = val;
break;
case "Button Green":
buttonGreenTexture = val;
break;
case "Button Red":
buttonRedTexture = val;
break;
case "Button Grey":
buttonGreyTexture = val;
break;
default:
_hexTextures[item] = val;
break;
}
}
}
else
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("[HexPatch] Texture not found: " + text2));
}
}
((BaseUnityPlugin)this).Logger.LogInfo((object)$"[HexPatch] Loaded {_hexTextures.Count} hex/map textures.");
}
private void Update()
{
if (Input.GetKeyDown((KeyCode)109))
{
showUI = !showUI;
stylesInitialized = false;
}
}
private void OnGUI()
{
//IL_0059: 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_007f: Expected O, but got Unknown
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Expected O, but got Unknown
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
if (showUI)
{
if (!stylesInitialized)
{
InitStyles();
}
bool flag = GetCurrentSettings().ModePresets[SelectedPreset] == GenerationMode.ManualPicker && CurrentMapType == MapType.Large;
((Rect)(ref windowRect)).height = (flag ? 720 : 620);
windowRect = GUILayout.Window(987654, windowRect, new WindowFunction(DrawWindow), "", windowStyle, Array.Empty<GUILayoutOption>());
if (_editingHexSlot != -1)
{
float num = 300f;
float num2 = 400f;
float num3 = ((Rect)(ref windowRect)).x + ((Rect)(ref _editingHexRect)).x + ((Rect)(ref _editingHexRect)).width / 2f - num / 2f;
float num4 = ((Rect)(ref windowRect)).y + ((Rect)(ref _editingHexRect)).y + ((Rect)(ref _editingHexRect)).height / 2f - num2 / 2f;
Rect val = default(Rect);
((Rect)(ref val))..ctor(num3, num4, num, num2);
GUI.ModalWindow(987655, val, new WindowFunction(DrawHexSelectionPopup), "", windowStyle);
}
}
}
private void InitStyles()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
//IL_0028: Expected O, but got Unknown
//IL_0033: 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_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: 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_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Expected O, but got Unknown
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: 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_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Expected O, but got Unknown
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Expected O, but got Unknown
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Expected O, but got Unknown
//IL_010f: Expected O, but got Unknown
windowStyle = new GUIStyle(GUI.skin.window)
{
padding = new RectOffset(10, 10, 10, 10)
};
GUIStyle val = new GUIStyle(GUI.skin.label)
{
richText = true,
fontSize = 20,
fontStyle = (FontStyle)1
};
val.normal.textColor = Color.white;
val.alignment = (TextAnchor)4;
headerStyle = val;
GUIStyle val2 = new GUIStyle(GUI.skin.label);
val2.normal.textColor = Color.white;
val2.wordWrap = true;
val2.alignment = (TextAnchor)4;
labelStyle = val2;
GUIStyle val3 = new GUIStyle(GUI.skin.button)
{
fontSize = 12,
padding = new RectOffset(8, 8, 6, 6)
};
val3.normal.textColor = Color.white;
val3.hover.textColor = Color.white;
val3.active.textColor = Color.white;
val3.alignment = (TextAnchor)4;
val3.border = new RectOffset(0, 0, 0, 0);
buttonStyle = val3;
stylesInitialized = true;
}
private bool TexturedButton(string text, Texture2D texture, params GUILayoutOption[] options)
{
Texture2D background = buttonStyle.normal.background;
Texture2D background2 = buttonStyle.hover.background;
Texture2D background3 = buttonStyle.active.background;
buttonStyle.normal.background = texture;
buttonStyle.hover.background = texture;
buttonStyle.active.background = texture;
bool result = GUILayout.Button(text, buttonStyle, options);
buttonStyle.normal.background = background;
buttonStyle.hover.background = background2;
buttonStyle.active.background = background3;
return result;
}
private void DrawWindow(int id)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)backgroundTexture != (Object)null)
{
GUI.DrawTexture(new Rect(0f, 0f, ((Rect)(ref windowRect)).width, ((Rect)(ref windowRect)).height), (Texture)(object)backgroundTexture);
}
GUI.enabled = _editingHexSlot == -1;
GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
GUILayout.Label("<b>Map Customization</b>", headerStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(8f);
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
if (TexturedButton("Small Map Settings", (CurrentMapType == MapType.Small) ? buttonGreenTexture : buttonGreyTexture, GUILayout.Height(36f)))
{
CurrentMapType = MapType.Small;
CheckAndSetCustomPatchEnabled();
}
if (TexturedButton("Large Map Settings", (CurrentMapType == MapType.Large) ? buttonGreenTexture : buttonGreyTexture, GUILayout.Height(36f)))
{
CurrentMapType = MapType.Large;
CheckAndSetCustomPatchEnabled();
}
GUILayout.EndHorizontal();
GUILayout.Space(10f);
MapSettings currentSettings = GetCurrentSettings();
bool flag = CanPatchBeEnabled();
GUI.enabled = flag && _editingHexSlot == -1;
string text = "";
Texture2D texture = (CustomPatchEnabled ? buttonGreenTexture : buttonRedTexture);
string text2 = (CustomPatchEnabled ? "Customized Map: ON" : "Customized Map: OFF");
if (!flag)
{
texture = buttonRedTexture;
text = GetPatchDisableReason();
text2 = "Customized Map: DISABLED";
}
if (TexturedButton(text2, texture, GUILayout.Height(44f)) && flag)
{
CustomPatchEnabled = !CustomPatchEnabled;
if (!CustomPatchEnabled)
{
currentSettings.SpawnDungeonPresets[SelectedPreset] = false;
SavePreset(SelectedPreset);
}
SaveGlobalEnabled();
}
if (!flag)
{
GUILayout.Label("(" + text + ")", labelStyle, Array.Empty<GUILayoutOption>());
}
GUI.enabled = _editingHexSlot == -1;
GUILayout.Space(8f);
GUILayout.Label("Presets", labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
for (int i = 0; i < 3; i++)
{
Texture2D texture2 = ((SelectedPreset == i) ? buttonGreenTexture : buttonGreyTexture);
if (TexturedButton($"Preset {i + 1}", texture2, GUILayout.Height(32f)))
{
SelectedPreset = i;
LoadPreset(i);
CheckAndSetCustomPatchEnabled();
}
}
GUILayout.EndHorizontal();
if (TexturedButton("Save Current Preset", buttonGreyTexture, GUILayout.Height(30f)))
{
SavePreset(SelectedPreset);
SaveAllToDisk();
CheckAndSetCustomPatchEnabled();
}
GUILayout.Space(10f);
GUILayout.Label("Generation Mode", labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
if (TexturedButton("Blacklist", (currentSettings.ModePresets[SelectedPreset] == GenerationMode.Blacklist) ? buttonGreenTexture : buttonGreyTexture, GUILayout.Height(32f)))
{
currentSettings.ModePresets[SelectedPreset] = GenerationMode.Blacklist;
}
if (TexturedButton("Manual", (currentSettings.ModePresets[SelectedPreset] == GenerationMode.ManualPicker) ? buttonGreenTexture : buttonGreyTexture, GUILayout.Height(32f)))
{
currentSettings.ModePresets[SelectedPreset] = GenerationMode.ManualPicker;
}
GUILayout.EndHorizontal();
GUILayout.Space(10f);
if (currentSettings.ModePresets[SelectedPreset] == GenerationMode.Blacklist)
{
DrawBlacklistUI();
}
else if (CurrentMapType == MapType.Small)
{
DrawSmallManualPickerUI();
}
else
{
DrawLargeManualPickerUI();
}
GUILayout.FlexibleSpace();
GUILayout.Label("press M to hide this menu.", labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.EndVertical();
GUI.DragWindow();
}
private void DrawBlacklistUI()
{
MapSettings currentSettings = GetCurrentSettings();
HashSet<int> hashSet = currentSettings.Presets[SelectedPreset];
bool flag = currentSettings.SpawnDungeonPresets[SelectedPreset];
Texture2D texture = (flag ? buttonGreenTexture : buttonGreyTexture);
if (TexturedButton("Force Mausoleum Spawn", texture, GUILayout.Height(36f)))
{
currentSettings.SpawnDungeonPresets[SelectedPreset] = !flag;
if (currentSettings.SpawnDungeonPresets[SelectedPreset])
{
hashSet.Remove(3);
}
}
GUILayout.Space(6f);
bool flag2 = currentSettings.ForceUniqueHexesPresets[SelectedPreset];
int num = GetCurrentSettings().NumHexes - GetCurrentSettings().SpawnHexIndices.Length;
bool flag3 = CanForceUniqueHexes(hashSet, num);
GUI.enabled = flag3 && _editingHexSlot == -1;
string text = "Force Unique Hexes";
Texture2D texture2 = (flag2 ? buttonGreenTexture : buttonGreyTexture);
if (!flag3)
{
text = $"Force Unique: DISABLED (need {num}+ hex types)";
texture2 = buttonRedTexture;
}
if (TexturedButton(text, texture2, GUILayout.Height(36f)) && flag3)
{
currentSettings.ForceUniqueHexesPresets[SelectedPreset] = !flag2;
}
GUI.enabled = _editingHexSlot == -1;
GUILayout.Space(8f);
GUILayout.Label("Blacklist (toggle):", labelStyle, Array.Empty<GUILayoutOption>());
int num2 = 2;
int num3 = Mathf.CeilToInt((float)HexNames.Length / (float)num2);
for (int i = 0; i < num3; i++)
{
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
for (int j = 0; j < num2; j++)
{
int num4 = i * num2 + j;
if (num4 >= HexNames.Length)
{
break;
}
bool flag4 = hashSet.Contains(num4);
Texture2D texture3 = (flag4 ? buttonRedTexture : buttonGreenTexture);
GUI.enabled = _editingHexSlot == -1;
if (TexturedButton(HexNames[num4], texture3, GUILayout.Width(240f), GUILayout.Height(28f)))
{
if (flag4)
{
hashSet.Remove(num4);
}
else
{
hashSet.Add(num4);
if (num4 == 3)
{
currentSettings.SpawnDungeonPresets[SelectedPreset] = false;
}
}
CheckAndSetCustomPatchEnabled();
}
GUI.enabled = _editingHexSlot == -1;
}
GUILayout.EndHorizontal();
}
}
private void DrawSmallManualPickerUI()
{
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: 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_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_017e: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
//IL_019b: Unknown result type (might be due to invalid IL or missing references)
//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: 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_006e: 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_0081: Expected O, but got Unknown
MapSettings currentSettings = GetCurrentSettings();
int[] array = currentSettings.ManualHexSelections[SelectedPreset];
GUILayout.Label("Click a hex to choose its biome. Castles are fixed.", labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(10f);
int num = array.Count((int hexId) => hexId == 3);
if (num > 1)
{
GUIStyle val = new GUIStyle(labelStyle);
val.normal.textColor = Color.yellow;
val.richText = true;
GUIStyle val2 = val;
GUILayout.Label($"<b>Warning:</b> {num} Mausoleums selected. Only one will be placed.", val2, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
}
float num2 = 96f;
float num3 = 96f;
Rect lastRect = GUILayoutUtility.GetLastRect();
float num4 = ((Rect)(ref lastRect)).yMax - 5f;
float num5 = ((Rect)(ref windowRect)).width / 2f - 50f;
float num6 = 1.05f;
DrawManualHexLayout((Rect[])(object)new Rect[7]
{
new Rect(num5 - num2 * 0.75f * num6, num4 + num3 * 1.35f * num6, num2, num3),
new Rect(num5 - num2 * 0.75f * num6, num4 + num3 * 0.5f * num6, num2, num3),
new Rect(num5, num4 + num3 * 1.75f * num6, num2, num3),
new Rect(num5, num4 + num3 * 0.9f * num6, num2, num3),
new Rect(num5, num4 + 5f * num6, num2, num3),
new Rect(num5 + num2 * 0.75f * num6, num4 + num3 * 1.3f * num6, num2, num3),
new Rect(num5 + num2 * 0.75f * num6, num4 + num3 * 0.45f * num6, num2, num3)
}, array, currentSettings.SpawnHexIndices);
GUILayout.Space(num3 * 3f);
}
private void DrawLargeManualPickerUI()
{
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: 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_0122: 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_0161: 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_018f: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
//IL_01de: Unknown result type (might be due to invalid IL or missing references)
//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
//IL_021d: Unknown result type (might be due to invalid IL or missing references)
//IL_0222: 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_024a: 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_006e: 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_0081: Expected O, but got Unknown
MapSettings currentSettings = GetCurrentSettings();
int[] array = currentSettings.ManualHexSelections[SelectedPreset];
GUILayout.Label("Click a hex to choose its biome. Castles are fixed.", labelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(10f);
int num = array.Count((int hexId) => hexId == 3);
if (num > 1)
{
GUIStyle val = new GUIStyle(labelStyle);
val.normal.textColor = Color.yellow;
val.richText = true;
GUIStyle val2 = val;
GUILayout.Label($"<b>Warning:</b> {num} Mausoleums selected. Only one will be placed.", val2, Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
}
float num2 = 96f;
float num3 = 96f;
float num4 = num2 * 0.75f;
float num5 = num3 * 0.5f;
Rect lastRect = GUILayoutUtility.GetLastRect();
float num6 = ((Rect)(ref lastRect)).yMax + 25f;
float num7 = ((Rect)(ref windowRect)).width / 2f;
Rect[] array2 = (Rect[])(object)new Rect[9];
array2[0] = new Rect(num7 - num4 * 2f - num2 / 2f, num6 + num5 * 2f, num2, num3);
array2[2] = new Rect(num7 - num4 - num2 / 2f, num6 + num5, num2, num3);
array2[7] = new Rect(num7 + num4 - num2 / 2f, num6 + num5, num2, num3);
array2[8] = new Rect(num7 + num4 * 2f - num2 / 2f, num6 + num5 * 2f, num2, num3);
array2[3] = new Rect(num7 - num2 / 2f, num6 + num5 * 4f, num2, num3);
array2[4] = new Rect(num7 - num2 / 2f, num6 + num5 * 2f, num2, num3);
array2[5] = new Rect(num7 - num2 / 2f, num6, num2, num3);
array2[6] = new Rect(num7 + num4 - num2 / 2f, num6 + num5 * 3f, num2, num3);
array2[1] = new Rect(num7 - num4 - num2 / 2f, num6 + num5 * 3f, num2, num3);
DrawManualHexLayout(array2, array, currentSettings.SpawnHexIndices);
GUILayout.Space(num5 * 6f);
}
private void DrawManualHexLayout(Rect[] hexRects, int[] manualSelections, int[] spawnHexIndices)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: 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_0033: 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_0042: Expected O, but got Unknown
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Expected O, but got Unknown
//IL_0052: Expected O, but got Unknown
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Expected O, but got Unknown
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: 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)
GUIStyle val = new GUIStyle(GUI.skin.button);
val.normal.background = null;
val.hover.background = null;
val.active.background = null;
val.border = new RectOffset(0, 0, 0, 0);
val.padding = new RectOffset(0, 0, 0, 0);
GUIStyle val2 = val;
for (int i = 0; i < hexRects.Length; i++)
{
int num = manualSelections[i];
bool flag = spawnHexIndices.Contains(i);
string text = "";
string text2 = "";
GUI.enabled = true;
if (flag)
{
text = ((i == spawnHexIndices[0]) ? "spawn1" : "spawn2");
text2 = $"P{((i == spawnHexIndices[0]) ? 1 : 2)}";
}
else
{
text = ((num == -1) ? "random" : HexNames[num]);
text2 = ((num == -1) ? "RANDOM" : HexNames[num]);
}
GUIContent val3 = new GUIContent();
if (_hexTextures.TryGetValue(text, out var value))
{
val3.image = (Texture)(object)value;
}
else
{
val3.text = text2;
}
if (GUI.Button(hexRects[i], val3, val2) && !flag)
{
_editingHexSlot = i;
_editingHexRect = hexRects[i];
}
GUI.enabled = _editingHexSlot == -1;
}
GUI.backgroundColor = Color.white;
}
private void DrawHexSelectionPopup(int id)
{
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
int[] array = GetCurrentSettings().ManualHexSelections[SelectedPreset];
GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
GUILayout.Label("Editing Hex Slot", headerStyle, Array.Empty<GUILayoutOption>());
GUILayout.Space(10f);
GUI.depth = -1000;
if ((Object)(object)backgroundTexture != (Object)null)
{
GUI.DrawTexture(new Rect(0f, 0f, 300f, 400f), (Texture)(object)backgroundTexture, (ScaleMode)0);
}
if (TexturedButton("Random", buttonGreyTexture))
{
array[_editingHexSlot] = -1;
_editingHexSlot = -1;
CheckAndSetCustomPatchEnabled();
return;
}
GUILayout.Space(5f);
bool flag = false;
for (int i = 0; i < array.Length; i++)
{
if (i != _editingHexSlot && array[i] == 3)
{
flag = true;
break;
}
}
for (int j = 0; j < HexNames.Length; j++)
{
GUI.enabled = !(j == 3 && flag);
if (TexturedButton(HexNames[j], buttonGreyTexture))
{
array[_editingHexSlot] = j;
_editingHexSlot = -1;
CheckAndSetCustomPatchEnabled();
}
GUI.enabled = true;
}
GUILayout.FlexibleSpace();
if (TexturedButton("Cancel", buttonRedTexture))
{
_editingHexSlot = -1;
}
GUILayout.EndVertical();
}
private bool CanForceUniqueHexes(HashSet<int> currentBlacklist, int slotsToFill)
{
return HexNames.Length - currentBlacklist.Count >= slotsToFill;
}
private string GetPatchDisableReason()
{
MapSettings currentSettings = GetCurrentSettings();
if (currentSettings.ModePresets[SelectedPreset] == GenerationMode.ManualPicker)
{
return "";
}
HashSet<int> currentBlacklist = currentSettings.Presets[SelectedPreset];
List<int> list = (from i in Enumerable.Range(0, HexNames.Length)
where !currentBlacklist.Contains(i)
select i).ToList();
if (list.Count == 0)
{
return "Blacklist is too restrictive.";
}
if (list.Count == 1 && list.Contains(3))
{
return "Blacklist is too restrictive.";
}
List<int> list2 = list.Where((int h) => h != 3).ToList();
int num = currentSettings.NumHexes - currentSettings.SpawnHexIndices.Length;
if (list.Contains(3))
{
num--;
}
if (num > 0 && list2.Count == 0)
{
return "Not enough non-special hexes available.";
}
return "";
}
private bool CanPatchBeEnabled()
{
return GetPatchDisableReason() == "";
}
private void CheckAndSetCustomPatchEnabled()
{
if (!CanPatchBeEnabled())
{
CustomPatchEnabled = false;
}
SaveGlobalEnabled();
}
private void SaveAllToDisk()
{
SaveMapSettings(SmallMapSettings, "Small");
SaveMapSettings(LargeMapSettings, "Large");
PlayerPrefs.SetInt("HexPatch_GlobalEnabled", CustomPatchEnabled ? 1 : 0);
PlayerPrefs.Save();
((BaseUnityPlugin)this).Logger.LogInfo((object)"[HexPatch] All settings saved to disk.");
}
private void LoadAll()
{
LoadMapSettings(SmallMapSettings, "Small");
LoadMapSettings(LargeMapSettings, "Large");
CustomPatchEnabled = PlayerPrefs.GetInt("HexPatch_GlobalEnabled", 1) == 1;
}
private void SavePreset(int index)
{
MapSettings currentSettings = GetCurrentSettings();
string arg = CurrentMapType.ToString();
PlayerPrefs.SetString($"HexPatch_{arg}_Preset_{index}_Blacklist", string.Join(",", currentSettings.Presets[index]));
PlayerPrefs.SetInt($"HexPatch_{arg}_Preset_{index}_SpawnDungeon", currentSettings.SpawnDungeonPresets[index] ? 1 : 0);
PlayerPrefs.SetInt($"HexPatch_{arg}_Preset_{index}_ForceUnique", currentSettings.ForceUniqueHexesPresets[index] ? 1 : 0);
PlayerPrefs.SetInt($"HexPatch_{arg}_Preset_{index}_Mode", (int)currentSettings.ModePresets[index]);
PlayerPrefs.SetString($"HexPatch_{arg}_Preset_{index}_ManualSelections", string.Join(",", currentSettings.ManualHexSelections[index]));
PlayerPrefs.Save();
}
private void SaveMapSettings(MapSettings settings, string mapTypeName)
{
for (int i = 0; i < 3; i++)
{
PlayerPrefs.SetString($"HexPatch_{mapTypeName}_Preset_{i}_Blacklist", string.Join(",", settings.Presets[i]));
PlayerPrefs.SetInt($"HexPatch_{mapTypeName}_Preset_{i}_SpawnDungeon", settings.SpawnDungeonPresets[i] ? 1 : 0);
PlayerPrefs.SetInt($"HexPatch_{mapTypeName}_Preset_{i}_ForceUnique", settings.ForceUniqueHexesPresets[i] ? 1 : 0);
PlayerPrefs.SetInt($"HexPatch_{mapTypeName}_Preset_{i}_Mode", (int)settings.ModePresets[i]);
PlayerPrefs.SetString($"HexPatch_{mapTypeName}_Preset_{i}_ManualSelections", string.Join(",", settings.ManualHexSelections[i]));
}
}
private void LoadMapSettings(MapSettings settings, string mapTypeName)
{
for (int i = 0; i < 3; i++)
{
string @string = PlayerPrefs.GetString($"HexPatch_{mapTypeName}_Preset_{i}_Blacklist", "");
settings.Presets[i] = new HashSet<int>(from s in @string.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
select (!int.TryParse(s, out var result2)) ? (-1) : result2 into n
where n != -1
select n);
settings.SpawnDungeonPresets[i] = PlayerPrefs.GetInt($"HexPatch_{mapTypeName}_Preset_{i}_SpawnDungeon", 0) == 1;
settings.ForceUniqueHexesPresets[i] = PlayerPrefs.GetInt($"HexPatch_{mapTypeName}_Preset_{i}_ForceUnique", 0) == 1;
settings.ModePresets[i] = (GenerationMode)PlayerPrefs.GetInt($"HexPatch_{mapTypeName}_Preset_{i}_Mode", 0);
string text = string.Join(",", Enumerable.Repeat("-1", settings.NumHexes));
string[] array = PlayerPrefs.GetString($"HexPatch_{mapTypeName}_Preset_{i}_ManualSelections", text).Split(new char[1] { ',' });
for (int j = 0; j < settings.NumHexes && j < array.Length; j++)
{
if (int.TryParse(array[j], out var result))
{
settings.ManualHexSelections[i][j] = result;
}
}
}
}
private void LoadPreset(int index)
{
if (index < 0 || index > 2)
{
index = 0;
}
SelectedPreset = index;
}
private void SaveGlobalEnabled()
{
PlayerPrefs.SetInt("HexPatch_GlobalEnabled", CustomPatchEnabled ? 1 : 0);
PlayerPrefs.Save();
}
private Texture2D MakeTex(int width, int height, Color col)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Expected O, but got Unknown
Color[] array = (Color[])(object)new Color[width * height];
for (int i = 0; i < array.Length; i++)
{
array[i] = col;
}
Texture2D val = new Texture2D(width, height);
val.SetPixels(array);
val.Apply();
((Object)val).hideFlags = (HideFlags)52;
return val;
}
}
[HarmonyPatch(typeof(DungeonGenerator))]
internal class DungeonGeneratorPatch
{
[HarmonyPatch("GenerateSmallMap")]
[HarmonyPrefix]
private static bool Prefix_SmallMap(DungeonGenerator __instance, ref IEnumerator __result)
{
if (!HexPatchPlugin.CustomPatchEnabled)
{
return true;
}
HexPatchPlugin.MapSettings smallMapSettings = HexPatchPlugin.SmallMapSettings;
HexPatchPlugin.GenerationMode generationMode = smallMapSettings.ModePresets[HexPatchPlugin.SelectedPreset];
__result = ((generationMode == HexPatchPlugin.GenerationMode.ManualPicker) ? ManualGenerateMap(__instance, smallMapSettings, "SmallMapRPC") : CustomGenerateMap(__instance, smallMapSettings, "SmallMapRPC"));
return false;
}
[HarmonyPatch("GenerateMap")]
[HarmonyPrefix]
private static bool Prefix_LargeMap(DungeonGenerator __instance, ref IEnumerator __result)
{
if (!HexPatchPlugin.CustomPatchEnabled)
{
return true;
}
HexPatchPlugin.MapSettings largeMapSettings = HexPatchPlugin.LargeMapSettings;
HexPatchPlugin.GenerationMode generationMode = largeMapSettings.ModePresets[HexPatchPlugin.SelectedPreset];
__result = ((generationMode == HexPatchPlugin.GenerationMode.ManualPicker) ? ManualGenerateMap(__instance, largeMapSettings, "LargeMapRPC") : CustomGenerateMap(__instance, largeMapSettings, "LargeMapRPC"));
return false;
}
private static IEnumerator ManualGenerateMap(DungeonGenerator instance, HexPatchPlugin.MapSettings settings, string rpcMethodName)
{
Type typeFromHandle = typeof(DungeonGenerator);
FieldInfo field = typeFromHandle.GetField("OccupiedHexes", BindingFlags.Instance | BindingFlags.NonPublic);
FieldInfo prevHexSpawnedField = typeFromHandle.GetField("PrevHexSpawned", BindingFlags.Instance | BindingFlags.NonPublic);
FieldInfo hexesPlacedField = typeFromHandle.GetField("HexesPlaced", BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo method = typeFromHandle.GetMethod(rpcMethodName, BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo serverPlaceHex = typeFromHandle.GetMethod("ServerPlaceHex", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[2]
{
typeof(int),
typeof(int)
}, null);
if (field == null || prevHexSpawnedField == null || hexesPlacedField == null || method == null || serverPlaceHex == null)
{
Debug.LogError((object)("[HexPatch] Reflection failed for Manual Generator (" + rpcMethodName + "). Aborting."));
yield break;
}
method.Invoke(instance, null);
bool[] occupiedHexes = (bool[])field.GetValue(instance);
int[] array = settings.ManualHexSelections[HexPatchPlugin.SelectedPreset];
List<int> biomeSelections = new List<int>();
for (int j = 0; j < array.Length; j++)
{
if (!settings.SpawnHexIndices.Contains(j))
{
biomeSelections.Add(array[j]);
}
}
if (settings.NumHexes != 9)
{
int[] spawnHexIndices = settings.SpawnHexIndices;
foreach (int num in spawnHexIndices)
{
if (num < occupiedHexes.Length)
{
occupiedHexes[num] = true;
}
}
}
bool mausoleumPlaced = false;
int biomeIndex = 0;
for (int i = 0; i < occupiedHexes.Length; i++)
{
if (occupiedHexes[i])
{
continue;
}
if (biomeIndex >= biomeSelections.Count)
{
break;
}
int num2 = biomeSelections[biomeIndex];
biomeIndex++;
if (num2 == 3)
{
if (mausoleumPlaced)
{
num2 = -1;
}
else
{
mausoleumPlaced = true;
}
}
if (num2 == -1)
{
List<int> list = Enumerable.Range(0, HexPatchPlugin.HexNames.Length).ToList();
if (mausoleumPlaced)
{
list.Remove(3);
}
num2 = (list.Any() ? list[Random.Range(0, list.Count)] : 0);
}
serverPlaceHex.Invoke(instance, new object[2] { num2, i });
yield return (object)new WaitUntil((Func<bool>)(() => (bool)prevHexSpawnedField.GetValue(instance)));
prevHexSpawnedField.SetValue(instance, false);
yield return null;
}
hexesPlacedField.SetValue(instance, true);
Array.Clear(occupiedHexes, 0, occupiedHexes.Length);
}
private static IEnumerator CustomGenerateMap(DungeonGenerator instance, HexPatchPlugin.MapSettings settings, string rpcMethodName)
{
Type typeFromHandle = typeof(DungeonGenerator);
FieldInfo field = typeFromHandle.GetField("OccupiedHexes", BindingFlags.Instance | BindingFlags.NonPublic);
FieldInfo dungeonPlacedField = typeFromHandle.GetField("dungeonPlaced", BindingFlags.Instance | BindingFlags.NonPublic);
FieldInfo prevHexSpawnedField = typeFromHandle.GetField("PrevHexSpawned", BindingFlags.Instance | BindingFlags.NonPublic);
FieldInfo hexesPlacedField = typeFromHandle.GetField("HexesPlaced", BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo method = typeFromHandle.GetMethod(rpcMethodName, BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo serverPlaceHex = typeFromHandle.GetMethod("ServerPlaceHex", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[2]
{
typeof(int),
typeof(int)
}, null);
if (field == null || dungeonPlacedField == null || prevHexSpawnedField == null || hexesPlacedField == null || method == null || serverPlaceHex == null)
{
Debug.LogError((object)("[HexPatch] Reflection failed for Custom Generator (" + rpcMethodName + "). Aborting."));
yield break;
}
int selectedPreset = HexPatchPlugin.SelectedPreset;
HashSet<int> blacklist = settings.Presets[selectedPreset];
bool forceDungeon = settings.SpawnDungeonPresets[selectedPreset];
bool forceUnique = settings.ForceUniqueHexesPresets[selectedPreset];
method.Invoke(instance, null);
dungeonPlacedField.SetValue(instance, false);
bool[] occupiedHexes = (bool[])field.GetValue(instance);
if (settings.NumHexes != 9)
{
int[] spawnHexIndices = settings.SpawnHexIndices;
foreach (int num in spawnHexIndices)
{
if (num < occupiedHexes.Length)
{
occupiedHexes[num] = true;
}
}
}
List<int> availableHexTypes = (from i in Enumerable.Range(0, HexPatchPlugin.HexNames.Length)
where !blacklist.Contains(i)
select i).ToList();
if (!availableHexTypes.Any())
{
Debug.LogError((object)"[HexPatch] No available hex types after applying blacklist. Aborting.");
yield break;
}
List<int> usedHexTypesInThisMap = new List<int>();
for (int j = 0; j < occupiedHexes.Length; j++)
{
if (occupiedHexes[j])
{
continue;
}
int num2 = -1;
bool flag = (bool)dungeonPlacedField.GetValue(instance);
List<int> list = new List<int>(availableHexTypes);
if (forceUnique)
{
List<int> list2 = list.Except(usedHexTypesInThisMap).ToList();
if (list2.Any())
{
list = list2;
}
}
if (forceDungeon && !flag && list.Contains(3) && (occupiedHexes.Length - 1 - j <= list.Count((int h) => h != 3) || Random.value > 0.5f))
{
num2 = 3;
}
if (num2 == -1)
{
List<int> list3 = new List<int>(list);
if (flag)
{
list3.Remove(3);
}
if (list3.Any())
{
num2 = list3[Random.Range(0, list3.Count)];
}
else
{
Debug.LogWarning((object)"[HexPatch] No available hex types to place. Defaulting to 1. (Frog Bog)");
num2 = 1;
}
}
serverPlaceHex.Invoke(instance, new object[2] { num2, j });
usedHexTypesInThisMap.Add(num2);
if (num2 == 3)
{
dungeonPlacedField.SetValue(instance, true);
}
yield return (object)new WaitUntil((Func<bool>)(() => (bool)prevHexSpawnedField.GetValue(instance)));
prevHexSpawnedField.SetValue(instance, false);
yield return null;
}
hexesPlacedField.SetValue(instance, true);
Array.Clear(occupiedHexes, 0, occupiedHexes.Length);
Debug.Log((object)$"[HexPatch] CustomGenerateMap finished for {settings.NumHexes}-hex map.");
}
}
[HarmonyPatch(typeof(DungeonGenerator), "RpcLogic___ServerPlaceHex_1692629761")]
public static class Patch_ServerPlaceHex
{
private static void Postfix(int HexType, int hexindex, DungeonGenerator __instance)
{
string arg = ((HexType >= 0 && HexType < __instance.Hexes.Length && (Object)(object)__instance.Hexes[HexType] != (Object)null) ? ((Object)__instance.Hexes[HexType]).name : "Unknown");
Debug.Log((object)$"[HexPatch] Placed hex at index {hexindex} - Type ID: {HexType}, Name: {arg}");
}
}
[HarmonyPatch(typeof(BootstrapManager), "OnLobbyCreated")]
internal class Patch_BootstrapManager_OnLobbyCreated
{
private static void Postfix(LobbyCreated_t callback)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
if ((int)callback.m_eResult == 1)
{
string key = "com.magearena.modsync";
if (!Chainloader.PluginInfos.ContainsKey(key))
{
CSteamID val = new CSteamID(BootstrapManager.CurrentLobbyID);
string text = SteamFriends.GetPersonaName().ToString();
string text2 = "(Modded Map) " + text;
SteamMatchmaking.SetLobbyData(val, "name", text2);
Debug.Log((object)("[CustomLobbyPatch] Lobby name changed to: " + text2));
}
}
}
}
namespace System.Runtime.CompilerServices;
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}