-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009, 2010, 2011 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 Map = require "engine.Map"

----------------------------------------------------------------
-- Poisons
----------------------------------------------------------------

newTalent{
	name = "Vile Poisons",
	display_name = "涂毒",
	type = {"cunning/poisons", 1},
	points = 5,
	mode = "passive",
	require = cuns_req_high1,
	on_learn = function(self, t)
		local lev = self:getTalentLevelRaw(t)
		if lev == 1 then
			self.vile_poisons = {}
			self:learnTalent(self.T_DEADLY_POISON, true, nil, {no_unlearn=true})
		elseif lev == 2 then
			self:learnTalent(self.T_NUMBING_POISON, true, nil, {no_unlearn=true})
		elseif lev == 3 then
			self:learnTalent(self.T_INSIDIOUS_POISON, true, nil, {no_unlearn=true})
		elseif lev == 4 then
			self:learnTalent(self.T_CRIPPLING_POISON, true, nil, {no_unlearn=true})
		elseif lev == 5 then
			self:learnTalent(self.T_STONING_POISON, true, nil, {no_unlearn=true})
		end
	end,
	on_unlearn = function(self, t)
		local lev = self:getTalentLevelRaw(t)
		if lev == 0 then
			self:unlearnTalent(self.T_DEADLY_POISON)
			self.vile_poisons = nil
		elseif lev == 1 then
			self:unlearnTalent(self.T_NUMBING_POISON)
		elseif lev == 2 then
			self:unlearnTalent(self.T_INSIDIOUS_POISON)
		elseif lev == 3 then
			self:unlearnTalent(self.T_CRIPPLING_POISON)
		elseif lev == 4 then
			self:unlearnTalent(self.T_STONING_POISON)
		end
	end,
	info = function(self, t)
		return ([[你学会如何在武器上涂毒。每等级你将会学到新的毒剂。
		等级1：致命毒剂
		等级2：麻木毒剂
		等级3：阴险毒剂
		等级4：致残毒剂
		等级5：石化毒剂
		同时你还可以向世界上特定的人学习新毒剂。
		同时提高你 %d%%的毒素效果。（此效果对每个毒剂都有改变）
		在你的武器上涂毒不会打破潜行状态。
		每次只能同时使用2种毒剂。
		每次你击中目标时，你有 %d%% 概率使目标随机感染已使用的2种毒素之一。
		如果目标已经处于中毒状态，则目标再次中毒的概率降低。]]):
		format(self:getTalentLevel(t) * 20, 20 + self:getTalentLevel(t) * 5)
	end,
}

newTalent{
	name = "Venomous Strike",
	display_name = "毒素爆发",
	type = {"cunning/poisons", 2},
	points = 5,
	cooldown = 5,
	stamina = 7,
	require = cuns_req_high2,
	requires_target = true,
	tactical = { ATTACK = function(self, t, target)
		local nb = 0
		for eff_id, p in pairs(target.tmp) do
			local e = target.tempeffect_def[eff_id]
			if e.subtype.poison then nb = nb + 1 end
		end
		return { NATURE = nb}
	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 nb = 0
		for eff_id, p in pairs(target.tmp) do
			local e = target.tempeffect_def[eff_id]
			if e.subtype.poison then nb = nb + 1 end
		end
		local dam = self:combatTalentWeaponDamage(t, 0.5 + nb * 0.6, 0.9 + nb * 1)

		self:attackTarget(target, DamageType.NATURE, dam, true)

		return true
	end,
	info = function(self, t)
		local dam0 = 100 * self:combatTalentWeaponDamage(t, 0.5, 0.9)
		local dam1 = 100 * self:combatTalentWeaponDamage(t, 0.5 + 0.6,   0.9 + 1)
		local dam2 = 100 * self:combatTalentWeaponDamage(t, 0.5 + 0.6*2, 0.9 + 1*2)
		local dam3 = 100 * self:combatTalentWeaponDamage(t, 0.5 + 0.6*3, 0.9 + 1*3)
		return ([[你击中目标并造成一定的自然伤害，伤害值取决于目标身上的中毒种类。
		- 0毒素：%d%%
		- 1毒素：%d%%
		- 2毒素：%d%%
		- 3毒素：%d%%]]):
		format(dam0, dam1, dam2, dam3)
	end,
}
newTalent{
	name = "Empower Poisons",
	display_name = "强化毒素",
	type = {"cunning/poisons", 3},
	points = 5,
	cooldown = 24,
	stamina = 15,
	require = cuns_req_high3,
	requires_target = true,
	no_energy = true,
	tactical = { ATTACK = {NATURE = 1} },
	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 mod = (100 + self:combatTalentStatDamage(t, "cun", 40, 250)) / 100
		for eff_id, p in pairs(target.tmp) do
			local e = target.tempeffect_def[eff_id]
			if e.subtype.poison then
				p.dur = math.ceil(p.dur / 2)
				p.power = (p.power or 0) * mod
			end
		end

		game.level.map:particleEmitter(target.x, target.y, 1, "slime")
		game:playSoundNear(self, "talents/slime")
		return true
	end,
	info = function(self, t)
		return ([[减少所有毒药50%%的持续时间但增加它们 %d%% 伤害。
		受灵巧影响，效果有额外加成。]]):
		format(100 + self:combatTalentStatDamage(t, "cun", 40, 250))
	end,
}

newTalent{
	name = "Toxic Death",
	display_name = "致命毒素",
	type = {"cunning/poisons", 4},
	points = 5,
	mode = "passive",
	require = cuns_req_high4,
	on_kill = function(self, t, target)
		local possible = {}
		for i = -1, 1 do for j = -1, 1 do if game.level.map:isBound(target.x + i, target.y + j) then if i ~= 0 or j ~= 0 then
			local tgt = game.level.map(target.x + i, target.y + j, Map.ACTOR)
			if tgt and not tgt.dead then possible[tgt] = true end
		end end end end
		possible[self] = nil
		possible[target] = nil
		possible = table.keys(possible)

		for eff_id, p in pairs(target.tmp) do
			local e = target.tempeffect_def[eff_id]
			if e.subtype.poison and p.src == self then
				for i, tgt in ipairs(possible) do if rng.percent(20 + self:getTalentLevelRaw(t) * 8) and not tgt:hasEffect(eff_id) and self:reactionToward(tgt) < 0 then
					p.src = nil
					local pp = table.clone(p)
					pp.src = self
					p.src = self
					tgt:setEffect(eff_id, pp.dur, pp)
				end end
			end
		end
	end,
	info = function(self, t)
		return ([[当你杀死一个敌人时，目标身上的中毒效果有 %d%% 的概率传染给周围单位。]]):format(20 + self:getTalentLevelRaw(t) * 8)
	end,
}

----------------------------------------------------------------
-- Poisons effects
----------------------------------------------------------------

local function checkChance(self, target)
	local chance = 20 + self:getTalentLevel(self.T_VILE_POISONS) * 5
	local nb = 1
	for eff_id, p in pairs(target.tmp) do
		local e = target.tempeffect_def[eff_id]
		if e.subtype.poison then nb = nb + 1 end
	end
	return rng.percent(chance / nb)
end

local function cancelPoisons(self)
	local todel = {}
	for tid, p in pairs(self.sustain_talents) do
		local t = self:getTalentFromId(tid)
		if t.type[1] == "cunning/poisons-effects" then
			todel[#todel+1] = tid
		end
	end
	while #todel > 1 do self:forceUseTalent(rng.tableRemove(todel), {ignore_energy=true}) end
end

newTalent{
	name = "Deadly Poison",
	display_name = "致命毒剂",
	type = {"cunning/poisons-effects", 1},
	points = 1,
	mode = "sustained",
	cooldown = 10,
	no_break_stealth = true,
	no_energy = true,
	tactical = { BUFF = 2 },
	getDuration = function(self, t) return 5 + self:getTalentLevel(self.T_VILE_POISONS) end,
	getDOT = function(self, t) return 8 + self:combatTalentStatDamage(self.T_VILE_POISONS, "cun", 10, 60) * 0.4 end,
	proc = function(self, t, target)
		if not checkChance(self, target) then return end
		target:setEffect(target.EFF_POISONED, t.getDuration(self, t), {src=self, power=t.getDOT(self, t), max_power=t.getDOT(self, t) * 4})
	end,
	activate = function(self, t)
		cancelPoisons(self)
		self.vile_poisons = self.vile_poisons or {}
		self.vile_poisons[t.id] = true
		return {}
	end,
	deactivate = function(self, t, p)
		self.vile_poisons[t.id] = nil
		return true
	end,
	info = function(self, t)
		return ([[造成每轮 %d 点自然伤害，持续 %d 轮，可叠加。
		伤害受灵巧加成。
		毒素效果可以叠加。]]):
		format(damDesc(self, DamageType.NATURE, t.getDOT(self, t)), t.getDuration(self, t))
	end,
}

newTalent{
	name = "Numbing Poison",
	display_name = "麻木毒剂",
	type = {"cunning/poisons-effects", 1},
	points = 1,
	mode = "sustained",
	cooldown = 10,
	no_break_stealth = true,
	no_energy = true,
	tactical = { BUFF = 2 },
	getDuration = function(self, t) return 5 + self:getTalentLevel(self.T_VILE_POISONS) end,
	getDOT = function(self, t) return 8 + self:combatTalentStatDamage(self.T_VILE_POISONS, "cun", 10, 50) * 0.4 end,
	getEffect = function(self, t) return 10 + self:getTalentLevel(self.T_VILE_POISONS) * 3 end,
	proc = function(self, t, target)
		if not checkChance(self, target) then return end
		target:setEffect(target.EFF_NUMBING_POISON, t.getDuration(self, t), {src=self, power=t.getDOT(self, t), reduce=t.getEffect(self, t)})
	end,
	activate = function(self, t)
		cancelPoisons(self)
		self.vile_poisons = self.vile_poisons or {}
		self.vile_poisons[t.id] = true
		return {}
	end,
	deactivate = function(self, t, p)
		self.vile_poisons[t.id] = nil
		return true
	end,
	info = function(self, t)
		return ([[造成每轮 %d 点自然伤害持续 %d 回合，中毒目标造成的伤害降低 %d%% 。
		效果受灵巧加成。]]):
		format(damDesc(self, DamageType.NATURE, t.getDOT(self, t)), t.getDuration(self, t), t.getEffect(self, t))
	end,
}

newTalent{
	name = "Insidious Poison",
	display_name = "阴险毒剂",
	type = {"cunning/poisons-effects", 1},
	points = 1,
	mode = "sustained",
	cooldown = 10,
	no_break_stealth = true,
	no_energy = true,
	tactical = { BUFF = 2 },
	getDuration = function(self, t) return 5 + self:getTalentLevel(self.T_VILE_POISONS) end,
	getDOT = function(self, t) return 8 + self:combatTalentStatDamage(self.T_VILE_POISONS, "cun", 10, 50) * 0.4 end,
	getEffect = function(self, t) return 30 + self:getTalentLevel(self.T_VILE_POISONS) * 5.5 end,
	proc = function(self, t, target)
		if not checkChance(self, target) then return end
		target:setEffect(target.EFF_INSIDIOUS_POISON, t.getDuration(self, t), {src=self, power=t.getDOT(self, t), heal_factor=t.getEffect(self, t)})
	end,
	activate = function(self, t)
		cancelPoisons(self)
		self.vile_poisons = self.vile_poisons or {}
		self.vile_poisons[t.id] = true
		return {}
	end,
	deactivate = function(self, t, p)
		self.vile_poisons[t.id] = nil
		return true
	end,
	info = function(self, t)
		return ([[造成每轮 %d 点自然伤害持续 %d 回合，中毒目标受到的治疗效果减少 %d%%。
		效果受灵巧加成。]]):
		format(damDesc(self, DamageType.NATURE, t.getDOT(self, t)), t.getDuration(self, t), t.getEffect(self, t))
	end,
}

newTalent{
	name = "Crippling Poison",
	display_name = "致残毒剂",
	type = {"cunning/poisons-effects", 1},
	points = 1,
	mode = "sustained",
	cooldown = 10,
	no_break_stealth = true,
	no_energy = true,
	tactical = { BUFF = 2 },
	getDuration = function(self, t) return 3 + self:getTalentLevel(self.T_VILE_POISONS) end,
	getDOT = function(self, t) return 8 + self:combatTalentStatDamage(self.T_VILE_POISONS, "cun", 10, 50) * 0.4 end,
	getEffect = function(self, t) return 10 + self:getTalentLevel(self.T_VILE_POISONS) * 3 end,
	proc = function(self, t, target)
		if not checkChance(self, target) then return end
		target:setEffect(target.EFF_CRIPPLING_POISON, t.getDuration(self, t), {src=self, power=t.getDOT(self, t), fail=t.getEffect(self, t)})
	end,
	activate = function(self, t)
		cancelPoisons(self)
		self.vile_poisons = self.vile_poisons or {}
		self.vile_poisons[t.id] = true
		return {}
	end,
	deactivate = function(self, t, p)
		self.vile_poisons[t.id] = nil
		return true
	end,
	info = function(self, t)
		return ([[造成每轮 %d 点自然伤害持续 %d 回合，中毒目标每次使用技能都有 %d%% 概率失败。
		伤害受灵巧加成。]]):
		format(damDesc(self, DamageType.NATURE, t.getDOT(self, t)), t.getDuration(self, t), t.getEffect(self, t))
	end,
}

newTalent{
	name = "Stoning Poison",
	display_name = "石化毒剂",
	type = {"cunning/poisons-effects", 1},
	points = 1,
	mode = "sustained",
	cooldown = 10,
	no_break_stealth = true,
	no_energy = true,
	tactical = { BUFF = 2 },
	getDuration = function(self, t) return 12 - self:getTalentLevel(self.T_VILE_POISONS) end,
	getDOT = function(self, t) return 8 + self:combatTalentStatDamage(self.T_VILE_POISONS, "cun", 10, 30) * 0.4 end,
	getEffect = function(self, t) return math.ceil(2 + self:getTalentLevel(t) / 2) end,
	proc = function(self, t, target)
		if not checkChance(self, target) then return end
		if target:hasEffect(target.EFF_STONED) or target:hasEffect(target.EFF_STONE_POISON) then return end
		target:setEffect(target.EFF_STONE_POISON, t.getDuration(self, t), {src=self, power=t.getDOT(self, t), stone=t.getEffect(self, t)})
	end,
	activate = function(self, t)
		cancelPoisons(self)
		self.vile_poisons = self.vile_poisons or {}
		self.vile_poisons[t.id] = true
		return {}
	end,
	deactivate = function(self, t, p)
		self.vile_poisons[t.id] = nil
		return true
	end,
	info = function(self, t)
		return ([[造成每轮 %d 点自然伤害持续 %d 回合，效果结束后目标将被石化 %d 回合。
		伤害受灵巧加成。]]):
		format(damDesc(self, DamageType.NATURE, t.getDOT(self, t)), t.getDuration(self, t), t.getEffect(self, t))
	end,
}

