diff --git a/game/modules/tome/class/Party.lua b/game/modules/tome/class/Party.lua
index 0e12ec2c9a9c19ff062943e3e73b0e8478503e53..e8d8adb38476c9692cfed57c3b47ce6a96277666 100644
--- a/game/modules/tome/class/Party.lua
+++ b/game/modules/tome/class/Party.lua
@@ -111,6 +111,9 @@ function _M:leftLevel()
 			todel[#todel+1] = actor
 			if actor == game.player then newplayer = true end
 		end
+		if def.leave_level then -- Special function on leaving the level.
+			def.leave_level(actor, def)
+		end
 	end
 	for i = 1, #todel do
 		self:removeMember(todel[i])
diff --git a/game/modules/tome/data/talents/misc/races.lua b/game/modules/tome/data/talents/misc/races.lua
index 63478b5b27168cfb49b856d9f6ab6e91b98e0884..d5f3ae5545885a70a4a5196344cc3fdffd8071a2 100644
--- a/game/modules/tome/data/talents/misc/races.lua
+++ b/game/modules/tome/data/talents/misc/races.lua
@@ -759,7 +759,7 @@ newTalent{
 		self:project(tg, x, y, function(px, py)
 			local target = game.level.map(px, py, Map.ACTOR)
 			if not target or target.dead or target == self then return end
-			if not target:canBe("instakill") or target.rank > 3 or target:attr("undead") or not target:checkHit(self:getWil(20, true) + self.level * 1.5, target.level) then
+			if not target:canBe("instakill") or target.rank > 3 or target:attr("undead") or game.party:hasMember(target) or not target:checkHit(self:getWil(20, true) + self.level * 1.5, target.level) then
 				game.logSeen(target, "%s resists the mental assault!", target.name:capitalize())
 				return
 			end
diff --git a/game/modules/tome/data/timed_effects/mental.lua b/game/modules/tome/data/timed_effects/mental.lua
index 33809ed499cbbfcb4740e1ff779890fc719f3c57..18a6a3ec9fb2d7b389b06437e5c43ea549cc5478 100644
--- a/game/modules/tome/data/timed_effects/mental.lua
+++ b/game/modules/tome/data/timed_effects/mental.lua
@@ -95,11 +95,21 @@ newEffect{
 	status = "detrimental",
 	parameters = { },
 	on_gain = function(self, err) return "#Target#'s mind is shattered." end,
-	on_lose = function(self, err) return "#Target# collapses." end,
 	activate = function(self, eff)
 		eff.pid = self:addTemporaryValue("inc_damage", {all=-15})
-		self.faction = eff.src.faction
 		self.ai_state = self.ai_state or {}
+		eff.oldstate = {
+			faction = self.faction,
+			ai_state = table.clone(self.ai_state, true),
+			remove_from_party_on_death = self.remove_from_party_on_death,
+			no_inventory_access = self.no_inventory_access,
+			move_others = self.move_others,
+			summoner = self.summoner,
+			summoner_gain_exp = self.summoner_gain_exp,
+			ai = self.ai,
+		}
+		self.faction = eff.src.faction
+		
 		self.ai_state.tactic_leash = 100
 		self.remove_from_party_on_death = true
 		self.no_inventory_access = true
@@ -115,10 +125,34 @@ newEffect{
 			on_control = function(self)
 				self:hotkeyAutoTalents()
 			end,
+			leave_level = function(self, party_def) -- Cancel control and restore previous actor status.
+				local eff = self:hasEffect(self.EFF_DOMINANT_WILL)
+				local uid = self.uid
+				eff.survive_domination = true
+				self:removeTemporaryValue("inc_damage", eff.pid)
+				game.party:removeMember(self)
+				self:replaceWith(require("mod.class.NPC").new(self))
+				self.uid = uid
+				__uids[uid] = self
+				self.faction = eff.oldstate.faction
+				self.ai_state = eff.oldstate.ai_state
+				self.ai = eff.oldstate.ai
+				self.remove_from_party_on_death = eff.oldstate.remove_from_party_on_death
+				self.no_inventory_access = eff.oldstate.no_inventory_access
+				self.move_others = eff.oldstate.move_others
+				self.summoner = eff.oldstate.summoner
+				self.summoner_gain_exp = eff.oldstate.summoner_gain_exp
+				self:removeEffect(self.EFF_DOMINANT_WILL)
+			end,
 		})
 	end,
 	deactivate = function(self, eff)
-		self:die(eff.src)
+		if eff.survive_domination then
+			game.logSeen(self, "%s's mind recovers from the domination.",self.name:capitalize())
+		else
+			game.logSeen(self, "%s collapses.",self.name:capitalize())
+			self:die(eff.src)
+		end
 	end,
 }