From e1c16e1ef6d7340de96b4cbb5c78aba01580c573 Mon Sep 17 00:00:00 2001
From: Tim Felgentreff <timfelgentreff@gmail.com>
Date: Wed, 16 Feb 2022 08:42:31 +0100
Subject: [PATCH] tweak map randomization

---
 src/editor/edmap.cpp  | 38 +++++++++++++++++++++++++++++++++++++-
 src/include/editor.h  |  2 +-
 src/include/tileset.h |  2 +-
 src/tolua/editor.pkg  |  2 +-
 4 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/src/editor/edmap.cpp b/src/editor/edmap.cpp
index 3a03b7ec2..abb62e916 100644
--- a/src/editor/edmap.cpp
+++ b/src/editor/edmap.cpp
@@ -402,10 +402,25 @@ static void EditorDestroyAllUnits()
 	}
 }
 
+static void RandomizeTransition(int x, int y)
+{
+	CMapField &mf = *Map.Field(x, y);
+	const CTileset &tileset = *Map.Tileset;
+	int baseTileIndex = tileset.tiles[tileset.findTileIndexByTile(mf.getGraphicTile())].tileinfo.BaseTerrain;
+	int mixTerrainIdx = tileset.tiles[tileset.findTileIndexByTile(mf.getGraphicTile())].tileinfo.MixTerrain;
+	if (mixTerrainIdx != 0) {
+		if (rand() % 8 == 0) {
+			// change only in ~12% of cases
+			const int tileIdx = tileset.findTileIndex(rand() % 2 ? baseTileIndex : mixTerrainIdx, 0);
+			EditorChangeTile(Vec2i(x, y), tileIdx, Vec2i(x, y), true);
+		}
+	}
+}
+
 /**
 **  Create a random map
 */
-void CEditor::CreateRandomMap() const
+void CEditor::CreateRandomMap(bool shuffleTranslitions) const
 {
 	const int mz = std::max(Map.Info.MapHeight, Map.Info.MapWidth);
 
@@ -425,6 +440,27 @@ void CEditor::CreateRandomMap() const
 		UI.Minimap.Update();
 		EditorUpdateDisplay();
 	}
+
+	if (shuffleTranslitions) {
+		// shuffle transitions in all directions
+		// from top left to bottom right
+		for (int x = 0; x < Map.Info.MapWidth; x++) {
+			for (int y = 0; y < Map.Info.MapHeight; y++) {
+				RandomizeTransition(x, y);
+			}
+		}
+		UI.Minimap.Update();
+		EditorUpdateDisplay();
+		// from bottom right to top left
+		for (int x = Map.Info.MapWidth - 1; x >= 0; x--) {
+			for (int y = Map.Info.MapHeight - 1; y >= 0; y--) {
+				RandomizeTransition(x, y);
+			}
+		}
+		UI.Minimap.Update();
+		EditorUpdateDisplay();
+	}
+
 	TileToolRandom = oldRandom;
 
 	for (std::tuple<std::string, int, int, int> t : RandomUnits) {
diff --git a/src/include/editor.h b/src/include/editor.h
index 9a12515bd..20e8ebaae 100644
--- a/src/include/editor.h
+++ b/src/include/editor.h
@@ -69,7 +69,7 @@ public:
 	void Init();
 
 	/// Make random map
-	void CreateRandomMap() const;
+	void CreateRandomMap(bool shuffleTransitions = false) const;
 	/// Variables for random map creation
 	int BaseTileIndex; /// Tile to fill the map with initially;
 	std::vector<std::tuple<int, int, int>> RandomTiles; /// other tiles to fill randomly. (tile, count, area size)
diff --git a/src/include/tileset.h b/src/include/tileset.h
index cabfd003a..0dde68fdf 100644
--- a/src/include/tileset.h
+++ b/src/include/tileset.h
@@ -170,10 +170,10 @@ public:
 	void parse(lua_State *l);
 	void buildTable(lua_State *l);
 	int parseTilesetTileFlags(lua_State *l, int *back, int *j);
+	int findTileIndex(unsigned char baseTerrain, unsigned char mixTerrain = 0) const;
 
 private:
 	unsigned int getOrAddSolidTileIndexByName(const std::string &name);
-	int findTileIndex(unsigned char baseTerrain, unsigned char mixTerrain = 0) const;
 	int getTileIndex(unsigned char baseTerrain, unsigned char mixTerrain, unsigned int quad) const;
 	void buildWallReplacementTable();
 	void parseSlots(lua_State *l, int t);
diff --git a/src/tolua/editor.pkg b/src/tolua/editor.pkg
index 6ebdcb309..6e033006c 100644
--- a/src/tolua/editor.pkg
+++ b/src/tolua/editor.pkg
@@ -14,7 +14,7 @@ class CEditor
 	const CUnitType *StartUnit;
 	bool WriteCompressedMaps;
 	EditorRunningType Running;
-	void CreateRandomMap() const;
+	void CreateRandomMap(bool shuffleTranslitions) const;
 };
 
 extern CEditor Editor;