diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
index 3ee8f0fd90f85ac580010406241cf8e95b8ca5d7..f5c6f9587eea054e7a34bc914c9ac348b5ec622d 100644
--- a/game/modules/tome/class/interface/Combat.lua
+++ b/game/modules/tome/class/interface/Combat.lua
@@ -119,6 +119,13 @@ function _M:attackTarget(target, damtype, mult, noenergy, force_unharmed)
 		local ret = target:callTalent(target.T_INTUITIVE_SHOTS, "proc", self)
 		if ret then return false end
 	end
+	
+	if not target.turn_procs.warding_weapon and target:knowTalent(target.T_WARDING_WEAPON) and target:getTalentLevelRaw(target.T_WARDING_WEAPON) >= 5 
+		and rng.percent(target:callTalent(target.T_WARDING_WEAPON, "getChance")) and target:getPsi() >= 15 then
+		target:setEffect(target.EFF_WEAPON_WARDING, 1, {})
+		target.turn_procs.warding_weapon = true
+		target:incPsi(-15)
+	end
 
 	-- Change attack type if using gems
 	if not damtype and self:getInven(self.INVEN_GEM) then
diff --git a/game/modules/tome/data/birth/classes/psionic.lua b/game/modules/tome/data/birth/classes/psionic.lua
index e30e630e8f0a6cc26124e26e3837550075af8933..60e7866ca0a3c58f20350d7e6aa74f010fa277c8 100644
--- a/game/modules/tome/data/birth/classes/psionic.lua
+++ b/game/modules/tome/data/birth/classes/psionic.lua
@@ -105,6 +105,11 @@ newBirthDescriptor{
 			{type="armor", subtype="cloth", name="linen robe", autoreq=true, ego_chance=-1000},
 			{type="weapon", subtype="greatsword", name="iron greatsword", autoreq=true, ego_chance=-1000},
 		},
+		resolvers.inventorybirth{ id=true,
+			{type="weapon", subtype="mindstar", name="mossy mindstar", autoreq=true, ego_chance=-1000},
+			{type="weapon", subtype="mindstar", name="mossy mindstar", autoreq=true, ego_chance=-1000},
+			{type="gem",},
+		},
 		resolvers.generic(function(self)
 			-- Make and wield some alchemist gems
 			local gs = game.zone:makeEntity(game.level, "object", {type="weapon", subtype="greatsword", name="iron greatsword", ego_chance=-1000}, nil, true)
diff --git a/game/modules/tome/data/talents/misc/npcs.lua b/game/modules/tome/data/talents/misc/npcs.lua
index c3f5c35696c8a5019b3274ab6a0e136a032ee14b..e5618860a9042e9488a2fe15e9c70beb4cc5be2b 100644
--- a/game/modules/tome/data/talents/misc/npcs.lua
+++ b/game/modules/tome/data/talents/misc/npcs.lua
@@ -2466,40 +2466,140 @@ newTalent{
 }
 
 newTalent{
-	name = "Mindhook",
+	name = "Shattering Charge",
 	type = {"psionic/other", 1},
-	cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 5, 18, 10)) end, -- Limit to >5
-	psi = 20,
+--	require = psi_wil_req4,
 	points = 5,
-	tactical = { CLOSEIN = 2 },
-	range = function(self, t)
-		local r = self:combatTalentLimit(t, 10, 3, 7) -- Limit base range to 10
-		local gem_level = getGemLevel(self)
-		local mult = 1 + 0.005*gem_level*self:callTalent(self.T_REACH, "rangebonus") -- reduced effect of reach
-		return math.floor(r*mult)
+	psi = 40,
+	cooldown = 12,
+	tactical = { CLOSEIN = 2, ATTACK = { PHYSICAL = 2 } },
+	range = function(self, t) return self:combatTalentLimit(t, 10, 6, 9) end,
+	direct_hit = true,
+	requires_target = true,
+	getDam = function(self, t) return self:combatTalentMindDamage(t, 20, 180) end,
+	action = function(self, t)
+		if self:getTalentLevelRaw(t) < 5 then
+			local tg = {type="beam", range=self:getTalentRange(t), nolock=true, talent=t}
+			local x, y = self:getTarget(tg)
+			if not x or not y then return nil end
+			if core.fov.distance(self.x, self.y, x, y) > tg.range then return nil end
+			if self:hasLOS(x, y) and not game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move") then
+				local dam = self:mindCrit(t.getDam(self, t))
+				self:project(tg, x, y, DamageType.MINDKNOCKBACK, self:mindCrit(rng.avg(2*dam/3, dam, 3)))
+				--local _ _, x, y = self:canProject(tg, x, y)
+				game.level.map:particleEmitter(self.x, self.y, tg.radius, "flamebeam", {tx=x-self.x, ty=y-self.y})
+				game:playSoundNear(self, "talents/lightning")
+				--self:move(x, y, true)
+				local fx, fy = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true})
+				if fx then
+					self:move(fx, fy, true)
+				end
+			else
+				game.logSeen(self, "You can't move there.")
+				return nil
+			end
+			return true
+		else
+			local tg = {type="beam", range=self:getTalentRange(t), nolock=true, talent=t, display={particle="bolt_earth", trail="earthtrail"}}
+			local x, y = self:getTarget(tg)
+			if not x or not y then return nil end
+			if core.fov.distance(self.x, self.y, x, y) > tg.range then return nil end
+			local dam = self:mindCrit(t.getDam(self, t))
+
+			for i = 1, self:getTalentRange(t) do
+				self:project(tg, x, y, DamageType.DIG, 1)
+			end
+			self:project(tg, x, y, DamageType.MINDKNOCKBACK, self:mindCrit(rng.avg(2*dam/3, dam, 3)))
+			local _ _, x, y = self:canProject(tg, x, y)
+			game.level.map:particleEmitter(self.x, self.y, tg.radius, "flamebeam", {tx=x-self.x, ty=y-self.y})
+			game:playSoundNear(self, "talents/lightning")
+
+			local block_actor = function(_, bx, by) return game.level.map:checkEntity(bx, by, engine.Map.TERRAIN, "block_move", self) end
+			local l = self:lineFOV(x, y, block_actor)
+			local lx, ly, is_corner_blocked = l:step()
+			local tx, ty = self.x, self.y
+			while lx and ly do
+				if is_corner_blocked or block_actor(_, lx, ly) then break end
+				tx, ty = lx, ly
+				lx, ly, is_corner_blocked = l:step()
+			end
+
+			--self:move(tx, ty, true)
+			local fx, fy = util.findFreeGrid(tx, ty, 5, true, {[Map.ACTOR]=true})
+			if fx then
+				self:move(fx, fy, true)
+			end
+			return true
+		end
+	end,
+	info = function(self, t)
+		local range = self:getTalentRange(t)
+		local dam = damDesc(self, DamageType.PHYSICAL, t.getDam(self, t))
+		return ([[You expend massive amounts of energy to launch yourself across %d squares at incredible speed. All enemies in your path will be knocked flying and dealt between %d and %d Physical damage. 
+		At talent level 5, you can batter through solid walls.]]):
+		format(range, 2*dam/3, dam)
+	end,
+}
+
+newTalent{
+	name = "Telekinetic Throw",
+	type = {"psionic/other", 1},
+--	require = psi_wil_high2,
+	points = 5,
+	random_ego = "attack",
+	cooldown = 15,
+	psi = 20,
+	tactical = { ATTACK = { PHYSICAL = 2 } },
+	range = function(self, t) return math.floor(self:combatStatScale("str", 1, 5) + self:combatMindpower()/20) end,
+	getDamage = function (self, t)
+		return math.floor(self:combatTalentMindDamage(t, 10, 170))
 	end,
+	getKBResistPen = function(self, t) return self:combatTalentLimit(t, 100, 25, 45) end,
+	requires_target = true,
+	target = function(self, t) return {type="ball", range=self:getTalentRange(t), radius=2, selffire=false, talent=t} end,
 	action = function(self, t)
-		local tg = {type="bolt", range=self:getTalentRange(t)}
+		local tg = {type="hit", range=1}
+		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 tg = self:getTalentTarget(t)
 		local x, y = self:getTarget(tg)
 		if not x or not y then return nil end
-		local _ _, x, y = self:canProject(tg, x, y)
-		local target = game.level.map(x, y, engine.Map.ACTOR)
-		if not target then
-			game.logPlayer(self, "The target is out of range")
-			return
+		local dam = self:mindCrit(t.getDamage(self, t))
+		
+		if target:canBe("knockback") or rng.percent(t.getKBResistPen(self, t)) then
+			self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam) --Direct Damage
+			
+		local tx, ty = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true})
+		if tx and ty then
+			local ox, oy = target.x, target.y
+			target:move(tx, ty, true)
+			if config.settings.tome.smooth_move > 0 then
+				target:resetMoveAnim()
+				target:setMoveAnim(ox, oy, 8, 5)
+			end
+		end
+		self:project(tg, target.x, target.y, DamageType.SPELLKNOCKBACK, dam/2) --AOE damage
+		if target:canBe("stun") then
+			target:setEffect(target.EFF_STUNNED, 4, {apply_power=self:combatMindpower()})
+		else
+			game.logSeen(target, "%s resists the stun!", target.name:capitalize())
+		end
+		else --If the target resists the knockback, do half damage to it.
+			target:logCombat(self, "#YELLOW##Source# resists #Target#'s throw!")
+			self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam/2)
 		end
-		target:pull(self.x, self.y, tg.range)
-		target:setEffect(target.EFF_DAZED, 1, {})
-		game:playSoundNear(self, "talents/arcane")
-
 		return true
 	end,
 	info = function(self, t)
 		local range = self:getTalentRange(t)
-		return ([[Briefly extend your telekinetic reach to grab an enemy and haul them towards you.
-		Works on enemies up to %d squares away. The cooldown decreases, and the range increases, with additional talent points spent.
-		This talent receives a reduced benefit from the Reach talent.]]):
-		format(range)
+		local dam = damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t))
+		return ([[Use your telekinetic power to enhance your strength, allowing you to pick up an adjacent enemy and hurl it anywhere within radius %d. 
+		Upon landing, your target takes %0.1f Physical damage and is stunned for 4 turns.  All other creatures within radius 2 of the landing point take %0.1f Physical damage and are knocked away from you.
+		This talent ignores %d%% of the knockback resistance of the thrown target, which takes half damage if it resists being thrown.
+		The damage improves with your Mindpower and the range increases with both Mindpower and Strength.]]):
+		format(range, dam, dam/2, t.getKBResistPen(self, t))
 	end,
 }
 
diff --git a/game/modules/tome/data/talents/psionic/absorption.lua b/game/modules/tome/data/talents/psionic/absorption.lua
index 14a6a12c4edeab65d63fda55b73b5340bb1969ee..c92c1dd52574ba32a808491de7b2d4ccbc251ec7 100644
--- a/game/modules/tome/data/talents/psionic/absorption.lua
+++ b/game/modules/tome/data/talents/psionic/absorption.lua
@@ -21,16 +21,11 @@
 -- Note: This is consistent with raw damage but is applied after damage multipliers
 local function getShieldStrength(self, t)
 	--return math.max(0, self:combatMindpower())
-	return self:combatTalentMindDamage(t, 10, 100)
-end
-
-local function getSpikeStrength(self, t)
-	local ss = getShieldStrength(self, t)
-	return 75*self:getTalentLevel(t) + ss*6.85
+	return self:combatTalentMindDamage(t, 20, 100)
 end
 
 local function getEfficiency(self, t)
-	return self:combatTalentLimit(t, 100, 20, 70)/100 -- Limit to <100%
+	return self:combatTalentLimit(t, 100, 20, 55)/100 -- Limit to <100%
 end
 
 local function maxPsiAbsorb(self, t) -- Max psi/turn to prevent runaway psi gains (solipsist randbosses)
@@ -60,9 +55,9 @@ local function shieldAbsorb(self, t, p, absorbed)
 	local cturn = math.floor(game.turn / 10)
 	if cturn ~= p.last_absorbs.last_turn then
 		local diff = cturn - p.last_absorbs.last_turn
-		for i = 5, 0, -1 do
+		for i = 2, 0, -1 do
 			local ni = i + diff
-			if ni <= 5 then
+			if ni <= 2 then
 				p.last_absorbs.values[ni] = p.last_absorbs.values[i]
 			end
 			p.last_absorbs.values[i] = nil
@@ -74,14 +69,14 @@ end
 
 local function shieldSpike(self, t, p)
 	local val = 0
-	for i = 0, 5 do val = val + (p.last_absorbs.values[i] or 0) end
+	for i = 0, 2 do val = val + (p.last_absorbs.values[i] or 0) end
 
-	self:setEffect(self.EFF_PSI_DAMAGE_SHIELD, 5, {power=val})
+	self:setEffect(self.EFF_PSI_DAMAGE_SHIELD, 5, {power=val*2})
 end
 
 local function shieldOverlay(self, t, p)
 	local val = 0
-	for i = 0, 5 do val = val + (p.last_absorbs.values[i] or 0) end
+	for i = 0, 2 do val = val + (p.last_absorbs.values[i] or 0) end
 	if val <= 0 then return "" end
 	local fnt = "buff_font_small"
 	if val >= 1000 then fnt = "buff_font_smaller" end
@@ -173,7 +168,6 @@ newTalent{
 	end,
 	deactivate = function(self, t, p)
 		self:removeParticles(p.particle)
-		local spike_str = getSpikeStrength(self, t)
 		self:removeTemporaryValue("kinetic_shield", p.am)
 		if self:attr("save_cleanup") then return true end
 
@@ -225,7 +219,7 @@ newTalent{
 		local absorb = 100*getEfficiency(self,t)
 		return ([[Surround yourself with a shield that will absorb %d%% of any physical/acid/nature/temporal attack, up to a maximum of %d damage per attack.
 		Every time your shield absorbs damage, you convert some of the attack into energy, gaining two points of Psi, plus an additional point for every %0.1f points of damage absorbed, up to a maximum %0.1f points each turn.
-		At talent level 3, when you de-activate the shield all the absorbed damage in the last 6 turns is released as a full psionic shield (absorbing all damage).
+		At talent level 3, when you de-activate the shield twice the absorbed damage in the last 3 turns is released as a full psionic shield (absorbing all damage).
 		The maximum amount of damage your shield can absorb and the efficiency of the psi gain scale with your mindpower.]]):
 		format(absorb, s_str, shieldMastery(self, t), maxPsiAbsorb(self,t))
 	end,
@@ -318,7 +312,6 @@ newTalent{
 	end,
 	deactivate = function(self, t, p)
 		self:removeParticles(p.particle)
-		local spike_str = getSpikeStrength(self, t)
 		self:removeTemporaryValue("thermal_shield", p.am)
 		if self:attr("save_cleanup") then return true end
 
@@ -368,7 +361,7 @@ newTalent{
 		local absorb = 100*getEfficiency(self,t)
 		return ([[Surround yourself with a shield that will absorb %d%% of any fire/cold/light/arcane attack, up to a maximum of %d damage per attack. 
 		Every time your shield absorbs damage, you convert some of the attack into energy, gaining two points of Psi, plus an additional point for every %0.1f points of damage absorbed, up to a maximum %0.1f points each turn.
-		At talent level 3, when you de-activate the shield all the absorbed damage in the last 6 turns is released as a full psionic shield (absorbing all damage).
+		At talent level 3, when you de-activate the shield twice the absorbed damage in the last 3 turns is released as a full psionic shield (absorbing all damage).
 		The maximum amount of damage your shield can absorb and the efficiency of the psi gain scale with your mindpower.]]):
 		format(absorb, s_str, shieldMastery(self, t), maxPsiAbsorb(self,t))
 	end,
@@ -458,7 +451,6 @@ newTalent{
 	end,
 	deactivate = function(self, t, p)
 		self:removeParticles(p.particle)
-		local spike_str = getSpikeStrength(self, t)
 		self:removeTemporaryValue("charged_shield", p.am)
 		if self:attr("save_cleanup") then return true end
 
@@ -510,7 +502,7 @@ newTalent{
 		local absorb = 100*getEfficiency(self,t)
 		return ([[Surround yourself with a shield that will absorb %d%% of any lightning/blight/darkness/mind attack, up to a maximum of %d damage per attack.
 		Every time your shield absorbs damage, you convert some of the attack into energy, gaining two points of Psi, plus an additional point for every %0.1f points of damage absorbed, up to a maximum %0.1f points each turn.
-		At talent level 3, when you de-activate the shield all the absorbed damage in the last 6 turns is released as a full psionic shield (absorbing all damage).
+		At talent level 3, when you de-activate the shield twice the absorbed damage in the last 3 turns is released as a full psionic shield (absorbing all damage).
 		The maximum amount of damage your shield can absorb and the efficiency of the psi gain scale with your mindpower.]]):
 		format(absorb, s_str, shieldMastery(self, t), maxPsiAbsorb(self,t))
 	end,
diff --git a/game/modules/tome/data/talents/psionic/augmented-mobility.lua b/game/modules/tome/data/talents/psionic/augmented-mobility.lua
index 311755851b1889aa6de1dbc68b07b0788e758272..b178442f8442af7bc88bbbbbe44c4ebd19125008 100644
--- a/game/modules/tome/data/talents/psionic/augmented-mobility.lua
+++ b/game/modules/tome/data/talents/psionic/augmented-mobility.lua
@@ -59,9 +59,9 @@ newTalent{
 	psi = 30,
 	no_energy = true,
 	getDuration = function(self, t) return math.floor(self:combatLimit(self:combatMindpower(0.1), 10, 4, 0, 6, 6)) end, -- Limit < 10
-	speed = function(self, t) return self:combatTalentScale(t, 0.1, 0.6, 0.75) end,
+	speed = function(self, t) return self:combatTalentScale(t, 0.1, 0.4, 0.75) end,
 	getBoost = function(self, t)
-		return self:combatScale(self:getTalentLevel(t)*self:combatStatTalentIntervalDamage(t, "combatMindpower", 1, 9), 15, 0, 49, 34)
+		return self:combatScale(self:combatTalentMindDamage(t, 20, 60), 0, 0, 50, 100, 0.75)
 	end,
 	action = function(self, t)
 		self:setEffect(self.EFF_QUICKNESS, t.getDuration(self, t), {power=t.speed(self, t)})
@@ -73,122 +73,75 @@ newTalent{
 		local percentinc = 100 * inc
 		local boost = t.getBoost(self, t)
 		return ([[Encase your body in a sheath of thought-quick forces, allowing you to control your body's movements directly without the inefficiency of dealing with crude mechanisms like nerves and muscles.
-		Increases Accuracy by %d, your critical strike chance by %0.1f%% and your attack speed by %d%% for %d turns.
+		Increases Accuracy by %d, your critical strike chance by %0.1f%% and your global speed by %d%% for %d turns.
 		The duration improves with your Mindpower.]]):
 		format(boost, 0.5*boost, percentinc, t.getDuration(self, t))
 	end,
 }
 
-
 newTalent{
-	name = "Telekinetic Leap",
+	name = "Mindhook",
 	type = {"psionic/augmented-mobility", 3},
 	require = psi_wil_req3,
-	cooldown = 15,
+	cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 5, 18, 10)) end, -- Limit to >5
 	psi = 10,
 	points = 5,
 	tactical = { CLOSEIN = 2 },
-	range = function(self, t)
-		return self:combatTalentLimit(t, 10, 5, 9) -- Limit < 10
-	end,
+	range = function(self, t) return self:combatTalentLimit(t, 10, 3, 7) end, -- Limit base range to 10
 	action = function(self, t)
-		local tg = {default_target=self, type="ball", nolock=true, pass_terrain=false, nowarning=true, range=self:getTalentRange(t), radius=0, requires_knowledge=false}
+		local tg = {type="bolt", range=self:getTalentRange(t)}
 		local x, y = self:getTarget(tg)
 		if not x or not y then return nil end
 		local _ _, x, y = self:canProject(tg, x, y)
-		if not x or not y then return nil end
-
-
-		local fx, fy = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true})
-		if not fx then
+		local target = game.level.map(x, y, engine.Map.ACTOR)
+		if not target then
+			game.logPlayer(self, "The target is out of range")
 			return
 		end
-		self:move(fx, fy, true)
-
+		target:pull(self.x, self.y, tg.range)
+		target:setEffect(target.EFF_DAZED, 1, {apply_power=self:combatMindpower()})
+		game:playSoundNear(self, "talents/arcane")
 
 		return true
 	end,
 	info = function(self, t)
 		local range = self:getTalentRange(t)
-		return ([[You perform a precise, telekinetically-enhanced leap, landing up to %d squares away.]]):
+		return ([[Briefly extend your telekinetic reach to grab an enemy and haul them towards you.
+		Works on enemies up to %d squares away. 
+		The cooldown decreases, and the range increases, with additional talent points spent.]]):
 		format(range)
 	end,
 }
 
 newTalent{
-	name = "Shattering Charge",
+	name = "Telekinetic Leap",
 	type = {"psionic/augmented-mobility", 4},
 	require = psi_wil_req4,
+	cooldown = 15,
+	psi = 10,
 	points = 5,
-	psi = 40,
-	cooldown = 12,
-	tactical = { CLOSEIN = 2, ATTACK = { PHYSICAL = 2 } },
-	range = function(self, t) return self:combatTalentLimit(t, 10, 6, 9) end,
-	direct_hit = true,
-	requires_target = true,
-	getDam = function(self, t) return self:combatTalentMindDamage(t, 20, 180) end,
+	tactical = { CLOSEIN = 2 },
+	range = function(self, t)
+		return math.floor(self:combatTalentLimit(t, 10, 2, 7.5)) -- Limit < 10
+	end,
 	action = function(self, t)
-		if self:getTalentLevelRaw(t) < 5 then
-			local tg = {type="beam", range=self:getTalentRange(t), nolock=true, talent=t}
-			local x, y = self:getTarget(tg)
-			if not x or not y then return nil end
-			if core.fov.distance(self.x, self.y, x, y) > tg.range then return nil end
-			if self:hasLOS(x, y) and not game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move") then
-				local dam = self:mindCrit(t.getDam(self, t))
-				self:project(tg, x, y, DamageType.MINDKNOCKBACK, self:mindCrit(rng.avg(2*dam/3, dam, 3)))
-				--local _ _, x, y = self:canProject(tg, x, y)
-				game.level.map:particleEmitter(self.x, self.y, tg.radius, "flamebeam", {tx=x-self.x, ty=y-self.y})
-				game:playSoundNear(self, "talents/lightning")
-				--self:move(x, y, true)
-				local fx, fy = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true})
-				if not fx then
-					return
-				end
-				self:move(fx, fy, true)
-			else
-				game.logSeen(self, "You can't move there.")
-				return nil
-			end
-			return true
-		else
-			local tg = {type="beam", range=self:getTalentRange(t), nolock=true, talent=t, display={particle="bolt_earth", trail="earthtrail"}}
-			local x, y = self:getTarget(tg)
-			if not x or not y then return nil end
-			if core.fov.distance(self.x, self.y, x, y) > tg.range then return nil end
-			local dam = self:mindCrit(t.getDam(self, t))
-
-			for i = 1, self:getTalentRange(t) do
-				self:project(tg, x, y, DamageType.DIG, 1)
-			end
-			self:project(tg, x, y, DamageType.MINDKNOCKBACK, self:mindCrit(rng.avg(2*dam/3, dam, 3)))
-			local _ _, x, y = self:canProject(tg, x, y)
-			game.level.map:particleEmitter(self.x, self.y, tg.radius, "flamebeam", {tx=x-self.x, ty=y-self.y})
-			game:playSoundNear(self, "talents/lightning")
-
-			local block_actor = function(_, bx, by) return game.level.map:checkEntity(bx, by, engine.Map.TERRAIN, "block_move", self) end
-			local l = self:lineFOV(x, y, block_actor)
-			local lx, ly, is_corner_blocked = l:step()
-			local tx, ty = self.x, self.y
-			while lx and ly do
-				if is_corner_blocked or block_actor(_, lx, ly) then break end
-				tx, ty = lx, ly
-				lx, ly, is_corner_blocked = l:step()
-			end
+		local tg = {default_target=self, type="ball", nolock=true, pass_terrain=false, nowarning=true, range=self:getTalentRange(t), radius=0, requires_knowledge=false}
+		local x, y = self:getTarget(tg)
+		if not x or not y then return nil end
+		local _ _, x, y = self:canProject(tg, x, y)
+		if not x or not y then return nil end
 
-			--self:move(tx, ty, true)
-			local fx, fy = util.findFreeGrid(tx, ty, 5, true, {[Map.ACTOR]=true})
-			if not fx then
-				return
-			end
-			self:move(fx, fy, true)
-			return true
+		local fx, fy = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true})
+		if not fx then
+			return
 		end
+		self:move(fx, fy, true)
+
+		return true
 	end,
 	info = function(self, t)
 		local range = self:getTalentRange(t)
-		local dam = damDesc(self, DamageType.PHYSICAL, t.getDam(self, t))
-		return ([[You expend massive amounts of energy to launch yourself across %d squares at incredible speed. All enemies in your path will be knocked flying and dealt between %d and %d Physical damage. 
-		At talent level 5, you can batter through solid walls.]]):
-		format(range, 2*dam/3, dam)
+		return ([[You perform a precise, telekinetically-enhanced leap, landing up to %d squares away.]]):
+		format(range)
 	end,
-}
\ No newline at end of file
+}
diff --git a/game/modules/tome/data/talents/psionic/augmented-striking.lua b/game/modules/tome/data/talents/psionic/augmented-striking.lua
index d97cf1063c5cfa84cb534b5ff8afd469b43b43e1..6260e0053f35c7044f623e88f704e5e31e96128e 100644
--- a/game/modules/tome/data/talents/psionic/augmented-striking.lua
+++ b/game/modules/tome/data/talents/psionic/augmented-striking.lua
@@ -28,7 +28,8 @@ newTalent{
 	range = 1,
 	requires_target = true,
 	tactical = { ATTACK = { PHYSICAL = 2 } },
-	getDam = function(self, t) return self:combatTalentMindDamage(t, 10, 100) end,
+	getDam = function(self, t) return self:combatTalentMindDamage(t, 20, 200) end,
+	getDur = function(self, t) return self:combatTalentScale(t, 2.0, 6.0) end,
 	action = function(self, t)
 		local weapon = self:getInven("MAINHAND") and self:getInven("MAINHAND")[1]
 		if type(weapon) == "boolean" then weapon = nil end
@@ -41,10 +42,18 @@ newTalent{
 		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 = self:mindCrit(t.getDam(self, t))
+		local dur = t.getDur(self, t)
 
-		local hit = self:attackTarget(target, DamageType.PHYSICAL, self:combatTalentWeaponDamage(t, 0.5, 2.0), true)
+		local hit = self:attackTarget(target, DamageType.PHYSICAL, self:combatTalentWeaponDamage(t, 0.5, 3.0), true)
 		if hit then
-			DamageType:get(DamageType.TK_PUSHPIN).projector(self, x, y, DamageType.TK_PUSHPIN, {push=4, dam=dam, dur=4})
+			if target:canBe("pin") then
+				target:setEffect(target.EFF_PINNED, dur, {apply_power=self:combatMindpower()})
+			else
+				game.logSeen(target, "%s resists the pin!", target.name:capitalize())
+			end
+			if target:attr("frozen") then
+				DamageType:get(DamageType.PHYSICAL).projector(self, x, y, DamageType.PHYSICAL, dam)
+			end
 		end
 		
 		if self:hasEffect(self.EFF_TRANSCENDENT_TELEKINESIS) then
@@ -56,23 +65,41 @@ newTalent{
 
 			local hit
 			if lt then
-				hit = self:attackTarget(lt, DamageType.PHYSICAL, self:combatTalentWeaponDamage(t, 0.5, 2.0), true)
-				if hit then DamageType:get(DamageType.TK_PUSHPIN).projector(self, lx, ly, DamageType.TK_PUSHPIN, {push=4, dam=dam, dur=4}) end
+				hit = self:attackTarget(lt, DamageType.PHYSICAL, self:combatTalentWeaponDamage(t, 0.5, 3.0), true)		
+				if hit then
+					if lt:canBe("pin") then
+						lt:setEffect(lt.EFF_PINNED, dur, {apply_power=self:combatMindpower()})
+					else
+						game.logSeen(lt, "%s resists the pin!", lt.name:capitalize())
+					end
+					if target:attr("frozen") then
+						DamageType:get(DamageType.PHYSICAL).projector(self, x, y, DamageType.PHYSICAL, dam)
+					end
+				end
 			end
 
 			if rt then
-				hit = self:attackTarget(rt, DamageType.PHYSICAL, self:combatTalentWeaponDamage(t, 0.5, 2.0), true)
-				if hit then DamageType:get(DamageType.TK_PUSHPIN).projector(self, rx, ry, DamageType.TK_PUSHPIN, {push=4, dam=dam, dur=4}) end
+				hit = self:attackTarget(rt, DamageType.PHYSICAL, self:combatTalentWeaponDamage(t, 0.5, 3.0), true)
+				if hit then
+					if rt:canBe("pin") then
+						rt:setEffect(rt.EFF_PINNED, dur, {apply_power=self:combatMindpower()})
+					else
+						game.logSeen(rt, "%s resists the pin!", rt.name:capitalize())
+					end
+					if target:attr("frozen") then
+						DamageType:get(DamageType.PHYSICAL).projector(self, x, y, DamageType.PHYSICAL, dam)
+					end
+				end
 			end
 		end
-		
 		return true
 	end,
 	info = function(self, t)
 		return ([[Focus kinetic energy and strike an enemy for %d%% weapon damage as physical.
-		They will then be thrown back by the force of the hit, taking an extra %0.1f Physical damage if they hit a wall, where they will be pinned for 4 turns.
-		The knockback damage will scale with your Mindpower.]]):
-		format(100 * self:combatTalentWeaponDamage(t, 0.5, 2.0), damDesc(self, DamageType.PHYSICAL, t.getDam(self, t)))
+		They will be pinned to the ground for %d turns by the force of this attack.
+		Any frozen creature hit by this attack will take an extra %0.1f physical damage.
+		The extra damage will scale with your Mindpower.]]):
+		format(100 * self:combatTalentWeaponDamage(t, 0.5, 2.0), t.getDur(self, t), damDesc(self, DamageType.PHYSICAL, t.getDam(self, t)))
 	end,
 }
 
@@ -88,7 +115,8 @@ newTalent{
 	range = 1,
 	requires_target = true,
 	tactical = { ATTACK = { COLD = 2 } },
-	getDam = function(self, t) return self:combatTalentMindDamage(t, 10, 100) end,
+	getDam = function(self, t) return self:combatTalentMindDamage(t, 20, 200) end,
+	getDur = function(self, t) return self:combatTalentScale(t, 2.0, 6.0) end,
 	action = function(self, t)
 		local weapon = self:getInven("MAINHAND") and self:getInven("MAINHAND")[1]
 		if type(weapon) == "boolean" then weapon = nil end
@@ -101,26 +129,27 @@ newTalent{
 		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 = self:mindCrit(t.getDam(self, t))
+		local dur = t.getDur(self, t)
 
 		local hit = self:attackTarget(target, DamageType.COLD, self:combatTalentWeaponDamage(t, 0.5, 2.0), true)
 		if hit then
 			if self:hasEffect(self.EFF_TRANSCENDENT_PYROKINESIS) then
 				local tg = {type="ball", range=1, radius=1, friendlyfire=false}
 				self:project(tg, x, y, DamageType.COLD, dam)
-				self:project(tg, x, y, DamageType.FREEZE, {dur=4, hp=dam})
+				self:project(tg, x, y, DamageType.FREEZE, {dur=dur, hp=dam})
 				game.level.map:particleEmitter(x, y, tg.radius, "iceflash", {radius=1})
 			else
 				DamageType:get(DamageType.COLD).projector(self, x, y, DamageType.COLD, dam)
-				DamageType:get(DamageType.FREEZE).projector(self, x, y, DamageType.FREEZE, {dur=4, hp=dam})
+				DamageType:get(DamageType.FREEZE).projector(self, x, y, DamageType.FREEZE, {dur=dur, hp=dam})
 			end
 		end
 		return true
 	end,
 	info = function(self, t)
 		return ([[Focus thermal energy and strike an enemy for %d%% weapon damage as cold.
-		A burst of cold will then engulf them, doing an extra %0.1f Cold damage and also freeze them for 4 turns.
+		A burst of cold will then engulf them, doing an extra %0.1f Cold damage and also freeze them for %d turns.
 		The cold burst damage will scale with your Mindpower.]]):
-		format(100 * self:combatTalentWeaponDamage(t, 0.5, 2.0), damDesc(self, DamageType.COLD, t.getDam(self, t)))
+		format(100 * self:combatTalentWeaponDamage(t, 0.5, 2.0), damDesc(self, DamageType.COLD, t.getDam(self, t)), t.getDur(self, t))
 	end,
 }
 
@@ -135,7 +164,8 @@ newTalent{
 	range = 1,
 	requires_target = true,
 	tactical = { ATTACK = { LIGHTNING = 2 } },
-	getDam = function(self, t) return self:combatTalentMindDamage(t, 10, 100) end,
+	getDam = function(self, t) return self:combatTalentMindDamage(t, 20, 200) end,
+	getDur = function(self, t) return self:combatTalentScale(t, 2.0, 6.0) end,
 	action = function(self, t)
 		local weapon = self:getInven("MAINHAND") and self:getInven("MAINHAND")[1]
 		if type(weapon) == "boolean" then weapon = nil end
@@ -148,6 +178,7 @@ newTalent{
 		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 = self:mindCrit(t.getDam(self, t))
+		local dur = t.getDur(self, t)
 
 		local hit = self:attackTarget(target, DamageType.LIGHTNING, self:combatTalentWeaponDamage(t, 0.5, 2.0), true)
 		if hit then
@@ -195,7 +226,7 @@ newTalent{
 					local tgr = {type="beam", range=self:getTalentRange(t), selffire=false, talent=t, x=sx, y=sy}
 					print("[Chain lightning] jumping from", sx, sy, "to", actor.x, actor.y)
 					self:project(tgr, actor.x, actor.y, DamageType.LIGHTNING, dam)
-					self:project(tgr, actor.x, actor.y, DamageType.BLINDCUSTOMMIND, {apply_power=self:combatMindpower(), turns=4})
+					actor:setEffect(actor.EFF_SHOCKED, dur, {apply_power=self:combatMindpower()})
 					if core.shader.active() then game.level.map:particleEmitter(sx, sy, math.max(math.abs(actor.x-sx), math.abs(actor.y-sy)), "lightning_beam", {tx=actor.x-sx, ty=actor.y-sy}, {type="lightning"})
 					else game.level.map:particleEmitter(sx, sy, math.max(math.abs(actor.x-sx), math.abs(actor.y-sy)), "lightning_beam", {tx=actor.x-sx, ty=actor.y-sy})
 					end
@@ -204,16 +235,19 @@ newTalent{
 				end
 			else
 				DamageType:get(DamageType.LIGHTNING).projector(self, x, y, DamageType.LIGHTNING, dam)
-				DamageType:get(DamageType.BLINDCUSTOMMIND).projector(self, x, y, DamageType.BLINDCUSTOMMIND, {apply_power=self:combatMindpower(), turns=4})
+				local actor = game.level.map(x, y, Map.ACTOR)
+				if actor then
+					actor:setEffect(actor.EFF_SHOCKED, dur, {apply_power=self:combatMindpower()})
+				end
 			end
 		end
 		return true
 	end,
 	info = function(self, t)
 		return ([[Focus charged energy and strike an enemy for %d%% weapon damage as lightning.
-		Energy will then discharge from your weapon, doing an extra %0.1f Lightning damage and blinding them for 4 turns.
+		Energy will then discharge from your weapon, doing an extra %0.1f Lightning damage and halving their stun/daze/freeze resistance for %d turns.
 		The discharge damage will scale with your Mindpower.]]):
-		format(100 * self:combatTalentWeaponDamage(t, 0.5, 2.0), damDesc(self, DamageType.LIGHTNING, t.getDam(self, t)))
+		format(100 * self:combatTalentWeaponDamage(t, 0.5, 2.0), damDesc(self, DamageType.LIGHTNING, t.getDam(self, t)), t.getDur(self, t))
 	end,
 }
 
@@ -223,12 +257,13 @@ newTalent{
 	mode = "passive",
 	points = 5,
 	require = psi_wil_req4,
-	getPsiRecover = function(self, t) return self:combatTalentScale(t, 1, 3) end,
+	getPsiRecover = function(self, t) return self:combatTalentScale(t, 1.0, 3.0) end,
 	passives = function(self, t, p)
 		self:talentTemporaryValue(p, "psi_regen_on_hit", t.getPsiRecover(self, t))
+		self:talentTemporaryValue(p, "combat_apr", t.getPsiRecover(self, t)*3)
 	end,
 	info = function(self, t)
-		return ([[Siphon excess energy from each weapon hit you land, gaining %0.1f psi per hit.]]):format(t.getPsiRecover(self, t))
+		return ([[Wrap a psionic energy field around you weapons, increasing their armour penentration by %d and allowing you to siphon excess energy from each weapon hit you land, gaining %0.1f psi per hit.]]):format(t.getPsiRecover(self, t)*3, t.getPsiRecover(self, t))
 	end,
 }
 
diff --git a/game/modules/tome/data/talents/psionic/charged-mastery.lua b/game/modules/tome/data/talents/psionic/charged-mastery.lua
index b16c6e0950a0152c38937e538bd35ae563489a2b..7ed2c43b2b0d2292528d5ffd2024efa84da37259 100644
--- a/game/modules/tome/data/talents/psionic/charged-mastery.lua
+++ b/game/modules/tome/data/talents/psionic/charged-mastery.lua
@@ -107,7 +107,7 @@ newTalent{
 			DamageType.STATIC_NET, {dam=t.getDamage(self, t), slow=t.getSlow(self, t), weapon=t.getWeaponDamage(self, t)},
 			self:getTalentRadius(t),
 			5, nil,
-			{type="ice_vapour"},
+			MapEffect.new{color_br=30, color_bg=100, color_bb=160, effect_shader="shader_images/retch_effect.png"},
 			nil, true
 		)
 		game:playSoundNear(self, "talents/lightning")
diff --git a/game/modules/tome/data/talents/psionic/finer-energy-manipulations.lua b/game/modules/tome/data/talents/psionic/finer-energy-manipulations.lua
index 77add76ce8af4dcbc0cf4cb1724681a07900d519..23c9c1c230eed978b76ec4756888b29755d218e0 100644
--- a/game/modules/tome/data/talents/psionic/finer-energy-manipulations.lua
+++ b/game/modules/tome/data/talents/psionic/finer-energy-manipulations.lua
@@ -53,12 +53,10 @@ newTalent{
 			end
 		end
 
-
 		for i = 1, t.numCure(self, t) do
 			if #effs == 0 then break end
 			local eff = rng.tableRemove(effs)
 
-
 			if eff[1] == "effect" then
 				self:removeEffect(eff[2])
 				known = true
@@ -195,33 +193,7 @@ newTalent{
 			self:setEffect(self.EFF_PSI_REGEN, dur, {power=amt})
 			self.changed = true
 			d.used_talent = true
-			local gem_names = {
-				GEM_DIAMOND = "Diamond",
-				GEM_PEARL = "Pearl",
-				GEM_MOONSTONE = "Moonstone", 
-				GEM_FIRE_OPAL = "Fire Opal",
-				GEM_BLOODSTONE = "Bloodstone",
-				GEM_RUBY = "Ruby",
-				GEM_AMBER = "Amber",
-				GEM_TURQUOISE = "Turquoise",
-				GEM_JADE = "Jade",
-				GEM_SAPPHIRE = "Sapphire",
-				GEM_QUARTZ = "Quartz",
-				GEM_EMERALD = "Emerald",
-				GEM_LAPIS_LAZULI = "Lapis Lazuli",
-				GEM_GARNET = "Garnet",
-				GEM_ONYX = "Onyx",
-				GEM_AMETHYST = "Amethyst", 
-				GEM_OPAL = "Opal", 
-				GEM_TOPAZ = "Topaz",
-				GEM_AQUAMARINE = "Aquamarine",
-				GEM_AMETRINE = "Ametrine",
-				GEM_ZIRCON = "Zircon",
-				GEM_SPINEL = "Spinel",
-				GEM_CITRINE = "Citrine",
-				GEM_AGATE = "Agate",
-			}
-			self:setEffect(self.EFF_CRYSTAL_BUFF, dur, {name=gem_names[gem.define_as], gem=gem.define_as})
+			self:setEffect(self.EFF_CRYSTAL_BUFF, dur, {name=gem.name, effects=gem.wielder})
 		end)
 		local co = coroutine.running()
 		d.unload = function(self) coroutine.resume(co, self.used_talent) end
@@ -259,9 +231,9 @@ newTalent{
 	info = function(self, t)
 		local inc = t.bonus(self,t)
 		return ([[By carefully synchronizing your mind to the resonant frequencies of your psionic focus, you strengthen its effects.
-		For conventional weapons, this increases the percentage of your willpower and cunning that is used in place of strength and dexterity, from 80%% to %d%%.
-		For mindstars, this increases the chance to pull enemies to you by +%d%%.
+		For conventional weapons, this increases the percentage of your willpower and cunning that is used in place of strength and dexterity, from 60%% to %d%%.
+		For mindstars, this increases the amount of Psi you can store by +%d.
 		For gems, this increases the bonus stats by %d.]]):
-		format(80+inc, inc, math.ceil(inc/5))
+		format(60+inc, inc, math.ceil(inc/5))
 	end,
 }
diff --git a/game/modules/tome/data/talents/psionic/focus.lua b/game/modules/tome/data/talents/psionic/focus.lua
index ba6e38ad5cabc090379a187bd27ca48c3ab30c23..5650bd92d9eaf72bcfaa1d13700ed1d31d5d409e 100644
--- a/game/modules/tome/data/talents/psionic/focus.lua
+++ b/game/modules/tome/data/talents/psionic/focus.lua
@@ -76,7 +76,7 @@ newTalent{
 	range = 0,
 	radius = function(self,t) return self:combatTalentScale(t, 4, 6) end,
 	getDamage = function (self, t)
-		return self:combatTalentMindDamage(t, 50, 480)
+		return self:combatTalentMindDamage(t, 20, 450)
 	end,
 	target = function(self, t)
 		return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), friendlyfire=false}
@@ -110,7 +110,7 @@ newTalent{
 	range = function(self,t) return self:combatTalentScale(t, 3, 5) end,
 	radius = function(self,t) return self:combatTalentScale(t, 2, 3) end,
 	tactical = { DISABLE = 2, ATTACKAREA = { LIGHTNING = 2 } },
-	getDamage = function(self, t) return self:combatTalentMindDamage(t, 30, 300) end,
+	getDamage = function(self, t) return self:combatTalentMindDamage(t, 20, 290) end,
 	action = function(self, t)		
 		local tg = {type="ball", range=self:getTalentRange(t), selffire=false, radius=self:getTalentRadius(t), talent=t}
 		local x, y = self:getTarget(tg)
@@ -150,13 +150,13 @@ newTalent{
 	require = psi_wil_req4,
 	points = 5,
 	mode = "passive",
-	stunImmune = function(self, t) return self:combatTalentLimit(t, 1, 0.10, 0.50) end,
-	cureChance = function(self, t) return self:combatTalentLimit(t, 1, 0.10, 0.35) end,
+	stunImmune = function(self, t) return self:combatTalentLimit(t, 1, 0.10, 0.40) end,
+	cureChance = function(self, t) return self:combatTalentLimit(t, 1, 0.10, 0.30) end,
 	passives = function(self, t, p)
 		self:talentTemporaryValue(p, "stun_immune", t.stunImmune(self, t))
 	end,
 	callbackOnActBase = function(self, t)
-		if not rng.chance(t.cureChance(self, t)*100) then return end
+		if not rng.percent(t.cureChance(self, t)*100) then return end
 	
 		local effs = {}
 		-- Go through all spell effects
@@ -170,7 +170,7 @@ newTalent{
 		if #effs > 0 then
 			local eff = rng.tableRemove(effs)
 			self:removeEffect(eff[2])
-			game.logSeen(self, "%s has recovered!", self.name:capitalize())
+			game.logSeen(self, "#ORCHID#%s has recovered!", self.name:capitalize())
 		end
 	end,
 	info = function(self, t)
diff --git a/game/modules/tome/data/talents/psionic/kinetic-mastery.lua b/game/modules/tome/data/talents/psionic/kinetic-mastery.lua
index 7df2cb19baadb5a7712a4f9f4ef2045cec6eb3ae..5215f10037402811105df901394754162ca2ea7a 100644
--- a/game/modules/tome/data/talents/psionic/kinetic-mastery.lua
+++ b/game/modules/tome/data/talents/psionic/kinetic-mastery.lua
@@ -53,68 +53,108 @@ newTalent{
 	end,
 }
 
+
 newTalent{
-	name = "Telekinetic Throw",
+	name = "Kinetic Surge",
 	type = {"psionic/kinetic-mastery", 2},
 	require = psi_wil_high2,
 	points = 5,
 	random_ego = "attack",
 	cooldown = 15,
 	psi = 20,
-	tactical = { ATTACK = { PHYSICAL = 2 } },
-	range = function(self, t) return math.floor(self:combatStatScale("str", 1, 5) + self:combatMindpower()/20) end,
+	tactical = { CLOSEIN = 2, ATTACK = { PHYSICAL = 2 }, ESCAPE = 2 },
+	range = function(self, t) return self:combatTalentLimit(t, 10, 6, 9) end,
 	getDamage = function (self, t)
-		return math.floor(self:combatTalentMindDamage(t, 10, 170))
+		return math.floor(self:combatTalentMindDamage(t, 20, 180))
 	end,
 	getKBResistPen = function(self, t) return self:combatTalentLimit(t, 100, 25, 45) end,
 	requires_target = true,
 	target = function(self, t) return {type="ball", range=self:getTalentRange(t), radius=2, selffire=false, talent=t} end,
 	action = function(self, t)
-		local tg = {type="hit", range=1}
+		local tg = {type="hit", range=1, nowarning=true }
 		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 tg = self:getTalentTarget(t)
-		local x, y = self:getTarget(tg)
-		if not x or not y then return nil end
 		local dam = self:mindCrit(t.getDamage(self, t))
-		
-		if target:canBe("knockback") or rng.percent(t.getKBResistPen(self, t)) then
-			self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam) --Direct Damage
-			
-		local tx, ty = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true})
-		if tx and ty then
-			local ox, oy = target.x, target.y
-			target:move(tx, ty, true)
-			if config.settings.tome.smooth_move > 0 then
-				target:resetMoveAnim()
-				target:setMoveAnim(ox, oy, 8, 5)
+				
+		if self:reactionToward(target) < 0 then
+			local tg = self:getTalentTarget(t)
+			local x, y = self:getTarget(tg)
+			if not x or not y then return nil end
+
+			if target:canBe("knockback") or rng.percent(t.getKBResistPen(self, t)) then
+				self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam) --Direct Damage
+				
+				local tx, ty = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true})
+				if tx and ty then
+					local ox, oy = target.x, target.y
+					target:move(tx, ty, true)
+					if config.settings.tome.smooth_move > 0 then
+						target:resetMoveAnim()
+						target:setMoveAnim(ox, oy, 8, 5)
+					end
+				end
+				self:project(tg, target.x, target.y, DamageType.SPELLKNOCKBACK, dam/2) --AOE damage
+				if target:canBe("stun") then
+					target:setEffect(target.EFF_STUNNED, math.floor(self:getTalentRange(t) / 2), {apply_power=self:combatMindpower()})
+				else
+					game.logSeen(target, "%s resists the stun!", target.name:capitalize())
+				end
+			else --If the target resists the knockback, do half damage to it.
+				target:logCombat(self, "#YELLOW##Source# resists #Target#'s throw!")
+				self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam/2)
 			end
-		end
-		self:project(tg, target.x, target.y, DamageType.SPELLKNOCKBACK, dam/2) --AOE damage
-		if target:canBe("stun") then
-			target:setEffect(target.EFF_STUNNED, 4, {apply_power=self:combatMindpower()})
 		else
-			game.logSeen(target, "%s resists the stun!", target.name:capitalize())
-		end
-		else --If the target resists the knockback, do half damage to it.
-			target:logCombat(self, "#YELLOW##Source# resists #Target#'s throw!")
-			self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam/2)
+			local tg = {type="beam", range=self:getTalentRange(t), nolock=true, talent=t, display={particle="bolt_earth", trail="earthtrail"}}
+			local x, y = self:getTarget(tg)
+			if not x or not y then return nil end
+			if core.fov.distance(self.x, self.y, x, y) > tg.range then return nil end
+
+			for i = 1, math.floor(self:getTalentRange(t) / 2) do
+				self:project(tg, x, y, DamageType.DIG, 1)
+			end
+			self:project(tg, x, y, DamageType.MINDKNOCKBACK, dam)
+			local _ _, x, y = self:canProject(tg, x, y)
+			game.level.map:particleEmitter(self.x, self.y, tg.radius, "flamebeam", {tx=x-self.x, ty=y-self.y})
+			game:playSoundNear(self, "talents/lightning")
+
+			local block_actor = function(_, bx, by) return game.level.map:checkEntity(bx, by, engine.Map.TERRAIN, "block_move", self) end
+			local l = self:lineFOV(x, y, block_actor)
+			local lx, ly, is_corner_blocked = l:step()
+			local tx, ty = self.x, self.y
+			while lx and ly do
+				if is_corner_blocked or block_actor(_, lx, ly) then break end
+				tx, ty = lx, ly
+				lx, ly, is_corner_blocked = l:step()
+			end
+
+			--self:move(tx, ty, true)
+			local fx, fy = util.findFreeGrid(tx, ty, 5, true, {[Map.ACTOR]=true})
+			if not fx then
+				self:move(fx, fy, true)
+			end
+			return true
 		end
 		return true
 	end,
 	info = function(self, t)
 		local range = self:getTalentRange(t)
 		local dam = damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t))
-		return ([[Use your telekinetic power to enhance your strength, allowing you to pick up an adjacent enemy and hurl it anywhere within radius %d. 
-		Upon landing, your target takes %0.1f Physical damage and is stunned for 4 turns.  All other creatures within radius 2 of the landing point take %0.1f Physical damage and are knocked away from you.
+		return ([[Build telekinetic power and dump it onto an adjacent creature or yourself. 
+		This will launch them to where ever you target in a radius of %d. 
+		
+		Upon landing, launched enemy takes %0.1f Physical damage and is stunned for %d turns.  
+		All other creatures within radius 2 of the landing point take %0.1f Physical damage and are knocked away from you.
 		This talent ignores %d%% of the knockback resistance of the thrown target, which takes half damage if it resists being thrown.
+		
+		When used on yourself, you will launch in a straight line, knocking enemies flying and doing %0.1f Physical damage to each.
+		You can break through %d walls while doing this.
 		The damage improves with your Mindpower and the range increases with both Mindpower and Strength.]]):
-		format(range, dam, dam/2, t.getKBResistPen(self, t))
+		format(range, dam, math.floor(range/2), dam/2, t.getKBResistPen(self, t), dam, math.floor(range/2))
 	end,
 }
 
+
 newTalent{
 	name = "Deflect Projectiles",
 	type = {"psionic/kinetic-mastery", 3},
diff --git a/game/modules/tome/data/talents/psionic/other.lua b/game/modules/tome/data/talents/psionic/other.lua
index 9dd24c3e671ec8fdc09136796b6af858948fb91c..4e1619ad48258b7df080ca8c13ad0c4c9d27a1d1 100644
--- a/game/modules/tome/data/talents/psionic/other.lua
+++ b/game/modules/tome/data/talents/psionic/other.lua
@@ -249,7 +249,7 @@ newTalent{
 
 		local ret = {}
 		if tk.type == "gem" then
-			local power = (tk.material_level or 1) * 4 + math.ceil(self:callTalent(self.T_RESONANT_FOCUS, "bonus") / 5)
+			local power = (tk.material_level or 1) * 3 + math.ceil(self:callTalent(self.T_RESONANT_FOCUS, "bonus") / 5)
 			self:talentTemporaryValue(ret, "inc_stats", {
 				[self.STAT_STR] = power,
 				[self.STAT_DEX] = power,
@@ -273,7 +273,7 @@ newTalent{
 	end,
 	info = function(self, t)
 		local base = [[Allows you to wield a physical melee weapon, a mindstar or a gem telekinetically, gaining a special effect for each.
-		A gem will provide +4 bonus to all primary stats per tier of the gem.
+		A gem will provide +3 bonus to all primary stats per tier of the gem.
 		A mindstar will randomly try to telekinetically grab a far away foe (5% chance and range 2 for a tier 1 mindstar, +1 range and +5% chance for each tier above 1) and pull it into melee range.
 		A physical melee weapon will act as a semi independant entity, attacking foes nearby each turn while also replacing Strength and Dexterity with Willpower and Cunning for accuracy and damage calculations (for all melee weapons).
 
diff --git a/game/modules/tome/data/talents/psionic/projection.lua b/game/modules/tome/data/talents/psionic/projection.lua
index dd93752e85db4a76bd4bfb3ffa2987cecace3aaf..cf458ca3d65e5764d088e6c0d75167069801e2f5 100644
--- a/game/modules/tome/data/talents/psionic/projection.lua
+++ b/game/modules/tome/data/talents/psionic/projection.lua
@@ -469,7 +469,7 @@ newTalent{
 	points = 5,
 	tactical = { ATTACK = { PHYSICAL = 3 } },
 	getTargNum = function(self,t)
-		return math.ceil(self:combatTalentScale(t, 1.2, 2.1, "log"))
+		return math.ceil(self:combatTalentScale(t, 1.0, 3.0, "log"))
 	end,
 	getDamage = function (self, t)
 		return math.floor(self:combatTalentMindDamage(t, 10, 200))
@@ -483,9 +483,8 @@ newTalent{
 		local targets = t.getTargNum(self,t)
 		local dur = t.duration(self,t)
 		return ([[Overcharge your psionic focus with energy for %d turns, producing a different effect depending on what it is.
-		A telekinetically wielded weapon enters a frenzy, striking up to %d targets every turn, also increases the radius by %d.
-		A mindstar will attempt to pull in all enemies within its normal range.
-		A gem will fire an energy bolt at a random enemy in range 6, each turn for %0.1f damage. The type is determined by the colour of the gem. Damage scales with Mindpower.]]):
+		A telekinetically wielded weapon enters a frenzy, striking up to %d times every turn, also increases the radius by %d.
+		A mindstar or a gem will fire an energy bolt at a random enemy in range 6, each turn for %0.1f damage. The type is determined by the colour of the gem or mindstar base damage. Damage scales with Mindpower. The mindstar will stop its normal attacks.]]):
 		format(dur, targets, targets, t.getDamage(self,t))
 	end,
 }
diff --git a/game/modules/tome/data/talents/psionic/psi-fighting.lua b/game/modules/tome/data/talents/psionic/psi-fighting.lua
index 4619e0f00ff969a24526009aa9102e6f1301e2e4..356b564b717575cb29d3d279b9d2b7643b552ec3 100644
--- a/game/modules/tome/data/talents/psionic/psi-fighting.lua
+++ b/game/modules/tome/data/talents/psionic/psi-fighting.lua
@@ -110,6 +110,7 @@ newTalent{
 	no_energy = true,
 	tactical = { BUFF = 2 },
 	getWeaponDamage = function(self, t) return self:combatTalentWeaponDamage(t, 0.75, 1.1) end,
+	getChance = function(self, t) return math.floor(self:combatStatScale("cun", 1, 30)) end,
 	action = function(self, t)
 		self:setEffect(self.EFF_WEAPON_WARDING, 1, {})
 		return true
@@ -117,9 +118,10 @@ newTalent{
 	info = function(self, t)
 		return ([[Assume a defensive mental state.
 		For one turn, you will fully block the next melee attack used against you with your telekinetically-wielded weapon and then strike the attacker with it for %d%% weapon damage. 
-		At talent level 3 you will also disarm the attacker for 3 turns.
-		This requires both a mainhand and a telekinetically-wielded weapon.]]):
-		format(100 * t.getWeaponDamage(self, t))
+		At raw talent level 3 you will also disarm the attacker for 3 turns.
+		At raw talent level 5 you will be able to reflexively block up to one attack per turn with a %d%% chance, based on your cunning. Each trigger requires and uses 15 Psi.
+		This requires a telekinetically-wielded weapon.]]):
+		format(100 * t.getWeaponDamage(self, t), t.getChance(self, t))
 	end,
 }
 
diff --git a/game/modules/tome/data/talents/psionic/thermal-mastery.lua b/game/modules/tome/data/talents/psionic/thermal-mastery.lua
index 508e9827248de50d6f004275742dfa1c0364b76a..9a16dd093cc5627fedbbc4b779e5a09ddccac8ed 100644
--- a/game/modules/tome/data/talents/psionic/thermal-mastery.lua
+++ b/game/modules/tome/data/talents/psionic/thermal-mastery.lua
@@ -155,8 +155,8 @@ newTalent{
 	cooldown = 10,
 	range = function(self,t) return self:combatTalentScale(t, 4, 6) end,
 	radius = function(self,t) return self:combatTalentScale(t, 2, 4) end,
-	tactical = { ATTACKAREA = { FIRE = 2, COLD = 2 } },
-	getDamage = function(self, t) return self:combatTalentMindDamage(t, 30, 300) end,
+	tactical = { ATTACKAREA = { FIRE = 3, COLD = 2 }, PSI = 2 },
+	getDamage = function(self, t) return self:combatTalentMindDamage(t, 50, 150) end,
 	action = function(self, t)
 		local tg = {type="ball", range=self:getTalentRange(t), selffire=false, radius=self:getTalentRadius(t), talent=t}
 		local x, y = self:getTarget(tg)
@@ -180,7 +180,7 @@ newTalent{
 	info = function(self, t)
 		local dam = t.getDamage(self, t)
 		local dam1 = dam * (self:getMaxPsi() - self:getPsi()) / self:getMaxPsi()
-		local dam2 = dam * self:getPsi() / self:getMaxPsi()
+		local dam2 = dam * self:getPsi() / self:getMaxPsi() * 2
 		return ([[You seek balance between fire and cold based on your current Psi level.
 		You blast your foes with %0.1f Fire damage based on your current Psi, %0.1f Cold damage based on your max Psi minus your current Psi, in a radius %d ball.
 		This sets your current Psi to half of your maximum Psi.
diff --git a/game/modules/tome/data/talents/psionic/voracity.lua b/game/modules/tome/data/talents/psionic/voracity.lua
index 97f665bf90488dd1c8aa0237d29a24ae4715ae1d..dd766be58ac83c765f75b10c1f867103eae5f75e 100644
--- a/game/modules/tome/data/talents/psionic/voracity.lua
+++ b/game/modules/tome/data/talents/psionic/voracity.lua
@@ -37,11 +37,11 @@ newTalent{
 	end,
 	getLeech = function(self, t, psi)
 		local psi = psi or self:getPsi()
-		return self:combatTalentScale(t, 10, 27)*math.max(0.5, (1.5-psi/self:getMaxPsi()))
+		return self:combatTalentScale(t, 10, 20)*math.max(0.5, (1.5-psi/self:getMaxPsi()))
 	end,
 	getDam = function(self, t, psi)
 		local psi = psi or self:getPsi()
-		return self:combatTalentMindDamage(t, 20, 200)*math.max(0.5, (1.5-psi/self:getMaxPsi())) --this looks high
+		return self:combatTalentMindDamage(t, 5, 45)*math.max(0.5, (1.5-psi/self:getMaxPsi())) --this looks high
 	end,
 	getSlow = function(self, t, psi)
 		local psi = psi or self:getPsi()
@@ -103,11 +103,11 @@ newTalent{
 	end,
 	getLeech = function(self, t, psi)
 		local psi = psi or self:getPsi()
-		return self:combatTalentScale(t, 10, 27)*math.max(0.5, (1.5-psi/self:getMaxPsi()))
+		return self:combatTalentScale(t, 10, 20)*math.max(0.5, (1.5-psi/self:getMaxPsi()))
 	end,
 	getDam = function(self, t, psi)
 		local psi = psi or self:getPsi()
-		return self:combatTalentMindDamage(t, 20, 200)*math.max(0.5, (1.5-psi/self:getMaxPsi()))
+		return self:combatTalentMindDamage(t, 20, 130)*math.max(0.5, (1.5-psi/self:getMaxPsi()))
 	end,
 	getDur = function(self, t, psi)
 		local psi = psi or self:getPsi()
@@ -163,11 +163,11 @@ newTalent{
 	end,
 	getLeech = function(self, t, psi)
 		local psi = psi or self:getPsi()
-		return self:combatTalentScale(t, 10, 27)*math.max(0.5, (1.5-psi/self:getMaxPsi()))
+		return self:combatTalentScale(t, 10, 20)*math.max(0.5, (1.5-psi/self:getMaxPsi()))
 	end,
 	getDam = function(self, t, psi)
 		local psi = psi or self:getPsi()
-		return self:combatTalentMindDamage(t, 20, 200)*math.max(0.5, (1.5-psi/self:getMaxPsi()))
+		return self:combatTalentMindDamage(t, 20, 130)*math.max(0.5, (1.5-psi/self:getMaxPsi()))
 	end,
 	getDaze = function(self, t, psi)
 		local psi = psi or self:getPsi()
@@ -222,13 +222,13 @@ newTalent{
 	getPsiRecover = function(self, t) return self:combatTalentScale(t, 1.5, 5, 0.75) end,
 	passives = function(self, t, p)
 		local recover = t.getPsiRecover(self, t)
-		self:talentTemporaryValue(p, "max_psi", self:getTalentLevel(t)*10)
+		self:talentTemporaryValue(p, "max_psi", recover*5)
 		self:talentTemporaryValue(p, "psi_per_kill", recover)
 		self:talentTemporaryValue(p, "psi_on_crit", recover*0.5)
 	end,
 	info = function(self, t)
 		local recover = t.getPsiRecover(self, t)
-		return ([[Increases your maximum energy by %d. You also gain %0.1f Psi for each kill and %0.1f Psi for each mind critical.]]):format(10 * self:getTalentLevel(t), recover, 0.5*recover)
+		return ([[Increases your maximum energy by %d. You also gain %0.1f Psi for each kill and %0.1f Psi for each mind critical.]]):format(5 * recover, recover, 0.5*recover)
 	end,
 }
 
diff --git a/game/modules/tome/data/timed_effects/mental.lua b/game/modules/tome/data/timed_effects/mental.lua
index a3ea9d68b2df2224daa3d7f3574cfcf1cb46ec7b..ca2b508f6def15f55477a3b8bf49c3a22892a6e5 100644
--- a/game/modules/tome/data/timed_effects/mental.lua
+++ b/game/modules/tome/data/timed_effects/mental.lua
@@ -1336,7 +1336,7 @@ newEffect{
 newEffect{
 	name = "QUICKNESS", image = "effects/quickness.png",
 	desc = "Quick",
-	long_desc = function(self, eff) return ("Increases physical attack speed by %d%%."):format(eff.power * 100) end,
+	long_desc = function(self, eff) return ("Increases global speed by %d%%."):format(eff.power * 100) end,
 	type = "mental",
 	subtype = { telekinesis=true, speed=true },
 	status = "beneficial",
@@ -1344,12 +1344,13 @@ newEffect{
 	on_gain = function(self, err) return "#Target# speeds up.", "+Quick" end,
 	on_lose = function(self, err) return "#Target# slows down.", "-Quick" end,
 	activate = function(self, eff)
-		eff.tmpid = self:addTemporaryValue("combat_physspeed", eff.power)
+		eff.tmpid = self:addTemporaryValue("global_speed_add", eff.power)
 	end,
 	deactivate = function(self, eff)
-		self:removeTemporaryValue("combat_physspeed", eff.tmpid)
+		self:removeTemporaryValue("global_speed_add", eff.tmpid)
 	end,
 }
+
 newEffect{
 	name = "PSIFRENZY", image = "talents/frenzied_focus.png",
 	desc = "Frenzied Focus",
@@ -3118,6 +3119,7 @@ newEffect{
 	on_lose = function(self, eff) return nil, nil end,
 	on_merge = function(self, old_eff, new_eff)
 		old_eff.power = new_eff.power + old_eff.power
+		old_eff.dur = new_eff.dur
 		return old_eff
 	end,
 	activate = function(self, eff)