Created
September 9, 2018 14:10
-
-
Save juntalis/393ae2c547e0bba21ada4889ae51ac5a to your computer and use it in GitHub Desktop.
Unofficial configurable maps B19
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using Harmony; | |
using MapReroll.Patches; | |
using MapReroll.UI; | |
using RimWorld; | |
using UnityEngine; | |
using Verse; | |
namespace MapReroll.Compat { | |
/// <summary> | |
/// Compatibility tweaks to play nicely with Rainbeau's Configurable Maps | |
/// </summary> | |
public class Compat_ConfigurableMaps { | |
private delegate TerrainDef RFRBeachMakerBeachTerrainAt(IntVec3 c, Map map, BiomeDef biome); | |
private static RFRBeachMakerBeachTerrainAt BeachMakerBeachTerrainAt; | |
public static void Apply(HarmonyInstance harmonyInst) { | |
try { | |
var rfrTerrainGenstep = GenTypes.GetTypeInAnyAssembly("ConfigurableMaps.Maker.CMGenStep_Terrain"); | |
if (rfrTerrainGenstep == null) return; // mod is not loaded | |
ReflectionCache.BeachMakerType = ReflectionCache.ReflectType("ConfigurableMaps.Maker.CMBeachMaker", rfrTerrainGenstep.Assembly); | |
if (ReflectionCache.BeachMakerType != null) { | |
ReflectionCache.BeachMaker_Init = ReflectionCache.ReflectMethod("Init", ReflectionCache.BeachMakerType, typeof(void), new[] {typeof(Map)}); | |
ReflectionCache.BeachMaker_Cleanup = ReflectionCache.ReflectMethod("Cleanup", ReflectionCache.BeachMakerType, typeof(void), new Type[0]); | |
var rfrBeachTerrainAt = ReflectionCache.ReflectMethod("BeachTerrainAt", ReflectionCache.BeachMakerType, typeof(TerrainDef), new[] {typeof(IntVec3), typeof(Map), typeof(BiomeDef)}); | |
BeachMakerBeachTerrainAt = (RFRBeachMakerBeachTerrainAt)Delegate.CreateDelegate(typeof(RFRBeachMakerBeachTerrainAt), null, rfrBeachTerrainAt); | |
if (BeachMakerBeachTerrainAt == null) throw new Exception("Failed to create BeachTerrainAt delegate"); | |
} | |
ReflectionCache.RiverMakerType = ReflectionCache.ReflectType("ConfigurableMaps.Maker.CMRiverMaker"); | |
if (ReflectionCache.RiverMakerType != null) { | |
ReflectionCache.GenStepTerrain_GenerateRiver = ReflectionCache.ReflectMethod("GenerateRiver", rfrTerrainGenstep, ReflectionCache.RiverMakerType, new[] {typeof(Map)}); | |
ReflectionCache.RiverMaker_TerrainAt = ReflectionCache.ReflectMethod("TerrainAt", ReflectionCache.RiverMakerType, typeof(TerrainDef), new[] {typeof(IntVec3), typeof(bool)}); | |
} | |
// required on account of different signatures | |
MapPreviewGenerator.AlternateBeachTerrainAtDelegate = AlternateBeachTerrainAt; | |
// add button to access settings window | |
Dialog_MapPreviews.DialogOnGUI -= ExtraMapPreviewsDialogOnGUI; | |
Dialog_MapPreviews.DialogOnGUI += ExtraMapPreviewsDialogOnGUI; | |
// ensures the modded BeachMaker is also affected by the "Map generator mode" setting | |
var beachMakerInit = AccessTools.Method(GenTypes.GetTypeInAnyAssembly("ConfigurableMaps.Maker.CMBeachMaker"), "Init"); | |
if (beachMakerInit == null) throw new Exception("Failed to reflect CMBeachMaker.Init"); | |
var prefix = ((Action<Map>)DeterministicGenerationPatcher.DeterministicBeachSetup).Method; | |
DeterministicGenerationPatcher.InstrumentMethodForDeterministicGeneration(beachMakerInit, prefix, harmonyInst); | |
// same for the river generator | |
var genStepTerrainGenerateRiver = AccessTools.Method(rfrTerrainGenstep, "GenerateRiver", new []{typeof(Map)}); | |
if (genStepTerrainGenerateRiver == null) throw new Exception("Failed to reflect CMGenStep_Terrain.GenerateRiver"); | |
prefix = ((Action<Map>)DeterministicGenerationPatcher.DeterministicRiverSetup).Method; | |
DeterministicGenerationPatcher.InstrumentMethodForDeterministicGeneration(genStepTerrainGenerateRiver, prefix, harmonyInst); | |
MapRerollController.Instance.Logger.Message("Applied Configurable Maps compatibility layer"); | |
} catch (Exception e) { | |
MapRerollController.Instance.Logger.Error("Failed to apply compatibility layer for Configurable Maps:" +e); | |
} | |
} | |
private static TerrainDef AlternateBeachTerrainAt(IntVec3 c, BiomeDef biome) { | |
return BeachMakerBeachTerrainAt(c, null, biome); | |
} | |
// add a button to the previews dialog for easy access to terrain settings | |
private static void ExtraMapPreviewsDialogOnGUI(Dialog_MapPreviews previewsDialog, Rect inRect) { | |
var closeButtonSize = new Vector2(120f, 40f); | |
var configureButtonSize = new Vector2(140f, 40f); | |
var elementSpacing = 10f; | |
if (Widgets.ButtonText(new Rect(inRect.width - closeButtonSize.x - elementSpacing - configureButtonSize.x, inRect.yMax - configureButtonSize.y, configureButtonSize.x, configureButtonSize.y), "Reroll2_previews_configureMap".Translate())) { | |
var mod = LoadedModManager.ModHandles.FirstOrDefault(m => m.GetType().FullName == "ConfigurableMaps.Settings.TerrainSettingsController"); | |
if (mod != null) { | |
previewsDialog.Close(); | |
var settingsDialog = new Dialog_ModSettings(); | |
// pre-select the terrain settings Mod | |
ReflectionCache.DialogModSettings_SelMod.SetValue(settingsDialog, mod); | |
Find.WindowStack.Add(settingsDialog); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment