From bc15e055ace8d14127d25476666553fdd2230e0e Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Fri, 30 Mar 2012 09:24:42 +0000
Subject: [PATCH] New generic tree for Reavers & Corruptors: Torment

git-svn-id: http://svn.net-core.org/repos/t-engine4@5013 51575b47-30f0-44d4-a5cc-537603b46e54
---
 .../default/engine/interface/ActorLife.lua    |   2 +
 game/modules/tome/class/Actor.lua             |  33 +++++
 .../tome/data/birth/classes/corrupted.lua     |   2 +
 .../tome/data/gfx/talents/blood_lock.png      | Bin 0 -> 2862 bytes
 .../tome/data/gfx/talents/blood_vengeance.png | Bin 0 -> 4104 bytes
 .../tome/data/gfx/talents/overkill.png        | Bin 0 -> 3941 bytes
 .../data/gfx/talents/willful_tormenter.png    | Bin 0 -> 2590 bytes
 .../data/talents/corruptions/corruptions.lua  |   2 +
 .../tome/data/talents/corruptions/torment.lua | 134 ++++++++++++++++++
 .../tome/data/timed_effects/magical.lua       |  21 ++-
 10 files changed, 193 insertions(+), 1 deletion(-)
 create mode 100644 game/modules/tome/data/gfx/talents/blood_lock.png
 create mode 100644 game/modules/tome/data/gfx/talents/blood_vengeance.png
 create mode 100644 game/modules/tome/data/gfx/talents/overkill.png
 create mode 100644 game/modules/tome/data/gfx/talents/willful_tormenter.png
 create mode 100644 game/modules/tome/data/talents/corruptions/torment.lua

diff --git a/game/engines/default/engine/interface/ActorLife.lua b/game/engines/default/engine/interface/ActorLife.lua
index 3691e68646..5d6d8c91d0 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 0e0597cec9..ea77d20ff5 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 8a3c48851e..6b75931383 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
GIT binary patch
literal 2862
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
M07*qoM6N<$f>ee{D*ylh

literal 0
HcmV?d00001

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
GIT binary patch
literal 4104
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
GLSTYtki`-J

literal 0
HcmV?d00001

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
GIT binary patch
literal 3941
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

literal 0
HcmV?d00001

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
GIT binary patch
literal 2590
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
Ap8x;=

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/talents/corruptions/corruptions.lua b/game/modules/tome/data/talents/corruptions/corruptions.lua
index 662a8729ef..b800d95e1a 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 0000000000..6c4c554199
--- /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 dc80cc79e3..905e11b349 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,
+}
-- 
GitLab