diff --git a/game/modules/tome/data/birth/classes/wilder.lua b/game/modules/tome/data/birth/classes/wilder.lua index 0b6bb978e587671e5da9c02fd92f4ec09729f187..4730169abc430fb316be2cc813bd458f6754dec0 100644 --- a/game/modules/tome/data/birth/classes/wilder.lua +++ b/game/modules/tome/data/birth/classes/wilder.lua @@ -123,6 +123,8 @@ newBirthDescriptor{ ["wild-gift/fire-drake"]={true, 0.3}, ["wild-gift/cold-drake"]={true, 0.3}, ["wild-gift/storm-drake"]={true, 0.3}, + ["wild-gift/venom-drake"]={true, 0.3}, + ["wild-gift/higher-draconic"]={false, 0.3}, ["wild-gift/fungus"]={true, 0.1}, ["cunning/survival"]={false, 0}, ["technique/shield-offense"]={true, 0.1}, diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 9076bd78db1e948eb9d382e998bcbf70f416b4e5..b1dcb20f5511cd3d36631a2e05e99c17c13585e4 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -21,7 +21,7 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr) if not game.level.map:isBound(x, y) then return 0 end local terrain = game.level.map(x, y, Map.TERRAIN) - if terrain then terrain:check("damage_project", src, x, y, type, dam) end + if terrain then terrain:check("da", src, x, y, type, dam) end local target = game.level.map(x, y, Map.ACTOR) if target then @@ -2338,3 +2338,31 @@ newDamageType{ end end, } + +newDamageType{ + name = "acid disarm", type = "ACID_DISARM", text_color = "#GREEN#", + projector = function(src, x, y, type, dam) + local realdam = DamageType:get(DamageType.ACID).projector(src, x, y, DamageType.ACID, dam) + local target = game.level.map(x, y, Map.ACTOR) + if target and rng.percent(50) then + if target:canBe("disarm") then + target:setEffect(target.EFF_DISARMED, 3, {src=src, apply_power=src:combatMindpower()}) + else + game.logSeen(target, "%s resists!", target.name:capitalize()) + end + end + return realdam + end, +} + +-- Acid damage + Accuracy/Defense/Armor Down Corrosion +newDamageType{ + name = "corrosive acid", type = "ACID_CORRODE", + projector = function(src, x, y, type, dam, tmp) + local target = game.level.map(x, y, Map.ACTOR) + if target then + DamageType:get(DamageType.ACID).projector(src, x, y, DamageType.ACID, dam.dam) + target:setEffect(target.EFF_CORRODE, dam.dur, {atk=dam.atk, armor=dam.armor, defense=dam.defense, apply_power=src:combatMindpower()}) + end + end, +} diff --git a/game/modules/tome/data/general/npcs/all.lua b/game/modules/tome/data/general/npcs/all.lua index e1c4797508ce163aabfe6bab9b0cd201147fac21..f9a14a679701b834c9259cff19ced279f6d42556 100644 --- a/game/modules/tome/data/general/npcs/all.lua +++ b/game/modules/tome/data/general/npcs/all.lua @@ -77,6 +77,7 @@ loadIfNot("/data/general/npcs/swarm.lua") loadIfNot("/data/general/npcs/thieve.lua") loadIfNot("/data/general/npcs/troll.lua") loadIfNot("/data/general/npcs/vampire.lua") +loadIfNot("/data/general/npcs/venom-drake.lua") loadIfNot("/data/general/npcs/vermin.lua") loadIfNot("/data/general/npcs/wight.lua") loadIfNot("/data/general/npcs/wild-drake.lua") diff --git a/game/modules/tome/data/general/npcs/venom-drake.lua b/game/modules/tome/data/general/npcs/venom-drake.lua new file mode 100644 index 0000000000000000000000000000000000000000..f2b49c8922a03111a329fa2298a4862c136f7caa --- /dev/null +++ b/game/modules/tome/data/general/npcs/venom-drake.lua @@ -0,0 +1,114 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010, 2011, 2012 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 Talents = require("engine.interface.ActorTalents") + +newEntity{ + define_as = "BASE_NPC_VENOM_DRAKE", + type = "dragon", subtype = "venom", + display = "D", color=colors.WHITE, + + body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, + resolvers.drops{chance=100, nb=1, {type="money"} }, + + infravision = 10, + life_rating = 15, + rank = 2, + size_category = 5, + + autolevel = "drake", + ai = "dumb_talented_simple", ai_state = { ai_move="move_dmap", talent_in=2, }, + stats = { str=20, dex=20, mag=30, con=16 }, + + resists = { [DamageType.ACID] = 100, }, + + knockback_immune = 1, + stun_immune = 0.5, + blind_immune = 0.5, +} + +newEntity{ base = "BASE_NPC_VENOM_DRAKE", + name = "venom drake hatchling", color=colors.GREEN, display="d", + desc = [[A corrosive venom drake hatchling; not too powerful by itself, but it usually comes with its brothers and sisters.]], + level_range = {8, nil}, exp_worth = 1, + rarity = 1, + rank = 1, size_category = 2, + max_life = resolvers.rngavg(40,60), + combat_armor = 5, combat_def = 0, + combat = { dam=resolvers.levelup(resolvers.rngavg(25,40), 1, 0.6), atk=resolvers.rngavg(25,60), apr=25, dammod={str=1.1} }, + on_melee_hit = {[DamageType.ACID]=resolvers.mbonus(7, 2)}, + + make_escort = { + {type="dragon", subtype="acid", name="acid drake hatchling", number=3, no_subescort=true}, + }, +} + +newEntity{ base = "BASE_NPC_VENOM_DRAKE", + name = "venom drake", color=colors.GREEN, display="D", + desc = [[A mature corrosive venom drake, armed with a deadly breath weapon and nasty claws.]], + level_range = {14, nil}, exp_worth = 1, + rarity = 3, + max_life = resolvers.rngavg(100,110), + combat_armor = 12, combat_def = 0, + combat = { dam=resolvers.levelup(resolvers.rngavg(25,70), 1, 1.2), atk=resolvers.rngavg(25,70), apr=25, dammod={str=1.1} }, + on_melee_hit = {[DamageType.ACID]=resolvers.mbonus(15, 10)}, + stats_per_level = 4, + lite = 1, + + make_escort = { + {type="dragon", name="acid drake hatchling", number=1}, + }, + + resolvers.talents{ + [Talents.T_ACIDIC_SPRAY]={base=2, every=5, max=7}, + [Talents.T_CORROSIVE_BREATH]={base=3, every=5, max=9}, + }, +} + +newEntity{ base = "BASE_NPC_VENOM_DRAKE", + name = "venom wyrm", color=colors.LIGHT_GREEN, display="D", + desc = [[An old and powerful corrosive venom drake, armed with a deadly breath weapon and nasty claws.]], + resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/dragon_venom_venom_wyrm.png", display_h=2, display_y=-1}}}, + level_range = {25, nil}, exp_worth = 1, + rarity = 5, + rank = 3, + max_life = resolvers.rngavg(170,190), + combat_armor = 30, combat_def = 0, + on_melee_hit = {[DamageType.ACID]=resolvers.mbonus(25, 10)}, + combat = { dam=resolvers.levelup(resolvers.rngavg(25,110), 1, 2), atk=resolvers.rngavg(25,70), apr=25, dammod={str=1.1} }, + stats_per_level = 5, + lite = 1, + stun_immune = 0.8, + blind_immune = 0.8, + + ai = "tactical", + ai_tactic = resolvers.tactic"melee", + + make_escort = { + {type="dragon", name="venom drake", number=1}, + {type="dragon", name="venom drake", number=1, no_subescort=true}, + }, + + resolvers.talents{ + [Talents.T_ACIDIC_SPRAY]={base=5, every=7}, + [Talents.T_CORROSIVE_MIST]={base=5, every=5}, + [Talents.T_CORROSIVE_BREATH]={base=5, every=4}, + [Talents.T_DISSOLVE]={base=5, every=6}, + }, +} diff --git a/game/modules/tome/data/gfx/particles/acidbeam.lua b/game/modules/tome/data/gfx/particles/acidbeam.lua new file mode 100644 index 0000000000000000000000000000000000000000..b72f6537b2330860b34f66511fa82a378e3d5687 --- /dev/null +++ b/game/modules/tome/data/gfx/particles/acidbeam.lua @@ -0,0 +1,59 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010, 2011, 2012 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 + +-- Make the ray +local ray = {} +local tiles = math.ceil(math.sqrt(tx*tx+ty*ty)) +local tx = tx * engine.Map.tile_w +local ty = ty * engine.Map.tile_h +local breakdir = math.rad(rng.range(-8, 8)) +ray.dir = math.atan2(ty, tx) +ray.size = math.sqrt(tx*tx+ty*ty) + +-- Populate the beam based on the forks +return { generator = function() + local a = ray.dir + local rad = rng.range(-3,3) + local ra = math.rad(rad) + local r = rng.range(1, ray.size) + + return { + life = 20, + size = rng.range(4, 6), sizev = -0.1, sizea = 0, + + x = r * math.cos(a) + 2 * math.cos(ra), xv = 0, xa = 0, + y = r * math.sin(a) + 2 * math.sin(ra), yv = 0, ya = 0, + dir = rng.percent(50) and ray.dir + math.rad(rng.range(50, 130)) or ray.dir - math.rad(rng.range(50, 130)), dirv = 0, dira = 0, + vel = rng.percent(30) and 1 or 0, velv = -0.1, vela = 0.01, + + r = rng.range(0, 60)/255, rv = 0, ra = 0, + g = rng.range(100, 170)/255, gv = 0, ga = 0, + b = rng.range(0, 60)/255, bv = 0, ba = 0, + a = rng.range(80, 220)/255, av = 0, aa = 0, + } +end, }, +function(self) + self.nb = (self.nb or 0) + 1 + if self.nb < 6 then + self.ps:emit(30*tiles) + end +end, +10*35*tiles, +"particle_torus" + diff --git a/game/modules/tome/data/gfx/particles/acidstorm.lua b/game/modules/tome/data/gfx/particles/acidstorm.lua new file mode 100644 index 0000000000000000000000000000000000000000..c94593ad9d9b33bc74327a9fe2ec73aecd93454d --- /dev/null +++ b/game/modules/tome/data/gfx/particles/acidstorm.lua @@ -0,0 +1,50 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010, 2011, 2012 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 + +base_size = 32 + +return { generator = function() + local ad = rng.range(0, 360) + local a = math.rad(ad) + local dir = math.rad(ad + 90) + local r = rng.avg(1, 40 * 3) + local dirv = math.rad(5) + + return { + trail = 1, + life = 20, + size = rng.range(3, 6), sizev = -0.1, sizea = 0, + + x = r * math.cos(a), xv = 0, xa = 0, + y = r * math.sin(a), yv = 0, ya = 0, + dir = dir, dirv = dirv, dira = 0, + vel = 3, velv = 0, vela = 0, + + r = rng.range(0, 0)/255, rv = 0, ra = 0, + g = rng.range(80, 140)/255, gv = 0.005, ga = 0.0005, + b = rng.range(0, 0)/255, bv = 0, ba = 0, + a = rng.range(155, 255)/255, av = 0, aa = 0.005, + } +end, }, +function(self) + self.ps:emit(10) +end, +500, +"particle_torus" + diff --git a/game/modules/tome/data/gfx/talents/acidic_spray.png b/game/modules/tome/data/gfx/talents/acidic_spray.png new file mode 100644 index 0000000000000000000000000000000000000000..c08522f835e9e20e4ffa092eb40b8ae1b058aaff Binary files /dev/null and b/game/modules/tome/data/gfx/talents/acidic_spray.png differ diff --git a/game/modules/tome/data/gfx/talents/chromatic_fury.png b/game/modules/tome/data/gfx/talents/chromatic_fury.png new file mode 100644 index 0000000000000000000000000000000000000000..e5940f52463971060db68ef3fc9bca2cd98ef767 Binary files /dev/null and b/game/modules/tome/data/gfx/talents/chromatic_fury.png differ diff --git a/game/modules/tome/data/gfx/talents/corrosive_breath.png b/game/modules/tome/data/gfx/talents/corrosive_breath.png new file mode 100644 index 0000000000000000000000000000000000000000..d09b03e487be63980c75c60dd0d2739e96f7bbb4 Binary files /dev/null and b/game/modules/tome/data/gfx/talents/corrosive_breath.png differ diff --git a/game/modules/tome/data/gfx/talents/corrosive_mist.png b/game/modules/tome/data/gfx/talents/corrosive_mist.png new file mode 100644 index 0000000000000000000000000000000000000000..1c83086b61a4d6dd4584ca6caca537d9397abb03 Binary files /dev/null and b/game/modules/tome/data/gfx/talents/corrosive_mist.png differ diff --git a/game/modules/tome/data/gfx/talents/dissolve.png b/game/modules/tome/data/gfx/talents/dissolve.png new file mode 100644 index 0000000000000000000000000000000000000000..465637fb507a124ae2f2f17f09ad4d8a9ac5d8af Binary files /dev/null and b/game/modules/tome/data/gfx/talents/dissolve.png differ diff --git a/game/modules/tome/data/gfx/talents/prismatic_slash.png b/game/modules/tome/data/gfx/talents/prismatic_slash.png new file mode 100644 index 0000000000000000000000000000000000000000..96ea0cc041f437d8555c2c49fcb7c49216f64e92 Binary files /dev/null and b/game/modules/tome/data/gfx/talents/prismatic_slash.png differ diff --git a/game/modules/tome/data/gfx/talents/venomous_breath.png b/game/modules/tome/data/gfx/talents/venomous_breath.png new file mode 100644 index 0000000000000000000000000000000000000000..69d0556c776ccd4570eb086fb276d98775ebd396 Binary files /dev/null and b/game/modules/tome/data/gfx/talents/venomous_breath.png differ diff --git a/game/modules/tome/data/gfx/talents/wyrmic_guile.png b/game/modules/tome/data/gfx/talents/wyrmic_guile.png new file mode 100644 index 0000000000000000000000000000000000000000..e0914767c1a14a7a043b4b33d45bc0802703c757 Binary files /dev/null and b/game/modules/tome/data/gfx/talents/wyrmic_guile.png differ diff --git a/game/modules/tome/data/talents/gifts/gifts.lua b/game/modules/tome/data/talents/gifts/gifts.lua index e0f539b9a992253b5079205dcf45d251d082b978..dc20b204a12d906c4148ebf070f8b119689947d2 100644 --- a/game/modules/tome/data/talents/gifts/gifts.lua +++ b/game/modules/tome/data/talents/gifts/gifts.lua @@ -32,6 +32,8 @@ newTalentType{ allow_random=true, is_nature=true, type="wild-gift/sand-drake", n newTalentType{ allow_random=true, is_nature=true, type="wild-gift/fire-drake", name = "fire drake aspect", description = "Take on the defining aspects of a Fire Drake." } newTalentType{ allow_random=true, is_nature=true, type="wild-gift/cold-drake", name = "cold drake aspect", description = "Take on the defining aspects of a Cold Drake." } newTalentType{ allow_random=true, is_nature=true, type="wild-gift/storm-drake", name = "storm drake aspect", description = "Take on the defining aspects of a Storm Drake." } +newTalentType{ allow_random=true, is_nature=true, type="wild-gift/venom-drake", name = "venom drake aspect", description = "Take on the defining aspects of a Venom Drake." } +newTalentType{ allow_random=true, is_nature=true, type="wild-gift/higher-draconic", name = "higher draconic abilities", description = "Take on the aspects of aged and powerful dragons." } newTalentType{ allow_random=true, is_nature=true, type="wild-gift/mindstar-mastery", name = "mindstar mastery", generic = true, description = "Learn to channel your mental power through mindstars, forming powerful psionic blades." } newTalentType{ allow_random=true, is_nature=true, type="wild-gift/mucus", name = "mucus", description = "Cover the floor with natural mucus." } newTalentType{ allow_random=true, is_nature=true, type="wild-gift/ooze", name = "ooze", description = "Your body and internal organs are becoming more ooze-like in nature, allowing you to spawn more of you." } @@ -201,6 +203,8 @@ load("/data/talents/gifts/sand-drake.lua") load("/data/talents/gifts/fire-drake.lua") load("/data/talents/gifts/cold-drake.lua") load("/data/talents/gifts/storm-drake.lua") +load("/data/talents/gifts/venom-drake.lua") +load("/data/talents/gifts/higher-draconic.lua") load("/data/talents/gifts/summon-melee.lua") load("/data/talents/gifts/summon-distance.lua") diff --git a/game/modules/tome/data/talents/gifts/higher-draconic.lua b/game/modules/tome/data/talents/gifts/higher-draconic.lua new file mode 100644 index 0000000000000000000000000000000000000000..5678e9379ce821601713abaf08d6167dca69e78b --- /dev/null +++ b/game/modules/tome/data/talents/gifts/higher-draconic.lua @@ -0,0 +1,210 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010, 2011, 2012 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 + +newTalent{ + name = "Prismatic Slash", + type = {"wild-gift/higher-draconic", 1}, + require = gifts_req_high1, + points = 5, + random_ego = "attack", + equilibrium = 20, + cooldown = 16, + range = 1, + tactical = { ATTACK = { PHYSICAL = 1, COLD = 1, FIRE = 1, LIGHTNING = 1, ACID = 1 } }, + requires_target = true, + getWeaponDamage = function(self, t) return self:combatTalentWeaponDamage(t, 1.2, 2.0) end, + getBurstDamage = function(self, t) return self:combatTalentMindDamage(t, 20, 230) end, + radius = function(self, t) + return 1 + self:getTalentLevel(t) / 2 + end, + on_learn = function(self, t) + self.combat_physresist = self.combat_physresist + 1 + self.combat_spellresist = self.combat_spellresist + 1 + self.combat_mentalresist = self.combat_mentalresist + 1 + end, + on_unlearn = function(self, t) + self.combat_physresist = self.combat_physresist - 1 + self.combat_spellresist = self.combat_spellresist - 1 + self.combat_mentalresist = self.combat_mentalresist - 1 + end, + action = function(self, t) + + local tg = {type="hit", range=self:getTalentRange(t)} + local x, y, target = self:getTarget(tg) + if not x or not y or not target then return nil end + if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end + + local elem = rng.table{"phys", "cold", "fire", "lightning", "acid",} + + if elem == "phys" then + self:attackTarget(target, DamageType.PHYSICAL, t.getWeaponDamage(self, t), true) + local tg = {type="ball", range=1, selffire=false, radius=self:getTalentRadius(t), talent=t} + local grids = self:project(tg, x, y, DamageType.SAND, {dur=3, dam=self:mindCrit(t.getBurstDamage(self, t))}) + game.level.map:particleEmitter(x, y, tg.radius, "ball_matter", {radius=tg.radius, grids=grids, tx=x, ty=y, max_alpha=80}) + game:playSoundNear(self, "talents/flame") + elseif elem == "cold" then + self:attackTarget(target, DamageType.ICE, t.getWeaponDamage(self, t), true) + local tg = {type="ball", range=1, selffire=false, radius=self:getTalentRadius(t), talent=t} + local grids = self:project(tg, x, y, DamageType.ICE, self:mindCrit(t.getBurstDamage(self, t))) + game.level.map:particleEmitter(x, y, tg.radius, "ball_ice", {radius=tg.radius, grids=grids, tx=x, ty=y, max_alpha=80}) + game:playSoundNear(self, "talents/flame") + elseif elem == "fire" then + self:attackTarget(target, DamageType.FIREBURN, t.getWeaponDamage(self, t), true) + local tg = {type="ball", range=1, selffire=false, radius=self:getTalentRadius(t), talent=t} + local grids = self:project(tg, x, y, DamageType.FIREBURN, self:mindCrit(t.getBurstDamage(self, t))) + game.level.map:particleEmitter(x, y, tg.radius, "ball_fire", {radius=tg.radius, grids=grids, tx=x, ty=y, max_alpha=80}) + game:playSoundNear(self, "talents/flame") + elseif elem == "lightning" then + self:attackTarget(target, DamageType.LIGHTNING_DAZE, t.getWeaponDamage(self, t), true) + local tg = {type="ball", range=1, selffire=false, radius=self:getTalentRadius(t), talent=t} + local grids = self:project(tg, x, y, DamageType.LIGHTNING_DAZE, self:mindCrit(t.getBurstDamage(self, t))) + game.level.map:particleEmitter(x, y, tg.radius, "ball_lightning", {radius=tg.radius, grids=grids, tx=x, ty=y, max_alpha=80}) + game:playSoundNear(self, "talents/flame") + elseif elem == "acid" then + self:attackTarget(target, DamageType.ACID_DISARM, t.getWeaponDamage(self, t), true) + local tg = {type="ball", range=1, selffire=false, radius=self:getTalentRadius(t), talent=t} + local grids = self:project(tg, x, y, DamageType.ACID_DISARM, self:mindCrit(t.getBurstDamage(self, t))) + game.level.map:particleEmitter(x, y, tg.radius, "ball_acid", {radius=tg.radius, grids=grids, tx=x, ty=y, max_alpha=80}) + game:playSoundNear(self, "talents/flame") + end + return true + end, + info = function(self, t) + local burstdamage = t.getBurstDamage(self, t) + local radius = self:getTalentRadius(t) + return ([[Unleash raw, chaotic elemental damage upon your enemy. + You strike your enemy for %d%% weapon damage in one of blinding sand, disarming acid, freezing ice, stunning lightning or burning flames, with equal odds. + Additionally, you will cause a burst of that deals %0.2f of that damage to enemies in radius %d, regardless of if you hit with the blow. + Each point in Prismatic Slash increase your physical, spell and mind saves by 1.]]):format(100 * self:combatTalentWeaponDamage(t, 1.2, 2.0), burstdamage, radius) + end, +} + +newTalent{ + name = "Venomous Breath", + type = {"wild-gift/higher-draconic", 2}, + require = gifts_req_high2, + points = 5, + random_ego = "attack", + equilibrium = 12, + cooldown = 12, + message = "@Source@ breathes venom!", + tactical = { ATTACKAREA = { poison = 2 } }, + range = 0, + radius = function(self, t) return 4 + self:getTalentLevelRaw(t) end, + direct_hit = true, + requires_target = true, + getDamage = function(self, t) return self:combatTalentStatDamage(t, "str", 60, 650) end, + getEffect = function(self, t) return 10 + self:getTalentLevel(t) * 8 end, + on_learn = function(self, t) self.resists[DamageType.NATURE] = (self.resists[DamageType.NATURE] or 0) + 2 end, + on_unlearn = function(self, t) self.resists[DamageType.NATURE] = (self.resists[DamageType.NATURE] or 0) - 2 end, + target = function(self, t) + return {type="cone", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false, talent=t} + end, + action = function(self, t) + local tg = self:getTalentTarget(t) + local x, y = self:getTarget(tg) + if not x or not y then return nil end + self:project(tg, x, y, DamageType.INSIDIOUS_POISON, {dam=self:mindCrit(t.getDamage(self,t)), dur=6, heal_factor=t.getEffect(self,t)}) + game.level.map:particleEmitter(self.x, self.y, tg.radius, "breath_slime", {radius=tg.radius, tx=x-self.x, ty=y-self.y}) + game:playSoundNear(self, "talents/breath") + return true + end, + info = function(self, t) + local effect = t.getEffect(self, t) + return ([[You breathe insidious poison in a frontal cone of radius %d. Any target caught in the area will take %0.2f nature damage each turn for 6 turns. + The poison also reduces the healing of enemies poisoned by %d%% while it is in effect. + The damage will increase with the Strength stat. + Each point in Venomous Breath also increases your nature resistance by 2%%.]]):format(self:getTalentRadius(t), damDesc(self, DamageType.NATURE, self:combatTalentStatDamage(t, "str", 60, 750)/6), effect) + end, +} + +newTalent{ + name = "Wyrmic Guile", + type = {"wild-gift/higher-draconic", 3}, + require = gifts_req_high3, + points = 5, + mode = "passive", + on_learn = function(self, t) + self.inc_stats[self.STAT_CUN] = self.inc_stats[self.STAT_CUN] + 2 + self:onStatChange(self.STAT_CUN, 2) + self.stun_immune = (self.stun_immune or 0) + .05 + self.blind_immune = (self.blind_immune or 0) + .05 + self.knockback_immune = (self.knockback_immune or 0) + .1 + end, + on_unlearn = function(self, t) + self.inc_stats[self.STAT_CUN] = self.inc_stats[self.STAT_CUN] - 2 + self:onStatChange(self.STAT_CUN, -2) + self.stun_immune = (self.stun_immune or 0) - .05 + self.blind_immune = (self.blind_immune or 0) - .05 + self.knockback_immune = (self.knockback_immune or 0) - .1 + end, + info = function(self, t) + return ([[You have the mental prowess of a Wyrm. + Increases Cunning by %d. + Each point in Wyrmic Guile also increases your knockback resistance by 10%%, and your blindness and stun resistances by 5%%.]]):format(4*self:getTalentLevelRaw(t)) + end, +} + +newTalent{ + name = "Chromatic Fury", + type = {"wild-gift/higher-draconic", 4}, + require = gifts_req_high4, + points = 5, + mode = "passive", + on_learn = function(self, t) + self.resists[DamageType.PHYSICAL] = (self.resists[DamageType.PHYSICAL] or 0) + 0.5 + self.resists[DamageType.COLD] = (self.resists[DamageType.COLD] or 0) + 0.5 + self.resists[DamageType.FIRE] = (self.resists[DamageType.FIRE] or 0) + 0.5 + self.resists[DamageType.LIGHTNING] = (self.resists[DamageType.LIGHTNING] or 0) + 0.5 + self.resists[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) + 0.5 + self.resists_pen[DamageType.PHYSICAL] = (self.resists[DamageType.PHYSICAL] or 0) + 4 + self.resists_pen[DamageType.COLD] = (self.resists[DamageType.COLD] or 0) + 4 + self.resists_pen[DamageType.FIRE] = (self.resists[DamageType.FIRE] or 0) + 4 + self.resists_pen[DamageType.LIGHTNING] = (self.resists[DamageType.LIGHTNING] or 0) + 4 + self.resists_pen[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) + 4 + self.inc_damage[DamageType.PHYSICAL] = (self.resists[DamageType.PHYSICAL] or 0) + 2 + self.inc_damage[DamageType.COLD] = (self.resists[DamageType.COLD] or 0) + 2 + self.inc_damage[DamageType.FIRE] = (self.resists[DamageType.FIRE] or 0) + 2 + self.inc_damage[DamageType.LIGHTNING] = (self.resists[DamageType.LIGHTNING] or 0) + 2 + self.inc_damage[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) + 2 + end, + on_unlearn = function(self, t) + self.resists[DamageType.PHYSICAL] = (self.resists[DamageType.PHYSICAL] or 0) - 0.5 + self.resists[DamageType.COLD] = (self.resists[DamageType.COLD] or 0) - 0.5 + self.resists[DamageType.FIRE] = (self.resists[DamageType.FIRE] or 0) - 0.5 + self.resists[DamageType.LIGHTNING] = (self.resists[DamageType.LIGHTNING] or 0) - 0.5 + self.resists[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) - 0.5 + self.resists_pen[DamageType.PHYSICAL] = (self.resists[DamageType.PHYSICAL] or 0) - 4 + self.resists_pen[DamageType.COLD] = (self.resists[DamageType.COLD] or 0) - 4 + self.resists_pen[DamageType.FIRE] = (self.resists[DamageType.FIRE] or 0) - 4 + self.resists_pen[DamageType.LIGHTNING] = (self.resists[DamageType.LIGHTNING] or 0) - 4 + self.resists_pen[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) - 4 + self.inc_damage[DamageType.PHYSICAL] = (self.resists[DamageType.PHYSICAL] or 0) - 2 + self.inc_damage[DamageType.COLD] = (self.resists[DamageType.COLD] or 0) - 2 + self.inc_damage[DamageType.FIRE] = (self.resists[DamageType.FIRE] or 0) - 2 + self.inc_damage[DamageType.LIGHTNING] = (self.resists[DamageType.LIGHTNING] or 0) - 2 + self.inc_damage[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) - 2 + end, + info = function(self, t) + return ([[You have gained the full power of the multihued dragon, and your mastery over the elements is complete. + Increases physical, fire, cold, lightning and acid damage by %d%%, and your resistance penetration in those elements by %d%%. + Each point in Chromatic Fury also increases your resistances to physical, fire, cold, lightning and acid by 0.5%%.]]) + :format(2*self:getTalentLevelRaw(t), 4*self:getTalentLevelRaw(t)) + end, +} diff --git a/game/modules/tome/data/talents/gifts/venom-drake.lua b/game/modules/tome/data/talents/gifts/venom-drake.lua new file mode 100644 index 0000000000000000000000000000000000000000..b25107f9e0a0fe9a318466cc77c33a5720004527 --- /dev/null +++ b/game/modules/tome/data/talents/gifts/venom-drake.lua @@ -0,0 +1,193 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010, 2011, 2012 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 + +newTalent{ + name = "Acidic Spray", + type = {"wild-gift/venom-drake", 1}, + require = gifts_req1, + points = 5, + random_ego = "attack", + message = "@Source@ spits acid!", + equilibrium = 3, + cooldown = function(self, t) return math.floor(8 - self:getTalentLevel(t)/3) end, + tactical = { ATTACK = { ACID = 2 } }, + range = function(self, t) return math.floor(5 + self:getTalentLevel(t)/2) end, + on_learn = function(self, t) self.resists[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) + 1 end, + on_unlearn = function(self, t) self.resists[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) - 1 end, + direct_hit = function(self, t) if self:getTalentLevel(t) >= 5 then return true else return false end end, + requires_target = true, + target = function(self, t) + local tg = {type="bolt", range=self:getTalentRange(t), talent=t} + if self:getTalentLevel(t) >= 5 then tg.type = "beam" end + return tg + end, + getDamage = function(self, t) return self:combatTalentMindDamage(t, 25, 250) end, + action = function(self, t) + local tg = self:getTalentTarget(t) + local x, y = self:getTarget(tg) + if not x or not y then return nil end + self:project(tg, x, y, DamageType.ACID_DISARM, self:mindCrit(t.getDamage(self, t)), nil) + local _ _, x, y = self:canProject(tg, x, y) + if tg.type == "beam" then + game.level.map:particleEmitter(self.x, self.y, math.max(math.abs(x-self.x), math.abs(y-self.y)), "acidbeam", {tx=x-self.x, ty=y-self.y}) + else + game.level.map:particleEmitter(x, y, 1, "acid") + end + game:playSoundNear(self, "talents/cloud") + return true + end, + info = function(self, t) + local damage = t.getDamage(self, t) + return ([[Spray forth a glob of acidic moisture at your enemy. + The target will take %0.2f mindpower-based acid damage. + Enemies struck have a 50%% chance to be Disarmed for three turns, as their weapon is rendered useless by an acid coating. + At Talent Level 5, this becomes a piercing line of acid. + Each point in acid drake talents also increases your acid resistance by 1%%.]]):format(damDesc(self, DamageType.ACID, damage)) + end, +} + +newTalent{ + name = "Corrosive Mist", + type = {"wild-gift/venom-drake", 2}, + require = gifts_req2, + points = 5, + random_ego = "attack", + equilibrium = 15, + cooldown = 25, + tactical = { ATTACKAREA = { ACID = 2 } }, + range = 0, + on_learn = function(self, t) self.resists[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) + 1 end, + on_unlearn = function(self, t) self.resists[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) - 1 end, + radius = function(self, t) return 2 + self:getTalentLevel(t)/2 end, + requires_target = true, + getDamage = function(self, t) return self:combatTalentMindDamage(t, 10, 70) end, + getDuration = function(self, t) return 6 + self:combatMindpower(0.04) + (self:getTalentLevel(t)/2) end, + getCorrodeDur = function(self, t) return 2 + (self:getTalentLevel(t)/3) end, + getAtk = function(self, t) return self:combatTalentMindDamage(t, 2, 20) end, + getArmor = function(self, t) return self:combatTalentMindDamage(t, 2, 20) end, + getDefense = function(self, t) return self:combatTalentMindDamage(t, 2, 20) end, + target = function(self, t) + return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false} + end, + action = function(self, t) + local damage = self:mindCrit(t.getDamage(self, t)) + local duration = t.getDuration(self, t) + local cordur = t.getCorrodeDur(self, t) + local atk = t.getAtk(self, t) + local armor = t.getArmor(self, t) + local defense = t.getDefense(self, t) + local actor = self + local radius = 2 + self:getTalentLevel(t)/2 + -- Add a lasting map effect + game.level.map:addEffect(self, + self.x, self.y, duration, + DamageType.ACID_CORRODE, {dam=damage, dur=cordur, atk=atk, armor=armor, defense=defense}, + radius, + 5, nil, + {type="acidstorm", only_one=true}, + function(e) + e.x = e.src.x + e.y = e.src.y + return true + end, + false + ) + game:playSoundNear(self, "talents/cloud") + return true + end, + info = function(self, t) + local damage = t.getDamage(self, t) + local duration = t.getDuration(self, t) + local cordur = t.getCorrodeDur(self, t) + local atk = t.getAtk(self, t) + local radius = 2 + self:getTalentLevel(t)/2 + return ([[Exhale a mist of lingering acid, dealing %0.2f acid damage in a radius of %d each turn for %d turns. + Enemies in this mist will be corroded for %d turns, lowering their accuracy, their armor and defense by %d. + The damage and duration will increase with mindpower, and the radius will increase with talent level. + Each point in acid drake talents also increases your acid resistance by 1%%.]]):format(damDesc(self, DamageType.ACID, damage), radius, duration, cordur, atk) + end, +} + +newTalent{ + name = "Dissolve", + type = {"wild-gift/venom-drake", 3}, + require = gifts_req3, + points = 5, + random_ego = "attack", + equilibrium = 10, + cooldown = 12, + range = 1, + tactical = { ATTACK = { ACID = 2 } }, + requires_target = true, + on_learn = function(self, t) self.resists[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) + 1 end, + on_unlearn = function(self, t) self.resists[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) - 1 end, + action = function(self, t) + local tg = {type="hit", range=self:getTalentRange(t)} + local x, y, target = self:getTarget(tg) + if not x or not y or not target then return nil end + if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end + + self:attackTarget(target, (self:getTalentLevel(t) >= 2) and DamageType.ACID_BLIND or DamageType.ACID, self:combatTalentWeaponDamage(t, 0.1, 0.60), true) + self:attackTarget(target, (self:getTalentLevel(t) >= 4) and DamageType.ACID_BLIND or DamageType.ACID, self:combatTalentWeaponDamage(t, 0.1, 0.60), true) + self:attackTarget(target, (self:getTalentLevel(t) >= 6) and DamageType.ACID_BLIND or DamageType.ACID, self:combatTalentWeaponDamage(t, 0.1, 0.60), true) + self:attackTarget(target, (self:getTalentLevel(t) >= 8) and DamageType.ACID_BLIND or DamageType.ACID, self:combatTalentWeaponDamage(t, 0.1, 0.60), true) + return true + end, + info = function(self, t) + return ([[You strike the enemy with a rain of fast, acidic blows. You strike four times for pure acid damage. Every blow does %d%% damage. + Every two talent levels, one of your strikes becomes blinding acid, instead of normal acid, blinding the target 25%% of the time if it hits. + Each point in acid drake talents also increases your acid resistance by 1%%.]]):format(100 * self:combatTalentWeaponDamage(t, 0.1, 0.6)) + end, +} + +newTalent{ + name = "Corrosive Breath", + type = {"wild-gift/venom-drake", 4}, + require = gifts_req4, + points = 5, + random_ego = "attack", + equilibrium = 12, + cooldown = 12, + message = "@Source@ breathes acid!", + tactical = { ATTACKAREA = { ACID = 2 } }, + range = 0, + radius = function(self, t) return 4 + self:getTalentLevelRaw(t) end, + direct_hit = true, + requires_target = true, + on_learn = function(self, t) self.resists[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) + 1 end, + on_unlearn = function(self, t) self.resists[DamageType.ACID] = (self.resists[DamageType.ACID] or 0) - 1 end, + target = function(self, t) + return {type="cone", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false, talent=t} + end, + action = function(self, t) + local tg = self:getTalentTarget(t) + local x, y = self:getTarget(tg) + if not x or not y then return nil end + self:project(tg, x, y, DamageType.ACID_DISARM, self:mindCrit(self:combatTalentStatDamage(t, "str", 30, 420))) + game.level.map:particleEmitter(self.x, self.y, tg.radius, "breath_acid", {radius=tg.radius, tx=x-self.x, ty=y-self.y}) + game:playSoundNear(self, "talents/breath") + return true + end, + info = function(self, t) + return ([[You breathe acid in a frontal cone of radius %d. Any target caught in the area will take %0.2f acid damage. + Enemies caught in the acid have a 50%% chance of their weapons becoming useless for three turns. + The damage will increase with the Strength stat. + Each point in acid drake talents also increases your acid resistance by 1%%.]]):format(self:getTalentRadius(t), damDesc(self, DamageType.COLD, self:combatTalentStatDamage(t, "str", 30, 420))) + end, +} \ No newline at end of file diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua index 3ad3e11ecd97d42052e84452caf5fdb2a2dc7743..0d8c3881c27ab2928ca25245b42e8857ccea451b 100644 --- a/game/modules/tome/data/timed_effects/physical.lua +++ b/game/modules/tome/data/timed_effects/physical.lua @@ -2009,3 +2009,20 @@ newEffect{ self:effectTemporaryValue(eff, "inc_damage", {all=eff.power}) end, } + +newEffect{ + name = "CORRODE", image = "talents/blightzone.png", + desc = "Corrode", + long_desc = function(self, eff) return ("The target is corroded, reducing their accuracy by %d, their armor by %d, and their defense by %d."):format(eff.atk, eff.armor, eff.defense) end, + type = "physical", + subtype = { acid=true }, + status = "detrimental", + parameters = { atk=5, armor=5, defense=10 }, no_ct_effect = true, + on_gain = function(self, err) return "#Target# is corroded." end, + on_lose = function(self, err) return "#Target# has shook off the effects of their corrosion." end, + activate = function(self, eff) + self:effectTemporaryValue(eff, "combat_atk", -eff.atk) + self:effectTemporaryValue(eff, "combat_armor", -eff.armor) + self:effectTemporaryValue(eff, "combat_def", -eff.defense) + end, +}