From 5fbb9f989908ee3650cb33e783f93d387418c835 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Sun, 20 Dec 2009 21:41:57 +0000
Subject: [PATCH] fix crash on scroll betet generator

git-svn-id: http://svn.net-core.org/repos/t-engine4@132 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engine/Zone.lua                          |  8 +--
 game/engine/generator/map/Maze.lua            | 14 ++++--
 game/engine/generator/map/Roomer.lua          | 50 +++++++++++++------
 game/engine/generator/map/TileSet.lua         | 50 ++-----------------
 game/engine/generator/object/Random.lua       |  4 +-
 game/modules/tome/class/Game.lua              |  2 +-
 game/modules/tome/data/tilesets/dungeon.lua   | 40 +++------------
 .../tome/data/zones/ancient_ruins/zone.lua    | 12 +----
 src/map.c                                     |  2 +-
 9 files changed, 67 insertions(+), 115 deletions(-)

diff --git a/game/engine/Zone.lua b/game/engine/Zone.lua
index c184e022be..051cdb033a 100644
--- a/game/engine/Zone.lua
+++ b/game/engine/Zone.lua
@@ -94,7 +94,7 @@ end
 --- Asks the zone to generate a level of level "lev"
 -- @param lev the level (from 1 to zone.max_level)
 -- @return a Level object
-function _M:getLevel(game, lev, no_close)
+function _M:getLevel(game, lev, old_lev, no_close)
 	-- Before doing anything else, close the current level
 	if not no_close and game.level and game.level.map then
 		if game.level.data.persistant then
@@ -123,7 +123,7 @@ function _M:getLevel(game, lev, no_close)
 
 	-- In any cases, make one if none was found
 	if not level then
-		level = self:newLevel(level_data, lev, game)
+		level = self:newLevel(level_data, lev, old_lev, game)
 	end
 
 	-- Clean up things
@@ -132,7 +132,7 @@ function _M:getLevel(game, lev, no_close)
 	return level
 end
 
-function _M:newLevel(level_data, lev, game)
+function _M:newLevel(level_data, lev, old_lev, game)
 	local map = self.map_class.new(level_data.width, level_data.height)
 	if level_data.all_lited then map:liteAll(0, 0, map.w, map.h) end
 	if level_data.all_remembered then map:rememberAll(0, 0, map.w, map.h) end
@@ -143,7 +143,7 @@ function _M:newLevel(level_data, lev, game)
 		self.grid_list,
 		level_data.generator.map
 	)
-	local startx, starty = generator:generate()
+	local startx, starty = generator:generate(lev, old_lev)
 
 	local level = self.level_class.new(lev, map)
 	level.start = {x=startx, y=starty}
diff --git a/game/engine/generator/map/Maze.lua b/game/engine/generator/map/Maze.lua
index da86740b28..5a28142c19 100644
--- a/game/engine/generator/map/Maze.lua
+++ b/game/engine/generator/map/Maze.lua
@@ -11,7 +11,7 @@ function _M:init(map, grid_list, data)
 	self.down = grid_list[data.down]
 end
 
-function _M:generate()
+function _M:generate(lev, old_lev)
 	for i = 0, self.map.w - 1 do for j = 0, self.map.h - 1 do
 		self.map(i, j, Map.TERRAIN, self.wall)
 	end end
@@ -60,7 +60,13 @@ function _M:generate()
 		end
 	end
 	-- Always starts at 1, 1
-	self.map(1, 1, Map.TERRAIN, self.up)
-	self.map(math.floor(self.map.w/2)*2-1-2*(1-math.mod(self.map.w,2)), math.floor(self.map.h/2)*2-1-2*(1-math.mod(self.map.h,2)), Map.TERRAIN, self.down)
-	return 1, 1
+	local ux, uy = 1, 1
+	local dx, dy = math.floor(self.map.w/2)*2-1-2*(1-math.mod(self.map.w,2)), math.floor(self.map.h/2)*2-1-2*(1-math.mod(self.map.h,2))
+	self.map(ux, uy, Map.TERRAIN, self.up)
+	self.map(dx, dy, Map.TERRAIN, self.down)
+	if lev > old_lev then
+		return ux, uy
+	else
+		return dx, dy
+	end
 end
diff --git a/game/engine/generator/map/Roomer.lua b/game/engine/generator/map/Roomer.lua
index ae24f87ced..d0f69a1be5 100644
--- a/game/engine/generator/map/Roomer.lua
+++ b/game/engine/generator/map/Roomer.lua
@@ -130,7 +130,7 @@ function _M:markTunnel(x, y, xdir, ydir, id)
 	local dir = coord_to_dir[xdir][ydir]
 	for i, d in ipairs(mark_dirs[dir]) do
 		local xd, yd = dir_to_coord[d][1], dir_to_coord[d][2]
-		if not self.room_map[x+xd][y+yd].tunnel then self.room_map[x+xd][y+yd].tunnel = id end
+		if self.map:isBound(x+xd, y+yd) and not self.room_map[x+xd][y+yd].tunnel then self.room_map[x+xd][y+yd].tunnel = id end
 	end
 	if not self.room_map[x][y].tunnel then self.room_map[x][y].tunnel = id end
 end
@@ -160,36 +160,37 @@ function _M:tunnel(x1, y1, x2, y2, id)
 			end
 			nx, ny = x1 + xdir, y1 + ydir
 		end
-		print(feat, "try pos", nx, ny, "dir", coord_to_dir[xdir][ydir])
+--		print(feat, "try pos", nx, ny, "dir", coord_to_dir[xdir][ydir])
 
 		if self.room_map[nx][ny].room then
 			tun[#tun+1] = {nx,ny}
 			x1, y1 = nx, ny
-			print(feat, "accept room")
+--			print(feat, "accept room")
 		elseif self.room_map[nx][ny].can_open ~= nil then
 			if self.room_map[nx][ny].can_open then
-				print(feat, "tunnel crossing can_open", nx,ny)
+--				print(feat, "tunnel crossing can_open", nx,ny)
 				for i = -1, 1 do for j = -1, 1 do if self.map:isBound(nx + i, ny + j) and self.room_map[nx + i][ny + j].can_open then
 					self.room_map[nx + i][ny + j].can_open = false
-					print(feat, "forbiding crossing at ", nx+i,ny+j)
+--					print(feat, "forbiding crossing at ", nx+i,ny+j)
 				end end end
 				tun[#tun+1] = {nx,ny,true}
 				x1, y1 = nx, ny
-				print(feat, "accept can_open")
+--				print(feat, "accept can_open")
 			else
-				print(feat, "reject can_open")
+--				print(feat, "reject can_open")
 			end
 		elseif self.room_map[x1][y1].tunnel then
 			if self.room_map[x1][y1].tunnel ~= id then
 				tun[#tun+1] = {nx,ny}
 				x1, y1 = nx, ny
+--				print(feat, "accept tunnel")
 			else
-				print(feat, "reject tunnel")
+--				print(feat, "reject tunnel")
 			end
 		else
 			tun[#tun+1] = {nx,ny}
 			x1, y1 = nx, ny
-			print(feat, "accept normal")
+--			print(feat, "accept normal")
 		end
 
 		self:markTunnel(x1, y2, xdir, ydir, id)
@@ -201,7 +202,6 @@ function _M:tunnel(x1, y1, x2, y2, id)
 
 	for _, t in ipairs(tun) do
 		local nx, ny = t[1], t[2]
---		self.room_map[nx][ny].tunnel = true
 		if t[3] and self.data.door and rng.percent(self.data.door_chance) then
 			self.map(nx, ny, Map.TERRAIN, self.grid_list[self:resolve("door")])
 		else
@@ -211,7 +211,7 @@ function _M:tunnel(x1, y1, x2, y2, id)
 end
 
 --- Make rooms and connect them with tunnels
-function _M:generate()
+function _M:generate(lev, old_lev)
 	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:resolve("#")])
 	end end
@@ -233,7 +233,29 @@ function _M:generate()
 		tx, ty = rooms[i].cx, rooms[i].cy
 	end
 
-	-- Always starts at 1, 1
-	self.map(rooms[1].cx, rooms[1].cy, Map.TERRAIN, self.up)
-	return rooms[1].cx, rooms[1].cy
+	-- Put down stairs
+	local dx, dy
+	while true do
+		dx, dy = rng.range(1, self.map.w - 1), rng.range(1, self.map.h - 1)
+		if not self.map:checkEntity(dx, dy, Map.TERRAIN, "block_move") and not self.room_map[dx][dy].special then
+			self.map(dx, dy, Map.TERRAIN, self.grid_list[self:resolve("down")])
+			break
+		end
+	end
+
+	-- Put up stairs
+	local ux, uy
+	while true do
+		ux, uy = rng.range(1, self.map.w - 1), rng.range(1, self.map.h - 1)
+		if not self.map:checkEntity(ux, uy, Map.TERRAIN, "block_move") and not self.room_map[ux][uy].special then
+			self.map(ux, uy, Map.TERRAIN, self.grid_list[self:resolve("down")])
+			break
+		end
+	end
+
+	if lev > old_lev then
+		return ux, uy
+	else
+		return dx, dy
+	end
 end
diff --git a/game/engine/generator/map/TileSet.lua b/game/engine/generator/map/TileSet.lua
index 2a6a2cac46..934d15a164 100644
--- a/game/engine/generator/map/TileSet.lua
+++ b/game/engine/generator/map/TileSet.lua
@@ -103,56 +103,14 @@ function _M:findMatchingTiles(st, dir)
 
 	for _, dt in ipairs(self.tiles) do
 		local ok = true
-		print("try match ", st.id, dt.id)
 		if dir == 8 then
-			local sw = #st
-			local dw = #dt
-			print("sw/dw", sw,dw,#st[1],#dt[1])
-			if dw < sw then
-				print("dest 8 smaller")
-				for offset = 0, sw - dw do
-					ok = true
-					for i = 1, dw do
-						print("","try offset",offset,i,"::",st[i+offset] and st[i+offset][1], dt[i] and dt[i][self.block.h])
-						if not st[i+offset] or not dt[i] or not self:matchTile(st[i+offset][1], dt[i][self.block.h]) then ok = false end
-					end
-					print("tried ",offset,"result",ok)
-					if ok then break end
-				end
-			else
-				print("dest 8 bigger")
-				for offset = 0, dw - sw do
-					ok = true
-					for i = 1, sw do
-						print("","try offset",offset,i,"::",st[i] and st[i][1], dt[i+offset] and dt[i+offset][self.block.h])
-						if not st[i] or not dt[i+offset] or not self:matchTile(st[i][1], dt[i+offset][self.block.h]) then ok = false end
-					end
-					print("tried ",offset,"result",ok)
-					if ok then break end
-				end
+			for i = 1, self.block.w do
+				if not self:matchTile(st[i][1], dt[i][self.block.h]) then ok = false end
 			end
 		elseif dir == 2 then
---[[
-			local sw = #st
-			local dw = #dt
-			if dw < sw then
-				print("dest 2 smaller")
-				for offset = 0, sw - dw do
-					for i = offset + 1, offset + dw do
-						if not st[i] or not dt[i] or not self:matchTile(st[i][self.block.h], dt[i][1]) then ok = false end
-					end
-				print("tried ",offset,"result",ok)
-				end
-			else
-				print("dest 2 bigger")
-				for offset = 0, dw - sw do
-					for i = offset + 1, offset + sw do
-						if not self:matchTile(st[i][self.block.h], dt[i][1]) then ok = false end
-					end
-				print("tried ",offset,"result",ok)
-				end
+			for i = 1, self.block.w do
+				if not self:matchTile(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 not self:matchTile(st[1][j], dt[#dt][j]) then ok = false end
diff --git a/game/engine/generator/object/Random.lua b/game/engine/generator/object/Random.lua
index 4087d5b3de..7dd9f9c051 100644
--- a/game/engine/generator/object/Random.lua
+++ b/game/engine/generator/object/Random.lua
@@ -24,8 +24,8 @@ function _M:generate()
 			o:resolve()
 			local x, y = rng.range(0, self.map.w), rng.range(0, self.map.h)
 			local tries = 0
-			while self.map(x, y, Map.OBJECT) and tries < 100 do
-				x, y = rng.range(0, self.map.w), rng.range(0, self.map.h)
+			while (self.map:checkEntity(x, y, Map.TERRAIN, "block_move") or self.map(x, y, Map.OBJECT)) and tries < 100 do
+				x, y = rng.range(0, self.map.w-1), rng.range(0, self.map.h-1)
 				tries = tries + 1
 			end
 			if tries < 100 then
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index a42846189b..b85bda72be 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -104,7 +104,7 @@ function _M:getSaveDescription()
 end
 
 function _M:changeLevel(lev)
-	self.zone:getLevel(self, lev)
+	self.zone:getLevel(self, lev, self.level and self.level.level or -1000)
 	self.player:move(self.level.start.x, self.level.start.y, true)
 	self.level:addEntity(self.player)
 end
diff --git a/game/modules/tome/data/tilesets/dungeon.lua b/game/modules/tome/data/tilesets/dungeon.lua
index ceb647b429..a5624245f7 100644
--- a/game/modules/tome/data/tilesets/dungeon.lua
+++ b/game/modules/tome/data/tilesets/dungeon.lua
@@ -11,11 +11,11 @@ tiles =
 {
 
 {type="tunnel",
-[[#.#]],
-[[#.#]],
-[[#<#]],
-[[#.#]],
-[[#.#]],
+[[##.##]],
+[[##.##]],
+[[##.##]],
+[[##.##]],
+[[##.##]],
 },
 
 {type="tunnel",
@@ -26,12 +26,13 @@ tiles =
 [[##.##]],
 },
 
---[=[
 {type="tunnel",
 {
 [[#####]],
+[[#####]],
 [[.....]],
 [[#####]],
+[[#####]],
 },
 
 {type="tunnel",
@@ -65,8 +66,7 @@ tiles =
 [[##.##]],
 [[##.##]],
 },
-]=]
---[=[
+
 {type="tunnel",
 [[##.##]],
 [[##.##]],
@@ -158,28 +158,4 @@ tiles =
 [[....#]],
 [[#####]],
 },
-]=]
-
---[=[
-{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 b552300185..2febdb7eac 100644
--- a/game/modules/tome/data/zones/ancient_ruins/zone.lua
+++ b/game/modules/tome/data/zones/ancient_ruins/zone.lua
@@ -10,19 +10,9 @@ return {
 		map = {
 			class = "engine.generator.map.Roomer",
 			nb_rooms = 9,
-			rooms = {"simple",},--"pilar"},
+			rooms = {"simple", "pilar"},
 			['.'] = "FLOOR",
 			['#'] = "WALL",
-			['<'] = "UP",
-			['1'] = "1",
-			['2'] = "2",
-			['3'] = "3",
-			['4'] = "4",
-			['5'] = "5",
-			['6'] = "6",
-			['7'] = "7",
-			['8'] = "8",
-			['9'] = "9",
 			up = "UP",
 			down = "DOWN",
 			door = "DOOR",
diff --git a/src/map.c b/src/map.c
index a8e6289ac7..2e6c67020a 100644
--- a/src/map.c
+++ b/src/map.c
@@ -190,7 +190,7 @@ static int map_to_screen(lua_State *L)
 	{
 		for (j = map->my; j < map->my + map->mheight; j++)
 		{
-			if ((i >= map->w) || (j >= map->h)) continue;
+			if ((i < 0) || (j < 0) || (i >= map->w) || (j >= map->h)) continue;
 
 			int dx = x + (i - map->mx) * 16;
 			int dy = y + (j - map->my) * 16;
-- 
GitLab