From 4713e8de669f21ead71dacccab6946c233551713 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Tue, 25 Dec 2012 16:42:54 +0000
Subject: [PATCH] 6 new prodigies: Superpower(str), Vital Shot(dex), Corrupted
 Shell(con), Cauterize(mag), Mental Tyrany(wil) and Tricks of the Trade(cun)

git-svn-id: http://svn.net-core.org/repos/t-engine4@6215 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engines/default/engine/Entity.lua        |   1 +
 game/engines/default/engine/Map.lua           |   2 +-
 game/modules/tome/class/Actor.lua             |  13 +++++++
 game/modules/tome/class/Game.lua              |  27 +------------
 game/modules/tome/class/Player.lua            |   3 +-
 .../tome/class/interface/ActorLife.lua        |   8 +++-
 game/modules/tome/class/interface/Archery.lua |   3 ++
 game/modules/tome/class/interface/Combat.lua  |  20 ++++++++++
 game/modules/tome/data/damage_types.lua       |  10 ++++-
 .../tome/data/gfx/talents/cauterize.png       | Bin 0 -> 3522 bytes
 .../tome/data/gfx/talents/corrupted_shell.png | Bin 0 -> 4769 bytes
 .../tome/data/gfx/talents/mental_tyranny.png  | Bin 0 -> 2565 bytes
 .../tome/data/gfx/talents/superpower.png      | Bin 0 -> 4472 bytes
 .../data/gfx/talents/tricks_of_the_trade.png  | Bin 0 -> 3900 bytes
 .../tome/data/gfx/talents/vital_shot.png      | Bin 0 -> 2693 bytes
 game/modules/tome/data/talents/misc/npcs.lua  |   4 +-
 game/modules/tome/data/talents/uber/const.lua |  22 +++++++++++
 game/modules/tome/data/talents/uber/cun.lua   |  26 +++++++++++++
 game/modules/tome/data/talents/uber/dex.lua   |  28 ++++++++++++++
 game/modules/tome/data/talents/uber/mag.lua   |  23 ++++++++++-
 game/modules/tome/data/talents/uber/str.lua   |  11 ++++++
 game/modules/tome/data/talents/uber/wil.lua   |  35 +++++++++++++++++
 .../modules/tome/data/timed_effects/other.lua |  36 ++++++++++++++++++
 23 files changed, 238 insertions(+), 34 deletions(-)
 create mode 100644 game/modules/tome/data/gfx/talents/cauterize.png
 create mode 100644 game/modules/tome/data/gfx/talents/corrupted_shell.png
 create mode 100644 game/modules/tome/data/gfx/talents/mental_tyranny.png
 create mode 100644 game/modules/tome/data/gfx/talents/superpower.png
 create mode 100644 game/modules/tome/data/gfx/talents/tricks_of_the_trade.png
 create mode 100644 game/modules/tome/data/gfx/talents/vital_shot.png

diff --git a/game/engines/default/engine/Entity.lua b/game/engines/default/engine/Entity.lua
index 02ce3c5cdc..d29573751b 100644
--- a/game/engines/default/engine/Entity.lua
+++ b/game/engines/default/engine/Entity.lua
@@ -690,6 +690,7 @@ end
 function _M:removeTemporaryValue(prop, id, noupdate)
 	local oldval = self.compute_vals[id]
 	print("removeTempVal", prop, oldval, " :=: ", id)
+	if not id then error("error removing prop "..tostring(prop).." with id nil") end
 	self.compute_vals[id] = nil
 
 	-- Find the base, one removed from the last prop
diff --git a/game/engines/default/engine/Map.lua b/game/engines/default/engine/Map.lua
index 83f6056f2d..58fbe79403 100644
--- a/game/engines/default/engine/Map.lua
+++ b/game/engines/default/engine/Map.lua
@@ -1144,7 +1144,7 @@ function _M:displayParticles(nb_keyframes)
 	local dx, dy = self.display_x, self.display_y
 	for i = #self.particles, 1, -1 do
 		e = self.particles[i]
-		if e.ps then
+		if e and e.ps then
 			adx, ady = 0, 0
 			if e.x and e.y then
 				-- Make sure we display on the real screen coords: handle current move anim position
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 23cf102fdf..16976a3972 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -116,6 +116,8 @@ function _M:init(t, no_default)
 	self.combat_spellresist = 0
 	self.combat_mentalresist = 0
 
+	t.old_life = 0
+
 	self.fatigue = 0
 
 	self.spell_cooldown_reduction = 0
@@ -635,6 +637,9 @@ function _M:act()
 	-- Still not dead ?
 	if self.dead then return false end
 
+	-- Register life for this turn
+	self.old_life = self.life
+
 	-- Ok reset the seen cache
 	self:resetCanSeeCache()
 
@@ -1834,6 +1839,14 @@ function _M:onTakeHit(value, src)
 		end
 	end
 
+	if self:hasEffect(self.EFF_CAUTERIZE) then
+		local eff = self:hasEffect(self.EFF_CAUTERIZE)
+		if eff.invulnerable then 
+			eff.dam = eff.dam + value / 10
+			return 0
+		end
+	end
+
 	-- Reduce sleep durations
 	if self:attr("sleep") then
 		local effs = {}
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 4021052c70..684ec6c3a5 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -1275,32 +1275,7 @@ function _M:setupCommands()
 			print("===============")
 		end end,
 		[{"_g","ctrl"}] = function() if config.settings.cheat then
-			local elf = mod.class.NPC.new{
-				name = "red helper elf", type="humanoid", subtype="elf",
-				image = "player/elf_female/base_shadow_01.png", display_w = 0.7, display_h = 0.7, display_x = 0.15, display_y = 0.15,
-				add_mos = {
-					{image="player/elf_female/cloak_behind_02.png", display_w = 0.7, display_h = 0.7, display_x = 0.15, display_y = 0.15},
-					{image="player/elf_female/base_redhead_01.png", display_w = 0.7, display_h = 0.7, display_x = 0.15, display_y = 0.15},
-					{image="player/elf_female/lower_body_06.png", display_w = 0.7, display_h = 0.7, display_x = 0.15, display_y = 0.15},
-					{image="player/elf_female/upper_body_09.png", display_w = 0.7, display_h = 0.7, display_x = 0.15, display_y = 0.15},
-					{image="player/elf_female/braid_redhead_02.png", display_w = 0.7, display_h = 0.7, display_x = 0.15, display_y = 0.15},
-				},
-			}
-			game.zone:addEntity(game.level, elf, "actor", game.player.x, game.player.y+1)
-
-			local elf = mod.class.NPC.new{
-				name = "green helper elf", type="humanoid", subtype="elf",
-				image = "player/elf_female/base_shadow_01.png", display_w = 0.7, display_h = 0.7, display_x = 0.15, display_y = 0.15,
-				add_mos = {
-					{image="player/elf_female/cloak_behind_06.png", display_w = 0.7, display_h = 0.7, display_x = 0.15, display_y = 0.15},
-					{image="player/elf_female/base_thalore_01.png", display_w = 0.7, display_h = 0.7, display_x = 0.15, display_y = 0.15},
-					{image="player/elf_female/lower_body_04.png", display_w = 0.7, display_h = 0.7, display_x = 0.15, display_y = 0.15},
-					{image="player/elf_female/upper_body_06.png", display_w = 0.7, display_h = 0.7, display_x = 0.15, display_y = 0.15},
-					{image="player/elf_female/braid_01.png", display_w = 0.7, display_h = 0.7, display_x = 0.15, display_y = 0.15},
-				},
-			}
-			game.zone:addEntity(game.level, elf, "actor", game.player.x+1, game.player.y+1)
-
+			game.player:takeHit(1500, game.player)
 do return end
 			self:registerDialog(require("mod.dialogs.DownloadCharball").new())
 do return end
diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua
index cfaaebac05..3494cc6c37 100644
--- a/game/modules/tome/class/Player.lua
+++ b/game/modules/tome/class/Player.lua
@@ -75,7 +75,6 @@ function _M:init(t, no_default)
 	t.lite = t.lite or 0
 
 	t.rank = t.rank or 3
-	t.old_life = 0
 	t.old_air = 0
 	t.old_psi = 0
 
@@ -90,6 +89,7 @@ function _M:init(t, no_default)
 	self.puuid = self.puuid or util.uuid()
 
 	self.damage_log = self.damage_log or {weapon={}}
+	self.damage_intake_log = self.damage_intake_log or {weapon={}}
 	self.talent_kind_log = self.talent_kind_log or {}
 end
 
@@ -296,7 +296,6 @@ function _M:act()
 	-- Funky shader things !
 	self:updateMainShader()
 
-	self.old_life = self.life
 	self.old_air = self.air
 	self.old_psi = self.psi
 
diff --git a/game/modules/tome/class/interface/ActorLife.lua b/game/modules/tome/class/interface/ActorLife.lua
index c4caebb40f..13690c4d1e 100644
--- a/game/modules/tome/class/interface/ActorLife.lua
+++ b/game/modules/tome/class/interface/ActorLife.lua
@@ -32,8 +32,12 @@ function _M:takeHit(value, src, death_note)
 	self.life = self.life - value
 	self.changed = true
 	if self.life <= self.die_at then
-		if src.on_kill and src:on_kill(self) then return false, value end
-		return self:die(src, death_note), value
+		if self:knowTalent(self.T_CAUTERIZE) and self:triggerTalent(self.T_CAUTERIZE, nil, value) then
+			return false, 0
+		else
+			if src.on_kill and src:on_kill(self) then return false, value end
+			return self:die(src, death_note), value
+		end
 	end
 	return false, value
 end
\ No newline at end of file
diff --git a/game/modules/tome/class/interface/Archery.lua b/game/modules/tome/class/interface/Archery.lua
index 41e588d11f..3627599a6a 100644
--- a/game/modules/tome/class/interface/Archery.lua
+++ b/game/modules/tome/class/interface/Archery.lua
@@ -132,6 +132,8 @@ local function archery_projectile(tx, ty, tg, self, tmp)
 	local damtype = tg.archery.damtype or ammo.damtype or DamageType.PHYSICAL
 	local mult = tg.archery.mult or 1
 
+	self.turn_procs.weapon_type = {kind=weapon and weapon.talented or "unknown", mode="archery"}
+
 	-- Does the blow connect? yes .. complex :/
 	if tg.archery.use_psi_archery then self.use_psi_combat = true end
 	local atk, def = self:combatAttackRanged(weapon, ammo), target:combatDefenseRanged()
@@ -404,6 +406,7 @@ local function archery_projectile(tx, ty, tg, self, tmp)
 		target.turn_procs.roll_with_it = true
 	end
 
+	self.turn_procs.weapon_type = nil
 	self.use_psi_combat = false
 end
 
diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
index 39f7c33b81..4db24aa03f 100644
--- a/game/modules/tome/class/interface/Combat.lua
+++ b/game/modules/tome/class/interface/Combat.lua
@@ -908,6 +908,9 @@ function _M:combatDefenseBase(fake)
 		local t = self:getTalentFromId(self.T_TACTICAL_EXPERT)
 		add = add + t.do_tact_update(self, t)
 	end
+	if self:knowTalent(self.T_CORRUPTED_SHELL) then
+		add = add + self:getCon() / 3
+	end
 	if self:knowTalent(self.T_STEADY_MIND) then
 		local t = self:getTalentFromId(self.T_STEADY_MIND)
 		add = add + t.getDefense(self, t)
@@ -1112,6 +1115,10 @@ function _M:combatDamage(weapon)
 		end
 	end
 
+	if self:knowTalent(self.T_SUPERPOWER) then
+		totstat = totstat + self:getStat("wil") * 0.3
+	end
+
 	if self:knowTalent(self.T_ARCANE_MIGHT) then
 		totstat = totstat + self:getStat("mag") * 0.5
 	end
@@ -1432,6 +1439,10 @@ function _M:combatMindpower(mod, add)
 	mod = mod or 1
 	add = add or 0
 
+	if self:knowTalent(self.T_SUPERPOWER) then
+		add = add + 25 * self:getStr() / 100
+	end
+
 	if self:knowTalent(self.T_GESTURE_OF_POWER) then
 		local t = self:getTalentFromId(self.T_GESTURE_OF_POWER)
 		add = add + t.getMindpowerChange(self, t)
@@ -1487,6 +1498,9 @@ function _M:combatPhysicalResist(fake)
 	if not fake then
 		add = add + (self:checkOnDefenseCall("physical") or 0)
 	end
+	if self:knowTalent(self.T_CORRUPTED_SHELL) then
+		add = add + self:getCon() / 3
+	end
 	if self:knowTalent(self.T_POWER_IS_MONEY) then
 		add = add + util.bound(self.money / (90 - self:getTalentLevelRaw(self.T_POWER_IS_MONEY) * 5), 0, self:getTalentLevelRaw(self.T_POWER_IS_MONEY) * 7)
 	end
@@ -1512,6 +1526,9 @@ function _M:combatSpellResist(fake)
 	if not fake then
 		add = add + (self:checkOnDefenseCall("spell") or 0)
 	end
+	if self:knowTalent(self.T_CORRUPTED_SHELL) then
+		add = add + self:getCon() / 3
+	end
 	if self:knowTalent(self.T_POWER_IS_MONEY) then
 		add = add + util.bound(self.money / (90 - self:getTalentLevelRaw(self.T_POWER_IS_MONEY) * 5), 0, self:getTalentLevelRaw(self.T_POWER_IS_MONEY) * 7)
 	end
@@ -1537,6 +1554,9 @@ function _M:combatMentalResist(fake)
 	if not fake then
 		add = add + (self:checkOnDefenseCall("mental") or 0)
 	end
+	if self:knowTalent(self.T_CORRUPTED_SHELL) then
+		add = add + self:getCon() / 3
+	end
 	if self:knowTalent(self.T_STEADY_MIND) then
 		local t = self:getTalentFromId(self.T_STEADY_MIND)
 		add = add + t.getMental(self, t)
diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua
index 404aec3f57..24090a856e 100644
--- a/game/modules/tome/data/damage_types.lua
+++ b/game/modules/tome/data/damage_types.lua
@@ -293,7 +293,7 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
 			print("[PROJECTOR] stunned dam", dam)
 		end
 		if src:attr("invisible_damage_penalty") then
-			dam = dam * util.bound(1 - src.invisible_damage_penalty, 0, 1)
+			dam = dam * util.bound(1 - (src.invisible_damage_penalty / (src.invisible_damage_penalty_divisor or 1)), 0, 1)
 			print("[PROJECTOR] invisible dam", dam)
 		end
 		if src:attr("numbed") then
@@ -400,6 +400,14 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
 			end
 		end
 
+		if dam > 0 and target.damage_intake_log and target.damage_intake_log.weapon then
+			target.damage_intake_log[type] = (target.damage_intake_log[type] or 0) + dam
+			if src.turn_procs and src.turn_procs.weapon_type then
+				target.damage_intake_log.weapon[src.turn_procs.weapon_type.kind] = (target.damage_intake_log.weapon[src.turn_procs.weapon_type.kind] or 0) + dam
+				target.damage_intake_log.weapon[src.turn_procs.weapon_type.mode] = (target.damage_intake_log.weapon[src.turn_procs.weapon_type.mode] or 0) + dam
+			end
+		end
+
 		if dam > 0 and source_talent then
 			local t = source_talent
 
diff --git a/game/modules/tome/data/gfx/talents/cauterize.png b/game/modules/tome/data/gfx/talents/cauterize.png
new file mode 100644
index 0000000000000000000000000000000000000000..5507a0b0ea4fa6b4869338cd9542137d58ae8464
GIT binary patch
literal 3522
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

literal 0
HcmV?d00001

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

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/gfx/talents/mental_tyranny.png b/game/modules/tome/data/gfx/talents/mental_tyranny.png
new file mode 100644
index 0000000000000000000000000000000000000000..a753d010e7c4527769dc680dc4363af7e007ed4e
GIT binary patch
literal 2565
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
b3zGi@kWQ8;T_AP(00000NkvXXu0mjfY*PbW

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/gfx/talents/superpower.png b/game/modules/tome/data/gfx/talents/superpower.png
new file mode 100644
index 0000000000000000000000000000000000000000..dd0d82028de3a3f449f67a49daa4cff33a5f4a5e
GIT binary patch
literal 4472
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
KMNUMnLSTYP*qBxT

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/gfx/talents/tricks_of_the_trade.png b/game/modules/tome/data/gfx/talents/tricks_of_the_trade.png
new file mode 100644
index 0000000000000000000000000000000000000000..3c0d7b6524a8137a79efbcc7bb37514e5b385ee5
GIT binary patch
literal 3900
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
KMNUMnLSTY9>||sB

literal 0
HcmV?d00001

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

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/talents/misc/npcs.lua b/game/modules/tome/data/talents/misc/npcs.lua
index da44ef28a6..28146f97fb 100644
--- a/game/modules/tome/data/talents/misc/npcs.lua
+++ b/game/modules/tome/data/talents/misc/npcs.lua
@@ -1724,7 +1724,9 @@ newTalent{
 		local x, y = self:getTarget(tg)
 		if not x or not y then return nil end
 
-		local terrains = mod.class.Grid:loadList("/data/general/grids/lava.lua")
+		local terrains = t.terrains or mod.class.Grid:loadList("/data/general/grids/lava.lua")
+		t.terrains = terrains -- cache
+
 		local meteor = function(src, x, y, dam)
 			game.level.map:particleEmitter(x, y, 10, "meteor", {x=x, y=y}).on_remove = function(self)
 				local x, y = self.args.x, self.args.y
diff --git a/game/modules/tome/data/talents/uber/const.lua b/game/modules/tome/data/talents/uber/const.lua
index f4afd1051c..1b583795f3 100644
--- a/game/modules/tome/data/talents/uber/const.lua
+++ b/game/modules/tome/data/talents/uber/const.lua
@@ -152,3 +152,25 @@ uberTalent{
 		:format(self:getCon() * 1.5, self:getCon() * self.max_life / 100)
 	end,
 }
+
+uberTalent{
+	name = "Corrupted Shell",
+	mode = "passive",
+	require = { special={desc="Received at least 50000 blight damage and destroyed Zigur with the Grand Corruptor.", fct=function(self) return
+		(self.damage_intake_log and self.damage_intake_log[DamageType.BLIGHT] and self.damage_intake_log[DamageType.BLIGHT] >= 50000) and
+		(game.state.birth.ignore_prodigies_special_reqs or (
+			self:hasQuest("anti-antimagic") and 
+			self:hasQuest("anti-antimagic"):isStatus(engine.Quest.DONE) and
+			not self:hasQuest("anti-antimagic"):isStatus(engine.Quest.COMPLETED, "grand-corruptor-treason")
+		))
+	end} },
+	on_learn = function(self, t)
+		self.max_life = self.max_life + 150
+	end,
+	info = function(self, t)
+		return ([[Thanks to your newfound knowledge of corruption, you've learned some tricks for toughening your body... but only if you are healthy enough to withstand the strain from the changes.
+		Improves your life by 150, your Defense by %d, and your saves by %d, as your natural toughness and reflexes are pushed beyond their normal limits.
+		Your saves and Defense will improve with your Constitution.]])
+		:format(self:getCon() / 3, self:getCon() / 3)
+	end,
+}
diff --git a/game/modules/tome/data/talents/uber/cun.lua b/game/modules/tome/data/talents/uber/cun.lua
index bfb768103c..1a2482d9d4 100644
--- a/game/modules/tome/data/talents/uber/cun.lua
+++ b/game/modules/tome/data/talents/uber/cun.lua
@@ -271,3 +271,29 @@ uberTalent{
 		:format()
 	end,
 }
+
+uberTalent{
+	name = "Tricks of the Trade",
+	mode = "passive",
+	require = { special={desc="Sided with the Assassin Lord.", fct=function(self) return game.state.birth.ignore_prodigies_special_reqs or (self:isQuestStatus("lost-merchant", engine.Quest.COMPLETED, "evil")) end} },
+	on_learn = function(self, t) 
+		if self:knowTalentType("cunning/stealth") then
+			self:setTalentTypeMastery("cunning/stealth", self:getTalentTypeMastery("cunning/stealth") + 0.2)
+		elseif self:knowTalentType("cunning/stealth") == false then
+			self:learnTalentType("cunning/stealth", true)
+		end
+		if self:knowTalentType("cunning/scoundrel") then
+			self:setTalentTypeMastery("cunning/scoundrel", self:getTalentTypeMastery("cunning/scoundrel") + 0.1)
+		else
+			self:learnTalentType("cunning/scoundrel", true)
+			self:setTalentTypeMastery("cunning/scoundrel", 0.9)
+		end
+		self.invisible_damage_penalty_divisor = (self.invisible_damage_penalty_divisor or 0) + 2
+	end,
+	info = function(self, t)
+		return ([[You have friends in low places, and have learned some underhanded tricks.
+		Gain 0.2 Category Mastery to the Cunning/Stealth Category (or unlock it, if locked), and either gain +0.1 to the Cunning/Scoundrel category or learn and unlock the category at 0.9, if you lack it.
+		Additionally, all of your damage penalties from invisibility are permanently halved.]]):
+		format()
+	end,
+}
diff --git a/game/modules/tome/data/talents/uber/dex.lua b/game/modules/tome/data/talents/uber/dex.lua
index 34b2fe981a..8b6f1f9041 100644
--- a/game/modules/tome/data/talents/uber/dex.lua
+++ b/game/modules/tome/data/talents/uber/dex.lua
@@ -195,3 +195,31 @@ uberTalent{
 		:format()
 	end,
 }
+
+uberTalent{
+	name = "Vital Shot",
+	no_energy = "fake",
+	cooldown = 20,
+	range = archery_range,
+	require = { special={desc="Dealt over 50000 damage with ranged weapons.", fct=function(self) return self.damage_log and self.damage_log.weapon.archery and self.damage_log.weapon.archery >= 50000 end} },
+	tactical = { ATTACK = { weapon = 3 }, DISABLE = 3 },
+	requires_target = true,
+	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	archery_onhit = function(self, t, target, x, y)
+		if target:canBe("stun") then
+			target:setEffect(target.EFF_STUNNED, 5, {apply_power=self:combatAttack()})
+		end
+		target:setEffect(target.EFF_CRIPPLE, 5, {speed=0.50, apply_power=self:combatAttack()})
+	end,
+	action = function(self, t)
+		local targets = self:archeryAcquireTargets(nil, {one_shot=true})
+		if not targets then return end
+		self:archeryShoot(targets, t, nil, {mult=4.5})
+		return true
+	end,
+	info = function(self, t)
+		return ([[You fire a shot straight at your enemy's vital areas, wounding them terribly.
+		Enemies hit by this shot will take 450%% weapon damage, and will be stunned and crippled (Losing 50%% physical, magical and mental attack speeds) for five turns, due to the incredibly disabling impact of the shot.
+		The stun and cripple chances increase with your Accuracy.]]):format()
+	end,
+}
diff --git a/game/modules/tome/data/talents/uber/mag.lua b/game/modules/tome/data/talents/uber/mag.lua
index 22f9aac946..1c73aa965e 100644
--- a/game/modules/tome/data/talents/uber/mag.lua
+++ b/game/modules/tome/data/talents/uber/mag.lua
@@ -157,7 +157,7 @@ uberTalent{
 
 uberTalent{
 	name = "Revisionist History",
-	cooldown = 40,
+	cooldown = 30,
 	no_energy = true,
 	is_spell = true,
 	no_npc_use = true,
@@ -184,3 +184,24 @@ uberTalent{
 		:format()
 	end,
 }
+
+uberTalent{
+	name = "Cauterize",
+	mode = "passive",
+	cooldown = 12,
+	require = { special={desc="Received at least 50000 fire damage and have cast at least 1000 spells.", fct=function(self) return
+		self.talent_kind_log and self.talent_kind_log.spell and self.talent_kind_log.spell >= 1000 and self.damage_intake_log and self.damage_intake_log[DamageType.FIRE] and self.damage_intake_log[DamageType.FIRE] >= 50000
+	end} },
+	trigger = function(self, t, value)
+		self:startTalentCooldown(t)
+
+		self:setEffect(self.EFF_CAUTERIZE, 8, {dam=value/10})
+		return true
+	end,
+	info = function(self, t)
+		return ([[Your inner flame is strong, each time you receive a blow that would kill you your body is wreathed in flames.
+		The flames will cauterize the wound, fully absorbing all damage done this turn but they will continue to burn for 8 turns.
+		Each turn 10% of the damage absorbed will be dealt by the flames (this will bypass resistance and affinity).
+		Warning, this has a cooldown.]])
+	end,
+}
diff --git a/game/modules/tome/data/talents/uber/str.lua b/game/modules/tome/data/talents/uber/str.lua
index 31e981370c..eb6c88620c 100644
--- a/game/modules/tome/data/talents/uber/str.lua
+++ b/game/modules/tome/data/talents/uber/str.lua
@@ -177,3 +177,14 @@ uberTalent{
 		:format()
 	end,
 }
+
+uberTalent{
+	name = "Superpower",
+	mode = "passive",
+	info = function(self, t)
+		return ([[A strong body is key to a strong mind. And a strong mind is powerful enough to make a strong body.
+		Grants a Mindpower bonus equal to 25%% of your Strength.
+		Additionally, you treat all weapons as having an additional 30%% Willpower modifier.]])
+		:format()
+	end,
+}
diff --git a/game/modules/tome/data/talents/uber/wil.lua b/game/modules/tome/data/talents/uber/wil.lua
index 6b569b70d1..b482c84ce5 100644
--- a/game/modules/tome/data/talents/uber/wil.lua
+++ b/game/modules/tome/data/talents/uber/wil.lua
@@ -214,3 +214,38 @@ uberTalent{
 		:format(damDesc(self, DamageType.MIND, 20 + self:getWil() * 2))
 	end,
 }
+
+uberTalent{
+	name = "Mental Tyranny",
+	mode = "sustained",
+	require = { },
+	cooldown = 20,
+	tactical = { BUFF = 2 },
+	require = { special={desc="Dealt over 50000 mind damage", fct=function(self) return 
+		self.damage_log and (
+			(self.damage_log[DamageType.MIND] and self.damage_log[DamageType.MIND] >= 50000)
+		)
+	end} },
+	activate = function(self, t)
+		game:playSoundNear(self, "talents/distortion")
+		return {
+			converttype = self:addTemporaryValue("all_damage_convert", DamageType.MIND),
+			convertamount = self:addTemporaryValue("all_damage_convert_percent", 100),
+			dam = self:addTemporaryValue("inc_damage", {[DamageType.MIND] = 10}),
+			resist = self:addTemporaryValue("resists_pen", {[DamageType.MIND] = 30}),
+		}
+	end,
+	deactivate = function(self, t, p)
+		self:removeTemporaryValue("all_damage_convert", p.converttype)
+		self:removeTemporaryValue("all_damage_convert_percent", p.convertamount)
+		self:removeTemporaryValue("inc_damage", p.dam)
+		self:removeTemporaryValue("resists_pen", p.resist)
+		return true
+	end,
+	info = function(self, t)
+		return ([[Transcend the physical and rule over all with an iron will.
+		While this sustain is active, all of your damage is converted into mind damage.
+		Additionally, you gain +30%% mind resistance penetration, and +10%% mind damage.]]):
+		format()
+	end,
+}
diff --git a/game/modules/tome/data/timed_effects/other.lua b/game/modules/tome/data/timed_effects/other.lua
index 70767a48bf..792cd165a7 100644
--- a/game/modules/tome/data/timed_effects/other.lua
+++ b/game/modules/tome/data/timed_effects/other.lua
@@ -2120,3 +2120,39 @@ newEffect{
 	deactivate = function(self, eff)
 	end,
 }
+
+newEffect{
+	name = "CAUTERIZE", image = "talents/cauterize.png",
+	desc = "Cauterize",
+	long_desc = function(self, eff) return ("Your body is cauterizing, burns for %0.2f damage each turn."):format(eff.dam) end,
+	type = "other",
+	subtype = { fire=true },
+	status = "detrimental",
+	parameters = { dam=10 },
+	on_gain = function(self, err) return "#CRIMSON##Target# is wreathed in flames on the brink of death!", "+Cauterize" end,
+	on_lose = function(self, err) return "#CRIMSON#The flames around #target# vanishes.", "-Cauterize" end,
+	on_merge = function(self, old_eff, new_eff)
+		old_eff.dur = new_eff.dur
+		old_eff.dam = old_eff.dam + new_eff.dam
+		return old_eff
+	end,
+	activate = function(self, eff)
+		self.life = self.old_life or 10
+		eff.invulnerable = true
+		eff.particle1 = self:addParticles(Particles.new("inferno", 1))
+		eff.particle2 = self:addParticles(Particles.new("inferno", 1))
+	end,
+	deactivate = function(self, eff)
+		self:removeParticles(eff.particle1)
+		self:removeParticles(eff.particle2)
+	end,
+	on_timeout = function(self, eff)
+		if eff.invulnerable then
+			eff.invulnerable = nil
+		end
+		local dead, val = self:takeHit(eff.dam, self, {special_death_msg="burnt to death by cauterize"})
+
+		local srcname = self.x and self.y and game.level.map.seens(self.x, self.y) and self.name:capitalize() or "Something"
+		game:delayedLogDamage(self, self, val, ("%s%d %s#LAST#"):format(DamageType:get(DamageType.FIRE).text_color or "#aaaaaa#", math.ceil(val), DamageType:get(DamageType.FIRE).name), false)
+	end,
+}
-- 
GitLab