Skip to content
Snippets Groups Projects
augmented-mobility.lua 7.14 KiB
Newer Older
dg's avatar
dg committed
-- ToME - Tales of Maj'Eyal
DarkGod's avatar
DarkGod committed
-- Copyright (C) 2009, 2010, 2011, 2012, 2013 Nicolas Casalini
dg's avatar
dg committed
--
-- 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

DarkGod's avatar
DarkGod committed

dg's avatar
dg committed
newTalent{
DarkGod's avatar
DarkGod committed
	name = "Skate",
dg's avatar
dg committed
	type = {"psionic/augmented-mobility", 1},
DarkGod's avatar
DarkGod committed
	require = psi_wil_req1,
DarkGod's avatar
DarkGod committed
	points = 5,
	mode = "sustained",
	cooldown = 0,
	sustain_psi = 10,
	no_energy = true,
	tactical = { BUFF = 2 },
DarkGod's avatar
DarkGod committed
	getSpeed = function(self, t) return self:combatTalentScale(t, 0.2, 0.5, 0.75) end,
DarkGod's avatar
DarkGod committed
	getKBVulnerable = function(self, t) return self:combatTalentLimit(t, 1, 0.2, 0.8) end,
DarkGod's avatar
DarkGod committed
	activate = function(self, t)
		return {
			speed = self:addTemporaryValue("movement_speed", t.getSpeed(self, t)),
DarkGod's avatar
DarkGod committed
			knockback = self:addTemporaryValue("knockback_immune", -t.getKBVulnerable(self, t))
DarkGod's avatar
DarkGod committed
		}
	end,
	deactivate = function(self, t, p)
		self:removeTemporaryValue("movement_speed", p.speed)
		self:removeTemporaryValue("knockback_immune", p.knockback)
		return true
	end,
	info = function(self, t)
DarkGod's avatar
DarkGod committed
		return ([[You telekinetically float just off the ground.
DarkGod's avatar
DarkGod committed
		This allows you to slide around the battle quickly, increasing your movement speed by %d%%. 
		It also makes you more vulnerable to being pushed around (-%d%% knockback resistance).]]): 
		format(t.getSpeed(self, t)*100, t.getKBVulnerable(self, t)*100) 
dg's avatar
dg committed
	end,
}

newTalent{
	name = "Quick as Thought",
DarkGod's avatar
DarkGod committed
	type = {"psionic/augmented-mobility", 2},
	require = psi_wil_req2,
dg's avatar
dg committed
	points = 5,
	random_ego = "utility",
DarkGod's avatar
DarkGod committed
	cooldown = 20,
dg's avatar
dg committed
	psi = 30,
dg's avatar
dg committed
	no_energy = true,
DarkGod's avatar
DarkGod committed
	getDuration = function(self, t) return math.floor(self:combatLimit(self:combatMindpower(0.1), 10, 4, 0, 6, 6)) end, -- Limit < 10
DarkGod's avatar
DarkGod committed
	speed = function(self, t) return self:combatTalentScale(t, 0.6, 2.0, 0.75) end,
	getBoost = function(self, t)
		return self:combatScale(self:getTalentLevel(t)*self:combatStatTalentIntervalDamage(t, "combatMindpower", 1, 9), 15, 0, 49, 34)
	end,
dg's avatar
dg committed
	action = function(self, t)
		self:setEffect(self.EFF_QUICKNESS, t.getDuration(self, t), {power=t.speed(self, t)})
DarkGod's avatar
DarkGod committed
		self:setEffect(self.EFF_CONTROL, t.getDuration(self, t), {power=t.getBoost(self, t)})
dg's avatar
dg committed
		return true
	end,
	info = function(self, t)
dg's avatar
dg committed
		local percentinc = 100 * inc
DarkGod's avatar
DarkGod committed
		local boost = t.getBoost(self, t)
		return ([[Encase your body in a sheath of thought-quick forces, allowing you to control your body's movements directly without the inefficiency of dealing with crude mechanisms like nerves and muscles.
DarkGod's avatar
DarkGod committed
		Increases Accuracy by %d, your critical strike chance by %0.1f%% and your attack speed by %d%% for %d turns.
dg's avatar
dg committed
		The duration improves with your Mindpower.]]):
DarkGod's avatar
DarkGod committed
		format(boost, 0.5*boost, percentinc, t.getDuration(self, t))
dg's avatar
dg committed
	end,
}

DarkGod's avatar
DarkGod committed

dg's avatar
dg committed
newTalent{
	name = "Telekinetic Leap",
DarkGod's avatar
DarkGod committed
	type = {"psionic/augmented-mobility", 3},
	require = psi_wil_req3,
dg's avatar
dg committed
	cooldown = 15,
	psi = 10,
	points = 5,
	tactical = { CLOSEIN = 2 },
dg's avatar
dg committed
	range = function(self, t)
DarkGod's avatar
DarkGod committed
		return self:combatTalentLimit(t, 10, 5, 9) -- Limit < 10
dg's avatar
dg committed
	end,
	action = function(self, t)
		local tg = {default_target=self, type="ball", nolock=true, pass_terrain=false, nowarning=true, range=self:getTalentRange(t), radius=0, requires_knowledge=false}
		local x, y = self:getTarget(tg)
dg's avatar
dg committed
		if not x or not y then return nil end
		local _ _, x, y = self:canProject(tg, x, y)
		if not x or not y then return nil end

DarkGod's avatar
DarkGod committed

		local fx, fy = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true})
		if not fx then
			return
		end
		self:move(fx, fy, true)

DarkGod's avatar
DarkGod committed

dg's avatar
dg committed
		return true
	end,
	info = function(self, t)
		local range = self:getTalentRange(t)
DarkGod's avatar
DarkGod committed
		return ([[You perform a precise, telekinetically-enhanced leap, landing up to %d squares away.]]):
dg's avatar
dg committed
		format(range)
	end,
}

DarkGod's avatar
DarkGod committed
newTalent{
	name = "Shattering Charge",
	type = {"psionic/augmented-mobility", 4},
	require = psi_wil_req4,
	points = 5,
	random_ego = "attack",
	psi = 60,
	cooldown = 10,
	tactical = { CLOSEIN = 2, ATTACK = { PHYSICAL = 2 } },
	range = function(self, t)
		return self:combatTalentLimit(t, 10, 6, 9) --Limit base range to 10
	end,
	--range = function(self, t) return 3+self:getTalentLevel(t)+self:getWil(4) end,
	direct_hit = true,
	requires_target = true,
	action = function(self, t)
		if self:getTalentLevelRaw(t) < 5 then
			local tg = {type="beam", range=self:getTalentRange(t), nolock=true, talent=t}
			local x, y = self:getTarget(tg)
			if not x or not y then return nil end
			if self:hasLOS(x, y) and not game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move") then
				local dam = self:mindCrit(self:combatTalentMindDamage(t, 20, 600))
				self:project(tg, x, y, DamageType.MINDKNOCKBACK, self:mindCrit(rng.avg(2*dam/3, dam, 3)))
				--local _ _, x, y = self:canProject(tg, x, y)
				game.level.map:particleEmitter(self.x, self.y, tg.radius, "flamebeam", {tx=x-self.x, ty=y-self.y})
				game:playSoundNear(self, "talents/lightning")
				--self:move(x, y, true)
				local fx, fy = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true})
				if not fx then
					return
				end
				self:move(fx, fy, true)
			else
				game.logSeen(self, "You can't move there.")
				return nil
			end
			return true
		else
			local tg = {type="beam", range=self:getTalentRange(t), nolock=true, talent=t, display={particle="bolt_earth", trail="earthtrail"}}
			local x, y = self:getTarget(tg)
			if not x or not y then return nil end
			local dam = self:mindCrit(self:combatTalentMindDamage(t, 20, 600))

			for i = 1, self:getTalentRange(t) do
				self:project(tg, x, y, DamageType.DIG, 1)
			end
			self:project(tg, x, y, DamageType.MINDKNOCKBACK, self:mindCrit(rng.avg(2*dam/3, dam, 3)))
			local _ _, x, y = self:canProject(tg, x, y)
			game.level.map:particleEmitter(self.x, self.y, tg.radius, "flamebeam", {tx=x-self.x, ty=y-self.y})
			game:playSoundNear(self, "talents/lightning")

			local block_actor = function(_, bx, by) return game.level.map:checkEntity(bx, by, engine.Map.TERRAIN, "block_move", self) end
			local l = self:lineFOV(x, y, block_actor)
			local lx, ly, is_corner_blocked = l:step()
			local tx, ty = self.x, self.y
			while lx and ly do
				if is_corner_blocked or block_actor(_, lx, ly) then break end
				tx, ty = lx, ly
				lx, ly, is_corner_blocked = l:step()
			end
DarkGod's avatar
DarkGod committed
			--self:move(tx, ty, true)
			local fx, fy = util.findFreeGrid(tx, ty, 5, true, {[Map.ACTOR]=true})
			if not fx then
				return
			end
			self:move(fx, fy, true)
			return true
		end
	end,
	info = function(self, t)
		local range = self:getTalentRange(t)
		local dam = self:combatTalentMindDamage(t, 20, 600)
		return ([[You expend massive amounts of energy to launch yourself across %d squares at incredible speed. All enemies in your path will be knocked flying and dealt between %d and %d damage. 
		At talent level 5, you can batter through solid walls.]]):
		format(range, 2*dam/3, dam)
	end,
}