diff --git a/game/modules/tome/data/general/events/pyroclast.lua b/game/modules/tome/data/general/events/pyroclast.lua new file mode 100644 index 0000000000000000000000000000000000000000..c89d6e77392224c99c512059e5e847a25aa1e9d8 --- /dev/null +++ b/game/modules/tome/data/general/events/pyroclast.lua @@ -0,0 +1,94 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010, 2011, 2012, 2013 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 function get_coords() + local function check(x, y) + local level = game.level + local function canEventGrid(level,x,y) return not level.map.attrs(x, y, "no_teleport") and not level.map:checkAllEntities(x, y, "change_level") end + + local list = {} + for i = -2, 2 do for j = -2, 2 do + if not canEventGrid(level, x+i, y+j) then return false end + list[#list+1] = {x=x+i, y=y+j} + end end + if not game.state:canEventGrid(level, x, y) then return false end -- Check the center is also accessible + + if #list < 5 then return false + else return list end + end + + local x, y = rng.range(3, level.map.w - 4), rng.range(3, level.map.h - 4) + local tries = 0 + while not check(x, y) and tries < 100 do + x, y = rng.range(3, level.map.w - 4), rng.range(3, level.map.h - 4) + tries = tries + 1 + end + if tries >= 100 then return nil end + return x, y +end + +local list = {} +for i = 1, math.floor(7 * (1 + level.level / 2)) do + local x, y = get_coords() + if x then list[#list+1] = {x=x,y=y} end +end + +game.zone.pyroclast_event_levels = game.zone.pyroclast_event_levels or {} +game.zone.pyroclast_event_levels[level.level] = list +print("Pyroclast crash sites") +table.print(list) + +if not game.zone.pyroclast_event_on_turn then game.zone.pyroclast_event_on_turn = game.zone.on_turn or function() end end +game.zone.on_turn = function() + if game.zone.pyroclast_event_on_turn then game.zone.pyroclast_event_on_turn() end + + if game.turn % 10 ~= 0 or not game.zone.pyroclast_event_levels[game.level.level] then return end + + local p = game:getPlayer(true) + local x, y, si = nil, nil, nil + for i = 1, #game.zone.pyroclast_event_levels[game.level.level] do + local fx, fy = game.zone.pyroclast_event_levels[game.level.level][i].x, game.zone.pyroclast_event_levels[game.level.level][i].y + if core.fov.distance(p.x, p.y, fx, fy) < 3 then x, y, si = fx, fy, i break end + end + + if not x then return end + print("Crashing at ",x,y, si) + table.remove(game.zone.pyroclast_event_levels[game.level.level], si) + + game.level.data.meteor_x, game.level.data.meteor_y = x, y + game.level.map:particleEmitter(game.level.data.meteor_x, game.level.data.meteor_y, 10, "meteor").on_remove = function() + local x, y = game.level.data.meteor_x, game.level.data.meteor_y + game.level.map:particleEmitter(x, y, 10, "ball_fire", {radius=5}) + game:playSoundNear(game.player, "talents/fireflash") + + for i = x-2, x+2 do for j = y-2, y+2 do + local og = game.level.map(i, j, engine.Map.TERRAIN) + if (core.fov.distance(x, y, i, j) <= 1 or rng.percent(40)) and og and not og.escort_portal and not og.change_level then + local g = game.zone.grid_list.LAVA_FLOOR:clone() + g:resolve() g:resolve(nil, true) + game.zone:addEntity(game.level, g, "terrain", i, j) + end + end end + for i = x-2, x+2 do for j = y-2, y+2 do + game.nicer_tiles:updateAround(game.level, i, j) + end end + end +end + +return true diff --git a/game/modules/tome/data/gfx/shockbolt/npc/dragon_fire_varsha_the_writhing.png b/game/modules/tome/data/gfx/shockbolt/npc/dragon_fire_varsha_the_writhing.png new file mode 100644 index 0000000000000000000000000000000000000000..c1b9d07b2a0257321f759ec4b0f1788c211a33aa Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/npc/dragon_fire_varsha_the_writhing.png differ diff --git a/game/modules/tome/data/zones/daikara/events.lua b/game/modules/tome/data/zones/daikara/events.lua index a346830781a466ad64f0cf3b216f437f45e52914..89b7fa4c73a769e394c6dd8af62a603b636facde 100644 --- a/game/modules/tome/data/zones/daikara/events.lua +++ b/game/modules/tome/data/zones/daikara/events.lua @@ -17,12 +17,20 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org -return { one_per_level=true, +local events = { one_per_level=true, {group="outdoor-majeyal-gloomy"}, {group="outdoor-majeyal-generic"}, {group="majeyal-generic"}, {name="cultists", percent=10}, - {name="icy-ground", minor=true, percent=50}, {name="font-life", minor=true, percent=30}, {name="whistling-vortex", minor=true, percent=30}, } + +if self.is_volcano then + events[#events+1] = {name="pyroclast", minor=true, percent=100} +else + events[#events+1] = {name="icy-ground", minor=true, percent=50} + +end + +return events \ No newline at end of file diff --git a/game/modules/tome/data/zones/daikara/grids.lua b/game/modules/tome/data/zones/daikara/grids.lua index 3dd539523c110f929f9fbdfcd3952aac2b51f2ee..e5cf60a3ccf1e76651c5d6b7254ac15f785fb06c 100644 --- a/game/modules/tome/data/zones/daikara/grids.lua +++ b/game/modules/tome/data/zones/daikara/grids.lua @@ -19,6 +19,7 @@ load("/data/general/grids/basic.lua") load("/data/general/grids/mountain.lua") +load("/data/general/grids/lava.lua", function(e) e.on_stand = nil end) newEntity{ define_as = "RIFT", diff --git a/game/modules/tome/data/zones/daikara/npcs.lua b/game/modules/tome/data/zones/daikara/npcs.lua index 6e0f03f2d8df6603e7d3dbc784c054a8ab69d694..580d62454c2c21a7e03c36768d6fa227debe2f8f 100644 --- a/game/modules/tome/data/zones/daikara/npcs.lua +++ b/game/modules/tome/data/zones/daikara/npcs.lua @@ -18,9 +18,14 @@ -- darkgod@te4.org load("/data/general/npcs/xorn.lua", rarity(4)) -load("/data/general/npcs/canine.lua", rarity(2)) load("/data/general/npcs/snow-giant.lua", rarity(0)) -load("/data/general/npcs/cold-drake.lua", rarity(2)) +if not currentZone.is_volcano then + load("/data/general/npcs/canine.lua", rarity(2)) + load("/data/general/npcs/cold-drake.lua", rarity(2)) +else + load("/data/general/npcs/fire-drake.lua", rarity(2)) + load("/data/general/npcs/faeros.lua", rarity(0)) +end load("/data/general/npcs/all.lua", rarity(4, 35)) @@ -79,6 +84,59 @@ newEntity{ define_as = "RANTHA_THE_WORM", end, } +newEntity{ define_as = "VARSHA_THE_WRITHING", + allow_infinite_dungeon = true, + type = "dragon", subtype = "fire", unique = true, + name = "Varsha the Writhing", + display = "D", color=colors.VIOLET, + resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/dragon_fire_varsha_the_writhing.png", display_h=2, display_y=-1}}}, + desc = [[Claws and teeth. Fire and death. Dragons are not all extinct it seems...]], + killer_message = "and fed to the hatchlings", + level_range = {12, nil}, exp_worth = 2, + max_life = 230, life_rating = 17, fixed_rating = true, + max_stamina = 85, + max_mana = 200, + stats = { str=25, dex=10, cun=8, mag=20, wil=20, con=20 }, + rank = 4, + size_category = 5, + combat_armor = 17, combat_def = 14, + infravision = 10, + instakill_immune = 1, + stun_immune = 1, + move_others=true, + + combat = { dam=resolvers.levelup(resolvers.rngavg(25,110), 1, 2), atk=resolvers.rngavg(25,70), apr=25, dammod={str=1.1} }, + + resists = { [DamageType.COLD] = -20, [DamageType.FIRE] = 100 }, + + body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, + resolvers.drops{chance=100, nb=1, {defined="FROST_TREADS", random_art_replace={chance=75}}, }, + resolvers.drops{chance=100, nb=3, {tome_drops="boss"} }, + resolvers.drops{chance=100, nb=10, {type="money"} }, + + resolvers.talents{ + [Talents.T_KNOCKBACK]=3, + + [Talents.T_ICE_STORM]=2, + [Talents.T_FREEZE]=3, + + [Talents.T_ICE_CLAW]={base=4, every=6}, + [Talents.T_ICY_SKIN]={base=3, every=7}, + [Talents.T_ICE_BREATH]={base=4, every=5}, + }, + resolvers.sustains_at_birth(), + + autolevel = "warriormage", + ai = "tactical", ai_state = { talent_in=1, ai_move="move_astar", }, + resolvers.inscriptions(1, "infusion"), + + on_die = function(self, who) + game.state:activateBackupGuardian("MASSOK", 4, 43, "I have heard there is a dragon hunter in the Daikara that is unhappy about the wyrm being already dead.") + game.player:resolveSource():grantQuest("starter-zones") + game.player:resolveSource():setQuestStatus("starter-zones", engine.Quest.COMPLETED, "daikara") + end, +} + newEntity{ base="BASE_NPC_ORC_GRUSHNAK", define_as = "MASSOK", allow_infinite_dungeon = true, name = "Massok the Dragonslayer", color=colors.VIOLET, unique = true, diff --git a/game/modules/tome/data/zones/daikara/zone.lua b/game/modules/tome/data/zones/daikara/zone.lua index 264fcba8c3792f72b9e0cebb86e328a4867df615..c175aa3bc494a7ff5b6fb28fc405c43bd1e8da7e 100644 --- a/game/modules/tome/data/zones/daikara/zone.lua +++ b/game/modules/tome/data/zones/daikara/zone.lua @@ -17,6 +17,10 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org +local layout = game.state:alternateZone(short_name, {"VOLCANO", 2}) +layout="VOLCANO" +local is_volcano = layout == "VOLCANO" + return { name = "Daikara", level_range = {7, 16}, @@ -32,6 +36,7 @@ return { ambient_music = "World of Ice.ogg", min_material_level = function() return game.state:isAdvanced() and 4 or 2 end, max_material_level = function() return game.state:isAdvanced() and 5 or 3 end, + is_volcano = is_volcano, generator = { map = { class = "engine.generator.map.Roomer", @@ -40,7 +45,7 @@ return { rooms = {"forest_clearing", "rocky_snowy_trees", {"lesser_vault",7}}, rooms_config = {forest_clearing={pit_chance=5, filters={{}}}}, lesser_vaults_list = {"snow-giant-camp"}, - ['.'] = "ROCKY_GROUND", + ['.'] = function() if rng.percent(5 + game.level.level * 6) then return "LAVA_FLOOR" else return "ROCKY_GROUND" end end, ['T'] = "ROCKY_SNOWY_TREE", ['#'] = "MOUNTAIN_WALL", up = "ROCKY_UP2", @@ -50,7 +55,9 @@ return { actor = { class = "mod.class.generator.actor.Random", nb_npc = {20, 30}, - guardian = "RANTHA_THE_WORM", + guardian = is_volcano and "VARSHA_THE_WRITHING" or "RANTHA_THE_WORM", +intentionaly breakso I rememebr to finis this +make the last level a caldera }, object = { class = "engine.generator.object.Random", @@ -100,4 +107,11 @@ return { game.state:makeWeather(level, 6, {max_nb=7, chance=1, dir=120, speed={0.1, 0.9}, alpha={0.2, 0.4}, particle_name="weather/grey_cloud_%02d"}) end, + + on_enter = function(lev) + if lev == 1 and not game.level.data.warned and game.zone.is_volcano then + game.level.data.warned = true + require("engine.ui.Dialog"):simpleLongPopup("BOOM!", "As you walk toward the Daikara you can not fail to notice the huge volcano that erupts in the center of it, right where the path is taking you.", 400) + end + end, }