diff --git a/game/engines/default/engine/interface/ActorLife.lua b/game/engines/default/engine/interface/ActorLife.lua index 3691e68646b43d06f7bd5491fd5be2c99d80031a..5d6d8c91d0f9a266ed34ada9c34f46c529f24865 100644 --- a/game/engines/default/engine/interface/ActorLife.lua +++ b/game/engines/default/engine/interface/ActorLife.lua @@ -81,6 +81,8 @@ function _M:die(src, death_note) self.changed = true self:check("on_die", src, death_note) + + return true end --- Actor is being attacked! diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 0e0597cec9f3a2f1aa3884a5e52f500a29372495..ea77d20ff5303d817f7f1a0e8db9ad5a54724133 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -1115,6 +1115,9 @@ end function _M:regenLife() if self.life_regen and not self:attr("no_life_regen") then self.life = util.bound(self.life + self.life_regen * util.bound((self.healing_factor or 1), 0, 2.5), self.die_at, self.max_life) + if self:attr("blood_lock") then + self.life = util.bound(self.life, self.die_at, self:attr("blood_lock")) + end end end @@ -1158,6 +1161,13 @@ function _M:onHeal(value, src) self:setEffect(self.EFF_DAMAGE_SHIELD, 3, {power=value * self.arcane_shield / 100}) end + -- Must be last! + if self:attr("blood_lock") then + if self.life + value > self:attr("blood_lock") then + value = math.max(0, self:attr("blood_lock") - self.life) + end + end + print("[HEALING]", self.uid, self.name, "for", value) if not self.resting and value >= 1 and game.level.map.seens(self.x, self.y) then local sx, sy = game.level.map:getTileToScreen(self.x, self.y) @@ -1522,6 +1532,18 @@ function _M:onTakeHit(value, src) for tid, _ in pairs(self.contingency_disable) do self:forceUseTalent(tid, {ignore_energy=true}) end end + -- Spell cooldowns on hit + if self:attr("reduce_spell_cooldown_on_hit") and value >= self.max_life * self:attr("reduce_spell_cooldown_on_hit") / 100 then + local alt = {} + for tid, cd in pairs(self.talents_cd) do + if rng.percent(self:attr("reduce_spell_cooldown_on_hit_chance")) then alt[tid] = cd - 1 end + end + for tid, cd in pairs(alt) do + if cd <= 0 then self.talents_cd[tid] = nil + else self.talents_cd[tid] = cd end + end + end + -- Life leech if value > 0 and src and src:attr("life_leech_chance") and rng.percent(src.life_leech_chance) then local leech = math.min(value, self.life) * src.life_leech_value / 100 @@ -1551,6 +1573,17 @@ function _M:onTakeHit(value, src) return value end +function _M:takeHit(value, src, death_note) + local dead, val = engine.interface.ActorLife.takeHit(self, value, src, death_note) + + if dead and src and src.attr and src:attr("overkill") and src.project then + local dam = (self.die_at - self.life) * src:attr("overkill") / 100 + src:project({type="ball", radius=2, selffire=false, x=self.x, y=self.y}, self.x, self.y, DamageType.BLIGHT, dam, {type="acid"}) + end + + return dead, val +end + function _M:removeTimedEffectsOnClone() local todel = {} for eff, p in pairs(self.tmp) do diff --git a/game/modules/tome/data/birth/classes/corrupted.lua b/game/modules/tome/data/birth/classes/corrupted.lua index 8a3c48851e8d13a912e3dcb58abf6716f14690ea..6b75931383c5b3d7995d0a402d2ed61195a0fc97 100644 --- a/game/modules/tome/data/birth/classes/corrupted.lua +++ b/game/modules/tome/data/birth/classes/corrupted.lua @@ -63,6 +63,7 @@ newBirthDescriptor{ ["corruption/hexes"]={false, 0.3}, ["corruption/curses"]={false, 0.3}, ["corruption/bone"]={true, 0.3}, + ["corruption/torment"]={true, 0.3}, }, talents = { [ActorTalents.T_CORRUPTED_STRENGTH] = 1, @@ -108,6 +109,7 @@ newBirthDescriptor{ ["corruption/blood"]={true, 0.3}, ["corruption/vim"]={true, 0.3}, ["corruption/blight"]={true, 0.3}, + ["corruption/torment"]={false, 0.3}, }, talents = { [ActorTalents.T_DRAIN] = 1, diff --git a/game/modules/tome/data/gfx/talents/blood_lock.png b/game/modules/tome/data/gfx/talents/blood_lock.png new file mode 100644 index 0000000000000000000000000000000000000000..ef58e5c0616e708f0b00c3adc0d1bbc033261884 Binary files /dev/null and b/game/modules/tome/data/gfx/talents/blood_lock.png differ diff --git a/game/modules/tome/data/gfx/talents/blood_vengeance.png b/game/modules/tome/data/gfx/talents/blood_vengeance.png new file mode 100644 index 0000000000000000000000000000000000000000..da2dd6978f7fc2d76aaee659ce18f2fb7c7096dc Binary files /dev/null and b/game/modules/tome/data/gfx/talents/blood_vengeance.png differ diff --git a/game/modules/tome/data/gfx/talents/overkill.png b/game/modules/tome/data/gfx/talents/overkill.png new file mode 100644 index 0000000000000000000000000000000000000000..33e55f9c6f95c451b6b00c1a35a74618cd156c73 Binary files /dev/null and b/game/modules/tome/data/gfx/talents/overkill.png differ diff --git a/game/modules/tome/data/gfx/talents/willful_tormenter.png b/game/modules/tome/data/gfx/talents/willful_tormenter.png new file mode 100644 index 0000000000000000000000000000000000000000..7020b2273e06271351396fdac7368537d039f1a4 Binary files /dev/null and b/game/modules/tome/data/gfx/talents/willful_tormenter.png differ diff --git a/game/modules/tome/data/talents/corruptions/corruptions.lua b/game/modules/tome/data/talents/corruptions/corruptions.lua index 662a8729efee74688c6367eb59d0e34ceb19245a..b800d95e1a67c535acbcc03ae00a8cdf5c83d6c8 100644 --- a/game/modules/tome/data/talents/corruptions/corruptions.lua +++ b/game/modules/tome/data/talents/corruptions/corruptions.lua @@ -19,6 +19,7 @@ -- Corruptions newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/sanguisuge", name = "sanguisuge", description = "Manipulate the life force to feed your own dark powers." } +newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/torment", name = "torment", generic = true, description = "All the tools to torment your foes." } newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/vim", name = "vim", description = "Touch the very essence of your victims." } newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/bone", name = "bone", description = "Harness the power of bones." } newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/hexes", name = "hexes", generic = true, description = "Hex your foes, hindering and crippling them." } @@ -83,3 +84,4 @@ load("/data/talents/corruptions/blood.lua") load("/data/talents/corruptions/blight.lua") load("/data/talents/corruptions/shadowflame.lua") load("/data/talents/corruptions/vim.lua") +load("/data/talents/corruptions/torment.lua") diff --git a/game/modules/tome/data/talents/corruptions/torment.lua b/game/modules/tome/data/talents/corruptions/torment.lua new file mode 100644 index 0000000000000000000000000000000000000000..6c4c554199fdec1370e9cb7ecb1ec6d16c4f6af8 --- /dev/null +++ b/game/modules/tome/data/talents/corruptions/torment.lua @@ -0,0 +1,134 @@ +-- 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 = "Willful Tormenter", + type = {"corruption/torment", 1}, + require = corrs_req1, + mode = "sustained", + points = 5, + cooldown = 20, + vim = 0, + tactical = { BUFF = 2 }, + activate = function(self, t) + game:playSoundNear(self, "talents/flame") + return { + vim = self:addTemporaryValue("max_vim", self:getTalentLevel(t) * 15), + } + end, + deactivate = function(self, t, p) + self:removeTemporaryValue("max_vim", p.vim) + return true + end, + info = function(self, t) + return ([[You set your mind toward a single goal: the destruction of all yuor foes. + Increases the maximum amount of vim you can store by %d.]]): + format(self:getTalentLevel(t) * 15) + end, +} + +newTalent{ + name = "Blood Lock", + type = {"corruption/torment", 2}, + require = corrs_req2, + points = 5, + cooldown = 16, + vim = 12, + range = 10, + radius = 2, + tactical = { DISABLE = 1 }, + direct_hit = true, + no_energy = true, + requires_target = true, + target = function(self, t) + return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), 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, function(tx, ty) + local target = game.level.map(tx, ty, Map.ACTOR) + if not target or target == self then return end + target:setEffect(target.EFF_BLOOD_LOCK, 2 + math.ceil(self:getTalentLevel(t) * 2), {src=self, dam=self:combatTalentSpellDamage(t, 4, 90), power=1+(self:getTalentLevel(t) / 10), apply_power=self:combatSpellpower()}) + end) + game:playSoundNear(self, "talents/slime") + return true + end, + info = function(self, t) + return ([[Reach out to your foe's blood and health. Any creature struck by Blood Lock will be unable to heal above their current life value (at the time of the casting) for %d turns in a radius 2.]]): + format(2 + math.ceil(self:getTalentLevel(t) * 2)) + end, +} + +newTalent{ + name = "Overkill", + type = {"corruption/torment", 3}, + require = corrs_req3, + points = 5, + mode = "sustained", + cooldown = 20, + vim = 18, + tactical = { BUFF = 2 }, + activate = function(self, t) + game:playSoundNear(self, "talents/flame") + return { + ov = self:addTemporaryValue("overkill", 40 + self:combatTalentSpellDamage(t, 10, 90)), + } + end, + deactivate = function(self, t, p) + self:removeTemporaryValue("overkill", p.ov) + return true + end, + info = function(self, t) + return ([[When you kill a creature, the remainer of the damage done will not be lost. Instead %d%% of it will splash in a radius 2, doing blight damage. + The damage will increase with Magic stat.]]):format(40 + self:combatTalentSpellDamage(t, 10, 90)) + end, +} + +newTalent{ + name = "Blood Vengeance", + type = {"corruption/torment", 4}, + require = corrs_req4, + points = 5, + mode = "sustained", + cooldown = 20, + getPower = function(self, t) return math.max(2, 10 - self:getTalentLevelRaw(t)), util.bound(40 + self:combatTalentSpellDamage(t, 10, 90), 0, 100) end, + vim = 22, + tactical = { BUFF = 2 }, + activate = function(self, t) + local l, c = t.getPower(self, t) + game:playSoundNear(self, "talents/flame") + return { + l = self:addTemporaryValue("reduce_spell_cooldown_on_hit", l), + c = self:addTemporaryValue("reduce_spell_cooldown_on_hit_chance", c), + } + end, + deactivate = function(self, t, p) + self:removeTemporaryValue("reduce_spell_cooldown_on_hit", p.l) + self:removeTemporaryValue("reduce_spell_cooldown_on_hit_chance", p.c) + return true + end, + info = function(self, t) + local l, c = t.getPower(self, t) + return ([[When you are dealt a blow that reduces your life by at least %d%% you have %d%% chances to reduce the remaining cooldown of all your spells by 1. + The chance will increase with Magic stat.]]): + format(l, c) + end, +} diff --git a/game/modules/tome/data/timed_effects/magical.lua b/game/modules/tome/data/timed_effects/magical.lua index dc80cc79e31cf5d73f635851b5638fb45226e6ae..905e11b3496ca7e70233def440046f8bebf76f2d 100644 --- a/game/modules/tome/data/timed_effects/magical.lua +++ b/game/modules/tome/data/timed_effects/magical.lua @@ -1671,4 +1671,23 @@ newEffect{ self:removeTemporaryValue("reduce_status_effects_time", eff.durid) self:removeParticles(eff.particle) end, -} \ No newline at end of file +} + +newEffect{ + name = "BLOOD_LOCK", image = "talents/blood_lock.png", + desc = "Blood Lock", + long_desc = function(self, eff) return ("Can not heal higher than %d life."):format(eff.power) end, + type = "magical", + subtype = { blood=true }, + status = "detrimental", + parameters = { }, + on_gain = function(self, err) return "#Target# is blood locked.", "+Blood Lock" end, + on_lose = function(self, err) return "#Target# is no longer blood locked.", "-Blood Lock" end, + activate = function(self, eff) + eff.power = self.life + eff.tmpid = self:addTemporaryValue("blood_lock", eff.power) + end, + deactivate = function(self, eff) + self:removeTemporaryValue("blood_lock", eff.tmpid) + end, +}