From 66afabb41d3d28091ec35d5cc35b8c2fdc8cba9f Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Tue, 8 Nov 2011 08:48:11 +0000
Subject: [PATCH] Doomed class updated to be a fully mind based class, using
 mindpower to power its talents. Doomed lost the Primal Magic tree and gained
 the Gestures tree

git-svn-id: http://svn.net-core.org/repos/t-engine4@4623 51575b47-30f0-44d4-a5cc-537603b46e54
---
 .../engine/interface/PlayerHotkeys.lua        |   2 +-
 game/modules/tome/class/Actor.lua             |   5 -
 game/modules/tome/class/interface/Combat.lua  |  65 +++++--
 .../tome/data/birth/classes/afflicted.lua     |  14 +-
 game/modules/tome/data/damage_types.lua       |  20 +-
 .../data/gfx/talents/gesture_of_command.png   | Bin 0 -> 2890 bytes
 .../data/gfx/talents/gesture_of_guarding.png  | Bin 0 -> 4016 bytes
 .../tome/data/gfx/talents/gesture_of_pain.png | Bin 0 -> 4046 bytes
 .../data/gfx/talents/gesture_of_power.png     | Bin 0 -> 3471 bytes
 .../tome/data/gfx/talents/willful_strike.png  | Bin 3975 -> 3918 bytes
 .../tome/data/talents/cursed/cursed-aura.lua  |   4 +
 .../tome/data/talents/cursed/cursed-form.lua  |   2 +-
 .../tome/data/talents/cursed/cursed.lua       |  24 +--
 .../data/talents/cursed/dark-sustenance.lua   |  24 +--
 .../tome/data/talents/cursed/darkness.lua     |  29 ++-
 .../tome/data/talents/cursed/doomed.lua       |  76 --------
 .../data/talents/cursed/force-of-will.lua     |  22 +--
 .../tome/data/talents/cursed/gestures.lua     | 173 ++++++++++++++++++
 .../tome/data/talents/cursed/gloom.lua        |   4 +-
 .../tome/data/talents/cursed/punishments.lua  |  72 +++-----
 .../tome/data/talents/cursed/shadows.lua      |  10 +-
 .../data/talents/gifts/summon-distance.lua    |   2 +-
 .../tome/data/timed_effects/mental.lua        |   2 +-
 .../tome/data/zones/dreadfell/npcs.lua        |   2 +-
 .../tome/data/zones/dreadfell/zone.lua        |   1 +
 game/modules/tome/dialogs/Birther.lua         |   4 +-
 26 files changed, 326 insertions(+), 231 deletions(-)
 create mode 100644 game/modules/tome/data/gfx/talents/gesture_of_command.png
 create mode 100644 game/modules/tome/data/gfx/talents/gesture_of_guarding.png
 create mode 100644 game/modules/tome/data/gfx/talents/gesture_of_pain.png
 create mode 100644 game/modules/tome/data/gfx/talents/gesture_of_power.png
 create mode 100644 game/modules/tome/data/talents/cursed/gestures.lua

diff --git a/game/engines/default/engine/interface/PlayerHotkeys.lua b/game/engines/default/engine/interface/PlayerHotkeys.lua
index c8d684df02..d0550cbe7b 100644
--- a/game/engines/default/engine/interface/PlayerHotkeys.lua
+++ b/game/engines/default/engine/interface/PlayerHotkeys.lua
@@ -236,7 +236,7 @@ function _M:updateQuickHotkeys(actor)
 				elseif hotkey[1] == "inventory" then
 					local item = actor:findInAllInventories(hotkey[2])
 
-					if item.save_hotkey then save_quickhotkey = true end
+					if item and item.save_hotkey then save_quickhotkey = true end
 				end
 
 				if save_quickhotkey then self:updateQuickHotkey(actor, position) end
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index ca4f1227ab..ec5f6f2a84 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -377,11 +377,6 @@ function _M:actBase()
 			local t = self:getTalentFromId(self.T_UNSEEN_FORCE)
 			t.do_unseenForce(self, t)
 		end
-		-- this handles doomed arcane bolts turn based effects
-		if self.arcaneBolts then
-			local t = self:getTalentFromId(self.T_ARCANE_BOLTS)
-			t.do_arcaneBolts(self, t)
-		end
 		-- Curse of Nightmares: Nightmare
 		if not self.dead and self:hasEffect(self.EFF_CURSE_OF_NIGHTMARES) then
 			local eff = self:hasEffect(self.EFF_CURSE_OF_NIGHTMARES)
diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
index 47a38f7ee7..6f74a83ea0 100644
--- a/game/modules/tome/class/interface/Combat.lua
+++ b/game/modules/tome/class/interface/Combat.lua
@@ -105,7 +105,14 @@ function _M:attackTarget(target, damtype, mult, noenergy)
 	end
 
 	local break_stealth = false
-	if not self:attr("disarmed") and not self:isUnarmed() then
+	if self:isTalentActive(self.T_GESTURE_OF_PAIN) then
+		print("[ATTACK] attacking with Gesture of Pain")
+		local t = self:getTalentFromId(self.T_GESTURE_OF_PAIN)
+		speed, hit = t.attack(self, t, target)
+		break_stealth = true
+	end
+
+	if not speed and not self:attr("disarmed") and not self:isUnarmed() then
 		-- All weapons in main hands
 		if self:getInven(self.INVEN_MAINHAND) then
 			for i, o in ipairs(self:getInven(self.INVEN_MAINHAND)) do
@@ -670,10 +677,6 @@ function _M:combatArmor()
 	if self:knowTalent(self.T_CARBON_SPIKES) and self:isTalentActive(self.T_CARBON_SPIKES) then
 		add = add + self.carbon_armor
 	end
-	if self:knowTalent(self.T_PRIMAL_SKIN) then
-		local t = self:getTalentFromId(self.T_PRIMAL_SKIN)
-		add = add + t.getArmor(self, t)
-	end
 	return self.combat_armor + add
 end
 
@@ -914,16 +917,22 @@ function _M:combatSpellCrit()
 	return self.combat_spellcrit + (self:getCun() - 10) * 0.3 + (self:getLck() - 50) * 0.30 + 1
 end
 
+--- Gets mindcrit
+function _M:combatMindCrit()
+	local add = 0
+	if self:knowTalent(self.T_GESTURE_OF_POWER) then
+		local t = self:getTalentFromId(self.T_GESTURE_OF_POWER)
+		add = t.getMindCritChange(self, t)
+	end
+
+	return self.combat_mindcrit + (self:getCun() - 10) * 0.3 + (self:getLck() - 50) * 0.30 + 1 + add
+end
+
 --- Gets spellspeed
 function _M:combatSpellSpeed()
 	return 1 / self.combat_spellspeed
 end
 
---- Gets mindcrit
-function _M:combatMindCrit()
-	return self.combat_mindcrit + (self:getCun() - 10) * 0.3 + (self:getLck() - 50) * 0.30 + 1
-end
-
 --- Gets summon speed
 function _M:combatSummonSpeed()
 	return math.max(1 - ((self:attr("fast_summons") or 0) / 100), 0.1)
@@ -1004,15 +1013,6 @@ function _M:spellCrit(dam, add_chance)
 	return dam, crit
 end
 
---- Do we get hit by our own AOE ?
-function _M:spellFriendlyFire()
-	local chance = (self:getLck() - 50) * 0.2
-	if self:isTalentActive(self.T_SPELLCRAFT) then chance = chance + self:getTalentLevelRaw(self.T_SPELLCRAFT) * 20 end
-	chance = 100 - chance
-	print("[SPELL] friendly fire chance", chance)
-	return chance
-end
-
 --- Computes mind crit for a damage
 function _M:mindCrit(dam, add_chance)
 	if self:isTalentActive(self.T_STEALTH) and self:knowTalent(self.T_SHADOWSTRIKE) then
@@ -1026,15 +1026,30 @@ function _M:mindCrit(dam, add_chance)
 	if rng.percent(chance) then
 		dam = dam * (1.5 + (self.combat_critical_power or 0) / 100)
 		crit = true
-		game.logSeen(self, "#{bold}#%s's power attains critical effect!#{normal}#", self.name:capitalize())
+		game.logSeen(self, "#{bold}#%s's mind surges with critical power!#{normal}#", self.name:capitalize())
 	end
 	return dam, crit
 end
 
+--- Do we get hit by our own AOE ?
+function _M:spellFriendlyFire()
+	local chance = (self:getLck() - 50) * 0.2
+	if self:isTalentActive(self.T_SPELLCRAFT) then chance = chance + self:getTalentLevelRaw(self.T_SPELLCRAFT) * 20 end
+	chance = 100 - chance
+	print("[SPELL] friendly fire chance", chance)
+	return chance
+end
+
 --- Gets mindpower
 function _M:combatMindpower(mod)
 	mod = mod or 1
 	local add = 0
+
+	if self:knowTalent(self.T_GESTURE_OF_COMMAND) then
+		local t = self:getTalentFromId(self.T_GESTURE_OF_COMMAND)
+		add = t.getMindpowerChange(self, t)
+	end
+
 	return self:rescaleCombatStats((self.combat_mindpower > 0 and self.combat_mindpower or 0) + add + self:getWil() * 0.7 + self:getCun() * 0.4) * mod
 end
 
@@ -1256,6 +1271,16 @@ function _M:isUnarmed()
 	return unarmed
 end
 
+-- Get the number of free hands the actor has
+function _M:getFreeHands()
+	if not self:getInven("MAINHAND") or not self:getInven("OFFHAND") then return end
+	local weapon = self:getInven("MAINHAND")[1]
+	local offweapon = self:getInven("OFFHAND")[1]
+	if weapon and offweapon then return 0 end
+	if weapon or offweapon then return 1 end
+	return 2
+end
+
 --- Check if the actor dual wields
 function _M:hasDualWeapon()
 	if self:attr("disarmed") then
diff --git a/game/modules/tome/data/birth/classes/afflicted.lua b/game/modules/tome/data/birth/classes/afflicted.lua
index 10596973fe..930ef89386 100644
--- a/game/modules/tome/data/birth/classes/afflicted.lua
+++ b/game/modules/tome/data/birth/classes/afflicted.lua
@@ -94,23 +94,23 @@ newBirthDescriptor{
 	locked_desc = "In shaded places in unknown lands thou must overcome thyself and see thy doom.",
 	desc = {
 		"The Doomed are fallen mages who once wielded powerful magic wrought by ambition and dark bargains.",
-		"They now possess only a twisted shadow of that power as they struggle to keep it from consuming them.",
+		"Stripped of their magic by the dark forces that once served them, they have learned to harness the hatred that burns in their minds.",
 		"Only time will tell if they can choose a new path or are doomed forever.",
 		"The Doomed strike from behind a veil of darkness or a host of shadows.",
-		"They feed upon their enemies as they unleash powerful forces and terrible punishments.",
-		"Their most important stats are: Magic and Willpower",
+		"They feed upon their enemies as they unleash their minds on all who confront them.",
+		"Their most important stats are: Willpower and Cunning",
 		"#GOLD#Stat modifiers:",
 		"#LIGHT_BLUE# * +0 Strength, +0 Dexterity, +0 Constitution",
-		"#LIGHT_BLUE# * +4 Magic, +4 Willpower, +0 Cunning",
+		"#LIGHT_BLUE# * +0 Magic, +4 Willpower, +5 Cunning",
 	},
-	stats = { wil=4, mag=4, },
+	stats = { wil=4, cun=4, },
 	talents_types = {
 		["cursed/dark-sustenance"]={true, 0.3},
 		["cursed/force-of-will"]={true, 0.3},
+		["cursed/gestures"]={true, 0.3},
 		["cursed/punishments"]={true, 0.3},
 		["cursed/shadows"]={true, 0.3},
 		["cursed/darkness"]={true, 0.3},
-		["cursed/primal-magic"]={true, 0.3},
 		["cursed/cursed-form"]={true, 0.0},
 		["cunning/survival"]={false, 0.0},
 		["cursed/dark-figure"]={false, 0.0},
@@ -118,13 +118,13 @@ newBirthDescriptor{
 	talents = {
 		[ActorTalents.T_UNNATURAL_BODY] = 1,
 		[ActorTalents.T_FEED] = 1,
+		[ActorTalents.T_GESTURE_OF_PAIN] = 1,
 		[ActorTalents.T_WILLFUL_STRIKE] = 1,
 		[ActorTalents.T_CALL_SHADOWS] = 1,
 	},
 	copy = {
 		max_life = 90,
 		resolvers.equip{ id=true,
-			{type="weapon", subtype="staff", name="elm staff", autoreq=true, ego_chance=-1000},
 			{type="armor", subtype="cloth", name="linen robe", autoreq=true, ego_chance=-1000},
 		},
 		chooseCursedAuraTree = true
diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua
index 9655ef0a9c..f369e3111b 100644
--- a/game/modules/tome/data/damage_types.lua
+++ b/game/modules/tome/data/damage_types.lua
@@ -64,6 +64,11 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
 			dam = dam + dam * target:attr("inc_necrotic_minions") / 100
 			print("[PROJECTOR] after necrotic increase dam", dam)
 		end
+		
+		if target.isTalentActive and target:isTalentActive(target.T_GESTURE_OF_GUARDING) then
+			local t = target:getTalentFromId(target.T_GESTURE_OF_GUARDING)
+			dam = t.on_damageInflicted(target, t, type, dam, src)
+		end
 
 		-- Blast the iceblock
 		if src.attr and src:attr("encased_in_ice") then
@@ -179,6 +184,11 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
 			local t = target:getTalentFromId(target.T_ENERGY_DECOMPOSITION)
 			dam = t.on_damage(target, t, type, dam)
 		end
+		
+		if target.isTalentActive and target:isTalentActive(target.T_GESTURE_OF_GUARDING) then
+			local t = target:getTalentFromId(target.T_GESTURE_OF_GUARDING)
+			dam = t.on_damageReceived(target, t, type, dam, src)
+		end
 
 		if src:attr("stunned") then
 			dam = dam * 0.3
@@ -396,8 +406,14 @@ newDamageType{
 		local target = game.level.map(x, y, Map.ACTOR)
 		if target then
 			local mindpower, mentalresist
-			if _G.type(dam) == "table" then dam, mindpower, mentalresist, factor = dam.dam, dam.mindpower, dam.mentalresist end
-			if target:checkHit(mindpower or src:combatMindpower(), mentalresist or target:combatMentalResist(), 0, 95, 15) then
+			if _G.type(dam) == "table" then dam, mindpower, mentalresist, factor, alwaysHit, criticals, crossTierChance = dam.dam, dam.mindpower, dam.mentalresist, dam.alwaysHit, dam.criticals, dam.crossTierChance end
+			if alwaysHit or target:checkHit(mindpower or src:combatMindpower(), mentalresist or target:combatMentalResist(), 0, 95, 15) then
+				if criticals then
+					dam = src:mindCrit(dam)
+				end
+				if crossTierChance and rng.change(crossTierChance) then
+					target:crossTierEffect(target.EFF_BRAINLOCKED, src:combatMindpower())
+				end
 				return DamageType.defaultProjector(src, x, y, type, dam)
 			else
 				game.logSeen(target, "%s resists the mind attack!", target.name:capitalize())
diff --git a/game/modules/tome/data/gfx/talents/gesture_of_command.png b/game/modules/tome/data/gfx/talents/gesture_of_command.png
new file mode 100644
index 0000000000000000000000000000000000000000..a7f5161c28724f86c7c7c4cea620f1e50b58ac17
GIT binary patch
literal 2890
zcmWkw2{=@38$OgJ4JON&B1?_<G*nFXb*!W8Ohaa}PS%JaM2j_qFMerE2ub)Xlg1JT
zB@<&TO}<G&ikXls!>2<2({--*yw`cIb3Nz1@8`as=VUrN+KP)E5d#1~9AjtY3hw5A
zmZ&gzuMNIB4Q>L_uC{2PVOU`Sd=U0KXKMxQ{ka}>RTqGf1Ce%~(ExBz`p*&oiXXzk
zpa==$U@bCvPy}{R^6a2{A^?aDVyrCO<321?m=W^h+x=$#c_wm~{24Lc&NWg-j-r}k
zvS=Zd7UWm4K4I9ZUX$Ne!7Z~}LdqT$?oXvC_Gwa9s(n@NvdFjYX;4NVf|Yin!Jo0!
z!P~(qs<K$&%TF$SIL;z|Hdr&}m-3QId3ROKS4AZc=KY9+^!NjcYbrDGXb%q(-ZuZS
zCQm*`xXLvXTemqQY|e=h78Y*8wZLra#*Y;-sdTzy7h!KjP#Gfy%ND8|e-TrUL;l#k
z@h#Sfd_LWeddC;OX9C2^=Oa`wQde5#tzF*CM+G!{){ZY$3iJ?_-927kY5fwZ4@T#r
z436aVgHf*PY^1)khinnk+O(|NUBji3vsZmTJ<&|=Tz)E&+2*aKAR#gyQs`P^RpVaa
zS~D7^d&uu*RXELyIuRx!So$#sgTTBDp;asyzGz@`IJWiJO4l0ay78x+B@~6FsmGxQ
zTf2;+#KFS^Xg_8z<eFc93cQExzr`Y2-VX$mr~5w0fC{RlVxD5_WV2uU5qN8Hiuz@5
zx{BM9+>B`NO45Dd?iz(6TF<{9036tnh9#5l{JIF$&g!EfG$?vB2&E3o{`w-fLVeOy
z@<ADs#|OW%CoU1$?rpr*Cp}pj);xhI82J1Ai5hGj>WKKi9FB`eq0i|%Q&(*B5vfpk
zy6@l;y4;+KGlr5iXCxPvAH!05m9r`$xBm+VvGMqSh}S0fEyo^DeMD$<1F>Q2-i6Ti
zg;Vfq7MT36OG}n)ls5UU=dT*~tVGiYso9i(Um}jl`H1r1BjwJbt&=&7FBWVROioV8
z@VM$qUqAk!JQDWMQLXsN>}JA&{elRo1KMN=i^wkrdc<~SN}NV!BbAx!x&MfNA{nm5
z8BZelSH^v)IIvLNGfwI<FXy9tX<orJucLL=)-J0FU6cDgI42)r>s*kqF;x8$6Ma9h
zlW>aASX5rF@@xVL$|Fqo92JL}Z}x@bkgzaa`4<geHWL<BRv62%I(mAHp`r5}!~WcJ
z%4H*zmTRpVUr7q4i4S^vdo_<*iuU&R3ujs--@YwS%;Mg+6!jHT@0iL(GP#?Z2_<Q1
zLRqi<R_vO*wF*XfV8-qUAU!=@KW0%Tt0HV$$<58po1RFf(awI0-KIyMr8vA@K+(MF
zTk+<i7Uj-8%dwTUi@W#kj%R@t<hsbDT_D5@HFB6~2jy^HUTF67qXK%6l&JQhw{NAW
zxPR&hz8qbgR?%OuY`mv%$JJyO(LXU!p=^X9X|`j2?B40hmKH0mLVH9328+eE#Vlbt
z((3W2qVt*apma?3mE%=XQc^nk!$#+wocNOw-B&jkJ%0b>DMhs_kk3D<mbiLRzB8IN
z@a*oB;EP_<Q_p)VZS%AZ4YQCd_3Z(kL?549b_n!o_+uRM*|TS8jl#vn;_j0`DilR=
zKsijJUAq9E=41s0g}M2nOWe7E0*Hh}MXd(SD<`VGGh#b*J1+=j-|jsv*O}DqLGw~A
z81QMG1ifUJAMjy{Ks<1zl_E!oyUi=RS=u^tgA!*vtaNjy_uDsQc6Rn-*T3wm@;$4x
zin3p2NJ{6}99B|NlgeBLzqCGaxomkr{%HK|MAN+5TH?hpTRgUocKKt|M2rLk0)+_2
zuf3K79q>P9pw6{0nip3)rrjH~O>M1ReqW7Sbz9`DpkBmury1Z?4_hD|p|H{!U&>u;
z{$|d{hF|Owd_`;~$6KitUjNcBu1y}AzEQ<K<=n`@RI|B;L&Rp#4<f|SG$>L_E9(14
zgWtcF8u7d4%@YBEfoaW`N1}dh1h4;0-1-(-<9@8ro@_zXrKrLorhjXkhNKi0%9`$O
zxHWjUzuaEwcG6d{$wxq5J#yEec6JV}bngvUoh$kQVzjGrof_FEmL`~wI0O-%c>lg<
zX)|_8f0<bC^iaRIV};ICD@%MSqLkPZ+Sp}NIpz}_oC)%`v4M(?j@~xi+!h2Cr&Xk5
zeRqVXgQ?~yJgU`*=-Pw<Aj4;hwD1*#Mhc@#zt1G5hfs;F8w)};O)kfEP2>3~9b*C|
z5DyQ78$0?h8gvW{1{N1X7-aMXfuIy;bs6xrABps%{5@y&zW47R41Ai(9~ldh$#`X9
zta#bqzf#Y>iT&MKqi}V5*QiA;`!!l$p?^8{S~%G*Kea;Ls?x<+QIgGO2Q*Kl2mp^<
zYm`%!p`s5$s3xFw!CFV^f4oQfo|^JuGBmcM#GjE1wv|7K{@W=P7;PEJsu-P_iI{%s
z3r8Z6(CpW73sps{amHI7LTFL!g$wOT+b!gigU^OmS5Hf1q~MUToWjwwKr!n{aM=pV
zo{GCmr<?XO7)Bq|J|3K_yU@7Kb}}npGVJvkg?Q&FndLI)kHNC1WYtLGw{(@<HDrwy
z^V+XHt<?aN1!xa6kC<l9taNX!qVJ!9q|DC;eqPfD&up&j!_C-2-^B|7k8nuWdhA+4
z7k4QZoDo4NXOBWEm3p0<+%g{1F|`BMd}wIsLE&ibw2h6;_bhmag!x6ye?!hj+df@h
zJdz{qWU?ufl$3Nd+CrBy59*;G?0(G?O*rJn*47u2p(lYrBoc*NCmocbr`_f{RQgK+
z<<!$N%99ZEbxTq}z~f4pwy~hq-K`n^Y=)8_&Fk>t!)H3qcPwjxVqN}l78JZ~u7bt=
zzyf%QqneJ6&UGx>33&hTI0zOTPypEa1_m%TwzdWd8$q_o3_oh*?yng7?_Z%L{ACj9
z-9M@3%D1Mj@F)@V*`1$!a3WWXse|V8_xtu25I)mHrw^~MYxDVhq^9Or2u=U$=RV!5
z{~HJxii)^!XJ$oBK|;sKh}qY-ALMOz)|Zdp=fM84$+`4%jiE%QP>#bPQW6=g<?SF;
z7JDHeHa6B4njqFgEO$r399TD&{?$x0RT?qbdbn^1Bx@#V>!?!F#vxq_3vmvUKh#9J
zaicUd^8g9YTc|EOQQ{cQ9Xd?^wRjTLR%mGG5Q{a-{|Q%Aw7EZ@l(}{rXmT@iLP#0^
zoGXAxN>ZvMB0+*qoH!BLF=ch^5ZhA0kaQ;qH8?kikUK>Ph>s`pc_Y#PeVfpv-wY3D
zeT)jd@RHCMrwjmLVPQ=zEj9?L**Eu&pXiVj7e51n1Y276<g#vAz;#YSR8)T1&EI5@
z+TS~TCym0vmiB@H1W2}JhQt{Z>UkPG2G8ryk(UumOA!M8n3-hgfI6ZoBj!uRiKd~!
z^MG2DmX?k)R_yQZSC<icXml<26#Yjs$*`+Yh=9kdD(10gX1dehW%1m@t~D~?D0=Qy
z4<`G>Wl<ipgVQrISaF(AQD~-B+l^gAFcmm8v<RJV!0tOdIB3s^Rx7}8dAwF=C6YNb
zJRJ3NJ&+$Rdv!EpJVZ94b1nTraj{fA_8dH2C4^QSx6-wh+OUM?#HcXWO-9U2O|^y}
z8XN~L_<CdGc^sdmmo^>}zPI~H07zvKr5n3{zi5k^&%)tw&}yeL*lc85C_e+OvbI>)
zm{p+WBxdb0#FvsBTM-WQ<i4l+gDCx|@PUA5OYNUaI@g>9BB5W_M!1UmR^hi8fU)o=
c7sWkEJIm6nY|&y8_@fJ8tR1Zy&_2ok2Z;WBt^fc4

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/gfx/talents/gesture_of_guarding.png b/game/modules/tome/data/gfx/talents/gesture_of_guarding.png
new file mode 100644
index 0000000000000000000000000000000000000000..22c7a18d4786a7f11dfe1e03b4c2c9b2a7353125
GIT binary patch
literal 4016
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
Jv8{uW{|_XByCMJp

literal 0
HcmV?d00001

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

literal 0
HcmV?d00001

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

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/gfx/talents/willful_strike.png b/game/modules/tome/data/gfx/talents/willful_strike.png
index cdacc681c54db534b275862cbc91f1e8816a5bad..267118789caca5229d15163c77d6d0be1c22561f 100644
GIT binary patch
delta 3881
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
RL^2F4107>+yrx6c{{U6dkZS+{

delta 3936
zcmW+&c_7p8AOD!ra?TmK7eeGdHfIZosFt}^LbGy*$T5{8HyLszvI*bjD05S3#BzKs
z<c?v<6+#O8eZIf<^Y8P#-_P@Y-mjxyDnU9!gOB5u^#wCv<i90`;#<f(D~&%U!K0@_
zp{lX~fbZBvvvYRd)2q%C{w|p28#4_f;}L(Ot>^R;>1F-Iyz8aYw$|kdrihbifbj9e
z6H>ngm4*AD8y^fezUpxtHxJHG-cIp8H_WyaWA`QNEir?moJZa_Yf#&EQvXCt6Oz)f
z>%3J%ans}Rb+??As4e@N){6JVcdY;U+wL#8`FD>M9_+UM{d<7Eg!sYv;8X3|CsWs^
zTJ%JcF%AycH)9J63#sft$I57vE4jbFKR%u#mv$6D_r}G=O*Hs-Gd5<BK$jyHi;aqk
zQWrJ**xL})G`Tv_@b}N3B<h?$Kj7i>cW1S}z8-_Y6mEr7D~Tlc;63X)I`Ho9vwBBN
zN4H<QG{kq#UQsN=jd!Z$pur-%yu1nmi8E%fmZ>%D^KepA(-?E>>YwlHY(Oqen45#`
zW@zZn=rLHTg^P=ebj5F-ZguYB0jy}(moHzcxnERNR8S}s&Fe%0@KZmHx&1(rx4X#T
zezX@?Z0Bs<M-mQiYhxoj_eVE#H%^>6$=pInq<L!Y-G#g&lkI^r0)xT05xqww;jUNT
zm*lRoUE6%n7Vo~F9D0)vAHnP|ig&+s>5^R5MJ2BVmnV)(>bB)tFeo=SHw@+M>})7C
z!1(xhba~2@Yh}E?s;$jPAo0uausNK+cp$gOQ-y|Jx5tmDWV`Q2<B>&D;^JB8X4kWw
z>dG((01-GMt_zgWmktjPeRNx70gB&LvlmT-3MJ6uQ6<gINHB+Oxhl=7oSvd#L)W%p
z2Y`T<sgf(+I2_K$M<uH#to3@s#7kU?X0IYqXjmF;#lJq?_iKBbh^|P0GJ}x~{xedE
zcr&S>u|Gg%Wo78v<kHsOS_=U!f6L9SsGD(-h)y(vXItU&Z;Ns;B>-1H2b&NcVz7^o
zPh{leYUon)thz+uy)IEA0qv|JQjV^8{``4fp4fJU74wU>st{*=LqkJ-z3&7?^<-*1
zO17MiKp^%Svqky&B#}a?7Sc}zZRq&If&y!WteL3YB0?RJNUSHy3nT`(U5If#Yl1-h
zJ26o(z?|~ioo<VG{QgDh$e2%PSXh|1w<Wap{`&OJPN<Su`xQlz<fkysclr!hj}%!r
z><VOYYcDf1v%S5&8&ZQEc&_R~F|>{AT?neMyW{Pxm~ExewX;6cfuoads^dQ?3ZqH%
zyaGLc*QOw<cAt*)uf0gt#^k+i9-d}*m{J@JWx4I+l=HyLDW@h@juKcmwvsBYM|N%6
zgaQvuUsP3{5#=_%%`JONw*{#a!YuG_@45ZPxOjaGTbybkE@68D;z*s_|FFNm|Ka=h
z?^7-J*<O%H3LvI1nD9wIJjC<~;Sp4+jBsXbrD$G`>D)-Mhgv&w#(6oR4(t`O5ctDL
zWKpzeOnGrMQY6{P_S{hj;i{RH66772a(j7{vC&AVd-;;_?jieZz%vbw7{II|3%Htj
z)1XZbWu;_Z>v)NXW)2ifi-{#tZ?X3FxAMs@l%F{@X0_h@a6G0SaevL#>+|G^k9~c8
z=}U&tclsVF8oi>}6s_t}@l;(uziC4wBO_zu=+*K1E^j-2pWas_Tr(Nh+>f|W241C%
zfKIAvn*90m=MudfM1SY(PiekG4H#6t3wG|IgOY8}N-$E)Bik_P^+n@&cRPzax&<Lk
zt|_%Te&?0&s#sx?<|%WxQ5R=t$T`+AX^9(dZo@q1=^<tx(Q^p`#0;xq@Pn4Lu>F&*
z;aT?%H)(1O6biD)R+ex~HU<CyYj^cza~t}PA3x&b<3Ywj0z*r0ars_;g|_8tu8o5u
zBlZ}KF!YF>J1RD!R7)ODJ?E_6H#|ISDK|8TAAAwW`$EWR$4cIWKPUT=LOSbUJ?|2U
zOkNvyxbd1ywg9Z5vaxX@j#j^{^m1=s<#_yF(jb(eH53Kh#$vbjS~VXLg1r6<Vn>HG
ze?fl!NpbPc*_vA{tAMV?*9QVAV5I>T^B(Hcnd;WL-MxnpbLXLs%CXSLx*#0zYcq#A
zw1v?1>8Rg7-P5~I#b%&i$g9xo5x}d<fYSTi*Z{PP%U#iU%@0w)=3Zoz@6i}<?LQy5
z)IRt1rKY4zHis;aymkR=6crhOEqMGMz{p++lC=<HdsbL@Nlu_Z*EdPmLX1g31EsA^
z|3uR2$TvEsr>1=K7p>LWg7M!6W!*;0GIFkza(QW)i9b3j^IqgR3?6&LG?!M-8>16!
zLw^hAy`uPKa8O-OFV|A8tE;R3`N0rlBRC{PM_W4<B`ePUl2F&w)Rb=g2MSz|Sk>tm
zNPhx6NjgyEJQ545Yi*7E^9x7U=94n~J(sMe*<Y4{g2EvDs@5`ayrUujJqIzhy!uGR
zz#N|07`e9z&Nb5MlX?os+`antq`?p)QBECQ3$V3?wph)))<8xVh`>p|hKbcsq+3eu
z@Z=AZ!)0kYojzc+JJ}xfSKG~lph+$*Dp|!5(3RpGvYr6}gUj1e`T?eNeN!>zak243
zFNmoeo6JYNcAvquYi&kG8)2;y@9(m`Qr`OJ$p+|q#IHd)9;g269T6eU9G{<`2a#6o
z)*`~2z;k|mX(_dv!NbE--Er7F%5bMV*60#DZ!nYdxST@SnWH9ys&Uz9+fH57F8c`h
zP+h2s13UwLTQd(Nb2VeuJ}9bur|!8>e4OZb`5c^tN0ObU&FDciYq77O!FNI-)>2M@
zot^#QU?wdkrEzNQ<%RV4PWKQU5SL`b6j?7J;WOqIJP8kDz)d}#o8LO5?Fi&~pX}pY
zK~+r~AAk2`olZzd7!CW41Sq}}i@SfN?K)JWmNGR+fvVqj{g=LfUs(Z3K}$<3A5UuA
zTP#RTO-<40M|ddPWJ8KHTKuls4Yz>wSzdlR(-M@fGp;UGl_Ijc08|#7`O8JfZR&{|
z^ILlt=u6((<3mFzB}}lDBr)1q*3gSEcJmo&`MqhtF4^t1ukSHFDIc7#D*d)S@|W?q
ze_YRUcdFZL^=6+D6cluGa|7#F<W~vYKAW4|&6t{+O83!U_bLGmMP??y{M$Px_%q>m
zn#tnLodHNm-cFoo^K5W)p>0Cv><hwG-saJkdraG2MXYnr@L1ai3nc&!SHgxIM<t<3
z)U~wEL&YQ|+X7}k6d(R-wX#F^j$I<Pv_yD&d%sk;S9mX%wy?EViLb2uFdGmRb&w`$
zAoQ>{yV|f=vy1?Nn=A5jLQKn4M3TGHrA-3oVux}^m!o#4?z2BM)h$?ET|M~O$>(5i
zA3g3JxVtu$gvu@FMu9|uehJ4U|37Fn+K<{HwR8!@=9h=;^5x8wtIl`iFzimHf>28p
z>&VTX)7@#3_%jWou^DM;X{Rov73v4h4H2!EIhIcWAhxKtYD4NyGYd8Pbrz^ko)F+{
z$I;Fo1nSC}c(v=Tjd<1}ct$k-y(p6iE$QWc_3AWa9MQgB(5^Qf=3%482UJe%=XnUz
zwWSNI#)c*MVOD`XI<LQM1@<HOe&0C!vs?`h37+dHeIY2@@#vX<F~St(d;mBhA~GG$
zEIM|YAKhE57uj$vy5tHBW$0ZLq+P|GD#R8u9w*55es#kRgXtR>IPuwV99I`<M|+ny
zg$zK=PxyBjX=rS4*_QhPU<b0LDxPF%Lg4~3yN)~%HgVCTpfix*<&xE0;x;$4P=e!$
zjwgv<5xMusxPAI%6NCF}lWHx}HEf?he-`45)2S_)OM^jTKolL3aqLZmS_1mmOv_l9
zriMldTv!P%bKd?(6X9|#l}g;5j#xiuz|sU3nM~<VuAzDk(dJexcGwXJCnxbvQe$1+
zBQNZkxYS4Q6xn0e*4A!}gs-v7;A0)%SgUODFK8#pJeqO_YFh*WfO_4*!2u(1W$0y5
zSPUF~3t4pdn~|<}tLJ`tgQ}|PRPix8t<yw84(!gR`*GP=W&Rujn)968RS)SdQ3%Y=
z4z0s@by5)Zsp48Wsk~ed^3F(E1BrCTV9b?NUm@}cLP`rM@O)B5O+^a6Oo}$SxVb>9
z%pd0^{UcZ6(-mpV0=<LpVE(pL43$cKgB>_rk=c6C_LKm9Ayijd>e}`o1T;aNY_BX8
zJN$foQ!QTRlb7@T(t|}Au8hLKepm%AzgLrl18tDWzWbS4W(=Bh;lZ7oiUUOkyWfHX
z&jWVPLG2qE=|V8^#2++-1E6i=QHXP8wAy7L7_M1p0j0Q%&}UGb6Losp8rxqu*670X
z^*p6iJ~!h-w8B$M9eYJ*Dv?SAaRz=we0HX#=S(}kicBscDEC!+zUemk{cXM{i#5l|
zz(NK?+&D|;70d)KCfNsu1nLy@fsVe)p;{rU=kHy-bU5o^cXxe;m21KpTi;DjOOrAP
z^$7^b@cHQ^9n(1*(Bz8dL_Ns}3debcdm-~K@p5x}YUTxfp@7zM{A~q^6c5|%<THu<
zyV`K#tg9sv4U*Z7sBO%`%D0Q`PpG#*YJpW4hQkpXOL%<cIBjup5j0_X{?iiNM_RAr
zt7p}<$$|ZB0fD&LYJXNp@P9!ttmusPK~P1nA!04(LL&0>^LJLpu3ft($Qd_zR&TVC
z6lhh!=|~eO^iULiu>86qP0Fa5|2}d5t)!E2adlM{J;ZHTC4oLRJ$+p~G0afPjh>Ms
zc6skTN%(B;-N?xO?j0v_YkB2?N&MvGuV2A9ZP}HBmht_scLkMVi3&YCx}WM)XsC~!
z34B?n!@i&2xshpUHX0l;?|{~U#QY$CyIyq#k*dl4vY}zO$LwdivuOwvyj@OBuHjC<
z71Wy3ec8pa67FbDQ&#4BM#4FbFsi@m*6_kmWVaT3@EP13M>(ybLMQ}2@n}x|?kVTW
zDgM%$w{KhPT7#Ncb;|r5#{n)bt{zWN<`w<?Wo2S8`4e0*kA&h-?&0AGsdPSWZo-A>
z%bSLCx6{K6*LMGkmtGYTaRi_;ijL-VZEQ}if`DM|S+`zKO%vSHEi*QuWa@ecYnrif
z<T0By@T{g;6Mz43ZO~$H8?@fWJ&`OeHW=z@&-~Y~qD)t4W{)Swv17xRwpc^wK02yU
k7N^r^2G$c`s81$r=#LY}YXynvp!EYTn%kO@Q8yp`5B&*;hyVZp

diff --git a/game/modules/tome/data/talents/cursed/cursed-aura.lua b/game/modules/tome/data/talents/cursed/cursed-aura.lua
index 71afb25f18..b0e267e125 100644
--- a/game/modules/tome/data/talents/cursed/cursed-aura.lua
+++ b/game/modules/tome/data/talents/cursed/cursed-aura.lua
@@ -401,7 +401,11 @@ newTalent{
 			resolvers.talents{
 				[Talents.T_WEAPON_COMBAT]={base=1, every=5, max=10},
 				[Talents.T_WEAPONS_MASTERY]={base=1, every=5, max=10},
+				[Talents.T_KNIFE_MASTERY]={base=1, every=5, max=10},
+				[Talents.T_EXOTIC_WEAPONS_MASTERY]={base=1, every=5, max=10},
+				[Talents.T_STAFF_MASTERY]={base=1, every=5, max=10},
 				[Talents.T_BOW_MASTERY]={base=1, every=5, max=10},
+				[Talents.T_SLING_MASTERY]={base=1, every=5, max=10},
 				[Talents.T_SHOOT]=1,
 			},
 
diff --git a/game/modules/tome/data/talents/cursed/cursed-form.lua b/game/modules/tome/data/talents/cursed/cursed-form.lua
index 780285ad78..bbadcff5a1 100644
--- a/game/modules/tome/data/talents/cursed/cursed-form.lua
+++ b/game/modules/tome/data/talents/cursed/cursed-form.lua
@@ -35,7 +35,7 @@ newTalent{
 		return true
 	end,
 	getHealPerKill = function(self, t)
-		return combatTalentDamage(self, t, 25, 70)
+		return combatTalentDamage(self, t, 15, 50)
 	end,
 	getMaxUnnaturalBodyHeal = function(self, t)
 		return t.getHealPerKill(self, t) * 2
diff --git a/game/modules/tome/data/talents/cursed/cursed.lua b/game/modules/tome/data/talents/cursed/cursed.lua
index 83d0298627..4f21dcccdc 100644
--- a/game/modules/tome/data/talents/cursed/cursed.lua
+++ b/game/modules/tome/data/talents/cursed/cursed.lua
@@ -30,7 +30,7 @@ newTalentType{ allow_random=true, type="cursed/force-of-will", name = "force of
 newTalentType{ allow_random=true, type="cursed/darkness", is_spell=true, name = "darkness", description = "Harness the power of darkness to envelop your foes." }
 newTalentType{ allow_random=true, type="cursed/shadows", is_spell=true, name = "shades", description = "Summon shadows from the darkness to aid you." }
 newTalentType{ allow_random=true, type="cursed/punishments", name = "punishments", description = "Your hate becomes punishment in the minds of your foes." }
-newTalentType{ allow_random=true, type="cursed/primal-magic", name = "primal magic", description = "You still control traces of power from your previous life." }
+newTalentType{ allow_random=true, type="cursed/gestures", name = "gestures", description = "Enhance the power of you mind with gestures." }
 
 -- Generic
 newTalentType{ allow_random=true, type="cursed/cursed-form", name = "cursed form", generic = true, description = "You are wracked with the dark energies of the curse." }
@@ -80,24 +80,24 @@ cursed_str_req5 = {
 	level = function(level) return 16 + (level-1)  end,
 }
 
-cursed_mag_req1 = {
-	stat = { mag=function(level) return 12 + (level-1) * 2 end },
+cursed_cun_req1 = {
+	stat = { cun=function(level) return 12 + (level-1) * 2 end },
 	level = function(level) return 0 + (level-1)  end,
 }
-cursed_mag_req2 = {
-	stat = { mag=function(level) return 20 + (level-1) * 2 end },
+cursed_cun_req2 = {
+	stat = { cun=function(level) return 20 + (level-1) * 2 end },
 	level = function(level) return 4 + (level-1)  end,
 }
-cursed_mag_req3 = {
-	stat = { mag=function(level) return 28 + (level-1) * 2 end },
+cursed_cun_req3 = {
+	stat = { cun=function(level) return 28 + (level-1) * 2 end },
 	level = function(level) return 8 + (level-1)  end,
 }
-cursed_mag_req4 = {
-	stat = { mag=function(level) return 36 + (level-1) * 2 end },
+cursed_cun_req4 = {
+	stat = { cun=function(level) return 36 + (level-1) * 2 end },
 	level = function(level) return 12 + (level-1)  end,
 }
-cursed_mag_req5 = {
-	stat = { mag=function(level) return 44 + (level-1) * 2 end },
+cursed_cun_req5 = {
+	stat = { cun=function(level) return 44 + (level-1) * 2 end },
 	level = function(level) return 16 + (level-1)  end,
 }
 
@@ -161,7 +161,7 @@ load("/data/talents/cursed/dark-sustenance.lua")
 load("/data/talents/cursed/shadows.lua")
 load("/data/talents/cursed/darkness.lua")
 load("/data/talents/cursed/punishments.lua")
-load("/data/talents/cursed/primal-magic.lua")
+load("/data/talents/cursed/gestures.lua")
 
 load("/data/talents/cursed/cursed-form.lua")
 load("/data/talents/cursed/cursed-aura.lua")
diff --git a/game/modules/tome/data/talents/cursed/dark-sustenance.lua b/game/modules/tome/data/talents/cursed/dark-sustenance.lua
index 3684520b04..351d0b47a1 100644
--- a/game/modules/tome/data/talents/cursed/dark-sustenance.lua
+++ b/game/modules/tome/data/talents/cursed/dark-sustenance.lua
@@ -17,14 +17,6 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
-local function combatTalentDamage(self, t, min, max)
-	return self:combatTalentSpellDamage(t, min, max, (self.level + self:getWil()) * 1.2)
-end
-
-local function combatPower(self, t, multiplier)
-	return (self.level + self:getWil()) * (multiplier or 1)
-end
-
 newTalent{
 	name = "Feed",
 	type = {"cursed/dark-sustenance", 1},
@@ -37,7 +29,7 @@ newTalent{
 	requires_target = function(self, t) return self:getTalentLevel(t) >= 5 end,
 	direct_hit = true,
 	getHateGain = function(self, t)
-		return math.sqrt(self:getTalentLevel(t)) * 0.2 + self:getWil(0.15, true)
+		return math.sqrt(self:getTalentLevel(t)) * 0.2 + self:combatMindpower() * 0.002
 	end,
 	action = function(self, t)
 		local range = self:getTalentRange(t)
@@ -85,7 +77,7 @@ newTalent{
 	info = function(self, t)
 		local hateGain = t.getHateGain(self, t)
 		return ([[Feed from the essence of your enemy. Draws %0.2f hate per turn from a targeted foe as long as they remain in your line of sight.
-		Improves with the Willpower stat.]]):format(hateGain)
+		Hate gain improves with your Mindpower.]]):format(hateGain)
 	end,
 }
 
@@ -101,7 +93,7 @@ newTalent{
 	direct_hit = true,
 	requires_target = true,
 	getLifeSteal = function(self, t, target)
-		return combatTalentDamage(self, t, 0, 100)
+		return self:combatTalentMindDamage(t, 0, 140)
 	end,
 	action = function(self, t)
 		local effect = self:hasEffect(self.EFF_FEED)
@@ -135,7 +127,7 @@ newTalent{
 	info = function(self, t)
 		local lifeSteal = t.getLifeSteal(self, t)
 		return ([[Devours life from the target of your feeding. %d life from the victim will be added to your own. This healing cannot be reduced. At level 5 Devour Life can be used like the Feed talent to begin feeding.
-		Improves with the Willpower stat.]]):format(lifeSteal)
+		Improves with your Mindpower.]]):format(lifeSteal)
 	end,
 }
 
@@ -174,12 +166,12 @@ newTalent{
 	require = cursed_wil_req3,
 	points = 5,
 	getDamageGain = function(self, t)
-		return math.sqrt(self:getTalentLevel(t)) * 5 + self:getWil(5, true)
+		return math.sqrt(self:getTalentLevel(t)) * 5 + self:combatMindpower() * 0.05
 	end,
 	info = function(self, t)
 		local damageGain = t.getDamageGain(self, t)
 		return ([[Enhances your feeding by reducing your targeted foe's damage by %d%% and increasing yours by the same amount.
-		Improves with the Willpower stat.]]):format(damageGain)
+		Improves with your Mindpower.]]):format(damageGain)
 	end,
 }
 
@@ -190,7 +182,7 @@ newTalent{
 	require = cursed_wil_req4,
 	points = 5,
 	getResistGain = function(self, t)
-		return math.sqrt(self:getTalentLevel(t)) * 22 + self:getWil(15, true)
+		return math.sqrt(self:getTalentLevel(t)) * 14 + self:combatMindpower() * 0.15
 	end,
 	getExtension = function(self, t)
 		return math.floor(self:getTalentLevel(t) - 1)
@@ -198,6 +190,6 @@ newTalent{
 	info = function(self, t)
 		local resistGain = t.getResistGain(self, t)
 		return ([[Enhances your feeding by reducing your targeted foe's positive resistances by %d%% and increasing yours by the same amount. Resistance to "all" is not affected.
-		Improves with the Willpower stat.]]):format(resistGain)
+		Improves with your Mindpower.]]):format(resistGain)
 	end,
 }
diff --git a/game/modules/tome/data/talents/cursed/darkness.lua b/game/modules/tome/data/talents/cursed/darkness.lua
index 5ed215c055..ca01ce6215 100644
--- a/game/modules/tome/data/talents/cursed/darkness.lua
+++ b/game/modules/tome/data/talents/cursed/darkness.lua
@@ -20,10 +20,6 @@
 local Object = require "engine.Object"
 local Map = require "engine.Map"
 
-local function combatTalentDamage(self, t, min, max)
-	return self:combatTalentSpellDamage(t, min, max, (self.level + self:getMag()) * 1.2)
-end
-
 local function createDarkTendrils(summoner, x, y, target, damage, duration, pinDuration)
 	if not summoner:getTalentFromId(summoner.T_CREEPING_DARKNESS) then return end
 
@@ -141,7 +137,7 @@ end
 newTalent{
 	name = "Creeping Darkness",
 	type = {"cursed/darkness", 1},
-	require = cursed_mag_req1,
+	require = cursed_wil_req1,
 	points = 5,
 	random_ego = "attack",
 	cooldown = 20,
@@ -277,7 +273,7 @@ newTalent{
 		return 5 + math.floor(self:getTalentLevel(t))
 	end,
 	getDamage = function(self, t)
-		return combatTalentDamage(self, t, 0, 80)
+		return self:combatTalentMindDamage(t, 0, 60)
 	end,
 	action = function(self, t)
 		local range = self:getTalentRange(t)
@@ -325,14 +321,14 @@ newTalent{
 		local damage = t.getDamage(self, t)
 		local darkCount = t.getDarkCount(self, t)
 		return ([[Creeping dark slowly spreads from %d spots in a radius of %d around the targeted location. The dark deals %d damage and blocks the sight of any who do not possess Dark Vision or some other magical means of seeing.
-		Damage improves with the Magic stat.]]):format(darkCount, radius, damage)
+		The damage will increase with your Mindpower.]]):format(darkCount, radius, damage)
 	end,
 }
 
 newTalent{
 	name = "Dark Vision",
 	type = {"cursed/darkness", 2},
-	require = cursed_mag_req2,
+	require = cursed_wil_req2,
 	points = 5,
 	mode = "passive",
 	random_ego = "attack",
@@ -340,18 +336,19 @@ newTalent{
 		return math.min(10, math.floor((math.sqrt(self:getTalentLevel(t)) - 0.5) * 5))
 	end,
 	getDamageIncrease = function(self, t)
-		return combatTalentDamage(self, t, 0, 40)
+		return self:combatTalentMindDamage(t, 0, 30)
 	end,
 	info = function(self, t)
 		local damageIncrease = t.getDamageIncrease(self, t)
-		return ([[Your eyes penetrate the darkness to find anyone that may be hiding there. You can also see through your clouds of creeping dark and gain the advantage of doing %d%% more damage to anyone enveloped by it.]]):format(damageIncrease)
+		return ([[Your eyes penetrate the darkness to find anyone that may be hiding there. You can also see through your clouds of creeping dark and gain the advantage of doing %d%% more damage to anyone enveloped by it.
+		The damage will increase with your Mindpower.]]):format(damageIncrease)
 	end,
 }
 
 newTalent{
 	name = "Dark Torrent",
 	type = {"cursed/darkness", 3},
-	require = cursed_mag_req3,
+	require = cursed_wil_req3,
 	points = 5,
 	random_ego = "attack",
 	hate = 0.8,
@@ -362,7 +359,7 @@ newTalent{
 	reflectable = true,
 	requires_target = true,
 	getDamage = function(self, t)
-		return combatTalentDamage(self, t, 0, 270)
+		return self:combatTalentMindDamage(t, 0, 260)
 	end,
 	action = function(self, t)
 		local tg = {type="beam", range=self:getTalentRange(t), talent=t}
@@ -396,14 +393,14 @@ newTalent{
 	info = function(self, t)
 		local damage = t.getDamage(self, t)
 		return ([[Sends a torrent of searing darkness through your foes doing %d damage. There is a small chance the rushing darkness will blind them for 3 turns and cause them to forget their target.
-		The damage will increase with the Magic stat.]]):format(damDesc(self, DamageType.DARKNESS, damage))
+		The damage will increase with your Mindpower.]]):format(damDesc(self, DamageType.DARKNESS, damage))
 	end,
 }
 
 newTalent{
 	name = "Dark Tendrils",
 	type = {"cursed/darkness", 4},
-	require = cursed_mag_req4,
+	require = cursed_wil_req4,
 	points = 5,
 	random_ego = "attack",
 	cooldown = 10,
@@ -416,7 +413,7 @@ newTalent{
 		return 2 + math.floor(self:getTalentLevel(t) / 2)
 	end,
 	getDamage = function(self, t)
-		return combatTalentDamage(self, t, 0, 100)
+		return self:combatTalentMindDamage(t, 0, 80)
 	end,
 	action = function(self, t)
 		if self.dark_tendrils then return false end
@@ -437,7 +434,7 @@ newTalent{
 		local pinDuration = t.getPinDuration(self, t)
 		local damage = t.getDamage(self, t)
 		return ([[Send tendrils of creeping dark out to attack your target and pin them in the darkness for %d turns. Creeping dark will trail behind the tendrils as they move. The darkness does %d damage per turn.
-		The damage will increase with the Magic stat.]]):format(pinDuration, damage)
+		The damage will increase with your Mindpower.]]):format(pinDuration, damage)
 	end,
 }
 
diff --git a/game/modules/tome/data/talents/cursed/doomed.lua b/game/modules/tome/data/talents/cursed/doomed.lua
index 4de223cd32..e69de29bb2 100644
--- a/game/modules/tome/data/talents/cursed/doomed.lua
+++ b/game/modules/tome/data/talents/cursed/doomed.lua
@@ -1,76 +0,0 @@
--- ToME - Tales of Middle-Earth
--- 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
-
--- Afflictions
-newTalentType{ type="cursed/cursed-form", name = "cursed form", description = "You are wracked with the dark energies of the curse." }
-newTalentType{ type="cursed/slaughter", name = "slaughter", description = "Your axe yearns for its next victim." }
-newTalentType{ type="cursed/endless-hunt", name = "endless hunt", description = "Each day you lift your weary body and begin the unending hunt." }
-newTalentType{ type="cursed/gloom", name = "gloom", description = "All those in your sight must share your despair." }
-newTalentType{ type="cursed/rampage", name = "rampage", generic = true, description = "Let loose the hate that has grown within." }
-newTalentType{ type="cursed/dark-figure", name = "dark figure", generic = true, description = "Life as an outcast has given you time to reflect on your misfortunes." }
-
--- Generic requires for corruptions based on talent level
-cursed_wil_req1 = {
-	stat = { wil=function(level) return 12 + (level-1) * 2 end },
-	level = function(level) return 0 + (level-1)  end,
-}
-cursed_wil_req2 = {
-	stat = { wil=function(level) return 20 + (level-1) * 2 end },
-	level = function(level) return 4 + (level-1)  end,
-}
-cursed_wil_req3 = {
-	stat = { wil=function(level) return 28 + (level-1) * 2 end },
-	level = function(level) return 8 + (level-1)  end,
-}
-cursed_wil_req4 = {
-	stat = { wil=function(level) return 36 + (level-1) * 2 end },
-	level = function(level) return 12 + (level-1)  end,
-}
-cursed_wil_req5 = {
-	stat = { wil=function(level) return 44 + (level-1) * 2 end },
-	level = function(level) return 16 + (level-1)  end,
-}
-
-cursed_str_req1 = {
-	stat = { str=function(level) return 12 + (level-1) * 2 end },
-	level = function(level) return 0 + (level-1)  end,
-}
-cursed_str_req2 = {
-	stat = { str=function(level) return 20 + (level-1) * 2 end },
-	level = function(level) return 4 + (level-1)  end,
-}
-cursed_str_req3 = {
-	stat = { str=function(level) return 28 + (level-1) * 2 end },
-	level = function(level) return 8 + (level-1)  end,
-}
-cursed_str_req4 = {
-	stat = { str=function(level) return 36 + (level-1) * 2 end },
-	level = function(level) return 12 + (level-1)  end,
-}
-cursed_str_req5 = {
-	stat = { str=function(level) return 44 + (level-1) * 2 end },
-	level = function(level) return 16 + (level-1)  end,
-}
-
-load("/data/talents/cursed/cursed-form.lua")
-load("/data/talents/cursed/slaughter.lua")
-load("/data/talents/cursed/endless-hunt.lua")
-load("/data/talents/cursed/gloom.lua")
-load("/data/talents/cursed/rampage.lua")
-load("/data/talents/cursed/dark-figure.lua")
diff --git a/game/modules/tome/data/talents/cursed/force-of-will.lua b/game/modules/tome/data/talents/cursed/force-of-will.lua
index eb924c0cfa..2b90f02981 100644
--- a/game/modules/tome/data/talents/cursed/force-of-will.lua
+++ b/game/modules/tome/data/talents/cursed/force-of-will.lua
@@ -18,10 +18,6 @@
 -- darkgod@te4.org
 
 
-local function combatTalentDamage(self, t, min, max)
-	return self:combatTalentSpellDamage(t, min, max, (self.level + self:getWil()) * 1.2)
-end
-
 -- damage: initial physical damage and used for fractional knockback damage
 -- knockback: distance to knockback
 -- knockbackDamage: when knockback strikes something, both parties take damage - percent of damage * remaining knockback
@@ -101,7 +97,7 @@ newTalent{
 	require = cursed_wil_req1,
 	points = 5,
 	random_ego = "attack",
-	cooldown = 4,
+	cooldown = 5,
 	hate = 0.5,
 	tactical = { ATTACK = 2 },
 	direct_hit = true,
@@ -110,7 +106,7 @@ newTalent{
 		return 4
 	end,
 	getDamage = function(self, t)
-		return combatTalentDamage(self, t, 0, 200)
+		return self:combatTalentMindDamage(t, 0, 240)
 	end,
 	getKnockback = function(self, t)
 		return math.floor((self:getTalentLevelRaw(t) + 1) / 2)
@@ -133,7 +129,7 @@ newTalent{
 		local damage = t.getDamage(self, t)
 		local knockback = t.getKnockback(self, t)
 		return ([[Focusing your hate, you strike your foe with unseen force for %d damage and %d knockback.
-		Damage increases with the Willpower stat.]]):format(damDesc(self, DamageType.PHYSICAL, damage), knockback)
+		Damage increases with your Mindpower.]]):format(damDesc(self, DamageType.PHYSICAL, damage), knockback)
 	end,
 }
 
@@ -148,7 +144,7 @@ newTalent{
 	tactical = { DEFEND = 2 },
 	no_sustain_autoreset = true,
 	getMaxDamage = function(self, t)
-		return combatTalentDamage(self, t, 0, 200)
+		return self:combatTalentMindDamage(t, 0, 240)
 	end,
 	getDisplayName = function(self, t, p)
 		return ("Deflection (%d)"):format(p.value)
@@ -199,7 +195,7 @@ newTalent{
 	info = function(self, t)
 		local maxDamage = t.getMaxDamage(self, t)
 		return ([[Deflect 50%% of incoming damage with the force of your will. You may deflect up to %d damage, but first your hate must slowly feed your strength (-0.02 hate regeneration while building strength).
-		The maximum damage deflected increases with the Willpower stat.]]):format(maxDamage)
+		The maximum damage deflected increases with your Mindpower.]]):format(maxDamage)
 	end,
 }
 
@@ -220,7 +216,7 @@ newTalent{
 		return math.floor(2 + self:getTalentLevel(t) / 3)
 	end,
 	getDamage = function(self, t)
-		return combatTalentDamage(self, t, 0, 240)
+		return self:combatTalentMindDamage(t, 0, 200)
 	end,
 	getKnockback = function(self, t)
 		return math.floor((self:getTalentLevelRaw(t) + 1) / 2)
@@ -271,7 +267,7 @@ newTalent{
 		local knockback = t.getKnockback(self, t)
 		local dazeDuration = t.getDazeDuration(self, t)
 		return ([[You rage coalesces at a single point and then explodes outward blasting enemies within a radius of %d in all directions. The blast causes %d damage and %d knockback at the center that decreases with distance. Anyone caught in the explosion will also be dazed for 3 turns.
-		Damage increases with the Willpower stat.]]):format(radius, damDesc(self, DamageType.PHYSICAL, damage), knockback)
+		Damage increases with your Mindpower.]]):format(radius, damDesc(self, DamageType.PHYSICAL, damage), knockback)
 	end,
 }
 
@@ -290,7 +286,7 @@ newTalent{
 		return 5 + math.floor(self:getTalentLevel(t))
 	end,
 	getDamage = function(self, t)
-		return combatTalentDamage(self, t, 0, 200)
+		return self:combatTalentMindDamage(t, 0, 140)
 	end,
 	getKnockback = function(self, t)
 		return math.floor(self:getTalentLevel(t))
@@ -348,7 +344,7 @@ newTalent{
 		local knockback = t.getKnockback(self, t)
 		local secondHitChance = t.getSecondHitChance(self, t)
 		return ([[Your fury becomes an unseen force that randomly lashes out at the foes around you. For %d turns you strike one nearby target doing %d damage and %d knockback. At higher levels there is a chance of a second strike.
-		Damage increases with the Willpower stat.]]):format(duration, damDesc(self, DamageType.PHYSICAL, damage), knockback, secondHitChance)
+		Damage increases with your Mindpower.]]):format(duration, damDesc(self, DamageType.PHYSICAL, damage), knockback, secondHitChance)
 	end,
 }
 
diff --git a/game/modules/tome/data/talents/cursed/gestures.lua b/game/modules/tome/data/talents/cursed/gestures.lua
new file mode 100644
index 0000000000..8350e6879c
--- /dev/null
+++ b/game/modules/tome/data/talents/cursed/gestures.lua
@@ -0,0 +1,173 @@
+-- ToME - Tales of Middle-Earth
+-- 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
+
+newTalent{
+	name = "Gesture of Pain",
+	type = {"cursed/gestures", 1},
+	mode = "sustained",
+	require = cursed_cun_req1,
+	points = 5,
+	random_ego = "attack",
+	proj_speed = 4,
+	tactical = { ATTACK = 2 },
+	getBaseDamage = function(self, t)
+		return self:combatTalentMindDamage(t, 0, 125)
+	end,
+	getSecondAttackChance = function(self, t)
+		return 20
+	end,
+	attack = function(self, t, target)
+		if self.hate < 0.1 then return true end
+	
+		local freeHands = self:getFreeHands()
+		if freeHands == 0 then return true end
+		
+		local hit = false
+		
+		local mindpower = self:combatMindpower()
+		local baseDamage = t.getBaseDamage(self, t)
+		if self:checkHit(mindpower, target:combatMentalResist()) then
+			local damage = baseDamage * rng.float(0.5, 1)
+			self:project({type="hit", x=target.x,y=target.y}, target.x, target.y, DamageType.MIND, { dam=damage,alwaysHit=true,criticals=true,crossTierChance=100 })
+			self:incHate(-0.1)
+			game:playSoundNear(self, "actions/melee_hit_squish")
+			hit = true
+		else
+			game.logSeen(self, "%s resists the Gesture of Pain.", target.name:capitalize())
+			game:playSoundNear(self, "actions/melee_miss")
+		end
+		
+		if not target.dead and freeHands > 1 and self.hate >= 0.1 and rng.chance(t.getSecondAttackChance(self, t)) then
+			if self:checkHit(mindpower, target:combatMentalResist()) then
+				local damage = baseDamage * rng.float(0.5, 1)
+				self:project({type="hit", x=target.x,y=target.y}, target.x, target.y, DamageType.MIND, { dam=damage,alwaysHit=true,criticals=true,crossTierChance=100 })
+				game:playSoundNear(self, "actions/melee_hit_squish")
+				hit = true
+				self:incHate(-0.1)
+			else
+				game.logSeen(self, "%s resists the Gesture of Pain.", target.name:capitalize())
+				game:playSoundNear(self, "actions/melee_miss")
+			end
+		end
+		
+		if hit then
+			game.level.map:particleEmitter(target.x, target.y, 1, "melee_attack", {color=colors.VIOLET})
+		end
+		
+		return self:combatSpeed(), hit
+	end,
+	activate = function(self, t)
+		return {}
+	end,
+	deactivate = function(self, t, p)
+		return true
+	end,
+	info = function(self, t)
+		local baseDamage = t.getBaseDamage(self, t)
+		local secondAttackChance = t.getSecondAttackChance(self, t)
+		return ([[Use a gesture of pain in place of an normal attack to strike into the minds of your enemies, inflicting between %0.1f and %0.1f mind damage. Requires a single free hand. A second free hand adds a %d%% chance of a second attack. Each hit costs 0.1 hate.
+		Can cause critical hits with cross tier effects. The damage will increase with your Mindpower.]]):format(damDesc(self, DamageType.MIND, baseDamage * 0.5), damDesc(self, DamageType.MIND, baseDamage), secondAttackChance)
+	end,
+}
+
+newTalent{
+	name = "Gesture of Command",
+	type = {"cursed/gestures", 2},
+	require = cursed_cun_req2,
+	mode = "passive",
+	points = 5,
+	getMindpowerChange = function(self, t, freeHands)
+		freeHands = freeHands or self:getFreeHands()
+		if freeHands == 0 then return 0 end
+		
+		local change = math.pow(self:getTalentLevel(t), 0.7) * 4
+		if freeHands > 1 then change = change * 1.4 end
+		return math.floor(change)
+	end,
+	info = function(self, t)
+		local mindpowerChange1 = t.getMindpowerChange(self, t, 1)
+		local mindpowerChange2 = t.getMindpowerChange(self, t, 2)
+		return ([[Command the forces of your mind through your gestures. With 1 free hand, you gain %d mindpower. With 2 free hands, you gain %d mindpower.]]):format(mindpowerChange1, mindpowerChange2)
+	end,
+}
+
+newTalent{
+	name = "Gesture of Power",
+	type = {"cursed/gestures", 3},
+	require = cursed_cun_req3,
+	mode = "passive",
+	points = 5,
+	getMindCritChange = function(self, t, freeHands)
+		freeHands = freeHands or self:getFreeHands()
+		if freeHands == 0 then return 0 end
+		
+		local change = math.pow(self:getTalentLevel(t), 0.5) * 2
+		if freeHands > 1 then change = change * 1.4 end
+		return change
+	end,
+	info = function(self, t)
+		local mindCritChange1 = t.getMindCritChange(self, t, 1)
+		local mindCritChange2 = t.getMindCritChange(self, t, 2)
+		return ([[Enhance your mental attacks with a single gesture, granting a chance to inflict critical damage with certain mind attacks. With 1 free hand, you gain a %0.1f%% chance. With 2 free hands, you gain %0.1f%% chance.]]):format(mindCritChange1, mindCritChange2)
+	end,
+}
+
+newTalent{
+	name = "Gesture of Guarding",
+	type = {"cursed/gestures", 4},
+	require = cursed_cun_req4,
+	mode = "sustained",
+	cooldown = 10,
+	points = 5,
+	getDamageResistChange = function(self, t, distance, freeHands)
+		freeHands = freeHands or self:getFreeHands()
+		if freeHands == 0 then return 0 end
+		
+		local change = math.pow(self:getTalentLevel(t), 0.5) * 1.15
+		if freeHands > 1 then change = change * 1.4 end
+		return change * math.min(7, distance)
+	end,
+	getIncDamageChange = function(self, t, distance)
+		local change = -(2 + math.pow(self:getTalentLevel(t), 0.5) * 0.8)
+		return change * math.min(7, distance)
+	end,
+	on_damageRecieved = function(self, t, type, dam, src)
+		if src and src.x and src.y and (self.x ~= src.x or self.y ~= src.y) and self:hasLOS(src.x, src.y) then
+			local distance = core.fov.distance(src.x, src.y, self.x, self.y)
+			dam = dam * (100 - t.getDamageResistChange(self, t, distance) / 100)
+		end
+		return dam
+	end,
+	on_damageInflicted = function(self, type, dam, target)
+		if target and target.x and target.y and (self.x ~= target.x or self.y ~= target.y) and self:hasLOS(target.x, target.y) then
+			local distance = core.fov.distance(target.x, target.y, self.x, self.y)
+			dam = dam * (100 + t.getIncDamageChange(self, t, distance) / 100)
+		end
+		return dam
+	end,
+	info = function(self, t)
+		local damageResistChange1 = t.getDamageResistChange(self, t, 1, 1)
+		local damageResistChangeMax1 = t.getDamageResistChange(self, t, 1000, 1)
+		local damageResistChange2 = t.getDamageResistChange(self, t, 1, 2)
+		local damageResistChangeMax2 = t.getDamageResistChange(self, t, 1000, 2)
+		local incDamageChange = t.getIncDamageChange(self, t, 1)
+		local incDamageChangeMax = t.getIncDamageChange(self, t, 1000)
+		return ([[While active, you guard against incoming damage with a sweep of your hand. The farther the source of damage the more it will be reduced, with a maximum reduction at range 7. With 1 free hand, damage taken is reduced by %0.1f%% per space away (up to a maximum of %0.1f%%). With 2 free hands it is reduced by %0.1f%% (up to a maximum of %0.1f%%). Guarding yourself requires great focus and reduces the damage you inflict at range by %0.1f%% per space away (up to a maximum of %0.1f%%).]]):format(damageResistChange1, damageResistChangeMax1, damageResistChange2, damageResistChangeMax2, -incDamageChange, -incDamageChangeMax)
+	end,
+}
diff --git a/game/modules/tome/data/talents/cursed/gloom.lua b/game/modules/tome/data/talents/cursed/gloom.lua
index 750e6a30e8..64fae1f504 100644
--- a/game/modules/tome/data/talents/cursed/gloom.lua
+++ b/game/modules/tome/data/talents/cursed/gloom.lua
@@ -221,10 +221,10 @@ newTalent{
 	require = cursed_wil_req4,
 	points = 5,
 	getDamage = function(self, t)
-		return combatTalentDamage(self, t, 3, 15)
+		return combatTalentDamage(self, t, 2, 10)
 	end,
 	getMaxHeal = function(self, t)
-		return combatTalentDamage(self, t, 5, 30)
+		return combatTalentDamage(self, t, 4, 25)
 	end,
 	info = function(self, t)
 		local damage = t.getDamage(self, t)
diff --git a/game/modules/tome/data/talents/cursed/punishments.lua b/game/modules/tome/data/talents/cursed/punishments.lua
index 5f154026a0..4c44bc943b 100644
--- a/game/modules/tome/data/talents/cursed/punishments.lua
+++ b/game/modules/tome/data/talents/cursed/punishments.lua
@@ -17,29 +17,18 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
-local function combatTalentDamage(self, t, min, max)
-	return self:combatTalentSpellDamage(t, min, max, (self.level + self:getWil()) * 1.2)
-end
-
-local function combatPower(self, t, multiplier)
-	return (self.level + self:getWil()) * (multiplier or 1)
-end
-
 newTalent{
 	name = "Reproach",
 	type = {"cursed/punishments", 1},
-	require = cursed_wil_req1,
+	require = cursed_cun_req1,
 	points = 5,
 	random_ego = "attack",
-	cooldown = 3,
+	cooldown = 4,
 	hate =  0.5,
 	range = 3,
 	tactical = { ATTACKAREA = 2 },
 	getDamage = function(self, t)
-		return combatTalentDamage(self, t, 10, 350)
-	end,
-	getMindpower = function(self, t)
-		return combatPower(self, t)
+		return self:combatTalentMindDamage(t, 10, 280)
 	end,
 	action = function(self, t)
 		local targets = {}
@@ -56,9 +45,8 @@ newTalent{
 		if #targets == 0 then return false end
 
 		local damage = t.getDamage(self, t) / #targets
-		local mindpower = t.getMindpower(self, t)
 		for i, t in ipairs(targets) do
-			self:project({type="hit", x=t.x,y=t.y}, t.x, t.y, DamageType.MIND, { dam=damage, mindpower=mindpower })
+			self:project({type="hit", x=t.x,y=t.y}, t.x, t.y, DamageType.MIND, { dam=damage,criticals=true })
 			game.level.map:particleEmitter(t.x, t.y, 1, "reproach", { dx = self.x - t.x, dy = self.y - t.y })
 		end
 
@@ -68,16 +56,15 @@ newTalent{
 	end,
 	info = function(self, t)
 		local damage = t.getDamage(self, t)
-		local mindpower = t.getMindpower(self, t)
-		return ([[You unleash your hateful mind on any who dare approach you. %d mind damage is spread between everyone in range (mindpower %d vs mental resistance).
-		The damage and mindpower will increase with the Willpower stat.]]):format(damDesc(self, DamageType.MIND, damage), mindpower)
+		return ([[You unleash your hateful mind on any who dare approach you. %d mind damage is spread between everyone in range.
+		Can cause critical hits. The damage increases with your Mindpower.]]):format(damDesc(self, DamageType.MIND, damage))
 	end,
 }
 
 newTalent{
 	name = "Hateful Whisper",
 	type = {"cursed/punishments", 2},
-	require = cursed_wil_req2,
+	require = cursed_cun_req2,
 	points = 5,
 	random_ego = "attack",
 	cooldown = 10,
@@ -90,10 +77,7 @@ newTalent{
 		return 10
 	end,
 	getDamage = function(self, t)
-		return combatTalentDamage(self, t, 0, 180)
-	end,
-	getMindpower = function(self, t)
-		return combatPower(self, t)
+		return self:combatTalentMindDamage(t, 0, 160)
 	end,
 	getJumpRange = function(self, t)
 		return 0.7 + math.sqrt(self:getTalentLevel(t))
@@ -109,7 +93,7 @@ newTalent{
 
 		local duration = t.getDuration(self, t)
 		local damage = t.getDamage(self, t)
-		local mindpower = t.getMindpower(self, t)
+		local mindpower = self:combatMindpower()
 		local jumpRange = t.getJumpRange(self, t)
 		local extraJumpChance = t.getExtraJumpChance(self, t)
 		target:setEffect(target.EFF_HATEFUL_WHISPER, duration, {
@@ -126,11 +110,10 @@ newTalent{
 	end,
 	info = function(self, t)
 		local damage = t.getDamage(self, t)
-		local mindpower = t.getMindpower(self, t)
 		local jumpRange = t.getJumpRange(self, t)
 		local extraJumpChance = t.getExtraJumpChance(self, t)
-		return ([[Send a whisper filled with hate to spread throughout your foes. When first heard they will suffer %d mind damage and the whisper can travel to another victim within a range of %0.2f and begin to spread from them. There is a %d%% chance the whisper will be passed to two victims instead of one. (%d mindpower vs mental resistance)
-		The damage and mindpower will increase with the Willpower stat.]]):format(damDesc(self, DamageType.MIND, damage), jumpRange, extraJumpChance, mindpower)
+		return ([[Send a whisper filled with hate to spread throughout your foes. When first heard they will suffer %d mind damage and the whisper can travel to another victim within a range of %0.2f and begin to spread from them. There is a %d%% chance the whisper will be passed to two victims instead of one.
+		Can cause critical hits. The damage increases with your Mindpower.]]):format(damDesc(self, DamageType.MIND, damage), jumpRange, extraJumpChance)
 	end,
 }
 
@@ -138,7 +121,7 @@ newTalent{
 newTalent{
 	name = "Cursed Ground",
 	type = {"cursed/punishments", 2},
-	require = cursed_wil_req2,
+	require = cursed_cun_req2,
 	points = 5,
 	random_ego = "attack",
 	cooldown = 6,
@@ -255,7 +238,7 @@ newTalent{
 newTalent{
 	name = "Agony",
 	type = {"cursed/punishments", 3},
-	require = cursed_wil_req3,
+	require = cursed_cun_req3,
 	points = 5,
 	random_ego = "attack",
 	cooldown = 3,
@@ -268,10 +251,7 @@ newTalent{
 		return 5
 	end,
 	getDamage = function(self, t)
-		return combatTalentDamage(self, t, 0, 160)
-	end,
-	getMindpower = function(self, t)
-		return combatPower(self, t, 1.2)
+		return self:combatTalentMindDamage(t, 0, 160)
 	end,
 	action = function(self, t)
 		local range = self:getTalentRange(t)
@@ -280,7 +260,7 @@ newTalent{
 		if not x or not y or not target or core.fov.distance(self.x, self.y, x, y) > range then return nil end
 
 		local damage = t.getDamage(self, t)
-		local mindpower = t.getMindpower(self, t)
+		local mindpower = self:combatMindpower()
 		local duration = t.getDuration(self, t)
 		target:setEffect(target.EFF_AGONY, duration, {
 			source = self,
@@ -295,9 +275,8 @@ newTalent{
 		local duration = t.getDuration(self, t)
 		local maxDamage = t.getDamage(self, t)
 		local minDamage = maxDamage / duration
-		local mindpower = t.getMindpower(self, t)
-		return ([[Unleash agony upon your target. The pain will grow over the course of %d turns. The first turn will inflict %d damage and slowly increase to %d on the last turn. (%d mindpower vs mental resistance)
-		The damage and mindpower will increase with the Willpower stat.]]):format(duration, damDesc(self, DamageType.MIND, minDamage), damDesc(self, DamageType.MIND, maxDamage), mindpower)
+		return ([[Unleash agony upon your target. The pain will grow over the course of %d turns. The first turn will inflict %d damage and slowly increase to %d on the last turn.
+		The damage will increase with your Mindpower.]]):format(duration, damDesc(self, DamageType.MIND, minDamage), damDesc(self, DamageType.MIND, maxDamage))
 	end,
 }
 
@@ -305,20 +284,15 @@ newTalent{
 	name = "Madness",
 	type = {"cursed/punishments", 4},
 	mode = "passive",
-	require = cursed_wil_req4,
+	require = cursed_cun_req4,
 	points = 5,
 	tactical = { ATTACK = 2 },
-	getMindpower = function(self, t)
-		return math.sqrt(self:getTalentLevel(t)) * 0.4 * combatPower(self, t)
-	end,
 	getChance = function(self, t)
-		return 25
+		return math.sqrt(self:getTalentLevel(t)) * 8
 	end,
 	doMadness = function(self, t, src)
-		local mindpower = t.getMindpower(src, t)
 		local chance = t.getChance(src, t)
-
-		if self and src and self:reactionToward(src) < 0 and self:checkHit(mindpower, self:combatMentalResist(), 0, chance, 5) then
+		if self and src and self:reactionToward(src) < 0 and self:checkHit(self:combatMindpower(), self:combatMentalResist(), 0, chance, 5) then
 			local effect = rng.range(1, 3)
 			if effect == 1 then
 				-- confusion
@@ -342,10 +316,8 @@ newTalent{
 		end
 	end,
 	info = function(self, t)
-		local mindpower = t.getMindpower(self, t)
 		local chance = t.getChance(self, t)
-		return ([[Every time you inflict mental damage there is a %d%% chance that your foe must save against your mindpower or go mad. Madness can briefly cause them to become confused, slowed or stunned. (%d mindpower vs mental resistance).
-		The mindpower will increase with the Willpower stat.]]):format(chance, mindpower)
+		return ([[Every time you inflict mental damage there is a %d%% chance that your foe must save against your Mindpower or go mad. Madness can briefly cause them to become confused, slowed or stunned.]]):format(chance)
 	end,
 }
 
@@ -353,7 +325,7 @@ newTalent{
 newTalent{
 	name = "Tortured Sanity",
 	type = {"cursed/punishments", 4},
-	require = cursed_wil_req4,
+	require = cursed_cun_req4,
 	points = 5,
 	random_ego = "attack",
 	cooldown = 30,
diff --git a/game/modules/tome/data/talents/cursed/shadows.lua b/game/modules/tome/data/talents/cursed/shadows.lua
index 7621908651..b0707c247e 100644
--- a/game/modules/tome/data/talents/cursed/shadows.lua
+++ b/game/modules/tome/data/talents/cursed/shadows.lua
@@ -288,12 +288,12 @@ newTalent{
 	name = "Call Shadows",
 	type = {"cursed/shadows", 1},
 	mode = "sustained",
-	require = cursed_mag_req1,
+	require = cursed_cun_req1,
 	points = 5,
 	cooldown = 10,
 	tactical = { BUFF = 5 },
 	getLevel = function(self, t)
-		return self.level --return math.max(1, self.level - 2 + self:getMag(4))
+		return self.level
 	end,
 	getMaxShadows = function(self, t)
 		return math.max(1, math.floor(self:getTalentLevel(t) * 0.55))
@@ -381,7 +381,7 @@ newTalent{
 newTalent{
 	name = "Focus Shadows",
 	type = {"cursed/shadows", 2},
-	require = cursed_mag_req2,
+	require = cursed_cun_req2,
 	points = 5,
 	random_ego = "attack",
 	cooldown = 6,
@@ -460,7 +460,7 @@ newTalent{
 	name = "Shadow Mages",
 	type = {"cursed/shadows", 3},
 	mode = "passive",
-	require = cursed_mag_req3,
+	require = cursed_cun_req3,
 	points = 5,
 	getCloseAttackSpellChance = function(self, t)
 		if self:getTalentLevelRaw(t) > 0 then
@@ -516,7 +516,7 @@ newTalent{
 	name = "Shadow Warriors",
 	type = {"cursed/shadows", 4},
 	mode = "passive",
-	require = cursed_mag_req4,
+	require = cursed_cun_req4,
 	points = 5,
 	getIncDamage = function(self, t)
 		return math.floor((math.sqrt(self:getTalentLevel(t)) - 0.5) * 23)
diff --git a/game/modules/tome/data/talents/gifts/summon-distance.lua b/game/modules/tome/data/talents/gifts/summon-distance.lua
index 131e07afc7..1bcfb5dc6d 100644
--- a/game/modules/tome/data/talents/gifts/summon-distance.lua
+++ b/game/modules/tome/data/talents/gifts/summon-distance.lua
@@ -102,7 +102,7 @@ newTalent{
 }
 
 newTalent{
-	name = "Lightning Breath", short_name = "LIGHTNING_BREATH_HYDRA",
+	name = "Lightning Breath", short_name = "LIGHTNING_BREATH_HYDRA", image = "talents/lightning_breath.png",
 	type = {"wild-gift/other",1},
 	require = gifts_req1,
 	points = 5,
diff --git a/game/modules/tome/data/timed_effects/mental.lua b/game/modules/tome/data/timed_effects/mental.lua
index 26df90d163..d335c8bee2 100644
--- a/game/modules/tome/data/timed_effects/mental.lua
+++ b/game/modules/tome/data/timed_effects/mental.lua
@@ -778,7 +778,7 @@ newEffect{
 	on_gain = function(self, err) return "#Target# has heard the hateful whisper!", "+Hateful Whisper" end,
 	on_lose = function(self, err) return "#Target# no longer hears the hateful whisper.", "-Hateful Whisper" end,
 	activate = function(self, eff)
-		DamageType:get(DamageType.MIND).projector(eff.source, self.x, self.y, DamageType.MIND, eff.damage)
+		DamageType:get(DamageType.MIND).projector(eff.source, self.x, self.y, DamageType.MIND, { dam=eff.damage,criticals=true })
 
 		if self.dead then
 			-- only spread on activate if the target is dead
diff --git a/game/modules/tome/data/zones/dreadfell/npcs.lua b/game/modules/tome/data/zones/dreadfell/npcs.lua
index cb4194d09a..bcda7a76ee 100644
--- a/game/modules/tome/data/zones/dreadfell/npcs.lua
+++ b/game/modules/tome/data/zones/dreadfell/npcs.lua
@@ -56,7 +56,7 @@ newEntity{ define_as = "THE_MASTER",
 		{type="jewelry", subtype="amulet", defined="AMULET_DREAD", random_art_replace={chance=75}, autoreq=true},
 	},
 	resolvers.drops{chance=100, nb=5, {tome_drops="boss"} },
-	resolvers.drops{chance=100, nb=1, {type="weapon", subtype="staff", defined="STAFF_ABSORPTION"} },
+	resolvers.drops{chance=100, nb=1, {type="weapon", subtype="staff", defined="STAFF_ABSORPTION", special=function() return game.zone.is_dreadfell end} },
 
 	summon = {
 		{type="undead", number=2, hasxp=true},
diff --git a/game/modules/tome/data/zones/dreadfell/zone.lua b/game/modules/tome/data/zones/dreadfell/zone.lua
index 28570a687c..06de652162 100644
--- a/game/modules/tome/data/zones/dreadfell/zone.lua
+++ b/game/modules/tome/data/zones/dreadfell/zone.lua
@@ -31,6 +31,7 @@ return {
 	ambient_music = "Dark Secrets.ogg",
 	min_material_level = function() return game.state:isAdvanced() and 4 or 3 end,
 	max_material_level = function() return game.state:isAdvanced() and 5 or 4 end,
+	is_dreadfell = true,
 	generator =  {
 		map = {
 			class = "engine.generator.map.Roomer",
diff --git a/game/modules/tome/dialogs/Birther.lua b/game/modules/tome/dialogs/Birther.lua
index 076393f511..a070c9b6db 100644
--- a/game/modules/tome/dialogs/Birther.lua
+++ b/game/modules/tome/dialogs/Birther.lua
@@ -273,8 +273,8 @@ function _M:makeDefault()
 	self:setDescriptor("permadeath", "Adventure")
 	self:setDescriptor("race", "Human")
 	self:setDescriptor("subrace", "Higher")
-	self:setDescriptor("class", "Wilder")
-	self:setDescriptor("subclass", "Summoner")
+	self:setDescriptor("class", "Warrior")
+	self:setDescriptor("subclass", "Berserker")
 	__module_extra_info.no_birth_popup = true
 	self:atEnd("created")
 end
-- 
GitLab