Skip to content
Snippets Groups Projects
Commit 07924bdd authored by dg's avatar dg
Browse files

New "Building" map generator

git-svn-id: http://svn.net-core.org/repos/t-engine4@3327 51575b47-30f0-44d4-a5cc-537603b46e54
parent bd8c270f
No related branches found
No related tags found
No related merge requests found
...@@ -53,7 +53,7 @@ function _M:partition(store) ...@@ -53,7 +53,7 @@ function _M:partition(store)
-- print("[BSP] vertical split", s) -- print("[BSP] vertical split", s)
store.nodes[1] = {depth=store.depth+1, x=0, y=0, rx=store.rx, ry=store.ry, w=store.w, h=s, nodes={}, id=self.node_id} self.node_id = self.node_id + 1 store.nodes[1] = {depth=store.depth+1, x=0, y=0, rx=store.rx, ry=store.ry, w=store.w, h=s, nodes={}, id=self.node_id} self.node_id = self.node_id + 1
store.nodes[2] = {depth=store.depth+1, x=0, y=s, rx=store.rx, ry=store.ry + s, w=store.w, h=store.h - s, nodes={}, id=self.node_id} self.node_id = self.node_id + 1 store.nodes[2] = {depth=store.depth+1, x=0, y=s, rx=store.rx, ry=store.ry + s, w=store.w, h=store.h - s, nodes={}, id=self.node_id} self.node_id = self.node_id + 1
self.splits.vert[store.ry + s] = true self.splits.vert[store.ry + s] = {min=store.rx, max=store.rx+store.w}
self:partition(store.nodes[1]) self:partition(store.nodes[1])
self:partition(store.nodes[2]) self:partition(store.nodes[2])
...@@ -62,7 +62,7 @@ function _M:partition(store) ...@@ -62,7 +62,7 @@ function _M:partition(store)
-- print("[BSP] horizontal split", s) -- print("[BSP] horizontal split", s)
store.nodes[1] = {depth=store.depth+1, x=0, y=0, rx=store.rx, ry=store.ry, w=s, h=store.h, nodes={}, id=self.node_id} self.node_id = self.node_id + 1 store.nodes[1] = {depth=store.depth+1, x=0, y=0, rx=store.rx, ry=store.ry, w=s, h=store.h, nodes={}, id=self.node_id} self.node_id = self.node_id + 1
store.nodes[2] = {depth=store.depth+1, x=s, y=0, rx=store.rx + s, ry=store.ry, w=store.w -s , h=store.h, nodes={}, id=self.node_id} self.node_id = self.node_id + 1 store.nodes[2] = {depth=store.depth+1, x=s, y=0, rx=store.rx + s, ry=store.ry, w=store.w -s , h=store.h, nodes={}, id=self.node_id} self.node_id = self.node_id + 1
self.splits.hor[store.rx + s] = true self.splits.hor[store.rx + s] = {min=store.ry, max=store.ry+store.h}
self:partition(store.nodes[1]) self:partition(store.nodes[1])
self:partition(store.nodes[2]) self:partition(store.nodes[2])
end end
......
-- TE4 - T-Engine 4
-- Copyright (C) 2009, 2010, 2011 Nicolas Casalini
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- Nicolas Casalini "DarkGod"
-- darkgod@te4.org
require "engine.class"
local Map = require "engine.Map"
local BSP = require "engine.BSP"
require "engine.Generator"
local RoomsLoader = require "engine.generator.map.RoomsLoader"
module(..., package.seeall, class.inherit(engine.Generator, RoomsLoader))
function _M:init(zone, map, level, data)
engine.Generator.init(self, zone, map, level)
self.data = data
self.grid_list = self.zone.grid_list
self.max_block_w = data.max_block_w or 20
self.max_block_h = data.max_block_h or 20
self.max_building_w = data.max_building_w or 7
self.max_building_h = data.max_building_h or 7
RoomsLoader.init(self, data)
end
function _M:building(leaf, spots)
-- local x1, x2 = leaf.rx + rng.range(2, math.max(2, math.floor(leaf.w / 2 - 3))), leaf.rx + leaf.w - rng.range(2, math.max(2, math.floor(leaf.w / 2 - 3)))
-- local y1, y2 = leaf.ry + rng.range(2, math.max(2, math.floor(leaf.h / 2 - 3))), leaf.ry + leaf.h - rng.range(2, math.max(2, math.floor(leaf.h / 2 - 3)))
local x1, x2 = leaf.rx, leaf.rx + leaf.w
local y1, y2 = leaf.ry, leaf.ry + leaf.h
local ix1, ix2, iy1, iy2 = x1 + 2, x2 - 1, y1 + 2, y2 - 1
local inner_grids = {}
local door_grids = {}
local is_lit = rng.percent(self.data.lite_room_chance or 70)
for i = leaf.rx, leaf.rx + leaf.w do for j = leaf.ry, leaf.ry + leaf.h do
-- Abort if there is something already
if self.map:isBound(i, j) and self.map.room_map[i][j].room then return end
end end
for i = x1, x2 do for j = y1, y2 do
if i == x1 or i == x2 or j == y1 or j == y2 then
if not self.map.room_map[i][j].walled then self.map(i, j, Map.TERRAIN, self:resolve("wall")) end
self.map.room_map[i][j].walled = true
if not (i == x1 and j == y1) and not (i == x1 and j == y2) and not (i == x2 and j == y1) and not (i == x2 and j == y2) then
door_grids[#door_grids+1] = {x=i,y=j}
end
else
self.map(i, j, Map.TERRAIN, self:resolve("floor"))
if is_lit then self.map.lites(i, j, true) end
if i >= ix1 and i <= ix2 and j >= iy1 and j <= iy2 then
inner_grids[#inner_grids+1] = {x=i,y=j}
end
end
end end
-- Door
local door = rng.table(door_grids)
self.map(door.x, door.y, Map.TERRAIN, self:resolve("door"))
-- Eliminate inner grids that face the door
for i = #inner_grids, 1, -1 do
local g = inner_grids[i]
if g.x == door.x or g.y == door.y then table.remove(inner_grids, i) end
end
spots[#spots+1] = {x=math.floor((x1+x2)/2), y=math.floor((y1+y2)/2), type="building", subtype="building"}
end
function _M:block(leaf, spots)
local x1, x2 = leaf.rx, leaf.rx + leaf.w
local y1, y2 = leaf.ry, leaf.ry + leaf.h
local ix1, ix2, iy1, iy2 = x1 + 2, x2 - 1, y1 + 2, y2 - 1
local inner_grids = {}
local door_grids = {}
for i = leaf.rx, leaf.rx + leaf.w do for j = leaf.ry, leaf.ry + leaf.h do
-- Abort if there is something already
if self.map:isBound(i, j) and self.map.room_map[i][j].room then return end
end end
local door_grids = {}
for i = x1, x2 do for j = y1, y2 do
if i == x1 or i == x2 or j == y1 or j == y2 then
self.map(i, j, Map.TERRAIN, self:resolve("floor"))
elseif (i == x1+1 or i == x2-1 or j == y1+1 or j == y2-1) and
not (i == x1+1 and j == y1+1) and not (i == x1+1 and j == y2-1) and not (i == x2-1 and j == y1+1) and not (i == x2-1 and j == y2-1) then
door_grids[#door_grids+1] = {x=i,y=j}
end
end end
-- Door
local door = rng.table(door_grids)
self.map(door.x, door.y, Map.TERRAIN, self:resolve("door"))
local bsp = BSP.new(leaf.w-2, leaf.h-2, self.max_building_w, self.max_building_h)
bsp:partition()
print("Building gen made ", #bsp.leafs, "building BSP leafs")
for z, sleaf in ipairs(bsp.leafs) do
sleaf.rx = sleaf.rx + leaf.rx + 1
sleaf.ry = sleaf.ry + leaf.ry + 1
self:building(sleaf, spots)
end
end
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:resolve("wall"))
end end
local spots = {}
self.spots = spots
local bsp = BSP.new(self.map.w, self.map.h, self.max_block_w, self.max_block_h)
bsp:partition()
print("Building gen made ", #bsp.leafs, "blocks BSP leafs")
for z, leaf in ipairs(bsp.leafs) do
self:block(leaf, spots)
end
local ux, uy, dx, dy
if self.data.edge_entrances then
ux, uy, dx, dy, spots = self:makeStairsSides(lev, old_lev, self.data.edge_entrances, spots)
else
ux, uy, dx, dy, spots = self:makeStairsInside(lev, old_lev, spots)
end
return ux, uy, dx, dy, spots
end
--- Create the stairs inside the level
function _M:makeStairsInside(lev, old_lev, spots)
-- Put down stairs
local dx, dy
if lev < self.zone.max_level or self.data.force_last_stair then
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.map.room_map[dx][dy].special then
self.map(dx, dy, Map.TERRAIN, self:resolve("down"))
self.map.room_map[dx][dy].special = "exit"
break
end
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.map.room_map[ux][uy].special then
self.map(ux, uy, Map.TERRAIN, self:resolve("up"))
self.map.room_map[ux][uy].special = "exit"
break
end
end
return ux, uy, dx, dy, spots
end
--- Create the stairs on the sides
function _M:makeStairsSides(lev, old_lev, sides, spots)
-- Put down stairs
local dx, dy
if lev < self.zone.max_level or self.data.force_last_stair then
while true do
if sides[2] == 4 then dx, dy = 0, rng.range(0, self.map.h - 1)
elseif sides[2] == 6 then dx, dy = self.map.w - 1, rng.range(0, self.map.h - 1)
elseif sides[2] == 8 then dx, dy = rng.range(0, self.map.w - 1), 0
elseif sides[2] == 2 then dx, dy = rng.range(0, self.map.w - 1), self.map.h - 1
end
if not self.map.room_map[dx][dy].special then
self.map(dx, dy, Map.TERRAIN, self:resolve("down"))
self.map.room_map[dx][dy].special = "exit"
break
end
end
end
-- Put up stairs
local ux, uy
while true do
if sides[1] == 4 then ux, uy = 0, rng.range(0, self.map.h - 1)
elseif sides[1] == 6 then ux, uy = self.map.w - 1, rng.range(0, self.map.h - 1)
elseif sides[1] == 8 then ux, uy = rng.range(0, self.map.w - 1), 0
elseif sides[1] == 2 then ux, uy = rng.range(0, self.map.w - 1), self.map.h - 1
end
if not self.map.room_map[ux][uy].special then
self.map(ux, uy, Map.TERRAIN, self:resolve("up"))
self.map.room_map[ux][uy].special = "exit"
break
end
end
return ux, uy, dx, dy, spots
end
...@@ -27,10 +27,13 @@ local ActorAI = require "engine.interface.ActorAI" ...@@ -27,10 +27,13 @@ local ActorAI = require "engine.interface.ActorAI"
local ActorLevel = require "engine.interface.ActorLevel" local ActorLevel = require "engine.interface.ActorLevel"
local ActorTemporaryEffects = require "engine.interface.ActorTemporaryEffects" local ActorTemporaryEffects = require "engine.interface.ActorTemporaryEffects"
local Birther = require "engine.Birther" local Birther = require "engine.Birther"
local UIBase = require "engine.ui.Base"
local n = core.noise.new(2) local n = core.noise.new(2)
_2DNoise = n:makeTexture2D(64, 64) _2DNoise = n:makeTexture2D(64, 64)
UIBase:setTextShadow(0.6)
-- Usefull keybinds -- Usefull keybinds
KeyBind:load("move,hotkeys,inventory,actions,interface,debug") KeyBind:load("move,hotkeys,inventory,actions,interface,debug")
......
...@@ -934,10 +934,10 @@ function _M:setupCommands() ...@@ -934,10 +934,10 @@ function _M:setupCommands()
print((" [ [[\n%d%d%d\n%d %d\n%d%d%d]] ] = '',"):format(g7,g8,g9,g4,g6,g1,g2,g3)) print((" [ [[\n%d%d%d\n%d %d\n%d%d%d]] ] = '',"):format(g7,g8,g9,g4,g6,g1,g2,g3))
end end, end end,
[{"_g","ctrl"}] = function() if config.settings.cheat then [{"_g","ctrl"}] = function() if config.settings.cheat then
-- self.state:debugRandomZone() self.state:debugRandomZone()
-- local m = game.zone:makeEntity(game.level, "actor", {random_boss=true}, nil, true) -- local m = game.zone:makeEntity(game.level, "actor", {random_boss=true}, nil, true)
-- if m then game.zone:addEntity(game.level, m, "actor", game.player.x, game.player.y + 1) end -- if m then game.zone:addEntity(game.level, m, "actor", game.player.x, game.player.y + 1) end
self:changeLevel(1, "test") -- self:changeLevel(1, "test")
end end, end end,
} }
......
...@@ -1049,6 +1049,19 @@ local random_zone_layouts = { ...@@ -1049,6 +1049,19 @@ local random_zone_layouts = {
door = data:getDoor(), door = data:getDoor(),
["'"] = data:getDoor(), ["'"] = data:getDoor(),
} end }, } end },
-- Building
{ name="building", rarity=1, gen=function(data)
return {
class = "engine.generator.map.Building",
lite_room_chance = rng.range(0, 100),
max_block_w = rng.range(14, 20), max_block_h = rng.range(14, 20),
max_building_w = rng.range(4, 8), max_building_h = rng.range(4, 8),
floor = data:getFloor(),
wall = data:getWall(),
up = data:getUp(),
down = data:getDown(),
door = data:getDoor(),
} end },
} }
local random_zone_themes = { local random_zone_themes = {
...@@ -1169,7 +1182,7 @@ function _M:createRandomZone(zbase) ...@@ -1169,7 +1182,7 @@ function _M:createRandomZone(zbase)
end end
end end
local base = rng.table(list) local base = rng.table(list)
local boss, boss_id = self:createRandomBoss(base, data.min_lev + data.depth + rng.range(2, 4)) local boss, boss_id = self:createRandomBoss(base, {level=data.min_lev + data.depth + rng.range(2, 4)})
npcs[boss_id] = boss npcs[boss_id] = boss
------------------------------------------------------------ ------------------------------------------------------------
...@@ -1379,15 +1392,15 @@ function _M:debugRandomZone() ...@@ -1379,15 +1392,15 @@ function _M:debugRandomZone()
local zone = self:createRandomZone() local zone = self:createRandomZone()
game:changeLevel(zone.max_level, zone) game:changeLevel(zone.max_level, zone)
game.level.map:liteAll(0, 0, game.level.map.w, game.level.map.h) game.level.map:liteAll(0, 0, game.level.map.w, game.level.map.h)
game.level.map:rememberAll(0, 0, game.level.map.w, game.level.map.h) game.level.map:rememberAll(0, 0, game.level.map.w, game.level.map.h)
for i = 0, game.level.map.w - 1 do for i = 0, game.level.map.w - 1 do
for j = 0, game.level.map.h - 1 do for j = 0, game.level.map.h - 1 do
local trap = game.level.map(i, j, game.level.map.TRAP) local trap = game.level.map(i, j, game.level.map.TRAP)
if trap then if trap then
trap:setKnown(game.player, true) trap:setKnown(game.player, true)
game.level.map:updateMap(i, j) game.level.map:updateMap(i, j)
end
end end
end end
end
end end
...@@ -32,6 +32,7 @@ return { ...@@ -32,6 +32,7 @@ return {
generator = { generator = {
map = { map = {
class = "engine.generator.map.Building", class = "engine.generator.map.Building",
max_block_w = 15, max_block_h = 15,
max_building_w = 5, max_building_h = 5, max_building_w = 5, max_building_h = 5,
floor = "FLOOR", floor = "FLOOR",
external_floor = "FLOOR", external_floor = "FLOOR",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment