diff --git a/game/engines/default/engine/Level.lua b/game/engines/default/engine/Level.lua
index bfcd51f2fe7032440ba5c87211f4b5d8516d9708..adadd7ac91485d0879759e71aa7ba997bfcaf847 100644
--- a/game/engines/default/engine/Level.lua
+++ b/game/engines/default/engine/Level.lua
@@ -119,32 +119,34 @@ end
 function _M:decay(what, check)
 	local total, nb = 0, 0
 	for i = 0, self.map.w - 1 do for j = 0, self.map.h - 1 do
-		if what == self.map.OBJECT then
-			for z = self.map:getObjectTotal(i, j), 1, -1 do
-				local e = self.map:getObject(i, j, z)
+		if not self.map.attrs(i, j, "no_decay") then
+			if what == self.map.OBJECT then
+				for z = self.map:getObjectTotal(i, j), 1, -1 do
+					local e = self.map:getObject(i, j, z)
+					if e and not e.no_decay and util.getval(check, e, i, j) then
+						print("[DECAY] decaying", e.uid, e.name)
+						self.map:removeObject(i, j, z)
+						e:removed()
+						nb = nb + 1
+					elseif e then
+						total = total + 1
+					end
+				end
+			else
+				local e = self.map(i, j, what)
 				if e and not e.no_decay and util.getval(check, e, i, j) then
 					print("[DECAY] decaying", e.uid, e.name)
-					self.map:removeObject(i, j, z)
+					if self:hasEntity(e) then
+						self:removeEntity(e)
+					else
+						self.map:remove(i, j, what)
+					end
 					e:removed()
 					nb = nb + 1
 				elseif e then
 					total = total + 1
 				end
 			end
-		else
-			local e = self.map(i, j, what)
-			if e and not e.no_decay and util.getval(check, e, i, j) then
-				print("[DECAY] decaying", e.uid, e.name)
-				if self:hasEntity(e) then
-					self:removeEntity(e)
-				else
-					self.map:remove(i, j, what)
-				end
-				e:removed()
-				nb = nb + 1
-			elseif e then
-				total = total + 1
-			end
 		end
 	end end
 	return nb, total
diff --git a/game/modules/tome/data/chats/zemekkys.lua b/game/modules/tome/data/chats/zemekkys.lua
index 14f76c57c902f32f4ed4dd20212a8f3e367e1af9..a27b9fe5f3dbb66d7d82e1aac06d444daad4bf2c 100644
--- a/game/modules/tome/data/chats/zemekkys.lua
+++ b/game/modules/tome/data/chats/zemekkys.lua
@@ -17,17 +17,37 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
+local function remove_materials(npc, player)
+	local gem_o, gem_item, gem_inven_id = player:findInAllInventories("Resonating Diamond")
+	player:removeObject(gem_inven_id, gem_item, true)
+	gem_o:removed()
+
+	local athame_o, athame_item, athame_inven_id = player:findInAllInventories("Blood-Runed Athame")
+	player:removeObject(athame_inven_id, athame_item, true)
+	athame_o:removed()
+end
+
+local function check_materials(npc, player)
+	local gem_o, gem_item, gem_inven_id = player:findInAllInventories("Resonating Diamond")
+	local athame_o, athame_item, athame_inven_id = player:findInAllInventories("Blood-Runed Athame")
+	return gem_o and athame_o and player.money >= 200
+end
+
+-----------------------------------------------------------------
+-- Main dialog
+-----------------------------------------------------------------
+
 newChat{ id="welcome",
 	text = [[#LIGHT_GREEN#*A slot in the door opens and a pair of wild eyes peer out.*#WHITE#
 What do you want, @playerdescriptor.race@?]],
 	answers = {
 		{"Paladin Aeryn told me that you could help me. I need to get to Middle Earth.", jump="help", cond=function(npc, player) return not player:hasQuest("west-portal") end},
 		{"I found the Blood-Runed Athame, but there was no Resonating Diamond.", jump="athame", cond=function(npc, player) return player:hasQuest("west-portal") and player:hasQuest("west-portal"):isCompleted("athame") end},
+		{"I have a Resonating Diamond.", jump="complete", cond=function(npc, player) return player:hasQuest("west-portal") and player:hasQuest("west-portal"):isCompleted("gem") end},
 		{"Sorry, I have to go!"},
 	}
 }
 
-
 -----------------------------------------------------------------
 -- Give quest
 -----------------------------------------------------------------
@@ -101,13 +121,19 @@ newChat{ id="athame3",
 -----------------------------------------------------------------
 -- Return gem
 -----------------------------------------------------------------
-newChat{ id="help",
-	text = [[Pfaugh! Her goal in life is to waste my time! Middle Earth? Why not Narnia or Chicago? Just as easy to send you someplace entirely fictional as Middle Earth. Go away.
-#LIGHT_GREEN#*Slot slams shut.*#WHITE#]],
+newChat{ id="complete",
+	text = [[[Yes? You got the athame, the gem and 200 gold?]],
 	answers = {
-		{"I got here from Middle Earth, didn't I? I have this magic Orb I looted from a dead orc, see, and...", jump="offer"},
+		{"[Give him the gem, the athame and 200 gold]", jump="complete2", cond=check_materials, action=remove_materials},
+		{"Sorry it seems I miss some stuff. I will be back."},
+	}
+}
+newChat{ id="complete2",
+	text = [[#LIGHT_GREEN#*The door opens and a shabby elf emerges.*#WHITE#
+Off we go to prepare the portal!]],
+	answers = {
+		{"[follow him]", action=function(npc, player) player:hasQuest("west-portal"):create_portal(npc, player) end},
 	}
 }
-
 
 return "welcome"
diff --git a/game/modules/tome/data/quests/west-portal.lua b/game/modules/tome/data/quests/west-portal.lua
index ec67aecdc8f9cece9f7528369042162fc37f16d2..102cac6195ae919c129b16882fa0bcc837b6c339 100644
--- a/game/modules/tome/data/quests/west-portal.lua
+++ b/game/modules/tome/data/quests/west-portal.lua
@@ -71,6 +71,53 @@ wyrm_lair = function(self, who)
 	game.logPlayer(game.player, "Zemekkys points the location of Briagh lair on your map.")
 end
 
+create_portal = function (npc, player)
+	-- Farportal
+	local g = mod.class.Grid.new{
+		name = "Farportal: Minas Tirith",
+		display = '&', color_r=255, color_g=0, color_b=220, back_color=colors.VIOLET,
+		notice = true,
+		always_remember = true,
+		show_tooltip = true,
+		desc = [[A farportal is a way to travel incredible distances in the blink of an eye. They usually require an external item to use.
+This one seems to go near the town of Minas Tirith in the West.]],
+
+		orb_portal = {
+			change_level = 1,
+			change_zone = "wilderness",
+			change_wilderness = {
+				x = 60, y = 54,
+			},
+			message = "#VIOLET#You enter the swirling portal and in the blink of an eye you set foot on the outskirts of Minas Tirith, with no trace of the portal...",
+			on_use = function(self, who)
+			end,
+		},
+	}
+	g:resolve() g:resolve(nil, true)
+
+	game.logPlayer(game.player, "#VIOLET#Zemekkys starts to draw runes on the floor using the athame and gem dust.")
+	game.logPlayer(game.player, "#VIOLET#The whole area starts to shake!")
+	game.logPlayer(game.player, "#VIOLET#Zemekkys says: 'The portal is done!'")
+
+	-- Zemekkys is not in his home anymore
+	npc.on_move = nil
+
+	-- Add Zemekkys near the portal
+	local zemekkys = mod.class.NPC.new{
+		type = "humanoid", subtype = "elf",
+		display = "p", color=colors.AQUAMARINE,
+		name = "High Chronomancer Zemekkys",
+		size_category = 3, rank = 3,
+		ai = "none",
+		faction = "sunwall",
+		can_talk = "zemekkys-done",
+	}
+	zemekkys:resolve() zemekkys:resolve(nil, true)
+
+	game.zone:addEntity(game.level, zemekkys, "actor", 41, 17)
+	game.zone:addEntity(game.level, g, "terrain", 41, 16)
+end
+
 on_status_change = function(self, who, status, sub)
 	if sub then
 --		if self:isCompleted() then
diff --git a/game/modules/tome/data/rooms/forest_clearing.lua b/game/modules/tome/data/rooms/forest_clearing.lua
index c78cff6fa75b0971919003def57a5a728418c41f..070bb9aa7774b33352c5ac0627018b7bd3dfb49a 100644
--- a/game/modules/tome/data/rooms/forest_clearing.lua
+++ b/game/modules/tome/data/rooms/forest_clearing.lua
@@ -43,6 +43,7 @@ return function(gen, id)
 						local e = gen.zone:makeEntity(gen.level, "actor", ispit, nil, true)
 						if e then
 							gen.zone:addEntity(gen.level, e, "actor", i-1+x, j-1+y)
+							gen.map.attrs(i-1+x, j-1+y, "no_decay", true)
 						end
 					end
 				end
diff --git a/game/modules/tome/data/rooms/greater_vault.lua b/game/modules/tome/data/rooms/greater_vault.lua
index f42c9b8669aad4b7d95d4d70b13291bfb9e8cd27..9157c2d6d568d106067709182d9af0b3695e1e43 100644
--- a/game/modules/tome/data/rooms/greater_vault.lua
+++ b/game/modules/tome/data/rooms/greater_vault.lua
@@ -47,6 +47,7 @@ return function(gen, id, lev, old_lev)
 		for i = x, x + w - 1 do for j = y, y + h - 1 do
 			gen.map.room_map[i][j].special = true
 			gen.map.room_map[i][j].room = id
+			gen.map.attrs(i, j, "no_decay", true)
 		end end
 		if vault.gen_map.startx and vault.gen_map.starty then
 			gen.spots[#gen.spots+1] = {x=vault.gen_map.startx + x, y=vault.gen_map.starty + y, check_connectivity="entrance", type="vault", subtype="greater"}
diff --git a/game/modules/tome/data/rooms/lesser_vault.lua b/game/modules/tome/data/rooms/lesser_vault.lua
index d1a5c0cf81c0ee4806d1da14a6d076c232a3d135..caa8321d8baf4fc1e2ed23def2dfa14e90f2bbac 100644
--- a/game/modules/tome/data/rooms/lesser_vault.lua
+++ b/game/modules/tome/data/rooms/lesser_vault.lua
@@ -47,6 +47,7 @@ return function(gen, id, lev, old_lev)
 		for i = x, x + w - 1 do for j = y, y + h - 1 do
 			gen.map.room_map[i][j].special = true
 			gen.map.room_map[i][j].room = id
+			gen.map.attrs(i, j, "no_decay", true)
 		end end
 		if vault.gen_map.startx and vault.gen_map.starty then
 			gen.spots[#gen.spots+1] = {x=vault.gen_map.startx + x, y=vault.gen_map.starty + y, check_connectivity="entrance", type="vault", subtype="lesser"}
diff --git a/game/modules/tome/data/rooms/pit.lua b/game/modules/tome/data/rooms/pit.lua
index 259d57a64260ad9c3ec61b91f9d628e2a6026e2b..bee748bfb7097c410d0f7826d06852863f11c807 100644
--- a/game/modules/tome/data/rooms/pit.lua
+++ b/game/modules/tome/data/rooms/pit.lua
@@ -34,6 +34,7 @@ return function(gen, id)
 					gen.map(i-1+x, j-1+y, Map.TERRAIN, gen:resolve('.'))
 				end
 				if is_lit then gen.map.lites(i-1+x, j-1+y, true) end
+				gen.map.attrs(i-1+x, j-1+y, "no_decay", true)
 			end
 		end
 
diff --git a/game/modules/tome/data/talents/misc/misc.lua b/game/modules/tome/data/talents/misc/misc.lua
index 7de6184a68beee93bb784024a5d3267fc388cd2c..cbc82f37ad42fa7a2ff77449cbe3fe4250bf606c 100644
--- a/game/modules/tome/data/talents/misc/misc.lua
+++ b/game/modules/tome/data/talents/misc/misc.lua
@@ -217,7 +217,7 @@ newTalent{
 	end,
 	info = function(self)
 		return ([[Call upon the luck and cunning of the Little Folk to increase your physical and spell critical strike chance by %d%% for 5 turns.
-		The bonus will increase with the Cunning stat]]):format(10 + self:getCon() / 5, 10 + self:getCon() / 5)
+		The bonus will increase with the Cunning stat]]):format(10 + self:getCun() / 5, 10 + self:getCun() / 5)
 	end,
 }
 
diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua
index e41e7ffeb6deb282841c9943858088793144fabf..a84a17fe56750b737075b88a9a15ef4b9bcbcc0f 100644
--- a/game/modules/tome/data/timed_effects.lua
+++ b/game/modules/tome/data/timed_effects.lua
@@ -498,7 +498,7 @@ newEffect{
 	status = "beneficial",
 	parameters = { power=10 },
 	on_gain = function(self, err) return "#Target# radiates power." end,
-	on_lose = function(self, err) return "#Target# aura of power vanishes." end,
+	on_lose = function(self, err) return "#Target#'s aura of power vanishes." end,
 	activate = function(self, eff)
 		eff.pid1 = self:addTemporaryValue("inc_damage", {all=eff.power})
 		eff.pid2 = self:addTemporaryValue("resists", {all=eff.power})
@@ -1431,14 +1431,14 @@ newEffect{
 	parameters = { hateLoss = 0, critical = 0, damage = 0, speed = 0, attack = 0, evasion = 0 }, -- use percentages not fractions
 	on_gain = function(self, err) return "#F53CBE##Target# begins rampaging!", "+Rampage" end,
 	on_lose = function(self, err) return "#F53CBE##Target# is no longer rampaging.", "-Rampage" end,
-	activate = function(self, eff)	
+	activate = function(self, eff)
 		if eff.hateLoss or 0 > 0 then eff.hateLossId = self:addTemporaryValue("hate_regen", -eff.hateLoss) end
 		if eff.critical or 0 > 0 then eff.criticalId = self:addTemporaryValue("combat_physcrit", eff.critical) end
 		if eff.damage or 0 > 0 then eff.damageId = self:addTemporaryValue("inc_damage", {[DamageType.PHYSICAL]=eff.damage}) end
 		if eff.speed or 0 > 0 then eff.speedId = self:addTemporaryValue("energy", {mod=eff.speed * 0.01}) end
 		if eff.attack or 0 > 0 then eff.attackId = self:addTemporaryValue("combat_atk", self.combat_atk * eff.attack * 0.01) end
 		if eff.evasion or 0 > 0 then eff.evasionId = self:addTemporaryValue("evasion", eff.evasion) end
-		
+
 		eff.particle = self:addParticles(Particles.new("rampage", 1))
 	end,
 	deactivate = function(self, eff)
@@ -1448,7 +1448,7 @@ newEffect{
 		if eff.speedId then self:removeTemporaryValue("energy", eff.speedId) end
 		if eff.attackId then self:removeTemporaryValue("combat_atk", eff.attackId) end
 		if eff.evasionId then self:removeTemporaryValue("evasion", eff.evasionId) end
-		
+
 		self:removeParticles(eff.particle)
 	end,
 }
@@ -1488,7 +1488,7 @@ newEffect{
 						end
 					end
 				end
-				
+
 				if bestDistance then
 					target:move(bestX, bestY, true)
 					if not target.did_energy then target:useEnergy() end
diff --git a/game/modules/tome/data/zones/high-peak/npcs.lua b/game/modules/tome/data/zones/high-peak/npcs.lua
index 30960cb5c9cb63e7b03b41094401af6f02b63714..08bc1339d44383b279479850e18701f1546d65de 100644
--- a/game/modules/tome/data/zones/high-peak/npcs.lua
+++ b/game/modules/tome/data/zones/high-peak/npcs.lua
@@ -70,7 +70,7 @@ newEntity{
 	see_invisible = 100,
 	instakill_immune = 1,
 	stun_immune = 0.5,
-	blind_immune = 1
+	blind_immune = 1,
 
 	body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1, HEAD=1, FEET=1 },
 	resolvers.equip{
@@ -135,7 +135,7 @@ newEntity{
 	see_invisible = 100,
 	instakill_immune = 1,
 	stun_immune = 0.5,
-	blind_immune = 1
+	blind_immune = 1,
 
 	body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 },
 	resolvers.equip{