diff --git a/game/engines/default/engine/GameEnergyBased.lua b/game/engines/default/engine/GameEnergyBased.lua
index 9e49bcbaa506a98f2f71c558bbdb655fe7c4871f..bfdb984053c0ec550fe3bc43a10e9a386da32e24 100644
--- a/game/engines/default/engine/GameEnergyBased.lua
+++ b/game/engines/default/engine/GameEnergyBased.lua
@@ -72,9 +72,9 @@ function _M:tick()
 		self.level = mainlev
 	end
 
-	local arr = self.entities
+	local arr = table.clone(self.entities)
 	for i, e in pairs(arr) do
-		e = arr[i]
+		e = self.entities[i]
 		if e and e.act and e.energy then
 			if e.energy.value < self.energy_to_act then
 				e.energy.value = (e.energy.value or 0) + self.energy_per_tick * (e.energy.mod or 1) * (e.global_speed or 1)
@@ -97,19 +97,19 @@ function _M:tickLevel(level)
 	local arr = level.e_array
 
 	if level.last_iteration then
-		i = nil
-
-		for ii = 1, #arr do if arr[ii] == level.last_iteration.e then i = ii + 1 break end end
-
-		if not i then i = level.last_iteration.i + 1 end
+		i = level.last_iteration.i + 1
 
 		if i > #arr then i = 1 end
 		level.last_iteration = nil
 --		print("=====LEVEL", level.level, level.sublevel_id, "resuming tick loop at ", i, arr[i].name)
 	end
 
-	for i = i, #arr do
+	level.last_iteration = {}  -- mark as iterating
+	local iter = level.last_iteration
+	local finished = true
+	while i <= #arr do
 		e = arr[i]
+		iter.e, iter.i = e, i
 		if e and e.act and e.energy then
 			if e.actBase and e.energyBase then
 				if e.energyBase < self.energy_to_act then
@@ -131,12 +131,14 @@ function _M:tickLevel(level)
 --			print(">ENERGY", e.name, e.uid, "::", e.energy.value, self.paused, "::", e.player)
 
 			if self.can_pause and self.paused then
-				level.last_iteration = {i=i, e=e}
+				finished = false
 --				print("====LEVEL", level.level, level.sublevel_id, "pausing tick loop at ", i, e.name)
 				break
 			end
 		end
+		i = iter.i + 1
 	end
+	if finished then level.last_iteration = nil end
 end
 
 --- Called every game turns
diff --git a/game/engines/default/engine/Level.lua b/game/engines/default/engine/Level.lua
index c74c47fe74e2c60d36d4e41eeda33cd696ff52e7..959b67b6d325aae2167ebbdb274527cfa207387e 100644
--- a/game/engines/default/engine/Level.lua
+++ b/game/engines/default/engine/Level.lua
@@ -107,6 +107,9 @@ function _M:addEntity(e, after, no_error)
 		end
 		if pos then
 			table.insert(self.e_array, pos+1, e)
+			if self.last_iteration and self.last_iteration.i >= pos then
+				self.last_iteration.i = self.last_iteration.i + 1
+			end
 		else
 			table.insert(self.e_array, e)
 		end
@@ -126,12 +129,19 @@ function _M:removeEntity(e, force)
 
 	if not self.entities[e.uid] and not force then error("Entity "..e.uid.."("..(e.name or "???")..") not present on the level") end
 	self.entities[e.uid] = nil
+	local pos = nil
 	for i = 1, #self.e_array do
 		if self.e_array[i] == e then
-			table.remove(self.e_array, i)
+			pos = i
 			break
 		end
 	end
+	if pos then
+		if self.last_iteration and self.last_iteration.i >= pos then
+			self.last_iteration.i = self.last_iteration.i - 1
+		end
+		table.remove(self.e_array, pos)
+	end
 	game:removeEntity(e)
 
 	-- Tells it to delete itself if needed
diff --git a/game/engines/default/engine/UserChat.lua b/game/engines/default/engine/UserChat.lua
index d955a3cf8b6b2fcf7fd5483e28808d0e307d9b99..b40f8e9e2d12a770635a12072000c897810e88f9 100644
--- a/game/engines/default/engine/UserChat.lua
+++ b/game/engines/default/engine/UserChat.lua
@@ -253,7 +253,7 @@ function _M:event(e)
 			local text = ([[#{bold}#Thank you#{normal}# for you donation, your support means a lot for the continued survival of this game.
 
 Your current donation total is #LIGHT_GREEN#%0.2f euro#WHITE# which equals to #ROYAL_BLUE#%d voratun coins#WHITE# to use on te4.org.
-Your Item's Vault has #TEAL#%d slots#WHITE#.
+Your Item Vault has #TEAL#%d slots#WHITE#.
 
 Again, thank you, and enjoy Eyal!
 
diff --git a/game/engines/default/engine/ui/Numberbox.lua b/game/engines/default/engine/ui/Numberbox.lua
index 55c59e861e79bc7db954f0c79ee4c13fb234b442..7f177020bd55baa64aea6ccc8d77472c2235a79e 100644
--- a/game/engines/default/engine/ui/Numberbox.lua
+++ b/game/engines/default/engine/ui/Numberbox.lua
@@ -50,11 +50,11 @@ function _M:generate()
 	self.key:addIgnore("_DOWN", false)
 
 	self.key:addCommands{
-		_UP = function() self.first = false self:updateText(1) end,
-		_DOWN = function() self.first = false self:updateText(-1) end,
+		_UP = function() self:updateText(1) end,
+		_DOWN = function() self:updateText(-1) end,
 		__TEXTINPUT = function(c)
 			if self.first then self.first = false self.tmp = {} self.cursor = 1 end
-			if #self.tmp and (c == '-' or c == '0' or c == '1' or c == '2' or c == '3' or c == '4' or c == '5' or c == '6' or c == '7' or c == '8' or c == '9') then
+			if #self.tmp and ((self.cursor == 1 and c == '-') or (c >= '0' and c <= '9')) then
 				table.insert(self.tmp, self.cursor, c)
 				self.cursor = self.cursor + 1
 				self.scroll = util.scroll(self.cursor, self.scroll, self.max_display)
@@ -65,6 +65,7 @@ function _M:generate()
 end
 
 function _M:updateText(v)
+	self.first = false
 	local old = self.number
 	if not v then
 		self.number = self.tmp and tonumber(table.concat(self.tmp)) or 0
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index a357ad044d9d60869053ca6a3c76491cb4511bd6..6a029ff332a0f0dd64c7f1729a441ccd17d05f15 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -351,18 +351,18 @@ function _M:loaded()
 				if self.difficulty == self.DIFFICULTY_NIGHTMARE then
 					zone.base_level_range = table.clone(zone.level_range, true)
 					zone.specific_base_level.object = -10 -zone.level_range[1]
-					zone.level_range[1] = zone.level_range[1] * 1.5 + 2
-					zone.level_range[2] = zone.level_range[2] * 1.5 + 2
+					zone.level_range[1] = zone.level_range[1] * 1.5 + 0
+					zone.level_range[2] = zone.level_range[2] * 1.5 + 0
 				elseif self.difficulty == self.DIFFICULTY_INSANE then
 					zone.base_level_range = table.clone(zone.level_range, true)
 					zone.specific_base_level.object = -10 -zone.level_range[1]
-					zone.level_range[1] = zone.level_range[1] * 1.5 + 3
-					zone.level_range[2] = zone.level_range[2] * 1.5 + 3
+					zone.level_range[1] = zone.level_range[1] * 1.5 + 1
+					zone.level_range[2] = zone.level_range[2] * 1.5 + 1
 				elseif self.difficulty == self.DIFFICULTY_MADNESS then
 					zone.base_level_range = table.clone(zone.level_range, true)
 					zone.specific_base_level.object = -10 -zone.level_range[1]
-					zone.level_range[1] = zone.level_range[1] * 2.5 + 6
-					zone.level_range[2] = zone.level_range[2] * 2.5 + 6
+					zone.level_range[1] = zone.level_range[1] * 2.5 + 1
+					zone.level_range[2] = zone.level_range[2] * 2.5 + 1
 				end
 			end
 		end,
diff --git a/game/modules/tome/class/GameState.lua b/game/modules/tome/class/GameState.lua
index af3d73e19b147d9abc0aa02f214143098f378548..d258abc85620ab20fe4f4c7d2bfaa46784bdf8b8 100644
--- a/game/modules/tome/class/GameState.lua
+++ b/game/modules/tome/class/GameState.lua
@@ -147,15 +147,15 @@ function _M:zoneCheckBackupGuardian()
 		if game.difficulty == game.DIFFICULTY_NIGHTMARE then
 			game.zone.base_level_range = table.clone(game.zone.level_range, true)
 			game.zone.specific_base_level.object = -10 -game.zone.base_level
-			game.zone.base_level = game.zone.base_level * 1.5 + 2
+			game.zone.base_level = game.zone.base_level * 1.5 + 0
 		elseif game.difficulty == game.DIFFICULTY_INSANE then
 			game.zone.base_level_range = table.clone(game.zone.level_range, true)
 			game.zone.specific_base_level.object = -10 -game.zone.base_level
-			game.zone.base_level = game.zone.base_level * 1.5 + 3
+			game.zone.base_level = game.zone.base_level * 1.5 + 1
 		elseif game.difficulty == game.DIFFICULTY_MADNESS then
 			game.zone.base_level_range = table.clone(game.zone.level_range, true)
 			game.zone.specific_base_level.object = -10 -game.zone.base_level
-			game.zone.base_level = game.zone.base_level * 2.5 + 6
+			game.zone.base_level = game.zone.base_level * 2.5 + 1
 		end
 		if data.action then data.action(false) end
 	end
diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua
index db48040123a67a77e48d004e62f796e820766173..cf65044d29d3d595a0ba1b38a2ca05bff59cc13e 100644
--- a/game/modules/tome/class/Object.lua
+++ b/game/modules/tome/class/Object.lua
@@ -760,10 +760,6 @@ function _M:getTextualDesc(compare_with, use_actor)
 			desc:add("Accuracy is based on willpower for this weapon.", true)
 		end
 
-		if combat.is_psionic_focus then
-			desc:add("This weapon will act as a psionic focus.", true)
-		end
-
 		compare_fields(combat, compare_with, field, "atk", "%+d", "Accuracy: ", 1, false, false, add_table)
 		compare_fields(combat, compare_with, field, "apr", "%+d", "Armour Penetration: ", 1, false, false, add_table)
 		compare_fields(combat, compare_with, field, "physcrit", "%+.1f%%", "Physical crit. chance: ", 1, false, false, add_table)
diff --git a/game/modules/tome/data/birth/classes/corrupted.lua b/game/modules/tome/data/birth/classes/corrupted.lua
index 9aac4439917aeb046bc006b5c8eb031f2357e1a0..92ad67b6ba0a083d69a6a09184ef137d01694fdd 100644
--- a/game/modules/tome/data/birth/classes/corrupted.lua
+++ b/game/modules/tome/data/birth/classes/corrupted.lua
@@ -73,6 +73,7 @@ newBirthDescriptor{
 		["corruption/bone"]={true, 0.3},
 		["corruption/torment"]={true, 0.3},
 		["corruption/vim"]={true, 0.3},
+		["corruption/rot"]={false, 0.3},
 	},
 	talents = {
 		[ActorTalents.T_CORRUPTED_STRENGTH] = 1,
@@ -139,4 +140,4 @@ newBirthDescriptor{
 			{type="armor", subtype="cloth", name="linen robe", autoreq=true, ego_chance=-1000}
 		},
 	},
-}
+}
\ No newline at end of file
diff --git a/game/modules/tome/data/birth/descriptors.lua b/game/modules/tome/data/birth/descriptors.lua
index 7dd9d0f54b9823615b449773dd3caa7321ff443f..7529606de155e9822a47a8fda21784490bca0159 100644
--- a/game/modules/tome/data/birth/descriptors.lua
+++ b/game/modules/tome/data/birth/descriptors.lua
@@ -193,7 +193,7 @@ newBirthDescriptor{
 	{
 		"#GOLD##{bold}#Nightmare mode#WHITE##{normal}#",
 		"Unfair game setting",
-		"All zone levels increased by 50% + 2",
+		"All zone levels increased by 50%",
 		"All creature talent levels increased by 30%",
 		"Player can earn Nightmare version of achievements if also playing in Roguelike or Adventure permadeath mode.",
 	},
@@ -216,7 +216,7 @@ newBirthDescriptor{
 	{
 		"#GOLD##{bold}#Insane mode#WHITE##{normal}#",
 		"Similar rules to Nightmare, but with more random bosses!",
-		"All zone levels increased by 50% + 3",
+		"All zone levels increased by 50% + 1",
 		"All creature talent levels increased by 50%",
 		"Rare creatures are far more frequent and random bosses start to appear",
 		"Nonrandom bosses will have randomly selected talents",
@@ -246,7 +246,7 @@ newBirthDescriptor{
 	{
 		"#GOLD##{bold}#Madness mode#WHITE##{normal}#",
 		"Absolutely unfair game setting.  You are really mentally ill and wish to get worse to play this mode!",
-		"All zone levels increased by 150% + 6",
+		"All zone levels increased by 150% + 1",
 		"All creature talent levels increased by 170%",
 		"Rare creatures are far more frequent and random bosses start to appear",
 		"Bosses will have randomly selected talents",
diff --git a/game/modules/tome/data/chats/last-hope-melinda-father.lua b/game/modules/tome/data/chats/last-hope-melinda-father.lua
index 15de07905f0de52c89ee51d3d20d42426ac31882..cad28bac6422e17ea53e21d2fd3b6bbf155927e3 100644
--- a/game/modules/tome/data/chats/last-hope-melinda-father.lua
+++ b/game/modules/tome/data/chats/last-hope-melinda-father.lua
@@ -88,7 +88,7 @@ newChat{ id="melinda",
 -- Flirting
 ------------------------------------------------------------------
 newChat{ id="scars",
-	text = [[Yes it has mostly healed, though I still do nightmares. I feel like something is still lurking.
+	text = [[Yes it has mostly healed, though I still do have nightmares. I feel like something is still lurking.
 Ah well, the bad dreams are still better than the fate you saved me from!]],
 	answers = {
 		{"Should I come across a way to help you during my travels, I will try to help.", quick_reply="Thank you, you are most welcome."},
@@ -121,7 +121,7 @@ My father gave me some funds so that I can take my future into my own hands. I h
 is_am and
 	[[I have seen how you fought those corruptors, the way you destroyed their magic. I want to learn to do the same, so that such horrors never happen again. To anyone.]]
 or (is_mage and
-	[[Or maybe, well I suppose I can trust you with this, I've always secretly dreamt of learning magic. Real magic I mean not alchemist tricks!
+	[[Or maybe, well I suppose I can trust you with this, I've always secretly dreamed of learning magic. Real magic I mean not alchemist tricks!
 I've learnt about a secret place, Angolwen, where I could learn it.]]
 or [[]])),
 	answers = (not is_am and not is_mage) and {
diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua
index af267f3c0870d4ef53476b42395be7b24cd49e49..4cdd8b1e2907ba1a77e461278669bf30fa9dc758 100644
--- a/game/modules/tome/data/damage_types.lua
+++ b/game/modules/tome/data/damage_types.lua
@@ -790,6 +790,9 @@ newDamageType{
 		if realdam > 0 and target and target:attr("diseases_spread_on_blight") and (not state or not state.from_disease) then
 			src:callTalent(src.T_EPIDEMIC, "do_spread", target, realdam)
 		end
+		if src and src.knowTalent and realdam > 0 and target and src:knowTalent(src.T_PESTILENT_BLIGHT) then
+			src:callTalent(src.T_PESTILENT_BLIGHT, "do_rot", target, realdam)
+		end
 		return realdam
 	end,
 	death_message = {"diseased", "poxed", "infected", "plagued", "debilitated by noxious blight before falling", "fouled", "tainted"},
@@ -3758,3 +3761,100 @@ newDamageType{
 		end
 	end,
 }
+
+newDamageType{
+	name = "wormblight", type = "WORMBLIGHT",
+	projector = function(src, x, y, type, dam, state)
+		state = initState(state)
+		useImplicitCrit(src, state)
+		local target = game.level.map(x, y, Map.ACTOR)
+		if target and target:attr("worm") then
+			target:heal(dam, src)
+			return -dam
+		elseif target then
+			DamageType:get(DamageType.BLIGHT).projector(src, x, y, DamageType.BLIGHT, dam)
+			return dam
+		end
+	end,
+}
+
+newDamageType{
+	name = "pestilent blight", type = "PESTILENT_BLIGHT",
+	text_color = "#GREEN#",
+	tdesc = function(dam, oldDam)
+		parens = ""
+		dam = dam or 0
+		if oldDam then
+			diff = dam - oldDam
+			if diff > 0 then
+				parens = (" (#LIGHT_GREEN#+%d%%#LAST#)"):format(diff)
+			elseif diff < 0 then
+				parens = (" (#RED#%d%%#LAST#)"):format(diff)
+			end
+		end
+		return ("* #LIGHT_GREEN#%d%%#LAST# chance to cause #GREEN#random blight#LAST#%s")
+			:format(dam, parens)
+	end,
+	projector = function(src, x, y, type, dam, state)
+		state = initState(state)
+		useImplicitCrit(src, state)
+		local target = game.level.map(x, y, Map.ACTOR)
+		if target then
+			game:delayedLogDamage(src, target, 0, ("%s<%d%%%% blight chance>#LAST#"):format(DamageType:get(type).text_color or "#aaaaaa#", dam), false)
+			if rng.percent(dam) then
+			local check = src:combatSpellpower()
+			if not src:checkHit(check, target:combatSpellResist()) then return end
+			local effect = rng.range(1, 4)
+			if effect == 1 then
+				if target:canBe("blind") and not target:hasEffect(target.EFF_BLINDED) then
+					target:setEffect(target.EFF_BLINDED, 2, {no_ct_effect=true} )
+				end
+			elseif effect == 2 then
+				if target:canBe("silence") and not target:hasEffect(target.EFF_SILENCED) then
+					target:setEffect(target.EFF_SILENCED, 2, {no_ct_effect=true})
+				end
+			elseif effect == 3 then
+				if target:canBe("disarm") and not target:hasEffect(target.EFF_DISARMED) then
+					target:setEffect(target.EFF_DISARMED, 2, {no_ct_effect=true})
+				end
+			elseif effect == 4 then
+				if target:canBe("pin") and not target:hasEffect(target.EFF_PINNED) then
+					target:setEffect(target.EFF_PINNED, 2, {no_ct_effect=true})
+				end
+			end
+		end
+		end
+	end,
+}
+
+newDamageType{
+	name = "blight poison", type = "BLIGHT_POISON", text_color = "#DARK_GREEN#",
+	projector = function(src, x, y, t, dam, poison, state)
+		state = initState(state)
+		useImplicitCrit(src, state)
+		local power
+		local realdam = DamageType:get(DamageType.BLIGHT).projector(src, x, y, DamageType.BLIGHT, dam.dam / 4)
+		local target = game.level.map(x, y, Map.ACTOR)
+		local chance = 0
+		if dam.poison == 4 then
+			chance = rng.range(1, 4)
+		elseif dam.poison == 3 then
+			chance = rng.range(1, 3)
+		elseif dam.poison == 2 then
+			chance = rng.range(1, 2)
+		else chance = 1
+		end
+		if target and target:canBe("poison") then
+			if chance == 1 then
+				target:setEffect(target.EFF_BLIGHT_POISON, 4, {src=src, power=dam.dam / 4, apply_power=dam.apply_power or (src.combatAttack and src:combatAttack()) or 0})
+			elseif chance == 2 then
+				target:setEffect(target.EFF_INSIDIOUS_BLIGHT, 4, {src=src, power=dam.dam / 4, heal_factor=dam.power*2, apply_power=dam.apply_power or (src.combatAttack and src:combatAttack()) or 0})
+			elseif chance == 3 then
+				target:setEffect(target.EFF_NUMBING_BLIGHT, 4, {src=src, power=dam.dam / 4, reduce=dam.power*1.2, apply_power=dam.apply_power or (src.combatAttack and src:combatAttack()) or 0})
+			elseif chance == 4 then
+				target:setEffect(target.EFF_CRIPPLING_BLIGHT, 4, {src=src, power=dam.dam / 4, fail=dam.power, apply_power=dam.apply_power or (src.combatAttack and src:combatAttack()) or 0})
+			end
+		end
+		return realdam
+	end,
+}
diff --git a/game/modules/tome/data/general/npcs/ogre.lua b/game/modules/tome/data/general/npcs/ogre.lua
index f08f59b30ad059c58fb29a796903405c1775f398..9837967afe450ed0a7b1b16fe0b29438a2d86dbc 100644
--- a/game/modules/tome/data/general/npcs/ogre.lua
+++ b/game/modules/tome/data/general/npcs/ogre.lua
@@ -61,7 +61,7 @@ newEntity{ base = "BASE_NPC_OGRE",
 
 newEntity{ base = "BASE_NPC_OGRE",
 	name = "ogre warmaster", color=colors.CRIMSON,
-	desc = [[A master of combat, she is impatient to test his newfound skills.]],
+	desc = [[A master of combat, she is impatient to test her newfound skills.]],
 	resolvers.nice_tile{tall=1}, female = 1,
 	level_range = {21, nil}, exp_worth = 1,
 	rarity = 4,
diff --git a/game/modules/tome/data/general/objects/egos/weapon.lua b/game/modules/tome/data/general/objects/egos/weapon.lua
index c96f3304e1a8a4f2d8c5c3fde954db6a8c2e4a68..89aa0b65ac918d7140b1dfb16ef3fbcb161a1f1e 100644
--- a/game/modules/tome/data/general/objects/egos/weapon.lua
+++ b/game/modules/tome/data/general/objects/egos/weapon.lua
@@ -846,7 +846,6 @@ newEntity{
 			[DamageType.MIND] = resolvers.mbonus_material(20, 5),
 			[DamageType.ITEM_MIND_GLOOM] = resolvers.mbonus_material(25, 10)
 		},
-		is_psionic_focus = true,
 	},
 	wielder = {
 		inc_stats = {
diff --git a/game/modules/tome/data/general/objects/scrolls.lua b/game/modules/tome/data/general/objects/scrolls.lua
index 6cc90d6103a04c00e472a40718a4219fb867acb9..f3f8dac4c0ea2944926c97dcaef8b615dcd170c1 100644
--- a/game/modules/tome/data/general/objects/scrolls.lua
+++ b/game/modules/tome/data/general/objects/scrolls.lua
@@ -47,7 +47,7 @@ newEntity{
 	material_level_min_only = true,
 
 	power_source = {nature=true},
-	use_simple = { name="inscribe your skin with the infusion.", use = function(self, who, inven, item)
+	use_simple = { name="inscribe your skin with the infusion", use = function(self, who, inven, item)
 		if who:setInscription(nil, self.inscription_talent, self.inscription_data, true, true, {obj=self, inven=inven, item=item}) then
 			return {used=true, id=true, destroy=true}
 		end
@@ -69,7 +69,7 @@ newEntity{
 	material_level_min_only = true,
 
 	power_source = {arcane=true},
-	use_simple = { name="inscribe your skin with the rune.", use = function(self, who, inven, item)
+	use_simple = { name="inscribe your skin with the rune", use = function(self, who, inven, item)
 		if who:setInscription(nil, self.inscription_talent, self.inscription_data, true, true, {obj=self, inven=inven, item=item}) then
 			return {used=true, id=true, destroy=true}
 		end
@@ -90,7 +90,7 @@ newEntity{
 	egos = "/data/general/objects/egos/infusions.lua", egos_chance = resolvers.mbonus(30, 5),
 
 	power_source = {arcane=true},
-	use_simple = { name="inscribe your skin with the taint.", use = function(self, who, inven, item)
+	use_simple = { name="inscribe your skin with the taint", use = function(self, who, inven, item)
 		if who:setInscription(nil, self.inscription_talent, self.inscription_data, true, true, {obj=self, inven=inven, item=item}) then
 			return {used=true, id=true, destroy=true}
 		end
diff --git a/game/modules/tome/data/general/objects/world-artifacts-far-east.lua b/game/modules/tome/data/general/objects/world-artifacts-far-east.lua
index 82b512fea4a7cc4ddfe8c422bcea7424e22dc7c2..0cb911b3274329ef424f00931c8d39c9a36e09ec 100644
--- a/game/modules/tome/data/general/objects/world-artifacts-far-east.lua
+++ b/game/modules/tome/data/general/objects/world-artifacts-far-east.lua
@@ -530,7 +530,7 @@ newEntity{ base = "BASE_KNIFE", define_as = "KINETIC_SPIKE",
 	},
 	max_power = 10, power_regen = 1,
 	use_power = {
-		name = function(self, who) return ("fires a bolt of kinetic force (range %d), dealing 150%% (physical) weapon damage"):format(self.use_power.range) end,
+		name = function(self, who) return ("fire a bolt of kinetic force (range %d), dealing 150%% (physical) weapon damage"):format(self.use_power.range) end,
 		power = 10,
 		range = 8,
 		use = function(self, who)
diff --git a/game/modules/tome/data/general/objects/world-artifacts.lua b/game/modules/tome/data/general/objects/world-artifacts.lua
index 468e672e75b80cf494c83b3a2c635b2686e6c954..27180bc70b8ffbc655549b70366c13622f7ae296 100644
--- a/game/modules/tome/data/general/objects/world-artifacts.lua
+++ b/game/modules/tome/data/general/objects/world-artifacts.lua
@@ -3497,7 +3497,7 @@ newEntity{ base = "BASE_GAUNTLETS",
 		self.use_power = {
 			name = function(self, who)
 				dam = who:damDesc(engine.DamageType.ARCANE, self.use_power.unnaturaldam(self, who))
-				return ("attempt to destroy all magic effects and sustains on creatures in a radius %d cone (unnatural creaters are additionally dealt %0.2f arcane damage and stunned)"):format(self.use_power.radius, dam)
+				return ("attempt to destroy all magic effects and sustains on creatures in a radius %d cone (unnatural creatures are additionally dealt %0.2f arcane damage and stunned)"):format(self.use_power.radius, dam)
 			end,
 			power = 100,
 			unnaturaldam = function(self, who) return 100+who:combatMindpower() end,
@@ -7366,6 +7366,7 @@ Their killing spree ended when one of the victims got lucky and managed to stab
 	require = { stat = { dex=42 }, },
 	cost = 400,
 	material_level = 4,
+	metallic = false,
 	combat = {
 		dam = 35,
 		apr = 10,
diff --git a/game/modules/tome/data/general/traps/temporal.lua b/game/modules/tome/data/general/traps/temporal.lua
index d93dcf0baee2e60f64f34b9f423751828a785044..4112404a718403291e2b76438bd770e162d39629 100644
--- a/game/modules/tome/data/general/traps/temporal.lua
+++ b/game/modules/tome/data/general/traps/temporal.lua
@@ -26,7 +26,7 @@ newEntity{ define_as = "TRAP_TEMPORAL",
 }
 
 newEntity{ base = "TRAP_TEMPORAL",
-	name = "disturbed pocket of time", auto_id = true, image = "trap/.png",
+	name = "disturbed pocket of time", auto_id = true, image = "trap/disturbed_pocket_of_time.png",
 	detect_power = resolvers.clscale(8,50,8),
 	disarm_power = resolvers.clscale(2,50,8),
 	rarity = 3, level_range = {1, 50},
@@ -39,7 +39,7 @@ newEntity{ base = "TRAP_TEMPORAL",
 }
 
 newEntity{ base = "TRAP_TEMPORAL",
-	name = "extremely disturbed pocket of time", auto_id = true, image = "trap/.png",
+	name = "extremely disturbed pocket of time", auto_id = true, image = "trap/extremely_disturbed_pocket_of_time.png",
 	detect_power = resolvers.clscale(8,50,8),
 	disarm_power = resolvers.clscale(2,50,8),
 	rarity = 6, level_range = {1, 50},
diff --git a/game/modules/tome/data/gfx/shockbolt/trap/disturbed_pocket_of_time.png b/game/modules/tome/data/gfx/shockbolt/trap/disturbed_pocket_of_time.png
new file mode 100644
index 0000000000000000000000000000000000000000..37f3b1d8470c9f91f538a3033a4d44a2925b541f
Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/trap/disturbed_pocket_of_time.png differ
diff --git a/game/modules/tome/data/gfx/shockbolt/trap/extremely_disturbed_pocket_of_time.png b/game/modules/tome/data/gfx/shockbolt/trap/extremely_disturbed_pocket_of_time.png
new file mode 100644
index 0000000000000000000000000000000000000000..77a613ad62d97e6ec4801f359234fd3dc0306ba6
Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/trap/extremely_disturbed_pocket_of_time.png differ
diff --git a/game/modules/tome/data/gfx/talents/infestation.png b/game/modules/tome/data/gfx/talents/infestation.png
new file mode 100644
index 0000000000000000000000000000000000000000..479ecae3eb676813d50d0a47ec3c79092047a1d8
Binary files /dev/null and b/game/modules/tome/data/gfx/talents/infestation.png differ
diff --git a/game/modules/tome/data/gfx/talents/pestilent_blight.png b/game/modules/tome/data/gfx/talents/pestilent_blight.png
new file mode 100644
index 0000000000000000000000000000000000000000..7a5fe809923401127535aa00bf58fe3d69d68fbf
Binary files /dev/null and b/game/modules/tome/data/gfx/talents/pestilent_blight.png differ
diff --git a/game/modules/tome/data/gfx/talents/worm_walk.png b/game/modules/tome/data/gfx/talents/worm_walk.png
new file mode 100644
index 0000000000000000000000000000000000000000..aa5ab0a3ba0a37d26888a72d31b66b4fef942977
Binary files /dev/null and b/game/modules/tome/data/gfx/talents/worm_walk.png differ
diff --git a/game/modules/tome/data/lore/elvala.lua b/game/modules/tome/data/lore/elvala.lua
index c47e2972dbe935b131ce51330fba891a5dfefff4..c34e64053325b2c94ba10621c4e18357e5773bd1 100644
--- a/game/modules/tome/data/lore/elvala.lua
+++ b/game/modules/tome/data/lore/elvala.lua
@@ -67,7 +67,7 @@ The burly man stared hard and long into Ephinias’ eyes, before turning to his
 
 Neira was the first to respond, and there was colour in her cheeks and emotion in her voice.  “I deem this Shaloren king remote and proud.  Sympathy he talks of whilst using our mother’s memory as a tool.  Understanding he proclaims, yet how can any truly know the subtlety behind these Sher’Tul relics?  Untouched they be for millennia, and their original power is still unknown.  What pride lets ye think ye can toy with them now?  It be folly to use a weapon that ye know not how to wield.”
 
-The room went quiet, and I could see Ephinias was silently fuming.  He was not accustomed to such open criticism.  Then Linaniil began to speak, and her voice was low and cool, yet all ears hung on her words.  “Many have been the works of pride over the years that have arisen in splendour.  Wherefore have come our great artworks, our grand cities, or the arcane weavings that shape our societies?  No meekness be found in their crafting.  There be no shame in acting out of pride, and we gain nothing from misplaced humility.  Too long have the powers of the Sher’Tul been left untapped by fearful and timid hearts.”  I could see then her eyes light up with excitement.  “Think of the glories we could unlock!  This war with the orcs would be but the beginning.  Great benefit could be brought to us all.  To leave these powers buried would be a crime, I say.”
+The room went quiet, and I could see Ephinias was silently fuming.  He was not accustomed to such open criticism.  Then Linaniil began to speak, and her voice was low and cool, yet all ears hung on her words.  “Many have been the works of pride over the years that have arisen in splendour.  Whence have come our great artworks, our grand cities, or the arcane weavings that shape our societies?  No meekness be found in their crafting.  There be no shame in acting out of pride, and we gain nothing from misplaced humility.  Too long have the powers of the Sher’Tul been left untapped by fearful and timid hearts.”  I could see then her eyes light up with excitement.  “Think of the glories we could unlock!  This war with the orcs would be but the beginning.  Great benefit could be brought to us all.  To leave these powers buried would be a crime, I say.”
 
 Turthel paused reflectively before nodding his head slowly, and it was clear that Linaniil’s words aligned better with his own thoughts.  “Very well,” he slowly announced, looking directly at Ephinias.  “We are with you.”  Neira stayed silent with brooding concern, but a flash of satisfaction crossed her sister’s eyes.]],
 	on_learn = function(who) world:gainAchievement("SPELLBLAZE_LORE") end,
diff --git a/game/modules/tome/data/lore/misc.lua b/game/modules/tome/data/lore/misc.lua
index 72ba5aa0f46ac012a4c17d82b22b8cc0c4ac9eca..9ee2c90069918fef5e17db28eb9ef69268f9fff0 100644
--- a/game/modules/tome/data/lore/misc.lua
+++ b/game/modules/tome/data/lore/misc.lua
@@ -31,7 +31,7 @@ Though armies would fall before the Spellblaze's might, though forests were raze
 
 How wrong they were. The Nalorën people, long secluded, were prepared to fend off any attacks on their land, but how could they hope to stop the land itself crumbling? Seeing their home literally tearing itself apart, plains and forests tumbling into the seas... For one brief, terrible moment, they beheld the true extent of the Spellblaze's power. Not only was it destroying the people of the world, but the world itself.
 
-The lands of the Narlorën had sunk beneath the waves.]],
+The lands of the Nalorën had sunk beneath the waves.]],
 }
 
 newLore{
diff --git a/game/modules/tome/data/lore/zigur.lua b/game/modules/tome/data/lore/zigur.lua
index 23f864ce216364fa07b0df29d3e27cfcadae4f70..800742405f0107c87ced9883d8d0f181e53dd533 100644
--- a/game/modules/tome/data/lore/zigur.lua
+++ b/game/modules/tome/data/lore/zigur.lua
@@ -75,9 +75,9 @@ One day however several people in the town fell ill from a mystery disease. Rumo
 
 I still remember how peaceful the evening had seemed when the townsfolk came for me. I was looking up at the brightness of the stars and the clear crescent summerglow moon, thinking of how I should restart my business, when I heard shouts from the distance. I saw the crowd appear from round the corner, advancing with their torches. I screamed for help, but they broke through my door, smashed through my windows and grabbed me. They dragged me outside and set their torches to my house. I was stripped to my skin and beaten heavily whilst they cursed and jeered, and even the man who had been my fiancé spat on my face and cursed me.
 
-They pulled me over grass and stone to the town square, and though half-blinded by the tears and my swollen flesh I could still make out the wooden stake they were erecting. I tried to cry out, I tried to beg for mercy, but their response was to hold me down by my throat and pull out my tongue with the blacksmith's tongs. As I coughed up blood they put me against the wooden pole and used barbed chords to tie my wrists to it above my head. The pain was unbearable and I passed out, and did not wake until I could feel the burning at my feet. The crowd were cheering as the smoke began to wrap around me, and they cheered louder with every pained scream I released from my lungs.
+They pulled me over grass and stone to the town square, and though half-blinded by the tears and my swollen flesh I could still make out the wooden stake they were erecting. I tried to cry out, I tried to beg for mercy, but their response was to hold me down by my throat and pull out my tongue with the blacksmith's tongs. As I coughed up blood they put me against the wooden pole and used barbed cords to tie my wrists to it above my head. The pain was unbearable and I passed out, and did not wake until I could feel the burning at my feet. The crowd were cheering as the smoke began to wrap around me, and they cheered louder with every pained scream I released from my lungs.
 
-I was choking from the smoke, barely able to breathe, and I could no longer feel my legs. Just when I felt my consciousness slipping away again I heard a commotion and a woman's voice shouted out, "She is no witch!" Then I saw some people coming towards me, and at the front was a halfling woman in dark armour. She rushed towards me, unheeding of the flames, and with a swift flick from her long sword she cut my bounds. She caught me as I fell and pulled me away from the fire, laying me down on the ground. I saw her soft face above mine as she whispered to me, "Tell me child, do you reject magic in all its forms?" I nodded my head - I could not say no to those bright eyes. She wiped the tears streaming down my face and kissed my forehead. "Then you will be safe - rest now." At once I passed out.
+I was choking from the smoke, barely able to breathe, and I could no longer feel my legs. Just when I felt my consciousness slipping away again I heard a commotion and a woman's voice shouted out, "She is no witch!" Then I saw some people coming towards me, and at the front was a halfling woman in dark armour. She rushed towards me, unheeding of the flames, and with a swift flick from her long sword she cut my bonds. She caught me as I fell and pulled me away from the fire, laying me down on the ground. I saw her soft face above mine as she whispered to me, "Tell me child, do you reject magic in all its forms?" I nodded my head - I could not say no to those bright eyes. She wiped the tears streaming down my face and kissed my forehead. "Then you will be safe - rest now." At once I passed out.
 
 When I awoke I was in another village in a soft bed. There were wrappings round my legs and bandages covering the cuts and bruises over the rest of my body. Healers tended to me, using natural remedies and herbal balms. The halfling woman would come and see me every day to check up on me. I longed for her every visit. She would speak to me sometimes. She explained how the townsfolk weren't to blame for their actions. It was all the mages' fault. They were corrupting the world, spreading chaos, and turning people against each other. I realised I was wrong for ever brewing potions - they were infested with arcane energies and could only bring harm to the world.
 
diff --git a/game/modules/tome/data/quests/lumberjack-cursed.lua b/game/modules/tome/data/quests/lumberjack-cursed.lua
index 5e2d0d921dbc0436bd35c001f4ff3a216426acfe..649a9e59c54756b6a374c191991e9b8314c9b941 100644
--- a/game/modules/tome/data/quests/lumberjack-cursed.lua
+++ b/game/modules/tome/data/quests/lumberjack-cursed.lua
@@ -60,7 +60,7 @@ on_status_change = function(self, who, status, sub)
 				game:addEntity(game.level, o, "object")
 				o:identify(true)
 				who:addObject(who.INVEN_INVEN, o)
-				require("engine.ui.Dialog"):simplePopup("Thanks", ("You saved %s of us, please take this has a reward. (They give you %s)"):format(self.lumberjacks_died == 0 and "all" or "most", o:getName{do_color=true}))
+				require("engine.ui.Dialog"):simplePopup("Thanks", ("You saved %s of us, please take this as a reward. (They give you %s)"):format(self.lumberjacks_died == 0 and "all" or "most", o:getName{do_color=true}))
 			end
 		end
 		who:setQuestStatus(self.id, engine.Quest.DONE)
diff --git a/game/modules/tome/data/talents/chronomancy/bow-threading.lua b/game/modules/tome/data/talents/chronomancy/bow-threading.lua
index e78a290bcf3740b267ec35ef12874a1de7771c2a..c0af01427b99164fec45d9f0a9a0247b089d52cc 100644
--- a/game/modules/tome/data/talents/chronomancy/bow-threading.lua
+++ b/game/modules/tome/data/talents/chronomancy/bow-threading.lua
@@ -19,6 +19,9 @@
 
 -- EDGE TODO: Particles, Timed Effect Particles
 
+
+local wardenPreUse = Talents.wardenPreUse
+
 newTalent{
 	name = "Arrow Stitching",
 	type = {"chronomancy/bow-threading", 1},
@@ -35,7 +38,7 @@ newTalent{
 	target = function(self, t)
 		return {type="bolt", range=self:getTalentRange(t), talent=t, friendlyfire=false, friendlyblock=false}
 	end,
-	on_pre_use = function(self, t, silent) if not doWardenPreUse(self, "bow") then if not silent then game.logPlayer(self, "You require a bow to use this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return wardenPreUse(self, t, silent, "bow") end,
 	passives = function(self, t, p)
 		self:talentTemporaryValue(p,"archery_pass_friendly", 1)
 	end,
@@ -117,7 +120,7 @@ newTalent{
 	target = function(self, t)
 		return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), talent=t, stop_block=true, friendlyfire=false, friendlyblock=false}
 	end,
-	on_pre_use = function(self, t, silent) if not doWardenPreUse(self, "bow") then if not silent then game.logPlayer(self, "You require a bow to use this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return wardenPreUse(self, t, silent, "bow") end,
 	archery_onreach = function(self, t, x, y)
 		game:onTickEnd(function() -- Let the arrow hit first
 			local tg = self:getTalentTarget(t)
@@ -212,7 +215,7 @@ newTalent{
 	target = function(self, t)
 		return {type="bolt", range=self:getTalentRange(t), talent=t, friendlyfire=false, friendlyblock=false}
 	end,
-	on_pre_use = function(self, t, silent) if not doWardenPreUse(self, "bow") then if not silent then game.logPlayer(self, "You require a bow to use this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return wardenPreUse(self, t, silent, "bow") end,
 	getDuration = function(self, t) return getExtensionModifier(self, t, 4) end,
 	getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 0.5, 1.3) end,
 	doEcho = function(self, t, eff)
diff --git a/game/modules/tome/data/talents/chronomancy/chronomancer.lua b/game/modules/tome/data/talents/chronomancy/chronomancer.lua
index 42ed00e1d5a52ee8153cf38a774249428fd82253..fc074c11461b3dd9ab17cdffd5fdceeb713c7147 100644
--- a/game/modules/tome/data/talents/chronomancy/chronomancer.lua
+++ b/game/modules/tome/data/talents/chronomancy/chronomancer.lua
@@ -217,16 +217,19 @@ end
 -- Checks for weapons in main and quickslot
 doWardenPreUse = function(self, weapon, silent)
 	if weapon == "bow" then
-		if not self:hasArcheryWeapon("bow") and not self:hasArcheryWeaponQS("bow") then
-			return false
+		local bow, ammo = self:hasArcheryWeapon("bow")
+		if not bow then
+			bow, ammo = self:hasArcheryWeaponQS("bow")
 		end
+		return bow, ammo
 	end
 	if weapon == "dual" then
-		if not self:hasDualWeapon() and not self:hasDualWeaponQS() then
-			return false
+		local mh, oh = self:hasDualWeapon()
+		if not mh then
+			mh, oh = self:hasDualWeaponQS()
 		end
+		return mh, oh
 	end
-	return true
 end
 
 -- Swaps weapons if needed
diff --git a/game/modules/tome/data/talents/chronomancy/temporal-archery.lua b/game/modules/tome/data/talents/chronomancy/temporal-archery.lua
index d4ba21b73f369d3737ecdcd362b03aaffae30c0c..4892e076abaa96778c8163ba067a8bafa68f0f8c 100644
--- a/game/modules/tome/data/talents/chronomancy/temporal-archery.lua
+++ b/game/modules/tome/data/talents/chronomancy/temporal-archery.lua
@@ -17,6 +17,8 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
+local archerPreUse = Talents.archerPreUse
+
 newTalent{
 	name = "Phase Shot",
 	type = {"chronomancy/temporal-archery", 1},
@@ -27,7 +29,7 @@ newTalent{
 	no_energy = "fake",
 	range = 10,
 	tactical = { ATTACK = {TEMPORAL = 2} },
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	requires_target = true,
 	action = function(self, t)
 		local tg = {type="bolt"}
@@ -53,7 +55,7 @@ newTalent{
 	no_energy = "fake",
 	range = 10,
 	tactical = { ATTACK = {PHYSICAL = 2} },
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	requires_target = true,
 	action = function(self, t)
 		local tg = {type="bolt"}
@@ -112,7 +114,7 @@ newTalent{
 	no_energy = true,
 	range = 10,
 	tactical = { ATTACK = {PHYSICAL = 2} },
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	requires_target = true,
 	action = function(self, t)
 		local old = self.energy.value
diff --git a/game/modules/tome/data/talents/corruptions/blight.lua b/game/modules/tome/data/talents/corruptions/blight.lua
index d932400bdc2d55e7809960ff2c3e21f617e3f42c..f88078734b19943e2ce6d3cb85168a6073f5a6c2 100644
--- a/game/modules/tome/data/talents/corruptions/blight.lua
+++ b/game/modules/tome/data/talents/corruptions/blight.lua
@@ -119,9 +119,12 @@ newTalent{
 	type = {"corruption/blight", 3},
 	require = corrs_req3,
 	points = 5,
-	cooldown = 10,
+	cooldown = 12,
 	vim = 12,
 	range = 10,
+	getResist = function(self, t) return math.ceil(self:combatTalentScale(t, 8, 35)) end,
+	getPercent = function(self, t) return self:combatTalentSpellDamage(t, 12, 45) end,	
+	getDamage = function(self, t) return self:combatTalentSpellDamage(t, 20, 60) end,
 	tactical = { ATTACK = {ACID = 2} },
 	requires_target = true,
 	action = function(self, t)
@@ -131,16 +134,16 @@ newTalent{
 		self:project(tg, x, y, function(px, py)
 			local target = game.level.map(px, py, Map.ACTOR)
 			if not target then return end
-			target:setEffect(target.EFF_CORROSIVE_WORM, 10, {src=self, dam=self:spellCrit(self:combatTalentSpellDamage(t, 10, 60)), explosion=self:spellCrit(self:combatTalentSpellDamage(t, 10, 230))})
+			target:setEffect(target.EFF_CORROSIVE_WORM, 6, {src = self, apply_power=self:combatSpellpower(), finaldam=t.getDamage(self, t), rate=t.getPercent(self, t) *0.01, power=t.getResist(self,t)})
 		end)
 		game:playSoundNear(self, "talents/slime")
 		return true
 	end,
 	info = function(self, t)
-		return ([[Infect your target with a corrosive worm that deals %0.2f acid damage per turn for 10 turns.
-		If the target dies while the worm is inside, it will explode, doing %0.2f acid damage in a radius of 4.
-		The damage will increase with your Spellpower, and can critical.]]):
-		format(damDesc(self, DamageType.ACID, self:combatTalentSpellDamage(t, 10, 60)), damDesc(self, DamageType.ACID, self:combatTalentSpellDamage(t, 10, 230)))
+		return ([[Infects the target with a corrosive worm for 6 turns that reduces blight and acid resistance by %d%% and feeds off damage taken.
+		When this effect ends or the target dies the worm will explode, dealing %d acid damage in a 4 radius ball. This damage will increase by %d%% of all damage taken while infected.
+		The damage dealt by the effect will increase with spellpower.]]):
+		format(t.getResist(self,t), t.getDamage(self, t), t.getPercent(self, t))
 	end,
 }
 
@@ -149,24 +152,35 @@ newTalent{
 	type = {"corruption/blight", 4},
 	require = corrs_req4,
 	points = 5,
-	vim = 36,
-	cooldown = 30,
+	vim = 28,
+	cooldown = 24,
 	range = 0,
 	radius = 4,
-	tactical = { ATTACKAREA = {NATURE = 2} },
+	tactical = { ATTACKAREA = {BLIGHT = 3}, DISABLE = 2 },
 	target = function(self, t)
 		return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t)}
 	end,
 	getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 6, 10)) end,
+	getDamage = function(self, t) return self:combatTalentSpellDamage(t, 12, 130) end,
+	getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 6, 10)) end,
+	getPower = function(self, t) return self:combatTalentSpellDamage(t, 10, 50) end,
+	getPoison = function(self,t) 
+		if self:getTalentLevel(t) >= 6 then return 4
+		elseif self:getTalentLevel(t) >= 4 then return 3
+		elseif self:getTalentLevel(t) >= 2 then return 2
+		else return 1 end
+	end,
 	action = function(self, t)
 		local duration = t.getDuration(self, t)
 		local radius = self:getTalentRadius(t)
-		local dam = self:spellCrit(self:combatTalentSpellDamage(t, 12, 130))
+		local dam = t.getDamage(self,t)
+		local poison = t.getPoison(self,t)
+		local power = t.getPower(self,t)
 		local actor = self
 		-- Add a lasting map effect
 		game.level.map:addEffect(self,
 			self.x, self.y, duration,
-			DamageType.POISON, {dam=dam, apply_power=actor:combatSpellpower()},
+			DamageType.BLIGHT_POISON, {dam=dam, power=power, poison=t.getPoison(self,t), apply_power=actor:combatSpellpower()},
 			radius,
 			5, nil,
 			MapEffect.new{color_br=20, color_bg=220, color_bb=70, effect_shader="shader_images/poison_effect.png"},
@@ -181,9 +195,12 @@ newTalent{
 		return true
 	end,
 	info = function(self, t)
-		return ([[A furious poison storm rages around the caster in a radius of %d for %d turns.  Each creature hit by the storm is poisoned for %0.2f nature damage over 6 turns.
-		Poisoning is cumulative; the longer they stay in the storm, the higher the poison damage they take.
-		The damage will increase with your Spellpower, and can critical.]]):
-		format(self:getTalentRadius(t), t.getDuration(self, t), damDesc(self, DamageType.NATURE, self:combatTalentSpellDamage(t, 12, 130)))
+		return ([[A furious storm of blighted poison rages around the caster in a radius of %d for %d turns.  Each creature hit by the storm takes %0.2f blight damage and is poisoned for %0.2f blight damage over 4 turns.
+		At talent level 2 you have a chance to inflict Insidious Blight, reducing healing factor by %d%%.
+		At talent level 4 you have a chance to inflict Numbing Blight, reducing damage dealt by %d%%.
+		At talent level 6 you have a chance to inflict Crippling Blight, giving a %d%% chance for talent failure.
+		The chance is evenly split between possible effects.
+		The damage and secondary effects will increase with your Spellpower.]]):
+		format(self:getTalentRadius(t), t.getDuration(self, t), damDesc(self, DamageType.BLIGHT, t.getDamage(self,t)/4), damDesc(self, DamageType.BLIGHT, t.getDamage(self,t)), t.getPower(self,t)*2, t.getPower(self,t)*1.2, t.getPower(self,t))
 	end,
-}
+}
\ No newline at end of file
diff --git a/game/modules/tome/data/talents/corruptions/corruptions.lua b/game/modules/tome/data/talents/corruptions/corruptions.lua
index 72542cb4b6b07077381604a208d947c66654ff04..9b488941246b89af74d18aa75df467761e41b34e 100644
--- a/game/modules/tome/data/talents/corruptions/corruptions.lua
+++ b/game/modules/tome/data/talents/corruptions/corruptions.lua
@@ -31,6 +31,7 @@ newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corrupti
 newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/blood", name = "blood", description = "Harness the power of blood, both your own and your foes'." }
 newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/blight", name = "blight", description = "Bring corruption and decay to all who oppose you." }
 newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/shadowflame", name = "Shadowflame", description = "Harness the power of the demonic shadowflame." }
+newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/rot", name = "rot", description = "Become one with rot and decay." }
 
 -- Generic requires for corruptions based on talent level
 corrs_req1 = {
@@ -108,3 +109,4 @@ load("/data/talents/corruptions/shadowflame.lua")
 load("/data/talents/corruptions/vim.lua")
 load("/data/talents/corruptions/torment.lua")
 load("/data/talents/corruptions/vile-life.lua")
+load("/data/talents/corruptions/rot.lua")
\ No newline at end of file
diff --git a/game/modules/tome/data/talents/corruptions/rot.lua b/game/modules/tome/data/talents/corruptions/rot.lua
new file mode 100644
index 0000000000000000000000000000000000000000..b8204c9e072745b20650e5b146ef301949714b43
--- /dev/null
+++ b/game/modules/tome/data/talents/corruptions/rot.lua
@@ -0,0 +1,348 @@
+-- ToME - Tales of Maj'Eyal
+-- Copyright (C) 2009 - 2014 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 = "Infectious Bite",
+	type = {"technique/other", 1},
+	points = 5,
+	message = "@Source@ bites blight poison into @target@.",
+	cooldown = 3,
+	tactical = { ATTACK = {BLIGHT = 2}, },
+	requires_target = true,
+	range = 1,
+	getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 1, 1.5) end,
+	getPoisonDamage = function(self, t) return self:combatTalentSpellDamage(t, 22, 200) end,
+	action = function(self, t)
+		
+		local tg = {type="hit", range=self:getTalentRange(t), talent=t}
+		local x, y, target = self:getTarget(tg)
+		if not x or not y or not target then return nil end
+		if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end
+		
+		local dam = t.getDamage(self,t)
+		local poison = t.getPoisonDamage(self,t)
+		
+		-- Hit?
+		local hitted = self:attackTarget(target, nil, dam, true)
+		
+		if hitted then
+			self:project({type="hit"}, target.x, target.y, DamageType.BLIGHT_POISON, {dam=poison, power=0, poison=1, apply_power=self:combatSpellpower()})
+		end
+		
+		return true
+	end,
+	info = function(self, t)
+		local damage = t.getDamage(self, t) * 100
+		local poison = t.getPoisonDamage(self, t)
+		return ([[Bite the target, dealing %d%% melee damage  
+		If the attack hits you'll inject blight poison into the target, dealing %0.2f blight damage and a further %0.2f blight damage over 4 turns.
+		The bonus damage improves with your Spellpower.]])
+		:format(damage, damDesc(self, DamageType.BLIGHT, poison/4), damDesc(self, DamageType.BLIGHT, poison) )
+	end
+}
+
+
+carrionworm = function(self, target, duration, x, y)
+	local m = mod.class.NPC.new{
+			type = "vermin", subtype = "worms",
+			display = "w", color=colors.SANDY_BROWN, image = "npc/vermin_worms_carrion_worm_mass.png",
+			name = "carrion worm mass", faction = self.faction,
+			desc = [[]],
+			autolevel = "none",
+			ai = "summoned", ai_real = "dumb_talented_simple", ai_state = { talent_in=1, },
+			stats = { str=10, dex=15, mag=3, con=3 },
+			level_range = {self.level, self.level}, exp_worth = 0,
+			global_speed_base = 1.0,
+
+			max_life = resolvers.rngavg(5,9),
+			size_category = 1,
+			cut_immune = 1,
+			blind_immune = 1,
+			life_rating = 6,
+			disease_immune = 1,
+			melee_project={[DamageType.PESTILENT_BLIGHT] = self:getTalentLevel(self.T_PESTILENT_BLIGHT)*4,},
+			resists = { [DamageType.PHYSICAL] = 50, [DamageType.ACID] = 100, [DamageType.BLIGHT] = 100, [DamageType.FIRE] = -50},
+			
+			combat_armor = 1, combat_def = 1,
+			combat = { dam=1, atk=100, apr=100 },
+			autolevel = "warriormage",
+			resolvers.talents{ 
+			[Talents.T_INFECTIOUS_BITE]=math.floor(self:getTalentLevelRaw(self.T_INFESTATION)),
+			},
+
+			
+			combat_spellpower = self:combatSpellpower(),
+
+			summoner = self, summoner_gain_exp=true,
+			summon_time = 10,
+			ai_target = {actor=target}
+			
+
+
+	}
+
+	m.unused_stats = 0
+	m.unused_talents = 0
+	m.unused_generics = 0
+	m.unused_talents_types = 0
+	m.no_inventory_access = true
+	m.no_points_on_levelup = true
+	m.save_hotkeys = true
+	m.ai_state = m.ai_state or {}
+	m.ai_state.tactic_leash = 100
+	-- Try to use stored AI talents to preserve tweaking over multiple summons
+	m.ai_talents = self.stored_ai_talents and self.stored_ai_talents[m.name] or {}
+	local damincrease = self:getTalentLevel(self.T_INFESTATION)*5
+	m.inc_damage.all = 0 + (damincrease or 0)
+	m.poolmult = (1 + self:getTalentLevel(self.T_WORM_WALK)*8/100 or 1)
+	m.on_die = function(self, src)
+				game.level.map:addEffect(self,
+				self.x, self.y, 5,
+				engine.DamageType.WORMBLIGHT, 0.6*self:combatSpellpower()*self.poolmult,
+					2,
+					5, nil,
+					engine.MapEffect.new{color_br=150, color_bg=255, color_bb=150, effect_shader="shader_images/poison_effect.png"}
+				)
+				game.logSeen(self, "%s exudes a corrupted gas as it dies.", self.name:capitalize())
+	end
+			
+	if game.party:hasMember(self) then
+		m.remove_from_party_on_death = true
+	end
+	m:resolve() m:resolve(nil, true)
+	m:forceLevelup(self.level)
+	game.zone:addEntity(game.level, m, "actor", x, y)
+	game.level.map:particleEmitter(x, y, 1, "summon")
+
+	-- Summons never flee
+	m.ai_tactic = m.ai_tactic or {}
+	m.ai_tactic.escape = 0
+	m.summon_time = 10
+
+	mod.class.NPC.castAs(m)
+	engine.interface.ActorAI.init(m, m)
+
+	return m
+end
+
+
+newTalent{
+	name = "Infestation",
+	type = {"corruption/rot", 1},
+	require = corrs_req_high1,
+	points = 5,
+	mode = "sustained",
+	sustain_vim = 40,
+	cooldown = 30,
+	getDamageReduction = function(self, t) 
+		return self:combatTalentLimit(t, 1, 0.1, 0.22)
+	end,
+	getDamagePct = function(self, t)
+		return self:combatTalentLimit(t, 0.11, 0.3, 0.15)
+	end,
+	getResist = function(self, t) return 5 * self:getTalentLevel(t) end,
+	getAffinity = function(self, t) return 4 * self:getTalentLevel(t) end,
+	activate = function(self, t)
+		local resist = t.getResist(self,t)
+		local affinity = t.getAffinity(self,t)
+		local ret = {
+					res = self:addTemporaryValue("resists", {[DamageType.BLIGHT]=resist, [DamageType.ACID]=resist}),
+					aff = self:addTemporaryValue("damage_affinity", {[DamageType.BLIGHT]=affinity}),
+					worm = self:addTemporaryValue("worm", 1),
+					}
+		return ret
+	end,
+	deactivate = function(self, t, p)
+		self:removeTemporaryValue("resists", p.res)
+		self:removeTemporaryValue("damage_affinity", p.aff)
+		self:removeTemporaryValue("worm", p.worm)
+		return true
+	end,
+	callbackOnHit = function(self, t, cb)
+		if ( cb.value > (t.getDamagePct(self, t) * self.max_life) ) then
+			local damageReduction = cb.value * t.getDamageReduction(self, t)
+			cb.value = cb.value - damageReduction
+			game.logPlayer(self, "#GREEN#A carrion worm mass bursts forth from your wounds, softening the blow and reducing damage taken by #ORCHID#" .. math.ceil(damageReduction) .. "#LAST#.")
+			local x, y = util.findFreeGrid(self.x, self.y, 10, true, {[Map.ACTOR]=true})
+			if not x then return nil end
+			
+				local m = carrionworm(self, self, 10, x, y)
+
+			end
+			return cb.value
+	end, 
+	info = function(self, t)
+	local resist = t.getResist(self,t)
+	local affinity = t.getAffinity(self,t)
+	local cap = t.getDamagePct(self,t)
+	local damage = t.getDamageReduction(self,t)	
+		return ([[Your body has become a mass of living corruption, increasing your blight and acid resistance by %d%%, blight affinity by %d%% and allowing you to heal from your carrion worm blight pools. On taking damage greater than %d%% of your maximum health, the damage will be reduced by %d%% and a carrion worm mass will burst forth onto an adjacent tile, attacking your foes for 10 turns.
+Also increases the damage dealt by your carrion worms by %d%% and grants them the Infectious Bite spell at level %d. Carrion worms fully inherit your Spellpower.]]):
+		format(resist, affinity, cap*100, damage*100, self:getTalentLevel(t)*5, self:getTalentLevelRaw(t))
+	end,
+}
+
+newTalent{
+	name = "Worm Walk",
+	type = {"corruption/rot", 2},
+	require = corrs_req_high2,
+	points = 5,
+	cooldown = function(self, t)
+		return math.ceil(self:combatTalentLimit(t, 4, 20, 8)) -- Limit > 4
+	end,
+	requires_target = true,
+	direct_hit = true,
+	range = function(self, t) return math.floor(self:combatTalentScale(t, 4, 9)) end,
+	getHeal = function(self, t) return self:combatTalentSpellDamage(t, 20, 100, 0.75)/100 end,
+	getVim = function(self, t) return 5 * self:getTalentLevel(t) end,
+	getDam = function(self, t) return self:combatTalentLimit(t, 4, 20, 10) end,
+	action = function(self, t)
+		local tg = {type="hit", range=self:getTalentRange(t), talent=t}
+		local tx, ty, target = self:getTarget(tg)
+		if not tx or not ty then return nil end
+		if target and target.summoner and target.summoner == self and target.name == "carrion worm mass" then
+			local didcrit = self:spellCrit(1)
+			self:incVim(didcrit * t.getVim(self, t))
+			self:attr("allow_on_heal", 1)
+			self:heal(didcrit * (t.getHeal(self, t)) * self.max_life, self)
+			self:attr("allow_on_heal", -1)
+
+			game.level.map:remove(self.x, self.y, Map.ACTOR)
+			target:die()
+			game.level.map(target.x, target.y, Map.ACTOR, self)
+			self.x, self.y, target.x, target.y = target.x, target.y, self.x, self.y
+
+			game.level.map:particleEmitter(tx, ty, 3, "circle", {empty_start=8, oversize=1, a=80, appear=8, limit_life=11, speed=5, img="green_demon_fire_circle", radius=3})
+			game.level.map:particleEmitter(tx, ty, 3, "circle", {oversize=1, a=80, appear=8, limit_life=11, speed=5, img="demon_fire_circle", radius=3})
+
+			game:playSoundNear(self, "talents/teleport")
+		else
+			local dam = t.getDam(self, t) * self.life / 100
+			local x, y = util.findFreeGrid(tx, ty, 10, true, {[Map.ACTOR]=true})
+			if not x then return nil end
+			local m = carrionworm(self, self, 10, x, y)
+			self:takeHit(dam, self, {source_talent=t})
+		end
+		return true
+	end,
+	info = function(self, t)
+		local range = self:getTalentRange(t)
+		local heal = t.getHeal(self, t) * 100
+		local vim = t.getVim(self, t)
+		local dam = t.getDam(self,t)
+		return ([[Gain the ability to merge and seperate carrion worm masses.
+If used on a worm mass, you merge with it, moving to it's location, healing you for %d%% of your maximum health, restoring %d vim, and destroying the mass.
+If used on another target, you sacrifice %d%% of your current health to create a worm mass at their location.
+Also increases the damage and healing of your carrion worm's blight pool by %d%%.]]):
+format (heal, vim, dam, self:getTalentLevel(t)*8)
+	end,
+}
+
+
+newTalent{
+	name = "Pestilent Blight",
+	type = {"corruption/rot",3},
+	require = corrs_req_high3,
+	points = 5,
+	mode = "passive",
+	cooldown = 6,
+	radius = function(self, t) return self:getTalentLevel(t) >= 4 and 1 or 0 end,
+	getChance = function(self, t) return self:combatTalentSpellDamage(t, 10, 60) end,
+	getDuration = function(self, t)  return math.floor(self:combatTalentScale(t, 2, 4)) end,
+	target = function(self, t)
+		return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), friendlyfire=false, talent=t}
+	end,
+	do_rot = function(self, t, target, dam)
+		local chance = t.getChance(self,t)
+		local dur = t.getDuration(self,t)
+		if not dam or type(dam) ~= "number" then return end
+		if rng.percent(chance) and not self:isTalentCoolingDown(t.id) then 
+				local tg = self:getTalentTarget(t)
+				self:project(tg, target.x, target.y, function(px, py, tg, self)
+					local target = game.level.map(px, py, Map.ACTOR)
+					if target then
+						local eff = rng.table{"blind", "silence", "disarm", "pin", }
+						if eff == "blind" and target:canBe("blind") then target:setEffect(target.EFF_BLINDED, dur, {apply_power=self:combatSpellpower(), no_ct_effect=true})
+							elseif eff == "silence" and target:canBe("silence") then target:setEffect(target.EFF_SILENCED, dur, {apply_power=self:combatSpellpower(), no_ct_effect=true})
+							elseif eff == "disarm" and target:canBe("disarm") then target:setEffect(target.EFF_DISARMED, dur, {apply_power=self:combatSpellpower(), no_ct_effect=true})
+							elseif eff == "pin" and target:canBe("pin") then target:setEffect(target.EFF_PINNED, dur, {apply_power=self:combatSpellpower(), no_ct_effect=true})
+						end
+					end
+				end)
+				self:startTalentCooldown(t.id)
+			end
+	end,
+info = function(self, t)
+	local chance = t.getChance(self,t)
+	local duration = t.getDuration(self,t)
+		return ([[You have a %d%% chance on dealing blight damage to cause the target to rot away, silencing, disarming, blinding or pinning them for %d turns. This effect has a cooldown.
+At talent level 4, this affects targets in a radius 1 ball.
+Your worms also have a %d%% chance to blind, silence, disarm or pin with their melee attacks, lasting 2 turns.
+The chance to apply this effect will increase with your Spellpower.]]):
+		format(chance, duration, self:getTalentLevel(t)*4)
+	end,
+}
+
+newTalent{
+	name = "Worm Rot",
+	type = {"corruption/rot", 4},
+	require = corrs_req_high4,
+	points = 5,
+	cooldown = 8,
+	vim = 10,
+	range = 6,
+	requires_target = true,
+	tactical = { ATTACK = { ACID = 1, BLIGHT = 1 }, DISABLE = 4 },
+	getBurstDamage = function(self, t) return self:combatTalentSpellDamage(t, 10, 150) end,
+	getDamage = function(self, t) return self:combatTalentSpellDamage(t, 10, 55) end,
+	proj_speed = 6,
+	spawn_carrion_worm = function (self, target, t)
+		local x, y = util.findFreeGrid(target.x, target.y, 10, true, {[Map.ACTOR]=true})
+		if not x then return nil end
+		local m = carrionworm(self, self, 10, x, y)
+		
+	end,
+	action = function(self, t)
+		local tg = {type="bolt", range=self:getTalentRange(t), talent=t, display={particle="bolt_slime"}}
+		local x, y = self:getTarget(tg)
+		if not x or not y then return nil end
+
+		self:project(tg, x, y, function(px, py)
+			local target = game.level.map(px, py, engine.Map.ACTOR)
+			if not target then return end
+			if target:canBe("disease") then
+				target:setEffect(target.EFF_WORM_ROT, 5, {src=self, dam=t.getDamage(self, t), burst=t.getBurstDamage(self, t), rot_timer = 5, apply_power=self:combatSpellpower()})
+			else
+				game.logSeen(target, "%s resists the worm rot!", target.name:capitalize())
+			end
+			game.level.map:particleEmitter(px, py, 1, "slime")
+		end)
+		game:playSoundNear(self, "talents/slime")
+
+		return true
+	end,
+	info = function(self, t)
+		local damage = t.getDamage(self, t)
+		local burst = t.getBurstDamage(self, t)
+		return ([[Infects the target with parasitic carrion worm larvae for 5 turns.  Each turn the disease will remove a beneficial physical effect and deal %0.2f acid and %0.2f blight damage.
+If not cleared after five turns it will inflict %0.2f blight damage as the larvae hatch, removing the effect but spawning a full grown carrion worm mass near the target's location.
+The damage dealt will increase with your Spellpower.]]):
+		format(damDesc(self, DamageType.ACID, (damage/2)), damDesc(self, DamageType.BLIGHT, (damage/2)), damDesc(self, DamageType.ACID, (burst)))
+	end,
+}
\ No newline at end of file
diff --git a/game/modules/tome/data/talents/cunning/called-shots.lua b/game/modules/tome/data/talents/cunning/called-shots.lua
index b91ad604ff6565b9b730d006f20222c195d03492..dcba9b7009769d166276403e062690f409d38e7e 100644
--- a/game/modules/tome/data/talents/cunning/called-shots.lua
+++ b/game/modules/tome/data/talents/cunning/called-shots.lua
@@ -13,15 +13,7 @@
 -- You should have received a copy of the GNU General Public License
 -- along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-local sling_equipped = function(self, silent)
-	if not self:hasArcheryWeapon("sling") then
-		if not silent then
-			game.logPlayer(self, "You must wield a sling!")
-		end
-		return false
-	end
-	return true
-end
+local archerPreUse = Talents.archerPreUse
 
 -- calc_all is so the info can show all the effects.
 local sniper_bonuses = function(self, calc_all)
@@ -89,7 +81,7 @@ newTalent {
 	cooldown = shot_cooldown,
 	requires_target = true,
 	range = archery_range,
-	on_pre_use = function(self, t, silent) return sling_equipped(self, silent) end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "sling") end,
 	pin_duration = function(self, t)
 		return math.floor(self:combatTalentScale(t, 1, 2))
 	end,
@@ -144,7 +136,7 @@ newTalent {
 	no_npc_use = true, -- Numbers overtuned to make sure the class has a satisfying high damage shot
 	requires_target = true,
 	range = archery_range,
-	on_pre_use = function(self, t, silent) return sling_equipped(self, silent) end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "sling") end,
 	getDistanceBonus = function(self, t, range)
 		return self:combatScale(range, -.5, 1, 2.5, 10, 0.25) --Slow scaling to allow for greater range variability
 	end,
@@ -207,7 +199,7 @@ newTalent {
 	cooldown = shot_cooldown,
 	requires_target = true,
 	range = archery_range,
-	on_pre_use = function(self, t, silent) return sling_equipped(self, silent) end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "sling") end,
 	damage_multiplier = function(self, t)
 		return self:combatTalentWeaponDamage(t, 0.3, 0.75)
 	end,
diff --git a/game/modules/tome/data/talents/cursed/endless-hunt.lua b/game/modules/tome/data/talents/cursed/endless-hunt.lua
index 8a8c9661792262094cbbc30dc85dc33f397db720..9fccf4dfb36faea68ad79bcd51fb4037be55d32d 100644
--- a/game/modules/tome/data/talents/cursed/endless-hunt.lua
+++ b/game/modules/tome/data/talents/cursed/endless-hunt.lua
@@ -252,6 +252,6 @@ newTalent{
 		return ([[Let hate fuel your movements. While active, you gain %d%% movement speed. The recklessness of your movement brings you bad luck (Luck -3).
 		Cleave, Repel and Surge cannot be active simultaneously, and activating one will place the others in cooldown.
 		The speed of your movements, combined with the balance and utility of two weapons, gives you %d extra Defense while dual-wielding.
-		Movement speed and dual-wielding Defense both increase with with the Willpower stat.]]):format(movementSpeedChange * 100, defenseChange)
+		Movement speed and dual-wielding Defense both increase with the Willpower stat.]]):format(movementSpeedChange * 100, defenseChange)
 	end,
 }
diff --git a/game/modules/tome/data/talents/cursed/predator.lua b/game/modules/tome/data/talents/cursed/predator.lua
index 74aced00d959e9af41b4752f470aef952a8ee430..a21677f92f69f19a3459489d5a651b60c8811d5b 100644
--- a/game/modules/tome/data/talents/cursed/predator.lua
+++ b/game/modules/tome/data/talents/cursed/predator.lua
@@ -170,7 +170,7 @@ newTalent{
 	end,
 	info = function(self, t)
 		local maxIncrease = t.getMaxIncrease(self, t)
-		return ([[You learn to mimic the strengths of your prey. Killing a marked sub-type raises your stats to match the strengths of the victim (up to a maximum of %d total points, subject to your current effectiveness). The effect lasts indefinitely, but only the effects of the lastest kill will be applied.
+		return ([[You learn to mimic the strengths of your prey. Killing a marked sub-type raises your stats to match the strengths of the victim (up to a maximum of %d total points, subject to your current effectiveness). The effect lasts indefinitely, but only the effects of the latest kill will be applied.
 		Each point in Mimic reduces the kill experience required to reach 100%% effectivess as a Predator.]]):format(maxIncrease)
 	end,
 }
diff --git a/game/modules/tome/data/talents/gifts/mindstar-mastery.lua b/game/modules/tome/data/talents/gifts/mindstar-mastery.lua
index 7be5f91b45058fbf82c10ed3ee22641536c54fed..9cf4035f7dd20c756efa01521da8a6cbe31d265e 100644
--- a/game/modules/tome/data/talents/gifts/mindstar-mastery.lua
+++ b/game/modules/tome/data/talents/gifts/mindstar-mastery.lua
@@ -64,7 +64,7 @@ newTalent{
 	info = function(self, t)
 		local damage = t.getDamage(self, t)
 		local inc = t.getPercentInc(self, t)
-		return ([[Channel your mental power through your wielded mindstars, generating psionic blades sprouting from the mindstars.
+		return ([[Channel your mental power through your wielded mindstars, generating psionic blades.
 		Mindstar psiblades have their damage modifiers (how much damage they gain from stats) multiplied by %0.2f, their armour penetration by %0.2f and mindpower, willpower and cunning by %0.2f.
 		Also increases Physical Power by %d and increases weapon damage by %d%% when using mindstars.]]):
 		format(t.getStatmult(self, t), t.getAPRmult(self, t), t.getPowermult(self, t), damage, 100 * inc) --I5
diff --git a/game/modules/tome/data/talents/misc/horrors.lua b/game/modules/tome/data/talents/misc/horrors.lua
index b5034ffc4c848c4a5280ea76cdb53b60b78d6f4b..e386092599dbec9d5c020e17616c7b7573990459 100644
--- a/game/modules/tome/data/talents/misc/horrors.lua
+++ b/game/modules/tome/data/talents/misc/horrors.lua
@@ -352,63 +352,6 @@ newTalent{
 		format(number, damDesc(self, DamageType.TEMPORAL, (damage)), damDesc(self, DamageType.TEMPORAL, (explosion/2)), damDesc(self, DamageType.PHYSICAL, (explosion/2)))
 	end,
 }
-
--- Worm that Walks Powers
-newTalent{
-	name = "Worm Rot",
-	type = {"corruption/horror", 1},
-	points = 5,
-	cooldown = 8,
-	vim = 10,
-	range = 6,
-	requires_target = true,
-	tactical = { ATTACK = { ACID = 1, BLIGHT = 1 }, DISABLE = 4 },
-	getBurstDamage = function(self, t) return self:combatTalentSpellDamage(t, 30, 300) end,
-	getDamage = function(self, t) return self:combatTalentSpellDamage(t, 5, 50) end,
-	getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 5, 9)) end,
-	proj_speed = 6,
-	target = function(self, t) return {type="bolt", range=self:getTalentRange(t), talent=t, display={particle="bolt_slime"}} end,
-	spawn_carrion_worm = function (self, target, t)
-		local x, y = util.findFreeGrid(target.x, target.y, 10, true, {[Map.ACTOR]=true})
-		if not x then return nil end
-
-		local worm = {type="vermin", subtype="worms", name="carrion worm mass"}
-		local list = mod.class.NPC:loadList("/data/general/npcs/vermin.lua")
-		local m = list.CARRION_WORM_MASS:clone()
-		if not m then return nil end
-
-		m:resolve() m:resolve(nil, true)
-		m.faction = self.faction
-		game.zone:addEntity(game.level, m, "actor", x, y)
-	end,
-	action = function(self, t)
-		local tg = self:getTalentTarget(t)
-		local x, y = self:getTarget(tg)
-		if not x or not y then return nil end
-
-		self:project(tg, x, y, function(px, py)
-			local target = game.level.map(px, py, engine.Map.ACTOR)
-			if not target then return end
-			if target:canBe("disease") then
-				target:setEffect(target.EFF_WORM_ROT, t.getDuration(self, t), {src=self, dam=t.getDamage(self, t), burst=t.getBurstDamage(self, t), rot_timer = 5, apply_power=self:combatSpellpower()})
-			else
-				game.logSeen(target, "%s resists the worm rot!", target.name:capitalize())
-			end
-			game.level.map:particleEmitter(px, py, 1, "slime")
-		end)
-		game:playSoundNear(self, "talents/slime")
-
-		return true
-	end,
-	info = function(self, t)
-		local duration = t.getDuration(self, t)
-		local damage = t.getDamage(self, t)
-		local burst = t.getBurstDamage(self, t)
-		return ([[Infects the target with parasitic carrion worm larvae for %d turns.  Each turn the disease will remove a beneficial physical effect and deal %0.2f acid and %0.2f blight damage.
-		If not cleared after five turns it will inflict %0.2f acid damage as the larvae hatch, removing the effect but spawning a full grown carrion worm mass near the target's location.]]):
-		format(duration, damDesc(self, DamageType.ACID, (damage/2)), damDesc(self, DamageType.BLIGHT, (damage/2)), damDesc(self, DamageType.ACID, (burst)))
-	end,
-}
 -------------------------------------------
 -- THE PUREQUESTION HORRORS AND ALL THAT --
 -------------------------------------------
diff --git a/game/modules/tome/data/talents/misc/inscriptions.lua b/game/modules/tome/data/talents/misc/inscriptions.lua
index 85fead55c4e7801777f3aeb720b8042b436093c6..d3d56ffec6aa7014b7fe59bee03d3d343e6623d3 100644
--- a/game/modules/tome/data/talents/misc/inscriptions.lua
+++ b/game/modules/tome/data/talents/misc/inscriptions.lua
@@ -520,8 +520,7 @@ newInscription{
 		local data = self:getInscriptionData(t.short_name)
 		local power = 100+5*self:getMag()
 		if data.power and data.inc_stat then power = data.power + data.inc_stat end
-		return ([[Activate the rune to create a protective shield absorbing and reflecting at most %d damage for %d turns.
-The effect will scale with your magic stat.]]):format(power, data.dur or 5)
+		return ([[Activate the rune to create a protective shield absorbing and reflecting at most %d damage for %d turns.]]):format(power, data.dur or 5)
 	end,
 	short_info = function(self, t)
 		local data = self:getInscriptionData(t.short_name)
@@ -877,7 +876,7 @@ newInscription{
 	end,
 	info = function(self, t)
 		local data = self:getInscriptionData(t.short_name)
-		return ([[Activate the rune to unleash a manasurge upon yourself, increasing mana regeneration by %d%% over %d turns and instantly restoring %d mana.
+		return ([[Activate the rune to unleash a manasurge upon yourself, increasing mana regeneration by %d%% for %d turns and instantly restoring %d mana.
 			Also when resting your mana will regenerate at 0.5 per turn.]]):format(data.mana + data.inc_stat, data.dur, (data.mana + data.inc_stat) / 20)
 	end,
 	short_info = function(self, t)
diff --git a/game/modules/tome/data/talents/psionic/psi-archery.lua b/game/modules/tome/data/talents/psionic/psi-archery.lua
index 779ba3b79c77d807fc137dbc1e7f0317c702c857..c1ae0ffccc491f2cc95322cff99a057ba933a6e1 100644
--- a/game/modules/tome/data/talents/psionic/psi-archery.lua
+++ b/game/modules/tome/data/talents/psionic/psi-archery.lua
@@ -17,6 +17,7 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
+local archerPreUse = Talents.archerPreUse
 
 newTalent{
 	name = "Guided Shot",
@@ -30,7 +31,7 @@ newTalent{
 	tactical = { ATTACK = { PHYSICAL = 2 } },
 	range = archery_range,
 	requires_target = true,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon("bow") then if not silent then game.logPlayer(self, "You require a bow for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "bow") end,
 	shot_boost = function(self, t) return self:combatTalentScale(t, 40, 80, 0.75) end,
 	use_psi_archery = function(self, t)
 		local pf_weapon = self:getInven("PSIONIC_FOCUS")[1]
@@ -64,7 +65,7 @@ newTalent{
 	range = archery_range,
 	requires_target = true,
 	tactical = { ATTACK = { PHYSICAL = 2 } },
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon("bow") then if not silent then game.logPlayer(self, "You require a bow for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "bow") end,
 	apr_boost = function(self, t) return math.floor(self:combatTalentScale(t, 20, 60)) end,
 	dam_mult = function(self, t)
 		return self:combatTalentWeaponDamage(t, 1.5, 2.5)
@@ -102,7 +103,7 @@ newTalent{
 	tactical = { ATTACK = { PHYSICAL = 2 } },
 	range = archery_range,
 	requires_target = true,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon("bow") then if not silent then game.logPlayer(self, "You require a bow for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "bow") end,
 	use_psi_archery = function(self, t)
 		local pf_weapon = self:getInven("PSIONIC_FOCUS")[1]
 		if pf_weapon and pf_weapon.archery then
diff --git a/game/modules/tome/data/talents/psionic/psionic.lua b/game/modules/tome/data/talents/psionic/psionic.lua
index a51d00e53dedd75b8c41c3861f38f0a8b361a123..cb7b1df94b2fca4e3e067372d76ae6008feb979f 100644
--- a/game/modules/tome/data/talents/psionic/psionic.lua
+++ b/game/modules/tome/data/talents/psionic/psionic.lua
@@ -152,17 +152,6 @@ psi_cun_high4 = {
 
 
 -- Useful definitions for psionic talents
-function getGemLevel(self)
-	local gem_level = 0
-	if self:getInven("PSIONIC_FOCUS") then
-		local tk_item = self:getInven("PSIONIC_FOCUS")[1]
-		if tk_item and ((tk_item.type == "gem") or (tk_item.subtype == "mindstar") or tk_item.combat.is_psionic_focus == true) then
-			gem_level = tk_item.material_level or 5
-		end
-	end
-	return gem_level
-end
-
 -- Cancel Thought Forms, we do this here because we use it for dreamscape and projection as well as thought-forms
 function cancelThoughtForms(self, id)
 	local forms = {self.T_TF_DEFENDER, self.T_TF_WARRIOR, self.T_TF_BOWMAN}
diff --git a/game/modules/tome/data/talents/spells/earth.lua b/game/modules/tome/data/talents/spells/earth.lua
index 1b2806e5c2d5b9e1f1ba11109ceb02abbb54fc08..9202a5d62d81674e9afa26ada32d21a39145aec6 100644
--- a/game/modules/tome/data/talents/spells/earth.lua
+++ b/game/modules/tome/data/talents/spells/earth.lua
@@ -86,7 +86,7 @@ newTalent{
 	info = function(self, t)
 		local damage = t.getDamage(self, t)
 		local nb = t.getDigs(self, t)
-		return ([[Fire a powerful beam of stone shaterring forces, digging out any walls in its path up to %d.
+		return ([[Fire a powerful beam of stone-shaterring force, digging out any walls in its path up to %d.
 		The beam also affect any creatures in its path, dealing %0.2f physical damage to all.
 		The damage will increase with your Spellpower.]]):
 		format(nb, damDesc(self, DamageType.PHYSICAL, damage))
diff --git a/game/modules/tome/data/talents/spells/stone-alchemy.lua b/game/modules/tome/data/talents/spells/stone-alchemy.lua
index 21c00a38209c066ea8062b3ff154a0cc8c8860d0..7e318fd72accc3a46c37fe61ea5b5b3f7296053a 100644
--- a/game/modules/tome/data/talents/spells/stone-alchemy.lua
+++ b/game/modules/tome/data/talents/spells/stone-alchemy.lua
@@ -58,7 +58,7 @@ newTalent{
 	end,
 	info = function(self, t)
 		return ([[Carve 40 to 80 alchemist gems out of a natural gemstone.
-		Alchemists gems are used for many other spells, and each gem type creates a different effect.]]):format()
+		Alchemist gems are used for many other spells, and each gem type creates a different effect.]]):format()
 	end,
 }
 
@@ -190,7 +190,7 @@ newTalent{
 	end,
 	info = function(self, t)
 		local range = t.getRange(self, t)
-		return ([[Crush 5 alchemists gems into dust to mark impassable terrain next to you. You immediately enter it and appear on the other side of the obstacle, up to %d grids away.]]):
+		return ([[Crush 5 alchemist gems into dust to mark impassable terrain next to you. You immediately enter it and appear on the other side of the obstacle, up to %d grids away.]]):
 		format(range)
 	end,
 }
diff --git a/game/modules/tome/data/talents/spells/stone.lua b/game/modules/tome/data/talents/spells/stone.lua
index e306d145b9fd542b0a7d3354873bf11aaa7902fa..e7d4042fca9e5170eb9a9a5aca87824f250c0e31 100644
--- a/game/modules/tome/data/talents/spells/stone.lua
+++ b/game/modules/tome/data/talents/spells/stone.lua
@@ -62,7 +62,7 @@ newTalent{
 			count = count + 1
 		end
 		local damage = t.getDamage(self, t)
-		return ([[Conjures %d missile shaped rocks that you target individually at any target or targets in range.  Each missile deals %0.2f physical damage, and an additional %0.2f bleeding damage every turn for 5 turns.
+		return ([[Conjures %d missile-shaped rocks that you target individually at any target or targets in range.  Each missile deals %0.2f physical damage, and an additional %0.2f bleeding damage every turn for 5 turns.
 		At talent level 5, you can conjure one additional missile.
 		The damage will increase with your Spellpower.]]):format(count,damDesc(self, DamageType.PHYSICAL, damage/2), damDesc(self, DamageType.PHYSICAL, damage/12))
 	end,
diff --git a/game/modules/tome/data/talents/spells/water.lua b/game/modules/tome/data/talents/spells/water.lua
index 5cec5a193b4608404bc3600339bc43efdb60165b..98fa86b5690759777e52a81220927d998e0d6b79 100644
--- a/game/modules/tome/data/talents/spells/water.lua
+++ b/game/modules/tome/data/talents/spells/water.lua
@@ -152,7 +152,7 @@ newTalent{
 		local radius = self:getTalentRadius(t)
 		return ([[A wall of water rushes out from the caster with an initial radius of 1, increasing 1 per turn to a maximum eventual radius of %d, doing %0.2f cold damage and %0.2f physical damage to all inside, as well as knocking back targets each turn.
 		The tidal wave lasts for %d turns.
-		All creatures hit gain the wet effect which reduces their stun/freeze resistance by half of their value and interracts with other cold spells.
+		All creatures hit gain the wet effect which reduces their stun/freeze resistance by half of their value and interacts with other cold spells.
 		The damage and duration will increase with your Spellpower.]]):
 		format(radius, damDesc(self, DamageType.COLD, damage/2), damDesc(self, DamageType.PHYSICAL, damage/2), duration)
 	end,
diff --git a/game/modules/tome/data/talents/techniques/archery.lua b/game/modules/tome/data/talents/techniques/archery.lua
index c98639a121f26697621f54abdbb1b986270e25eb..7e6ba313b118d7203f4adc79178cda7b1fb58d85 100644
--- a/game/modules/tome/data/talents/techniques/archery.lua
+++ b/game/modules/tome/data/talents/techniques/archery.lua
@@ -18,6 +18,46 @@
 -- darkgod@te4.org
 
 -- Default archery attack
+
+local weaponCheck = function(self, weapon, ammo, silent, weapon_type)
+	if not weapon then
+		if not silent then
+			-- ammo contains error message
+			game.logPlayer(self, ({
+				["disarmed"] = "You are currently disarmed and cannot use this talent.",
+				["no shooter"] = "You require a missile weapon to use this talent.",
+				["no ammo"] = "You require ammo to use this talent.",
+				["bad ammo"] = "Your ammo type does not match your weapon type.",
+				["bad type"] = ("You require a %s to use this talent."):format(weapon_type or "bow"), --  warden hack
+			})[ammo] or "You require a bow or sling and ammo for this talent.")
+		end
+		return false
+	else
+		local infinite = ammo and ammo.infinite or self:attr("infinite_ammo")
+		if not ammo or (ammo.combat.shots_left <= 0 and not infinite) then
+			if not silent then game.logPlayer(self, "You do not have enough ammo left!") end
+			return false
+		end
+	end
+	return true
+end
+
+local archerPreUse = function(self, t, silent, weapon_type)
+	local weapon, ammo = self:hasArcheryWeapon(weapon_type)
+	return weaponCheck(self, weapon, ammo, silent, weapon_type)
+end
+
+local wardenPreUse = function(self, t, silent, weapon_type)
+	local weapon, ammo = self:hasArcheryWeapon(weapon_type)
+	if self:attr("warden_swap") and not weapon and weapon_type == nil or weapon_type == "bow" then
+		weapon, ammo = doWardenPreUse(self, "bow")
+	end
+	return weaponCheck(self, weapon, ammo, silent, weapon_type)
+end
+
+Talents.archerPreUse = archerPreUse
+Talents.wardenPreUse = wardenPreUse
+
 newTalent{
 	name = "Shoot",
 	type = {"technique/archery-base", 1},
@@ -37,7 +77,7 @@ newTalent{
 	message = "@Source@ shoots!",
 	requires_target = true,
 	tactical = { ATTACK = { weapon = 1 } },
-	on_pre_use = function(self, t, silent) if not (self:attr("warden_swap") and doWardenPreUse(self, "bow")) and not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling and ammo for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return wardenPreUse(self, t, silent) end,
 	no_unlearn_last = true,
 	use_psi_archery = function(self, t)
 		local inven = self:getInven("PSIONIC_FOCUS")
@@ -62,11 +102,6 @@ newTalent{
 		
 		local weapon, ammo, offweapon = self:hasArcheryWeapon()
 		if not weapon then return nil end
-		local infinite = ammo.infinite or self:attr("infinite_ammo")
-		if not ammo or (ammo.combat.shots_left <= 0 and not infinite) then
-			game.logPlayer(self, "You do not have enough ammo left!")
-			return nil
-		end
 
 		-- Bombardment.
 		local weapon = self:hasArcheryWeapon("sling")
@@ -113,7 +148,7 @@ newTalent{
 	range = archery_range,
 	requires_target = true,
 	tactical = { ATTACK = { weapon = 2 } },
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	action = function(self, t)
 		local targets = self:archeryAcquireTargets(nil, {one_shot=true})
 		if not targets then return end
@@ -136,7 +171,7 @@ newTalent{
 	no_energy = true,
 	tactical = { BUFF = 2 },
 	no_npc_use = true,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	getCombatVals = function(self, t)
 		local vals = {speed = -self:combatTalentLimit(t, 0.5, 0.05, 0.25), -- Limit < 50% speed loss
 			crit =  self:combatScale(self:getTalentLevel(t) * self:getDex(10, true), 7, 0, 57, 50),
@@ -188,7 +223,7 @@ newTalent{
 	sustain_stamina = 20,
 	no_energy = true,
 	tactical = { BUFF = 2 },
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	getCombatVals = function(self, t)
 		local vals = {speed = self:combatTalentScale(t, 0.1, 0.5, 0.75),
 			crit = -self:combatTalentScale(t, 10.4, 20),
@@ -238,7 +273,7 @@ newTalent{
 	range = archery_range,
 	requires_target = true,
 	tactical = { ATTACK = { weapon = 1 }, STAMINA = 1 },
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	action = function(self, t)
 		local targets = self:archeryAcquireTargets(nil, {one_shot=true})
 		if not targets then return end
@@ -270,7 +305,7 @@ newTalent{
 	end,
 	require = techs_dex_req1,
 	tactical = { ATTACKAREA = { FIRE = 2 }, DISABLE = { blind = 2 } },
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	requires_target = true,
 	target = function(self, t)
 		return {type="ball", x=x, y=y, radius=self:getTalentRadius(t), range=self:getTalentRange(t)}
@@ -312,7 +347,7 @@ newTalent{
 	range = archery_range,
 	tactical = { ATTACK = { weapon = 1 }, DISABLE = 1 },
 	requires_target = true,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	archery_onhit = function(self, t, target, x, y)
 		target:setEffect(target.EFF_SLOW, 7, {power=util.bound((self:combatAttack() * 0.15 * self:getTalentLevel(t)) / 100, 0.1, 0.4), apply_power=self:combatAttack()})
 	end,
@@ -341,7 +376,7 @@ newTalent{
 	tactical = { ATTACK = { weapon = 1 }, DISABLE = { pin = 2 } },
 	requires_target = true,
 	getDur = function(self, t) return math.floor(self:combatTalentScale(t, 2.3, 5.5)) end,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	archery_onhit = function(self, t, target, x, y)
 		if target:canBe("pin") then
 			target:setEffect(target.EFF_PINNED, t.getDur(self, t), {apply_power=self:combatAttack()})
@@ -380,7 +415,7 @@ newTalent{
 		local weapon, ammo = self:hasArcheryWeapon()
 		return {type="ball", radius=self:getTalentRadius(t), range=self:getTalentRange(t), display=self:archeryDefaultProjectileVisual(weapon, ammo)}
 	end,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	getStunDur = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end,
 	archery_onhit = function(self, t, target, x, y)
 		if target:canBe("stun") then
diff --git a/game/modules/tome/data/talents/techniques/bow.lua b/game/modules/tome/data/talents/techniques/bow.lua
index ed1e14a3dd62cc4790bdd29c5d8e13131003bcd3..283c86f3830f5350f25317c61622482652863495 100644
--- a/game/modules/tome/data/talents/techniques/bow.lua
+++ b/game/modules/tome/data/talents/techniques/bow.lua
@@ -17,6 +17,8 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
+local archerPreUse = Talents.archerPreUse
+
 newTalent{
 	name = "Bow Mastery",
 	type = {"technique/archery-bow", 1},
@@ -51,7 +53,7 @@ newTalent{
 	range = archery_range,
 	tactical = { ATTACK = { weapon = 2 } },
 	requires_target = true,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon("bow") then if not silent then game.logPlayer(self, "You require a bow for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "bow") end,
 	action = function(self, t)
 		if not self:hasArcheryWeapon("bow") then game.logPlayer(self, "You must wield a bow!") return nil end
 
@@ -79,7 +81,7 @@ newTalent{
 	target = function(self, t)
 		return {type="ball", radius=self:getTalentRadius(t), range=self:getTalentRange(t)}
 	end,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon("bow") then if not silent then game.logPlayer(self, "You require a bow for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "bow") end,
 	action = function(self, t)
 		if not self:hasArcheryWeapon("bow") then game.logPlayer(self, "You must wield a bow!") return nil end
 
@@ -111,7 +113,7 @@ newTalent{
 	target = function(self, t)
 		return {type="ball", radius=self:getTalentRadius(t), range=self:getTalentRange(t), selffire=false}
 	end,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon("bow") then if not silent then game.logPlayer(self, "You require a bow for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "bow") end,
 	action = function(self, t)
 		if not self:hasArcheryWeapon("bow") then game.logPlayer(self, "You must wield a bow!") return nil end
 
diff --git a/game/modules/tome/data/talents/techniques/buckler-training.lua b/game/modules/tome/data/talents/techniques/buckler-training.lua
index a60192b305b3fb3719515d14afeee10261c81893..c556b98935d3583fe4cd8765f4f75aa36ce33192 100644
--- a/game/modules/tome/data/talents/techniques/buckler-training.lua
+++ b/game/modules/tome/data/talents/techniques/buckler-training.lua
@@ -13,6 +13,15 @@
 -- You should have received a copy of the GNU General Public License
 -- along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+local archerPreUse = Talents.archerPreUse
+
+local preUse = function(self, t, silent)
+	if not self:hasShield() or not archerPreUse(self, t, true) then
+		if not silent then game.logPlayer("You require a ranged weapon and a shield to use this talent.") end
+		return false
+	end
+	return true
+end
 
 newTalent {
 	short_name = "SKIRMISHER_BUCKLER_EXPERTISE",
@@ -70,11 +79,7 @@ newTalent {
 	range = 1,
 	is_special_melee = true,
 	on_pre_use = function(self, t, silent)
-		if not self:hasShield() or not self:hasArcheryWeapon() then
-			if not silent then game.logPlayer(self, "You require a ranged weapon and a shield to use this talent.") end
-			return false
-		end
-		return true
+		return preUse(self, t, silent)
 	end,
 	getDist = function(self, t)
 		if self:getTalentLevelRaw(t) >= 3 then
@@ -203,11 +208,7 @@ newTalent {
 	require = techs_dex_req4,
 	tactical = { BUFF = 2 },
 	on_pre_use = function(self, t, silent)
-		if not self:hasShield() or not self:hasArcheryWeapon() then
-			if not silent then game.logPlayer(self, "You require a ranged weapon and a shield to use this talent.") end
-			return false
-		end
-		return true
+		return preUse(self, t, silent)
 	end,
 	activate = function(self, t)
 		return {}
diff --git a/game/modules/tome/data/talents/techniques/excellence.lua b/game/modules/tome/data/talents/techniques/excellence.lua
index 27240c2d2440a579727eff21858fcff354891534..7f4bb4f08381e2107e58dfb68b1f27d61d5f9d6b 100644
--- a/game/modules/tome/data/talents/techniques/excellence.lua
+++ b/game/modules/tome/data/talents/techniques/excellence.lua
@@ -17,6 +17,8 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
+local archerPreUse = Talents.archerPreUse
+
 newTalent{
 	name = "Shoot Down",
 	type = {"technique/archery-excellence", 1},
@@ -36,7 +38,7 @@ newTalent{
 		if #tgts > 0 then return tgts[1].x, tgts[1].y, tgts[1].tgt end
 	end,
 	on_pre_use_ai = function(self, t, silent) return t.onAIGetTarget(self, t) and true or false end,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	requires_target = true,
 	getNb = function(self, t) return math.floor(self:combatTalentScale(t, 1, 5, "log")) end,
 	target = function(self, t)
@@ -80,7 +82,7 @@ newTalent{
 	tactical = { ATTACK = { weapon = 1 } },
 	requires_target = true,
 	on_pre_use = function(self, t, silent)
-		if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end
+		if not archerPreUse(self, t, silent) then return false end
 		if self:attr("never_move") then return false end
 		return true
 	end,
@@ -166,7 +168,7 @@ newTalent{
 		self:archeryShoot(targets, t, nil, {atk = xatk, mult=self:combatTalentWeaponDamage(t, 0.4, 0.9)})
 		return ret
 	end,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	activate = function(self, t)
 		return {}
 	end,
@@ -196,7 +198,7 @@ newTalent{
 		local weapon, ammo = self:hasArcheryWeapon()
 		return {type="bolt", range=self:getTalentRange(t), display=self:archeryDefaultProjectileVisual(weapon, ammo)}
 	end,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end,
 	getDur = function(self, t) return math.floor(self:combatTalentScale(t, 2, 6)) end,
 	archery_onhit = function(self, t, target, x, y)
 		if target:canBe("silence") then
diff --git a/game/modules/tome/data/talents/techniques/skirmisher-slings.lua b/game/modules/tome/data/talents/techniques/skirmisher-slings.lua
index 0ff6f95c1f2d91fc7d0622513e01b22ca4303a41..90719e1891b129425d114aefb309e8fcaeeec7c8 100644
--- a/game/modules/tome/data/talents/techniques/skirmisher-slings.lua
+++ b/game/modules/tome/data/talents/techniques/skirmisher-slings.lua
@@ -13,15 +13,7 @@
 -- You should have received a copy of the GNU General Public License
 -- along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-local sling_equipped = function(self, silent)
-	if not self:hasArcheryWeapon("sling") then
-		if not silent then
-			game.logPlayer(self, "You must wield a sling!")
-		end
-		return false
-	end
-	return true
-end
+local archerPreUse = Talents.archerPreUse
 
 -- Currently just a copy of Sling Mastery.
 newTalent {
@@ -62,7 +54,7 @@ newTalent {
 	cooldown = 5,
 	stamina = 15,
 	requires_target = true,
-	on_pre_use = function(self, t, silent) return sling_equipped(self, silent) end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "sling") end,
 	getDamage = function(self, t)
 		return self:combatTalentWeaponDamage(t, 0.4, 1.6)
 	end,
@@ -129,7 +121,7 @@ newTalent {
 			--cone_angle = 50, -- degrees
 		}
 	end,
-	on_pre_use = function(self, t, silent) return sling_equipped(self, silent) end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "sling") end,
 	damage_multiplier = function(self, t)
 		return self:combatTalentWeaponDamage(t, 0.2, 0.8)
 	end,
@@ -198,7 +190,7 @@ newTalent {
 	mode = "sustained",
 	no_energy = true,
 	tactical = { BUFF = 2 },
-	on_pre_use = function(self, t, silent) return sling_equipped(self, silent) end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "sling") end,
 	cooldown = function(self, t)
 		return 10
 	end,
diff --git a/game/modules/tome/data/talents/techniques/sling.lua b/game/modules/tome/data/talents/techniques/sling.lua
index 62983a5d10ea372b43a64068e32ee37c62e97c56..02bb16daeb778e3bd2ce1eb81656c125908e0157 100644
--- a/game/modules/tome/data/talents/techniques/sling.lua
+++ b/game/modules/tome/data/talents/techniques/sling.lua
@@ -17,6 +17,8 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
+local archerPreUse = Talents.archerPreUse
+
 newTalent{
 	name = "Sling Mastery",
 	type = {"technique/archery-sling", 1},
@@ -52,7 +54,7 @@ newTalent{
 	requires_target = true,
 	tactical = { ATTACK = { weapon = 2 }, DISABLE = { blind = 2 } },
 	getBlindDur = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon("sling") then if not silent then game.logPlayer(self, "You require a sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "sling") end,
 	archery_onhit = function(self, t, target, x, y)
 		if target:canBe("blind") then
 			target:setEffect(target.EFF_BLINDED, t.getBlindDur(self, t), {apply_power=self:combatAttack()})
@@ -86,21 +88,7 @@ newTalent{
 	range = archery_range,
 	requires_target = true,
 	tactical = { ATTACK = { weapon = 2 }, DISABLE = { knockback = 2 }, ESCAPE = { knockback = 1 } },
---	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon("sling") then if not silent then game.logPlayer(self, "You require a sling for this talent.") end return false end return true end,
-	on_pre_use = function(self, t, silent) -- normally handled with archeryAcquireTargets
-		local weap, ammo = self:hasArcheryWeapon("sling")
-		if weap and ammo then
-			local infinite = ammo.infinite or self:attr("infinite_ammo")
-			if not infinite and ammo.combat.shots_left <= 0 then
-				if not silent then game.logPlayer(self, "You do not have enough ammo left!") end
-				return nil
-			end
-			return true
-		else
-			if not silent then game.logPlayer(self, "You require a sling and ammo for this talent!") end
-			return false
-		end
-	end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "sling") end,
 	archery_onhit = function(self, t, target, x, y)
 		if target:checkHit(self:combatAttack(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("knockback") then
 			target:knockback(self.x, self.y, 4)
@@ -140,7 +128,7 @@ newTalent{
 		if fake then return count end
 		return math.floor(count) + (rng.percent(100*(count - math.floor(count))) and 1 or 0)
 	end,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon("sling") then if not silent then game.logPlayer(self, "You require a sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "sling") end,
 	action = function(self, t)
 		if not self:hasArcheryWeapon("sling") then game.logPlayer(self, "You must wield a sling!") return nil end
 		local targets = self:archeryAcquireTargets(nil, {multishots=t.getShots(self, t)})
diff --git a/game/modules/tome/data/talents/techniques/techniques.lua b/game/modules/tome/data/talents/techniques/techniques.lua
index 45c5a7c4c3e49f997445971372d5507e1eca1f67..a129a0700c81f22d928c06e1c10e9597cc63b269 100644
--- a/game/modules/tome/data/talents/techniques/techniques.lua
+++ b/game/modules/tome/data/talents/techniques/techniques.lua
@@ -326,9 +326,9 @@ load("/data/talents/techniques/battle-tactics.lua")
 load("/data/talents/techniques/field-control.lua")
 load("/data/talents/techniques/combat-techniques.lua")
 load("/data/talents/techniques/combat-training.lua")
+load("/data/talents/techniques/archery.lua")
 load("/data/talents/techniques/bow.lua")
 load("/data/talents/techniques/sling.lua")
-load("/data/talents/techniques/archery.lua")
 load("/data/talents/techniques/excellence.lua")
 load("/data/talents/techniques/magical-combat.lua")
 load("/data/talents/techniques/mobility.lua")
diff --git a/game/modules/tome/data/talents/uber/dex.lua b/game/modules/tome/data/talents/uber/dex.lua
index eb0cb04d105c234540a0df5bf93372ada0d341cb..938dfaf6252a67b7ff3eaa019b6e0f9a2071540e 100644
--- a/game/modules/tome/data/talents/uber/dex.lua
+++ b/game/modules/tome/data/talents/uber/dex.lua
@@ -237,7 +237,7 @@ uberTalent{
 	require = { special={desc="Have dealt over 50000 damage with ranged weapons", fct=function(self) return self.damage_log and self.damage_log.weapon.archery and self.damage_log.weapon.archery >= 50000 end} },
 	tactical = { ATTACK = { weapon = 3 }, DISABLE = 3 },
 	requires_target = true,
-	on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end,
+	on_pre_use = function(self, t, silent) return Talents.archerPreUse(self, t, silent) end,
 	archery_onhit = function(self, t, target, x, y)
 		if target:canBe("stun") then
 			target:setEffect(target.EFF_STUNNED, 5, {apply_power=self:combatAttack()})
diff --git a/game/modules/tome/data/timed_effects/magical.lua b/game/modules/tome/data/timed_effects/magical.lua
index 8436a85249c778b0b1400b4e97daf2235d4add3b..69f1bc78f8009a3609c1bae5e91c46c466227c00 100644
--- a/game/modules/tome/data/timed_effects/magical.lua
+++ b/game/modules/tome/data/timed_effects/magical.lua
@@ -1047,22 +1047,31 @@ newEffect{
 newEffect{
 	name = "CORROSIVE_WORM", image = "talents/corrosive_worm.png",
 	desc = "Corrosive Worm",
-	long_desc = function(self, eff) return ("Target is infected with a corrosive worm doing %0.2f acid damage per turn."):format(eff.dam) end,
+	long_desc = function(self, eff) return ("The target is infected with a corrosive worm, reducing blight and acid resistance by %d%%. When the effect ends, the worm will explode, dealing %d acid damage in a 4 radius ball. This damage will increase by %d%% of all damage taken while under torment"):format(eff.power, eff.finaldam, eff.rate*100) end,
 	type = "magical",
 	subtype = { acid=true },
 	status = "detrimental",
-	parameters = { dam=1, explosion=10 },
+	parameters = { power=20, rate=10, finaldam=50, },
 	on_gain = function(self, err) return "#Target# is infected by a corrosive worm.", "+Corrosive Worm" end,
 	on_lose = function(self, err) return "#Target# is free from the corrosive worm.", "-Corrosive Worm" end,
-	on_timeout = function(self, eff)
-		DamageType:get(DamageType.ACID).projector(eff.src or self, self.x, self.y, DamageType.ACID, eff.dam)
-	end,
 	activate = function(self, eff)
 		eff.particle = self:addParticles(Particles.new("circle", 1, {base_rot=0, oversize=0.7, a=255, appear=8, speed=0, img="blight_worms", radius=0}))
+		self:effectTemporaryValue(eff, "resists", {[DamageType.BLIGHT]=-eff.power, [DamageType.ACID]=-eff.power})
 	end,
 	deactivate = function(self, eff)
+		local tg = {type="ball", radius=4, selffire=false, x=self.x, y=self.y}
+		eff.src:project(tg, self.x, self.y, DamageType.ACID, eff.finaldam, {type="acid"})
 		self:removeParticles(eff.particle)
 	end,
+	callbackOnHit = function(self, eff, cb)
+		eff.finaldam = eff.finaldam + (cb.value * eff.rate)
+		return true
+	end,
+	
+	on_die = function(self, eff)
+		local tg = {type="ball", radius=4, selffire=false, x=self.x, y=self.y}
+		eff.src:project(tg, self.x, self.y, DamageType.ACID, eff.finaldam, {type="acid"})
+	end,
 }
 
 newEffect{
@@ -3632,4 +3641,118 @@ newEffect{
 	end,
 	deactivate = function(self, eff)
 	end,
+}
+
+newEffect{
+	name = "BLIGHT_POISON", image = "effects/poisoned.png",
+	desc = "Blight Poison",
+	long_desc = function(self, eff) return ("The target is poisoned, taking %0.2f blight damage per turn."):format(eff.power) end,
+	type = "magical",
+	subtype = { poison=true, blight=true }, no_ct_effect = true,
+	status = "detrimental",
+	parameters = { power=10 },
+	on_gain = function(self, err) return "#Target# is poisoned!", "+Blight Poison" end,
+	on_lose = function(self, err) return "#Target# stops being poisoned.", "-Blight Poison" end,
+	on_merge = function(self, old_eff, new_eff)
+		-- Merge the poison
+		local olddam = old_eff.power * old_eff.dur
+		local newdam = new_eff.power * new_eff.dur
+		local dur = math.ceil((old_eff.dur + new_eff.dur) / 2)
+		old_eff.dur = dur
+		old_eff.power = (olddam + newdam) / dur
+		if new_eff.max_power then old_eff.power = math.min(old_eff.power, new_eff.max_power) end
+		return old_eff
+	end,
+	on_timeout = function(self, eff)
+		if self:attr("purify_poison") then self:heal(eff.power, eff.src)
+		else DamageType:get(DamageType.BLIGHT).projector(eff.src, self.x, self.y, DamageType.BLIGHT, eff.power)
+		end
+	end,
+}
+
+newEffect{
+	name = "INSIDIOUS_BLIGHT", image = "effects/insidious_poison.png",
+	desc = "Insidious Blight",
+	long_desc = function(self, eff) return ("The target is poisoned, taking %0.2f blight damage per turn and decreasing all heals received by %d%%."):format(eff.power, eff.heal_factor) end,
+	type = "magical",
+	subtype = { poison=true, blight=true }, no_ct_effect = true,
+	status = "detrimental",
+	parameters = {power=10, heal_factor=30},
+	on_gain = function(self, err) return "#Target# is poisoned!", "+Insidious Blight" end,
+	on_lose = function(self, err) return "#Target# is no longer poisoned.", "-Insidious Blight" end,
+	activate = function(self, eff)
+		eff.healid = self:addTemporaryValue("healing_factor", -eff.heal_factor / 100)
+	end,
+	-- There are situations this matters, such as copyEffect
+	on_merge = function(self, old_eff, new_eff)
+		old_eff.dur = math.max(old_eff.dur, new_eff.dur)
+		return old_eff
+	end,
+	on_timeout = function(self, eff)
+		if self:attr("purify_poison") then self:heal(eff.power, eff.src)
+		else DamageType:get(DamageType.BLIGHT).projector(eff.src, self.x, self.y, DamageType.BLIGHT, eff.power)
+		end
+	end,
+	deactivate = function(self, eff)
+		self:removeTemporaryValue("healing_factor", eff.healid)
+	end,
+}
+
+
+newEffect{
+	name = "CRIPPLING_BLIGHT", image = "talents/crippling_poison.png",
+	desc = "Crippling Blight",
+	long_desc = function(self, eff) return ("The target is poisoned and sick, doing %0.2f blight damage per turn. Each time it tries to use a talent there is %d%% chance of failure."):format(eff.power, eff.fail) end,
+	type = "magical",
+	subtype = { poison=true, blight=true }, no_ct_effect = true,
+	status = "detrimental",
+	parameters = {power=10, fail=5},
+	on_gain = function(self, err) return "#Target# is poisoned!", "+Crippling Blight" end,
+	on_lose = function(self, err) return "#Target# is no longer poisoned.", "-Crippling Blight" end,
+	-- Damage each turn
+	on_timeout = function(self, eff)
+		if self:attr("purify_poison") then self:heal(eff.power, eff.src)
+		else DamageType:get(DamageType.BLIGHT).projector(eff.src, self.x, self.y, DamageType.BLIGHT, eff.power)
+		end
+	end,
+	-- There are situations this matters, such as copyEffect
+	on_merge = function(self, old_eff, new_eff)
+		old_eff.dur = math.max(old_eff.dur, new_eff.dur)
+		return old_eff
+	end,
+	activate = function(self, eff)
+		eff.tmpid = self:addTemporaryValue("talent_fail_chance", eff.fail)
+	end,
+	deactivate = function(self, eff)
+		self:removeTemporaryValue("talent_fail_chance", eff.tmpid)
+	end,
+}
+
+newEffect{
+	name = "NUMBING_BLIGHT", image = "effects/numbing_poison.png",
+	desc = "Numbing Blight",
+	long_desc = function(self, eff) return ("The target is poisoned and sick, doing %0.2f blight damage per turn. All damage it does is reduced by %d%%."):format(eff.power, eff.reduce) end,
+	type = "magical",
+	subtype = { poison=true, blight=true }, no_ct_effect = true,
+	status = "detrimental",
+	parameters = {power=10, reduce=5},
+	on_gain = function(self, err) return "#Target# is poisoned!", "+Numbing Blight" end,
+	on_lose = function(self, err) return "#Target# is no longer poisoned.", "-Numbing Blight" end,
+	-- Damage each turn
+	on_timeout = function(self, eff)
+		if self:attr("purify_poison") then self:heal(eff.power, eff.src)
+		else DamageType:get(DamageType.BLIGHT).projector(eff.src, self.x, self.y, DamageType.BLIGHT, eff.power)
+		end
+	end,
+	-- There are situations this matters, such as copyEffect
+	on_merge = function(self, old_eff, new_eff)
+		old_eff.dur = math.max(old_eff.dur, new_eff.dur)
+		return old_eff
+	end,
+	activate = function(self, eff)
+		eff.tmpid = self:addTemporaryValue("numbed", eff.reduce)
+	end,
+	deactivate = function(self, eff)
+		self:removeTemporaryValue("numbed", eff.tmpid)
+	end,
 }
\ No newline at end of file
diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua
index ef66a162f6ee9a7903e588ad111ab0e2b9f41d2f..c52d0aa998e26b7773d334a9d3a8af6cb3aea32e 100644
--- a/game/modules/tome/data/timed_effects/physical.lua
+++ b/game/modules/tome/data/timed_effects/physical.lua
@@ -2572,7 +2572,7 @@ newEffect{
 newEffect{
 	name = "JUGGERNAUT", image = "talents/juggernaut.png",
 	desc = "Juggernaut",
-	long_desc = function(self, eff) return ("Reduces physical damage received by %d%% and provides a %d%% chance to ignore critial hits."):format(eff.power, eff.crits) end,
+	long_desc = function(self, eff) return ("Reduces physical damage received by %d%% and provides a %d%% chance to ignore critical hits."):format(eff.power, eff.crits) end,
 	type = "physical",
 	subtype = { superiority=true },
 	status = "beneficial",
diff --git a/game/modules/tome/data/zones/dreams/zone.lua b/game/modules/tome/data/zones/dreams/zone.lua
index 7f4db0495a3316613cb6a3174bfa05ec8af90b4a..84d5eadd6d7ab11dec42889a4d7ce3c909d25fc6 100644
--- a/game/modules/tome/data/zones/dreams/zone.lua
+++ b/game/modules/tome/data/zones/dreams/zone.lua
@@ -309,14 +309,16 @@ You feel good!]],
 				end
 			end
 			game.party:setPlayer(game:getPlayer(true))
+			if self.success then
+				world:gainAchievement("ALL_DREAMS", self.summoner, dream)
+			end
 			if self.success and danger then
 				require("engine.ui.Dialog"):simpleLongPopup("Deep slumber...", msg, 600)
 				game.logPlayer(game.player, msg:gsub("\n", " "))
 				game.player:setEffect(game.player.EFF_VICTORY_RUSH_ZIGUR, 4, {})
-				world:gainAchievement("ALL_DREAMS", self.summoner, dream)
 			elseif danger then
 				local msg = [[As you die in a dream you suddenly wake up.
-Posionous fumes take their toll on your body!]]
+Poisonous fumes take their toll on your body!]]
 				game.logPlayer(game.player)
 				require("engine.ui.Dialog"):simpleLongPopup("Deep slumber...", msg, 600)
 				local hit = math.max(0, game.player.life * 2 / 3)
diff --git a/game/modules/tome/data/zones/ruined-dungeon/grids.lua b/game/modules/tome/data/zones/ruined-dungeon/grids.lua
index 0356a4ca74b7e0545db6f03733783dc5c291e251..ea2a3bb874581a6570ff2d50a4c1126f2b8e2236 100644
--- a/game/modules/tome/data/zones/ruined-dungeon/grids.lua
+++ b/game/modules/tome/data/zones/ruined-dungeon/grids.lua
@@ -68,7 +68,7 @@ newEntity{
 				end
 			end)
 		else
-			require("engine.ui.Dialog"):simplePopup("Infinite Dungeon", "You should not go there, there is no way back. Ever. Maybe later when you did all you must do.")
+			require("engine.ui.Dialog"):simplePopup("Infinite Dungeon", "You should not go there. There is no way back. Ever. Maybe later when you have done all you must do.")
 		end
 	end,
 }
diff --git a/game/modules/tome/dialogs/CharacterSheet.lua b/game/modules/tome/dialogs/CharacterSheet.lua
index d1e8466dd7c16fea050310d8b192ca97eaee007c..26b53174a03b8ae1d24c9b9ab899e77f3cba5da8 100644
--- a/game/modules/tome/dialogs/CharacterSheet.lua
+++ b/game/modules/tome/dialogs/CharacterSheet.lua
@@ -68,7 +68,7 @@ function _M:init(actor)
 	self.vs = Separator.new{dir="vertical", size=self.iw}
 
 	self.c_tut = Textzone.new{width=self.iw * 0.6, auto_height=true, no_color_bleed=true, font = self.font, text=[[
-Values #00FF00#in brackets ( )#LAST# shows changes made from last character sheet checking.
+Values #00FF00#in brackets ( )#LAST# show changes made from last character sheet checking.
 Keyboard: #00FF00#'d'#LAST# to save character dump. #00FF00#TAB key#LAST# to switch between tabs.
 Mouse: Hover over stat for info
 ]]}
diff --git a/src/web-cef3/web.cpp b/src/web-cef3/web.cpp
index 4d46fb8933b8e983a3708869cfa3105e99746200..f4744670ec8f4b34010dd4d8c910dd7cda54fe16 100644
--- a/src/web-cef3/web.cpp
+++ b/src/web-cef3/web.cpp
@@ -67,7 +67,7 @@ public:
 	}
 
 	~RenderHandler() {
-		fprintf(logfile, "[WEBCORE] Destroyed renreder\n");
+		fprintf(logfile, "[WEBCORE] Destroyed renderer\n");
 
 		WebEvent *event = new WebEvent();
 		event->kind = TE4_WEB_EVENT_DELETE_TEXTURE;