Skip to content
Snippets Groups Projects
Forked from tome / Tales of MajEyal
2841 commits behind the upstream repository.
summon-augmentation.lua 7.23 KiB
-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009 - 2018 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 = "Rage",
	type = {"wild-gift/summon-augmentation", 1},
	require = gifts_req1,
	mode = "passive",
	points = 5,
	radius = 5,
	incStats = function(self, t) return self:combatTalentMindDamage(t, 10, 100)/4 end,
	callbackOnSummonDeath = function(self, t, summon, src, death_note)
	if summon.summoner ~= self or not summon.wild_gift_summon or summon.summon_time <= 0 then return end
		local tg = {type="ball", range=0, radius=self:getTalentRadius(t), selffire = false, talent=t}
		summon:project(tg, self.x, self.y, function(px, py)
			local target = game.level.map(px, py, Map.ACTOR)
			if not target or target.summoner ~= self or not target.wild_gift_summon then return end
			target:setEffect(target.EFF_ALL_STAT, 5, {power=t.incStats(self,t)})
		end)
	end,
	info = function(self, t)
		return ([[Induces a killing rage in all your summons within a radius of 5 when a summon is killed, increasing all their stats by %d for 5 turns.]]):format(t.incStats(self, t))
	end,
}

newTalent{
	name = "Detonate",
	type = {"wild-gift/summon-augmentation", 2},
	require = gifts_req2,
	points = 5,
	equilibrium = 5,
	cooldown = 25,
	range = 10,
	radius = function(self, t) return math.floor(self:combatTalentScale(t, 4, 8, 0.5, 0, 0, true)) end,
	requires_target = true,
	no_npc_use = true,
--[[ WIP: how to set up tactics: (Not implemented at this time)
-- onAIgetTarget to find summon to detonate (closest to target) within radius
-- make sure target is in LOS and can be seen to not waste the summon
-- (use target.fov.actors_dist or LOS to target from summon grid?)
	
--	summon.wild_gift_detonate == t.id for summoning talent
--	tactical = summon.detonate_tactical

	tactical = function(self, t, aitarget)
		local sy, sy, summon = t.onAIgetTarget(self, t) -- finds summon to detonate
		
		if summon and summon.wild_gift_detonate then
			return self:getTalentFromID(summon.wild_gift_detonate).detonate_tactical
		
		end
	end,
--]]
	explodeDamage = function(self,t) return self:combatTalentMindDamage(t, 30, 250) end,
	explodeBleed = function(self,t) return self:combatTalentMindDamage(t, 30, 350) end,
	explodeBurn = function(self,t) return self:combatTalentMindDamage(t, 30, 300) end,
	explodeFire = function(self,t) return self:combatTalentMindDamage(t, 10, 70) end,
	knockbackDamage = function(self,t) return self:combatTalentMindDamage(t, 30, 150) end,
	knockbackDist = function(self,t) return 4 end,
	shellShielding = function(self,t) return self:combatTalentMindDamage(t, 10, 35) end,
	explodePin = function(self,t) return 3 end,
	action = function(self, t)
		local tg = {type="hit", range=self:getTalentRange(t), talent=t, first_target="friend"}
		local tx, ty, target = self:getTarget(tg)
		if not tx or not ty or not target or not target.summoner or target.summoner ~= self or not target.wild_gift_summon or not target.wild_gift_detonate then return nil end

		local dt = self:getTalentFromId(target.wild_gift_detonate)

		if not dt.on_detonate then
			game.logPlayer("You may not detonate this summon.")
			return nil
		end

		dt.on_detonate(self, t, target)
		target:die(self)

		local l = {}
		for tid, cd in pairs(self.talents_cd) do
			local t = self:getTalentFromId(tid)
			if t.is_summon then l[#l+1] = tid end
		end
		if #l > 0 then 
			self.talents_cd[rng.table(l)] = nil
		end

		game:playSoundNear(self, "talents/fireflash")
		return true
	end,
	info = function(self, t)
		local radius = self:getTalentRadius(t)
		return ([[Destroys one of your summons, making it detonate in radius of %d.
		- Ritch Flamespitter: Explodes into a fireball dealing %d damage
		- Hydra: Explodes into a ball of %d lightning, acid or poison damage, chosen at random
		- Rimebark: Explodes into an iceball dealing %d ice damage, possibly freezing damaged foes
		- Fire Drake: Explodes into a cloud of lingering fire, dealing %d damage per turn
		- War Hound: Explodes into a ball dealing %d physical damage
		- Jelly: Explodes into a ball of slowing slime, dealing %d nature damage and slowing foes by 15%%
		- Minotaur: Explodes into a sharp ball, cutting all creatures for %0.1f bleeding damage per turn for 6 turns
		- Stone Golem: Knocks back all creatures %d tiles and deals %d physical damage
		- Turtle: Grants a small shell shield to all friendly creatures, granting %d%% all resist
		- Spider: Pins all foes around for %d turns
		In addition, a random summon will come off cooldown.
		Hostile effects will not hit you or your other summons.
		The effects improve with your mindpower, and can crit.]]):format(radius, t.explodeBurn(self,t), t.explodeDamage(self,t), t.explodeBurn(self,t), t.explodeFire(self,t), t.explodeDamage(self, t), t.explodeDamage(self,t), t.explodeBleed(self,t) / 6, t.knockbackDist(self,t), t.knockbackDamage(self,t), t.shellShielding(self,t), t.explodePin(self,t))
	end,
}

newTalent{
	name = "Resilience",
	type = {"wild-gift/summon-augmentation", 3},
	require = gifts_req3,
	mode = "passive",
	points = 5,
	incLife = function(self, t) return self:combatTalentLimit(t, 1, 0.05, 0.20) end,
	incDur = function(self, t) return math.floor(self:combatTalentLimit(t, 6, 1, 2.8)) end,
	info = function(self, t)
		return ([[Increases all your summons' max life by %0.1f%% and extends your summons' maximum lifetime by %d turns.]]):format(100*t.incLife(self, t), t.incDur(self,t))
	end,
}

newTalent{
	name = "Phase Summon",
	type = {"wild-gift/summon-augmentation", 4},
	require = gifts_req4,
	points = 5,
	equilibrium = 5,
	cooldown = 25,
	range = 10,
	requires_target = true,
	np_npc_use = true,
	getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 2, 6)) end,
	action = function(self, t)
		local tg = {type="hit", nolock=true, range=self:getTalentRange(t), talent=t}
		local tx, ty, target = self:getTarget(tg)
		if not tx or not ty or not target or not target.summoner or target.summoner ~= self or not target.wild_gift_summon then return nil end

		local dur = t.getDuration(self, t)
		self:setEffect(self.EFF_EVASION, dur, {chance=50})
		target:setEffect(target.EFF_EVASION, dur, {chance=50})

		-- Displace
		game.level.map:remove(self.x, self.y, Map.ACTOR)
		game.level.map:remove(target.x, target.y, Map.ACTOR)
		game.level.map(self.x, self.y, Map.ACTOR, target)
		game.level.map(target.x, target.y, Map.ACTOR, self)
		self.x, self.y, target.x, target.y = target.x, target.y, self.x, self.y

		game:playSoundNear(self, "talents/teleport")
		return true
	end,
	info = function(self, t)
		return ([[Switches places with one of your summons. This disorients your foes, granting both you and your summon 50%% evasion for %d turns.]]):format(t.getDuration(self, t))
	end,
}