diff --git a/game/engines/default/engine/generator/map/Octopus.lua b/game/engines/default/engine/generator/map/Octopus.lua
new file mode 100644
index 0000000000000000000000000000000000000000..304c405a5009fe2750e66a26bed5a6f405d1b698
--- /dev/null
+++ b/game/engines/default/engine/generator/map/Octopus.lua
@@ -0,0 +1,103 @@
+-- TE4 - T-Engine 4
+-- Copyright (C) 2009, 2010, 2011 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
+
+require "engine.class"
+local Map = require "engine.Map"
+require "engine.generator.map.Roomer"
+module(..., package.seeall, class.inherit(engine.generator.map.Roomer))
+
+function _M:init(zone, map, level, data)
+	engine.generator.map.Roomer.init(self, zone, map, level, data)
+
+	self.spots = {}
+
+	self.nb_rooms = data.nb_rooms or {5, 10}
+	self.base_breakpoint = data.base_breakpoint or 0.4
+	self.arms_range = data.arms_range or {0.5, 0.7}
+	self.arms_radius = data.arms_radius or {0.2, 0.3}
+	self.main_radius = data.main_radius or {0.3, 0.5}
+
+	self.noise = data.noise or "fbm_perlin"
+	self.zoom = data.zoom or 5
+	self.hurst = data.hurst or nil
+	self.lacunarity = data.lacunarity or nil
+	self.octave = data.octave or 4
+end
+
+function _M:generate(lev, old_lev)
+	for i = 0, self.map.w - 1 do for j = 0, self.map.h - 1 do
+		self.map(i, j, Map.TERRAIN, self:resolve("#"))
+	end end
+
+	local spots = self.spots
+
+	-- Main center room
+	local cx, cy = math.floor(self.map.w / 2), math.floor(self.map.h / 2)
+	self:makePod(cx, cy, rng.float(self.main_radius[1], self.main_radius[2]) * ((self.map.w / 2) + (self.map.h / 2)) / 2, 1, self)
+	spots[#spots+1] = {x=cx, y=cy, type="room", subtype="main"}
+
+	-- Rooms around it
+	local nb_rooms = rng.range(self.nb_rooms[1], self.nb_rooms[2])
+	for i = 0, nb_rooms - 1 do
+		local angle = math.rad(i * 360 / nb_rooms)
+
+		local range = rng.float(self.arms_range[1], self.arms_range[2])
+		local rx = math.floor(cx + math.cos(angle) * self.map.w / 2 * range)
+		local ry = math.floor(cy + math.sin(angle) * self.map.h / 2 * range)
+		print("Side octoroom", rx, ry, range)
+		self:makePod(rx, ry, rng.float(self.arms_radius[1], self.arms_radius[2]) * ((self.map.w / 2) + (self.map.h / 2)) / 2, 2 + i, self)
+		spots[#spots+1] = {x=rx, y=ry, type="room", subtype="side"}
+
+		self:tunnel(rx, ry, cx, cy, 2 + i)
+	end
+
+	-- Always starts at 1, 1
+	self.map(1, 1, Map.TERRAIN, self.up)
+	self.map.room_map[1][1].special = "exit"
+	return self:makeStairsInside(lev, old_lev, self.spots)
+end
+
+--- Create the stairs inside the level
+function _M:makeStairsInside(lev, old_lev, spots)
+	-- Put down stairs
+	local dx, dy
+	if lev < self.zone.max_level or self.data.force_last_stair then
+		while true do
+			dx, dy = rng.range(1, self.map.w - 1), rng.range(1, self.map.h - 1)
+			if not self.map:checkEntity(dx, dy, Map.TERRAIN, "block_move") and not self.map.room_map[dx][dy].special then
+				self.map(dx, dy, Map.TERRAIN, self:resolve("down"))
+				self.map.room_map[dx][dy].special = "exit"
+				break
+			end
+		end
+	end
+
+	-- Put up stairs
+	local ux, uy
+	while true do
+		ux, uy = rng.range(1, self.map.w - 1), rng.range(1, self.map.h - 1)
+		if not self.map:checkEntity(ux, uy, Map.TERRAIN, "block_move") and not self.map.room_map[ux][uy].special then
+			self.map(ux, uy, Map.TERRAIN, self:resolve("up"))
+			self.map.room_map[ux][uy].special = "exit"
+			break
+		end
+	end
+
+	return ux, uy, dx, dy, spots
+end
diff --git a/game/engines/default/engine/generator/map/Roomer.lua b/game/engines/default/engine/generator/map/Roomer.lua
index e34722ea263aff914e0234612d6cede9776566a8..e27af4419deab45803da8fe60039e895d552b5f5 100644
--- a/game/engines/default/engine/generator/map/Roomer.lua
+++ b/game/engines/default/engine/generator/map/Roomer.lua
@@ -96,11 +96,6 @@ function _M:canDoor(x, y)
 	local w8 = not g8
 	local w9 = not g9
 
-	print("============", x, y, "::", w1,w2,w3,w4,w6,w7,w8,w9)
-	print(("%s%s%s"):format(w7 and "X" or " ", w8 and "X" or " ", w9 and "X" or " "))
-	print(("%s%s%s"):format(w4 and "X" or " "," ", w6 and "X" or " "))
-	print(("%s%s%s"):format(w1 and "X" or " ", w2 and "X" or " ", w3 and "X" or " "))
-
 	if
 		(not w1 and not w4 and not w6 and not w3 and w2 and w8) or
 		(not w7 and not w8 and not w1 and not w2 and w4 and w6) or
diff --git a/game/engines/default/engine/generator/map/RoomsLoader.lua b/game/engines/default/engine/generator/map/RoomsLoader.lua
index 36c09cc73f33164b54b494984e8cf8ed750152e9..fa6f74b08d0038c011424fa96b3d5c1741b466ac 100644
--- a/game/engines/default/engine/generator/map/RoomsLoader.lua
+++ b/game/engines/default/engine/generator/map/RoomsLoader.lua
@@ -75,6 +75,50 @@ function _M:loadRoom(file)
 	return t
 end
 
+--- Easy way to make an irregular shapped room
+function _M:makePod(x, y, radius, room_id, data)
+	self.map(x, y, Map.TERRAIN, self:resolve('.'))
+	self.map.room_map[x][y].room = room_id
+
+	local lowest = {x=x, y=y}
+
+	local noise = core.noise.new(1, data.hurst, data.lacunarity)
+
+	local idx = 0
+	local quadrant = function(i, j)
+		local breakdist = radius
+		local n = noise[data.noise](noise, data.zoom * idx / (radius * 4), data.octave)
+		n = (n + 1) / 2
+		breakdist = data.base_breakpoint * breakdist + ((1 - data.base_breakpoint) * breakdist * n)
+		idx = idx + 1
+
+		local l = line.new(lowest.x, lowest.y, i, j)
+		local lx, ly = l()
+		while lx do
+			if core.fov.distance(lowest.x, lowest.y, lx, ly) >= breakdist then break end
+			if self.map:isBound(lx, ly) then
+				self.map(lx, ly, Map.TERRAIN, self:resolve('.'))
+				self.map.room_map[lx][ly].room = room_id
+			end
+			lx, ly = l()
+		end
+	end
+	local idx = 0
+	for i = -radius + x, radius + x do
+		quadrant(i, -radius + y)
+	end
+	for i = -radius + y, radius + y do
+		quadrant(radius + x, i)
+	end
+	for i = -radius + x, radius + x do
+		quadrant(i, radius + y)
+	end
+	for i = -radius + y, radius + y do
+		quadrant(-radius + x, i)
+	end
+end
+
+
 --- Generates a room
 function _M:roomGen(room, id, lev, old_lev)
 	if type(room) == 'function' then
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 401c91bcf56aed96fe0e94ebcaf7e7070d9300bd..c56b922ca6da7ebd83c1b07e731799ff24f9f0f6 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -919,7 +919,7 @@ function _M:setupCommands()
 --			self.nicer_tiles:postProcessLevelTiles(self.level)
 --			game:registerDialog(require("mod.dialogs.Donation").new())
 --			self.state:debugRandomZone()
-			self:changeLevel(1, "test")
+			self:changeLevel(1, "heart-gloom")
 		end end,
 	}
 
diff --git a/game/modules/tome/data/gfx/particles/fullgloom.lua b/game/modules/tome/data/gfx/particles/fullgloom.lua
new file mode 100644
index 0000000000000000000000000000000000000000..22ca5e11d08e21bf85cf4b4f9ace175f2333b49a
--- /dev/null
+++ b/game/modules/tome/data/gfx/particles/fullgloom.lua
@@ -0,0 +1,50 @@
+-- ToME - Tales of Maj'Eyal
+-- Copyright (C) 2009, 2010, 2011 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
+
+base_size = 32
+
+local toggle = false
+
+return { generator = function()
+	local ad = rng.range(0, 360)
+	local a = math.rad(ad)
+	local dir = -math.rad(ad)
+	local r = rng.range(10, 32 * radius)
+	local dirchance = rng.chance(2)
+
+	return {
+		trail = 1,
+		life = 30,
+		size = 12, sizev = -0.3, sizea = 0,
+
+		x = r * math.cos(a), xv = 0, xa = 0,
+		y = r * math.sin(a), yv = 0, ya = 0,
+		dir = dir, dirv = 0, dira = 0,
+		vel = dirchance and 0.32 or -0.2, velv = 0, vela = dirchance and -0.01 or 0.01,
+
+		r = 32,  rv = 0, ra = 0,
+		g = 0,  gv = 0, ga = 0,
+		b = 64,  bv = 0, ba = 0,
+		a = rng.range(20, 50) / 255,  av = 0, aa = 0,
+	}
+end, },
+function(self)
+	self.ps:emit(1)
+end,
+400
diff --git a/game/modules/tome/data/quests/start-thaloren.lua b/game/modules/tome/data/quests/start-thaloren.lua
new file mode 100644
index 0000000000000000000000000000000000000000..0e0be22215b8636843e3dd74018e70d30d9e3bb7
--- /dev/null
+++ b/game/modules/tome/data/quests/start-thaloren.lua
@@ -0,0 +1,45 @@
+-- ToME - Tales of Maj'Eyal
+-- Copyright (C) 2009, 2010, 2011 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
+
+name = "Madness of the ages"
+desc = function(self, who)
+	local desc = {}
+	desc[#desc+1] = "The Thaloren forest is disrupted, corruption is spreading. Norgos the guardian bear is said to have gone mad.\n"
+	desc[#desc+1] = "On the western border of the forest a gloomy aura has been setup, things inside are... twisted.\n"
+	if self:isCompleted("norgos") then
+		desc[#desc+1] = "#LIGHT_GREEN#* You have explored norgos lair and put it at rest.#WHITE#"
+	else
+		desc[#desc+1] = "#SLATE#* You must explore norgos lair.#WHITE#"
+	end
+	if self:isCompleted("heart-gloom") then
+		desc[#desc+1] = "#LIGHT_GREEN#* You have explored the Heart of the Gloom and slew the Withering Thing.#WHITE#"
+	else
+		desc[#desc+1] = "#SLATE#* You must explore the Heart of the Gloom.#WHITE#"
+	end
+	return table.concat(desc, "\n")
+end
+
+on_status_change = function(self, who, status, sub)
+	if sub then
+		if self:isCompleted("norgos") and self:isCompleted("heart-gloom") then
+			who:setQuestStatus(self.id, engine.Quest.DONE)
+			who:grantQuest("starter-zones")
+		end
+	end
+end
diff --git a/game/modules/tome/data/rooms/pod.lua b/game/modules/tome/data/rooms/pod.lua
new file mode 100644
index 0000000000000000000000000000000000000000..ad9e491307c57a82535a66cccaf4b2859167230f
--- /dev/null
+++ b/game/modules/tome/data/rooms/pod.lua
@@ -0,0 +1,28 @@
+-- ToME - Tales of Maj'Eyal
+-- Copyright (C) 2009, 2010, 2011 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
+
+return function(gen, id)
+	local w = rng.table{4,6,8,10}
+	local h = h
+	local function make_pod(self, x, y, is_lit)
+		gen:makePod(x + w / 2, y + h / 2, w, id)
+	end
+
+	return { name="pod"..w.."x"..h, w=w, h=h, generator = make_pod}
+end
diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua
index 42d0d47e9084f561fe4f5610ad5b1cbfa7b95756..bf14f829ef3bf0cd65e5c85b0e36d7aeaba52d87 100644
--- a/game/modules/tome/data/timed_effects.lua
+++ b/game/modules/tome/data/timed_effects.lua
@@ -2697,7 +2697,7 @@ newEffect{
 newEffect{
 	name = "AGONY",
 	desc = "Agony",
-	long_desc = function(self, eff) return ("%s is writhing in agony, suffering from %d to %d damage over %d turns."):format(self.name:capitalize(), eff.damage / duration, eff.damage, eff.duration) end,
+	long_desc = function(self, eff) return ("%s is writhing in agony, suffering from %d to %d damage over %d turns."):format(self.name:capitalize(), eff.damage / eff.duration, eff.damage, eff.duration) end,
 	type = "mental",
 	status = "detrimental",
 	parameters = { damage=10, mindpower=10, range=10, minPercent=10 },
diff --git a/game/modules/tome/data/zones/heart-gloom/grids.lua b/game/modules/tome/data/zones/heart-gloom/grids.lua
new file mode 100644
index 0000000000000000000000000000000000000000..70526e1e795ab1af46ebf44254449d8eb36cf11f
--- /dev/null
+++ b/game/modules/tome/data/zones/heart-gloom/grids.lua
@@ -0,0 +1,23 @@
+-- ToME - Tales of Maj'Eyal
+-- Copyright (C) 2009, 2010, 2011 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
+
+load("/data/general/grids/basic.lua")
+load("/data/general/grids/forest.lua", function(e) if e.image == "terrain/grass.png" then e.image = "terrain/underground_floor.png" end end)
+load("/data/general/grids/underground.lua")
+
diff --git a/game/modules/tome/data/zones/heart-gloom/npcs.lua b/game/modules/tome/data/zones/heart-gloom/npcs.lua
new file mode 100644
index 0000000000000000000000000000000000000000..19be4a0d2cf31e12aa1994e0d9fb89021d14fbf8
--- /dev/null
+++ b/game/modules/tome/data/zones/heart-gloom/npcs.lua
@@ -0,0 +1,76 @@
+-- ToME - Tales of Maj'Eyal
+-- Copyright (C) 2009, 2010, 2011 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
+
+local Talents = require("engine.interface.ActorTalents")
+
+local gloomify = function(add, mult)
+	add = add or 0
+	mult = mult or 1
+	return function(e)
+		if e.rarity then
+			local list = {"T_GLOOM", "T_AGONY", "T_REPROACH", "T_DARK_TENDRILS", "T_BLINDSIDE", "T_RADIANT_FEAR"}
+			e[#e+1] = resolvers.talents{[ Talents[rng.table(list)] ] = {base=1, every=5, max=6}}
+			e.rarity = math.ceil(e.rarity * mult + add)
+			e.name = rng.table{"gloomy ", "deformed ", "sick "}..e.name
+		end
+	end
+end
+
+load("/data/general/npcs/rodent.lua", gloomify(0))
+load("/data/general/npcs/bear.lua", gloomify(3))
+load("/data/general/npcs/canine.lua", gloomify(1))
+load("/data/general/npcs/plant.lua", gloomify(0))
+
+--load("/data/general/npcs/all.lua", rarity(4, 35))
+
+newEntity{ base="BASE_NPC_CANINE", define_as = "WITHERING_THING",
+	unique = true,
+	name = "The Withering Thing", tint=colors.PURPLE, image = "npc/the_withering_thing.png",
+	color=colors.VIOLET,
+	desc = [[This deformed beast might have been a wolf before, but now it is just.. terrible.]],
+	level_range = {7, nil}, exp_worth = 2,
+	max_life = 100, life_rating = 15, fixed_rating = true,
+	stats = { str=20, dex=20, cun=12, wil=20, con=10 },
+	rank = 4,
+	size_category = 3,
+	infravision = 20,
+	instakill_immune = 1,
+
+	combat = { dam=resolvers.levelup(8, 1, 0.9), atk=15, apr=3 },
+
+	body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 },
+--	resolvers.drops{chance=100, nb=1, {defined="TOOTH_MOUTH", random_art_replace={chance=35}} },
+	resolvers.drops{chance=100, nb=3, {tome_drops="boss"} },
+
+	resolvers.talents{
+		[Talents.T_BLINDSIDE]=2,
+		[Talents.T_CALL_SHADOWS]={base=3, every=4, max=6},
+		[Talents.T_SHADOW_MAGES]={base=1, every=4, max=6},
+		[Talents.T_SHADOW_WARRIORS]={base=1, every=4, max=6},
+	},
+	resolvers.sustains_at_birth(),
+
+	autolevel = "warriorwill",
+	ai = "tactical", ai_state = { talent_in=2 },
+	ai_tactic = resolvers.tactic"melee",
+
+	on_die = function(self, who)
+		game.player:resolveSource():setQuestStatus("start-thaloren", engine.Quest.COMPLETED, "heart-gloom")
+	end,
+}
diff --git a/game/modules/tome/data/zones/heart-gloom/objects.lua b/game/modules/tome/data/zones/heart-gloom/objects.lua
new file mode 100644
index 0000000000000000000000000000000000000000..ec49544d72f177b0f84e9a87d48c15a30231d1f3
--- /dev/null
+++ b/game/modules/tome/data/zones/heart-gloom/objects.lua
@@ -0,0 +1,31 @@
+-- ToME - Tales of Maj'Eyal
+-- Copyright (C) 2009, 2010, 2011 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
+
+load("/data/general/objects/objects.lua")
+
+for i = 1, 5 do
+newEntity{ base = "BASE_LORE",
+	define_as = "NOTE"..i,
+	name = "research log", lore="scintillating-caves-note-"..i,
+	desc = [[A paper scrap, left by an adventurer.]],
+	rarity = false,
+	is_magic_device = false,
+	encumberance = 0,
+}
+end
diff --git a/game/modules/tome/data/zones/heart-gloom/traps.lua b/game/modules/tome/data/zones/heart-gloom/traps.lua
new file mode 100644
index 0000000000000000000000000000000000000000..3b1074cc013a9b8a1de41e8bce6218431046cfa7
--- /dev/null
+++ b/game/modules/tome/data/zones/heart-gloom/traps.lua
@@ -0,0 +1,20 @@
+-- ToME - Tales of Maj'Eyal
+-- Copyright (C) 2009, 2010, 2011 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
+
+load("/data/general/traps/natural_forest.lua")
diff --git a/game/modules/tome/data/zones/heart-gloom/zone.lua b/game/modules/tome/data/zones/heart-gloom/zone.lua
new file mode 100644
index 0000000000000000000000000000000000000000..a763c42fb476245f2c88f565698738388507582e
--- /dev/null
+++ b/game/modules/tome/data/zones/heart-gloom/zone.lua
@@ -0,0 +1,82 @@
+-- ToME - Tales of Maj'Eyal
+-- Copyright (C) 2009, 2010, 2011 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
+
+return {
+	name = "Heart of the Gloom",
+	level_range = {1, 5},
+	level_scheme = "player",
+	max_level = 3,
+	decay = {300, 800},
+	actor_adjust_level = function(zone, level, e) return zone.base_level + e:getRankLevelAdjust() + level.level-1 + rng.range(-1,2) end,
+	width = 50, height = 50,
+--	all_remembered = true,
+	all_lited = true,
+	persistent = "zone",
+	ambient_music = "Rainy Day.ogg",
+	max_material_level = 2,
+	generator =  {
+		map = {
+			class = "engine.generator.map.Octopus",
+			main_radius = {0.3, 0.4},
+			arms_radius = {0.1, 0.2},
+			arms_range = {0.7, 0.8},
+			nb_rooms = {5, 9},
+			['#'] = {
+				"TREE","TREE2","TREE3","TREE4","TREE5","TREE6","TREE7","TREE8","TREE9","TREE10","TREE11","TREE12","TREE13","TREE14","TREE15","TREE16","TREE17","TREE18","TREE19","TREE20",
+				"UNDERGROUND_TREE","UNDERGROUND_TREE2","UNDERGROUND_TREE3","UNDERGROUND_TREE4","UNDERGROUND_TREE5","UNDERGROUND_TREE6","UNDERGROUND_TREE7","UNDERGROUND_TREE8","UNDERGROUND_TREE9","UNDERGROUND_TREE10","UNDERGROUND_TREE11","UNDERGROUND_TREE12","UNDERGROUND_TREE13","UNDERGROUND_TREE14","UNDERGROUND_TREE15","UNDERGROUND_TREE16","UNDERGROUND_TREE17","UNDERGROUND_TREE18","UNDERGROUND_TREE19","UNDERGROUND_TREE20",
+			},
+			['.'] = "UNDERGROUND_FLOOR",
+			up = "UNDERGROUND_LADDER_UP",
+			down = "UNDERGROUND_LADDER_DOWN",
+			door = "UNDERGROUND_FLOOR",
+		},
+		actor = {
+			class = "engine.generator.actor.Random",
+			nb_npc = {20, 30},
+			filters = { {max_ood=2}, },
+			guardian = "WITHERING_THING",
+		},
+		object = {
+			class = "engine.generator.object.Random",
+			nb_object = {6, 9},
+		},
+		trap = {
+			class = "engine.generator.trap.Random",
+			nb_trap = {6, 9},
+		},
+	},
+	levels =
+	{
+		[1] = {
+			generator = { map = {
+				up = "UNDERGROUND_LADDER_UP_WILDERNESS",
+			}, },
+		},
+	},
+
+	post_process = function(level)
+		local Map = require "engine.Map"
+		level.foreground_particle = require("engine.Particles").new("fullgloom", 1, {radius=(Map.viewport.mwidth + Map.viewport.mheight) / 2})
+	end,
+
+	foreground = function(level, x, y, nb_keyframes)
+		if not level.foreground_particle then return end
+		level.foreground_particle.ps:toScreen(x + level.map.viewport.width / 2, y + level.map.viewport.height / 2, true, 1)
+	end,
+}
diff --git a/game/modules/tome/data/zones/test/zone.lua b/game/modules/tome/data/zones/test/zone.lua
index 9fc42640853132d712ba3f30f057ef4e7501faee..ce251ea338a7bd0c9827133ccdb28450adc20495 100644
--- a/game/modules/tome/data/zones/test/zone.lua
+++ b/game/modules/tome/data/zones/test/zone.lua
@@ -31,6 +31,10 @@ return {
 	generator =  {
 		map = {
 			class = "engine.generator.map.Octopus",
+			main_radius = {0.3, 0.4},
+			arms_radius = {0.1, 0.2},
+			arms_range = {0.7, 0.8},
+			nb_rooms = {5, 9},
 			['.'] = "FLOOR",
 			['#'] = "WALL",
 			up = "FLOOR",