From 758e5bab8507d25ea5b9681b77ca9bf98c3cca86 Mon Sep 17 00:00:00 2001
From: DarkGod <darkgod@net-core.org>
Date: Tue, 24 Dec 2013 15:53:33 +0100
Subject: [PATCH] New Doomed tree: One with Shadows

---
 game/modules/tome/class/Actor.lua             |  21 +++
 game/modules/tome/class/Player.lua            |  18 +++
 .../tome/data/birth/classes/afflicted.lua     |   1 +
 .../data/gfx/particles/darkness_power.lua     |  51 ++++++
 .../tome/data/gfx/talents/shadow_decoy.png    | Bin 0 -> 3474 bytes
 .../tome/data/gfx/talents/shadow_empathy.png  | Bin 0 -> 3625 bytes
 .../tome/data/gfx/talents/shadow_senses.png   | Bin 0 -> 5217 bytes
 .../data/gfx/talents/shadow_transposition.png | Bin 0 -> 4095 bytes
 .../tome/data/talents/cursed/cursed.lua       |  23 +++
 .../data/talents/cursed/one-with-shadows.lua  | 147 ++++++++++++++++++
 .../tome/data/talents/cursed/shadows.lua      |   1 +
 .../tome/data/talents/misc/inscriptions.lua   |   2 +-
 .../tome/data/timed_effects/mental.lua        |  34 ++++
 13 files changed, 297 insertions(+), 1 deletion(-)
 create mode 100644 game/modules/tome/data/gfx/particles/darkness_power.lua
 create mode 100644 game/modules/tome/data/gfx/talents/shadow_decoy.png
 create mode 100644 game/modules/tome/data/gfx/talents/shadow_empathy.png
 create mode 100644 game/modules/tome/data/gfx/talents/shadow_senses.png
 create mode 100644 game/modules/tome/data/gfx/talents/shadow_transposition.png
 create mode 100644 game/modules/tome/data/talents/cursed/one-with-shadows.lua

diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 0418c80932..b7545e080b 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -1791,6 +1791,19 @@ function _M:onTakeHit(value, src, death_note)
 		end
 	end
 
+	if value > 0 and self:attr("shadow_empathy") then
+		-- Absorb damage into a random shadow
+		local shadow = self:callTalent(self.T_SHADOW_EMPATHY, "getRandomShadow")
+		if shadow then
+			game:delayedLogMessage(self, src,  "displacement_shield"..(shadow.uid or ""), "#CRIMSON##Source# shares some damage with a shadow!")
+			local displaced = math.min(value * self.shadow_empathy / 100, shadow.life)
+			shadow:takeHit(displaced, src)
+			game:delayedLogDamage(src, self, 0, ("#PINK#(%d linked)#LAST#"):format(displaced), false)
+			game:delayedLogDamage(src, shadow, displaced, ("#PINK#%d linked#LAST#"):format(displaced), false)
+			value = value - displaced
+		end
+	end
+
 	if value > 0 and self:attr("displacement_shield") then
 		-- Absorb damage into the displacement shield
 		if rng.percent(self.displacement_shield_chance) then
@@ -2149,6 +2162,14 @@ function _M:onTakeHit(value, src, death_note)
 			game.level.map:particleEmitter(self.x, self.y, 1, "teleport_in")
 		end
 	end
+	
+	-- Shadow decoy
+	if value >= self.life and self:isTalentActive(self.T_SHADOW_DECOY) then
+		local t = self:getTalentFromId(self.T_SHADOW_DECOY)
+		if t.onDie(self, t, value, src) then
+			value = 0
+		end
+	end
 
 	if value <= 0 then return 0 end
 	-- Vim leech
diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua
index aea2345d56..26fba12e91 100644
--- a/game/modules/tome/class/Player.lua
+++ b/game/modules/tome/class/Player.lua
@@ -508,6 +508,24 @@ function _M:playerFOV()
 		end
 	end
 
+	if self:knowTalent(self.T_SHADOW_SENSE) then
+		local t = self:getTalentFromId(self.T_SHADOW_SENSE)
+		local range = self:getTalentRange(t)
+		local sqsense = range * range
+
+		for shadow, _ in pairs(game.party.members) do if shadow.is_doomed_shadow and not shadow.dead then
+			local arr = shadow.fov.actors_dist
+			local tbl = shadow.fov.actors
+			local act
+			for i = 1, #arr do
+				act = arr[i]
+				if act and not act.dead and act.x and tbl[act] and shadow:canSee(act) and tbl[act].sqdist <= sqsense then
+					game.level.map.seens(act.x, act.y, 0.6)
+				end
+			end
+		end end 
+	end
+
 	if not self:attr("blind") then
 		-- Handle dark vision; same as infravision, but also sees past creeping dark
 		-- this is treated as a sense, but is filtered by custom LOS code
diff --git a/game/modules/tome/data/birth/classes/afflicted.lua b/game/modules/tome/data/birth/classes/afflicted.lua
index e03304129f..a3f10a6829 100644
--- a/game/modules/tome/data/birth/classes/afflicted.lua
+++ b/game/modules/tome/data/birth/classes/afflicted.lua
@@ -129,6 +129,7 @@ newBirthDescriptor{
 		["cursed/cursed-form"]={true, 0.0},
 		["cunning/survival"]={false, 0.0},
 		["cursed/fears"]={false, 0.0},
+		["cursed/one-with-shadows"]={false, 0.3},
 	},
 	talents = {
 		[ActorTalents.T_UNNATURAL_BODY] = 1,
diff --git a/game/modules/tome/data/gfx/particles/darkness_power.lua b/game/modules/tome/data/gfx/particles/darkness_power.lua
new file mode 100644
index 0000000000..a16c384e3c
--- /dev/null
+++ b/game/modules/tome/data/gfx/particles/darkness_power.lua
@@ -0,0 +1,51 @@
+-- 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
+
+base_size = 32
+
+return { generator = function()
+	local ad = rng.range(0, 360)
+	local a = math.rad(ad)
+	local dir = math.rad(90)
+	local r = rng.range(18, 22)
+	local dirchance = rng.chance(2)
+	local x = rng.range(-16, 16)
+	local y = 16 - math.abs(math.sin(x / 16) * 8)
+	local c = rng.float(0, 0.3)
+
+	return {
+		trail = 1,
+		life = rng.range(10, 18),
+		size = rng.range(2, 3), sizev = 0, sizea = 0.005,
+
+		x = x, xv = 0, xa = 0,
+		y = y, yv = 0, ya = -0.2,
+		dir = 0, dirv = 0, dira = 0,
+		vel = 0, velv = 0, vela = 0,
+
+		r = c,   rv = 0, ra = 0,
+		g = c,   gv = 0, ga = 0,
+		b = c,   bv = 0, ba = 0,
+		a = rng.float(0.5, 1),   av = 0, aa = 0,
+	}
+end, },
+function(self)
+	self.ps:emit(4)
+end,
+40
diff --git a/game/modules/tome/data/gfx/talents/shadow_decoy.png b/game/modules/tome/data/gfx/talents/shadow_decoy.png
new file mode 100644
index 0000000000000000000000000000000000000000..8b0804e2e7c0d8a5b899d21305138d0c10cbb380
GIT binary patch
literal 3474
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
AZ~y=R

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/gfx/talents/shadow_empathy.png b/game/modules/tome/data/gfx/talents/shadow_empathy.png
new file mode 100644
index 0000000000000000000000000000000000000000..66c17e50e42599029b9dec08ce2f3e0658802bf9
GIT binary patch
literal 3625
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

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/gfx/talents/shadow_senses.png b/game/modules/tome/data/gfx/talents/shadow_senses.png
new file mode 100644
index 0000000000000000000000000000000000000000..d98a59dd2b98a6e1e7e34ae0c06563de52f9af89
GIT binary patch
literal 5217
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
b|M>b}kUaN+?ky3*00000NkvXXu0mjfebyKh

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/gfx/talents/shadow_transposition.png b/game/modules/tome/data/gfx/talents/shadow_transposition.png
new file mode 100644
index 0000000000000000000000000000000000000000..abc54b45763aaf48f9786ee2b165421b5f07cc24
GIT binary patch
literal 4095
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

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/talents/cursed/cursed.lua b/game/modules/tome/data/talents/cursed/cursed.lua
index 5b430729b6..d71b4422c1 100644
--- a/game/modules/tome/data/talents/cursed/cursed.lua
+++ b/game/modules/tome/data/talents/cursed/cursed.lua
@@ -31,6 +31,7 @@ newTalentType{ allow_random=true, is_mind=true, type="cursed/force-of-will", nam
 newTalentType{ allow_random=true, is_mind=true, type="cursed/darkness", name = "darkness", description = "Harness the power of darkness to envelop your foes." }
 newTalentType{ allow_random=true, is_mind=true, type="cursed/shadows", name = "shadows", description = "Summon shadows from the darkness to aid you." }
 newTalentType{ allow_random=true, is_mind=true, type="cursed/punishments", name = "punishments", description = "Your hate becomes punishment in the minds of your foes." }
+newTalentType{ allow_random=true, is_mind=true, type="cursed/one-with-shadows", name = "one with shadows", min_lev = 10, description = "Harness your shadows to their full potential." }
 
 -- Generic
 newTalentType{ allow_random=true, is_mind=true, type="cursed/gestures", name = "gestures", generic = true, description = "Enhance the power of you mind with gestures." }
@@ -102,6 +103,27 @@ cursed_cun_req5 = {
 	level = function(level) return 16 + (level-1)  end,
 }
 
+cursed_req_high1 = {
+	stat = { cun=function(level) return 22 + (level-1) * 2 end },
+	level = function(level) return 10 + (level-1)  end,
+}
+cursed_req_high2 = {
+	stat = { cun=function(level) return 30 + (level-1) * 2 end },
+	level = function(level) return 14 + (level-1)  end,
+}
+cursed_req_high3 = {
+	stat = { cun=function(level) return 38 + (level-1) * 2 end },
+	level = function(level) return 18 + (level-1)  end,
+}
+cursed_req_high4 = {
+	stat = { cun=function(level) return 46 + (level-1) * 2 end },
+	level = function(level) return 22 + (level-1)  end,
+}
+cursed_req_high5 = {
+	stat = { cun=function(level) return 54 + (level-1) * 2 end },
+	level = function(level) return 26 + (level-1)  end,
+}
+
 cursed_lev_req1 = {
 	level = function(level) return 0 + (level-1)  end,
 }
@@ -146,6 +168,7 @@ load("/data/talents/cursed/shadows.lua")
 load("/data/talents/cursed/darkness.lua")
 load("/data/talents/cursed/punishments.lua")
 load("/data/talents/cursed/gestures.lua")
+load("/data/talents/cursed/one-with-shadows.lua")
 
 load("/data/talents/cursed/cursed-form.lua")
 load("/data/talents/cursed/cursed-aura.lua")
diff --git a/game/modules/tome/data/talents/cursed/one-with-shadows.lua b/game/modules/tome/data/talents/cursed/one-with-shadows.lua
new file mode 100644
index 0000000000..e41576d5a4
--- /dev/null
+++ b/game/modules/tome/data/talents/cursed/one-with-shadows.lua
@@ -0,0 +1,147 @@
+-- ToME - Tales of Middle-Earth
+-- 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 Emote = require "engine.Emote"
+
+newTalent{
+	name = "Shadow Senses",
+	type = {"cursed/one-with-shadows", 1},
+	require = cursed_cun_req_high1,
+	mode = "passive",
+	points = 5,
+	no_npc_use = true,
+	range = function(self, t) return math.floor(self:combatTalentScale(t, 1, 5, 1)) end,
+	info = function(self, t)
+		return ([[Your awareness extends to your shadows.
+		You always know exactly where your shadows are and can perceive any foe within %d tiles of their vision.]])
+		:format(self:getTalentRange(t))
+	end,
+}
+
+newTalent{
+	name = "Shadow Empathy",
+	type = {"cursed/one-with-shadows", 2},
+	require = cursed_cun_req_high2,
+	points = 5,
+	hate = 10,
+	cooldown = 25,
+	getRandomShadow = function(self, t)
+		local shadows = {}
+		if game.party and game.party:hasMember(self) then
+			for act, def in pairs(game.party.members) do
+				if act.summoner and act.summoner == self and act.is_doomed_shadow and not act.dead then
+					shadows[#shadows+1] = act
+				end
+			end
+		else
+			for uid, act in pairs(game.level.entities) do
+				if act.summoner and act.summoner == self and act.is_doomed_shadow and not act.dead then
+					shadows[#shadows+1] = act
+				end
+			end
+		end
+		return #shadows > 0 and rng.table(shadows)
+	end,
+	getDur = function(self, t) return math.floor(self:combatTalentScale(t, 3, 10)) end,
+	getPower = function(self, t) return 5 + self:combatTalentMindDamage(t, 0, 300) / 8 end,
+	action = function(self, t)
+		self:setEffect(self.EFF_SHADOW_EMPATHY, t.getDur(self, t), {power=t.getPower(self, t)})
+		return true
+	end,
+	info = function(self, t)
+		local power = t.getPower(self, t)
+		local duration = t.getDur(self, t)
+		return ([[You are linked to your shadows for %d turns, diverting %d%% of all damage you take to a random shadow.
+		Effect increases with Mindpower.]]):
+		format(duration, power)
+	end,
+}
+
+newTalent{
+	name = "Shadow Transposition",
+	type = {"cursed/one-with-shadows", 3},
+	require = cursed_cun_req_high3,
+	points = 5,
+	hate = 6,
+	no_npc_use = true,
+	radius = function(self, t) return math.floor(self:combatTalentScale(t, 1, 15, 1)) end,
+	getNb = function(self, t) return math.floor(self:combatTalentScale(t, 1, 3, 1)) end,
+	action = function(self, t)
+		local tg = {type="hit", range=self:getTalentRadius(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, target.x, target.y) > self:getTalentRadius(t) then return nil end
+		if target.summoner ~= self or not target.is_doomed_shadow then return end
+
+		-- Displace
+		local tx, ty, sx, sy = target.x, target.y, self.x, self.y
+		target.x = nil target.y = nil
+		self.x = nil self.y = nil
+		target:move(sx, sy, true)
+		self:move(tx, ty, true)
+
+		self:removeEffectsFilter(function(t) return (t.type == "physical" or t.type == "magical") and t.status == "detrimental" end, t.getNb(self, t))
+
+		return true
+	end,
+	info = function(self, t)
+		return ([[Observers find it difficult to tell you and your shadows apart.
+		You can target a shadow in radius %d and instantly trade places with it.
+		%d random negative physical or magical effects are transferred from you to the chosen shadow in the process.]])
+		:format(self:getTalentRadius(t), t.getNb(self, t))
+	end,
+}
+
+newTalent{
+	name = "Shadow Decoy",
+	type = {"cursed/one-with-shadows", 4},
+	require = cursed_cun_req_high4,
+	mode = "sustained",
+	cooldown = 10,
+	points = 5,
+	cooldown = 50,
+	sustain_hate = 40,
+	getPower = function(self, t) return 10 + self:combatTalentMindDamage(t, 0, 300) end,
+	onDie = function(self, t, value, src)
+		local shadow = self:callTalent(self.T_SHADOW_EMPATHY, "getRandomShadow")
+		if not shadow then return false end
+
+		game:delayedLogDamage(src, self, 0, ("#GOLD#(%d decoy)#LAST#"):format(value), false)
+		game:delayedLogDamage(src, shadow, value, ("#GOLD#%d decoy#LAST#"):format(value), false)
+		shadow:takeHit(value, src)
+		self:setEffect(self.EFF_SHADOW_DECOY, 4, {power=t.getPower(self, t)})
+		self:forceUseTalent(t.id, {ignore_energy=true})
+
+		if self.player then self:setEmote(Emote.new("Fools, you never killed me; that was only my shadow!", 45)) end
+		return true
+	end,
+	activate = function(self, t)
+		return {}
+	end,
+	deactivate = function(self, t, p)
+		return true
+	end,
+	info = function(self, t)
+		return ([[Your shadows guard you with their lifes.
+		When you would receive a fatal blow, you instantly transpose with a random shadow that takes the blow instead, putting this talent on cooldown.
+		For the next 4 turns you only die if you reach -%d life. However, when below 0 you cannot see how much life you have left.
+		Effect increases with Mindpower.]]):
+		format(t.getPower(self, t))
+	end,
+}
diff --git a/game/modules/tome/data/talents/cursed/shadows.lua b/game/modules/tome/data/talents/cursed/shadows.lua
index af46b97418..18b3fcafd8 100644
--- a/game/modules/tome/data/talents/cursed/shadows.lua
+++ b/game/modules/tome/data/talents/cursed/shadows.lua
@@ -194,6 +194,7 @@ local function createShadow(self, level, tCallShadows, tShadowWarriors, tShadowM
 		exp_worth=0,
 		hate_regen = 1,
 		avoid_traps = 1,
+		is_doomed_shadow = true,
 
 		max_life = resolvers.rngavg(3,12), life_rating = 5,
 		stats = { -- affected by stat limits
diff --git a/game/modules/tome/data/talents/misc/inscriptions.lua b/game/modules/tome/data/talents/misc/inscriptions.lua
index d61739e8e1..d92ade3f3f 100644
--- a/game/modules/tome/data/talents/misc/inscriptions.lua
+++ b/game/modules/tome/data/talents/misc/inscriptions.lua
@@ -258,7 +258,7 @@ newInscription{
 	info = function(self, t)
 		local data = self:getInscriptionData(t.short_name)
 		return ([[Activate the infusion to increase three of your primary stats by %d for %d turns.
-		Also while Heroism is active, you will only die when reaching -%d life. However, when below 0 you cannot see how much life you have left, and you will die if you did not heal before the effect ends.
+		Also while Heroism is active, you will only die when reaching -%d life. However, when below 0 you cannot see how much life you have left.
 		It will always increase your three highest stats.]]):format(data.power + data.inc_stat, data.dur, data.die_at + data.inc_stat * 30)
 	end,
 	short_info = function(self, t)
diff --git a/game/modules/tome/data/timed_effects/mental.lua b/game/modules/tome/data/timed_effects/mental.lua
index 5c9ce2c490..fdbcdf8945 100644
--- a/game/modules/tome/data/timed_effects/mental.lua
+++ b/game/modules/tome/data/timed_effects/mental.lua
@@ -2952,3 +2952,37 @@ newEffect{
 		eff.power = 2
 	end,
 }
+
+newEffect{
+	name = "SHADOW_EMPATHY", image = "talents/shadow_empathy.png",
+	desc = "Shadow Empathy",
+	long_desc = function(self, eff) return ("%d%% of all damage is redirected to a random shadow."):format(eff.power) end,
+	type = "mental",
+	subtype = { mind=true, shield=true },
+	status = "beneficial",
+	parameters = { power=10 },
+	activate = function(self, eff)
+		self:effectTemporaryValue(eff, "shadow_empathy", eff.power)
+		eff.particle = self:addParticles(Particles.new("darkness_power", 1))
+	end,
+	deactivate = function(self, eff)
+		self:removeParticles(eff.particle)		
+	end,
+}
+
+newEffect{
+	name = "SHADOW_DECOY", image = "talents/shadow_decoy.png",
+	desc = "Shadow Decoy",
+	long_desc = function(self, eff) return ("A random shadow absorbed a fatal blow for you, granting you a negative shield of %d."):format(eff.power) end,
+	type = "mental",
+	subtype = { mind=true, shield=true },
+	status = "beneficial",
+	parameters = { power=10 },
+	activate = function(self, eff)
+		self:effectTemporaryValue(eff, "die_at", -eff.power)
+		eff.particle = self:addParticles(Particles.new("darkness_power", 1))
+	end,
+	deactivate = function(self, eff)
+		self:removeParticles(eff.particle)		
+	end,
+}
-- 
GitLab