From 4e90c5336dd603867ffb12ed6ac687ef1ed0721f Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Wed, 1 Aug 2012 08:59:31 +0000
Subject: [PATCH] New artifact in the Infinite Dungeon to learn antimagic

git-svn-id: http://svn.net-core.org/repos/t-engine4@5406 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/modules/tome/class/Actor.lua             |  2 +-
 .../tome/data/birth/classes/psionic.lua       |  9 ++--
 .../tome/data/talents/psionic/discharge.lua   |  5 +-
 .../tome/data/talents/psionic/distortion.lua  |  9 ++--
 .../tome/data/talents/psionic/dreaming.lua    |  7 ++-
 .../tome/data/talents/psionic/feedback.lua    |  4 +-
 .../tome/data/talents/psionic/mentalism.lua   | 16 +++++--
 .../tome/data/talents/psionic/nightmare.lua   | 12 ++---
 .../data/talents/psionic/psychic-assault.lua  | 20 ++++----
 .../tome/data/talents/psionic/slumber.lua     | 10 ++--
 .../tome/data/talents/psionic/solipsism.lua   | 11 ++---
 .../data/talents/psionic/thought-forms.lua    |  6 ++-
 .../tome/data/timed_effects/mental.lua        | 10 ++--
 .../modules/tome/data/timed_effects/other.lua |  2 +-
 .../data/zones/infinite-dungeon/objects.lua   | 48 +++++++++++++++++++
 15 files changed, 112 insertions(+), 59 deletions(-)

diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index f45a50d29e..9d362167fe 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -1751,7 +1751,7 @@ function _M:onTakeHit(value, src)
 				if e.power * e.dur < value then
 					game:onTickEnd(function() self:removeEffect(eff[2]) end) -- Happens on tick end so Night Terror can work properly
 				else
-					e.dur = e.dur - math.ceil(value/e.power)
+					e.dur = math.max(0, e.dur - math.ceil(value/e.power))
 				end
 			end
 		end
diff --git a/game/modules/tome/data/birth/classes/psionic.lua b/game/modules/tome/data/birth/classes/psionic.lua
index 7d62f80862..64dad34645 100644
--- a/game/modules/tome/data/birth/classes/psionic.lua
+++ b/game/modules/tome/data/birth/classes/psionic.lua
@@ -148,21 +148,22 @@ newBirthDescriptor{
 		life_rating = -4,
 	},
 }
-
+-- Edge TODO: Unlock stuff
 newBirthDescriptor{
 	type = "subclass",
 	name = "Solipsist",
 	locked = function() return profile.mod.allow_build.psionic_solipsist and true or "hide"  end,
-	locked_desc = "TODO",
+	locked_desc = "The world as we know it is the collective dream of those that live in it.  Find and wake the sleeper and you'll unlock the potential of your dreams.",
 	desc = {
-		"blahblah",
+		"The Solipsist has awakened to the truth of reality, that it's malleable, nothing more than the collective vision of those that experience it.",
+		"They wield this knowledge to both create and destory, to invade the minds of others, and to manipulate the dreams of the unenlightened.",
+		"This knowledge comes with a heavy price and the Solipsist must guard his thoughts, lest he come to believe that the world exists only within his own mind.",
 		"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*)",
 	},
-	not_on_random_boss = true, -- remove later, this is here so half-finished talents don't end up on bosses
 	power_source = {psionic=true},
 	stats = { str=0, wil=5, cun=4, },
 	talents_types = {
diff --git a/game/modules/tome/data/talents/psionic/discharge.lua b/game/modules/tome/data/talents/psionic/discharge.lua
index 97d5832595..fa792b8a1a 100644
--- a/game/modules/tome/data/talents/psionic/discharge.lua
+++ b/game/modules/tome/data/talents/psionic/discharge.lua
@@ -17,8 +17,6 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
--- Edge TODO: Sounds
-
 newTalent{
 	name = "Mind Storm",
 	type = {"psionic/discharge", 1},
@@ -86,6 +84,7 @@ newTalent{
 		
 	end,
 	activate = function(self, t)
+		game:playSoundNear(self, "talents/thunderstorm")
 		local ret = {
 			overcharge = 0,
 			particles = self:addParticles(Particles.new("ultrashield", 1, {rm=255, rM=255, gm=180, gM=255, bm=0, bM=0, am=35, aM=90, radius=0.2, density=15, life=28, instop=10}))
@@ -121,6 +120,7 @@ newTalent{
 	action = function(self, t)
 		local wrath = self:hasEffect(self.EFF_FOCUSED_WRATH)
 		self:setEffect(self.EFF_FEEDBACK_LOOP, self:mindCrit(t.getDuration(self, t), nil, wrath and wrath.power or 0), {})
+		game:playSoundNear(self, "talents/heal")
 		return true
 	end,
 	info = function(self, t)
@@ -196,6 +196,7 @@ newTalent{
 		self:setEffect(self.EFF_FOCUSED_WRATH, t.getDuration(self, t), {target=target, power=t.getCritBonus(self, t)/100})
 
 		game.level.map:particleEmitter(self.x, self.y, 1, "generic_charge", {rm=255, rM=255, gm=180, gM=255, bm=0, bM=0, am=35, aM=90})
+		game:playSoundNear(self, "talents/fireflash")
 		return true
 	end,
 	info = function(self, t)
diff --git a/game/modules/tome/data/talents/psionic/distortion.lua b/game/modules/tome/data/talents/psionic/distortion.lua
index 94bc626c3f..8f342f4218 100644
--- a/game/modules/tome/data/talents/psionic/distortion.lua
+++ b/game/modules/tome/data/talents/psionic/distortion.lua
@@ -17,8 +17,6 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
--- Edge TODO: Sounds
-
 local Object = require "mod.class.Object"
 
 newTalent{
@@ -42,6 +40,7 @@ newTalent{
 		local x, y = self:getTarget(tg)
 		if not x or not y then return nil end
 		self:projectile(tg, x, y, DamageType.DISTORTION, {dam=self:mindCrit(t.getDamage(self, t)), explosion=t.getDetonateDamage(self, t), penetrate=true, radius=self:getTalentRadius(t)})
+		game:playSoundNear(self, "talents/distortion")
 		return true
 	end,
 	info = function(self, t)
@@ -76,6 +75,7 @@ newTalent{
 		local x, y = self:getTarget(tg)
 		if not x or not y then return nil end
 		self:project(tg, x, y, DamageType.DISTORTION, {dam=self:mindCrit(t.getDamage(self, t)), knockback=t.getPower(self, t), stun=t.getPower(self, t)})
+		game:playSoundNear(self, "talents/warp")
 		game.level.map:particleEmitter(self.x, self.y, tg.radius, "generic_wave", {radius=tg.radius, tx=x-self.x, ty=y-self.y, rm=255, rM=255, gm=180, gM=255, bm=180, bM=255, am=35, aM=90})
 		return true
 	end,
@@ -118,9 +118,8 @@ newTalent{
 		if target:hasEffect(target.EFF_DISTORTION) then
 			ravage = true
 		end
-		
 		target:setEffect(target.EFF_RAVAGE, t.getDuration(self, t), {src=self, dam=self:mindCrit(t.getDamage(self, t)), ravage=ravage, apply_power=self:combatMindpower()})
-							
+		game:playSoundNear(self, "talents/echo")
 		return true
 	end,
 	info = function(self, t)
@@ -212,7 +211,7 @@ newTalent{
 		game.level.map(x, y, Map.TERRAIN, e)
 		game.nicer_tiles:updateAround(game.level, x, y)
 		game.level.map:updateMap(x, y)
-		game:playSoundNear(self, "talents/fire")
+		game:playSoundNear(self, "talents/lightning_loud")
 		return true
 	end,
 	info = function(self, t)
diff --git a/game/modules/tome/data/talents/psionic/dreaming.lua b/game/modules/tome/data/talents/psionic/dreaming.lua
index 1788ae4240..f72626a2e5 100644
--- a/game/modules/tome/data/talents/psionic/dreaming.lua
+++ b/game/modules/tome/data/talents/psionic/dreaming.lua
@@ -17,8 +17,6 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
--- Edge TODO: Sounds
-
 newTalent{
 	name = "Sleep",
 	type = {"psionic/dreaming", 1},
@@ -36,7 +34,7 @@ newTalent{
 	getInsomniaPower= function(self, t)
 		local t = self:getTalentFromId(self.T_SANDMAN)
 		local reduction = t.getInsomniaPower(self, t)
-		return 10 - reduction
+		return 20 - reduction
 	end,
 	getSleepPower = function(self, t) 
 		local power = self:combatTalentMindDamage(t, 5, 25)
@@ -84,6 +82,7 @@ newTalent{
 				end
 			end
 		end)
+		game:playSoundNear(self, "talents/dispel")
 		return true
 	end,
 	info = function(self, t)
@@ -207,7 +206,7 @@ newTalent{
 	getDrain = function(self, t) return 10 - math.min(8, math.ceil(self:getTalentLevel(t))) end,
 	remove_on_zero = true,
 	activate = function(self, t)
-		game:playSoundNear(self, "talents/heal")
+		game:playSoundNear(self, "talents/spell_generic")
 		local ret = {
 			drain = self:addTemporaryValue("psi_regen", -t.getDrain(self, t)),
 			particles = self:addParticles(engine.Particles.new("ultrashield", 1, {rm=0, rM=0, gm=180, gM=255, bm=180, bM=255, am=70, aM=180, radius=0.8, density=60, life=14, instop=20, static=80}))
diff --git a/game/modules/tome/data/talents/psionic/feedback.lua b/game/modules/tome/data/talents/psionic/feedback.lua
index 0b47a699b1..8016baa2ee 100644
--- a/game/modules/tome/data/talents/psionic/feedback.lua
+++ b/game/modules/tome/data/talents/psionic/feedback.lua
@@ -17,8 +17,6 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
--- Edge TODO: Sounds
-
 newTalent{
 	name = "Biofeedback",
 	type = {"psionic/feedback", 1},
@@ -45,6 +43,7 @@ newTalent{
 	getShieldPower = function(self, t) return self:combatTalentMindDamage(t, 30, 470) end,
 	action = function(self, t)
 		self:setEffect(self.EFF_RESONANCE_FIELD, 10, {power = self:mindCrit(t.getShieldPower(self, t))})
+		game:playSoundNear(self, "talents/spell_generic2")
 		return true
 	end,
 	info = function(self, t)
@@ -113,6 +112,7 @@ newTalent{
 			end
 		end
 		game.level.map:particleEmitter(self.x, self.y, 1, "generic_charge", {rm=255, rM=255, gm=180, gM=255, bm=0, bM=0, am=35, aM=90})
+		game:playSoundNear(self, "talents/heal")
 		return true
 	end,
 	info = function(self, t)
diff --git a/game/modules/tome/data/talents/psionic/mentalism.lua b/game/modules/tome/data/talents/psionic/mentalism.lua
index 0f011aec9e..0013ba7a31 100644
--- a/game/modules/tome/data/talents/psionic/mentalism.lua
+++ b/game/modules/tome/data/talents/psionic/mentalism.lua
@@ -17,8 +17,6 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
--- Edge TODO: Sounds
-
 local Map = require "engine.Map"
 
 newTalent{
@@ -96,6 +94,7 @@ newTalent{
 		end
 		
 		game.logSeen(self, "%s's mind is clear!", self.name:capitalize())
+		game:playSoundNear(self, "talents/heal")
 		return true
 	end,
 	info = function(self, t)
@@ -176,6 +175,8 @@ newTalent{
 		m.on_takehit = function(self, value, src) self.summoner:takeHit(value, src) return value end
 		
 		game.zone:addEntity(game.level, m, "actor", x, y)
+		game.level.map:particleEmitter(m.x, m.y, 1, "generic_teleport", {rm=0, rM=0, gm=100, gM=180, bm=180, bM=255, am=35, aM=90})
+		game:playSoundNear(self, "talents/teleport")
 	
 		if game.party:hasMember(self) then
 			game.party:addMember(m, {
@@ -189,9 +190,13 @@ newTalent{
 					self.summoner.ai = "none"
 				end,
 				on_uncontrol = function(self)
-					self.summoner.ai = self.summoner.projection_ai
-					self.summon_time = 0
-					game:onTickEnd(function() game.party:removeMember(self) end)
+					game:onTickEnd(function() 
+						self.summoner.ai = self.summoner.projection_ai
+						self.energy.value = 0
+						self.summon_time = 0
+						game.party:removeMember(self)
+						game.level.map:particleEmitter(self.summoner.x, self.summoner.y, 1, "generic_teleport", {rm=0, rM=0, gm=100, gM=180, bm=180, bM=255, am=35, aM=90})
+					end)
 				end,
 			})
 		end
@@ -240,6 +245,7 @@ newTalent{
 		
 		game.level.map:particleEmitter(self.x, self.y, 1, "generic_discharge", {rm=0, rM=0, gm=100, gM=180, bm=180, bM=255, am=35, aM=90})
 		game.level.map:particleEmitter(target.x, target.y, 1, "generic_discharge", {rm=0, rM=0, gm=100, gM=180, bm=180, bM=255, am=35, aM=90})
+		game:playSoundNear(self, "talents/echo")
 		
 		local ret = {
 			target = target,
diff --git a/game/modules/tome/data/talents/psionic/nightmare.lua b/game/modules/tome/data/talents/psionic/nightmare.lua
index b2c650a4f1..986e04de99 100644
--- a/game/modules/tome/data/talents/psionic/nightmare.lua
+++ b/game/modules/tome/data/talents/psionic/nightmare.lua
@@ -17,8 +17,6 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
--- Edge TODO: Sounds
-
 newTalent{
 	name = "Nightmare",
 	type = {"psionic/nightmare", 1},
@@ -35,7 +33,7 @@ newTalent{
 	getInsomniaPower= function(self, t)
 		local t = self:getTalentFromId(self.T_SANDMAN)
 		local reduction = t.getInsomniaPower(self, t)
-		return 10 - reduction
+		return 20 - reduction
 	end,
 	getSleepPower = function(self, t) 
 		local power = self:combatTalentMindDamage(t, 5, 25)
@@ -71,7 +69,7 @@ newTalent{
 		end)
 		
 		game.level.map:particleEmitter(self.x, self.y, tg.radius, "generic_wave", {radius=tg.radius, tx=x-self.x, ty=y-self.y, rm=60, rM=130, gm=20, gM=110, bm=90, bM=130, am=35, aM=90})
-		
+		game:playSoundNear(self, "talents/breath")
 		return true
 	end,
 	info = function(self, t)
@@ -199,7 +197,8 @@ newTalent{
 		else
 			game.logSeen(target, "%s resists the demons!", target.name:capitalize())
 		end
-
+		
+		game:playSoundNear(self, "talents/arcane")
 		return true
 	end,
 	info = function(self, t)
@@ -243,6 +242,7 @@ newTalent{
 			game.logSeen(target, "%s resists the nightmare!", target.name:capitalize())
 		end
 
+		game:playSoundNear(self, "talents/arcane")
 		return true
 	end,
 	info = function(self, t)
@@ -330,7 +330,7 @@ newTalent{
 
 	end,
 	activate = function(self, t)
-		game:playSoundNear(self, "talents/heal")
+		game:playSoundNear(self, "talents/spell_generic")
 		local ret = {
 			damage = self:addTemporaryValue("night_terror", t.getDamageBonus(self, t)),
 			particle = self:addParticles(Particles.new("ultrashield", 1, {rm=60, rM=130, gm=20, gM=110, bm=90, bM=130, am=70, aM=180, radius=0.4, density=60, life=14, instop=20})),
diff --git a/game/modules/tome/data/talents/psionic/psychic-assault.lua b/game/modules/tome/data/talents/psionic/psychic-assault.lua
index ca15e3dd85..5f73e9a4da 100644
--- a/game/modules/tome/data/talents/psionic/psychic-assault.lua
+++ b/game/modules/tome/data/talents/psionic/psychic-assault.lua
@@ -17,8 +17,6 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
--- Edge TODO: Sounds
-
 newTalent{
 	name = "Sunder Mind",
 	type = {"psionic/psychic-assault", 1},
@@ -27,7 +25,7 @@ newTalent{
 	cooldown = 2,
 	psi = 5,
 	tactical = { ATTACK = { MIND = 2}, DISABLE = 1},
-	range = 10,
+	range = 7,
 	requires_target = true,
 	getDamage = function(self, t) return self:combatTalentMindDamage(t, 10, 150) end,
 	target = function(self, t)
@@ -44,7 +42,8 @@ newTalent{
 		local dam =self:mindCrit(t.getDamage(self, t))
 		self:project(tg, x, y, DamageType.MIND, {dam=dam, alwaysHit=true}, {type="mind"})
 		target:setEffect(target.EFF_SUNDER_MIND, 2, {power=dam/10})
-			
+		
+		game:playSoundNear(self, "talents/warp")
 		return true
 	end,
 	info = function(self, t)
@@ -62,11 +61,11 @@ newTalent{
 	require = psi_wil_req2,
 	points = 5,
 	cooldown = 10,
-	psi = 25,
+	psi = 10,
 	range = 0,
 	direct_hit = true,
 	requires_target = true,
-	radius = function(self, t) return math.min(10, 3 + math.ceil(self:getTalentLevel(t))) end,
+	radius = function(self, t) return math.min(10, 3 + math.ceil(self:getTalentLevel(t)/2)) end,
 	target = function(self, t) return {type="ball", radius=self:getTalentRadius(t), range=self:getTalentRange(t), talent=t, selffire=false} end,
 	tactical = { ATTACKAREA = { MIND = 3 }, DISABLE=1 },
 	getDamage = function(self, t) return self:combatTalentMindDamage(t, 20, 200) end,
@@ -74,7 +73,7 @@ newTalent{
 		local tg = self:getTalentTarget(t)
 		self:project(tg, self.x, self.y, DamageType.MIND, {dam=self:mindCrit(self:combatTalentMindDamage(t, 20, 200)), crossTierChance=100} )
 		game.level.map:particleEmitter(self.x, self.y, self:getTalentRadius(t), "generic_ball", {radius=self:getTalentRadius(t), rm=100, rM=125, gm=100, gM=125, bm=100, bM=125, am=200, aM=255})
-		game:playSoundNear(self, "talents/spell_generic")
+		game:playSoundNear(self, "talents/echo")
 		return true
 	end,
 	info = function(self, t)
@@ -90,15 +89,15 @@ newTalent{
 	type = {"psionic/psychic-assault", 3},
 	require = psi_wil_req3,
 	points = 5,
-	cooldown = 6,
-	range = 10,
+	cooldown = 8,
+	range = 7,
 	psi = 10,
 	direct_hit = true,
 	requires_target = true,
 	tactical = { ATTACK = { MIND = 2 }, DISABLE = { confusion = 2 } },
 	getDamage = function(self, t) return self:combatTalentMindDamage(t, 20, 200) end,
 	getPower = function(self, t) return self:combatTalentMindDamage(t, 20, 60) end,
-	getDuration = function(self, t) return math.floor(self:getTalentLevel(t)) end,
+	getDuration = function(self, t) return 1 + math.floor(self:getTalentLevel(t)) end,
 	no_npc = true,
 	action = function(self, t)
 		local tg = {type="hit", range=self:getTalentRange(t), talent=t}
@@ -116,6 +115,7 @@ newTalent{
 			game.logSeen(target, "%s resists the lobotomy!", target.name:capitalize())
 		end
 
+		game:playSoundNear(self, "talents/cloud")
 		return true
 	end,
 	info = function(self, t)
diff --git a/game/modules/tome/data/talents/psionic/slumber.lua b/game/modules/tome/data/talents/psionic/slumber.lua
index 5b8068b8b7..3b320948d4 100644
--- a/game/modules/tome/data/talents/psionic/slumber.lua
+++ b/game/modules/tome/data/talents/psionic/slumber.lua
@@ -17,8 +17,6 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
--- Edge TODO: Sounds
-
 newTalent{
 	name = "Slumber",
 	type = {"psionic/slumber", 1},
@@ -35,7 +33,7 @@ newTalent{
 	getInsomniaPower = function(self, t)
 		local t = self:getTalentFromId(self.T_SANDMAN)
 		local reduction = t.getInsomniaPower(self, t)
-		return 10 - reduction
+		return 20 - reduction
 	end,
 	getSleepPower = function(self, t) 
 		local power = self:combatTalentMindDamage(t, 10, 100)
@@ -67,6 +65,7 @@ newTalent{
 		else
 			game.logSeen(self, "%s resists the sleep!", target.name:capitalize())
 		end
+		game:playSoundNear(self, "talents/dispel")
 		return true
 	end,
 	info = function(self, t)
@@ -100,7 +99,7 @@ newTalent{
 	require = psi_wil_req3,
 	mode = "passive",
 	getSleepPowerBonus = function(self, t) return self:combatTalentMindDamage(t, 5, 25) end,
-	getInsomniaPower = function(self, t) return math.min(5, self:getTalentLevelRaw(t)) end,
+	getInsomniaPower = function(self, t) return math.min(10, self:getTalentLevel(t) * 1.2) end,
 	info = function(self, t)
 		local power_bonus = t.getSleepPowerBonus(self, t)
 		local insomnia = t.getInsomniaPower(self, t)
@@ -217,12 +216,13 @@ newTalent{
 		
 		local power = self:mindCrit(t.getPower(self, t))
 		self:setEffect(self.EFF_DREAMSCAPE, t.getDuration(self, t), {target=target, power=power, projections_killed=0, x=self.x, y=self.y, tx=target.x, ty=target.y})
+		game:playSoundNear(self, "talents/teleport")
 		return true
 	end,
 	info = function(self, t)
 		local duration = t.getDuration(self, t)
 		local power = t.getPower(self, t)
-		return([[Enter a sleeping target's dreams for %d turns.  While in the dreamscape you'll encounter the target's invulnerable sleeping form as well as dream projections that it will spawn every four turns to defend it's mind.  When the dreamscape ends the target's life will be reduced by 20%% and it will to be brainlocked for one turn for each projection destroyed.
+		return([[Enter a sleeping target's dreams for %d turns.  While in the dreamscape you'll encounter the target's invulnerable sleeping form as well as dream projections that it will spawn every four turns to defend it's mind.  When the dreamscape ends the target's life will be reduced by 10%% and it will to be brainlocked for one turn for each projection destroyed.
 		Lucid dreamers will spawn projections every two turns instead of every four and their projections will deal more damage (generally projections have a 50%% penalty to all damage).
 		In the dreamscape your damage will be improved by %d%%.
 		The damage bonus will improve with your mindpower.]]):format(duration, power)
diff --git a/game/modules/tome/data/talents/psionic/solipsism.lua b/game/modules/tome/data/talents/psionic/solipsism.lua
index a34826e129..b8b808de5d 100644
--- a/game/modules/tome/data/talents/psionic/solipsism.lua
+++ b/game/modules/tome/data/talents/psionic/solipsism.lua
@@ -17,9 +17,6 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
-
--- Edge TODO: Sounds
-
 newTalent{
 	name = "Solipsism",
 	type = {"psionic/solipsism", 1},
@@ -27,7 +24,7 @@ newTalent{
 	require = psi_wil_req1,
 	mode = "passive",
 	no_unlearn_last = true,
-	getConversionRatio = function(self, t) return math.min(self:getTalentLevel(t) * 0.13, 1) end,
+	getConversionRatio = function(self, t) return math.min(0.25 + self:getTalentLevel(t) * 0.1, 1) end,
 	on_learn = function(self, t)
 		if self:getTalentLevelRaw(t) == 1 then
 			self:incMaxPsi((self:getWil()-10) * 1)
@@ -63,7 +60,7 @@ newTalent{
 	points = 5, 
 	require = psi_wil_req2,
 	mode = "passive",
-	getBalanceRatio = function(self, t) return math.min(self:getTalentLevel(t) * 0.13, 1) end,
+	getBalanceRatio = function(self, t) return math.min(0.25 + self:getTalentLevel(t) * 0.1, 1) end,
 	on_learn = function(self, t)
 		if self:getTalentLevelRaw(t) == 1 then
 			self:incMaxPsi((self:getWil()-10) * 1)
@@ -96,7 +93,7 @@ newTalent{
 	points = 5, 
 	require = psi_wil_req3,
 	mode = "passive",
-	getClarityThreshold = function(self, t) return math.max(0.5, 1 - self:getTalentLevel(t) / 15) end,
+	getClarityThreshold = function(self, t) return math.max(0.95 - self:getTalentLevel(t) * 0.06, 0.5) end,
 	on_learn = function(self, t)
 		self.clarity_threshold = t.getClarityThreshold(self, t)
 		if self:getTalentLevelRaw(t) == 1 then
@@ -133,7 +130,7 @@ newTalent{
 	points = 5, 
 	require = psi_wil_req4,
 	mode = "passive",
-	getSavePercentage = function(self, t) return math.min(2, self:getTalentLevel(t)/4) end,
+	getSavePercentage = function(self, t) return math.min(0.4 + self:getTalentLevel(t) * 0.16, 1.5) end,
 	on_learn = function(self, t)
 		if self:getTalentLevelRaw(t) == 1 then
 			self:incMaxPsi((self:getWil()-10) * 1)
diff --git a/game/modules/tome/data/talents/psionic/thought-forms.lua b/game/modules/tome/data/talents/psionic/thought-forms.lua
index a458408ba1..5af9d16220 100644
--- a/game/modules/tome/data/talents/psionic/thought-forms.lua
+++ b/game/modules/tome/data/talents/psionic/thought-forms.lua
@@ -17,8 +17,6 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
--- Edge TODO: Sounds
-
 -- Thought Forms
 newTalent{
 	name = "Thought-Form: Bowman",
@@ -522,11 +520,15 @@ newTalent{
 				if self.summoner:isTalentActive(self.summoner.T_OVER_MIND) then
 					self.summoner:forceUseTalent(self.summoner.T_OVER_MIND, {ignore_energy=true})
 				end
+				game.level.map:particleEmitter(self.x, self.y, 1, "generic_discharge", {rm=225, rM=255, gm=225, gM=255, bm=225, bM=255, am=35, aM=90})
+				game.level.map:particleEmitter(self.summoner.x, self.summoner.y, 1, "generic_discharge", {rm=225, rM=255, gm=225, gM=255, bm=225, bM=255, am=35, aM=90})
 			end
 			game.level.map:particleEmitter(target.x, target.y, 1, "generic_discharge", {rm=225, rM=255, gm=225, gM=255, bm=225, bM=255, am=35, aM=90})
 			game.party:setPlayer(target)
 			self:resetCanSeeCache()
 		end)
+		
+		game:playSoundNear(self, "talents/teleport")
 			
 		local ret = {
 			target = target, old_control = old_control,
diff --git a/game/modules/tome/data/timed_effects/mental.lua b/game/modules/tome/data/timed_effects/mental.lua
index e6c718eacf..e7edf0c872 100644
--- a/game/modules/tome/data/timed_effects/mental.lua
+++ b/game/modules/tome/data/timed_effects/mental.lua
@@ -2447,7 +2447,7 @@ newEffect{
 	end,
 	activate = function(self, eff)
 		eff.insomnia_duration = 0
-		eff.sid = self:addTemporaryValue("sleep", eff.power)
+		eff.sid = self:addTemporaryValue("sleep", 1)
 	end,
 	deactivate = function(self, eff)
 		self:removeTemporaryValue("sleep", eff.sid)
@@ -2495,7 +2495,7 @@ newEffect{
 	end,
 	activate = function(self, eff)
 		eff.insomnia_duration = 0
-		eff.sid = self:addTemporaryValue("sleep", eff.power)
+		eff.sid = self:addTemporaryValue("sleep", 1)
 	end,
 	deactivate = function(self, eff)
 		self:removeTemporaryValue("sleep", eff.sid)
@@ -2552,14 +2552,14 @@ newEffect{
 	end,
 	activate = function(self, eff)
 		eff.insomnia_duration = 0
-		eff.sid = self:addTemporaryValue("sleep", eff.power)
+		eff.sid = self:addTemporaryValue("sleep", 1)
 	end,
 	deactivate = function(self, eff)
 		self:removeTemporaryValue("sleep", eff.sid)
 		if not self:attr("lucid_dreamer") and eff.insomnia_duration > 0 then
 			self:setEffect(self.EFF_INSOMNIA, eff.insomnia_duration, {power=eff.insomnia})
 		end
-		if not self:attr("sleep") and eff.waking > 0 then
+		if not self:attr("sleep") or self:attr("sleep") < 0  and eff.waking > 0 then
 			DamageType:get(DamageType.MIND).projector(eff.src or self, self.x, self.y, DamageType.MIND, eff.src:mindCrit(eff.waking))
 			game.level.map:particleEmitter(self.x, self.y, 1, "generic_discharge", {rm=180, rM=200, gm=100, gM=120, bm=30, bM=50, am=70, aM=180})
 		end
@@ -2591,7 +2591,7 @@ newEffect{
 	end,
 	on_timeout = function(self, eff)
 		-- Insomnia only ticks when we're awake
-		if self:attr("sleep") then
+		if self:attr("sleep") and self:attr("sleep") > 0 then
 			eff.dur = eff.dur + 1
 		else
 			-- Deincrement the power
diff --git a/game/modules/tome/data/timed_effects/other.lua b/game/modules/tome/data/timed_effects/other.lua
index 424a8d5521..6bf3208081 100644
--- a/game/modules/tome/data/timed_effects/other.lua
+++ b/game/modules/tome/data/timed_effects/other.lua
@@ -1772,7 +1772,7 @@ newEffect{
 
 			-- Apply Dreamscape hit
 			if eff.projections_killed > 0 then
-				eff.target:takeHit(eff.target.max_life/5 * eff.projections_killed, self)
+				eff.target:takeHit(eff.target.max_life/10 * eff.projections_killed, self)
 				eff.target:setEffect(eff.target.EFF_BRAINLOCKED, eff.projections_killed, {})
 			end
 		end)
diff --git a/game/modules/tome/data/zones/infinite-dungeon/objects.lua b/game/modules/tome/data/zones/infinite-dungeon/objects.lua
index f6a242eeeb..7ca0977e9f 100644
--- a/game/modules/tome/data/zones/infinite-dungeon/objects.lua
+++ b/game/modules/tome/data/zones/infinite-dungeon/objects.lua
@@ -55,3 +55,51 @@ newEntity{
 		return {used=true, id=true, destroy=true}
 	end},
 }
+
+newEntity{
+	power_source = {technique=true},
+	unique = true,
+	type = "potion", subtype="potion",
+	name = "Antimagic Wyrm Bile Extract",
+	unided_name = "phial filled with slimy liquid",
+	level_range = {10, 50},
+	display = '!', color=colors.VIOLET, image="object/elixir_of_avoidance.png",
+	encumber = 0.4,
+	rarity = 150,
+	desc = [[This potent elixir extracted from a powerful wyrm can grant the power to repel arcane forces.]],
+	cost = 500,
+
+	use_simple = { name = "quaff the elixir", use = function(self, who, inven, item)
+		local d = require("engine.ui.Dialog"):yesnoLongPopup("Antimagic", [[Quaffing this potion will grant you access to the antimagic talents but at the cost of all access to runes, arcane items and spells.]], 500, function(ret)
+			if ret then
+				game.logSeen(who, "%s quaffs the %s!", who.name:capitalize(), self:getName())
+
+				who:removeObject(inven, item)
+
+				for tid, _ in pairs(who.sustain_talents) do
+					local t = who:getTalentFromId(tid)
+					if t.is_spell then who:forceUseTalent(tid, {ignore_energy=true}) end
+				end
+
+				-- Remove equipment
+				for inven_id, inven in pairs(who.inven) do
+					for i = #inven, 1, -1 do
+						local o = inven[i]
+						if o.power_source and o.power_source.arcane then
+							game.logPlayer(who, "You can not use your %s anymore, it is tainted by magic.", o:getName{do_color=true})
+							local o = who:removeObject(inven, i, true)
+							who:addObject(who.INVEN_INVEN, o)
+							who:sortInven()
+						end
+					end
+				end
+
+				who:attr("forbid_arcane", 1)
+				who:learnTalentType("wild-gift/antimagic", true)
+				who:learnTalent(who.T_RESOLVE, true, nil, {no_unlearn=true})
+			end
+		end)
+
+		return {used=true, id=true}
+	end},
+}
-- 
GitLab