From 730c28f3bb1bb624e9c4b1917409fe0117c47296 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Tue, 26 Jan 2010 09:47:50 +0000
Subject: [PATCH] disruption shield explodes if low on mana time shield

git-svn-id: http://svn.net-core.org/repos/t-engine4@272 51575b47-30f0-44d4-a5cc-537603b46e54
---
 .../interface/ActorTemporaryEffects.lua       |  7 ++-
 game/modules/tome/class/Actor.lua             | 43 +++++++++++++++----
 game/modules/tome/data/autolevel_schemes.lua  | 10 +++++
 game/modules/tome/data/damage_types.lua       |  1 +
 .../tome/data/talents/spells/arcane.lua       |  7 ++-
 .../tome/data/talents/spells/nature.lua       |  4 +-
 .../tome/data/talents/spells/temporal.lua     | 16 ++++---
 game/modules/tome/data/timed_effects.lua      | 38 ++++++++++++++++
 8 files changed, 106 insertions(+), 20 deletions(-)

diff --git a/game/engine/interface/ActorTemporaryEffects.lua b/game/engine/interface/ActorTemporaryEffects.lua
index 1a8bd9bfa5..d237e11e1b 100644
--- a/game/engine/interface/ActorTemporaryEffects.lua
+++ b/game/engine/interface/ActorTemporaryEffects.lua
@@ -43,16 +43,21 @@ end
 --- Counts down timed effects, call from your actors "act" method
 --
 function _M:timedEffects()
+	local todel = {}
 	for eff, p in pairs(self.tmp) do
 		p.dur = p.dur - 1
 		if p.dur <= 0 then
-			self:removeEffect(eff)
+			todel[#todel+1] = eff
 		else
 			if _M.tempeffect_def[eff].on_timeout then
 				_M.tempeffect_def[eff].on_timeout(self, p)
 			end
 		end
 	end
+
+	while #todel > 0 do
+		self:removeEffect(table.remove(todel))
+	end
 end
 
 --- Sets a timed effect on the actor
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index dce7878d51..bcf13c7b2d 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -155,14 +155,45 @@ function _M:onTakeHit(value, src)
 		return 0
 	end
 
-	if self:attr("mana_shield") then
+	if self:attr("disruption_shield") then
 		local mana = self:getMana()
-		local mana_val = value * self:attr("mana_shield")
+		local mana_val = value * self:attr("disruption_shield")
 		-- We have enough to absord the full hit
 		if mana_val <= mana then
 			self:incMana(-mana_val)
+			self.disruption_shield_absorb = self.disruption_shield_absorb + value
 			return 0
-		-- Or we dont! and we do nothing
+		-- Or the shield collapses in a deadly arcane explosion
+		else
+			local dam = self.disruption_shield_absorb
+
+			-- Deactivate without loosing energy
+			local old = self.energy.value
+			self.energy.value = 10000
+			self:useTalent(self.T_DISRUPTION_SHIELD)
+			self.energy.value = old
+
+			-- Explode!
+			game.logSeen(self, "%s disruption shield collapses and then explodes in a powerfull manastorm!", self.name:capitalize())
+			local tg = {type="ball", radius=5}
+			self:project(tg, self.x, self.y, engine.DamageType.ARCANE, dam, {type="manathrust"})
+		end
+	end
+
+	if self:attr("time_shield") then
+		-- Absorb damage into the time shield
+		if value <= self.time_shield_absorb then
+			self.time_shield_absorb = self.time_shield_absorb - value
+			value = 0
+		else
+			self.time_shield_absorb = 0
+			value = value - self.time_shield_absorb
+		end
+
+		-- If we are at the end of the capacity, release the time shield damage
+		if self.time_shield_absorb <= 0 then
+			game.logPlayer(self, "Your time shield crumbles under the damage!")
+			self:removeEffect(self.EFF_TIME_SHIELD)
 		end
 	end
 	return value
@@ -190,7 +221,7 @@ function _M:die(src)
 end
 
 function _M:levelup()
-	self.unused_stats = self.unused_stats + 2
+	self.unused_stats = self.unused_stats + 3
 	self.unused_talents = self.unused_talents + 2
 	if self.level % 10 == 0 then
 		self.unused_talents_types = self.unused_talents_types + 1
@@ -222,10 +253,6 @@ function _M:levelup()
 	end
 end
 
-function _M:updateBonus()
-	engine.Actor.updateBonus(self)
-end
-
 --- Notifies a change of stat value
 function _M:onStatChange(stat, v)
 	if stat == self.STAT_CON then
diff --git a/game/modules/tome/data/autolevel_schemes.lua b/game/modules/tome/data/autolevel_schemes.lua
index 5804bfa354..511c328fc7 100644
--- a/game/modules/tome/data/autolevel_schemes.lua
+++ b/game/modules/tome/data/autolevel_schemes.lua
@@ -14,6 +14,16 @@ Autolevel:registerScheme{ name = "warrior", levelup = function(self)
 	learnStats(self, { self.STAT_STR, self.STAT_STR, self.STAT_DEX })
 end}
 
+Autolevel:registerScheme{ name = "warrior", levelup = function(self)
+	-- 2 STR for 1 DEX
+	learnStats(self, { self.STAT_STR, self.STAT_STR, self.STAT_DEX })
+end}
+
+Autolevel:registerScheme{ name = "rogue", levelup = function(self)
+	-- 2 STR for 1 DEX
+	learnStats(self, { self.STAT_DEX, self.STAT_CUN, self.STAT_CUN })
+end}
+
 Autolevel:registerScheme{ name = "caster", levelup = function(self)
 	-- 2 MAG for 1 WIL
 	learnStats(self, { self.STAT_MAG, self.STAT_MAG, self.STAT_WIL })
diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua
index 2a375a3676..6bf9a832d3 100644
--- a/game/modules/tome/data/damage_types.lua
+++ b/game/modules/tome/data/damage_types.lua
@@ -31,6 +31,7 @@ setDefaultProjector(function(src, x, y, type, dam)
 end)
 
 local function tryDestroy(who, inven, destroy_prop, proof_prop, msg)
+	if not inven then return end
 	for i = #inven, 1, -1 do
 		local o = inven[i]
 		print(who, inven, destroy_prop, proof_prop, msg, "::", i)
diff --git a/game/modules/tome/data/talents/spells/arcane.lua b/game/modules/tome/data/talents/spells/arcane.lua
index baa5b69dfc..d7e29134d7 100644
--- a/game/modules/tome/data/talents/spells/arcane.lua
+++ b/game/modules/tome/data/talents/spells/arcane.lua
@@ -75,16 +75,19 @@ newTalent{
 	},
 	activate = function(self, t)
 		local power = math.max(0.8, 3 - (self:combatSpellpower(1) * self:getTalentLevel(t)) / 280)
+		self.disruption_shield_absorb = 0
 		return {
-			shield = self:addTemporaryValue("mana_shield", power),
+			shield = self:addTemporaryValue("disruption_shield", power),
 		}
 	end,
 	deactivate = function(self, t, p)
-		self:removeTemporaryValue("mana_shield", p.shield)
+		self:removeTemporaryValue("disruption_shield", p.shield)
+		self.disruption_shield_absorb = nil
 		return true
 	end,
 	info = function(self, t)
 		return ([[Uses mana instead of life to take damage. Uses %0.2f mana per damage taken.
+		If your mana is brought too low by the shield it will de-activate and the chain reaction will release a deadly arcane explosion of the amount of damage absorbed.
 		The damage to mana ratio increases with the Magic stat]]):format(math.max(0.8, 3 - (self:combatSpellpower(1) * self:getTalentLevel(t)) / 280))
 	end,
 }
diff --git a/game/modules/tome/data/talents/spells/nature.lua b/game/modules/tome/data/talents/spells/nature.lua
index 3566ccedef..4b30b70f01 100644
--- a/game/modules/tome/data/talents/spells/nature.lua
+++ b/game/modules/tome/data/talents/spells/nature.lua
@@ -82,7 +82,7 @@ newTalent{
 			combat = { dam=resolvers.rngavg(12,25), atk=10, apr=10, physspeed=2 },
 
 			summoner = self,
-			summon_time = util.bound(self:getTalentLevel(t) * self:combatSpellpower(25), 5, 90),
+			summon_time = util.bound(self:getTalentLevel(t) * self:combatSpellpower(0.15), 5, 90),
 		}
 
 		bear:resolve()
@@ -94,6 +94,6 @@ newTalent{
 	end,
 	info = function(self, t)
 		return ([[Call upon the forces of nature to summon bear ally for %d turns.
-		The power of the ally will increase with the Magic stat]]):format(util.bound(self:getTalentLevel(t) * self:combatSpellpower(25), 5, 90))
+		The power of the ally will increase with the Magic stat]]):format(util.bound(self:getTalentLevel(t) * self:combatSpellpower(0.15), 5, 90))
 	end,
 }
diff --git a/game/modules/tome/data/talents/spells/temporal.lua b/game/modules/tome/data/talents/spells/temporal.lua
index b6b874a100..6cd6fcdf88 100644
--- a/game/modules/tome/data/talents/spells/temporal.lua
+++ b/game/modules/tome/data/talents/spells/temporal.lua
@@ -36,12 +36,12 @@ newTalent{
 		local tg = {type="hit", range=self:getTalentRange(t)}
 		local x, y = self:getTarget(tg)
 		if not x or not y then return nil end
-		self:project(tg, x, y, DamageType.SLOW, util.bound((self:combatSpellpower(25) * self:getTalentLevel(t)) / 100, 0.1, 0.4), {type="manathrust"})
+		self:project(tg, x, y, DamageType.SLOW, util.bound((self:combatSpellpower(0.25) * self:getTalentLevel(t)) / 100, 0.1, 0.4), {type="manathrust"})
 		return true
 	end,
 	info = function(self, t)
 		return ([[Decreases the target global speed by %.2f for 7 turns.
-		The speed decreases with the Magic stat]]):format(util.bound((self:combatSpellpower(25) * self:getTalentLevel(t)) / 100, 0.1, 0.4))
+		The speed decreases with the Magic stat]]):format(util.bound((self:combatSpellpower(0.25) * self:getTalentLevel(t)) / 100, 0.1, 0.4))
 	end,
 }
 
@@ -57,7 +57,7 @@ newTalent{
 		BUFF = 10,
 	},
 	activate = function(self, t)
-		local power = util.bound((self:combatSpellpower(50) * self:getTalentLevel(t)) / 100, 0.1, 2)
+		local power = util.bound((self:combatSpellpower(0.5) * self:getTalentLevel(t)) / 100, 0.1, 2)
 		return {
 			speed = self:addTemporaryValue("energy", {mod=power}),
 		}
@@ -68,7 +68,7 @@ newTalent{
 	end,
 	info = function(self, t)
 		return ([[Increases the caster global speed by %.2f.
-		The speed increases with the Magic stat]]):format(util.bound((self:combatSpellpower(50) * self:getTalentLevel(t)) / 100, 0.1, 2))
+		The speed increases with the Magic stat]]):format(util.bound((self:combatSpellpower(0.5) * self:getTalentLevel(t)) / 100, 0.1, 2))
 	end,
 }
 
@@ -84,12 +84,14 @@ newTalent{
 	},
 	range = 20,
 	action = function(self, t)
-		print("IMPLEMENT ME ยง!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+		local dur = util.bound(5 + math.floor(self:getTalentLevel(t)), 5, 15)
+		local power = 50 + self:combatSpellpower(0.5) * self:getTalentLevel(t)
+		self:setEffect(self.EFF_TIME_SHIELD, dur, {power=power})
 		return true
 	end,
 	info = function(self, t)
 		return ([[This intricate spell erects time shield around the caster, preventing any incomming damage and sending it forward in time.
-		Once the maximun damage (%d) is absorbed or the time runs out (%d turns) the stored damage will come back as a damage over time.
-		The duration and max absorption will increase with the Magic stat]]):format(4 + self:combatSpellpower(0.03) * self:getTalentLevel(t), 1)
+		Once the maximun damage (%d) is absorbed or the time runs out (%d turns) the stored damage will come back as a damage over time (5 turns).
+		The duration and max absorption will increase with the Magic stat]]):format(50 + self:combatSpellpower(0.5) * self:getTalentLevel(t), util.bound(5 + math.floor(self:getTalentLevel(t)), 5, 15))
 	end,
 }
diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua
index 0f5f97028b..ef13c74e87 100644
--- a/game/modules/tome/data/timed_effects.lua
+++ b/game/modules/tome/data/timed_effects.lua
@@ -320,3 +320,41 @@ newEffect{
 		self:removeTemporaryValue("stats", eff.stat)
 	end,
 }
+
+newEffect{
+	name = "TIME_SHIELD",
+	desc = "Time Shield",
+	type = "time",
+	status = "beneficial",
+	parameters = { power=10 },
+	on_gain = function(self, err) return "The very fabric of time alters around #target#.", "+Time Shield" end,
+	on_lose = function(self, err) return "The fabric of time around #target# stabilizes to normal.", "-Time Shield" end,
+	activate = function(self, eff)
+		eff.tmpid = self:addTemporaryValue("time_shield", eff.power)
+		--- Warning there can be only one time shield active at once for an actor
+		self.time_shield_absorb = eff.power
+	end,
+	deactivate = function(self, eff)
+		-- Time shield ends, setup a dot if needed
+		if eff.power - self.time_shield_absorb > 0 then
+			print("Time shield dot", eff.power - self.time_shield_absorb, (eff.power - self.time_shield_absorb) / 5)
+			self:setEffect(self.EFF_TIME_DOT, 5, {power=(eff.power - self.time_shield_absorb) / 5})
+		end
+
+		self:removeTemporaryValue("time_shield", eff.tmpid)
+		self.time_shield_absorb = nil
+	end,
+}
+
+newEffect{
+	name = "TIME_DOT",
+	desc = "Time Shield Backfire",
+	type = "time",
+	status = "detrimental",
+	parameters = { power=10 },
+	on_gain = function(self, err) return "The powerfull time altering energies come crashing down on #target#.", "+Time Shield Backfire" end,
+	on_lose = function(self, err) return "The fabric of time around #target# returns to normal.", "-Time Shield Backfire" end,
+	on_timeout = function(self, eff)
+		DamageType:get(DamageType.ARCANE).projector(self, self.x, self.y, DamageType.ARCANE, eff.power)
+	end,
+}
-- 
GitLab