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