diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 267f99fead623af9d87ad935d982700e5bce6cb7..3b7e39ecefbeff15a7fc6eb7ec45c28afd1ed8f9 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -611,12 +611,45 @@ function _M:actBase()
 	self:checkStillInCombat()
 end
 
+function _M:hasProc(proc)
+	if not self.turn_procs then return end
+	if self.turn_procs[proc] then 
+		return self.turn_procs[proc] 
+	elseif self.turn_procs.multi then 
+		return self.turn_procs.multi[proc] 
+	end
+end
+
+function _M:setProc(name, val, turns)
+	turns = turns or 1
+	val = val or true
+	local proc = {val = val, turns = turns}
+	if turns > 1 then
+		table.set(self, "turn_procs", "multi", name, proc)
+	else 
+		self.turn_procs[name] = proc
+	end
+end
+
 -- General entry point for Actors to act, called by NPC:act or Player:act
 function _M:act()
 	if not engine.Actor.act(self) then return end
 
 	self.changed = true
+
+	-- Store procs with more than 1 turn remaining and re-add them after we clear turn_procs
+	local temp = {}
+	if self.turn_procs.multi then
+		for proc, val in pairs(self.turn_procs.multi) do
+			if proc then
+				self.turn_procs.multi[proc].turns = self.turn_procs.multi[proc].turns - 1
+				if self.turn_procs.multi[proc].turns > 0 then temp[proc] = val end
+			end
+		end
+	end
+
 	self.turn_procs = {}
+	if temp then self.turn_procs.multi = temp end
 
 	-- Break some sustains if certain resources are too low
 	-- Note: force_talent_ignore_ressources has no effect here
diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
index 17e4e0fb5bdbf4816d6d69cde878a9b86aa29414..4a30dcd2b70fe5eca026ff0e3d557c8766ed8a17 100644
--- a/game/modules/tome/class/interface/Combat.lua
+++ b/game/modules/tome/class/interface/Combat.lua
@@ -248,13 +248,6 @@ function _M:attackTarget(target, damtype, mult, noenergy, force_unarmed)
 		t.on_attackTarget(self, t, target)
 	end
 
-	if self:attr("unharmed_attack_on_hit") then
-		local v = self:attr("unharmed_attack_on_hit")
-		self:attr("unharmed_attack_on_hit", -v)
-		if rng.percent(60) then self:attackTarget(target, nil, 1, true, true) end
-		self:attr("unharmed_attack_on_hit", v)
-	end
-
 	-- Cancel stealth!
 	if break_stealth then self:breakStealth() end
 	self:breakLightningSpeed()
@@ -693,6 +686,15 @@ function _M:attackTargetHitProcs(target, weapon, dam, apr, armor, damtype, mult,
 		self.__global_accuracy_damage_bonus = self.__global_accuracy_damage_bonus / self.__attacktargetwith_recursing_procs_reduce
 	end
 
+	if self:attr("unharmed_attack_on_hit") and not (self.turn_procs.flexible_combat and (self.turn_procs.flexible_combat >= self:callTalent(self.T_FLEXIBLE_COMBAT, "getProcs")) ) then
+		self.turn_procs.flexible_combat = self.turn_procs.flexible_combat or 0
+		self.turn_procs.flexible_combat = self.turn_procs.flexible_combat + 1
+		local v = self:attr("unharmed_attack_on_hit")
+		self:attr("unharmed_attack_on_hit", -v)
+		if rng.percent(30) then self:attackTarget(target, nil, 1, true, true) end
+		self:attr("unharmed_attack_on_hit", v)
+	end
+
 	-- handle stalk targeting for hits (also handled in Actor for turn end effects)
 	if hitted and target ~= self then
 		local effStalker = self:hasEffect(self.EFF_STALKER)
diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua
index cd7b301d5f043ca1bb6a7c5387be968bea99876f..07186b7fd7f4d94adf8224ca98527b5a1d94d463 100644
--- a/game/modules/tome/data/damage_types.lua
+++ b/game/modules/tome/data/damage_types.lua
@@ -542,10 +542,6 @@ setDefaultProjector(function(src, x, y, type, dam, state)
 			end
 		end
 
-		if not target.dead and dam > 0 and src.knowTalent and src:knowTalent(src.T_ENDLESS_WOES) then
-			src:triggerTalent(src.T_ENDLESS_WOES, nil, target, type, dam)
-		end
-
 		-- damage affinity healing
 		if not target.dead and affinity_heal > 0 then
 			target:heal(affinity_heal, src)
@@ -637,15 +633,6 @@ setDefaultProjector(function(src, x, y, type, dam, state)
 			end
 		end
 
-		-- Use state, because we don't care if it was shrugged off.
-		if state.crit_power > 1 and not state.crit_elemental_surge then
-			if src.knowTalent and src:knowTalent(src.T_ELEMENTAL_SURGE) then
-				src:triggerTalent(src.T_ELEMENTAL_SURGE, nil, target, type, dam)
-			end
-
-			state.crit_elemental_surge = true
-		end
-
 		if src.turn_procs and not src.turn_procs.dazing_damage and src.hasEffect and src:hasEffect(src.EFF_DAZING_DAMAGE) then
 			if target:canBe("stun") then
 				local power = math.max(src:combatSpellpower(), src:combatMindpower(), src:combatPhysicalpower())
diff --git a/game/modules/tome/data/talents/uber/cun.lua b/game/modules/tome/data/talents/uber/cun.lua
index 8ec4a86da0f3218864ad088e95f5f9a9d1e8a991..f9a5d3003915daef87d75e6098c75b1a6604be34 100644
--- a/game/modules/tome/data/talents/uber/cun.lua
+++ b/game/modules/tome/data/talents/uber/cun.lua
@@ -20,6 +20,7 @@
 uberTalent{
 	name = "Fast As Lightning",
 	mode = "passive",
+	not_listed = true,
 	trigger = function(self, t, ox, oy)
 		local dx, dy = (self.x - ox), (self.y - oy)
 		if dx ~= 0 then dx = dx / math.abs(dx) end
@@ -93,36 +94,113 @@ uberTalent{
 			(self.damage_log[DamageType.TEMPORAL] and self.damage_log[DamageType.TEMPORAL] >= 50000)
 		)
 	end} },
-	cunmult = function(self) return self:combatStatScale("cun", 0.15, 1) end,
-	trigger = function(self, t, target, damtype, dam)
-		if dam < 150 then return end
-		if damtype == DamageType.ACID and rng.percent(20) then
-			target:setEffect(target.EFF_ACID_SPLASH, 5, {src=self, dam=(dam * t.cunmult(self) / 2.5) / 5, atk=self:getCun() / 2, apply_power=math.max(self:combatSpellpower(), self:combatMindpower())})
-		elseif damtype == DamageType.BLIGHT and target:canBe("disease") and rng.percent(20) then
-			local diseases = {{self.EFF_WEAKNESS_DISEASE, "str"}, {self.EFF_ROTTING_DISEASE, "con"}, {self.EFF_DECREPITUDE_DISEASE, "dex"}}
-			local disease = rng.table(diseases)
-			target:setEffect(disease[1], 5, {src=self, dam=(dam * t.cunmult(self)/ 2.5) / 5, [disease[2]]=self:getCun() / 3, apply_power=math.max(self:combatSpellpower(), self:combatMindpower())})
-		elseif damtype == DamageType.DARKNESS and target:canBe("blind") and rng.percent(20) then
-			target:setEffect(target.EFF_BLINDED, 5, {apply_power=math.max(self:combatSpellpower(), self:combatMindpower())})
-		elseif damtype == DamageType.TEMPORAL and target:canBe("slow") and rng.percent(20) then
-			target:setEffect(target.EFF_SLOW, 5, {apply_power=math.max(self:combatSpellpower(), self:combatMindpower()), power=0.3})
-		elseif damtype == DamageType.MIND and target:canBe("confusion") and rng.percent(20) then
-			target:setEffect(target.EFF_CONFUSED, 5, {apply_power=math.max(self:combatSpellpower(), self:combatMindpower()), power=20})
+	getBlight = function(self, t)
+		return self:combatStatScale("cun", 1, 20, 0.75), self:combatStatScale("cun", 5, 30, 0.75)
+	end,
+	getDarkness = function(self, t) return self:combatStatScale("cun", 1, 30, 0.75) end,
+	getAcid = function(self, t) return self:combatStatScale("cun", 10, 50, 0.75) end,
+	getTemporal = function(self, t) return self:combatStatScale("cun", 1, 40, 0.75) end,
+	getMind = function(self, t) return self:combatStatScale("cun", 1, 40, 0.75) end,
+	range = 10,
+	radius = 3,
+	dts = {TEMPORAL=true, BLIGHT=true, ACID=true, DARKNESS=true, MIND=true,},
+	getThreshold = function(self, t) return 8*self.level end,
+	getDamage = function(self, t) return self:combatStatScale("cun", 10, 150, 0.75) end,
+	doProject = function(self, t, damtype, effect, part)
+		local tgts = {}
+		-- Find everything nearby and pick one at random
+		local grids = core.fov.circle_grids(self.x, self.y, self:getTalentRange(t), true)
+		for x, yy in pairs(grids) do for y, _ in pairs(grids[x]) do
+			local a = game.level.map(x, y, Map.ACTOR)
+			if a and self:reactionToward(a) < 0 then
+				tgts[#tgts+1] = a
+			end
+		end end
+		local target = rng.table(tgts)
+		if not target then return end
+		
+		local eff = effect
+		local tg = {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false, friendlyfire=false, talent=t}
+		game.level.map:particleEmitter(target.x, target.y, tg.radius, part, {radius=tg.radius})
+		self:project(tg, target.x, target.y, function(tx, ty)
+			local target = game.level.map(tx, ty, Map.ACTOR)
+			if not target or target == self then return end
+			if not effect.params then return end
+			--local p = table.clone(effect.params)
+			local eff = table.clone(effect, true)
+
+			if not effect.canbe or target:canBe(effect.canbe) then
+				eff.params.apply_power = math.max(self:combatSpellpower(), self:combatMindpower())
+				target:setEffect(target[effect.id], 5, eff.params)
+			end
+			DamageType:get(damtype).projector(self, tx, ty, damtype, t.getDamage(self, t))
+		end)
+	end,
+	callbackOnRest = function(self, t) self.endless_woes = {} end, -- No storing damage out of combat
+	callbackOnRun = function(self, t) self.endless_woes = {} end,
+	callbackOnDealDamage = function(self, t, value, target, dead, death_note)
+		local damtype = death_note.damtype
+		if not t.dts[damtype] then return end
+		self.endless_woes = self.endless_woes or {}
+		self.endless_woes[damtype] = (self.endless_woes[damtype] or 0) + value
+
+		if self.endless_woes[damtype] > t.getThreshold(self, t) then
+			self.endless_woes[damtype] = 0
+			if damtype == DamageType.TEMPORAL and not self:hasProc("endless_woes_temporal") then
+				self:setProc("endless_woes_temporal", true, 12)
+				game.logSeen(self, "You unleash a blast of #LIGHT_STEEL_BLUE#temporal#LAST# energy!", self.name:capitalize())
+				t.doProject(self, t, damtype, {id="EFF_SLOW", dur=5, params={power=0.3}, canbe="slow"}, "ball_temporal")
+			elseif damtype == DamageType.BLIGHT and not self:hasProc("endless_woes_blight") then
+				self:setProc("endless_woes_blight", true, 12)				
+				game.logSeen(self, "You unleash a blast of #DARK_GREEN#virulent blight!#LAST#!", self.name:capitalize())
+				local dam, stat = t.getBlight(self, t)
+				t.doProject(self, t, damtype, {id="EFF_WOEFUL_DISEASE", dur=5, params = {src=self, dam=dam, str=stat, con=stat, dex=stat}, canbe="disease"}, "ball_blight")
+			elseif damtype == DamageType.ACID and not self:hasProc("endless_woes_acid") then
+				self:setProc("endless_woes_acid", true, 12)
+				local dam = t.getAcid(self, t)
+				game.logSeen(self, "You unleash a blast of #GREEN#acid#LAST#!", self.name:capitalize())
+				t.doProject(self, t, damtype, {id="EFF_WOEFUL_CORROSION", dur=5, params={src=self, dam=dam}}, "ball_acid")
+			elseif damtype == DamageType.DARKNESS and not self:hasProc("endless_woes_darkness") then
+				self:setProc("endless_woes_darkness", true, 12)
+				game.logSeen(self, "You unleash a blast of numbing #GREY#darkness#LAST#!", self.name:capitalize())
+				t.doProject(self, t, damtype, {id="EFF_WOEFUL_DARKNESS", dur=5, params={reduce=t.getDarkness(self, t)}}, "shadow_flash")
+			elseif damtype == DamageType.MIND and not self:hasProc("endless_woes_mind") then
+				self:setProc("endless_woes_mind", true, 12)
+				game.logSeen(self, "You unleash a confusing blast of #YELLOW#mental#LAST# energy!", self.name:capitalize())
+				t.doProject(self, t, damtype, {id="EFF_CONFUSED", dur=5, params={power=50}, canbe="confusion"}, "starfall")
+			end
 		end
 	end,
 	info = function(self, t)
-		return ([[Surround yourself with a malevolent aura.
-		Any acid damage you do has a 20%% chance to apply a lasting acid that deals %d%% of the initial damage for 5 turns and reduces accuracy by %d.
-		Any blight damage you do has a 20%% chance to cause a random disease that deals %d%% of the initial damage for 5 turns and reduces a stat by %d.
-		Any darkness damage you do has a 20%% chance to blind the target for 5 turns.
-		Any temporal damage you do has a 20%% chance to slow (30%%) the target for 5 turns.
-		Any mind damage you do has a 20%% chance to confuse (20%%) the target for 5 turns.
-		This only triggers for hits over 150 damage.
-		The damage values increase with your Cunning.]])
-		:format(100*t.cunmult(self) / 2.5, self:getCun() / 2, 100*t.cunmult(self) / 2.5, self:getCun() / 3)
+		local blight_dam, blight_disease = t.getBlight(self, t)
+		local cooldowns = {}
+		local str = ""
+		-- Display the remaining cooldowns in the talent tooltip only if its learned
+		if self:knowTalent(self.T_ENDLESS_WOES) then
+			for dt, _ in pairs(t.dts) do
+				local proc = self:hasProc("endless_woes_"..dt:lower())
+				if proc then cooldowns[#cooldowns+1] = (dt:lower()):capitalize()..": "..proc.turns end
+			end
+			str = "(Cooldowns)".."\n"..table.concat(cooldowns, "\n")
+		end
+		return ([[Surround yourself with a malevolent aura that stores damage you deal.
+		Whenever you have stored %d damage of one type you unleash a powerful blast at a random enemy dealing %d damage of that type in radius %d and applying one of the following effects:
+
+		#GREEN#Acid:#LAST#  Deals %d acid damage each turn for 5 turns.
+		#DARK_GREEN#Blight:#LAST#  Deals %d blight damage each turn for 5 turns and reduces strength, constitution, and dexterity by %d.
+		#GREY#Darkness:#LAST#  Reduces damage dealt by %d%% for 5 turns.
+		#LIGHT_STEEL_BLUE#Temporal:#LAST#  Slows global action speed by %d%% for 5 turns.
+		#YELLOW#Mind:#LAST#  Confuses (power %d%%) for 5 turns.
+
+		Each effect has an independent 12 player turn cooldown.
+		The damage and effect power increase with your Cunning, the threshold with your level, and the apply power is the highest of your mind or spell power.
+
+		%s]])
+		:format(t.getThreshold(self, t), t.getDamage(self, t), self:getTalentRadius(t), t.getAcid(self, t), blight_dam, blight_disease, t.getDarkness(self, t), t.getTemporal(self, t), t.getMind(self, t), str)
 	end,
 }
 
+-- Item rarities
 uberTalent{
 	name = "Secrets of Telos",
 	mode = "passive",
@@ -161,7 +239,6 @@ uberTalent{
 uberTalent{
 	name = "Elemental Surge",
 	mode = "passive",
-	cooldown = 12,
 	require = { special={desc="Have dealt over 50000 arcane, fire, cold, lightning, light or nature damage", fct=function(self) return 
 		self.damage_log and (
 			(self.damage_log[DamageType.ARCANE] and self.damage_log[DamageType.ARCANE] >= 50000) or
@@ -172,45 +249,85 @@ uberTalent{
 			(self.damage_log[DamageType.NATURE] and self.damage_log[DamageType.NATURE] >= 50000)
 		)
 	end} },
-	getThreshold = function(self, t) return 4*self.level end,
-	getColdEffects = function(self, t)
-		return {physresist = 30,
-		armor = self:combatStatScale("cun", 20, 50, 0.75),
-		dam = math.max(100, self:getCun()),
+	dts = {PHYSICAL=true, ARCANE=true, LIGHT=true, COLD=true, LIGHTNING=true, FIRE=true, NATURE=true,},	getCold = function(self, t)
+		return {
+			armor = self:combatStatScale("cun", 10, 30, 0.75),
+			dam = math.max(100, self:getCun()),
 		}
 	end,
-	getShield = function(self, t) return 100 + 2*self:getCun() end,
-	-- triggered in default projector in mod.data.damage_types.lua
-	trigger = function(self, t, target, damtype, dam)
-		if dam < t.getThreshold(self, t) then return end
-		
-		local ok = false
-		if damtype == DamageType.ARCANE and rng.percent(30) then ok=true self:setEffect(self.EFF_ELEMENTAL_SURGE_ARCANE, 5, {})
-		elseif damtype == DamageType.FIRE and rng.percent(30) then ok=true self:removeEffectsFilter{type="magical", status="detrimental"} self:removeEffectsFilter{type="physical", status="detrimental"} game.logSeen(self, "#CRIMSON#%s fiery attack invokes a cleansing flame!", self.name:capitalize())
-		elseif damtype == DamageType.COLD and rng.percent(30) then
-			-- EFF_ELEMENTAL_SURGE_COLD in mod.data.timed_effect.magical.lua holds the parameters
-			ok=true self:setEffect(self.EFF_ELEMENTAL_SURGE_COLD, 5, t.getColdEffects(self, t))
-		elseif damtype == DamageType.LIGHTNING and rng.percent(30) then ok=true self:setEffect(self.EFF_ELEMENTAL_SURGE_LIGHTNING, 5, {})
-		elseif damtype == DamageType.LIGHT and rng.percent(30) and not self:hasEffect(self.EFF_DAMAGE_SHIELD) then
-			ok=true
-			self:setEffect(self.EFF_DAMAGE_SHIELD, 5, {power=t.getShield(self, t)})
-		elseif damtype == DamageType.NATURE and rng.percent(30) then ok=true self:setEffect(self.EFF_ELEMENTAL_SURGE_NATURE, 5, {})
-		end
+	getLight = function(self, t) return 20 end,
+	getLightning = function(self, t) return self:combatStatScale("cun", 10, 70, 0.75) end,
+	getFire = function(self, t) return 20 end,
+	getThreshold = function(self, t) return 8*self.level end,
+	callbackOnRest = function(self, t) self.elemental_surge = nil end, -- No storing damage out of combat
+	callbackOnRun = function(self, t) self.elemental_surge = nil end,
+	callbackOnDealDamage = function(self, t, value, target, dead, death_note)
+		local damtype = death_note.damtype
+		if not t.dts[damtype] then return end
+		self.elemental_surge = self.elemental_surge or {}
+		self.elemental_surge[damtype] = (self.elemental_surge[damtype] or 0) + value
 
-		if ok then self:startTalentCooldown(t) end
+		if self.elemental_surge[damtype] > t.getThreshold(self, t) then
+			self.elemental_surge[damtype] = 0
+			if damtype == DamageType.PHYSICAL and not self:hasProc("elemental_surge_physical") then
+				self:setProc("elemental_surge_physical", true, 12)
+				game.logSeen(self, "%s surges with earthen! power!", self.name:capitalize()) 
+				self:removeEffectsFilter({status="detrimental", type="physical", ignore_crosstier=true}, 1)
+			elseif damtype == DamageType.ARCANE and not self:hasProc("elemental_surge_arcane") then
+				self:setProc("elemental_surge_arcane", true, 12)
+				game.logSeen(self, "%s surges with #PURPLE#arcane#LAST# power!", self.name:capitalize())
+				self:setEffect(self.EFF_ELEMENTAL_SURGE_ARCANE, 3, {})
+			elseif damtype == DamageType.FIRE and not self:hasProc("elemental_surge_fire") then
+				self:setProc("elemental_surge_fire", true, 12)
+				self:setEffect(self.EFF_ELEMENTAL_SURGE_FIRE, 3, {damage = t.getFire(self, t)})
+				game.logSeen(self, "%s surges with #LIGHT_RED#fiery#LAST# power!", self.name:capitalize())
+			elseif damtype == DamageType.COLD and not self:hasProc("elemental_surge_cold") then
+				self:setProc("elemental_surge_cold", true, 12)
+				game.logSeen(self, "%s surges with #1133F3#icy#LAST# power!", self.name:capitalize()) 
+				self:setEffect(self.EFF_ELEMENTAL_SURGE_COLD, 3, t.getCold(self, t) )
+			elseif damtype == DamageType.LIGHTNING and not self:hasProc("elemental_surge_lightning") then
+				self:setProc("elemental_surge_lightning", true, 12)
+				game.logSeen(self, "%s surges with #ROYAL_BLUE#lightning#LAST# power!", self.name:capitalize())
+				self:setEffect(self.EFF_ELEMENTAL_SURGE_LIGHTNING, 3, {move = t.getLightning(self, t)})
+			elseif damtype == DamageType.LIGHT and not self:hasProc("elemental_surge_light") then
+				self:setProc("elemental_surge_light", true, 12)
+				game.logSeen(self, "%s surges with #YELLOW#light#LAST# power!", self.name:capitalize())
+				self:setEffect(self.EFF_ELEMENTAL_SURGE_LIGHT, 3, {cooldown = t.getLight(self, t)}) -- Cooldown reduction
+			elseif damtype == DamageType.NATURE and not self:hasProc("elemental_surge_nature") then
+				self:setProc("elemental_surge_nature", true, 12)
+				game.logSeen(self, "%s surges with #LIGHT_GREEN#natural#LAST# power!", self.name:capitalize())
+				self:removeEffectsFilter({status="detrimental", type="magical", ignore_crosstier=true}, 1)
+			end
+		end
 	end,
 	info = function(self, t)
-		local cold = t.getColdEffects(self, t)
-		return ([[Surround yourself with an elemental aura. When you deal a critical hit with an element, you have a chance to trigger a special effect.
-		Arcane damage has a 30%% chance to increase your spellcasting speed by 20%% for 5 turns.
-		Fire damage has a 30%% chance to cleanse all physical or magical detrimental effects on you.
-		Cold damage has a 30%% chance to turn your skin into ice for 5 turns, reducing physical damage taken by %d%%, increasing armor by %d, and dealing %d ice damage to attackers.
-		Lightning damage has a 30%% chance to transform you into pure lightning for 5 turns; any damage will displace you to an adjacent tile and ignore the damage (can only happen once per turn).
-		Light damage has a 30%% chance to create a barrier around you, absorbing %d damage for 5 turns.
-		Nature damage has a 30%% chance to harden your skin, preventing the application of any magical detrimental effects for 5 turns.
-		The Cold and Light effects scale with your Cunning.
-		These effects only trigger for hits over %d damage (based on your level).]])
-		:format(cold.physresist, cold.armor, cold.dam, t.getShield(self, t), t.getThreshold(self, t))
+		local cooldowns = {}
+		local str = ""
+		local cold = t.getCold(self, t)
+		-- Display the remaining cooldowns in the talent tooltip only if its learned
+		if self:knowTalent(self.T_ELEMENTAL_SURGE) then
+			for dt, _ in pairs(t.dts) do
+				local proc = self:hasProc("elemental_surge_"..dt:lower())
+				if proc then cooldowns[#cooldowns+1] = (dt:lower()):capitalize()..": "..proc.turns end
+			end
+		str = "(Cooldowns)".."\n"..table.concat(cooldowns, "\n")
+		end
+		return ([[Surround yourself with an elemental aura. Whenever you deal elemental damage you store it, unleashing a powerful effect when %d total damage (based on level) is reached.
+			The charge totals are cleared out of combat.
+
+		Physical:		Cleanses 1 physical debuff.
+		#PURPLE#Arcane:#LAST#		Increases your non-physical combat speeds by 30%% for 3 turns.
+		#LIGHT_RED#Fire:#LAST#		Increases all damage dealt by %d%% for 3 turns.
+		#1133F3#Cold:#LAST#		Turn your skin into ice for 3 turns increasing armor by %d and dealing %d ice damage to attackers.
+		#ROYAL_BLUE#Lightning:#LAST#	Increases your movement speed by %d%% for 3 turns.
+		#YELLOW#Light:#LAST#		Reduce all cooldowns by 20%% for 3 turns.
+		#LIGHT_GREEN#Nature:#LAST#		Cleanses 1 magical debuff.
+
+		Each cooldown is independent.
+		Some effects scale with your Cunning stat.
+
+		%s]])
+		:format(t.getThreshold(self, t), t.getFire(self, t), cold.armor, cold.dam, t.getLightning(self, t), str)
 	end,
 }
 
@@ -235,7 +352,8 @@ uberTalent{
 	name = "Eye of the Tiger",
 	mode = "passive",
 	trigger = function(self, t, kind)
-		if self.turn_procs.eye_tiger then return end
+		local kind_str = "eye_tiger_"..kind
+		if self:hasProc(kind_str) then return end
 
 		local tids = {}
 
@@ -258,13 +376,13 @@ uberTalent{
 		self.talents_cd[tid] = self.talents_cd[tid] - (d and d.reduce or 1)
 		if self.talents_cd[tid] <= 0 then self.talents_cd[tid] = nil end
 		self.changed = true
-		self.turn_procs.eye_tiger = true
+		self:setProc(kind_str)
 	end,
 	info = function(self, t)
 		local list = {}
 		for _, d in pairs(eye_of_the_tiger_data) do list[#list+1] = d.desc end
 		return ([[%s		
-		This can only happen once per turn, and cannot affect the talent that triggers it.]])
+		This can only happen once per turn per type, and cannot affect the talent that triggers it.]])
 		:format(table.concat(list, "\n"))
 	end,
 }
@@ -302,6 +420,32 @@ uberTalent{
 	end,
 }
 
+uberTalent{
+	name = "Adept",
+	mode = "passive",
+	cant_steal = true,
+	info = function(self, t)
+		return ([[All talent types you know when you aquire this prodigy have their mastery increased by 0.3]])
+		:format()
+	end,
+	on_learn = function(self, t)
+		for i, def in ipairs(engine.interface.ActorTalents.talents_types_def) do
+			if not def.hide and self:knowTalentType(def.type) then -- Do not increase mastery for NPC talents, inscriptions, prodigies, Cursed Sentry, etc
+				self:setTalentTypeMastery(def.type, self:getTalentTypeMastery(def.type) + 0.3)
+				self:updateTalentTypeMastery(def.type)
+			end
+		end
+	end,
+	on_unlearn = function(self, t)
+		for i, def in ipairs(engine.interface.ActorTalents.talents_types_def) do
+			if not def.hide and self:knowTalentType(def.type) then
+				self:setTalentTypeMastery(def.type, self:getTalentTypeMastery(def.type) - 0.3)
+				self:updateTalentTypeMastery(def.type)
+			end
+		end
+	end
+}
+
 uberTalent{
 	name = "Tricks of the Trade",
 	mode = "passive",
diff --git a/game/modules/tome/data/talents/uber/dex.lua b/game/modules/tome/data/talents/uber/dex.lua
index 60409d061735389ffa733b4fd0fd0eba0dee6b93..78f83de42e7becf7af3260db52b48f8343b56d98 100644
--- a/game/modules/tome/data/talents/uber/dex.lua
+++ b/game/modules/tome/data/talents/uber/dex.lua
@@ -17,6 +17,24 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
+uberTalent{
+	name = "Flexible Combat",
+	mode = "passive",
+	on_learn = function(self, t)
+		self:attr("unharmed_attack_on_hit", 1)
+		self:attr("show_gloves_combat", 1)
+	end,
+	on_unlearn = function(self, t)
+		self:attr("unharmed_attack_on_hit", -1)
+		self:attr("show_gloves_combat", -1)
+	end,
+	getProcs = function(self, t) return math.floor(self:getDex() / 30) end,
+	info = function(self, t)
+		return ([[Each time that you make a melee attack you have a 30%% chance to execute an additional unarmed strike.  This can occur once per turn for every 30 Dexterity (currently %d) you have.]])
+		:format(t.getProcs(self, t))
+	end,
+}
+
 uberTalent{
 	name = "Through The Crowd",
 	require = { special={desc="Have had at least 6 party members at the same time", fct=function(self)
@@ -149,67 +167,6 @@ uberTalent{
 	end,
 }
 
-uberTalent{
-	name = "Giant Leap",
-	mode = "activated",
-	require = { special={desc="Have dealt over 50000 damage with any weapon or unarmed", fct=function(self) return
-		self.damage_log and (
-			(self.damage_log.weapon.twohanded and self.damage_log.weapon.twohanded >= 50000) or
-			(self.damage_log.weapon.shield and self.damage_log.weapon.shield >= 50000) or
-			(self.damage_log.weapon.dualwield and self.damage_log.weapon.dualwield >= 50000) or
-			(self.damage_log.weapon.other and self.damage_log.weapon.other >= 50000)
-		)
-	end} },
-	cooldown = 12,
-	radius = 1,
-	range = 10,
-	is_melee = true,
-	requires_target = true,
-	tactical = { CLOSEIN = 2, ATTACKAREA = { weapon = 2 }, DISABLE = { stun = 1 } },
-	target = function(self, t)
-		return {type="ball", range=self:getTalentRange(t), selffire=false, radius=self:getTalentRadius(t)}
-	end,
-	action = function(self, t)
-		local tg = self:getTalentTarget(t)
-		local x, y, target = self:getTarget(tg)
-		if not x or not y then return nil end
-		local _ _, x, y = self:canProject(tg, x, y)
-
-		if game.level.map(x, y, Map.ACTOR) then
-			x, y = util.findFreeGrid(x, y, 1, true, {[Map.ACTOR]=true})
-			if not x then return end
-		end
-
-		if game.level.map:checkAllEntities(x, y, "block_move") then return end
-
-		local ox, oy = self.x, self.y
-		self:move(x, y, true)
-		if config.settings.tome.smooth_move > 0 then
-			self:resetMoveAnim()
-			self:setMoveAnim(ox, oy, 8, 5)
-		end
-
-		self:removeEffectsFilter({subtype={stun=true, daze=true, pin=true, pinned=true, pinning=true}}, 50)
-
-		self:project(tg, self.x, self.y, function(px, py, tg, self)
-			local target = game.level.map(px, py, Map.ACTOR)
-			if target and target ~= self then
-				local hit = self:attackTarget(target, nil, 2, true)
-				if hit and target:canBe("stun") then
-					target:setEffect(target.EFF_DAZED, 3, {})
-				end
-			end
-		end)
-
-		return true
-	end,
-	info = function(self, t)
-		return ([[You accurately jump to the target and deal 200%% weapon damage to all foes within radius 1 on impact as well as dazing them for 3 turns.
-		When you jump you free yourself from any stun, daze and pinning effects.]])
-		:format()
-	end,
-}
-
 uberTalent{
 	name = "Crafty Hands",
 	mode = "passive",
diff --git a/game/modules/tome/data/talents/uber/str.lua b/game/modules/tome/data/talents/uber/str.lua
index dcd9db3b0a32d3d3634c8d17dc8bef955c782d88..294bc725e28e76e7e2635e2d5964f71d9ddf326f 100644
--- a/game/modules/tome/data/talents/uber/str.lua
+++ b/game/modules/tome/data/talents/uber/str.lua
@@ -18,18 +18,62 @@
 -- darkgod@te4.org
 
 uberTalent{
-	name = "Flexible Combat",
-	mode = "passive",
-	on_learn = function(self, t)
-		self:attr("unharmed_attack_on_hit", 1)
-		self:attr("show_gloves_combat", 1)
+	name = "Giant Leap",
+	mode = "activated",
+	require = { special={desc="Have dealt over 50000 damage with any weapon or unarmed", fct=function(self) return
+		self.damage_log and (
+			(self.damage_log.weapon.twohanded and self.damage_log.weapon.twohanded >= 50000) or
+			(self.damage_log.weapon.shield and self.damage_log.weapon.shield >= 50000) or
+			(self.damage_log.weapon.dualwield and self.damage_log.weapon.dualwield >= 50000) or
+			(self.damage_log.weapon.other and self.damage_log.weapon.other >= 50000)
+		)
+	end} },
+	cooldown = 12,
+	radius = 1,
+	range = 10,
+	is_melee = true,
+	requires_target = true,
+	tactical = { CLOSEIN = 2, ATTACKAREA = { weapon = 2 }, DISABLE = { stun = 1 } },
+	target = function(self, t)
+		return {type="ball", range=self:getTalentRange(t), selffire=false, radius=self:getTalentRadius(t)}
 	end,
-	on_unlearn = function(self, t)
-		self:attr("unharmed_attack_on_hit", -1)
-		self:attr("show_gloves_combat", -1)
+	action = function(self, t)
+		local tg = self:getTalentTarget(t)
+		local x, y, target = self:getTarget(tg)
+		if not x or not y then return nil end
+		local _ _, x, y = self:canProject(tg, x, y)
+
+		if game.level.map(x, y, Map.ACTOR) then
+			x, y = util.findFreeGrid(x, y, 1, true, {[Map.ACTOR]=true})
+			if not x then return end
+		end
+
+		if game.level.map:checkAllEntities(x, y, "block_move") then return end
+
+		local ox, oy = self.x, self.y
+		self:move(x, y, true)
+		if config.settings.tome.smooth_move > 0 then
+			self:resetMoveAnim()
+			self:setMoveAnim(ox, oy, 8, 5)
+		end
+
+		self:removeEffectsFilter({subtype={stun=true, daze=true, pin=true, pinned=true, pinning=true}}, 50)
+
+		self:project(tg, self.x, self.y, function(px, py, tg, self)
+			local target = game.level.map(px, py, Map.ACTOR)
+			if target and target ~= self then
+				local hit = self:attackTarget(target, nil, 2, true)
+				if hit and target:canBe("stun") then
+					target:setEffect(target.EFF_DAZED, 3, {})
+				end
+			end
+		end)
+
+		return true
 	end,
 	info = function(self, t)
-		return ([[Each time that you make a melee attack you have a 60%% chance to execute an additional unarmed strike.]])
+		return ([[You accurately jump to the target and deal 200%% weapon damage to all foes within radius 1 on impact as well as dazing them for 3 turns.
+		When you jump you free yourself from any stun, daze and pinning effects.]])
 		:format()
 	end,
 }
@@ -142,12 +186,12 @@ uberTalent{
 		)
 	end} },
 	action = function(self, t)
-		self:setEffect(self.EFF_IRRESISTIBLE_SUN, 6, {dam=50 + self:getStr() * 1.7})
+		self:setEffect(self.EFF_IRRESISTIBLE_SUN, 8, {dam=35 + self:getStr() * 1.3})
 		return true
 	end,
 	info = function(self, t)
-		local dam = (50 + self:getStr() * 1.7) / 3
-		return ([[For 6 turns you gain the mass and power of a star, drawing all creatures within radius 5 toward you and dealing %0.2f fire, %0.2f light and %0.2f physical damage to all foes.
+		local dam = (35 + self:getStr() * 1.3) / 3
+		return ([[For 8 turns you gain the mass and power of a star, drawing all creatures within radius 5 toward you and dealing %0.2f fire, %0.2f light and %0.2f physical damage to all foes and reducing their damage dealt by 30%%.
 		Foes closer to you take up to 150%% damage.
 		The damage will increase with your Strength.]])
 		:format(damDesc(self, DamageType.FIRE, dam), damDesc(self, DamageType.LIGHT, dam), damDesc(self, DamageType.PHYSICAL, dam))
diff --git a/game/modules/tome/data/talents/uber/wil.lua b/game/modules/tome/data/talents/uber/wil.lua
index 82b5852e843310b6e1dcb9142d0102b053048487..f66ac24bf71ce579e54d435585329cd6277a4cb5 100644
--- a/game/modules/tome/data/talents/uber/wil.lua
+++ b/game/modules/tome/data/talents/uber/wil.lua
@@ -41,13 +41,23 @@ uberTalent{
 	name = "Meteoric Crash",
 	mode = "passive",
 	cooldown = 15,
-	getDamage = function(self, t) return math.max(100 + self:combatSpellpower() * 5, 100 + self:combatMindpower() * 5) end,
+	getDamage = function(self, t) return math.max(50 + self:combatSpellpower() * 5, 50 + self:combatMindpower() * 5) end,
+	getLava = function(self, t) return math.max(self:combatSpellpower() + 30, self:combatMindpower() + 30) end,
 	require = { special={desc="Have witnessed a meteoric crash", fct=function(self) return game.state.birth.ignore_prodigies_special_reqs or self:attr("meteoric_crash") end} },
 	trigger = function(self, t, target)
 		self:startTalentCooldown(t)
 		local terrains = t.terrains or mod.class.Grid:loadList("/data/general/grids/lava.lua")
 		t.terrains = terrains -- cache
 
+		local lava_dam = t.getLava(self, t)
+		local dam = t.getDamage(self, t)
+		if self:combatMindCrit() > self:combatSpellCrit() then 
+			_dam = self:mindCrit(dam)
+			lava_dam = self:mindCrit(lava_dam)
+		else 
+			dam = self:spellCrit(dam)
+			lava_dam = self:spellCrit(lava_dam)
+		end
 		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
@@ -55,22 +65,26 @@ uberTalent{
 				game:playSoundNear(game.player, "talents/fireflash")
 
 				local grids = {}
-				for i = x-1, x+1 do for j = y-1, y+1 do
+				for i = x-3, x+3 do for j = y-3, y+3 do
 					local oe = game.level.map(i, j, engine.Map.TERRAIN)
-					if oe and not oe:attr("temporary") and
-					(core.fov.distance(x, y, i, j) < 1 or rng.percent(40)) and (game.level.map:checkEntity(i, j, engine.Map.TERRAIN, "dig") or game.level.map:checkEntity(i, j, engine.Map.TERRAIN, "grow")) then
+					-- Create "patchy" lava, but guarantee that the center tiles are lava
+					if oe and not oe:attr("temporary") and not oe.special and not game.level.map:checkEntity(i, j, engine.Map.TERRAIN, "block_move") and (core.fov.distance(x, y, i, j) < 1 or rng.percent(40)) then
 						local g = terrains.LAVA_FLOOR:clone()
 						g:resolve() g:resolve(nil, true)
 						game.zone:addEntity(game.level, g, "terrain", i, j)
 						grids[#grids+1] = {x=i,y=j,oe=oe}
 					end
 				end end
-				for i = x-1, x+1 do for j = y-1, y+1 do
+				for i = x-3, x+3 do for j = y-3, y+3 do
 					game.nicer_tiles:updateAround(game.level, i, j)
 				end end
 				for _, spot in ipairs(grids) do
 					local i, j = spot.x, spot.y
 					local g = game.level.map(i, j, engine.Map.TERRAIN)
+
+					g.mindam = lava_dam
+					g.maxdam = lava_dam
+					g.faction = src.faction -- Don't hit self or allies
 					g.temporary = 8
 					g.x = i g.y = j
 					g.canAct = false
@@ -89,9 +103,9 @@ uberTalent{
 					game.level:addEntity(g)
 				end
 
-				src:project({type="ball", radius=2, selffire=false}, x, y, engine.DamageType.FIRE, dam/2)
-				src:project({type="ball", radius=2, selffire=false}, x, y, engine.DamageType.PHYSICAL, dam/2)
-				src:project({type="ball", radius=2, selffire=false}, x, y, function(px, py)
+				src:project({type="ball", radius=2, selffire=false, friendlyfire=false}, x, y, engine.DamageType.FIRE, dam/2)
+				src:project({type="ball", radius=2, selffire=false, friendlyfire=false}, x, y, engine.DamageType.PHYSICAL, dam/2)
+				src:project({type="ball", radius=2, selffire=false, friendlyfire=false}, x, y, function(px, py)
 					local target = game.level.map(px, py, engine.Map.ACTOR)
 					if target then
 						if target:canBe("stun") then
@@ -117,9 +131,11 @@ uberTalent{
 	info = function(self, t)
 		local dam = t.getDamage(self, t)/2
 		return ([[When casting damaging spells or mind attacks, the release of your willpower can call forth a meteor to crash down near your foes.
-		The affected area is turned into lava for 8 turns, and the crash itself will deal %0.2f fire and %0.2f physical damage.
-		The meteor also stuns affected creatures for 3 turns. The damage scales with your Spellpower or Mindpower.]])
-		:format(damDesc(self, DamageType.FIRE, dam), damDesc(self, DamageType.PHYSICAL, dam))
+		The meteor deals %0.2f fire and %0.2f physical damage in radius 2 and stuns enemies for 3 turns.
+		Lava is created in radius 3 around the impact dealing %0.2f fire damage per turn for 8 turns.
+		You and your allies take no damage from either effect.
+		The damage scales with your Spellpower or Mindpower.]])
+		:format(damDesc(self, DamageType.FIRE, dam), damDesc(self, DamageType.PHYSICAL, dam), damDesc(self, DamageType.FIRE, t.getLava(self, t)))
 	end,
 }
 
@@ -201,7 +217,7 @@ uberTalent{
 uberTalent{
 	name = "Unbreakable Will",
 	mode = "passive",
-	cooldown = 7,
+	cooldown = 5,
 	trigger = function(self, t)
 		self:startTalentCooldown(t)
 		game.logSeen(self, "#LIGHT_BLUE#%s's unbreakable will shrugs off the effect!", self.name:capitalize())
@@ -209,7 +225,7 @@ uberTalent{
 	end,
 	info = function(self, t)
 		return ([[Your will is so strong that you simply ignore mental effects used against you.
-		Warning: this has a cooldown.]])
+		This effect can only occur once every 5 turns.]])
 		:format()
 	end,
 }
diff --git a/game/modules/tome/data/timed_effects/magical.lua b/game/modules/tome/data/timed_effects/magical.lua
index ff075238d0a5876e39078e751e52c08244face97..a4ff1e6a4b502f2eb31809660d0ddd04f5185b33 100644
--- a/game/modules/tome/data/timed_effects/magical.lua
+++ b/game/modules/tome/data/timed_effects/magical.lua
@@ -2081,6 +2081,77 @@ newEffect{
 	end,
 }
 
+-- Endless Woes prodigy effects
+newEffect{
+	name = "WOEFUL_DISEASE", image = "talents/weakness_disease.png",
+	desc = "Woeful Disease",
+	long_desc = function(self, eff) return ("The target is infected by a disease, reducing its strength, constitution, dexterity by %d and doing %0.2f blight damage per turn."):
+		format(eff.str, eff.con, eff.dex, eff.dam) end,
+	type = "magical",
+	subtype = {disease=true, blight=true},
+	status = "detrimental",
+	parameters = {str = 1, con = 1, dex = 1, dam = 0},
+	on_gain = function(self, err) return "#Target# is afflicted by a woeful disease!" end,
+	on_lose = function(self, err) return "#Target# is free from the woeful disease." end,
+	-- Damage each turn
+	on_timeout = function(self, eff)
+		if self:attr("purify_disease") then self:heal(eff.dam, eff.src)
+		else if eff.dam > 0 then DamageType:get(DamageType.BLIGHT).projector(eff.src, self.x, self.y, DamageType.BLIGHT, eff.dam, {from_disease=true})
+		end end
+	end,
+	activate = function(self, eff)
+		self:effectTemporaryValue(eff, "inc_stats", {
+			[Stats.STAT_STR] = math.floor(eff.str),
+			[Stats.STAT_CON] = math.floor(eff.con),
+			[Stats.STAT_DEX] = math.floor(eff.dex),
+		})
+	end,
+	deactivate = function(self, eff)
+	end,
+}
+
+newEffect{
+	name = "WOEFUL_DARKNESS", image = "effects/bane_blinded.png",
+	desc = "Woeful Darkness",
+	long_desc = function(self, eff) return ("The target is weakened and lost, all damage it does is reduced by %d%%."):format(eff.reduce) end,
+	type = "magical",
+	subtype = { darkness=true,},
+	status = "detrimental",
+	parameters = {power=10, reduce=5},
+	on_gain = function(self, err) return "#Target# is weakened by the darkness!", "+Woeful Darkness" end,
+	on_lose = function(self, err) return "#Target# looks more determined.", "-Woeful Darkness" end,
+	on_timeout = function(self, eff)
+
+	end,
+	activate = function(self, eff)
+		eff.tmpid = self:addTemporaryValue("numbed", eff.reduce)
+	end,
+	deactivate = function(self, eff)
+		self:removeTemporaryValue("numbed", eff.tmpid)
+	end,
+}
+
+newEffect{
+	name = "WOEFUL_CORROSION", image = "talents/acidic_skin.png",
+	desc = "Woeful Corrosion",
+	long_desc = function(self, eff) return ("The target has been splashed with acid, taking %0.2f acid damage per turn."):format(eff.dam) end,
+	type = "magical",
+	subtype = { acid=true,},
+	status = "detrimental",
+	parameters = {dam = 0},
+	on_gain = function(self, err) return "#Target# is covered in acid!" end,
+	on_lose = function(self, err) return "#Target# is free from the acid." end,
+	-- Damage each turn
+	on_timeout = function(self, eff)
+		DamageType:get(DamageType.ACID).projector(eff.src, self.x, self.y, DamageType.ACID, eff.dam)
+	end,
+	activate = function(self, eff)
+	end,
+	deactivate = function(self, eff)
+	end,
+}
+
+
 newEffect{
 	name = "EPIDEMIC", image = "talents/epidemic.png",
 	desc = "Epidemic",
@@ -2510,47 +2581,6 @@ newEffect{
 	end,
 }
 
-newEffect{
-	name = "ELEMENTAL_SURGE_ARCANE", image = "talents/elemental_surge.png",
-	desc = "Elemental Surge: Arcane",
-	long_desc = function(self, eff) return ("Spellcasting speed increased by 20%") end,
-	type = "magical",
-	subtype = { arcane=true },
-	status = "beneficial",
-	parameters = { },
-	activate = function(self, eff)
-		self:effectTemporaryValue(eff, "combat_spellspeed", 0.2)
-	end,
-}
-
-newEffect{
-	name = "ELEMENTAL_SURGE_COLD", image = "talents/elemental_surge.png",
-	desc = "Elemental Surge: Cold",
-	long_desc = function(self, eff) return ("Icy Skin: Physical damage reduced by 30%%, armor increased by %d, and deals %d ice damage when hit in melee."):format(eff.armor, eff.dam) end,
-	type = "magical",
-	subtype = { arcane=true },
-	status = "beneficial",
-	parameters = {physresist=30, armor=0, dam=100 },
-	activate = function(self, eff)
-		self:effectTemporaryValue(eff, "resists", {[DamageType.PHYSICAL]=eff.physresist})
-		self:effectTemporaryValue(eff, "combat_armor", eff.armor)
-		self:effectTemporaryValue(eff, "on_melee_hit", {[DamageType.ICE]=eff.dam})
-	end,
-}
-
-newEffect{
-	name = "ELEMENTAL_SURGE_LIGHTNING", image = "talents/elemental_surge.png",
-	desc = "Elemental Surge: Lightning",
-	long_desc = function(self, eff) return ("When hit you turn into pure lightning and reappear near where you where, ignoring the blow.") end,
-	type = "magical",
-	subtype = { arcane=true },
-	status = "beneficial",
-	parameters = { },
-	activate = function(self, eff)
-		self:effectTemporaryValue(eff, "phase_shift", 1)
-	end,
-}
-
 newEffect{
 	name = "VULNERABILITY_POISON", image = "talents/vulnerability_poison.png",
 	desc = "Vulnerability Poison",
@@ -2615,6 +2645,7 @@ newEffect{
 
 					if self:reactionToward(target) < 0 then
 						local dam = eff.dam * (1 + (5 - core.fov.distance(self.x, self.y, target.x, target.y)) / 8)
+						target:setEffect(target.EFF_WEIGHT_OF_THE_SUN, 2, {reduce = 30})  -- Quickly wears off when outside of AoE
 						DamageType:get(DamageType.FIRE).projector(self, target.x, target.y, DamageType.FIRE, dam/3)
 						DamageType:get(DamageType.LIGHT).projector(self, target.x, target.y, DamageType.LIGHT, dam/3)
 						DamageType:get(DamageType.PHYSICAL).projector(self, target.x, target.y, DamageType.PHYSICAL, dam/3)
@@ -2625,6 +2656,21 @@ newEffect{
 	end,
 }
 
+newEffect{
+	name = "WEIGHT_OF_THE_SUN", image = "talents/irresistible_sun.png",
+	desc = "Weight of the Sun",
+	long_desc = function(self, eff) return ("The target is struggling against immense gravity, all damage it does is reduced by %d%%."):format(eff.reduce) end,
+	type = "magical",
+	subtype = { sun=true,},
+	status = "detrimental",
+	parameters = {reduce=5},
+	on_gain = function(self, err) return "#Target# can barely stand!", "+Weight of the Sun" end,
+	on_lose = function(self, err) return "#Target# can move freely once more.", "-Weight of the Sun" end,
+	activate = function(self, eff)
+		self:effectTemporaryValue(eff, "numbed", eff.reduce)
+	end,
+}
+
 newEffect{
 	name = "TEMPORAL_FORM", image = "talents/temporal_form.png",
 	desc = "Temporal Form",
diff --git a/game/modules/tome/data/timed_effects/other.lua b/game/modules/tome/data/timed_effects/other.lua
index 9bb4d1bb66ec2c84dd72774f4d953390bcffc7bb..bb5ec91c1c2ed6c13fe2c3122c9895bcb48432a5 100644
--- a/game/modules/tome/data/timed_effects/other.lua
+++ b/game/modules/tome/data/timed_effects/other.lua
@@ -25,6 +25,74 @@ local Map = require "engine.Map"
 local Level = require "engine.Level"
 local Combat = require "mod.class.interface.Combat"
 
+newEffect{
+	name = "ELEMENTAL_SURGE_ARCANE", image = "talents/elemental_surge.png",
+	desc = "Elemental Surge: Arcane",
+	long_desc = function(self, eff) return ("Spell and mind speed increased by 30%") end,
+	type = "other",
+	subtype = {elemental = true },
+	status = "beneficial",
+	parameters = { },
+	activate = function(self, eff)
+		self:effectTemporaryValue(eff, "combat_spellspeed", 0.3)
+		self:effectTemporaryValue(eff, "combat_mindspeed", 0.3)
+	end,
+}
+
+-- Elemental Surge effects here to avoid interaction with duration increases since so many can be up at once
+newEffect{
+	name = "ELEMENTAL_SURGE_FIRE", image = "talents/elemental_surge.png",
+	desc = "Elemental Surge: Fire",
+	long_desc = function(self, eff) return ("All damage increased by %d%%"):format(eff.damage) end,
+	type = "other",
+	subtype = {elemental = true },
+	status = "beneficial",
+	parameters = {damage = 30 },
+	activate = function(self, eff)
+		self:effectTemporaryValue(eff,"inc_damage", {all = eff.damage})
+	end,
+}
+
+newEffect{
+	name = "ELEMENTAL_SURGE_COLD", image = "talents/elemental_surge.png",
+	desc = "Elemental Surge: Cold",
+	long_desc = function(self, eff) return ("Armor increased by %d, deals %d ice damage when hit in melee."):format(eff.armor, eff.dam) end,
+	type = "other",
+	subtype = {elemental = true },
+	status = "beneficial",
+	parameters = {armor=0, dam=100 },
+	activate = function(self, eff)
+		self:effectTemporaryValue(eff, "combat_armor", eff.armor)
+		self:effectTemporaryValue(eff, "on_melee_hit", {[DamageType.ICE]=eff.dam})
+	end,
+}
+
+newEffect{
+	name = "ELEMENTAL_SURGE_LIGHTNING", image = "talents/elemental_surge.png",
+	desc = "Elemental Surge: Lightning",
+	long_desc = function(self, eff) return ("Movement speed increased by %d%%."):format(eff.move) end,
+	type = "other",
+	subtype = {elemental = true },
+	status = "beneficial",
+	parameters = { move = 50},
+	activate = function(self, eff)
+		self:effectTemporaryValue(eff, "movement_speed", eff.move/100)
+	end,
+}
+
+newEffect{
+	name = "ELEMENTAL_SURGE_LIGHT", image = "talents/elemental_surge.png",
+	desc = "Elemental Surge: Light",
+	long_desc = function(self, eff) return ("All talent cooldowns reduced by %d%%."):format(eff.cooldown) end,
+	type = "other",
+	subtype = {elemental = true },
+	status = "beneficial",
+	parameters = {cooldown = 20 },
+	activate = function(self, eff)
+		self:effectTemporaryValue(eff, "talent_cd_reduction", {allpct = eff.cooldown / 100})
+	end,
+}
+
 newEffect{
 	name = "FLASH_SHIELD", image = "talents/flash_of_the_blade.png",
 	desc = "Protected by the Sun",
diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua
index 842a4841937c30b05b0792aa920e0cdd7001c1af..0d1cea1cecf2a94ec736ccb22580f0835a459ec5 100644
--- a/game/modules/tome/data/timed_effects/physical.lua
+++ b/game/modules/tome/data/timed_effects/physical.lua
@@ -2570,19 +2570,6 @@ newEffect{
 	end,
 }
 
-newEffect{
-	name = "ELEMENTAL_SURGE_NATURE", image = "talents/elemental_surge.png",
-	desc = "Elemental Surge: Nature",
-	long_desc = function(self, eff) return ("Immune to physical effects.") end,
-	type = "physical",
-	subtype = { status=true },
-	status = "beneficial",
-	parameters = { },
-	activate = function(self, eff)
-		self:effectTemporaryValue(eff, "spell_negative_status_effect_immune", 1)
-	end,
-}
-
 newEffect{
 	name = "STEAMROLLER", image = "talents/steamroller.png",
 	desc = "Steamroller",
diff --git a/game/modules/tome/dialogs/UberTalent.lua b/game/modules/tome/dialogs/UberTalent.lua
index c868a6188125f1288c0d366a8f653176dcfa3865..0002db2045d9cbff7e9d9d46c596e77294d769ae 100644
--- a/game/modules/tome/dialogs/UberTalent.lua
+++ b/game/modules/tome/dialogs/UberTalent.lua
@@ -75,7 +75,7 @@ function _M:generateList()
 	local cols = {}
 	local list = {}
 	for tid, t in pairs(self.actor.talents_def) do
-		if t.uber then
+		if t.uber and not t.not_listed then
 			cols[t.type[1]] = cols[t.type[1]] or {}
 			local c = cols[t.type[1]]
 			c[#c+1] = t