diff --git a/game/engines/default/engine/Zone.lua b/game/engines/default/engine/Zone.lua index 9e52037236297e2fa8881113ead72f3074a222db..772f6bbf984d4fc751bc24229af80f09522ccc05 100644 --- a/game/engines/default/engine/Zone.lua +++ b/game/engines/default/engine/Zone.lua @@ -937,6 +937,11 @@ function _M:newLevel(level_data, lev, old_lev, game) -- Generate the map local generator = self:getGenerator("map", level, level_data.generator.map) local ux, uy, dx, dy, spots = generator:generate(lev, old_lev) + if level.force_recreate then + level:removed() + return self:newLevel(level_data, lev, old_lev, game) + end + spots = spots or {} for i = 1, #spots do print("[NEW LEVEL] spot", spots[i].x, spots[i].y, spots[i].type, spots[i].subtype) end diff --git a/game/engines/default/engine/generator/map/Roomer.lua b/game/engines/default/engine/generator/map/Roomer.lua index b854244fb2c5ba781f4bd867b484593cc6b4c76f..b44957a0adc4e906d48f4c3fd2c736ed75424a9a 100644 --- a/game/engines/default/engine/generator/map/Roomer.lua +++ b/game/engines/default/engine/generator/map/Roomer.lua @@ -119,6 +119,26 @@ function _M:generate(lev, old_lev) local nb_room = util.getval(self.data.nb_rooms or 10) local rooms = {} + + -- Those we are required to have + if #self.required_rooms > 0 then + for i, rroom in ipairs(self.required_rooms) do + local ok = false + if type(rroom) == "table" and rroom.chance_room then + if rng.percent(rroom.chance_room) then rroom = rroom[1] ok = true end + else ok = true + end + + if ok then + local r = self:roomAlloc(rroom, #rooms+1, lev, old_lev) + if r then rooms[#rooms+1] = r + else self.force_recreate = true return end + nb_room = nb_room - 1 + end + end + end + + -- Normal, random rooms while nb_room > 0 do local rroom while true do diff --git a/game/engines/default/engine/generator/map/RoomsLoader.lua b/game/engines/default/engine/generator/map/RoomsLoader.lua index e95e308c797970a5c8c72fe2ff78137843d5e2f5..565f5d282a7aad1d66bf10d6901236614e94b140 100644 --- a/game/engines/default/engine/generator/map/RoomsLoader.lua +++ b/game/engines/default/engine/generator/map/RoomsLoader.lua @@ -25,19 +25,26 @@ module(..., package.seeall, class.make) function _M:init(data) self.rooms = {} + self.required_rooms = {} data.tunnel_change = self.data.tunnel_change or 30 data.tunnel_random = self.data.tunnel_random or 10 - if not data.rooms then return end - - for i, file in ipairs(data.rooms) do + if data.rooms then for i, file in ipairs(data.rooms) do if type(file) == "table" then table.insert(self.rooms, {self:loadRoom(file[1]), chance_room=file[2]}) else table.insert(self.rooms, self:loadRoom(file)) end - end + end end + + if data.required_rooms then for i, file in ipairs(data.required_rooms) do + if type(file) == "table" then + table.insert(self.required_rooms, {self:loadRoom(file[1]), chance_room=file[2]}) + else + table.insert(self.required_rooms, self:loadRoom(file)) + end + end end end local rooms_cache = {} @@ -45,7 +52,10 @@ local rooms_cache = {} function _M:loadRoom(file) if rooms_cache[file] then return rooms_cache[file] end - local f, err = loadfile("/data/rooms/"..file..".lua") + local filename = "/data/rooms/"..file..".lua" + -- Found in the zone itself ? + if file:find("^!") then filename = self.zone:getBaseName().."/rooms/"..file:sub(2)..".lua" end + local f, err = loadfile(filename) if not f and err then error(err) end setfenv(f, setmetatable({ Map = require("engine.Map"), @@ -142,7 +152,7 @@ end --- Generates parse data for from an ascii def, for function room generators function _M:roomParse(def) - local room = { w=def[1]:len(), h=#def, spots={} } + local room = { w=def[1]:len(), h=#def, spots={}, special=def.special } -- Read the room map for j, line in ipairs(def) do @@ -154,7 +164,7 @@ function _M:roomParse(def) c = tonumber(c) room.spots[c] = room.spots[c] or {} room.spots[c][#room.spots[c]+1] = {x=i-1, y=j-1} - c = '.' + c = def.numbers or '.' end room[i][j] = c @@ -178,6 +188,7 @@ function _M:roomFrom(id, x, y, is_lit, room) else self.map(i-1+x, j-1+y, Map.TERRAIN, self:resolve(c)) end + if room.special then self.map.room_map[i-1+x][j-1+y].special = true end if is_lit then self.map.lites(i-1+x, j-1+y, true) end end end diff --git a/game/engines/default/engine/generator/map/Static.lua b/game/engines/default/engine/generator/map/Static.lua index 57605ccd9fe4d2cfb7fc04508fc70ca08db37302..570128c69bf7e327ca8b1b5432599b184d31ef57 100644 --- a/game/engines/default/engine/generator/map/Static.lua +++ b/game/engines/default/engine/generator/map/Static.lua @@ -43,6 +43,9 @@ function _M:init(zone, map, level, data) end function _M:getMapFile(file) + -- Found in the zone itself ? + if file:find("^!") then return self.zone:getBaseName().."/maps/"..file:sub(2)..".lua" end + local _, _, addon, rfile = file:find("^([^+]+)%+(.+)$") if addon and rfile then return "/data-"..addon.."/maps/"..rfile..".lua" diff --git a/game/engines/default/engine/utils.lua b/game/engines/default/engine/utils.lua index f4a6dcfaef4baf3f7a852bd6ca15496a0f02baf8..776038ddcd216c560f47338a149f61826bc81f7b 100644 --- a/game/engines/default/engine/utils.lua +++ b/game/engines/default/engine/utils.lua @@ -1784,6 +1784,12 @@ function util.bound(i, min, max) return i end +function util.squareApply(x, y, w, h, fct) + for i = x, x + w do for j = y, y + h do + fct(i, j) + end end +end + function util.minBound(i, min, max) return math.max(math.min(max, i), min) end diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index 697c3c8ca5c843ebd9fb20ab83a3fec83026fb99..a9e6770f2edf1dfd25235f3327b02bee990da71e 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -1589,7 +1589,7 @@ function _M:setupCommands() print("===============") end end, [{"_g","ctrl"}] = function() if config.settings.cheat then - game:changeLevel(1, "conclave-vault") + game:changeLevel(4, "conclave-vault") do return end local npc = game.zone:makeEntity(game.level, "actor", {random_boss = {name_scheme="#rng# the Fearsome", class_filter=function(d) return d.name == "Demonologist" end}}, nil, true) local nx, ny = util.findFreeGrid(game.player.x, game.player.y, 10, true, {[engine.Map.ACTOR]=true}) diff --git a/game/modules/tome/data/lore/age-allure.lua b/game/modules/tome/data/lore/age-allure.lua index 655c5c980a4f38d001f3ae6e5e3e97b8eeb36081..1699932733cacdaa058b44d7885fffce8475e4cf 100644 --- a/game/modules/tome/data/lore/age-allure.lua +++ b/game/modules/tome/data/lore/age-allure.lua @@ -243,5 +243,9 @@ This is my last order: I have prepared a golem to apply the Ogric inscriptions t It has been an honor working with such talented individuals, and an honor doing everything I can for a noble cause. Perhaps we still had some progress to make, but overall I'm proud of what we've accomplished, and the contributions the Ogre race will make to all of Maj'Eyal. Long live the Conclave, -Healer Astelrid]] +Healer Astelrid]], + on_learn = function(who) + game:setAllowedBuild("race_giant") + game:setAllowedBuild("race_ogre", true) + end, } diff --git a/game/modules/tome/data/talents/misc/races.lua b/game/modules/tome/data/talents/misc/races.lua index e1d1c5e0ee90ca1f9ddc48fd6d246121804d4faf..9d41f0ada265788371add0002afa8735541f4859 100644 --- a/game/modules/tome/data/talents/misc/races.lua +++ b/game/modules/tome/data/talents/misc/races.lua @@ -963,7 +963,7 @@ newTalent{ end, info = function(self, t) return ([[An ogre's body is used to spells and inscriptions. - Increases spell save by %d and improves the contibution of primary stats on infusions and runes by %d%%.]]): + Increases spell save by %d and improves the contribution of primary stats on infusions and runes by %d%%.]]): format(t.getSave(self, t), t.getMult(self, t) * 100) end, } diff --git a/game/modules/tome/data/texts/unlock-race_ogre.lua b/game/modules/tome/data/texts/unlock-race_ogre.lua new file mode 100644 index 0000000000000000000000000000000000000000..1b01de08dc81b0bc03f84ad92fe5eebf74554b58 --- /dev/null +++ b/game/modules/tome/data/texts/unlock-race_ogre.lua @@ -0,0 +1,31 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009 - 2014 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 "New Race: #LIGHT_GREEN#Ogre", +[[ +WRITE ME + +You have discovered the truth about the creation of the Ogres and can now create a new character with the #LIGHT_GREEN#Ogre race#WHITE#. + +Race features:#YELLOW# +- Strong but not stupid +- Efficient at using all kind of runes and infusions +- Imbued with arcane forces +#WHITE# +]] diff --git a/game/modules/tome/data/maps/zones/conclave-vault-entrance.lua b/game/modules/tome/data/zones/conclave-vault/maps/conclave-vault-entrance.lua similarity index 98% rename from game/modules/tome/data/maps/zones/conclave-vault-entrance.lua rename to game/modules/tome/data/zones/conclave-vault/maps/conclave-vault-entrance.lua index 3119d203ae1e14c2e912d8468a3115ab2d2d32f4..4176f49341e128beb61604815a3ad1e347026468 100644 --- a/game/modules/tome/data/maps/zones/conclave-vault-entrance.lua +++ b/game/modules/tome/data/zones/conclave-vault/maps/conclave-vault-entrance.lua @@ -45,7 +45,7 @@ return [[ ################ ########.O###### ########..###### ->*.............< +>..............< ########..###### ########.o###### ################ diff --git a/game/modules/tome/data/zones/conclave-vault/npcs.lua b/game/modules/tome/data/zones/conclave-vault/npcs.lua index d26e22b973df5aff2a39fc710eb155d0df04dd8b..6fe968416f4567eab74c48e2374cdcc45915b2f2 100644 --- a/game/modules/tome/data/zones/conclave-vault/npcs.lua +++ b/game/modules/tome/data/zones/conclave-vault/npcs.lua @@ -33,6 +33,9 @@ newEntity{ infravision = 10, resolvers.racial(), + resolvers.sustains_at_birth(), + resolvers.inscriptions(1, "rune"), + resolvers.inscriptions(1, "infusion"), autolevel = "warriormage", ai = "dumb_talented_simple", ai_state = { ai_move="move_complex", talent_in=2, }, @@ -48,74 +51,151 @@ newEntity{ newEntity{ base = "BASE_NPC_OGRE", name = "ogre guard", color=colors.LIGHT_GREY, - desc = [[WRITE ME]], - level_range = {1, nil}, exp_worth = 1, + desc = [[A maul-wield ogre. Ready to CRUSH!]], + level_range = {20, nil}, exp_worth = 1, rarity = 2, rank = 2, - max_life = resolvers.rngavg(110,120), life_rating = 14, + max_life = resolvers.rngavg(150,170), life_rating = 14, + + resolvers.equip{{type="weapon", subtype="greatmaul", forbid_power_source={antimagic=true}, autoreq=true} }, + resolvers.talents{ + [Talents.T_SUNDER_ARMOUR]={base=3, every=4, max=8}, + [Talents.T_WEAPON_COMBAT]={base=3, every=4, max=7}, + [Talents.T_WEAPONS_MASTERY]={base=4, every=5, max=7}, + }, } newEntity{ base = "BASE_NPC_OGRE", - name = "ogre warmaster", color=colors.LIGHT_GREY, - desc = [[WRITE ME]], - level_range = {1, nil}, exp_worth = 1, - rarity = 2, - rank = 2, - max_life = resolvers.rngavg(110,120), life_rating = 14, + name = "ogre warmaster", color=colors.CRIMSON, + desc = [[A master of combat, he is impatient to test his newfound skills.]], + level_range = {21, nil}, exp_worth = 1, + rarity = 4, + rank = 3, + max_life = resolvers.rngavg(110,120), life_rating = 15, + + resolvers.equip{ + {type="weapon", subtype="mace", forbid_power_source={antimagic=true}, autoreq=true}, + {type="armor", subtype="shield", forbid_power_source={antimagic=true}, autoreq=true}, + }, + resolvers.talents{ + [Talents.T_BATTLE_CRY]={base=3, every=4, max=8}, + [Talents.T_DISARM]={base=3, every=4, max=8}, + [Talents.T_BATTLE_CALL]={base=3, every=4, max=8}, + [Talents.T_WEAPON_COMBAT]={base=3, every=4, max=7}, + [Talents.T_SHATTERING_BLOW]={base=3, every=4, max=8}, + [Talents.T_WEAPONS_MASTERY]={base=4, every=5, max=7}, + [Talents.T_ARMOUR_TRAINING]={base=4, every=5, max=7}, + }, } newEntity{ base = "BASE_NPC_OGRE", - name = "ogre mauler", color=colors.LIGHT_GREY, - desc = [[WRITE ME]], - level_range = {1, nil}, exp_worth = 1, + name = "ogre mauler", color=colors.LIGHT_UMBER, + desc = [[Crush! Destroy! Maim!]], + level_range = {22, nil}, exp_worth = 1, rarity = 2, rank = 2, - max_life = resolvers.rngavg(110,120), life_rating = 14, + max_life = resolvers.rngavg(110,120), life_rating = 13, + + resolvers.equip{{type="weapon", subtype="greatmaul", forbid_power_source={antimagic=true}, autoreq=true} }, + resolvers.talents{ + [Talents.T_WARSHOUT_BERSERKER]={base=3, every=4, max=8}, + [Talents.T_WEAPON_COMBAT]={base=3, every=4, max=7}, + [Talents.T_WEAPONS_MASTERY]={base=4, every=5, max=7}, + }, } newEntity{ base = "BASE_NPC_OGRE", - name = "ogre pounder", color=colors.LIGHT_GREY, - desc = [[WRITE ME]], - level_range = {1, nil}, exp_worth = 1, - rarity = 2, - rank = 2, - max_life = resolvers.rngavg(110,120), life_rating = 14, + name = "ogre pounder", color=colors.DARK_UMBER, + desc = [[This ogre closes in fast on you, arms open for the hug of death.]], + level_range = {20, nil}, exp_worth = 1, + rarity = 3, + rank = 3, + max_life = resolvers.rngavg(150,170), life_rating = 15, + + resolvers.equip{{type="armor", subtype="hands", autoreq=true},}, + resolvers.talents{ + [Talents.T_DOUBLE_STRIKE] = {base=3, every=5, max=7}, + [Talents.T_UPPERCUT] = {base=3, every=5, max=7}, + [Talents.T_EMPTY_HAND] = 1, + [Talents.T_CLINCH] = {base=3, every=5, max=7}, + [Talents.T_MAIM] = {base=3, every=5, max=7}, + [Talents.T_UNARMED_MASTERY] = {base=4, every=6, max=8}, + [Talents.T_WEAPON_COMBAT] = {base=2, every=6, max=8}, + }, } newEntity{ base = "BASE_NPC_OGRE", - name = "degenerated ogre", color=colors.LIGHT_GREY, - desc = [[WRITE ME]], - level_range = {1, nil}, exp_worth = 1, + name = "degenerated ogric mass", color=colors.BLUE, + desc = [[This huge mass of deformed flesh was probably once an ogre, but something had gone wrong.]], + level_range = {20, nil}, exp_worth = 1, rarity = 2, rank = 2, - max_life = resolvers.rngavg(110,120), life_rating = 14, + max_life = resolvers.rngavg(110,120), life_rating = 13, + + resolvers.equip{{type="weapon", subtype="greatmaul", forbid_power_source={antimagic=true}, autoreq=true} }, + resolvers.talents{ + [Talents.T_EPIDEMIC]={base=3, every=4, max=8}, + [Talents.T_ROTTING_DISEASE]={base=3, every=4, max=8}, + [Talents.T_WEAPON_COMBAT]={base=3, every=4, max=7}, + [Talents.T_CATALEPSY]={base=4, every=5, max=7}, + }, } newEntity{ base = "BASE_NPC_OGRE", name = "ogric abomination", color=colors.LIGHT_GREY, - desc = [[WRITE ME]], - level_range = {1, nil}, exp_worth = 1, - rarity = 2, - rank = 2, - max_life = resolvers.rngavg(110,120), life_rating = 14, + desc = [[This ogre seems to have tried to graft golem parts on its own body. To various interresting results.]], + level_range = {22, nil}, exp_worth = 1, + rarity = 4, + rank = 3, + max_life = resolvers.rngavg(110,120), life_rating = 13, + + resolvers.equip{{type="weapon", subtype="greatmaul", forbid_power_source={antimagic=true}, autoreq=true} }, + resolvers.talents{ + [Talents.T_GOLEM_CRUSH]={base=3, every=4, max=8}, + [Talents.T_GOLEM_KNOCKBACK]={base=3, every=4, max=8}, + [Talents.T_GOLEM_POUND]={base=3, every=4, max=8}, + [Talents.T_GOLEM_REFLECTIVE_SKIN]={base=3, every=4, max=8}, + [Talents.T_WEAPON_COMBAT]={base=3, every=4, max=7}, + [Talents.T_WEAPONS_MASTERY]={base=4, every=5, max=7}, + }, } newEntity{ base = "BASE_NPC_OGRE", - name = "ogre rune-spinner", color=colors.LIGHT_GREY, - desc = [[WRITE ME]], - level_range = {1, nil}, exp_worth = 1, + name = "ogre rune-spinner", color=colors.LIGHT_RED, + desc = [[A towering ogre guard, his skin covered in runes and arcane designs.]], + level_range = {23, nil}, exp_worth = 1, rarity = 2, - rank = 2, - max_life = resolvers.rngavg(110,120), life_rating = 14, + rank = 3, + max_life = resolvers.rngavg(110,120), life_rating = 13, + + resolvers.equip{{type="weapon", subtype="staff", forbid_power_source={antimagic=true}, autoreq=true} }, + resolvers.talents{ + [Talents.T_LIGHTNING]={base=3, every=4, max=8}, + [Talents.T_FLAME]={base=3, every=4, max=7}, + [Talents.T_EARTHEN_MISSILES]={base=4, every=5, max=7}, + [Talents.T_BARRIER]={base=4, every=5, max=7}, + }, } + +------------- Non random + newEntity{ base = "BASE_NPC_OGRE", define_as = "OGRE_SENTRY", - name = "ogre sentry", color=colors.LIGHT_GREY, - desc = [[WRITE ME]], - level_range = {1, nil}, exp_worth = 1, - rarity = 2, - rank = 2, - max_life = resolvers.rngavg(110,120), life_rating = 14, + name = "ogre sentry", color=colors.GREY, + desc = [[This greatsword-wielding ogre looks at you with contempt and hatred.]], + level_range = {21, nil}, exp_worth = 1, + rank = 3, + max_life = resolvers.rngavg(110,120), life_rating = 13, + blind_immune = 1, + + resolvers.equip{{type="weapon", subtype="greatsword", forbid_power_source={antimagic=true}, autoreq=true} }, + resolvers.talents{ + [Talents.T_STUNNING_BLOW]={base=3, every=4, max=8}, + [Talents.T_WEAPON_COMBAT]={base=3, every=4, max=7}, + [Talents.T_WEAPONS_MASTERY]={base=4, every=5, max=7}, + [Talents.T_ILLUMINATE]={base=3, every=5, max=7}, + }, + seen_by = function(self, who) if not game.party:hasMember(who) then return end self.seen_by = nil @@ -134,3 +214,43 @@ newEntity{ base = "OGRE_SENTRY", define_as = "OGRE_SENTRY2", chat:invoke() end, } + + +newEntity{ base = "BASE_NPC_OGRE", define_as = "HEALER_ASTELRID", + name = "Healer Astelrid", color=colors.VIOLET, + desc = [[An enormous ogre, clad in a tattered set of robes with an officer's badge. She clutches a healer's staff, wrapped in casting plaster and scalpels for use as a massive spiked club.]], + killer_message = "and spliced for experiments", + level_range = {23, nil}, exp_worth = 2, + female = 1, + rank = 4, + max_life = 170, life_rating = 14, fixed_rating = true, + + stats = { str=20, dex=10, cun=8, mag=25, con=20 }, + instakill_immune = 1, + move_others=true, + + body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1, TOOL=1 }, + resolvers.equip{ + {defined="ASTELRID_CLUBSTAFF"}, + {type="armor", subtype="cloth", forbid_power_source={antimagic=true}, force_drop=true, tome_drops="boss", autoreq=true}, + {type="armor", subtype="head", forbid_power_source={antimagic=true}, force_drop=true, tome_drops="boss", autoreq=true}, + {type="armor", subtype="feet", forbid_power_source={antimagic=true}, force_drop=true, tome_drops="boss", autoreq=true}, + }, + resolvers.drops{chance=100, nb=1, {defined="NOTE4"} }, + resolvers.drops{chance=100, nb=3, {tome_drops="boss"} }, + + resolvers.talents{ + [Talents.T_HEAL]={base=3, every=4, max=8}, + [Talents.T_ARCANE_SHIELD]={base=3, every=4, max=8}, + [Talents.T_AEGIS]={base=3, every=4, max=8}, + [Talents.T_EARTHQUAKE]={base=3, every=4, max=8}, + [Talents.T_RUSH]={base=3, every=4, max=8}, + [Talents.T_STUNNING_BLOW]={base=3, every=4, max=8}, + [Talents.T_LIVING_LIGHTNING]={base=3, every=4, max=8}, + }, + resolvers.inscriptions(2, "rune"), + resolvers.inscriptions(2, "infusion"), + + autolevel = "warriormage", + ai = "tactical", ai_state = { talent_in=1, ai_move="move_astar", }, +} diff --git a/game/modules/tome/data/zones/conclave-vault/objects.lua b/game/modules/tome/data/zones/conclave-vault/objects.lua index 30edb9f14e0a6c3b3327440f59238013e685e7c5..3e60c857a74a9a4184ec10e809b6633da731e91c 100644 --- a/game/modules/tome/data/zones/conclave-vault/objects.lua +++ b/game/modules/tome/data/zones/conclave-vault/objects.lua @@ -17,6 +17,9 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org +local Stats = require "engine.interface.ActorStats" +local Talents = require "engine.interface.ActorTalents" + load("/data/general/objects/objects-maj-eyal.lua") for i = 1, 4 do @@ -29,20 +32,19 @@ newEntity{ base = "BASE_LORE", } end -newEntity{ base = "BASE_GREATMAUL", +newEntity{ base = "BASE_GREATMAUL", define_as = "ASTELRID_CLUBSTAFF", power_source = {arcane=true}, name = "Astelrid's Clubstaff", color = colors.GREEN, unided_name = "huge maul", unique = true, desc = [[Like its former owner, this was once an instrument of altruistic healing, before fury and fear caused its twisting into a sadistic weapon. Surges of restorative magic can be faintly felt under the layers of plaster and sharp surgical equipment.]], - level_range = {10, 20}, - rarity = 300, - require = { stat = { str=20 }, }, + level_range = {20, 30}, + require = { stat = { str=23 }, }, cost = 650, - material_level = 2, + material_level = 3, combat = { - dam = 32, + dam = 45, apr = 4, - physcrit = 4, + physcrit = 8, dammod = {str=1, mag=0.4}, }, wielder = { @@ -50,5 +52,7 @@ newEntity{ base = "BASE_GREATMAUL", inc_stats = {[Stats.STAT_MAG] = 4}, combat_spellpower = 15, healing_factor = 0.25, + inscriptions_stat_multiplier = 0.15, }, + special_desc = function(self) return "Improves the contribution of primary stats on infusions and runes by 15%" end, } diff --git a/game/modules/tome/data/zones/conclave-vault/rooms/boss.lua b/game/modules/tome/data/zones/conclave-vault/rooms/boss.lua new file mode 100644 index 0000000000000000000000000000000000000000..fc9c4c33ed8a6b9fbb5833e6497f436d42d39480 --- /dev/null +++ b/game/modules/tome/data/zones/conclave-vault/rooms/boss.lua @@ -0,0 +1,55 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009 - 2014 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 + +local def = { numbers = '.', +[[###########]], +[[#42..#..23#]], +[[#####.#####]], +[[#...212...#]], +[[#.#.....#.#]], +[[#.........#]], +[[#####+#####]], +[[#####!#####]], +} + +return function(gen, id) + local room = gen:roomParse(def) + return { name="conclave-ogre-final"..room.w.."x"..room.h, w=room.w, h=room.h, generator = function(self, x, y, is_lit) + gen:roomFrom(id, x, y, is_lit, room) + + -- Everything but the entrance is special: cant have the player spawn here + util.squareApply(x, y, room.w, room.h-2, function(i, j) gen.map.room_map[i][j].special = true end) + + local spot = room.spots[1][1] + local e = gen.zone:makeEntityByName(gen.level, "actor", "HEALER_ASTELRID") + if e then + gen:roomMapAddEntity(x + spot.x, y + spot.y, "actor", e) + gen.spots[#gen.spots+1] = {x=x+spot.x, y=y+spot.y, guardian=true, check_connectivity="entrance"} + e.on_added_to_level = nil + end + + for _, spot in ipairs(room.spots[2]) do + local e = gen.zone:makeEntity(gen.level, "actor", {type="giant", subtype="ogre"}, nil, true) + if e then + gen:roomMapAddEntity(x + spot.x, y + spot.y, "actor", e) + e.on_added_to_level = nil + end + end + end} +end diff --git a/game/modules/tome/data/rooms/zones/conclave-vault-ogre-room-1.lua b/game/modules/tome/data/zones/conclave-vault/rooms/room1.lua similarity index 83% rename from game/modules/tome/data/rooms/zones/conclave-vault-ogre-room-1.lua rename to game/modules/tome/data/zones/conclave-vault/rooms/room1.lua index 324cc4eb8467d579904864956625e9f646590d4d..f8b9220c4cab0d45e7fe0b1ffa0a8d5c726147b8 100644 --- a/game/modules/tome/data/rooms/zones/conclave-vault-ogre-room-1.lua +++ b/game/modules/tome/data/zones/conclave-vault/rooms/room1.lua @@ -17,29 +17,29 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org -local def = { +local def = { numbers = '.', [[#!!!!!!!!!!#]], -[[!..2....2..!]], -[[!.#.#..#.#.!]], +[[!.222..222.!]], +[[!.#2#..#2#.!]], [[!.#1#..#1#.!]], [[!.###..###.!]], [[!..........!]], [[!.###..###.!]], [[!.#1#..#1#.!]], -[[!.#.#..#.#.!]], -[[!..2....2..!]], +[[!.#2#..#2#.!]], +[[!.222..222.!]], [[#!!!!!!!!!!#]], } return function(gen, id) local room = gen:roomParse(def) - return { name="conclave-ogre"..room.w.."x"..room.h, w=room.w, h=room.h, generator = function(self, x, y, is_lit) + return { name="conclave-ogre-1"..room.w.."x"..room.h, w=room.w, h=room.h, generator = function(self, x, y, is_lit) gen:roomFrom(id, x, y, is_lit, room) for _, spot in ipairs(room.spots[1]) do local e = gen.zone:makeEntity(gen.level, "actor", {type="giant", subtype="ogre"}, nil, true) - if e then gen:roomMapAddEntity(x + spot.x, y + spot.y, "actor", e) end + if e then gen:roomMapAddEntity(x + spot.x, y + spot.y, "actor", e) gen.map.room_map[x + spot.x][y + spot.y].special = true end end for _, spot in ipairs(room.spots[2]) do game.level.map(x + spot.x, y + spot.y, gen.map.TRIGGER, engine.Entity.new{ on_move = function(self, x, y, who) if who and game.zone.awaken_ogres then diff --git a/game/modules/tome/data/zones/conclave-vault/rooms/room2.lua b/game/modules/tome/data/zones/conclave-vault/rooms/room2.lua new file mode 100644 index 0000000000000000000000000000000000000000..9ffecdbdc1fc5d704c79abf9bfac75eecc6a70cb --- /dev/null +++ b/game/modules/tome/data/zones/conclave-vault/rooms/room2.lua @@ -0,0 +1,53 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009 - 2014 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 + +local def = { numbers = '.', +[[###!!!!###]], +[[###....###]], +[[#1#....#1#]], +[[#1#....#1#]], +[[##222222##]], +[[!.222222.!]], +[[!.222222.!]], +[[!.222222.!]], +[[!.222222.!]], +[[##222222##]], +[[#1#....#1#]], +[[#1#....#1#]], +[[###....###]], +[[###!!!!###]], +} + +return function(gen, id) + local room = gen:roomParse(def) + return { name="conclave-ogre-2"..room.w.."x"..room.h, w=room.w, h=room.h, generator = function(self, x, y, is_lit) + + gen:roomFrom(id, x, y, is_lit, room) + + for _, spot in ipairs(room.spots[1]) do + local e = gen.zone:makeEntity(gen.level, "actor", {type="giant", subtype="ogre"}, nil, true) + if e then gen:roomMapAddEntity(x + spot.x, y + spot.y, "actor", e) gen.map.room_map[x + spot.x][y + spot.y].special = true end + end + for _, spot in ipairs(room.spots[2]) do + game.level.map(x + spot.x, y + spot.y, gen.map.TRIGGER, engine.Entity.new{ on_move = function(self, x, y, who) if who and game.zone.awaken_ogres then + game.zone.awaken_ogres(who, x, y, 4) + end end}) + end + end} +end diff --git a/game/modules/tome/data/zones/conclave-vault/zone.lua b/game/modules/tome/data/zones/conclave-vault/zone.lua index 8bab035b28f7585ec732f4b391b379cf6678e51a..741fc6d6c879495aa9b5a6a4a813766f73d366ba 100644 --- a/game/modules/tome/data/zones/conclave-vault/zone.lua +++ b/game/modules/tome/data/zones/conclave-vault/zone.lua @@ -19,7 +19,7 @@ return { name = "Old Conclave Vault", - level_range = {25, 35}, + level_range = {20, 30}, level_scheme = "player", max_level = 4, decay = {300, 800, only={object=true}}, @@ -28,17 +28,18 @@ return { persistent = "zone", -- all_remembered = true, all_lited = true, - ambient_music = "Far away.ogg", + ambient_music = "Sinestra.ogg", min_material_level = 2, max_material_level = 3, generator = { map = { class = "engine.generator.map.Roomer", nb_rooms = 10, - rooms = {"zones/conclave-vault-ogre-room-1"}, + rooms = {"!room1", "!room2", }, lite_room_chance = 100, ['.'] = "FLOOR", ['#'] = "WALL", + ['+'] = "DOOR", up = "UP", down = "DOWN", door = "DOOR", @@ -54,7 +55,7 @@ return { }, trap = { class = "engine.generator.trap.Random", - nb_trap = {0, 0}, + nb_trap = {4, 4}, }, }, levels = @@ -62,14 +63,17 @@ return { [1] = { generator = { map = { class = "engine.generator.map.Static", - map = "zones/conclave-vault-entrance", + map = "!conclave-vault-entrance", }, object = { nb_object = {0, 0}, + }, trap = { + nb_trap = {2, 2}, }}, }, [4] = { - generator = { - }, + generator = { map = { + required_rooms = {"!boss"}, + } }, }, }, post_process = function(level) diff --git a/tiled-maps/conclave-vaul-entrance.tmx b/tiled-maps/conclave-vaul-entrance.tmx index 40a6f4ba4839df3e6b468b145d1b663ffe5b428a..3ff3d4b44823b8493dc4ee3c6abe482f9448c032 100644 --- a/tiled-maps/conclave-vaul-entrance.tmx +++ b/tiled-maps/conclave-vaul-entrance.tmx @@ -50,7 +50,7 @@ </tileset> <layer name="Terrain" width="16" height="16"> <data encoding="base64" compression="zlib"> - eJxjZGBgYBzFgxZbQTGt9AsCMTuSOlKwwCBw/yimDAMADdkF0w== + eJxjZGBgYBzFgxZbQTGt9AsiqSEVCwwC949iyjAAcw0GBg== </data> </layer> <objectgroup name="Actor" width="16" height="16">