From c2e59b6967522f8a26644601f786785162241db6 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Thu, 17 Dec 2009 01:02:05 +0000
Subject: [PATCH] test tileset level generator

git-svn-id: http://svn.net-core.org/repos/t-engine4@128 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engine/generator/map/DungeonBuilder.lua  |  55 +++++-
 game/engine/generator/map/TileSet.lua         | 174 ++++++++++++++++++
 game/modules/tome/class/Game.lua              |   1 +
 game/modules/tome/data/tilesets/dungeon.lua   | 131 +++++++++++++
 .../tome/data/zones/ancient_ruins/zone.lua    |  11 +-
 5 files changed, 366 insertions(+), 6 deletions(-)
 create mode 100644 game/engine/generator/map/TileSet.lua
 create mode 100644 game/modules/tome/data/tilesets/dungeon.lua

diff --git a/game/engine/generator/map/DungeonBuilder.lua b/game/engine/generator/map/DungeonBuilder.lua
index 1a93fd51ec..e8bb0f53ee 100644
--- a/game/engine/generator/map/DungeonBuilder.lua
+++ b/game/engine/generator/map/DungeonBuilder.lua
@@ -9,6 +9,53 @@ function _M:init(map, grid_list, data)
 	self.wall = grid_list[data.wall]
 	self.up = grid_list[data.up]
 	self.down = grid_list[data.down]
+
+	self.block = {w=11, h=11}
+	self.cols = math.floor(self.map.w / self.block.w)
+	self.rows = math.floor(self.map.h / self.block.h)
+	self.room_map = {}
+	for i = 0, self.cols do
+		self.room_map[i] = {}
+		for j = 0, self.rows do
+			self.room_map[i][j] = false
+		end
+	end
+end
+
+function _M:roomAlloc(bx, by, bw, bh, rid)
+	print("trying room at", bx,by,bw,bh)
+	if bx + bw - 1 > self.cols or by + bh - 1 > self.rows then return false end
+
+	-- Do we stomp ?
+	for i = bx, bx + bw - 1 do
+		for j = by, by + bh - 1 do
+			if self.room_map[i][j] then return false end
+		end
+	end
+
+	-- ok alloc it
+	for i = bx, bx + bw - 1 do
+		for j = by, by + bh - 1 do
+			self.room_map[i][j] = true
+		end
+	end
+	print("room allocated at", bx,by,bw,bh)
+
+	return true
+end
+
+function _M:buildSimpleRoom(bx, by, rid)
+	local bw, bh = rng.range(1, 3), rng.range(1, 3)
+
+	if not self:roomAlloc(bx, by, bw, bh, rid) then return false end
+
+	for i = bx * self.block.w + 1, (bx + bw - 1) * self.block.w - 2 do
+		for j = by * self.block.h + 1, (by + bh - 1) * self.block.h - 2 do
+			self.map(i, j, Map.TERRAIN, self.floor)
+		end
+	end
+
+	return true
 end
 
 function _M:generate()
@@ -16,7 +63,13 @@ function _M:generate()
 		self.map(i, j, Map.TERRAIN, self.wall)
 	end end
 
-
+	local nb_room = 10
+	while nb_room > 0 do
+		local bx, by = rng.range(0, self.cols), rng.range(0, self.rows)
+		if self:buildSimpleRoom(bx, by, nb_room) then
+			nb_room = nb_room - 1
+		end
+	end
 
 	-- Always starts at 1, 1
 	self.map(1, 1, Map.TERRAIN, self.up)
diff --git a/game/engine/generator/map/TileSet.lua b/game/engine/generator/map/TileSet.lua
new file mode 100644
index 0000000000..86ff2d5fe9
--- /dev/null
+++ b/game/engine/generator/map/TileSet.lua
@@ -0,0 +1,174 @@
+require "engine.class"
+local Map = require "engine.Map"
+require "engine.Generator"
+module(..., package.seeall, class.inherit(engine.Generator))
+
+function _M:init(map, grid_list, data)
+	engine.Generator.init(self, map)
+	self.data = data
+	self.grid_list = grid_list
+	self.tiles, self.raw = self:loadTiles(data.tileset)
+
+	self.block = self.raw.base
+	self.cols = math.floor(self.map.w / self.block.w)
+	self.rows = math.floor(self.map.h / self.block.h)
+	self.room_map = {}
+	for i = 0, self.cols do
+		self.room_map[i] = {}
+		for j = 0, self.rows do
+			self.room_map[i][j] = false
+		end
+	end
+end
+
+function _M:loadTiles(tileset)
+	local f = loadfile("/data/tilesets/"..tileset..".lua")
+	local d = {}
+	setfenv(f, d)
+	local ret, err = f()
+	if not ret and err then error(err) end
+
+	local tiles = {}
+	for idx, ts in ipairs(d.tiles) do
+		local t = { id=idx, openings={} }
+		tiles[idx] = t
+		for j, line in ipairs(ts) do
+			local i = 1
+			for c in line:gmatch(".") do
+				t[i] = t[i] or {}
+				t[i][j] = self.data[c]
+
+				-- Find edge openings
+				local mx, my = line:len(), #ts
+				if c == '.' and (i == 1 or i == mx or j == 1 or j == my) then
+					if i == 1 and j == 1 then
+						table.insert(t.openings, {i, j, 7})
+					elseif i == 1 and j == my then
+						table.insert(t.openings, {i, j, 1})
+					elseif i == mx and j == my then
+						table.insert(t.openings, {i, j, 3})
+					elseif i == mx and j == 1 then
+						table.insert(t.openings, {i, j, 9})
+					elseif i == 1 then
+						table.insert(t.openings, {i, j, 4})
+					elseif i == mx then
+						table.insert(t.openings, {i, j, 6})
+					elseif j == 1 then
+						table.insert(t.openings, {i, j, 8})
+					elseif j == my then
+						table.insert(t.openings, {i, j, 2})
+					end
+				end
+
+				i = i + 1
+			end
+		end
+	end
+
+	return tiles, d
+end
+
+function _M:roomAlloc(bx, by, bw, bh, rid)
+	print("trying room at", bx,by,bw,bh)
+	if bx + bw - 1 > self.cols or by + bh - 1 > self.rows then return false end
+	if bx < 0 or by < 0 then return false end
+
+	-- Do we stomp ?
+	for i = bx, bx + bw - 1 do
+		for j = by, by + bh - 1 do
+			if self.room_map[i][j] then return false end
+		end
+	end
+
+	-- ok alloc it
+	for i = bx, bx + bw - 1 do
+		for j = by, by + bh - 1 do
+			self.room_map[i][j] = true
+		end
+	end
+	print("room allocated at", bx,by,bw,bh)
+
+	return true
+end
+
+function _M:findMatchingTiles(st, dir)
+	local m = {}
+
+	for _, dt in ipairs(self.tiles) do
+		local ok = true
+		if dir == 8 then
+			for i = 1, self.block.w do
+				if st[i][1] ~= dt[i][self.block.h] then ok = false end
+			end
+		elseif dir == 2 then
+			for i = 1, self.block.w do
+				if st[i][self.block.h] ~= dt[i][1] then ok = false end
+			end
+		elseif dir == 4 then
+			for j = 1, self.block.h do
+				if st[1][j] ~= dt[self.block.w][j] then ok = false end
+			end
+		elseif dir == 6 then
+			for j = 1, self.block.h do
+				if st[self.block.w][j] ~= dt[1][j] then ok = false end
+			end
+		end
+		if ok then
+			m[#m+1] = dt
+			print("found matching tile in dir", dir, "from", st.id, "to", dt.id)
+		end
+	end
+
+	return m
+end
+
+function _M:buildTile(tile, bx, by, rid)
+	local bw, bh = 1, 1
+
+	if not self:roomAlloc(bx, by, bw, bh, rid) then return false end
+
+	for i = 1, self.block.w do
+		for j = 1, self.block.h do
+			self.map(bx * self.block.w + i - 1, by * self.block.h + j - 1, Map.TERRAIN, self.grid_list[tile[i][j]])
+		end
+	end
+	local opens = {}
+	for i, o in ipairs(tile.openings) do
+		local coord = dir_to_coord[o[3]]
+		local mts = self:findMatchingTiles(tile, o[3])
+
+		opens[#opens+1] = {bx + coord[1], by + coord[2], tile=mts[rng.range(1, #mts)]}
+		print("room at ",bx,by,"opens to",o[3],"::",bx + coord[1], by + coord[2])
+	end
+
+	return opens
+end
+
+function _M:generate()
+	for i = 0, self.map.w - 1 do for j = 0, self.map.h - 1 do
+		self.map(i, j, Map.TERRAIN, self.grid_list[self.data["#"]])
+	end end
+
+	local first = true
+	local process = {}
+	local id = 1
+	process[#process+1] = {rng.range(0, self.cols), rng.range(0, self.rows), tile=self.tiles[rng.range(1, #self.tiles)]}
+	while #process > 0 do
+		local b = table.remove(process)
+		local type = "room"
+		if not first and rng.percent(70) then type = "tunnel" end
+		first = false
+
+		local opens = self:buildTile(b.tile, b[1], b[2], id)
+		if opens then
+			id = id + 1
+
+			-- Add openings
+			for i, o in ipairs(opens) do process[#process+1] = o end
+		end
+	end
+
+	-- Always starts at 1, 1
+	self.map(1, 1, Map.TERRAIN, self.up)
+	return 1, 1
+end
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index fa86718b34..a42846189b 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -468,6 +468,7 @@ function _M:setupMouse()
 				game.level.map.my = game.level.map.my + 1
 				derivy = derivy + game.level.map.tile_h
 			end
+			game.level.map._map:setScroll(game.level.map.mx, game.level.map.my)
 		end
 	end)
 	-- Scroll message log
diff --git a/game/modules/tome/data/tilesets/dungeon.lua b/game/modules/tome/data/tilesets/dungeon.lua
new file mode 100644
index 0000000000..db5cd03835
--- /dev/null
+++ b/game/modules/tome/data/tilesets/dungeon.lua
@@ -0,0 +1,131 @@
+base = {w=5, h=5}
+
+tiles =
+{type="tunnel",
+{
+[[#####]],
+[[#####]],
+[[.....]],
+[[#####]],
+[[#####]],
+},
+
+{type="tunnel",
+[[##.##]],
+[[##.##]],
+[[##.##]],
+[[##.##]],
+[[##.##]],
+},
+
+
+{type="tunnel",
+[[##.##]],
+[[##.##]],
+[[...##]],
+[[##.##]],
+[[##.##]],
+},
+
+{type="tunnel",
+[[##.##]],
+[[##.##]],
+[[##...]],
+[[##.##]],
+[[##.##]],
+},
+
+{type="tunnel",
+[[#####]],
+[[#####]],
+[[.....]],
+[[##.##]],
+[[##.##]],
+},
+
+{type="tunnel",
+[[##.##]],
+[[##.##]],
+[[.....]],
+[[#####]],
+[[#####]],
+},
+
+{type="tunnel",
+[[##.##]],
+[[##.##]],
+[[.....]],
+[[##.##]],
+[[##.##]],
+},
+
+{type="room",
+[[##.##]],
+[[#...#]],
+[[##.##]],
+[[#...#]],
+[[#####]],
+},
+
+{type="room",
+[[##.##]],
+[[#...#]],
+[[.....]],
+[[#...#]],
+[[##.##]],
+},
+
+{type="room",
+[[##.##]],
+[[#....]],
+[[#....]],
+[[#....]],
+[[#####]],
+},
+{type="room",
+[[#####]],
+[[....#]],
+[[....#]],
+[[....#]],
+[[#####]],
+},
+
+{type="room",
+[[#####]],
+[[#....]],
+[[....#]],
+[[#....]],
+[[#####]],
+},
+{type="room",
+[[#####]],
+[[....#]],
+[[#....]],
+[[....#]],
+[[#####]],
+},
+
+
+--[=[
+{type="room",
+[[#####.####]],
+[[#........#]],
+[[....##....]],
+[[#........#]],
+[[#####.####]],
+},
+
+{type="room",
+[[#####.####]],
+[[#........#]],
+[[....##....]],
+[[#........#]],
+[[####..####]],
+[[####..####]],
+[[#........#]],
+[[....##....]],
+[[#........#]],
+[[#####.####]],
+},
+]=]
+}
diff --git a/game/modules/tome/data/zones/ancient_ruins/zone.lua b/game/modules/tome/data/zones/ancient_ruins/zone.lua
index 971dc8047d..6dc43e6a32 100644
--- a/game/modules/tome/data/zones/ancient_ruins/zone.lua
+++ b/game/modules/tome/data/zones/ancient_ruins/zone.lua
@@ -2,15 +2,16 @@ return {
 	name = "ancient ruins",
 	level_range = {1, 5},
 	max_level = 5,
-	width = 100, height = 100,
---	all_remembered = true,
+	width = 50, height = 30,
+	all_remembered = true,
 	all_lited = true,
 --	persistant = true,
 	generator =  {
 		map = {
-			class= "engine.generator.map.Empty",
-			floor = "FLOOR",
-			wall = "WALL",
+			class = "engine.generator.map.TileSet",
+			tileset = "dungeon",
+			['.'] = "FLOOR",
+			['#'] = "WALL",
 			up = "UP",
 			down = "DOWN",
 			door = "DOOR",
-- 
GitLab