diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 6a1cfe758177cb6e824233b78449dc458c2771c5..2b5f2a6f808d458223bd57346ed39513847b5e74 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -327,6 +327,24 @@ function _M:useEnergy(val)
 end
 
 function _M:actBase()
+	-- Solipsism speed effects
+	local current_psi_percentage = self:getPsi() / self:getMaxPsi()
+	if self:attr("solipsism_threshold") and current_psi_percentage < self:attr("solipsism_threshold") then
+		if self:hasEffect(self.EFF_CLARITY) then
+			self:removeEffect(self.EFF_CLARITY)
+		end
+		self:setEffect(self.EFF_SOLIPSISM, 1, {power = self:attr("solipsism_threshold") - current_psi_percentage})
+	elseif self:attr("clarity_threshold") and current_psi_percentage > self:attr("clarity_threshold") then
+		if self:hasEffect(self.EFF_SOLIPSISM) then
+			self:removeEffect(self.EFF_SOLIPSISM)
+		end
+		self:setEffect(self.EFF_CLARITY, 1, {power = current_psi_percentage - self:attr("clarity_threshold")})
+	elseif self:hasEffect(self.EFF_SOLIPSISM) then
+		self:removeEffect(self.EFF_SOLIPSISM)
+	elseif self:hasEffect(self.EFF_CLARITY) then
+		self:removeEffect(self.EFF_CLARITY)
+	end
+
 	self.energyBase = self.energyBase - game.energy_to_act
 
 	if self:attr("no_timeflow") then
@@ -361,6 +379,11 @@ function _M:actBase()
 	end
 
 	self:regenResources()
+	
+	-- update psionic feedback
+	if self.psionic_feedback and self.psionic_feedback > 0 then
+		self.psionic_feedback = math.max(0, self.psionic_feedback - 1)
+	end
 
 	-- Compute timed effects
 	self:timedEffects()
@@ -1304,7 +1327,23 @@ end
 --- Regenerate life, call it from your actor class act() method
 function _M:regenLife()
 	if self.life_regen and not self:attr("no_life_regen") then
-		self.life = util.bound(self.life + self.life_regen * util.bound((self.healing_factor or 1), 0, 2.5), self.die_at, self.max_life)
+		local regen = self.life_regen * util.bound((self.healing_factor or 1), 0, 2.5)
+		
+		-- Psionic Balance
+		if self:knowTalent(self.T_BALANCE) then
+			local t = self:getTalentFromId(self.T_BALANCE)
+			local ratio = t.getBalanceRatio(self, t)
+			local psi_increase = regen * ratio
+			self:incPsi(psi_increase)
+			-- Quality of life hack, doesn't decrease life regen while resting..  was way to painful
+			if not self.resting then
+				regen = regen - psi_increase
+			end
+		end
+		
+		self.life = util.bound(self.life + regen, self.die_at, self.max_life)
+		
+		-- Blood Lock
 		if self:attr("blood_lock") then
 			self.life = util.bound(self.life, self.die_at, self:attr("blood_lock"))
 		end
@@ -1355,6 +1394,15 @@ function _M:onHeal(value, src)
 		self:setEffect(self.EFF_REGENERATION, 6, {power=(value * self.fungal_growth / 100) / 6, no_wild_growth=true})
 	end
 
+	-- Psionic Balance
+	if self:knowTalent(self.T_BALANCE) then
+		local t = self:getTalentFromId(self.T_BALANCE)
+		local ratio = t.getBalanceRatio(self, t)
+		local psi_increase = value * ratio
+		self:incPsi(psi_increase)
+		value = value - psi_increase
+	end
+	
 	-- Must be last!
 	if self:attr("blood_lock") then
 		if self.life + value > self:attr("blood_lock") then
@@ -1532,13 +1580,27 @@ function _M:onTakeHit(value, src)
 			t.explode(self, t, dam)
 		end
 	end
+	
+	if self:attr("resonance_shield") then
+	-- Absorb damage into the shield
+		if value / 2 <= self.resonance_shield_absorb then
+			self.resonance_shield_absorb = self.resonance_shield_absorb - (value / 2)
+			value = value / 2
+		else
+			value = value - self.resonance_shield_absorb
+			self.resonance_shield_absorb = 0
+		end
+		if self.resonance_shield_absorb <= 0 then
+			self:removeEffect(self.EFF_RESONANCE_SHIELD)
+		end
+	end
 
 	if self:isTalentActive(self.T_BONE_SHIELD) then
 		local t = self:getTalentFromId(self.T_BONE_SHIELD)
 		t.absorb(self, t, self:isTalentActive(self.T_BONE_SHIELD))
 		value = 0
 	end
-
+	
 	if self.knowTalent and (self:knowTalent(self.T_SEETHE) or self:knowTalent(self.T_GRIM_RESOLVE)) then
 		if not self:hasEffect(self.EFF_CURSED_FORM) then
 			self:setEffect(self.EFF_CURSED_FORM, 1, { increase=0 })
@@ -1571,13 +1633,6 @@ function _M:onTakeHit(value, src)
 		if value >= 6000 then world:gainAchievement("DAMAGE_6000", rsrc) end
 	end
 
-	-- Stoned ? SHATTER !
-	if self:attr("stoned") and value >= self.max_life * 0.3 then
-		-- Make the damage high enough to kill it
-		value = self.max_life + 1
-		game.logSeen(self, "%s shatters into pieces!", self.name:capitalize())
-	end
-
 	-- Frozen: absorb some damage into the iceblock
 	if self:attr("encased_in_ice") then
 		local eff = self:hasEffect(self.EFF_FROZEN)
@@ -1588,6 +1643,36 @@ function _M:onTakeHit(value, src)
 			eff.begone = game.turn
 		end
 	end
+	
+	-- Feedback pool: Stores damage as energy to use later
+	if self.psionic_feedback then
+		local current = self.psionic_feedback
+		local max = self.psionic_feedback_max or 100
+		self.psionic_feedback = math.min(self.psionic_feedback_max, self.psionic_feedback + value)
+	end
+		
+	-- Solipsism
+	if self.knowTalent and self:knowTalent(self.T_SOLIPSISM) then
+		local t = self:getTalentFromId(self.T_SOLIPSISM)
+		local damage_to_psi = value * t.damageToPsi(self, t)
+		if self:getPsi() > damage_to_psi then
+			self:incPsi(-damage_to_psi)
+		else
+			damage_to_psi = self:getPsi()
+			self:incPsi(-damage_to_psi)
+		end
+		if damage_to_psi > 0 then
+			game.logSeen(self, "%s's mind suffers #BLUE#%d psi#LAST# damage from the attack.", self.name:capitalize(), damage_to_psi)
+		end
+		value = value - damage_to_psi
+	end
+
+	-- Stoned ? SHATTER !
+	if self:attr("stoned") and value >= self.max_life * 0.3 then
+		-- Make the damage high enough to kill it
+		value = self.max_life + 1
+		game.logSeen(self, "%s shatters into pieces!", self.name:capitalize())
+	end
 
 	-- Adds hate
 	if self:knowTalent(self.T_HATE_POOL) then
@@ -3286,6 +3371,9 @@ function _M:breakStepUp()
 	if self:hasEffect(self.EFF_REFLEXIVE_DODGING) then
 		self:removeEffect(self.EFF_REFLEXIVE_DODGING)
 	end
+	if self:hasEffect(self.EFF_DISMISSAL) then
+		self:removeEffect(self.EFF_DISMISSAL)
+	end
 end
 
 --- Breaks lightning speed if active
diff --git a/game/modules/tome/class/PlayerDisplay.lua b/game/modules/tome/class/PlayerDisplay.lua
index 3f135f17d90b74a3f52d5f636d23a9c16df47fcb..85c985fd2d231e8e19d026f2ce27c73883e830e8 100644
--- a/game/modules/tome/class/PlayerDisplay.lua
+++ b/game/modules/tome/class/PlayerDisplay.lua
@@ -372,6 +372,13 @@ function _M:display()
 			{r=colors.BLUE.r / 5, g=colors.BLUE.g / 5, b=colors.BLUE.b / 5}
 		)) h = h + self.font_h
 	end
+	
+	if player.psionic_feedback_max then
+		self:mouseTooltip(self.TOOLTIP_FEEDBACK, self:makeTextureBar("#7fffd4#Feedback:", nil, player.psionic_feedback or 0, player.psionic_feedback_max, -1, x, h, 255, 255, 255,
+			{r=colors.YELLOW.r / 2, g=colors.YELLOW.g / 2, b=colors.YELLOW.b / 2},
+			{r=colors.YELLOW.r / 5, g=colors.YELLOW.g / 5, b=colors.YELLOW.b / 5}
+		)) h = h + self.font_h
+	end
 
 	local quiver = player:getInven("QUIVER")
 	local ammo = quiver and quiver[1]
diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
index e50d082836a1193b420ea8e0a2e83f6376ce32fc..906c363d54426a2c1a6b3689c81cca5bf8a06407 100644
--- a/game/modules/tome/class/interface/Combat.lua
+++ b/game/modules/tome/class/interface/Combat.lua
@@ -1295,7 +1295,17 @@ function _M:combatPhysicalResist(fake)
 	if self:knowTalent(self.T_POWER_IS_MONEY) then
 		add = add + util.bound(self.money / (90 - self:getTalentLevelRaw(self.T_POWER_IS_MONEY) * 5), 0, self:getTalentLevelRaw(self.T_POWER_IS_MONEY) * 7)
 	end
-	return self:rescaleCombatStats(self.combat_physresist + (self:getCon() + self:getStr() + (self:getLck() - 50) * 0.5) * 0.35 + add)
+	
+	-- To return later
+	local total = self:rescaleCombatStats(self.combat_physresist + (self:getCon() + self:getStr() + (self:getLck() - 50) * 0.5) * 0.35 + add)
+	
+	-- Psionic Balance
+	if self:knowTalent(self.T_BALANCE) then
+		local t = self:getTalentFromId(self.T_BALANCE)
+		local ratio = t.getBalanceRatio(self, t)
+		total = (1 - ratio)*total + self:combatMentalResist(fake)*ratio
+	end
+	return total
 end
 
 --- Computes spell resistance
diff --git a/game/modules/tome/class/interface/TooltipsData.lua b/game/modules/tome/class/interface/TooltipsData.lua
index de7a62cbe35ee547bb118d677564b32788f609cc..5b1c44f799cff69bca53a2b73becdeff56afd40e 100644
--- a/game/modules/tome/class/interface/TooltipsData.lua
+++ b/game/modules/tome/class/interface/TooltipsData.lua
@@ -115,6 +115,12 @@ To get meaningful amounts back in combat, you must absorb it through shields or
 Your capacity for storing energy is determined by your Willpower.
 ]]
 
+TOOLTIP_FEEDBACK = [[#GOLD#Feedback#LAST#
+Feedback represents energy you've stored up from being attacked. It decays quickly over time.
+To get meaningful amounts back in combat, you must take damage.
+Your capacity for storing feedback is determined by how many talents you know that harness it.
+]]
+
 TOOLTIP_NECROTIC_AURA = [[#GOLD#Necrotic Aura#LAST#
 Represents the raw materials for creating undead minions.
 It increases each time you or your minions kill something that is inside the aura radius.
diff --git a/game/modules/tome/class/uiset/Minimalist.lua b/game/modules/tome/class/uiset/Minimalist.lua
index bd00e18f9ff1516fde1de2c5ed21c20ccf28404b..d088dccab23c9bdb37dee2391463588c28f07150 100644
--- a/game/modules/tome/class/uiset/Minimalist.lua
+++ b/game/modules/tome/class/uiset/Minimalist.lua
@@ -72,6 +72,8 @@ hate_c = {0xF5/255, 0x3C/255, 0xBE/255}
 hate_sha = Shader.new("resources", {color=hate_c, speed=1000, distort={0.4,0.4}})
 psi_c = {colors.BLUE.r/255, colors.BLUE.g/255, colors.BLUE.b/255}
 psi_sha = Shader.new("resources", {color=psi_c, speed=2000, distort={0.4,0.4}})
+feedback_c = {colors.YELLOW.r/255, colors.YELLOW.g/255, colors.YELLOW.b/255}
+feedback_sha = Shader.new("resources", {color=feedback_c, speed=2000, distort={0.4,0.4}})
 save_c = pos_c
 save_sha = pos_sha
 
@@ -103,6 +105,8 @@ fshat_vim = {core.display.loadImage("/data/gfx/ui/resources/front_vim.png"):glTe
 fshat_vim_dark = {core.display.loadImage("/data/gfx/ui/resources/front_vim_dark.png"):glTexture()}
 fshat_psi = {core.display.loadImage("/data/gfx/ui/resources/front_psi.png"):glTexture()}
 fshat_psi_dark = {core.display.loadImage("/data/gfx/ui/resources/front_psi_dark.png"):glTexture()}
+fshat_feedback = {core.display.loadImage("/data/gfx/ui/resources/front_psi.png"):glTexture()}
+fshat_feedback_dark = {core.display.loadImage("/data/gfx/ui/resources/front_psi_dark.png"):glTexture()}
 fshat_air = {core.display.loadImage("/data/gfx/ui/resources/front_air.png"):glTexture()}
 fshat_air_dark = {core.display.loadImage("/data/gfx/ui/resources/front_air_dark.png"):glTexture()}
 
@@ -511,6 +515,7 @@ function _M:showResourceTooltip(x, y, w, h, id, desc, is_first)
 						if player:knowTalent(player.T_VIM_POOL) then list[#list+1] = {name="Vim", id="vim"} end
 						if player:knowTalent(player.T_HATE_POOL) then list[#list+1] = {name="Hate", id="hate"} end
 						if player:knowTalent(player.T_PSI_POOL) then list[#list+1] = {name="Psi", id="psi"} end
+						if player.psionic_feedback_max then list[#list+1] = {name="Feedback", id="feedback"} end
 						Dialog:listPopup("Display/Hide resources", "Toggle:", list, 300, 300, function(sel)
 							if not sel or not sel.id then return end
 							game.player["_hide_resource_"..sel.id] = not game.player["_hide_resource_"..sel.id]
@@ -969,6 +974,38 @@ function _M:displayResources(scale, bx, by, a)
 			self:showResourceTooltip(bx+x*scale, by+y*scale, fshat[6], fshat[7], "res:psi", self.TOOLTIP_PSI)
 			x, y = self:resourceOrientStep(orient, bx, by, scale, x, y, fshat[6], fshat[7])
 		elseif game.mouse:getZone("res:psi") then game.mouse:unregisterZone("res:psi") end
+		
+		-----------------------------------------------------------------------------------
+		-- Feedback
+		if player.psionic_feedback_max and not player._hide_resource_feedback then
+			sshat[1]:toScreenFull(x-6, y+8, sshat[6], sshat[7], sshat[2], sshat[3], 1, 1, 1, a)
+			bshat[1]:toScreenFull(x, y, bshat[6], bshat[7], bshat[2], bshat[3], 1, 1, 1, a)
+			if feedback_sha.shad then feedback_sha:setUniform("a", a) feedback_sha.shad:use(true) end
+			local p = player.psionic_feedback / player.psionic_feedback_max
+			shat[1]:toScreenPrecise(x+49, y+10, shat[6] * p, shat[7], 0, p * 1/shat[4], 0, 1/shat[5], feedback_c[1], feedback_c[2], feedback_c[3], a)
+			if feedback_sha.shad then feedback_sha.shad:use(false) end
+
+			if not self.res.feedback or self.res.feedback.vc ~= player.psionic_feedback or self.res.feedback.vm ~= player.psionic_feedback_max or self.res.feedback.vr ~= -1 then
+				self.res.feedback = {
+					hidable = "Feedback",
+					vc = player.psionic_feedback, vm = player.psionic_feedback_max, vr = -1,
+					cur = {core.display.drawStringBlendedNewSurface(font_sha, ("%d/%d"):format(player.psionic_feedback, player.psionic_feedback_max), 255, 255, 255):glTexture()},
+					regen={core.display.drawStringBlendedNewSurface(sfont_sha, ("%+0.2f"):format(-1), 255, 255, 255):glTexture()},
+				}
+			end
+			local dt = self.res.feedback.cur
+			dt[1]:toScreenFull(2+x+64, 2+y+10 + (shat[7]-dt[7])/2, dt[6], dt[7], dt[2], dt[3], 0, 0, 0, 0.7 * a)
+			dt[1]:toScreenFull(x+64, y+10 + (shat[7]-dt[7])/2, dt[6], dt[7], dt[2], dt[3], 1, 1, 1, a)
+			dt = self.res.feedback.regen
+			dt[1]:toScreenFull(2+x+144, 2+y+10 + (shat[7]-dt[7])/2, dt[6], dt[7], dt[2], dt[3], 0, 0, 0, 0.7 * a)
+			dt[1]:toScreenFull(x+144, y+10 + (shat[7]-dt[7])/2, dt[6], dt[7], dt[2], dt[3], 1, 1, 1, a)
+
+			local front = fshat_feedback_dark
+			if player.psionic_feedback >= player.psionic_feedback_max then front = fshat_feedback end
+			front[1]:toScreenFull(x, y, front[6], front[7], front[2], front[3], 1, 1, 1, a)
+			self:showResourceTooltip(bx+x*scale, by+y*scale, fshat[6], fshat[7], "res:feedback", self.TOOLTIP_FEEDBACK)
+			x, y = self:resourceOrientStep(orient, bx, by, scale, x, y, fshat[6], fshat[7])
+		elseif game.mouse:getZone("res:feedback") then game.mouse:unregisterZone("res:feedback") end
 
 		-----------------------------------------------------------------------------------
 		-- Ammo
diff --git a/game/modules/tome/data/birth/classes/psionic.lua b/game/modules/tome/data/birth/classes/psionic.lua
index fb7b66e3276fa912b135ac0b63879be69080c4a7..3e9565c426bdd064c5eb07407446ed8f4636f242 100644
--- a/game/modules/tome/data/birth/classes/psionic.lua
+++ b/game/modules/tome/data/birth/classes/psionic.lua
@@ -32,12 +32,12 @@ newBirthDescriptor{
 			__ALL__ = "disallow",
 			Mindslayer = "allow",
 			Psion = "allow",
+			Solipsist = "allow",
 		},
 	},
 	copy = {
 		psi_regen = 0.2,
 	},
-	body = { PSIONIC_FOCUS = 1, QS_PSIONIC_FOCUS = 1,},
 }
 
 newBirthDescriptor{
@@ -85,6 +85,7 @@ newBirthDescriptor{
 		[ActorTalents.T_TELEKINETIC_SMASH] = 1,
 		[ActorTalents.T_SHOOT] = 1,
 	},
+	body = { PSIONIC_FOCUS = 1, QS_PSIONIC_FOCUS = 1,},
 	copy = {
 		max_life = 110,
 		resolvers.equip{ id=true,
@@ -147,3 +148,41 @@ newBirthDescriptor{
 		life_rating = -4,
 	},
 }
+
+newBirthDescriptor{
+	type = "subclass",
+	name = "Solipsist",
+	locked = function() return profile.mod.allow_build.psionic_solipsist and true or "hide"  end,
+	locked_desc = "TODO",
+	desc = {
+		"blahblah",
+		"Their most important stats are: Willpower and Cunning",
+		"#GOLD#Stat modifiers:",
+		"#LIGHT_BLUE# * +0 Strength, +0 Dexterity, +0 Constitution",
+		"#LIGHT_BLUE# * +0 Magic, +5 Willpower, +4 Cunning",
+		"#GOLD#Life per level:#LIGHT_BLUE# -4 (*special*)",
+	},
+	power_source = {psionic=true},
+	stats = { str=0, wil=5, cun=4, },
+	talents_types = {
+		["psionic/feedback"]={true, 0.3},
+		["psionic/psychic-assault"]={true, 0.3},
+		["psionic/solipsism"]={true, 0.3},
+	},
+	talents = {
+		[ActorTalents.T_FEEDBACK] = 1,
+		[ActorTalents.T_PSYCHIC_LOBOTOMY] = 1,
+		[ActorTalents.T_SOLIPSISM] = 1,
+	},
+	copy = {
+		max_life = 90,
+		resolvers.equip{ id=true,
+			{type="armor", subtype="cloth", name="linen robe", autoreq=true, ego_chance=-1000},
+			{type="weapon", subtype="mindstar", name="mossy mindstar", autoreq=true, ego_chance=-1000},
+			{type="weapon", subtype="mindstar", name="mossy mindstar", autoreq=true, ego_chance=-1000},
+		},
+	},
+	copy_add = {
+		life_rating = -4,
+	},
+}
diff --git a/game/modules/tome/data/general/events/mice-quest.lua b/game/modules/tome/data/general/events/mice-quest.lua
new file mode 100644
index 0000000000000000000000000000000000000000..1ead996be4684d394a783f70f959c519fee1b823
--- /dev/null
+++ b/game/modules/tome/data/general/events/mice-quest.lua
@@ -0,0 +1,94 @@
+-- ToME - Tales of Maj'Eyal
+-- Copyright (C) 2009, 2010, 2011, 2012 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
+
+-- Find a random spot
+local x, y = rng.range(1, level.map.w - 2), rng.range(1, level.map.h - 2)
+local tries = 0
+while not game.state:canEventGrid(level, x, y) and tries < 100 do
+	x, y = rng.range(1, level.map.w - 2), rng.range(1, level.map.h - 2)
+	tries = tries + 1
+end
+if tries >= 100 then return false end
+
+local id = "mouse-quest-"..game.turn
+
+local changer = function(id)
+	local npcs = mod.class.NPC:loadList{"/data/general/npcs/thieve.lua"}
+	local objects = mod.class.Object:loadList("/data/general/objects/objects.lua")
+	local terrains = mod.class.Grid:loadList("/data/general/grids/cave.lua")
+	local zone = mod.class.Zone.new(id, {
+		name = "Unknown cave",
+		level_range = {1, 1},
+		level_scheme = "player",
+		max_level = 1,
+		actor_adjust_level = function(zone, level, e) return zone.base_level + e:getRankLevelAdjust() + level.level-1 + rng.range(-1,2) end,
+		width = 20, height = 20,
+		ambient_music = "Suspicion.ogg",
+		reload_lists = false,
+		persistent = "zone",
+		min_material_level = 1,
+		max_material_level = 1,
+		generator =  {
+			map = {
+				class = "engine.generator.map.Cavern",
+				zoom = 4,
+				min_floor = 120,
+				floor = "CAVEFLOOR",
+				wall = "CAVEWALL",
+				up = "CAVE_LADDER_UP_WILDERNESS",
+				door = "CAVEFLOOR",
+			},
+			actor = {
+				class = "mod.class.generator.actor.Random",
+				nb_npc = {14, 14},
+				guardian = {random_elite={life_rating=function(v) return v * 1.5 + 4 end, nb_rares=3}},
+			},
+			object = {
+				class = "engine.generator.object.Random",
+				filters = {{type="gem"}},
+				nb_object = {6, 9},
+			},
+			trap = {
+				class = "engine.generator.trap.Random",
+				nb_trap = {6, 9},
+			},
+		},
+--		levels = { [1] = { generator = { map = { up = "CAVEFLOOR", }, }, }, },
+		npc_list = npcs,
+		grid_list = terrains,
+		object_list = objects,
+		trap_list = {}},
+	})
+	return zone
+end
+
+local g = game.level.map(x, y, engine.Map.TERRAIN):cloneFull()
+g.name = ""
+g.display='>' g.color_r=0 g.color_g=0 g.color_b=255 g.notice = true
+g.change_level=1 g.change_zone=id
+g.add_displays = g.add_displays or {}
+g.add_displays[#g.add_displays+1] = mod.class.Grid.new{image="terrain/pedestal_heart.png", z=5}
+g.nice_tiler = nil
+g.block_move = function(self)
+	game:changeLevel(1, self.real_change(self.change_zone), {temporary_zone_shift=true})
+	return true
+end
+game.zone:addEntity(game.level, g, "terrain", x, y)
+
+return true
diff --git a/game/modules/tome/data/gfx/shockbolt/terrain/pedestal_heart.png b/game/modules/tome/data/gfx/shockbolt/terrain/pedestal_heart.png
new file mode 100644
index 0000000000000000000000000000000000000000..a3f0cf662ec0a9db89c1a5355443499aa3f52cbc
Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/terrain/pedestal_heart.png differ
diff --git a/game/modules/tome/data/talents/misc/npcs.lua b/game/modules/tome/data/talents/misc/npcs.lua
index ee35842b9c61f9e38dacf864de9be33094035891..2d8daebf6229faaa927ab8dcc2348cd2c66896b2 100644
--- a/game/modules/tome/data/talents/misc/npcs.lua
+++ b/game/modules/tome/data/talents/misc/npcs.lua
@@ -1062,7 +1062,7 @@ newTalent{
 		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, DamageType.MIND, self:spellCrit(self:combatTalentMindDamage(t, 10, 340)), {type="mind"})
+		self:project(tg, x, y, DamageType.MIND, self:mindCrit(self:combatTalentMindDamage(t, 10, 340)), {type="mind"})
 		game:playSoundNear(self, "talents/spell_generic")
 		return true
 	end,
@@ -1112,7 +1112,7 @@ newTalent{
 		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, DamageType.MINDKNOCKBACK, self:spellCrit(self:combatTalentMindDamage(t, 10, 170)), {type="mind"})
+		self:project(tg, x, y, DamageType.MINDKNOCKBACK, self:mindCrit(self:combatTalentMindDamage(t, 10, 170)), {type="mind"})
 		game:playSoundNear(self, "talents/spell_generic")
 		return true
 	end,
diff --git a/game/modules/tome/data/talents/psionic/feedback.lua b/game/modules/tome/data/talents/psionic/feedback.lua
new file mode 100644
index 0000000000000000000000000000000000000000..9c8f0a962472aa74b29af54468006ef2e3019fe5
--- /dev/null
+++ b/game/modules/tome/data/talents/psionic/feedback.lua
@@ -0,0 +1,221 @@
+-- ToME - Tales of Maj'Eyal
+-- Copyright (C) 2009, 2010, 2011, 2012 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
+
+-- TODO: Sounds and particles
+
+newTalent{
+	name = "Feedback",
+	type = {"psionic/feedback", 1},
+	points = 5,
+	require = psi_wil_req1,
+	cooldown = 10,
+	psi = 10,
+	tactical = { PSI = 2 },
+	on_pre_use = function(self, t, silent) if self.psionic_feedback <= 0 then if not silent then game.logPlayer(self, "You have no feedback to power this talent.") end return false end return not self:hasEffect(self.EFF_REGENERATION) end,
+	getConversionRatio = function(self, t) return self:combatTalentMindDamage(t, 50, 150)/100 end,
+	on_learn = function(self, t)
+		if self:getTalentLevelRaw(t) == 1 then
+			if not self.psionic_feedback then
+				self.psionic_feedback = 0
+			end
+			self.psionic_feedback_max = (self.psionic_feedback_max or 0) + 50
+		end
+		return true
+	end,
+	on_unlearn = function(self, t)
+		if not self:knowTalent(t) then
+			self.psionic_feedback_max = self.psionic_feedback_max - 50
+			if self.psionic_feedback_max <= 0 then
+				self.psionic_feedback_max = nil
+				self.psionic_feedback = nil
+			end
+		end
+		return true
+	end,
+	action = function(self, t)
+		local power = self.psionic_feedback *  t.getConversionRatio(self, t)
+		self:setEffect(self.EFF_REGENERATION, 5, {power = self:mindCrit(power/5)})
+		self.psionic_feedback = 0
+		return true
+	end,
+	info = function(self, t)
+		local conversion = t.getConversionRatio(self, t)
+		return ([[You now store damage you take as psionic feedback.  Activating this talent removes all stored feedback, converting %d%% of the stored energy into life regen over the next five turns.
+		Learning this talent will increase the amount of feedback you can store by 50 (first talent point only).
+		The conversion ratio will scale with your mindpower.]]):format(conversion * 100)
+	end,
+}
+
+newTalent{
+	name = "Discharge",
+	type = {"psionic/feedback", 2},
+	points = 5, 
+	require = psi_wil_req2,
+	cooldown = 10,
+	psi = 10,
+	tactical = { DISABLE = 2},
+	range = 0,
+	direct_hit = true,
+	requires_target = true,
+	getConversionRatio = function(self, t) return 100 - math.min(50, self:combatTalentMindDamage(t, 0, 50)) end,
+	getDuration = function(self, t)
+		local power = (self.psionic_feedback or 0) / t.getConversionRatio(self, t)
+		local duration = 1 + math.floor(power)
+		return duration
+	end,
+	radius = function(self, t) return math.ceil(self:getTalentLevel(t)) end,
+	target = function(self, t)
+		return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false}
+	end,
+	on_pre_use = function(self, t, silent) if self.psionic_feedback <= 0 then if not silent then game.logPlayer(self, "You have no feedback to power this talent.") end return false end return true end,
+	on_learn = function(self, t)
+		if self:getTalentLevelRaw(t) == 1 then
+			if not self.psionic_feedback then
+				self.psionic_feedback = 0
+			end
+			self.psionic_feedback_max = (self.psionic_feedback_max or 0) + 50
+		end
+		return true
+	end,
+	on_unlearn = function(self, t)
+		if not self:knowTalent(t) then
+			self.psionic_feedback_max = self.psionic_feedback_max - 50
+			if self.psionic_feedback_max <= 0 then
+				self.psionic_feedback_max = nil
+				self.psionic_feedback = nil
+			end
+		end
+		return true
+	end,
+	action = function(self, t)
+		local tg = self:getTalentTarget(t)
+
+		self:project(tg, self.x, self.y, function(px, py)
+			local target = game.level.map(px, py, engine.Map.ACTOR)
+			if not target then return end
+			
+			if target:canBe("stun") then
+				target:setEffect(target.EFF_DAZED, math.floor(self:mindCrit(t.getDuration(self, t))), {apply_power=self:combatMindpower()})
+			else
+				game.logSeen(target, "%s resists the daze!", target.name:capitalize())
+			end
+			game.level.map:particleEmitter(px, py, 1, "light")
+		end)
+		
+		self.psionic_feedback = 0
+		
+		return true
+	end,
+	info = function(self, t)
+		local conversion = t.getConversionRatio(self, t)
+		local radius = self:getTalentRadius(t)
+		return ([[Activate to discharge all stored feedback, dazing creatures in a radius of %d for 1 turn.  The duration of the effect will be increased by 1 for every %d feedback you have stored.
+		Learning this talent will increase the amount of feedback you can store by 50 (first talent point only).
+		The conversion ratio will scale with your mindpower.]]):format(radius, conversion)
+	end,
+}
+
+newTalent{
+	name = "Resonance Shield",
+	type = {"psionic/feedback", 3},
+	points = 5, 
+	require = psi_wil_req3,
+	cooldown = 15,
+	psi = 10,
+	tactical = { DEFEND = 2, ATTACK = {MIND = 2}},
+	on_pre_use = function(self, t, silent) if self.psionic_feedback <= 0 then if not silent then game.logPlayer(self, "You have no feedback to power this talent.") end return false end return true end,
+	getConversionRatio = function(self, t) return self:combatTalentMindDamage(t, 50, 150) / 100 end,
+	getDamage = function(self, t) return self:combatTalentMindDamage(t, 10, 50) end,
+	on_learn = function(self, t)
+		if self:getTalentLevelRaw(t) == 1 then
+			if not self.psionic_feedback then
+				self.psionic_feedback = 0
+			end
+			self.psionic_feedback_max = (self.psionic_feedback_max or 0) + 50
+		end
+		return true
+	end,
+	on_unlearn = function(self, t)
+		if not self:knowTalent(t) then
+			self.psionic_feedback_max = self.psionic_feedback_max - 50
+			if self.psionic_feedback_max <= 0 then
+				self.psionic_feedback_max = nil
+				self.psionic_feedback = nil
+			end
+		end
+		return true
+	end,
+	action = function(self, t)
+		local power = (self.psionic_feedback or 0) * t.getConversionRatio(self, t)
+		self:setEffect(self.EFF_RESONANCE_SHIELD, 10, {power = self:mindCrit(power), dam = self:mindCrit(t.getDamage(self, t))})
+		self.psionic_feedback = 0
+		return true
+	end,
+	info = function(self, t)
+		local conversion = t.getConversionRatio(self, t)
+		local damage = t.getDamage(self, t)
+		return ([[Activate to remove all stored feedback, converting %d%% of the stored energy into a resonance field that will absorb 50%% of all damage you take and inflict %0.2f mind damage to melee attackers.
+		Learning this talent will increase the amount of feedback you can store by 50 (first talent point only).
+		The conversion ratio will scale with your mindpower and the effect lasts up to ten turns.]]):format(conversion * 100, damDesc(self, DamageType.MIND, damage))
+	end,
+}
+
+newTalent{
+	name = "Feedback Loop",
+	type = {"psionic/feedback", 4},
+	points = 5, 
+	require = psi_wil_req4,
+	cooldown = 24,
+	psi = 10,
+	tactical = { FEEDBACK = 2 },
+	getConversionRatio = function(self, t) return math.min(100, self:combatTalentMindDamage(t, 20, 100))/100 end,
+	getFeedbackIncrease = function(self, t) return (self.psionic_feedback_max or 0) * t.getConversionRatio(self, t) end,
+	no_energy = true,
+	on_learn = function(self, t)
+		if self:getTalentLevelRaw(t) == 1 then
+			if not self.psionic_feedback then
+				self.psionic_feedback = 0
+			end
+			self.psionic_feedback_max = (self.psionic_feedback_max or 0) + 50
+		end
+		return true
+	end,
+	on_unlearn = function(self, t)
+		if not self:knowTalent(t) then
+			self.psionic_feedback_max = self.psionic_feedback_max - 50
+			if self.psionic_feedback_max <= 0 then
+				self.psionic_feedback_max = nil
+				self.psionic_feedback = nil
+			end
+		end
+		return true
+	end,
+	action = function(self, t)
+		self.psionic_feedback = math.min(self.psionic_feedback_max or 0, (self.psionic_feedback or 0) + t.getFeedbackIncrease(self, t))
+		return true
+	end,
+	info = function(self, t)
+		local conversion = t.getConversionRatio(self, t)
+		local feedback = t.getFeedbackIncrease(self, t)
+		return ([[Activate to instantly convert psi (the cost of the talent) into %d%% of your maximum feedback (currently %d).
+		Learning this talent will increase the amount of feedback you can store by 50 (first talent point only).
+		The feedback gain will scale with your mindpower.
+		This talent takes no time to use.]]):format(conversion * 100, feedback)
+	end,
+}
\ No newline at end of file
diff --git a/game/modules/tome/data/talents/psionic/psionic.lua b/game/modules/tome/data/talents/psionic/psionic.lua
index 5792ff0ce7532ec88e5d3a360a862650a917ae25..1f03e7bcd1b867e0849cf53ec5dde4185b581b05 100644
--- a/game/modules/tome/data/talents/psionic/psionic.lua
+++ b/game/modules/tome/data/talents/psionic/psionic.lua
@@ -37,7 +37,9 @@ newTalentType{ allow_random=true, type="psionic/brainstorm", name = "brainstorm"
 -- Secret Project...
 -- Solipsist Talent Trees
 newTalentType{ allow_random=true, type="psionic/psychic-assault", name = "psychic assault", description = "Directly attack your opponents minds." }
+newTalentType{ allow_random=true, type="psionic/solipsism", name = "solipsism", description = "Nothing exists outside the minds ability to perceive it." }
 -- Generic Solipsist Trees
+newTalentType{ allow_random=true, type="psionic/feedback", generic = true, name = "feedback", description = "Store and discharge psychic feedback." }
 
 newTalentType{ allow_random=true, type="psionic/possession", name = "possession", description = "You have learnt to shed away your body, allowing you to possess any other." }
 
@@ -169,7 +171,10 @@ load("/data/talents/psionic/psi-archery.lua")
 load("/data/talents/psionic/grip.lua")
 
 -- Solipsist
+load("/data/talents/psionic/feedback.lua")
 load("/data/talents/psionic/psychic-assault.lua")
+load("/data/talents/psionic/solipsism.lua")
+
 
 load("/data/talents/psionic/possession.lua")
 
diff --git a/game/modules/tome/data/talents/psionic/solipsism.lua b/game/modules/tome/data/talents/psionic/solipsism.lua
new file mode 100644
index 0000000000000000000000000000000000000000..e1c2f35601d3416a9444064182d2fb09ca73bfa1
--- /dev/null
+++ b/game/modules/tome/data/talents/psionic/solipsism.lua
@@ -0,0 +1,151 @@
+-- ToME - Tales of Maj'Eyal
+-- Copyright (C) 2009, 2010, 2011, 2012 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
+
+
+-- TODO: Sounds and particles
+
+newTalent{
+	name = "Solipsism",
+	type = {"psionic/solipsism", 1},
+	points = 5,
+	require = psi_wil_req1,
+	mode = "passive",
+	no_unlearn_last = true,
+	damageToPsi = function(self, t) return math.min(self:getTalentLevel(t) * 0.15, 1) end,
+	on_learn = function(self, t)
+		self:incMaxPsi(10)
+		if self:getTalentLevelRaw(t) == 1 then
+			self.life_rating = 0
+			self.psi_rating =  self.psi_rating + 10
+			self.solipsism_threshold = (self.solipsism_threshold or 0) + 0.2
+		end
+		return true
+	end,
+	on_unlearn = function(self, t)
+		self:incMaxPsi(-10)
+		if not self:knowTalent(t) then
+			self.solipsism_threshold = self.solipsism_threshold - 0.2
+		end
+		return true
+	end,
+	info = function(self, t)
+		local damage_to_psi = t.damageToPsi(self, t)
+		return ([[You believe that your mind is the center of everything.  Permanently increases the amount of psi you gain per level by 10 and reduces your life rating (affects life at level up) to 0 (one time only adjustment).
+		You also have learned to overcome physical damage with your mind alone and convert %d%% of all damage into psi damage.
+		Increases your solipsism threshold by 20%% (first point only), reducing global speed if your Psi falls below the threshold (currently %d%%).
+		Each talent point invested will also increase your max Psi by 10.]]):format(damage_to_psi * 100, self.solipsism_threshold * 100)
+	end,
+}
+
+newTalent{
+	name = "Balance",
+	type = {"psionic/solipsism", 2},
+	points = 5,
+	require = psi_wil_req2,
+	mode = "passive",
+	getBalanceRatio = function(self, t) return math.min(self:getTalentLevel(t) * 0.15, 1) end,
+	on_learn = function(self, t)
+		self:incMaxPsi(10)
+		if self:getTalentLevelRaw(t) == 1 then
+			self.solipsism_threshold = (self.solipsism_threshold or 0) + 0.1
+		end
+		return true
+	end,
+	on_unlearn = function(self, t)
+		self:incMaxPsi(-10)
+		if not self:knowTalent(t) then
+			self.solipsism_threshold = self.solipsism_threshold - 0.1
+		end
+		return true
+	end,
+	info = function(self, t)
+		local ratio = t.getBalanceRatio(self, t) * 100
+		return ([[%d%% of your healing and life regen now recovers Psi instead of life.  You now use %d%% of your physical save value and %d%% of your mental save value for physical saving throws.
+		Increases your solipsism threshold by 10%% (first point only), reducing global speed if your Psi falls below the threshold (currently %d%%).
+		Each talent point invested will also increase your max Psi by 10.]]):format(ratio, ratio, ratio, self.solipsism_threshold * 100)
+	end,
+}
+
+newTalent{
+	name = "Clarity",
+	type = {"psionic/solipsism", 3},
+	points = 5,
+	require = psi_wil_req3,
+	mode = "passive",
+	getClarityThreshold = function(self, t) return math.max(0.5, 1 - self:getTalentLevelRaw(t) / 10) end,
+	on_learn = function(self, t)
+		self:incMaxPsi(10)
+		self.solipsism_threshold = (self.solipsism_threshold or 0) + 0.1
+		if self:getTalentLevelRaw(t) == 1 then
+			self.clarity_threshold = t.getClarityThreshold(self, t)
+		end
+		return true
+	end,
+	on_unlearn = function(self, t)
+		self:incMaxPsi(-10)
+		if not self:knowTalent(t) then
+			self.solipsism_threshold = self.solipsism_threshold - 0.1
+			self.clarity_threshold = nil
+		else
+			self.clarity_threshold = t.getClarityThreshold(self, t)
+		end
+		return true
+	end,
+	info = function(self, t)
+		local threshold = t.getClarityThreshold(self, t)
+		return ([[For every percent that your Psi pool exceeds %d%% you gain 1%% global speed.
+		Increases your solipsism threshold by 10%% (first point only), reducing global speed if your Psi falls below the threshold (currently %d%%).
+		Each talent point invested will also increase your max Psi by 10.]]):format(threshold * 100, self.solipsism_threshold * 100)
+	end,
+}
+
+newTalent{
+	name = "Dismissal",
+	type = {"psionic/solipsism", 4},
+	points = 5,
+	require = psi_wil_req4,
+	cooldown = 12,
+	psi = 20,
+	tactical = { DEFEND = 2},
+	getDuration = function(self, t) return 1 + math.ceil(self:getTalentLevel(t)) end,
+	on_learn = function(self, t)
+		self:incMaxPsi(10)
+		if self:getTalentLevelRaw(t) == 1 then
+			self.solipsism_threshold = (self.solipsism_threshold or 0) + 0.1
+		end
+		return true
+	end,
+	on_unlearn = function(self, t)
+		self:incMaxPsi(-10)
+		if not self:knowTalent(t) then
+			self.solipsism_threshold = self.solipsism_threshold - 0.1
+		end
+		return true
+	end,
+	action = function(self, t)
+		self:setEffect(self.EFF_DISMISSAL, t.getDuration(self, t), {})
+		return true
+	end,
+	info = function(self, t)
+		local duration = t.getDuration(self, t)
+		return ([[You dismiss 'reality' as merely a figment of your mind.  For the next %d turns you are immune to all damage and ignore new status effects.  Performing any action other then movement will reaffirm your belief in 'reality' and end the effect.
+		Increases your solipsism threshold by 10%% (first point only), reducing global speed if your Psi falls below the threshold (currently %d%%).
+		Each talent point invested will also increase your max Psi by 10.]]):format(duration, self.solipsism_threshold * 100)
+	end,
+}
diff --git a/game/modules/tome/data/timed_effects/mental.lua b/game/modules/tome/data/timed_effects/mental.lua
index 2fe15cffedce7e36c55aa246727b4a0fb2defaa7..f17a324a8dde935c417571cb3ad7def736b24d69 100644
--- a/game/modules/tome/data/timed_effects/mental.lua
+++ b/game/modules/tome/data/timed_effects/mental.lua
@@ -2317,3 +2317,46 @@ newEffect{
 		self.mental_negative_status_effect_immune = nil
 	end,
 }
+
+
+newEffect{
+	name = "FEEDBACK", image = "talents/feedback.png",
+	desc = "Feedback",
+	long_desc = function(self, eff) return ("The target is converting feedback into Psi regen at the rate of %0.2f per turn."):format(eff.power) end,
+	type = "mental",
+	subtype = { psionic=true },
+	status = "beneficial",
+	parameters = { power=1 },
+	on_gain = function(self, err) return "#target# is recovering Psi quickly.", "+Feedback" end,
+	on_lose = function(self, err) return "#target#'s Psi recover has returned to normal.", "-Feedback" end,
+	activate = function(self, eff)
+		eff.tid = self:addTemporaryValue("psi_regen", eff.power)
+	end,
+	deactivate = function(self, eff)
+		self:removeTemporaryValue("psi_regen", eff.tid)
+	end,
+}
+
+newEffect{
+	name = "RESONANCE_SHIELD", image = "talents/resonance_shield.png",
+	desc = "Resonance Shield",
+	long_desc = function(self, eff) return ("The target is surrounded by a psychic shield, absorbing 50%% of all damage (up to %d/%d).  Additionally melee attackers will suffer %0.2f mind damage on contact."):format(self.resonance_shield_absorb, eff.power, eff.dam) end,
+	type = "mental",
+	subtype = { psionic=true, shield=true },
+	status = "beneficial",
+	parameters = { power=100, dam = 1 },
+	on_gain = function(self, err) return "A psychic shield forms around #target#.", "+Resonance Shield" end,
+	on_lose = function(self, err) return "The psychic shield around #target# crumbles.", "-Resonance Shield" end,
+	activate = function(self, eff)
+		self.resonance_shield_absorb = eff.power
+		eff.particle = self:addParticles(Particles.new("damage_shield", 1))
+		eff.sid = self:addTemporaryValue("resonance_shield", eff.power)
+		eff.did = self:addTemporaryValue("on_melee_hit", {[DamageType.MIND]=eff.dam})
+	end,
+	deactivate = function(self, eff)
+		self.resonance_shield_absorb = nil
+		self:removeParticles(eff.particle)
+		self:removeTemporaryValue("resonance_shield", eff.sid)
+		self:removeTemporaryValue("on_melee_hit", eff.did)
+	end,
+}
diff --git a/game/modules/tome/data/timed_effects/other.lua b/game/modules/tome/data/timed_effects/other.lua
index d5d5167f5d2b6252cd09d8b1cf82c5d8cdb5be69..78c8404bfd73de9ceea8283a12b489f54c9cf2ae 100644
--- a/game/modules/tome/data/timed_effects/other.lua
+++ b/game/modules/tome/data/timed_effects/other.lua
@@ -1541,3 +1541,59 @@ newEffect{
 		self:removeTemporaryValue("invulnerable", eff.tmpid)
 	end,
 }
+
+newEffect{
+	name = "SOLIPSISM", image = "talents/solipsism.png",
+	desc = "Solipsism",
+	long_desc = function(self, eff) return ("This creature has fallen into a solipsistic state and is caught up in its own thoughts (-%d%% global speed)."):format(eff.power * 100) end,
+	type = "other",
+	subtype = { psionic=true },
+	status = "detrimental",
+	decrease = 0,
+	no_stop_enter_worlmap = true, no_stop_resting = true,
+	parameters = { },
+	activate = function(self, eff)
+		eff.tmpid = self:addTemporaryValue("global_speed_add", -eff.power)
+	end,
+	deactivate = function(self, eff)
+		self:removeTemporaryValue("global_speed_add", eff.tmpid)
+	end,
+}
+
+newEffect{
+	name = "CLARITY", image = "talents/clarity.png",
+	desc = "Clarity",
+	long_desc = function(self, eff) return ("The creature has found a state of clarity (+%d%% global speed)."):format(eff.power * 100) end,
+	type = "other",
+	subtype = { psionic=true },
+	status = "beneficial",
+	decrease = 0,
+	no_stop_enter_worlmap = true, no_stop_resting = true,
+	parameters = { },
+	activate = function(self, eff)
+		eff.tmpid = self:addTemporaryValue("global_speed_add", eff.power)
+	end,
+	deactivate = function(self, eff)
+		self:removeTemporaryValue("global_speed_add", eff.tmpid)
+	end,
+}
+
+newEffect{
+	name = "DISMISSAL", image = "talents/dismissal.png",
+	desc = "Dismissal",
+	long_desc = function(self, eff) return "The target has dismissed reality.  For the duration it is immune to new status effects and all damage." end,
+	type = "other",
+	subtype = { psionic=true },
+	status = "beneficial",
+	parameters = {},
+	on_gain = function(self, err) return "#Target# dismisses reality!", "+Dismissal" end,
+	on_lose = function(self, err) return "#Target# reaffirms it's belief in reality.", "-Dismissal" end,
+	activate = function(self, eff)
+		eff.iid = self:addTemporaryValue("invulnerable", 1)
+		eff.imid = self:addTemporaryValue("status_effect_immune", 1)
+	end,
+	deactivate = function(self, eff)
+		self:removeTemporaryValue("invulnerable", eff.iid)
+		self:removeTemporaryValue("status_effect_immune", eff.imid)
+	end,
+}
\ No newline at end of file