diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 5e2af38e3f3617a6fedb89a1e458cafd87443a0b..d68a13abf4a9f493e64396e41405969b3d3ae1e7 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -48,6 +48,12 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr) dam = dam + (dam * inc / 100) end + -- Rigor mortis + if src.necrotic_minion and target:attr("inc_necrotic_minions") then + dam = dam + dam * target:attr("inc_necrotic_minions") / 100 + print("[PROJECTOR] after necrotic increase dam", dam) + end + -- Blast the iceblock if src.attr and src:attr("encased_in_ice") then local eff = src:hasEffect(src.EFF_FROZEN) @@ -749,6 +755,26 @@ newDamageType{ end, } +-- Darkness damage + repulsion; checks for spell power against mental resistance +newDamageType{ + name = "darkness knockback", type = "DARKKNOCKBACK", + projector = function(src, x, y, type, dam, tmp) + local target = game.level.map(x, y, Map.ACTOR) + if _G.type(dam) ~= "table" then dam = {dam=dam, dist=3} end + tmp = tmp or {} + if target and not tmp[target] then + tmp[target] = true + DamageType:get(DamageType.DARKNESS).projector(src, x, y, DamageType.DARKNESS, dam.dam) + if target:checkHit(src:combatSpellpower(), target:combatMentalResist(), 0, 95, 15) and target:canBe("knockback") then + target:knockback(src.x, src.y, dam.dist) + game.logSeen(target, "%s is knocked back!", target.name:capitalize()) + else + game.logSeen(target, "%s resists the darkness!", target.name:capitalize()) + end + end + end, +} + -- Physical damage + repulsion; checks for spell power against physical resistance newDamageType{ name = "spell knockback", type = "SPELLKNOCKBACK", @@ -1639,3 +1665,18 @@ newDamageType{ end end, } + +-- Darkness damage + speed reduction + minion damage inc +newDamageType{ + name = "rigor mortis", type = "RIGOR_MORTIS", + projector = function(src, x, y, type, dam, tmp) + local target = game.level.map(x, y, Map.ACTOR) + if target then + DamageType:get(DamageType.DARKNESS).projector(src, x, y, DamageType.DARKNESS, dam.dam) + if target:checkHit(src:combatSpellpower(), target:combatSpellResist(), 0, 95, 15) then + target:setEffect(target.EFF_SLOW, dam.dur, {power=dam.speed}) + end + target:setEffect(target.EFF_RIGOR_MORTIS, dam.dur, {power=dam.minion}) + end + end, +} diff --git a/game/modules/tome/data/general/traps/natural_forest.lua b/game/modules/tome/data/general/traps/natural_forest.lua index ab82bd1bec935c78448b36a6b9b81340f283c68f..b7734669c1080be2548ab8764d0c1a9ef0083adb 100644 --- a/game/modules/tome/data/general/traps/natural_forest.lua +++ b/game/modules/tome/data/general/traps/natural_forest.lua @@ -21,7 +21,7 @@ newEntity{ define_as = "TRAP_NATURAL_FOREST", type = "natural", subtype="forest", id_by_type=true, unided_name = "trap", display = '^', triggered = function(self, x, y, who) - self:project({type="hit",x=x,y=y}, x, y, self.damtype, self.dam, self.particles and {type=self.particles}) + self:project({type="hit",x=x,y=y}, x, y, self.damtype, self.dam or 10, self.particles and {type=self.particles}) return true end, } diff --git a/game/modules/tome/data/talents/spells/grave.lua b/game/modules/tome/data/talents/spells/grave.lua index 37a824f1b581632f387962f2aaeb5d4503f21619..bc942387ff53717b983125a687522c3d174d4388 100644 --- a/game/modules/tome/data/talents/spells/grave.lua +++ b/game/modules/tome/data/talents/spells/grave.lua @@ -68,6 +68,7 @@ newTalent{ tactical = { BUFF = 3 }, getParams = function(self, t) return util.bound(30 + self:getTalentLevel(t) * 10, 30, 100), 20 + self:combatTalentSpellDamage(t, 25, 300) end, summon = function(self, t, dam, src, killer) + if not killer or not killer.faction or self:reactionToward(killer) >= 0 then return end local minion = require("mod.class.NPC").new{ name = "will o' the wisp", type = "undead", subtype = "ghost", @@ -106,7 +107,6 @@ newTalent{ minion.on_act = nil minion:setTarget(killer) end - end, activate = function(self, t) local chance, dam = t.getParams(self, t) diff --git a/game/modules/tome/data/talents/spells/nightfall.lua b/game/modules/tome/data/talents/spells/nightfall.lua index 38119e79aa0814b99acfe1891545f745ccb3d20e..a260937e0836c60f00f1130136140c8ad141d0c6 100644 --- a/game/modules/tome/data/talents/spells/nightfall.lua +++ b/game/modules/tome/data/talents/spells/nightfall.lua @@ -122,45 +122,29 @@ newTalent{ points = 5, random_ego = "attack", mana = 40, - cooldown = 8, - tactical = { ATTACKAREA = 2 }, - range = 7, - radius = function(self, t) - return 1 + self:getTalentLevelRaw(t) - end, - proj_speed = 4, + cooldown = 12, direct_hit = true, + tactical = { ATTACK = 2, DISABLE = 2, ESCAPE = 1 }, + range = 0, + radius = function(self, t) return 3 + self:getTalentLevelRaw(t) end, requires_target = true, - target = function(self, t) - return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=self:spellFriendlyFire(), talent=t, display={particle="bolt_fire", trail="firetrail"}} - end, - getDamage = function(self, t) return self:combatTalentSpellDamage(t, 28, 280) end, + target = function(self, t) return {type="cone", range=self:getTalentRange(t), radius=self:getTalentRadius(t), friendlyfire=isFF(self), talent=t} end, + getDamage = function(self, t) return self:combatTalentSpellDamage(t, 10, 230) 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:projectile(tg, x, y, DamageType.FIRE, self:spellCrit(t.getDamage(self, t)), function(self, tg, x, y, grids) - game.level.map:particleEmitter(x, y, tg.radius, "fireflash", {radius=tg.radius, tx=x, ty=y}) - if self:attr("burning_wake") then - game.level.map:addEffect(self, - x, y, 4, - engine.DamageType.INFERNO, self:attr("burning_wake"), - tg.radius, - 5, nil, - {type="inferno"}, - nil, tg.selffire - ) - end - end) - game:playSoundNear(self, "talents/fireflash") + self:project(tg, x, y, DamageType.DARKKNOCKBACK, {dist=4, dam=self:spellCrit(t.getDamage(self, t))}) + game.level.map:particleEmitter(self.x, self.y, tg.radius, "breath_dark", {radius=tg.radius, tx=x-self.x, ty=y-self.y}) + game:playSoundNear(self, "talents/fire") return true end, info = function(self, t) local damage = t.getDamage(self, t) local radius = self:getTalentRadius(t) - return ([[Conjures up a bolt of fire moving toward the target that explodes into a flash of fire doing %0.2f fire damage in a radius of %d. + return ([[Invoke a cone dealing %0.2f darkness damage, any creatures caught inside must make a mental save or be knocked back 4 grids away The damage will increase with the Magic stat]]): - format(damDesc(self, DamageType.FIRE, damage), radius) + format(damDesc(self, DamageType.DARKNESS, damage)) end, } @@ -169,43 +153,35 @@ newTalent{ type = {"spell/nightfall",4}, require = spells_req4, points = 5, - random_ego = "attack", - mana = 100, - cooldown = 30, + mana = 60, + cooldown = 20, tactical = { ATTACKAREA = 3 }, - range = 10, - radius = 5, + range = 7, + radius = 1, direct_hit = true, requires_target = true, - target = function(self, t) - return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t)} - end, - getDamage = function(self, t) return self:combatTalentSpellDamage(t, 15, 80) end, - getDuration = function(self, t) return 5 + self:getTalentLevel(t) end, + target = function(self, t) return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), friendlyfire=isFF(self), talent=t, display={particle="bolt_dark", trail="darktrail"}} end, + getDamage = function(self, t) return self:combatTalentSpellDamage(t, 28, 280) end, + getMinion = function(self, t) return 10 + self:combatTalentSpellDamage(t, 10, 30) end, + getDur = function(self, t) return math.floor(3 + self:getTalentLevel(t)) end, + getSpeed = function(self, t) return math.min(self:getTalentLevel(t) * 0.065, 0.5) 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 - local _ _, _, _, x, y = self:canProject(tg, x, y) - -- Add a lasting map effect - game.level.map:addEffect(self, - x, y, t.getDuration(self, t), - DamageType.INFERNO, t.getDamage(self, t), - self:getTalentRadius(t), - 5, nil, - {type="inferno"}, - nil, self:spellFriendlyFire() - ) - - game:playSoundNear(self, "talents/fire") + self:projectile(tg, x, y, DamageType.RIGOR_MORTIS, {dam=t.getDamage(self, t), minion=t.getMinion(self, t), speed=t.getSpeed(self, t), dur=t.getDur(self, t)}, {type="dark"}) + game:playSoundNear(self, "talents/fireflash") return true end, info = function(self, t) local damage = t.getDamage(self, t) - local duration = t.getDuration(self, t) - local radius = self:getTalentRadius(t) - return ([[Raging flames burn foes and allies alike doing %0.2f fire damage in a radius of %d each turn for %d turns. - The damage will increase with the Magic stat]]): - format(damDesc(self, DamageType.FIRE, damage), radius, duration) + local speed = t.getSpeed(self, t) * 100 + local dur = t.getDur(self, t) + local minion = t.getMinion(self, t) + return ([[Invoke a ball of darkness that deals %0.2f darkness damage. Every creature hit will start to become closer to death and thus reduce global speed by %d%%. + Necrotic minions damage against those creatures is increased by %d%%. + The effects last for %d turns. + The damage done and minions damage increase will increase with the Magic stat]]): + format(damDesc(self, DamageType.DARKNESS, damage), speed, minion, dur) end, } diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua index 3b43d011e04066cfdd2fdf0daa2f068ea573b3a6..62359fbb864c60c3b11377947fff94013f380427 100644 --- a/game/modules/tome/data/timed_effects.lua +++ b/game/modules/tome/data/timed_effects.lua @@ -4370,3 +4370,20 @@ newEffect{ self:removeTemporaryValue("no_healing", eff.healid) end, } + +newEffect{ + name = "RIGOR_MORTIS", + desc = "Rigor Mortis", + long_desc = function(self, eff) return ("The target takes %d%% more damage from necrotic minions."):format(eff.power) end, + type = "magical", + status = "detrimental", + parameters = {power=20}, + on_gain = function(self, err) return "#Target# feels death coming!", "+Rigor Mortis" end, + on_lose = function(self, err) return "#Target# is freed from the rigor mortis.", "-Rigor Mortis" end, + activate = function(self, eff) + eff.tmpid = self:addTemporaryValue("inc_necrotic_minions", eff.power) + end, + deactivate = function(self, eff) + self:removeTemporaryValue("inc_necrotic_minions", eff.tmpid) + end, +} diff --git a/ideas/spells.ods b/ideas/spells.ods index f2029f33d673dd5f950fdbdcbf5117cfbc26cffd..ffe46c4e4165133b9104f8174f1ff080aacc9bdd 100644 Binary files a/ideas/spells.ods and b/ideas/spells.ods differ