diff --git a/game/engine/Actor.lua b/game/engine/Actor.lua index a953d5dbf889fd5ddf1c352ebd508e9798af1b2c..313acffd78623a81a9f9d37129fad45356fb5bca 100644 --- a/game/engine/Actor.lua +++ b/game/engine/Actor.lua @@ -13,8 +13,8 @@ function _M:init(t) Entity.init(self, t) end -function _M:move(map, x, y) - if map:checkAllEntity(x, y, "block_move", self) then return true end +function _M:move(map, x, y, force) + if not force and map:checkAllEntities(x, y, "block_move", self) then return true end if self.x and self.y then map:remove(self.x, self.y, Map.ACTOR) diff --git a/game/engine/Level.lua b/game/engine/Level.lua index 4ce8f1280695c65a8d5c8266e31e6bbacd41064b..7a69f842779ad9a575cf09ff34999757561e7c09 100644 --- a/game/engine/Level.lua +++ b/game/engine/Level.lua @@ -1,12 +1,18 @@ require "engine.class" + +--- Define a level module(..., package.seeall, class.make) +--- Initializes the level with a "level" and a map function _M:init(level, map) self.level = level self.map = map self.entities = {} end + +--- Adds an entity to the level +-- Only entities that need to act need to be added. Terrain features do not need this usualy function _M:addEntity(e) if self.entities[e.uid] then error("Entity "..e.uid.." already present on the level") end self.entities[e.uid] = e diff --git a/game/engine/Map.lua b/game/engine/Map.lua index 5c5a4f618b7050f4a961be9dfe1ba8bfec1b82c1..f1256e1f7809937099c0fe39a05e6e480e170aae 100644 --- a/game/engine/Map.lua +++ b/game/engine/Map.lua @@ -5,8 +5,8 @@ local Tiles = require "engine.Tiles" module(..., package.seeall, class.make) TERRAIN = 1 -OBJECT = 10 -ACTOR = 20 +ACTOR = 100 +OBJECT = 1000 displayOrder = { ACTOR, OBJECT, TERRAIN } rememberDisplayOrder = { TERRAIN } @@ -45,7 +45,7 @@ end function _M:call(x, y, pos, entity) if entity then - table.insert(self.map[x + y * self.w], pos, entity) + self.map[x + y * self.w][pos] = entity self.changed = true else if self.map[x + y * self.w] then @@ -149,7 +149,7 @@ function _M:applyLite(x, y) self.remembers[x + y * self.w] = true end -function _M:checkAllEntity(x, y, what, ...) +function _M:checkAllEntities(x, y, what, ...) if x < 0 or x >= self.w or y < 0 or y >= self.h then return end if self.map[x + y * self.w] then for _, e in pairs(self.map[x + y * self.w]) do diff --git a/game/engine/Zone.lua b/game/engine/Zone.lua index 13f97d5fc2dd4fa7b1370009b0a3a78927b612bd..75dca1900690159c0a92e1504f15a607bde3ec8b 100644 --- a/game/engine/Zone.lua +++ b/game/engine/Zone.lua @@ -56,12 +56,16 @@ function _M:getLevel(lev) map:liteAll(0, 0, map.w, map.h) map:rememberAll(0, 0, map.w, map.h) - local floor = self.grid_list.GRASS - local wall = self.grid_list.TREE - - local generator = require(level_data.generator.class).new(map, {0.4, 0.6}, floor, wall) - generator:generate() + local generator = require(level_data.generator.class).new( + map, + self.grid_list[level_data.generator.floor], + self.grid_list[level_data.generator.wall], + self.grid_list[level_data.generator.up], + self.grid_list[level_data.generator.down] + ) + local startx, starty = generator:generate() local level = self.level_class.new(lev, map) + level.start = {x=startx, y=starty} return level end diff --git a/game/engine/generator/BST.lua b/game/engine/generator/BSP.lua similarity index 83% rename from game/engine/generator/BST.lua rename to game/engine/generator/BSP.lua index ff63723527b56c9419f7ae22cab66de039451a9f..6eac8344bbdef1a86d4238cfa7c4aad6fb5ceaad 100644 --- a/game/engine/generator/BST.lua +++ b/game/engine/generator/BSP.lua @@ -4,7 +4,7 @@ module(..., package.seeall, class.inherit(engine.MapGenerator)) function _M:init(map, splitzone, floor, wall) engine.MapGenerator.init(self, map) - self.smallest = 100000 + self.min_dimention = 4 self.tree = {} self.splitzone = splitzone self.floor, self.wall = floor, wall @@ -14,16 +14,18 @@ function _M:split(x, y, w, h) local x1, y1, w1, h1 local x2, y2, w2, h2 local split, dir - if rng.chance(2) then + if w >= self.min_dimention * 2 + 1 and rng.chance(2) then split = rng.range(w * self.splitzone[1], w * self.splitzone[2]) x1, y1, w1, h1 = x, y, split, h x2, y2, w2, h2 = x + split, y, w - split, h - else + elseif h >= self.min_dimention * 2 + 1 then split = rng.range(h * self.splitzone[1], h * self.splitzone[2]) x1, y1, w1, h1 = x, y, w, split x2, y2, w2, h2 = x, y + split, w, h - split -- print(x1, y1, w1, h1) -- print(x2, y2, w2, h2) + else + return nil end return {x1, y1, w1, h1}, {x2, y2, w2, h2} end @@ -52,7 +54,9 @@ function _M:generate() local r1, r2 = self:split(unpack(baser)) - if self:roomSize(r1) <= 40 or self:roomSize(r2) <= 40 or r1[3] < 6 or r1[4] < 6 or r2[3] < 6 or r2[4] < 6 then + if not r1 then + table.insert(process, baser) + elseif self:roomSize(r1) <= 40 or self:roomSize(r2) <= 40 or r1[3] < 6 or r1[4] < 6 or r2[3] < 6 or r2[4] < 6 then table.insert(rooms, r1) table.insert(rooms, r2) else diff --git a/game/engine/generator/Maze.lua b/game/engine/generator/Maze.lua new file mode 100644 index 0000000000000000000000000000000000000000..8ed21fdc9ea43a413b83f347d65f329234161f4e --- /dev/null +++ b/game/engine/generator/Maze.lua @@ -0,0 +1,65 @@ +require "engine.class" +local Map = require "engine.Map" +require "engine.MapGenerator" +module(..., package.seeall, class.inherit(engine.MapGenerator)) + +function _M:init(map, floor, wall, up, down) + engine.MapGenerator.init(self, map) + self.floor, self.wall, self.up, self.down = floor, wall, up, down +end + +function _M:generate() + local backentity = engine.Entity.new{display='*', color_r=128, color_g=128, color_n=128} + + 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 + + local xpos, ypos = 1, 1 + local moves = {{xpos,ypos}} + while #moves > 0 do + local dir = {} + if self.map(xpos+2, ypos, Map.TERRAIN) == self.wall and xpos+2>0 and xpos+2<self.map.w-1 then + dir[#dir+1] = 6 + end + if self.map(xpos-2, ypos, Map.TERRAIN) == self.wall and xpos-2>0 and xpos-2<self.map.w-1 then + dir[#dir+1] = 4 + end + if self.map(xpos, ypos-2, Map.TERRAIN) == self.wall and ypos-2>0 and ypos-2<self.map.h-1 then + dir[#dir+1] = 8 + end + if self.map(xpos, ypos+2, Map.TERRAIN) == self.wall and ypos+2>0 and ypos+2<self.map.h-1 then + dir[#dir+1] = 2 + end + + if #dir > 0 then + local d = dir[rng.range(1, #dir)] + if d == 4 then + self.map(xpos-2, ypos, Map.TERRAIN, self.floor) + self.map(xpos-1, ypos, Map.TERRAIN, self.floor) + xpos = xpos - 2 + elseif d == 6 then + self.map(xpos+2, ypos, Map.TERRAIN, self.floor) + self.map(xpos+1, ypos, Map.TERRAIN, self.floor) + xpos = xpos + 2 + elseif d == 8 then + self.map(xpos, ypos-2, Map.TERRAIN, self.floor) + self.map(xpos, ypos-1, Map.TERRAIN, self.floor) + ypos = ypos - 2 + elseif d == 2 then + self.map(xpos, ypos+2, Map.TERRAIN, self.floor) + self.map(xpos, ypos+1, Map.TERRAIN, self.floor) + ypos = ypos + 2 + end + table.insert(moves, {xpos, ypos}) + else + local back = table.remove(moves) + xpos = back[1] + ypos = back[2] + end + end + -- Always starts at 1, 1 + self.map(1, 1, Map.TERRAIN, self.up) + self.map(math.floor(self.map.w/2)*2-3, math.floor(self.map.h/2)*2-3, Map.TERRAIN, self.up) + return 1, 1 +end diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 2670d91216e57b99521e656368e75b85492282d5..5acd56975f3bc695fc9e52e71c63aae2ded17fa0 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -21,7 +21,7 @@ end function _M:move(x, y, force) local moved = false if force or self.energy.value >= game.energy_to_act then - moved = engine.Actor.move(self, game.level.map, x, y) + moved = engine.Actor.move(self, game.level.map, x, y, force) if not force then self.energy.value = self.energy.value - game.energy_to_act end end return moved diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index ad7342f4f738b3d10826aa713633dfc8b12cb85d..fa4bf14e7b20a1c12182c5859f129afb30850379 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -3,7 +3,6 @@ require "engine.GameTurnBased" require "engine.KeyCommand" require "engine.LogDisplay" local Tooltip = require "engine.Tooltip" -local BST = require "engine.generator.BST" local Zone = require "engine.Zone" local Map = require "engine.Map" local Level = require "engine.Level" @@ -35,14 +34,14 @@ function _M:run() self:setLevel(level) self.player = Player.new{name="player", image='player.png', display='@', color_r=230, color_g=230, color_b=230} - self.player:move(4, 3, true) + self.player:move(level.start.x, level.start.y, true) level:addEntity(self.player) for i = 1, 5 do -- local m = self.npc_list[rng.range(1, 2)]:clone() -- level:addEntity(m) -- local x, y = rng.range(0, map.w), rng.range(0, map.h) --- while map:checkAllEntity(x, y, "block_move") do x, y = rng.range(0, map.w), rng.range(0, map.h) end +-- while map:checkAllEntities(x, y, "block_move") do x, y = rng.range(0, map.w), rng.range(0, map.h) end -- m:move(x, y, true) end @@ -69,7 +68,7 @@ function _M:display() end local mx, my = core.mouse.get() - local tt = self.level.map:checkAllEntity(math.floor(mx / self.level.map.tile_w), math.floor(my / self.level.map.tile_h), "tooltip") + local tt = self.level.map:checkAllEntities(math.floor(mx / self.level.map.tile_w), math.floor(my / self.level.map.tile_h), "tooltip") if tt then self.tooltip:set(tt) local t = self.tooltip:display() diff --git a/game/modules/tome/data/zones/ancient_ruins/grids.lua b/game/modules/tome/data/zones/ancient_ruins/grids.lua index 0a5ffb2ad5d1bc8c6c19cdbac6580663b4decff7..ab41eafcec39dcf178b80bfc78563da374c186b9 100644 --- a/game/modules/tome/data/zones/ancient_ruins/grids.lua +++ b/game/modules/tome/data/zones/ancient_ruins/grids.lua @@ -1,14 +1,24 @@ return { { - define_as = "GRASS", - name = "grass", - display = ".", color_g=255, + define_as = "UP", + name = "previous level", + display = '<', color_r=255, color_g=255, color_b=0, }, { - define_as = "TREE", - name = "tree", - display = "#", color_g=200, + define_as = "DOWN", + name = "next level", + display = '>', color_r=255, color_g=255, color_b=0, +}, +{ + define_as = "FLOOR", + name = "floor", + display = '.', color_r=255, color_g=255, color_b=255, +}, +{ + define_as = "WALL", + name = "wall", + display = '#', color_r=255, color_g=255, color_b=255, block_move = true, block_sight = true, }, diff --git a/game/modules/tome/data/zones/ancient_ruins/zone.lua b/game/modules/tome/data/zones/ancient_ruins/zone.lua index 865da06ebe830e63f8e81b45c1fe2f207049af90..857dc60309721246dc048c53eb6bbc87c43b4a7e 100644 --- a/game/modules/tome/data/zones/ancient_ruins/zone.lua +++ b/game/modules/tome/data/zones/ancient_ruins/zone.lua @@ -1,6 +1,12 @@ return { name = "ancient ruins", max_level = 5, - width = 50, height = 30, - generator = { class= "engine.generator.BST", } + width = 15, height = 25, + generator = { + class= "engine.generator.Maze", + floor = "FLOOR", + wall = "WALL", + up = "UP", + down = "DOWN", + } }