diff --git a/game/engine/Actor.lua b/game/engine/Actor.lua index f775c3f900bc358f3ec37f964ba33552df319637..4c870ac89b8da9976731fda5a91a38aa1b5a63ef 100644 --- a/game/engine/Actor.lua +++ b/game/engine/Actor.lua @@ -56,6 +56,7 @@ end --- Can the actor go there -- @param terrain_only if true checks only the terrain, otherwise checks all entities function _M:canMove(x, y, terrain_only) + if not game.level.map:isBound(x, y) then return false end if terrain_only then return not game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move") else diff --git a/game/engine/generator/actor/Random.lua b/game/engine/generator/actor/Random.lua index 17d2961d13fcebc6cd1951eddaf6e0e0881b3e02..a47e17a5101bcc8025149edf715e6b2cc616193b 100644 --- a/game/engine/generator/actor/Random.lua +++ b/game/engine/generator/actor/Random.lua @@ -7,8 +7,8 @@ function _M:init(zone, map, level) engine.Generator.init(self, map) self.zone = zone self.level = level - local data = level.data - self.npc_list = zone:computeRarities(zone.npc_list, level.level, data.generator and data.generator.actor and data.generator.actor.ood, nil) + local data = level.data.generator.actor + self.npc_list = zone:computeRarities(zone.npc_list, level.level, data.ood, nil) if data.adjust_level_to_player and game:getPlayer() then self.adjust_level_to_player = {base=game:getPlayer().level, min=data.adjust_level_to_player[1], max=data.adjust_level_to_player[2]} end diff --git a/game/engine/generator/map/Roomer.lua b/game/engine/generator/map/Roomer.lua index 9530aee1f654ead61d8986969d0afb49060c0bdd..ae24f87cedad4a3dee58834c7d2e08a7a1cd3183 100644 --- a/game/engine/generator/map/Roomer.lua +++ b/game/engine/generator/map/Roomer.lua @@ -8,7 +8,7 @@ function _M:init(map, grid_list, data) self.data = data self.data.tunnel_change = self.data.tunnel_change or 30 self.data.tunnel_random = self.data.tunnel_random or 10 - self.data.tunnel_premature_end = self.data.tunnel_premature_end or 10 + self.data.door_chance = self.data.door_chance or 50 self.grid_list = grid_list self.rooms = {} @@ -60,6 +60,7 @@ function _M:resolve(c) end end +--- Make up a room function _M:roomAlloc(room, id) print("alloc", room.name) @@ -83,6 +84,7 @@ function _M:roomAlloc(room, id) self.room_map[i-1+x][j-1+y].room = id local c = room[i][j] if c == '!' then + self.room_map[i-1+x][j-1+y].room = nil self.room_map[i-1+x][j-1+y].can_open = true self.map(i-1+x, j-1+y, Map.TERRAIN, self.grid_list[self:resolve('#')]) else @@ -98,12 +100,14 @@ function _M:roomAlloc(room, id) return false end +--- Random tunnel dir function _M:randDir() local dirs = {4,6,8,2} local d = dir_to_coord[dirs[rng.range(1, #dirs)]] return d[1], d[2] end +--- Find the direction in which to tunnel function _M:tunnelDir(x1, y1, x2, y2) local xdir = (x1 == x2) and 0 or ((x1 < x2) and 1 or -1) local ydir = (y1 == y2) and 0 or ((y1 < y2) and 1 or -1) @@ -115,7 +119,24 @@ function _M:tunnelDir(x1, y1, x2, y2) return xdir, ydir end -function _M:tunnel(x1, y1, x2, y2) +local mark_dirs = { + [4] = {9,6,3}, + [6] = {7,4,1}, + [8] = {1,2,3}, + [2] = {7,8,9}, +} +--- Marks a tunnel as a tunnel and the space behind it +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 + end + if not self.room_map[x][y].tunnel then self.room_map[x][y].tunnel = id end +end + +--- Tunnel from x1,y1 to x2,y2 +function _M:tunnel(x1, y1, x2, y2, id) local xdir, ydir = self:tunnelDir(x1, y1, x2, y2) print("tunneling from",x1, y1, "to", x2, y2, "initial dir", xdir, ydir) @@ -125,38 +146,55 @@ function _M:tunnel(x1, y1, x2, y2) local tries = 2000 while tries > 0 do if rng.percent(self.data.tunnel_change) then - if rng.percent(self.data.tunnel_random) then - xdir, ydir = self:randDir() - else - xdir, ydir = self:tunnelDir(x1, y1, x2, y2) + if rng.percent(self.data.tunnel_random) then xdir, ydir = self:randDir() + else xdir, ydir = self:tunnelDir(x1, y1, x2, y2) end end local nx, ny = x1 + xdir, y1 + ydir while true do - if self.map:isBound(nx, ny) and (self.room_map[nx][ny].room or not self.room_map[nx][ny].tunnel) then break end + if self.map:isBound(nx, ny) then break end - if rng.percent(self.data.tunnel_random) then - xdir, ydir = self:randDir() - else - xdir, ydir = self:tunnelDir(x1, y1, x2, y2) + if rng.percent(self.data.tunnel_random) then xdir, ydir = self:randDir() + else xdir, ydir = self:tunnelDir(x1, y1, x2, y2) end nx, ny = x1 + xdir, y1 + ydir end + print(feat, "try pos", nx, ny, "dir", coord_to_dir[xdir][ydir]) - if self.room_map[nx][ny].room and not self.room_map[nx][ny].can_open then - else - for i = -1, 1 do for j = -1, 1 do - if self.map:isBound(nx + i, ny + j) then + if self.room_map[nx][ny].room then + tun[#tun+1] = {nx,ny} + x1, y1 = nx, ny + 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) + 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 - end - end end - + 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") + else + 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 + else + print(feat, "reject tunnel") + end + else tun[#tun+1] = {nx,ny} + x1, y1 = nx, ny + print(feat, "accept normal") end - x1, y1 = nx, ny - if x1 == x2 and y1 == y2 then break end + self:markTunnel(x1, y2, xdir, ydir, id) + + if x1 == x2 and y1 == y2 then print(feat, "done") break end tries = tries - 1 end @@ -164,16 +202,21 @@ function _M:tunnel(x1, y1, x2, y2) for _, t in ipairs(tun) do local nx, ny = t[1], t[2] -- self.room_map[nx][ny].tunnel = true - self.map(nx, ny, Map.TERRAIN, self.grid_list[self:resolve("<")]) + 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 + self.map(nx, ny, Map.TERRAIN, self.grid_list[self:resolve('.')]) + end end end +--- Make rooms and connect them with tunnels 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:resolve("#")]) end end - local nb_room = 10 + local nb_room = self.data.nb_rooms or 10 local rooms = {} while nb_room > 0 do local r = self:roomAlloc(self.rooms[rng.range(1, #self.rooms)], #rooms+1) @@ -184,12 +227,13 @@ function _M:generate() -- Tunnels ! print("Begin tunnel", #rooms, rooms[1]) local tx, ty = rooms[1].cx, rooms[1].cy - for i = 2, #rooms do - self:tunnel(tx, ty, rooms[i].cx, rooms[i].cy) + for ii = 2, #rooms + 1 do + local i = util.boundWrap(ii, 1, #rooms) + self:tunnel(tx, ty, rooms[i].cx, rooms[i].cy, rooms[i].id) tx, ty = rooms[i].cx, rooms[i].cy end -- Always starts at 1, 1 - self.map(1, 1, Map.TERRAIN, self.up) - return 1, 1 + self.map(rooms[1].cx, rooms[1].cy, Map.TERRAIN, self.up) + return rooms[1].cx, rooms[1].cy end diff --git a/game/modules/tome/data/rooms/simple.lua b/game/modules/tome/data/rooms/simple.lua index fc78931335db48bf7c13f0028360fc50698dfc2b..d538564f09bf5d5d8e9dbe30ffa0dd8a31c0577b 100644 --- a/game/modules/tome/data/rooms/simple.lua +++ b/game/modules/tome/data/rooms/simple.lua @@ -1,3 +1,21 @@ +--[[ +return function(self, gen) + return { name=self.name, w = rng.range(6, 15), h = rng.range(6, 15), generator = function(self, gen, x, y, id) + for i = 1, self.w do + for j = 1, self.h do + gen.room_map[i-1+x][j-1+y].room = id + if i == 1 or i == self.w or j == 1 or j == self.h then + gen.room_map[i-1+x][j-1+y].can_open = true + gen.map(i-1+x, j-1+y, Map.TERRAIN, gen.grid_list[gen:resolve('#')]) + else + gen.map(i-1+x, j-1+y, Map.TERRAIN, gen.grid_list[gen:resolve('.')]) + end + end + end + end} +end +-- ]] +-- [=[ return { [[#!!!!!!!!!!#]], [[!..........!]], @@ -7,3 +25,4 @@ return { [[!..........!]], [[#!!!!!!!!!!#]], } +-- ]=] diff --git a/game/modules/tome/data/zones/ancient_ruins/grids.lua b/game/modules/tome/data/zones/ancient_ruins/grids.lua index 27e1303b2a96004b8f510e020ac7fae34d8722f0..6f57264915caceb09704393c94cf4614ce15fa88 100644 --- a/game/modules/tome/data/zones/ancient_ruins/grids.lua +++ b/game/modules/tome/data/zones/ancient_ruins/grids.lua @@ -43,3 +43,49 @@ newEntity{ block_sight = false, door_closed = "DOOR", } + +newEntity{ + define_as = "1", + name = "1", + display = '1', color_r=255, color_g=255, color_b=0, +} +newEntity{ + define_as = "2", + name = "2", + display = '2', color_r=255, color_g=255, color_b=0, +} +newEntity{ + define_as = "3", + name = "3", + display = '3', color_r=255, color_g=255, color_b=0, +} +newEntity{ + define_as = "4", + name = "4", + display = '4', color_r=255, color_g=255, color_b=0, +} +newEntity{ + define_as = "5", + name = "5", + display = '5', color_r=255, color_g=255, color_b=0, +} +newEntity{ + define_as = "6", + name = "6", + display = '6', color_r=255, color_g=255, color_b=0, +} +newEntity{ + define_as = "7", + name = "7", + display = '7', color_r=255, color_g=255, color_b=0, +} +newEntity{ + define_as = "8", + name = "8", + display = '8', color_r=255, color_g=255, color_b=0, +} +newEntity{ + define_as = "9", + name = "9", + display = '9', color_r=255, color_g=255, color_b=0, +} diff --git a/game/modules/tome/data/zones/ancient_ruins/zone.lua b/game/modules/tome/data/zones/ancient_ruins/zone.lua index 13c29e2b696979dd4ba928617c62e8ebd06d697b..b5523001852edb3fcc68e59646bb29bd60ad7fe0 100644 --- a/game/modules/tome/data/zones/ancient_ruins/zone.lua +++ b/game/modules/tome/data/zones/ancient_ruins/zone.lua @@ -9,23 +9,33 @@ return { generator = { map = { class = "engine.generator.map.Roomer", - rooms = {"simple","pilar"}, + nb_rooms = 9, + 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 = "DOOR", }, actor = { class = "engine.generator.actor.Random", - nb_npc = {40, 40}, + nb_npc = {1, 1}, ood = {chance=5, range={1, 10}}, adjust_level_to_player = {-1, 2}, }, object = { class = "engine.generator.object.Random", - nb_object = {10, 10}, + nb_object = {1, 1}, ood = {chance=5, range={1, 10}}, }, }