diff --git a/game/engine/Astar.lua b/game/engine/Astar.lua
index fa87eafaa07711c73228194b6a13b1ad0f8abe64..b1b2523d97732db1f350f661357720dd232323a3 100644
--- a/game/engine/Astar.lua
+++ b/game/engine/Astar.lua
@@ -30,9 +30,18 @@ function _M:init(map, actor)
 	self.move_cache = {}
 end
 
---- The default heuristic for A*, simple distance
-function _M:heuristic(sx, sy, tx, ty)
-	return core.fov.distance(sx, sy, tx, ty)
+--- The default heuristic for A*, tries to come close to the straight path
+function _M:heuristicCloserPath(sx, sy, cx, cy, tx, ty)
+	local dx1 = cx - tx
+	local dy1 = cy - ty
+	local dx2 = sx - tx
+	local dy2 = sy - ty
+	return math.abs(dx1*dy2 - dx2*dy1)
+end
+
+--- The a simple heuristic for A*, using distance
+function _M:heuristicDistance(sx, sy, cx, cy, tx, ty)
+	return core.fov.distance(cx, cy, tx, ty)
 end
 
 function _M:toSingle(x, y)
@@ -62,15 +71,16 @@ end
 -- @param ty the end coord
 -- @param use_has_seen if true the astar wont consider non-has_seen grids
 -- @return either nil if no path or a list of nodes in the form { {x=...,y=...}, {x=...,y=...}, ..., {x=tx,y=ty}}
-function _M:calc(sx, sy, tx, ty, use_has_seen)
+function _M:calc(sx, sy, tx, ty, use_has_seen, heuristic)
+	local heur = heuristic or self.heuristicCloserPath
 	local w, h = self.map.w, self.map.h
 	local start = self:toSingle(sx, sy)
 	local stop = self:toSingle(tx, ty)
 	local open = {[start]=true}
 	local closed = {}
 	local g_score = {[start] = 0}
-	local h_score = {[start] = self:heuristic(sx, sy, tx, ty)}
-	local f_score = {[start] = self:heuristic(sx, sy, tx, ty)}
+	local h_score = {[start] = heur(self, sx, sy, sx, sy, tx, ty)}
+	local f_score = {[start] = heur(self, sx, sy, sx, sy, tx, ty)}
 	local came_from = {}
 
 	local cache = self.map._fovcache.path_caches[self.actor:getPathString()]
@@ -88,7 +98,7 @@ function _M:calc(sx, sy, tx, ty, use_has_seen)
 				if tent_is_better then
 					came_from[nnode] = node
 					g_score[nnode] = tent_g_score
-					h_score[nnode] = self:heuristic(tx, ty, nx, ny)
+					h_score[nnode] = heur(self, sx, sy, tx, ty, nx, ny)
 					f_score[nnode] = g_score[nnode] + h_score[nnode]
 				end
 			end
@@ -106,7 +116,7 @@ function _M:calc(sx, sy, tx, ty, use_has_seen)
 				if tent_is_better then
 					came_from[nnode] = node
 					g_score[nnode] = tent_g_score
-					h_score[nnode] = self:heuristic(tx, ty, nx, ny)
+					h_score[nnode] = heur(self, sx, sy, tx, ty, nx, ny)
 					f_score[nnode] = g_score[nnode] + h_score[nnode]
 				end
 			end
diff --git a/game/engine/BSP.lua b/game/engine/BSP.lua
new file mode 100644
index 0000000000000000000000000000000000000000..0fbfd520d855d4f8e4feaf66e5049c4e470427b3
--- /dev/null
+++ b/game/engine/BSP.lua
@@ -0,0 +1,68 @@
+-- TE4 - T-Engine 4
+-- Copyright (C) 2009, 2010 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"
+
+--- Abstract binary space partionning
+-- Can be used to generator levels and so on
+module(..., package.seeall, class.make)
+
+function _M:init(w, h, min_w, min_h, max_depth)
+	self.max_depth = max_depth or 8
+	self.min_w, self.min_h = min_w, min_h
+	self.node_id = 1
+	self.leafs = {}
+	self.bsp = {x=0, y=0, rx=0, ry=0, w=w, h=h, nodes={}, id=0, depth=0}
+	print("[BSP] ", w, h)
+end
+
+function _M:partition(store)
+	store = store or self.bsp
+
+	local split_vert, split_hor = false, false
+	if store.w >= self.min_w * 2 then split_hor = true end
+	if store.h >= self.min_h * 2 then split_vert = true end
+	print("[BSP] "..store.id.." partitioning", store.rx, store.ry, "::", store.w, store.h, " splits ", split_hor, split_vert)
+
+	if split_vert and split_hor then
+		local ok = rng.percent(50)
+		split_vert, split_hor = ok, not ok
+	end
+
+	if store.depth > self.max_depth then split_vert, split_hor = false, false end
+
+	if split_vert and not split_hor then
+		local s = rng.range(self.min_h, store.h - self.min_h)
+--		print("[BSP] vertical split", s)
+		store.nodes[1] = {depth=store.depth+1, x=0, y=0, rx=store.rx, ry=store.ry, w=store.w, h=s, nodes={}, id=self.node_id} self.node_id = self.node_id + 1
+		store.nodes[2] = {depth=store.depth+1, x=0, y=s, rx=store.rx, ry=store.ry + s, w=store.w, h=store.h - s, nodes={}, id=self.node_id} self.node_id = self.node_id + 1
+		self:partition(store.nodes[1])
+		self:partition(store.nodes[2])
+
+	elseif not split_vert and split_hor then
+		local s = rng.range(self.min_w, store.w - self.min_w)
+--		print("[BSP] horizontal split", s)
+		store.nodes[1] = {depth=store.depth+1, x=0, y=0, rx=store.rx, ry=store.ry, w=s, h=store.h, nodes={}, id=self.node_id} self.node_id = self.node_id + 1
+		store.nodes[2] = {depth=store.depth+1, x=s, y=0, rx=store.rx + s, ry=store.ry, w=store.w -s , h=store.h, nodes={}, id=self.node_id} self.node_id = self.node_id + 1
+		self:partition(store.nodes[1])
+		self:partition(store.nodes[2])
+	end
+
+	if #store.nodes == 0 then self.leafs[#self.leafs+1] = store end
+end
diff --git a/game/engine/generator/map/Cavern.lua b/game/engine/generator/map/Cavern.lua
index ce221308c0702320df0e0404775ea1d261476d2f..2b0d4f68766988504d4a6777ddc9b618c43a1b9d 100644
--- a/game/engine/generator/map/Cavern.lua
+++ b/game/engine/generator/map/Cavern.lua
@@ -55,7 +55,7 @@ function _M:generate(lev, old_lev)
 		opens[i] = {}
 		for j = 0, self.map.h - 1 do
 			if noise[self.noise](noise, self.zoom * i / self.map.w, self.zoom * j / self.map.h, self.octave) > 0 then
-				self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("floor")]:clone())
+				self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("floor")])
 				opens[i][j] = #list+1
 				list[#list+1] = {x=i, y=j}
 			else
diff --git a/game/engine/generator/map/Forest.lua b/game/engine/generator/map/Forest.lua
index 6b46c8d3ea4dbbe2dc258a86489ee9307a11cb26..4b3919365c49b2f61be97a1d79246f32ae2fb54e 100644
--- a/game/engine/generator/map/Forest.lua
+++ b/game/engine/generator/map/Forest.lua
@@ -48,7 +48,7 @@ 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.grid_list[self.floor])
+		self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("floor")])
 	end end
 
 	-- make the noise
diff --git a/game/engine/generator/map/Town.lua b/game/engine/generator/map/Town.lua
new file mode 100644
index 0000000000000000000000000000000000000000..d9a3c17220bb1163dd9f435b10ebc89299265fc0
--- /dev/null
+++ b/game/engine/generator/map/Town.lua
@@ -0,0 +1,214 @@
+-- TE4 - T-Engine 4
+-- Copyright (C) 2009, 2010 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"
+local BSP = require "engine.BSP"
+require "engine.Generator"
+module(..., package.seeall, class.inherit(engine.Generator))
+
+function _M:init(zone, map, level, data)
+	engine.Generator.init(self, zone, map, level)
+	self.data = data
+	self.grid_list = self.zone.grid_list
+	self.max_building_w = data.max_building_w or 12
+	self.max_building_h = data.max_building_h or 12
+	self.building_chance = data.building_chance or  85
+	self.lshape_chance = data.lshape_chance or 50
+	self.double_lshape_chance = data.double_lshape_chance or 40
+	self.yard_chance = data.yard_chance or 30
+end
+
+function _M:resolve(c)
+	local res = self.data[c]
+	if type(res) == "function" then
+		return res()
+	elseif type(res) == "table" then
+		return res[rng.range(1, #res)]
+	else
+		return res
+	end
+end
+
+function _M:Lshape(inner_grids, x1, x2, y1, y2, ix1, ix2, iy1, iy2)
+	if #inner_grids == 0 then return end
+	local door_grids = {}
+	local void = rng.percent(self.yard_chance)
+	local point = rng.tableRemove(inner_grids)
+	local dx1, dx2 = math.abs(point.x - ix1), math.abs(point.x - ix2)
+	local dy1, dy2 = math.abs(point.y - iy1), math.abs(point.y - iy2)
+	if dx1 == dx2 then if rng.percent(50) then dx1 = dx1 + 1 else dx2 = dx2 + 1 end end
+	if dy1 == dy2 then if rng.percent(50) then dy1 = dy1 + 1 else dy2 = dy2 + 1 end end
+	print("room", dx1, dx2, "::", dy1, dy2)
+
+	if dx2 > dx1 and dy2 > dy1 then
+		for i = point.x, x2 do door_grids[#door_grids+1] = {x=i,y=point.y} self.map(i, point.y, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end
+		for j = point.y, y2 do door_grids[#door_grids+1] = {x=point.x,y=j} self.map(point.x, j, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end
+		for i = point.x+1, x2 do for j = point.y+1, y2 do if void then self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("external_floor")]) end end end
+	elseif dx1 > dx2 and dy2 > dy1 then
+		for i = x1, point.x do door_grids[#door_grids+1] = {x=i,y=point.y} self.map(i, point.y, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end
+		for j = point.y, y2 do door_grids[#door_grids+1] = {x=point.x,y=j} self.map(point.x, j, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end
+		for i = x1, point.x-1 do for j = point.y+1, y2 do if void then self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("external_floor")]) end end end
+	elseif dx1 > dx2 and dy1 > dy2 then
+		for i = x1, point.x do door_grids[#door_grids+1] = {x=i,y=point.y} self.map(i, point.y, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end
+		for j = y1, point.y do door_grids[#door_grids+1] = {x=point.x,y=j} self.map(point.x, j, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end
+		for i = x1, point.x-1 do for j = y1, point.y-1 do if void then self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("external_floor")]) end end end
+	elseif dx2 > dx1 and dy1 > dy2 then
+		for i = point.x, x2 do door_grids[#door_grids+1] = {x=i,y=point.y} self.map(i, point.y, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end
+		for j = y1, point.y do door_grids[#door_grids+1] = {x=point.x,y=j} self.map(point.x, j, Map.TERRAIN, self.grid_list[self:resolve("wall")]) end
+		for i = point.x+1, x2 do for j = y1, point.y-1 do if void then self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("external_floor")]) end end end
+	end
+
+	-- Door
+	if #door_grids > 0 then
+		local door = rng.table(door_grids)
+		self.map(door.x, door.y, Map.TERRAIN, self.grid_list[self:resolve("door")])
+	end
+end
+
+function _M:building(leaf)
+	local x1, x2 = leaf.rx + rng.range(2, math.max(2, math.floor(leaf.w / 2 - 3))), leaf.rx + leaf.w - rng.range(2, math.max(2, math.floor(leaf.w / 2 - 3)))
+	local y1, y2 = leaf.ry + rng.range(2, math.max(2, math.floor(leaf.h / 2 - 3))), leaf.ry + leaf.h - rng.range(2, math.max(2, math.floor(leaf.h / 2 - 3)))
+	local ix1, ix2, iy1, iy2 = x1 + 2, x2 - 2, y1 + 2, y2 - 2
+	local inner_grids = {}
+	local door_grids = {}
+
+	for i = x1, x2 do for j = y1, y2 do
+		if i == x1 or i == x2 or j == y1 or j == y2 then
+			self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("wall")])
+			door_grids[#door_grids+1] = {x=i,y=j}
+		else
+			self.map(i, j, Map.TERRAIN, self.grid_list[self:resolve("floor")])
+			if i >= ix1 and i <= ix2 and j >= iy1 and j <= iy2 then
+				inner_grids[#inner_grids+1] = {x=i,y=j}
+			end
+		end
+	end end
+
+	-- Door
+	local door = rng.table(door_grids)
+	self.map(door.x, door.y, Map.TERRAIN, self.grid_list[self:resolve("door")])
+	-- Eliminate inner grids that face the door
+	for i = #inner_grids, 1, -1 do
+		local g = inner_grids[i]
+		if g.x == door.x or g.y == door.y then table.remove(inner_grids, i) end
+	end
+
+	-- L shape
+	if rng.percent(self.lshape_chance) then
+		self:Lshape(inner_grids, x1, x2, y1, y2, ix1, ix2, iy1, iy2)
+	end
+--	if rng.percent(self.lshape_chance) then
+--		self:Lshape(inner_grids, x1, x2, y1, y2, ix1, ix2, iy1, iy2)
+--	end
+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.grid_list[self:resolve("external_floor")])
+	end end
+
+	local bsp = BSP.new(self.map.w, self.map.h, self.max_building_w, self.max_building_h)
+	bsp:partition()
+
+	print("Town gen made ", #bsp.leafs, "BSP leafs")
+	for z, leaf in ipairs(bsp.leafs) do
+		if rng.percent(self.building_chance) then
+			self:building(leaf)
+		end
+	end
+
+	local spots = {}
+	local ux, uy, dx, dy
+	if self.data.edge_entrances then
+		ux, uy, dx, dy, spots = self:makeStairsSides(lev, old_lev, self.data.edge_entrances, spots)
+	else
+		ux, uy, dx, dy, spots = self:makeStairsInside(lev, old_lev, spots)
+	end
+
+	return ux, uy, dx, dy, 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.grid_list[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.grid_list[self:resolve("up")])
+			self.map.room_map[ux][uy].special = "exit"
+			break
+		end
+	end
+
+	return ux, uy, dx, dy, spots
+end
+
+--- Create the stairs on the sides
+function _M:makeStairsSides(lev, old_lev, sides, spots)
+	-- Put down stairs
+	local dx, dy
+	if lev < self.zone.max_level or self.data.force_last_stair then
+		while true do
+			if     sides[2] == 4 then dx, dy = 0, rng.range(0, self.map.h - 1)
+			elseif sides[2] == 6 then dx, dy = self.map.w - 1, rng.range(0, self.map.h - 1)
+			elseif sides[2] == 8 then dx, dy = rng.range(0, self.map.w - 1), 0
+			elseif sides[2] == 2 then dx, dy = rng.range(0, self.map.w - 1), self.map.h - 1
+			end
+
+			if not self.map.room_map[dx][dy].special then
+				self.map(dx, dy, Map.TERRAIN, self.grid_list[self:resolve("down")])
+				self.map.room_map[dx][dy].special = "exit"
+				break
+			end
+		end
+	end
+
+	-- Put up stairs
+	local ux, uy
+	while true do
+		if     sides[1] == 4 then ux, uy = 0, rng.range(0, self.map.h - 1)
+		elseif sides[1] == 6 then ux, uy = self.map.w - 1, rng.range(0, self.map.h - 1)
+		elseif sides[1] == 8 then ux, uy = rng.range(0, self.map.w - 1), 0
+		elseif sides[1] == 2 then ux, uy = rng.range(0, self.map.w - 1), self.map.h - 1
+		end
+
+		if not self.map.room_map[ux][uy].special then
+			self.map(ux, uy, Map.TERRAIN, self.grid_list[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/modules/tome/data/birth/races/orc.lua b/game/modules/tome/data/birth/races/orc.lua
index e9151e703a755c78e81140422838e6af3328c9db..0770897ffc0c1519abce9432cbc5c2c06201b176 100644
--- a/game/modules/tome/data/birth/races/orc.lua
+++ b/game/modules/tome/data/birth/races/orc.lua
@@ -24,7 +24,9 @@ newBirthDescriptor{
 	type = "race",
 	name = "Orc",
 	desc = {
-		"",
+		"Since their creation by Morgoth the Orcs have been the pawns of the forces of darkness.",
+		"While both Sauron and Morgoth were destroy, the orcs survived and found a new master in the Far East.",
+		"Orcs are a ruthless warriors, yet they are not dumb and some are terribly cunning.",
 	},
 	descriptor_choices =
 	{
@@ -38,25 +40,29 @@ newBirthDescriptor{
 			__ALL__ = "never",
 			Male = "allow",
 		},
+		class =
+		{
+			Mage = "never",
+		},
 	},
-	stats = { str=4, con=3, wil=3, mag=-2, dex=-2 },
+	stats = { str=4, con=1, wil=2, mag=-2, dex=-2 },
 	talents = {
---		[ActorTalents.T_DWARF_RESILIENCE]=1,
+		[ActorTalents.T_ORC_FURY]=1,
 	},
 	copy = {
 		type = "humanoid", subtype="orc",
-		default_wilderness = {39, 17},
-		starting_zone = "tower-amon-sul",
+		default_wilderness = {10, 39},
+		starting_zone = "wilderness-arda-fareast",
 		starting_quest = "start-dunadan",
-		starting_intro = "dwarf",
+		starting_intro = "orc",
 		life_rating=12,
 	},
-	experience = 1.1,
+	experience = 1.3,
 }
 
----------------------------------------------------------
---                       Dwarves                       --
----------------------------------------------------------
+--------------------------------------------------------
+--                       Orcs                         --
+--------------------------------------------------------
 newBirthDescriptor
 {
 	type = "subrace",
diff --git a/game/modules/tome/data/birth/worlds.lua b/game/modules/tome/data/birth/worlds.lua
index b0d3a123eadbd226e816071ebb8d22998c2ee6bd..a4f84ea80d96f81c85ed5626b069c9b4eb9d939a 100644
--- a/game/modules/tome/data/birth/worlds.lua
+++ b/game/modules/tome/data/birth/worlds.lua
@@ -38,8 +38,8 @@ newBirthDescriptor{
 			Elf = "allow",
 			Dwarf = "allow",
 			Hobbit = "allow",
---			Orc = function() return profile.mod.allow_build.evil and "allow" or "never" end,
---			Troll = function() return profile.mod.allow_build.evil and "allow" or "never" end,
+			Orc = function() return profile.mod.allow_build.orc and "allow" or "never" end,
+			Troll = function() return profile.mod.allow_build.troll and "allow" or "never" end,
 			Undead = function() return profile.mod.allow_build.undead and "allow" or "never" end,
 		},
 
diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua
index 6c46b9ac4a280de084f4a3a9d5df9b7e57d7fe8c..69060956c59a30a596a256caf35b9427edebfb2e 100644
--- a/game/modules/tome/data/damage_types.lua
+++ b/game/modules/tome/data/damage_types.lua
@@ -36,7 +36,7 @@ setDefaultProjector(function(src, x, y, type, dam)
 
 		-- Increases damage
 		if src.inc_damage then
-			local inc = src.inc_damage[type] or 0
+			local inc = (src.inc_damage.all or 0) + (src.inc_damage[type] or 0)
 			dam = dam + (dam * inc / 100)
 		end
 
diff --git a/game/modules/tome/data/general/grids/basic.lua b/game/modules/tome/data/general/grids/basic.lua
index 6d14ec4987bcf837299356f63b8c6a22595e75eb..88b511ae9272483bfd7660cf1e9bd4b52f21e867 100644
--- a/game/modules/tome/data/general/grids/basic.lua
+++ b/game/modules/tome/data/general/grids/basic.lua
@@ -26,6 +26,15 @@ newEntity{
 	change_level = 1,
 	change_zone = "wilderness",
 }
+newEntity{
+	define_as = "UP_WILDERNESS_FAR_EAST",
+	name = "exit to the wilds",
+	display = '<', color_r=255, color_g=0, color_b=255,
+	always_remember = true,
+	notice = true,
+	change_level = 1,
+	change_zone = "wilderness-arda-fareast",
+}
 
 newEntity{
 	define_as = "UP",
diff --git a/game/modules/tome/data/maps/wilderness/arda-fareast.lua b/game/modules/tome/data/maps/wilderness/arda-fareast.lua
index 2065c456ae5d4d9807510d72cf1af7f5c167ccac..ad949721596f0211d325a3a8c5dd2c71a5d6f42c 100644
--- a/game/modules/tome/data/maps/wilderness/arda-fareast.lua
+++ b/game/modules/tome/data/maps/wilderness/arda-fareast.lua
@@ -28,7 +28,7 @@ quickEntity('t', {always_remember = true, show_tooltip=true, name='forest', disp
 quickEntity('m', {always_remember = true, show_tooltip=true, name='mountains', display='^', color=colors.LIGHT_UMBER, back_color=colors.UMBER, image="terrain/mountain.png", block_move=true})
 quickEntity('h', {always_remember = true, show_tooltip=true, name='low hills', display='^', color=colors.GREEN, back_color=colors.DARK_GREEN, image="terrain/hills.png", can_encounter=true, equilibrium_level=-10})
 
---quickEntity('A', {always_remember = true, show_tooltip=true, name="Caves below the tower of Amon Sûl", 	display='>', color={r=0, g=255, b=255}, notice = true, change_level=1, change_zone="tower-amon-sul"})
+quickEntity('A', {always_remember = true, show_tooltip=true, name="Sun Wall Outpost (Town)", display='*', color=colors.GOLD, notice = true, change_level=1, change_zone="town-sunwall-outpost"})
 
 quickEntity('1', {always_remember = true, show_tooltip=true, name="Gates of Morning", desc="A massive hole in the Sun Wall", display='*', color=colors.GOLD, back_color=colors.CRIMSON, image="terrain/gate-morning.png", tint=colors.GOLD, notice = true, change_level=1, change_zone="town-gates-of-morning"})
 --quickEntity('2', {always_remember = true, show_tooltip=true, name="Minas Tirith (Town)", desc="Captical city of the Reunited-Kingdom and Gondor ruled by High King Eldarion", display='*', color={r=255, g=255, b=255}, image="terrain/town1.png", notice = true, change_level=1, change_zone="town-minas-tirith"})
@@ -88,13 +88,13 @@ return [[
 ==============================       hhhhhhh                      www============
 ================================         h                        www============
 =================================                  hh             www============
-=================================                  hhh            www============
-=================================tttt             hhhh            www============
-================================tttttttt          hh               w  ===========
-================================tttttttttt                            ===========
-================================ttttttttttt                            ==========
-===============================stttttttttttt                sssssss    ==========
-==============================sstssstttttttt            sssssssssssssss==========
+========== ======================                  hhh            www============
+=======h   ======================tttt             hhhh            www============
+=====hh     ====================tttttttt          hh               w  ===========
+======mm    ====================tttttttttt                            ===========
+======tttmm A===================ttttttttttt                            ==========
+======ttt=mm===================stttttttttttt                sssssss    ==========
+=======t======================sstssstttttttt            sssssssssssssss==========
 =============================sstssttsst            ssssssssssssssssssss==========
 =============================ssssssssssssssssssssssssssssssssssssssssss==========
 =============================sssssssssssssssssssssssssssssssssssssssss===========
diff --git a/game/modules/tome/data/talents/misc/misc.lua b/game/modules/tome/data/talents/misc/misc.lua
index 6d81b5534913e98376795f763743589e523a67d7..892c35fafbde29dd39fb85221f672655db62b448 100644
--- a/game/modules/tome/data/talents/misc/misc.lua
+++ b/game/modules/tome/data/talents/misc/misc.lua
@@ -197,3 +197,19 @@ newTalent{
 		The bonus will increase with the Constitution stat]]):format(10 + self:getCon() / 5, 10 + self:getCon() / 5)
 	end,
 }
+
+-- Orc's power: temporary damage increase
+newTalent{
+	short_name = "ORC_FURY",
+	name = "Orcish Fury",
+	type = {"base/race", 1},
+	cooldown = 50,
+	action = function(self, t)
+		self:setEffect(self.EFF_ORC_FURY, 5, {power=10 + self:getWil(20)})
+		return true
+	end,
+	info = function(self)
+		return ([[Summons your lust for blood and destruction, increasing all damage by %d for 5 turns.
+		The bonus will increase with the Willpower stat]]):format(10 + self:getWil(20))
+	end,
+}
diff --git a/game/modules/tome/data/texts/intro-orc.lua b/game/modules/tome/data/texts/intro-orc.lua
new file mode 100644
index 0000000000000000000000000000000000000000..613dcc823b959b53e9a51e5816dc76615ce0fb5b
--- /dev/null
+++ b/game/modules/tome/data/texts/intro-orc.lua
@@ -0,0 +1,28 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 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 [[Welcome #LIGHT_GREEN#]]..name..[[#WHITE#.
+You are a member of the feared race of the Orcs.
+For ages your kind has served Morgoth and his lieutenant Sauron, but they have all been vanquished by the free people.
+Now as come the time for your revenge, a new power is rising in the far east of Arda, and you are one of its soldiers!
+
+You have been sent to a remote island on the south-west coast of the Far East to crush an outpost of the Sun Wall, the last remaining bastion of men, elves and dwarves on this continent.
+
+A little to the south lies the outpost. Your task: destroy it and bathe in the blood of its people!
+]]
diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua
index 5e48baab46bb176f50c4e760b2b8c2a4d3c12863..f6355836e44a7fc88601f94378b2455087b7dec3 100644
--- a/game/modules/tome/data/timed_effects.lua
+++ b/game/modules/tome/data/timed_effects.lua
@@ -337,6 +337,22 @@ newEffect{
 	end,
 }
 
+newEffect{
+	name = "ORC_FURY",
+	desc = "Orcish Fury",
+	type = "physical",
+	status = "beneficial",
+	parameters = { power=10 },
+	on_gain = function(self, err) return "#Target# enters a state of bloodlust." end,
+	on_lose = function(self, err) return "#Target# calms down." end,
+	activate = function(self, eff)
+		eff.pid = self:addTemporaryValue("inc_damage", {all=eff.power})
+	end,
+	deactivate = function(self, eff)
+		self:removeTemporaryValue("inc_damage", eff.pid)
+	end,
+}
+
 newEffect{
 	name = "TIME_PRISON",
 	desc = "Time Prison",
diff --git a/game/modules/tome/data/zones/test/zone.lua b/game/modules/tome/data/zones/test/zone.lua
index 2c9aeac7b27e1ff0b6ebea58b23d003cbb23a661..84584796d2d6c8283daa6b31ac8e932f992330c3 100644
--- a/game/modules/tome/data/zones/test/zone.lua
+++ b/game/modules/tome/data/zones/test/zone.lua
@@ -24,19 +24,19 @@ return {
 	max_level = 4,
 	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 = 70, height = 70,
-	all_remembered = true,
+	width = 90, height = 90,
+--	all_remembered = true,
 	all_lited = true,
 --	persistant = "zone",
 	generator =  {
 		map = {
-			class = "engine.generator.map.Cavern",
-			zoom = 16,
-			min_floor = 1200,
+			class = "engine.generator.map.Town",
 			floor = "FLOOR",
+			external_floor = "GRASS",
 			wall = "WALL",
 			up = "UP",
 			down = "DOWN",
+			door = "DOOR",
 		},
 --[[
 		actor = {
@@ -57,7 +57,7 @@ return {
 	{
 		[1] = {
 			generator = { map = {
-				up = "UP_WILDERNESS",
+				up = "UP_WILDERNESS_FAR_EAST",
 			}, },
 		},
 	},
diff --git a/game/modules/tome/data/zones/town-sunwall-outpost/grids.lua b/game/modules/tome/data/zones/town-sunwall-outpost/grids.lua
new file mode 100644
index 0000000000000000000000000000000000000000..17d13d0604094de870b55cca229193a50d5ac0a8
--- /dev/null
+++ b/game/modules/tome/data/zones/town-sunwall-outpost/grids.lua
@@ -0,0 +1,22 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 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")
+load("/data/general/grids/water.lua")
diff --git a/game/modules/tome/data/zones/town-sunwall-outpost/npcs.lua b/game/modules/tome/data/zones/town-sunwall-outpost/npcs.lua
new file mode 100644
index 0000000000000000000000000000000000000000..82f2444fc95fc2babd498e489ddf6df8a60a6198
--- /dev/null
+++ b/game/modules/tome/data/zones/town-sunwall-outpost/npcs.lua
@@ -0,0 +1,19 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 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
+
diff --git a/game/modules/tome/data/zones/town-sunwall-outpost/objects.lua b/game/modules/tome/data/zones/town-sunwall-outpost/objects.lua
new file mode 100644
index 0000000000000000000000000000000000000000..b5facd63f5b34e95c1aab209db0f312a8aef3e91
--- /dev/null
+++ b/game/modules/tome/data/zones/town-sunwall-outpost/objects.lua
@@ -0,0 +1,20 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 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")
diff --git a/game/modules/tome/data/zones/town-sunwall-outpost/zone.lua b/game/modules/tome/data/zones/town-sunwall-outpost/zone.lua
new file mode 100644
index 0000000000000000000000000000000000000000..f8252906c01a076116ec6c0736d7a351e451f9cc
--- /dev/null
+++ b/game/modules/tome/data/zones/town-sunwall-outpost/zone.lua
@@ -0,0 +1,59 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 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 = "Sun Wall Outpost",
+	level_range = {1, 10},
+	max_level = 5,
+	width = 50, height = 50,
+	persistent = "zone",
+--	all_remembered = true,
+	all_lited = true,
+	ambiant_music = "80s_song.ogg",
+	generator =  {
+		map = {
+			class = "engine.generator.map.Town",
+			building_chance = 70,
+			max_building_w = 8, max_building_h = 8,
+			edge_entrances = {8,2},
+			floor = "FLOOR",
+			external_floor = "GRASS",
+			wall = "WALL",
+			up = "UP",
+			down = "DOWN",
+			door = "DOOR",
+		},
+		actor = {
+			class = "engine.generator.actor.Random",
+			nb_npc = {0, 0},
+		},
+		object = {
+			class = "engine.generator.object.Random",
+			nb_object = {0, 0},
+		},
+	},
+	levels =
+	{
+		[1] = {
+			generator = { map = {
+				up = "UP_WILDERNESS_FAR_EAST",
+			}, },
+		},
+	},
+}
diff --git a/game/modules/tome/data/zones/wilderness-arda-fareast/zone.lua b/game/modules/tome/data/zones/wilderness-arda-fareast/zone.lua
index 835d7f2374b1a93fcd72dac7150fc60694f8b4f5..554456c8a39495d5539904f175f61fb715f7e488 100644
--- a/game/modules/tome/data/zones/wilderness-arda-fareast/zone.lua
+++ b/game/modules/tome/data/zones/wilderness-arda-fareast/zone.lua
@@ -23,10 +23,10 @@ return {
 	max_level = 1,
 	width = 100, height = 100,
 --	all_remembered = true,
---	all_lited = true,
---	persistant = "memory",
+	all_lited = true,
+	persistant = "memory",
 	wilderness = true,
-	wilderness_see_radius = 3,
+--	wilderness_see_radius = 3,
 	ambiant_music = "last",
 	generator =  {
 		map = {