From 23ccecb6e803f3a5947d692e07fff55ec98beef0 Mon Sep 17 00:00:00 2001 From: DarkGod <darkgod@net-core.org> Date: Tue, 23 Dec 2014 17:32:37 +0100 Subject: [PATCH] Rooms and Maps can now be in a zone subfolder for better organisation moar work on ogres unlock, nearly done --- game/engines/default/engine/Zone.lua | 5 + .../default/engine/generator/map/Roomer.lua | 20 ++ .../engine/generator/map/RoomsLoader.lua | 25 ++- .../default/engine/generator/map/Static.lua | 3 + game/engines/default/engine/utils.lua | 6 + game/modules/tome/class/Game.lua | 2 +- game/modules/tome/data/lore/age-allure.lua | 6 +- game/modules/tome/data/talents/misc/races.lua | 2 +- .../tome/data/texts/unlock-race_ogre.lua | 31 +++ .../maps}/conclave-vault-entrance.lua | 2 +- .../tome/data/zones/conclave-vault/npcs.lua | 198 ++++++++++++++---- .../data/zones/conclave-vault/objects.lua | 18 +- .../data/zones/conclave-vault/rooms/boss.lua | 55 +++++ .../conclave-vault/rooms/room1.lua} | 14 +- .../data/zones/conclave-vault/rooms/room2.lua | 53 +++++ .../tome/data/zones/conclave-vault/zone.lua | 18 +- tiled-maps/conclave-vaul-entrance.tmx | 2 +- 17 files changed, 388 insertions(+), 72 deletions(-) create mode 100644 game/modules/tome/data/texts/unlock-race_ogre.lua rename game/modules/tome/data/{maps/zones => zones/conclave-vault/maps}/conclave-vault-entrance.lua (98%) create mode 100644 game/modules/tome/data/zones/conclave-vault/rooms/boss.lua rename game/modules/tome/data/{rooms/zones/conclave-vault-ogre-room-1.lua => zones/conclave-vault/rooms/room1.lua} (83%) create mode 100644 game/modules/tome/data/zones/conclave-vault/rooms/room2.lua diff --git a/game/engines/default/engine/Zone.lua b/game/engines/default/engine/Zone.lua index 9e52037236..772f6bbf98 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 b854244fb2..b44957a0ad 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 e95e308c79..565f5d282a 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 57605ccd9f..570128c69b 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 f4a6dcfaef..776038ddcd 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 697c3c8ca5..a9e6770f2e 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 655c5c980a..1699932733 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 e1d1c5e0ee..9d41f0ada2 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 0000000000..1b01de08dc --- /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 3119d203ae..4176f49341 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 d26e22b973..6fe968416f 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 30edb9f14e..3e60c857a7 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 0000000000..fc9c4c33ed --- /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 324cc4eb84..f8b9220c4c 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 0000000000..9ffecdbdc1 --- /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 8bab035b28..741fc6d6c8 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 40a6f4ba48..3ff3d4b448 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"> -- GitLab