diff --git a/game/engine/Astar.lua b/game/engine/Astar.lua index fa87eafaa07711c73228194b6a13b1ad0f8abe64..b1b2523d97732db1f350f661357720dd232323a3 100644 --- a/game/engine/Astar.lua +++ b/game/engine/Astar.lua @@ -30,9 +30,18 @@ function _M:init(map, actor) self.move_cache = {} end ---- The default heuristic for A*, simple distance -function _M:heuristic(sx, sy, tx, ty) - return core.fov.distance(sx, sy, tx, ty) +--- The default heuristic for A*, tries to come close to the straight path +function _M:heuristicCloserPath(sx, sy, cx, cy, tx, ty) + local dx1 = cx - tx + local dy1 = cy - ty + local dx2 = sx - tx + local dy2 = sy - ty + return math.abs(dx1*dy2 - dx2*dy1) +end + +--- The a simple heuristic for A*, using distance +function _M:heuristicDistance(sx, sy, cx, cy, tx, ty) + return core.fov.distance(cx, cy, tx, ty) end function _M:toSingle(x, y) @@ -62,15 +71,16 @@ end -- @param ty the end coord -- @param use_has_seen if true the astar wont consider non-has_seen grids -- @return either nil if no path or a list of nodes in the form { {x=...,y=...}, {x=...,y=...}, ..., {x=tx,y=ty}} -function _M:calc(sx, sy, tx, ty, use_has_seen) +function _M:calc(sx, sy, tx, ty, use_has_seen, heuristic) + local heur = heuristic or self.heuristicCloserPath local w, h = self.map.w, self.map.h local start = self:toSingle(sx, sy) local stop = self:toSingle(tx, ty) local open = {[start]=true} local closed = {} local g_score = {[start] = 0} - local h_score = {[start] = self:heuristic(sx, sy, tx, ty)} - local f_score = {[start] = self:heuristic(sx, sy, tx, ty)} + local h_score = {[start] = heur(self, sx, sy, sx, sy, tx, ty)} + local f_score = {[start] = heur(self, sx, sy, sx, sy, tx, ty)} local came_from = {} local cache = self.map._fovcache.path_caches[self.actor:getPathString()] @@ -88,7 +98,7 @@ function _M:calc(sx, sy, tx, ty, use_has_seen) if tent_is_better then came_from[nnode] = node g_score[nnode] = tent_g_score - h_score[nnode] = self:heuristic(tx, ty, nx, ny) + h_score[nnode] = heur(self, sx, sy, tx, ty, nx, ny) f_score[nnode] = g_score[nnode] + h_score[nnode] end end @@ -106,7 +116,7 @@ function _M:calc(sx, sy, tx, ty, use_has_seen) if tent_is_better then came_from[nnode] = node g_score[nnode] = tent_g_score - h_score[nnode] = self:heuristic(tx, ty, nx, ny) + h_score[nnode] = heur(self, sx, sy, tx, ty, nx, ny) f_score[nnode] = g_score[nnode] + h_score[nnode] end end diff --git a/game/engine/BSP.lua b/game/engine/BSP.lua new file mode 100644 index 0000000000000000000000000000000000000000..0fbfd520d855d4f8e4feaf66e5049c4e470427b3 --- /dev/null +++ b/game/engine/BSP.lua @@ -0,0 +1,68 @@ +-- TE4 - T-Engine 4 +-- Copyright (C) 2009, 2010 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" + +--- Abstract binary space partionning +-- Can be used to generator levels and so on +module(..., package.seeall, class.make) + +function _M:init(w, h, min_w, min_h, max_depth) + self.max_depth = max_depth or 8 + self.min_w, self.min_h = min_w, min_h + self.node_id = 1 + self.leafs = {} + self.bsp = {x=0, y=0, rx=0, ry=0, w=w, h=h, nodes={}, id=0, depth=0} + print("[BSP] ", w, h) +end + +function _M:partition(store) + store = store or self.bsp + + local split_vert, split_hor = false, false + if store.w >= self.min_w * 2 then split_hor = true end + if store.h >= self.min_h * 2 then split_vert = true end + print("[BSP] "..store.id.." partitioning", store.rx, store.ry, "::", store.w, store.h, " splits ", split_hor, split_vert) + + if split_vert and split_hor then + local ok = rng.percent(50) + split_vert, split_hor = ok, not ok + end + + if store.depth > self.max_depth then split_vert, split_hor = false, false end + + if split_vert and not split_hor then + local s = rng.range(self.min_h, store.h - self.min_h) +-- 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[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:partition(store.nodes[1]) + self:partition(store.nodes[2]) + + elseif not split_vert and split_hor then + local s = rng.range(self.min_w, store.w - self.min_w) +-- 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[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:partition(store.nodes[1]) + self:partition(store.nodes[2]) + end + + if #store.nodes == 0 then self.leafs[#self.leafs+1] = store end +end diff --git a/game/engine/generator/map/Cavern.lua b/game/engine/generator/map/Cavern.lua index ce221308c0702320df0e0404775ea1d261476d2f..2b0d4f68766988504d4a6777ddc9b618c43a1b9d 100644 --- a/game/engine/generator/map/Cavern.lua +++ b/game/engine/generator/map/Cavern.lua @@ -55,7 +55,7 @@ function _M:generate(lev, old_lev) opens[i] = {} for j = 0, self.map.h - 1 do if noise[self.noise](noise, self.zoom * i / self.map.w, self.zoom * j / self.map.h, self.octave) > 0 then - self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("floor")]:clone()) + self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("floor")]) opens[i][j] = #list+1 list[#list+1] = {x=i, y=j} else diff --git a/game/engine/generator/map/Forest.lua b/game/engine/generator/map/Forest.lua index 6b46c8d3ea4dbbe2dc258a86489ee9307a11cb26..4b3919365c49b2f61be97a1d79246f32ae2fb54e 100644 --- a/game/engine/generator/map/Forest.lua +++ b/game/engine/generator/map/Forest.lua @@ -48,7 +48,7 @@ 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.grid_list[self.floor]) + self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("floor")]) end end -- make the noise diff --git a/game/engine/generator/map/Town.lua b/game/engine/generator/map/Town.lua new file mode 100644 index 0000000000000000000000000000000000000000..d9a3c17220bb1163dd9f435b10ebc89299265fc0 --- /dev/null +++ b/game/engine/generator/map/Town.lua @@ -0,0 +1,214 @@ +-- TE4 - T-Engine 4 +-- Copyright (C) 2009, 2010 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" +module(..., package.seeall, class.inherit(engine.Generator)) + +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_building_w = data.max_building_w or 12 + self.max_building_h = data.max_building_h or 12 + self.building_chance = data.building_chance or 85 + self.lshape_chance = data.lshape_chance or 50 + self.double_lshape_chance = data.double_lshape_chance or 40 + self.yard_chance = data.yard_chance or 30 +end + +function _M:resolve(c) + local res = self.data[c] + if type(res) == "function" then + return res() + elseif type(res) == "table" then + return res[rng.range(1, #res)] + else + return res + end +end + +function _M:Lshape(inner_grids, x1, x2, y1, y2, ix1, ix2, iy1, iy2) + if #inner_grids == 0 then return end + local door_grids = {} + local void = rng.percent(self.yard_chance) + local point = rng.tableRemove(inner_grids) + local dx1, dx2 = math.abs(point.x - ix1), math.abs(point.x - ix2) + local dy1, dy2 = math.abs(point.y - iy1), math.abs(point.y - iy2) + if dx1 == dx2 then if rng.percent(50) then dx1 = dx1 + 1 else dx2 = dx2 + 1 end end + if dy1 == dy2 then if rng.percent(50) then dy1 = dy1 + 1 else dy2 = dy2 + 1 end end + print("room", dx1, dx2, "::", dy1, dy2) + + if dx2 > dx1 and dy2 > dy1 then + for i = point.x, x2 do door_grids[#door_grids+1] = {x=i,y=point.y} self.map(i, point.y, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end + for j = point.y, y2 do door_grids[#door_grids+1] = {x=point.x,y=j} self.map(point.x, j, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end + for i = point.x+1, x2 do for j = point.y+1, y2 do if void then self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("external_floor")]) end end end + elseif dx1 > dx2 and dy2 > dy1 then + for i = x1, point.x do door_grids[#door_grids+1] = {x=i,y=point.y} self.map(i, point.y, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end + for j = point.y, y2 do door_grids[#door_grids+1] = {x=point.x,y=j} self.map(point.x, j, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end + for i = x1, point.x-1 do for j = point.y+1, y2 do if void then self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("external_floor")]) end end end + elseif dx1 > dx2 and dy1 > dy2 then + for i = x1, point.x do door_grids[#door_grids+1] = {x=i,y=point.y} self.map(i, point.y, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end + for j = y1, point.y do door_grids[#door_grids+1] = {x=point.x,y=j} self.map(point.x, j, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end + for i = x1, point.x-1 do for j = y1, point.y-1 do if void then self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("external_floor")]) end end end + elseif dx2 > dx1 and dy1 > dy2 then + for i = point.x, x2 do door_grids[#door_grids+1] = {x=i,y=point.y} self.map(i, point.y, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end + for j = y1, point.y do door_grids[#door_grids+1] = {x=point.x,y=j} self.map(point.x, j, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end + for i = point.x+1, x2 do for j = y1, point.y-1 do if void then self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("external_floor")]) end end end + end + + -- Door + if #door_grids > 0 then + local door = rng.table(door_grids) + self.map(door.x, door.y, Map.TERRAIN, self.grid_list[self:resolve("door")]) + end +end + +function _M:building(leaf) + 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 ix1, ix2, iy1, iy2 = x1 + 2, x2 - 2, y1 + 2, y2 - 2 + local inner_grids = {} + 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.grid_list[self:resolve("wall")]) + door_grids[#door_grids+1] = {x=i,y=j} + else + self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("floor")]) + 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.grid_list[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 + + -- L shape + if rng.percent(self.lshape_chance) then + self:Lshape(inner_grids, x1, x2, y1, y2, ix1, ix2, iy1, iy2) + end +-- if rng.percent(self.lshape_chance) then +-- self:Lshape(inner_grids, x1, x2, y1, y2, ix1, ix2, iy1, iy2) +-- 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.grid_list[self:resolve("external_floor")]) + end end + + local bsp = BSP.new(self.map.w, self.map.h, self.max_building_w, self.max_building_h) + bsp:partition() + + print("Town gen made ", #bsp.leafs, "BSP leafs") + for z, leaf in ipairs(bsp.leafs) do + if rng.percent(self.building_chance) then + self:building(leaf) + end + end + + local spots = {} + 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.grid_list[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.grid_list[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.grid_list[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.grid_list[self:resolve("up")]) + self.map.room_map[ux][uy].special = "exit" + break + end + end + + return ux, uy, dx, dy, spots +end diff --git a/game/modules/tome/data/birth/races/orc.lua b/game/modules/tome/data/birth/races/orc.lua index e9151e703a755c78e81140422838e6af3328c9db..0770897ffc0c1519abce9432cbc5c2c06201b176 100644 --- a/game/modules/tome/data/birth/races/orc.lua +++ b/game/modules/tome/data/birth/races/orc.lua @@ -24,7 +24,9 @@ newBirthDescriptor{ type = "race", name = "Orc", desc = { - "", + "Since their creation by Morgoth the Orcs have been the pawns of the forces of darkness.", + "While both Sauron and Morgoth were destroy, the orcs survived and found a new master in the Far East.", + "Orcs are a ruthless warriors, yet they are not dumb and some are terribly cunning.", }, descriptor_choices = { @@ -38,25 +40,29 @@ newBirthDescriptor{ __ALL__ = "never", Male = "allow", }, + class = + { + Mage = "never", + }, }, - stats = { str=4, con=3, wil=3, mag=-2, dex=-2 }, + stats = { str=4, con=1, wil=2, mag=-2, dex=-2 }, talents = { --- [ActorTalents.T_DWARF_RESILIENCE]=1, + [ActorTalents.T_ORC_FURY]=1, }, copy = { type = "humanoid", subtype="orc", - default_wilderness = {39, 17}, - starting_zone = "tower-amon-sul", + default_wilderness = {10, 39}, + starting_zone = "wilderness-arda-fareast", starting_quest = "start-dunadan", - starting_intro = "dwarf", + starting_intro = "orc", life_rating=12, }, - experience = 1.1, + experience = 1.3, } ---------------------------------------------------------- --- Dwarves -- ---------------------------------------------------------- +-------------------------------------------------------- +-- Orcs -- +-------------------------------------------------------- newBirthDescriptor { type = "subrace", diff --git a/game/modules/tome/data/birth/worlds.lua b/game/modules/tome/data/birth/worlds.lua index b0d3a123eadbd226e816071ebb8d22998c2ee6bd..a4f84ea80d96f81c85ed5626b069c9b4eb9d939a 100644 --- a/game/modules/tome/data/birth/worlds.lua +++ b/game/modules/tome/data/birth/worlds.lua @@ -38,8 +38,8 @@ newBirthDescriptor{ Elf = "allow", Dwarf = "allow", Hobbit = "allow", --- Orc = function() return profile.mod.allow_build.evil and "allow" or "never" end, --- Troll = function() return profile.mod.allow_build.evil and "allow" or "never" end, + Orc = function() return profile.mod.allow_build.orc and "allow" or "never" end, + Troll = function() return profile.mod.allow_build.troll and "allow" or "never" end, Undead = function() return profile.mod.allow_build.undead and "allow" or "never" end, }, diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 6c46b9ac4a280de084f4a3a9d5df9b7e57d7fe8c..69060956c59a30a596a256caf35b9427edebfb2e 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -36,7 +36,7 @@ setDefaultProjector(function(src, x, y, type, dam) -- Increases damage if src.inc_damage then - local inc = src.inc_damage[type] or 0 + local inc = (src.inc_damage.all or 0) + (src.inc_damage[type] or 0) dam = dam + (dam * inc / 100) end diff --git a/game/modules/tome/data/general/grids/basic.lua b/game/modules/tome/data/general/grids/basic.lua index 6d14ec4987bcf837299356f63b8c6a22595e75eb..88b511ae9272483bfd7660cf1e9bd4b52f21e867 100644 --- a/game/modules/tome/data/general/grids/basic.lua +++ b/game/modules/tome/data/general/grids/basic.lua @@ -26,6 +26,15 @@ newEntity{ change_level = 1, change_zone = "wilderness", } +newEntity{ + define_as = "UP_WILDERNESS_FAR_EAST", + name = "exit to the wilds", + display = '<', color_r=255, color_g=0, color_b=255, + always_remember = true, + notice = true, + change_level = 1, + change_zone = "wilderness-arda-fareast", +} newEntity{ define_as = "UP", diff --git a/game/modules/tome/data/maps/wilderness/arda-fareast.lua b/game/modules/tome/data/maps/wilderness/arda-fareast.lua index 2065c456ae5d4d9807510d72cf1af7f5c167ccac..ad949721596f0211d325a3a8c5dd2c71a5d6f42c 100644 --- a/game/modules/tome/data/maps/wilderness/arda-fareast.lua +++ b/game/modules/tome/data/maps/wilderness/arda-fareast.lua @@ -28,7 +28,7 @@ quickEntity('t', {always_remember = true, show_tooltip=true, name='forest', disp quickEntity('m', {always_remember = true, show_tooltip=true, name='mountains', display='^', color=colors.LIGHT_UMBER, back_color=colors.UMBER, image="terrain/mountain.png", block_move=true}) quickEntity('h', {always_remember = true, show_tooltip=true, name='low hills', display='^', color=colors.GREEN, back_color=colors.DARK_GREEN, image="terrain/hills.png", can_encounter=true, equilibrium_level=-10}) ---quickEntity('A', {always_remember = true, show_tooltip=true, name="Caves below the tower of Amon Sûl", display='>', color={r=0, g=255, b=255}, notice = true, change_level=1, change_zone="tower-amon-sul"}) +quickEntity('A', {always_remember = true, show_tooltip=true, name="Sun Wall Outpost (Town)", display='*', color=colors.GOLD, notice = true, change_level=1, change_zone="town-sunwall-outpost"}) quickEntity('1', {always_remember = true, show_tooltip=true, name="Gates of Morning", desc="A massive hole in the Sun Wall", display='*', color=colors.GOLD, back_color=colors.CRIMSON, image="terrain/gate-morning.png", tint=colors.GOLD, notice = true, change_level=1, change_zone="town-gates-of-morning"}) --quickEntity('2', {always_remember = true, show_tooltip=true, name="Minas Tirith (Town)", desc="Captical city of the Reunited-Kingdom and Gondor ruled by High King Eldarion", display='*', color={r=255, g=255, b=255}, image="terrain/town1.png", notice = true, change_level=1, change_zone="town-minas-tirith"}) @@ -88,13 +88,13 @@ return [[ ============================== hhhhhhh www============ ================================ h www============ ================================= hh www============ -================================= hhh www============ -=================================tttt hhhh www============ -================================tttttttt hh w =========== -================================tttttttttt =========== -================================ttttttttttt ========== -===============================stttttttttttt sssssss ========== -==============================sstssstttttttt sssssssssssssss========== +========== ====================== hhh www============ +=======h ======================tttt hhhh www============ +=====hh ====================tttttttt hh w =========== +======mm ====================tttttttttt =========== +======tttmm A===================ttttttttttt ========== +======ttt=mm===================stttttttttttt sssssss ========== +=======t======================sstssstttttttt sssssssssssssss========== =============================sstssttsst ssssssssssssssssssss========== =============================ssssssssssssssssssssssssssssssssssssssssss========== =============================sssssssssssssssssssssssssssssssssssssssss=========== diff --git a/game/modules/tome/data/talents/misc/misc.lua b/game/modules/tome/data/talents/misc/misc.lua index 6d81b5534913e98376795f763743589e523a67d7..892c35fafbde29dd39fb85221f672655db62b448 100644 --- a/game/modules/tome/data/talents/misc/misc.lua +++ b/game/modules/tome/data/talents/misc/misc.lua @@ -197,3 +197,19 @@ newTalent{ The bonus will increase with the Constitution stat]]):format(10 + self:getCon() / 5, 10 + self:getCon() / 5) end, } + +-- Orc's power: temporary damage increase +newTalent{ + short_name = "ORC_FURY", + name = "Orcish Fury", + type = {"base/race", 1}, + cooldown = 50, + action = function(self, t) + self:setEffect(self.EFF_ORC_FURY, 5, {power=10 + self:getWil(20)}) + return true + end, + info = function(self) + return ([[Summons your lust for blood and destruction, increasing all damage by %d for 5 turns. + The bonus will increase with the Willpower stat]]):format(10 + self:getWil(20)) + end, +} diff --git a/game/modules/tome/data/texts/intro-orc.lua b/game/modules/tome/data/texts/intro-orc.lua new file mode 100644 index 0000000000000000000000000000000000000000..613dcc823b959b53e9a51e5816dc76615ce0fb5b --- /dev/null +++ b/game/modules/tome/data/texts/intro-orc.lua @@ -0,0 +1,28 @@ +-- ToME - Tales of Middle-Earth +-- Copyright (C) 2009, 2010 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 + +return [[Welcome #LIGHT_GREEN#]]..name..[[#WHITE#. +You are a member of the feared race of the Orcs. +For ages your kind has served Morgoth and his lieutenant Sauron, but they have all been vanquished by the free people. +Now as come the time for your revenge, a new power is rising in the far east of Arda, and you are one of its soldiers! + +You have been sent to a remote island on the south-west coast of the Far East to crush an outpost of the Sun Wall, the last remaining bastion of men, elves and dwarves on this continent. + +A little to the south lies the outpost. Your task: destroy it and bathe in the blood of its people! +]] diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua index 5e48baab46bb176f50c4e760b2b8c2a4d3c12863..f6355836e44a7fc88601f94378b2455087b7dec3 100644 --- a/game/modules/tome/data/timed_effects.lua +++ b/game/modules/tome/data/timed_effects.lua @@ -337,6 +337,22 @@ newEffect{ end, } +newEffect{ + name = "ORC_FURY", + desc = "Orcish Fury", + type = "physical", + status = "beneficial", + parameters = { power=10 }, + on_gain = function(self, err) return "#Target# enters a state of bloodlust." end, + on_lose = function(self, err) return "#Target# calms down." end, + activate = function(self, eff) + eff.pid = self:addTemporaryValue("inc_damage", {all=eff.power}) + end, + deactivate = function(self, eff) + self:removeTemporaryValue("inc_damage", eff.pid) + end, +} + newEffect{ name = "TIME_PRISON", desc = "Time Prison", diff --git a/game/modules/tome/data/zones/test/zone.lua b/game/modules/tome/data/zones/test/zone.lua index 2c9aeac7b27e1ff0b6ebea58b23d003cbb23a661..84584796d2d6c8283daa6b31ac8e932f992330c3 100644 --- a/game/modules/tome/data/zones/test/zone.lua +++ b/game/modules/tome/data/zones/test/zone.lua @@ -24,19 +24,19 @@ return { max_level = 4, decay = {300, 800}, actor_adjust_level = function(zone, level, e) return zone.base_level + e:getRankLevelAdjust() + level.level-1 + rng.range(-1,2) end, - width = 70, height = 70, - all_remembered = true, + width = 90, height = 90, +-- all_remembered = true, all_lited = true, -- persistant = "zone", generator = { map = { - class = "engine.generator.map.Cavern", - zoom = 16, - min_floor = 1200, + class = "engine.generator.map.Town", floor = "FLOOR", + external_floor = "GRASS", wall = "WALL", up = "UP", down = "DOWN", + door = "DOOR", }, --[[ actor = { @@ -57,7 +57,7 @@ return { { [1] = { generator = { map = { - up = "UP_WILDERNESS", + up = "UP_WILDERNESS_FAR_EAST", }, }, }, }, diff --git a/game/modules/tome/data/zones/town-sunwall-outpost/grids.lua b/game/modules/tome/data/zones/town-sunwall-outpost/grids.lua new file mode 100644 index 0000000000000000000000000000000000000000..17d13d0604094de870b55cca229193a50d5ac0a8 --- /dev/null +++ b/game/modules/tome/data/zones/town-sunwall-outpost/grids.lua @@ -0,0 +1,22 @@ +-- ToME - Tales of Middle-Earth +-- Copyright (C) 2009, 2010 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 + +load("/data/general/grids/basic.lua") +load("/data/general/grids/forest.lua") +load("/data/general/grids/water.lua") diff --git a/game/modules/tome/data/zones/town-sunwall-outpost/npcs.lua b/game/modules/tome/data/zones/town-sunwall-outpost/npcs.lua new file mode 100644 index 0000000000000000000000000000000000000000..82f2444fc95fc2babd498e489ddf6df8a60a6198 --- /dev/null +++ b/game/modules/tome/data/zones/town-sunwall-outpost/npcs.lua @@ -0,0 +1,19 @@ +-- ToME - Tales of Middle-Earth +-- Copyright (C) 2009, 2010 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 + diff --git a/game/modules/tome/data/zones/town-sunwall-outpost/objects.lua b/game/modules/tome/data/zones/town-sunwall-outpost/objects.lua new file mode 100644 index 0000000000000000000000000000000000000000..b5facd63f5b34e95c1aab209db0f312a8aef3e91 --- /dev/null +++ b/game/modules/tome/data/zones/town-sunwall-outpost/objects.lua @@ -0,0 +1,20 @@ +-- ToME - Tales of Middle-Earth +-- Copyright (C) 2009, 2010 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 + +load("/data/general/objects/objects.lua") diff --git a/game/modules/tome/data/zones/town-sunwall-outpost/zone.lua b/game/modules/tome/data/zones/town-sunwall-outpost/zone.lua new file mode 100644 index 0000000000000000000000000000000000000000..f8252906c01a076116ec6c0736d7a351e451f9cc --- /dev/null +++ b/game/modules/tome/data/zones/town-sunwall-outpost/zone.lua @@ -0,0 +1,59 @@ +-- ToME - Tales of Middle-Earth +-- Copyright (C) 2009, 2010 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 + +return { + name = "Sun Wall Outpost", + level_range = {1, 10}, + max_level = 5, + width = 50, height = 50, + persistent = "zone", +-- all_remembered = true, + all_lited = true, + ambiant_music = "80s_song.ogg", + generator = { + map = { + class = "engine.generator.map.Town", + building_chance = 70, + max_building_w = 8, max_building_h = 8, + edge_entrances = {8,2}, + floor = "FLOOR", + external_floor = "GRASS", + wall = "WALL", + up = "UP", + down = "DOWN", + door = "DOOR", + }, + actor = { + class = "engine.generator.actor.Random", + nb_npc = {0, 0}, + }, + object = { + class = "engine.generator.object.Random", + nb_object = {0, 0}, + }, + }, + levels = + { + [1] = { + generator = { map = { + up = "UP_WILDERNESS_FAR_EAST", + }, }, + }, + }, +} diff --git a/game/modules/tome/data/zones/wilderness-arda-fareast/zone.lua b/game/modules/tome/data/zones/wilderness-arda-fareast/zone.lua index 835d7f2374b1a93fcd72dac7150fc60694f8b4f5..554456c8a39495d5539904f175f61fb715f7e488 100644 --- a/game/modules/tome/data/zones/wilderness-arda-fareast/zone.lua +++ b/game/modules/tome/data/zones/wilderness-arda-fareast/zone.lua @@ -23,10 +23,10 @@ return { max_level = 1, width = 100, height = 100, -- all_remembered = true, --- all_lited = true, --- persistant = "memory", + all_lited = true, + persistant = "memory", wilderness = true, - wilderness_see_radius = 3, +-- wilderness_see_radius = 3, ambiant_music = "last", generator = { map = {