diff --git a/game/engine/Actor.lua b/game/engine/Actor.lua
deleted file mode 100644
index f5c43106756ce1a9327eb96b5e1bab31ae8896e4..0000000000000000000000000000000000000000
--- a/game/engine/Actor.lua
+++ /dev/null
@@ -1,414 +0,0 @@
--- 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 Entity = require "engine.Entity"
-local Map = require "engine.Map"
-local Faction = require "engine.Faction"
-
-module(..., package.seeall, class.inherit(Entity))
-
-_M.display_on_seen = true
-_M.display_on_remember = false
-_M.display_on_unknown = false
--- Allow actors to act as object carriers, if the interface is loaded
-_M.__allow_carrier = true
-
-function _M:init(t, no_default)
-	t = t or {}
-
-	if not self.targetable and self.targetable == nil then self.targetable = true end
-	self.name = t.name or "unknown actor"
-	self.level = t.level or 1
-	self.sight = t.sight or 20
-	self.energy = t.energy or { value=0, mod=1 }
-	self.energy.value = self.energy.value or 0
-	self.energy.mod = self.energy.mod or 0
-	self.faction = t.faction or "enemies"
-	self.changed = true
-	Entity.init(self, t, no_default)
-
-	self.compute_vals = {n=0}
-end
-
---- Called when it is time to act
-function _M:act()
-	if self.dead then return false end
-	return true
-end
-
---- Gets the actor target
--- Does nothing, AI redefines it so should a "Player" class
-function _M:getTarget()
-end
---- Sets the actor target
--- Does nothing, AI redefines it so should a "Player" class
-function _M:setTarget(target)
-end
-
---- Adds a particles emitter following the actor
-function _M:addParticles(ps)
-	self.__particles[ps] = true
-	if self.x and self.y and game.level and game.level.map then
-		ps.x = self.x
-		ps.y = self.y
-		game.level.map:addParticleEmitter(ps)
-	end
-	return ps
-end
-
---- Removes a particles emitter following the actor
-function _M:removeParticles(ps)
-	self.__particles[ps] = nil
-	if self.x and self.y and game.level and game.level.map then
-		ps.x = nil
-		ps.y = nil
-		game.level.map:removeParticleEmitter(ps)
-	end
-end
-
---- Set the current emote
-function _M:setEmote(e)
-	-- Remove previous
-	if self.__emote then
-		game.level.map:removeEmote(self.__emote)
-	end
-	self.__emote = e
-	if e and self.x and self.y and game.level and game.level.map then
-		e.x = self.x
-		e.y = self.y
-		game.level.map:addEmote(e)
-	end
-end
-
---- Moves an actor on the map
--- *WARNING*: changing x and y properties manualy is *WRONG* and will blow up in your face. Use this method. Always.
--- @param map the map to move onto
--- @param x coord of the destination
--- @param y coord of the destination
--- @param force if true do not check for the presence of an other entity. *Use wisely*
--- @return true if a move was *ATTEMPTED*. This means the actor will proably want to use energy
-function _M:move(x, y, force)
-	if self.dead then return true end
-	local map = game.level.map
-
-	if x < 0 then x = 0 end
-	if x >= map.w then x = map.w - 1 end
-	if y < 0 then y = 0 end
-	if y >= map.h then y = map.h - 1 end
-
-	if not force and map:checkAllEntities(x, y, "block_move", self, true) then return true end
-
-	if self.x and self.y then
-		map:remove(self.x, self.y, Map.ACTOR)
-	else
-		print("[MOVE] actor moved without a starting position", self.name, x, y)
-	end
-	self.old_x, self.old_y = self.x or x, self.y or y
-	self.x, self.y = x, y
-	map(x, y, Map.ACTOR, self)
-
-	-- Update particle emitters attached to that actor
-	local del = {}
-	for e, _ in pairs(self.__particles) do
-		if e.dead then del[#del+1] = e
-		else
-			e.x = x
-			e.y = y
-			map.particles[e] = true
-		end
-	end
-	for i = 1, #del do self.particles[del[i]] = nil end
-
-	-- Move emote
-	if self.__emote then
-		if self.__emote.dead then self.__emote = nil
-		else
-			self.__emote.x = x
-			self.__emote.y = y
-			map.emotes[self.__emote] = true
-		end
-	end
-
-	map:checkAllEntities(x, y, "on_move", self, force)
-
-	return true
-end
-
---- Moves into the given direction (calls actor:move() internally)
-function _M:moveDir(dir)
-	local dx, dy = dir_to_coord[dir][1], dir_to_coord[dir][2]
-	local x, y = self.x + dx, self.y + dy
-	return self:move(x, y)
-end
-
---- Can the actor go there
--- @param terrain_only if true checks only the terrain, otherwise checks all entities
-function _M:canMove(x, y, terrain_only)
-	if not game.level.map:isBound(x, y) then return false end
-	if terrain_only then
-		return not game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move")
-	else
-		return not game.level.map:checkAllEntities(x, y, "block_move", self)
-	end
-end
-
---- Remove the actor from the level, marking it as dead but not using the death functions
-function _M:disappear(src)
-	if game.level:hasEntity(self) then game.level:removeEntity(self) end
-	self.dead = true
-	self.changed = true
-end
-
---- Get the "path string" for this actor
--- See Map:addPathString() for more info
-function _M:getPathString()
-	return ""
-end
-
---- Teleports randomly to a passable grid
--- @param x the coord of the teleporatation
--- @param y the coord of the teleporatation
--- @param dist the radius of the random effect, if set to 0 it is a precise teleport
--- @param min_dist the minimun radius of of the effect, will never teleport closer. Defaults to 0 if not set
--- @return true if the teleport worked
-function _M:teleportRandom(x, y, dist, min_dist)
-	local poss = {}
-	dist = math.floor(dist)
-	min_dist = math.floor(min_dist or 0)
-
-	for i = x - dist, x + dist do
-		for j = y - dist, y + dist do
-			if game.level.map:isBound(i, j) and
-			   core.fov.distance(x, y, i, j) <= dist and
-			   core.fov.distance(x, y, i, j) >= min_dist and
-			   self:canMove(i, j) and
-			   not game.level.map.attrs(i, j, "no_teleport") then
-				poss[#poss+1] = {i,j}
-			end
-		end
-	end
-
-	if #poss == 0 then return false end
-	local pos = poss[rng.range(1, #poss)]
-	return self:move(pos[1], pos[2], true)
-end
-
---- Knock back the actor
-function _M:knockback(srcx, srcy, dist)
-	print("[KNOCKBACK] from", srcx, srcy, "over", dist)
-
-	local l = line.new(srcx, srcy, self.x, self.y, true)
-	local lx, ly = l(true)
-	local ox, oy = lx, ly
-	dist = dist - 1
-
-	print("[KNOCKBACK] try", lx, ly, dist)
-
-	while game.level.map:isBound(lx, ly) and not game.level.map:checkAllEntities(lx, ly, "block_move", self) and dist > 0 do
-		dist = dist - 1
-		ox, oy = lx, ly
-		lx, ly = l(true)
-		print("[KNOCKBACK] try", lx, ly, dist, "::", game.level.map:checkAllEntities(lx, ly, "block_move", self))
-	end
-
-	if game.level.map:isBound(lx, ly) and not game.level.map:checkAllEntities(lx, ly, "block_move", self) then
-		print("[KNOCKBACK] ok knocked to", lx, ly, "::", game.level.map:checkAllEntities(lx, ly, "block_move", self))
-		self:move(lx, ly, true)
-	elseif game.level.map:isBound(ox, oy) and not game.level.map:checkAllEntities(ox, oy, "block_move", self) then
-		print("[KNOCKBACK] failsafe knocked to", ox, oy, "::", game.level.map:checkAllEntities(ox, oy, "block_move", self))
-		self:move(ox, oy, true)
-	end
-end
-
-function _M:deleteFromMap(map)
-	if self.x and self.y and map then
-		map:remove(self.x, self.y, engine.Map.ACTOR)
-		for e, _ in pairs(self.__particles) do
-			e.x = nil
-			e.y = nil
-			map:removeParticleEmitter(e)
-		end
-	end
-end
-
---- Do we have enough energy
-function _M:enoughEnergy(val)
-	val = val or game.energy_to_act
-	return self.energy.value >= val
-end
-
---- Use some energy
-function _M:useEnergy(val)
-	val = val or game.energy_to_act
-	self.energy.value = self.energy.value - val
-	self.energy.used = true
-	if self.player and self.energy.value < game.energy_to_act then game.paused = false end
---	print("USE ENERGY", self.name, self.uid, "::", self.energy.value, game.paused, "::", self.player)
-end
-
---- What is our reaction toward the target
--- See Faction:factionReaction()
-function _M:reactionToward(target)
-	return Faction:factionReaction(self.faction, target.faction)
-end
-
---- Can the actor see the target actor
--- This does not check LOS or such, only the actual ability to see it.<br/>
--- By default this returns true, but a module can override it to check for telepathy, invisibility, stealth, ...
--- @param actor the target actor to check
--- @param def the default
--- @param def_pct the default percent chance
--- @return true or false and a number from 0 to 100 representing the "chance" to be seen
-function _M:canSee(actor, def, def_pct)
-	return true, 100
-end
-
---- Does the actor have LOS to the target
-function _M:hasLOS(x, y)
-	local l = line.new(self.x, self.y, x, y)
-	local lx, ly = l()
-	while lx and ly do
-		if game.level.map:checkAllEntities(lx, ly, "block_sight") then break end
-
-		lx, ly = l()
-	end
-	-- Ok if we are at the end reset lx and ly for the next code
-	if not lx and not ly then lx, ly = x, y end
-
-	if lx == x and ly == y then return true, lx, ly end
-	return false, lx, ly
-end
-
-local function gettable(base, name)
-	for w in name:gmatch("[^.]+") do
-		base = base[w]
-	end
-	return base
-end
-
---- Computes a "temporary" value into a property
--- Example: You cant to give an actor a boost to life_regen, but you do not want it to be permanent<br/>
--- You cannot simply increase life_regen, so you use this method which will increase it AND
--- store the increase. it will return an "increase id" that can be passed to removeTemporaryValue()
--- to remove the effect.
--- @param prop the property to affect
--- @param v the value to add (only numbers supported for now)
--- @param noupdate if true the actual property is not changed and needs to be changed by the caller
--- @return an id that can be passed to removeTemporaryValue() to delete this value
-function _M:addTemporaryValue(prop, v, noupdate)
-	local t = self.compute_vals
-	local id = t.n + 1
-	while t[id] ~= nil do id = id + 1 end
-	t[id] = v
-	t.n = id
-
-	-- Update the base prop
-	if not noupdate then
-		if type(v) == "number" then
-			-- Simple addition
-			self[prop] = (self[prop] or 0) + v
-			self:onTemporaryValueChange(prop, nil, v)
-			print("addTmpVal", prop, v, " :=: ", #t, id)
-		elseif type(v) == "table" then
-			for k, e in pairs(v) do
-				self[prop][k] = (self[prop][k] or 0) + e
-				self:onTemporaryValueChange(prop, k, e)
-				print("addTmpValTable", prop, k, e, " :=: ", #t, id)
-				if #t == 0 then print("*******************************WARNING") end
-			end
---		elseif type(v) == "boolean" then
---			-- False has precedence over true
---			if v == false then
---				self[prop] = false
---			elseif self[prop] ~= false then
---				self[prop] = true
---			end
-		else
-			error("unsupported temporary value type: "..type(v))
-		end
-	end
-
-	return id
-end
-
---- Removes a temporary value, see addTemporaryValue()
--- @param prop the property to affect
--- @param id the id of the increase to delete
--- @param noupdate if true the actual property is not changed and needs to be changed by the caller
-function _M:removeTemporaryValue(prop, id, noupdate)
-	local oldval = self.compute_vals[id]
-	print("removeTempVal", prop, oldval, " :=: ", id)
-	self.compute_vals[id] = nil
-	if not noupdate then
-		if type(oldval) == "number" then
-			self[prop] = self[prop] - oldval
-			self:onTemporaryValueChange(prop, nil, -oldval)
-			print("delTmpVal", prop, oldval)
-		elseif type(oldval) == "table" then
-			for k, e in pairs(oldval) do
-				self[prop][k] = self[prop][k] - e
-				self:onTemporaryValueChange(prop, k, -e)
-				print("delTmpValTable", prop, k, e)
-			end
---		elseif type(oldval) == "boolean" then
-		else
-			error("unsupported temporary value type: "..type(oldval))
-		end
-	end
-end
-
---- Called when a temporary value changes (added or deleted)
--- This does nothing by default, you can overload it to react to changes
--- @param prop the property changing
--- @param sub the sub element of the property if it is a table, or nil
--- @param v the value of the change
-function _M:onTemporaryValueChange(prop, sub, v)
-end
-
---- Increases/decreases an attribute
--- The attributes are just actor properties, but this ensures they are numbers and not booleans
--- thus making them compatible with temporary values system
--- @param prop the property to use
--- @param v the value to add, if nil this the function return
--- @param fix forces the value to v, do not add
--- @return nil if v was specified. If not then it returns the current value if it exists and is not 0 otherwise returns nil
-function _M:attr(prop, v, fix)
-	if v then
-		if fix then self[prop] = v
-		else self[prop] = (self[prop] or 0) + v
-		end
-	else
-		if self[prop] and self[prop] ~= 0 then
-			return self[prop]
-		else
-			return nil
-		end
-	end
-end
-
---- Are we within a certain distance of the target
--- @param x the spot we test for near-ness
--- @param y the spot we test for near-ness
--- @param radius how close we should be (defaults to 1)
-function _M:isNear(x, y, radius)
-	radius = radius or 1
-	if math.floor(core.fov.distance(self.x, self.y, x, y)) > radius then return false end
-	return true
-end
diff --git a/game/engine/ActorsSeenDisplay.lua b/game/engine/ActorsSeenDisplay.lua
deleted file mode 100644
index b8a7698055d957bde54680a0d4a71b77b5bf3314..0000000000000000000000000000000000000000
--- a/game/engine/ActorsSeenDisplay.lua
+++ /dev/null
@@ -1,75 +0,0 @@
--- 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"
-
-module(..., package.seeall, class.make)
-
-function _M:init(actor, x, y, w, h, bgcolor)
-	self.actor = actor
-	self.bgcolor = bgcolor
-	self.font = core.display.newFont("/data/font/VeraMono.ttf", 10)
-	self.font_h = self.font:lineSkip()
-	self:resize(x, y, w, h)
-end
-
---- Resize the display area
-function _M:resize(x, y, w, h)
-	self.display_x, self.display_y = math.floor(x), math.floor(y)
-	self.w, self.h = math.floor(w), math.floor(h)
-	self.surface = core.display.newSurface(w, h)
-	if self.actor then self.actor.changed = true end
-
-	local cw, ch = self.font:size(" ")
-	self.font_w = cw
-end
-
--- Displays the hotkeys, keybinds & cooldowns
-function _M:display()
-	local a = self.actor
-	if not a or not a.changed then return self.surface end
-
-	self.surface:erase(self.bgcolor[1], self.bgcolor[2], self.bgcolor[3])
-
-	local list = {}
-
-	-- initialize the array
-	for i, act in ipairs(a.fov.actors_dist) do
-		if a:canSee(act) then
-			local n = act.name:capitalize()
-			list[n] = list[n] or { name=n, nb=0, dist={} }
-			list[n].nb = list[n].nb + 1
-			list[n].dist[#list[n].dist+1] = math.floor(math.sqrt(a.fov.actors[act].sqdist))
-
-			local r = a:reactionToward(act)
-			if r > 0 then list[n].color={0,255,0}
-			elseif r == 0 then list[n].color={176,196,222}
-			elseif r < 0 then list[n].color={255,0,0} end
-		end
-	end
-	local l = {}
-	for _, a in pairs(list) do l[#l+1] = a end
-	table.sort(l, function(a, b) return a.name < b.name end)
-
-	for i, a in ipairs(l) do
-		self.surface:drawColorStringBlended(self.font, ("%s (%d)#WHITE#; distance [%s]"):format(a.name, a.nb, table.concat(a.dist, ",")), 0, (i - 1) * self.font_h, a.color[1], a.color[2], a.color[3])
-	end
-
-	return self.surface
-end
diff --git a/game/engine/Astar.lua b/game/engine/Astar.lua
deleted file mode 100644
index b1b2523d97732db1f350f661357720dd232323a3..0000000000000000000000000000000000000000
--- a/game/engine/Astar.lua
+++ /dev/null
@@ -1,149 +0,0 @@
--- 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"
-
---- Pathfinding using A*
-module(..., package.seeall, class.make)
-
---- Initializes Astar for a map and an actor
-function _M:init(map, actor)
-	self.map = map
-	self.actor = actor
-	self.move_cache = {}
-end
-
---- 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)
-	return x + y * self.map.w
-end
-function _M:toDouble(c)
-	local y = math.floor(c / self.map.w)
-	return c - y * self.map.w, y
-end
-
-function _M:createPath(came_from, cur)
-	if not came_from[cur] then return end
-	local rpath, path = {}, {}
-	while came_from[cur] do
-		local x, y = self:toDouble(cur)
-		rpath[#rpath+1] = {x=x,y=y}
-		cur = came_from[cur]
-	end
-	for i = #rpath, 1, -1 do path[#path+1] = rpath[i] end
-	return path
-end
-
---- Compute path from sx/sy to tx/ty
--- @param sx the start coord
--- @param sy the start coord
--- @param tx the end coord
--- @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, 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] = 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()]
-	local checkPos
-	if cache then
-		checkPos = function(node, nx, ny)
-			local nnode = self:toSingle(nx, ny)
-			if not closed[nnode] and self.map:isBound(nx, ny) and ((use_has_seen and not self.map.has_seens(nx, ny)) or not cache:get(nx, ny)) then
-				local tent_g_score = g_score[node] + 1 -- we can adjust hre for difficult passable terrain
-				local tent_is_better = false
-				if not open[nnode] then open[nnode] = true; tent_is_better = true
-				elseif tent_g_score < g_score[nnode] then tent_is_better = true
-				end
-
-				if tent_is_better then
-					came_from[nnode] = node
-					g_score[nnode] = tent_g_score
-					h_score[nnode] = heur(self, sx, sy, tx, ty, nx, ny)
-					f_score[nnode] = g_score[nnode] + h_score[nnode]
-				end
-			end
-		end
-	else
-		checkPos = function(node, nx, ny)
-			local nnode = self:toSingle(nx, ny)
-			if not closed[nnode] and self.map:isBound(nx, ny) and ((use_has_seen and not self.map.has_seens(nx, ny)) or not self.map:checkEntity(nx, ny, Map.TERRAIN, "block_move", self.actor, nil, true)) then
-				local tent_g_score = g_score[node] + 1 -- we can adjust hre for difficult passable terrain
-				local tent_is_better = false
-				if not open[nnode] then open[nnode] = true; tent_is_better = true
-				elseif tent_g_score < g_score[nnode] then tent_is_better = true
-				end
-
-				if tent_is_better then
-					came_from[nnode] = node
-					g_score[nnode] = tent_g_score
-					h_score[nnode] = heur(self, sx, sy, tx, ty, nx, ny)
-					f_score[nnode] = g_score[nnode] + h_score[nnode]
-				end
-			end
-		end
-	end
-
-	while next(open) do
-		-- Find lowest of f_score
-		local node, lowest = nil, 999999999999999
-		for n, _ in pairs(open) do
-			if f_score[n] < lowest then node = n; lowest = f_score[n] end
-		end
-
-		if node == stop then return self:createPath(came_from, stop) end
-
-		open[node] = nil
-		closed[node] = true
-		local x, y = self:toDouble(node)
-
-		-- Check sides
-		checkPos(node, x + 1, y)
-		checkPos(node, x - 1, y)
-		checkPos(node, x, y + 1)
-		checkPos(node, x, y - 1)
-		checkPos(node, x + 1, y + 1)
-		checkPos(node, x + 1, y - 1)
-		checkPos(node, x - 1, y + 1)
-		checkPos(node, x - 1, y - 1)
-	end
-end
diff --git a/game/engine/Autolevel.lua b/game/engine/Autolevel.lua
deleted file mode 100644
index fcb197e1259abd6c7d9d94ee241684c937755441..0000000000000000000000000000000000000000
--- a/game/engine/Autolevel.lua
+++ /dev/null
@@ -1,40 +0,0 @@
--- 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"
-
---- Handles autoleveling schemes
--- Proably used mainly for NPCS, although it could also be used for player allies
--- or players themselves for lazy players/modules
-module(..., package.seeall, class.make)
-
-_M.schemes = {}
-
-function _M:registerScheme(t)
-	assert(t.name, "no autolevel name")
-	assert(t.levelup, "no autolevel levelup function")
-	_M.schemes[t.name] = t
-end
-
-function _M:autoLevel(actor)
-	if not actor.autolevel then return end
-	assert(_M.schemes[actor.autolevel], "no autoleveling scheme "..actor.autolevel)
-
-	_M.schemes[actor.autolevel].levelup(actor)
-end
diff --git a/game/engine/BSP.lua b/game/engine/BSP.lua
deleted file mode 100644
index 0fbfd520d855d4f8e4feaf66e5049c4e470427b3..0000000000000000000000000000000000000000
--- a/game/engine/BSP.lua
+++ /dev/null
@@ -1,68 +0,0 @@
--- 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/Birther.lua b/game/engine/Birther.lua
deleted file mode 100644
index 5d40f06b6fb6cbc6ebc5fa2dbfd21286dae479ad..0000000000000000000000000000000000000000
--- a/game/engine/Birther.lua
+++ /dev/null
@@ -1,272 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-_M.birth_descriptor_def = {}
-_M.birth_auto = {}
-
---- Defines birth descriptors
--- Static!
-function _M:loadDefinition(file)
-	local f, err = loadfile(file)
-	if not f and err then error(err) os.exit() end
-	setfenv(f, setmetatable({
-		ActorTalents = require("engine.interface.ActorTalents"),
-		newBirthDescriptor = function(t) self:newBirthDescriptor(t) end,
-		setAuto = function(type, v) self.birth_auto[type] = v end,
-		load = function(f) self:loadDefinition(f) end
-	}, {__index=_G}))
-	f()
-end
-
---- Defines one birth descriptor
--- Static!
-function _M:newBirthDescriptor(t)
-	assert(t.name, "no birth name")
-	assert(t.type, "no birth type")
-	t.short_name = t.short_name or t.name
-	t.short_name = t.short_name:upper():gsub("[ ]", "_")
-	assert(t.desc, "no birth description")
-	if type(t.desc) == "table" then t.desc = table.concat(t.desc, "\n") end
-	t.desc = t.desc:gsub("\n\t+", "\n")
-	t.descriptor_choices = t.descriptor_choices or {}
-
-	table.insert(self.birth_descriptor_def, t)
-	t.id = #self.birth_descriptor_def
-	self.birth_descriptor_def[t.type] = self.birth_descriptor_def[t.type] or {}
-	self.birth_descriptor_def[t.type][t.name] = t
-	table.insert(self.birth_descriptor_def[t.type], t)
-end
-
-
---- Instanciates a birther for the given actor
-function _M:init(actor, order, at_end, quickbirth)
-	self.quickbirth = quickbirth
-	self.actor = actor
-	self.order = order
-	self.at_end = at_end
-
-	engine.Dialog.init(self, "Character Creation: "..actor.name, 600, 400)
-
-	self.descriptors = {}
-
-	self.cur_order = 1
-	self:next()
-
-	self:keyCommands({
-		_BACKSPACE = function() self:prev() end,
-	},{
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list); self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list); self.changed = true end,
-		ACCEPT = function() self:next() end,
-	})
-	self:mouseZones{
-		{ x=2, y=25, w=350, h=self.h, fct=function(button, x, y, xrel, yrel, tx, ty)
-			self.changed = true
-			if ty < self.font_h*#self.list then
-				self.sel = 1 + math.floor(ty / self.font_h)
-				if button == "left" then self:next()
-				elseif button == "right" then self:prev()
-				end
-			end
-		end },
-	}
-end
-
-function _M:on_register()
-	if self.quickbirth then
-		self:yesnoPopup("Quick Birth", "Do you want to recreate the same character?", function(ret)
-			if ret then
-				self.do_quickbirth = true
-				self:quickBirth()
-			end
-		end)
-	end
-end
-
-function _M:quickBirth()
-	if not self.do_quickbirth then return end
-	-- Aborth quickbirth if stage not found
-	if not self.quickbirth[self.current_type] then self.do_quickbirth = false end
-
-	-- Find the corect descriptor
-	for i, d in ipairs(self.list) do
-		if self.quickbirth[self.current_type] == d.name then
-			print("[QUICK BIRTH] using", d.name, "for", self.current_type)
-			self.sel = i
-			self:next()
-			return true
-		end
-	end
-
-	-- Abord if not found
-	self.do_quickbirth = false
-end
-
-function _M:selectType(type)
-	local default = 1
-	self.list = {}
-	-- Make up the list
-	print("[BIRTHER] selecting type", type)
-	for i, d in ipairs(self.birth_descriptor_def[type]) do
-		local allowed = true
-		print("[BIRTHER] checking allowance for ", d.name)
-		for j, od in ipairs(self.descriptors) do
-			if od.descriptor_choices[type] then
-				local what = util.getval(od.descriptor_choices[type][d.name]) or util.getval(od.descriptor_choices[type].__ALL__)
-				if what and what == "allow" then
-					allowed = true
-				elseif what and (what == "never" or what == "disallow") then
-					allowed = false
-				elseif what and what == "forbid" then
-					allowed = nil
-				end
-				print("[BIRTHER] test against ", od.name, "=>", what, allowed)
-				if allowed == nil then break end
-			end
-		end
-
-		-- Check it is allowed
-		if allowed then
-			table.insert(self.list, d)
-			if d.selection_default then default = #self.list end
-		end
-	end
-	self.sel = default
-	self.current_type = type
-end
-
-function _M:prev()
-	if self.cur_order == 1 then
-		if #self.list == 1 and self.birth_auto[self.current_type] ~= false  then self:next() end
-		return
-	end
-	if not self.list then return end
-	self.changed = true
-	table.remove(self.descriptors)
-	self.cur_order = self.cur_order - 1
-	self:selectType(self.order[self.cur_order])
-	if #self.list == 1 then
-		self:prev()
-	end
-end
-
-function _M:next()
-	self.changed = true
-	if self.list then
-		table.insert(self.descriptors, self.list[self.sel])
-		if self.list[self.sel].on_select then self.list[self.sel]:on_select() end
-
-		self.cur_order = self.cur_order + 1
-		if not self.order[self.cur_order] then
-			game:unregisterDialog(self)
-			self:apply()
-			self.at_end()
-			return
-		end
-	end
-	self:selectType(self.order[self.cur_order])
-
-	if self:quickBirth() then return end
-
-	if #self.list == 1 and self.birth_auto[self.current_type] ~= false then
-		self:next()
-	end
-end
-
---- Apply all birth options to the actor
-function _M:apply()
-	self.actor.descriptor = {}
-	for i, d in ipairs(self.descriptors) do
-		print("[BIRTH] Applying descriptor "..d.name)
-		self.actor.descriptor[d.type] = d.name
-
-		if d.copy then
-			local copy = table.clone(d.copy, true)
-			-- Append array part
-			while #copy > 0 do
-				local f = table.remove(copy)
-				table.insert(self.actor, f)
-			end
-			-- Copy normal data
-			table.merge(self.actor, copy, true)
-		end
-		-- Change stats
-		if d.stats then
-			for stat, inc in pairs(d.stats) do
-				self.actor:incStat(stat, inc)
-			end
-		end
-		if d.talents_types then
-			for t, v in pairs(d.talents_types) do
-				local mastery
-				if type(v) == "table" then
-					v, mastery = v[1], v[2]
-				else
-					v, mastery = v, 0
-				end
-				self.actor:learnTalentType(t, v)
-				self.actor.talents_types_mastery[t] = (self.actor.talents_types_mastery[t] or 1) + mastery
-				print(t)
-			end
-		end
-		if d.talents then
-			for tid, lev in pairs(d.talents) do
-				for i = 1, lev do
-					self.actor:learnTalent(tid, true)
-				end
-			end
-		end
-		if d.experience then self.actor.exp_mod = self.actor.exp_mod * d.experience end
-		if d.body then
-			self.actor.body = d.body
-			self.actor:initBody()
-		end
-	end
-end
-
-function _M:drawDialog(s)
-	if not self.list or not self.list[self.sel] then return end
-
-	-- Description part
-	self:drawHBorder(s, self.iw / 2, 2, self.ih - 4)
-	local birthhelp = ([[Keyboard: #00FF00#up key/down key#FFFFFF# to select an option; #00FF00#Enter#FFFFFF# to accept; #00FF00#Backspace#FFFFFF# to go back.
-Mouse: #00FF00#Left click#FFFFFF# to accept; #00FF00#right click#FFFFFF# to go back.
-]]):splitLines(self.iw / 2 - 10, self.font)
-	for i = 1, #birthhelp do
-		s:drawColorStringBlended(self.font, birthhelp[i], self.iw / 2 + 5, 2 + (i-1) * self.font:lineSkip())
-	end
-
-	local lines = self.list[self.sel].desc:splitLines(self.iw / 2 - 10, self.font)
-	local r, g, b
-	for i = 1, #lines do
-		r, g, b = s:drawColorStringBlended(self.font, lines[i], self.iw / 2 + 5, 2 + (i + #birthhelp + 1) * self.font:lineSkip(), r, g, b)
-	end
-
-	-- Stats
-	s:drawColorStringBlended(self.font, "Selecting: "..self.current_type:capitalize(), 2, 2)
-	self:drawWBorder(s, 2, 20, 200)
-
-	self:drawSelectionList(s, 2, 25, self.font_h, self.list, self.sel, "name")
-	self.changed = false
-end
diff --git a/game/engine/Button.lua b/game/engine/Button.lua
deleted file mode 100644
index 09c034c639c74787477204ef3750191653dc88b8..0000000000000000000000000000000000000000
--- a/game/engine/Button.lua
+++ /dev/null
@@ -1,57 +0,0 @@
--- 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"
-require "engine.Tiles"
-require "engine.Mouse"
-require "engine.KeyBind"
-local ButtonList = require "engine.ButtonList"
-
---- Handles dialog windows
-module(..., package.seeall, class.make)
-
-function _M:init(name, text, x, y, w, height, owner, font, fct)	
-	self.type = "Button"
-	self.owner = owner
-	self.name = name	
-	self.fct = fct
-	self.font = font	
-	self.x = x
-	self.y = y
-	self.btn = 	{ 
-		susel = ButtonList:makeButton(text, self.font, w, height, false),
-		sel = ButtonList:makeButton(text, self.font, 50, height, true),
-		h = height,
-		mouse_over= function(button)							
-						if self.owner.state ~= self.name then self.owner:focusControl(self.name) end						
-						if button == "left" then
-							self:fct()
-						end
-					end
-					}
-	self.owner.mouse:registerZone(owner.display_x + self.x, owner.display_y + self.y + height, w, height, self.btn.mouse_over)	
-end
-
-function _M:drawControl(s)	
-	if (self.owner.state == self.name) then
-		s:merge(self.btn.sel, self.x, self.y)		
-	else
-		s:merge(self.btn.susel, self.x, self.y)				
-	end	
-end
\ No newline at end of file
diff --git a/game/engine/ButtonList.lua b/game/engine/ButtonList.lua
deleted file mode 100644
index 7b2713c91409b473acb8427f358a44696ac55a0a..0000000000000000000000000000000000000000
--- a/game/engine/ButtonList.lua
+++ /dev/null
@@ -1,161 +0,0 @@
--- 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"
-require "engine.Tiles"
-require "engine.Mouse"
-require "engine.KeyBind"
-
---- Handles dialog windows
-module(..., package.seeall, class.make)
-
-tiles = engine.Tiles.new(16, 16)
-
---- Create a buttons list
-function _M:init(list, x, y, w, h, font, separator)
-	self.separator = separator or 20
-	self.w, self.h = math.floor(w), math.floor(h)
-	self.display_x = math.floor(x or (game.w - self.w) / 2)
-	self.display_y = math.floor(y or (game.h - self.h) / 2)
-	self.font = font
-	self.list = list
-	if not font then self.font = core.display.newFont("/data/font/VeraBd.ttf", 16) end
-	self.surface = core.display.newSurface(w, h)
-	self.texture = self.surface:glTexture()
-	self.surface:erase()
-
-	self.old_selected = 0
-	self.selected = 0
-	self:select(1)
-
-	for i, b in ipairs(self.list) do
-		assert(b.name, "no button name")
-		assert(b.fct, "no button function")
-		local bw, bh = (b.font or self.font):size(b.name)
-		b.w, b.h = w, h / (#list + 1)
-		b.susel = self:makeButton(b.name, b.font, b.w, b.h, false)
-		b.ssel = self:makeButton(b.name, b.font, b.w, b.h, true)
-		b.mouse_over = function(button)
-			self:select(i)
-
-			if button == "left" then
-				self:click(i)
-			end
-		end
-	end
-
-	self.changed = true
-end
-
-function _M:close()
-	if self.old_key then self.old_key:setCurrent() end
-	if self.old_mouse then self.old_mouse:setCurrent() end
-end
-
-function _M:setKeyHandling()
-	self.old_key = engine.KeyBind.current
-	self.key = engine.KeyBind.new()
-	self.key:setCurrent()
-	self.key:addBinds
-	{
-		MOVE_UP = function()
-			self:select(-1, true)
-		end,
-		MOVE_DOWN = function()
-			self:select(1, true)
-		end,
-		ACCEPT = function()
-			self:click()
-		end,
-	}
-	game.key = self.key
-end
-
-function _M:setMouseHandling()
-	self.old_mouse = engine.Mouse.current
-	self.mouse = engine.Mouse.new()
-	self.mouse:setCurrent()
-	for i, b in ipairs(self.list) do
-		self.mouse:registerZone(self.display_x, self.display_y + (i - 1) * (b.h + self.separator), b.w, b.h, b.mouse_over)
-	end
-	game.mouse = self.mouse
-end
-
-function _M:select(i, offset)
-	if offset then
-		self.selected = self.selected + i
-	else
-		self.selected = i
-	end
-	if self.selected > #self.list then self.selected = 1 self.old_selected = 0 end
-	if self.selected < 1 then self.selected = #self.list self.old_selected = #self.list + 1 end
-	if (not self.old_selected or self.old_selected ~= self.selected) and self.list[self.selected].onSelect then self.list[self.selected].onSelect() end
-	self.old_selected = self.selected
-	self.changed = true
-end
-
-function _M:skipSelected()
-	if self.old_selected < self.selected then self:select(1, true)
-	elseif self.old_selected > self.selected then self:select(-1, true) end
-end
-
-function _M:click(i)
-	self.list[i or self.selected].fct()
-end
-
-function _M:display()
-end
-
-function _M:toScreen(x,y)
-	for i, b in ipairs(self.list) do
-		if i == self.selected then
-			b.ssel:toScreen(x + 0, y + (i - 1) * (b.h + self.separator))
-		else
-			b.susel:toScreen(x + 0, y + (i - 1) * (b.h + self.separator))
-		end
-	end
-end
-
-function _M:makeButton(name, font, w, h, sel)
-	font = font or self.font
-	local s = core.display.newSurface(w, h)
-	if sel then
-		s:erase(143, 155, 85, 200)
-	else
-		s:erase(0,0,0,200)
-	end
-
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_7"..(sel and "_sel" or "")..".png"), 0, 0)
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_9"..(sel and "_sel" or "")..".png"), w - 8, 0)
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_1"..(sel and "_sel" or "")..".png"), 0, h - 8)
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_3"..(sel and "_sel" or "")..".png"), w - 8, h - 8)
-	for i = 8, w - 9 do
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_8.png"), i, 0)
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_8.png"), i, h - 3)
-	end
-	for i = 8, h - 9 do
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_4.png"), 0, i)
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_4.png"), w - 3, i)
-	end
-
-	local sw, sh = font:size(name)
-	s:drawColorStringBlended(font, name, (w - sw) / 2, (h - sh) / 2)
-
-	return s
-end
diff --git a/game/engine/Calendar.lua b/game/engine/Calendar.lua
deleted file mode 100644
index ae157054f6bc731973f6e3a9375b222da20358f3..0000000000000000000000000000000000000000
--- a/game/engine/Calendar.lua
+++ /dev/null
@@ -1,97 +0,0 @@
--- 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"
-
---- Defines factions
-module(..., package.seeall, class.make)
-
-seconds_per_turn = 10
-
-MINUTE = 60 / seconds_per_turn
-HOUR = MINUTE * 60
-DAY = HOUR * 24
-YEAR = DAY * 365
-DAY_START = HOUR * 6
-
---- Create a calendar
--- @param definition the file to load that returns a table containing calendar months
--- @param datestring a string to format the date when requested, in the format "%s %s %s %d %d", standing for, day, month, year, hour, minute
-function _M:init(definition, datestring, start_year)
-	local data = dofile(definition)
-	self.calendar = {}
-	local days = 0
-	for _, e in ipairs(data) do
-		if not e[3] then e[3] = 0 end
-		table.insert(self.calendar, { days=days, name=e[2], length=e[1], offset=e[3] })
-		days = days + e[1]
-	end
-	assert(days == 365, "Calendar incomplete, days ends at "..days.." instead of 365")
-
-	self.datestring = datestring
-	self.start_year = start_year
-end
-
-function _M:getTimeDate(turn)
-	local doy, year = self:getDayOfYear(turn)
-	local hour, min = self:getTimeOfDay(turn)
-	return self.datestring:format(tostring(self:getDayOfMonth(doy)):ordinal(), self:getMonthName(doy), tostring(year):ordinal(), hour, min)
-end
-
-function _M:getDayOfYear(turn)
-	local d, y
-	d = math.floor(turn / self.DAY)
-	y = math.floor(d / 365)
-	d = math.floor(d % 365)
-	return d, self.start_year + y
-end
-
-function _M:getTimeOfDay(turn)
-	local hour, min
-	min = math.floor((turn % self.DAY) / self.MINUTE)
-	hour = math.floor(min / 60)
-	min = math.floor(min % 60)
-	return hour, min
-end
-
-function _M:getMonthNum(dayofyear)
-	local i = #self.calendar
-
-	-- Find the period name
-	while ((i > 1) and (dayofyear < self.calendar[i].days)) do
-		i = i - 1
-	end
-
-	return i
-end
-
-function _M:getMonthName(dayofyear)
-	local month = self:getMonthNum(dayofyear)
-	return self.calendar[month].name
-end
-
-function _M:getDayOfMonth(dayofyear)
-	local month = self:getMonthNum(dayofyear)
-	return dayofyear - self.calendar[month].days + 1 + self.calendar[month].offset
-end
-
-function _M:getMonthLength(dayofyear)
-	local month = self:getMonthNum(dayofyear)
-	return self.calendar[month].length
-end
diff --git a/game/engine/Chat.lua b/game/engine/Chat.lua
deleted file mode 100644
index 243a744d529b90e9e3a02a6727dae2197198f166..0000000000000000000000000000000000000000
--- a/game/engine/Chat.lua
+++ /dev/null
@@ -1,69 +0,0 @@
--- 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"
-require "engine.dialogs.Chat"
-
---- Handle chats between the player and NPCs
-module(..., package.seeall, class.make)
-
-function _M:init(name, npc, player, data)
-	self.chats = {}
-	self.npc = npc
-	self.player = player
-	data = setmetatable(data or {}, {__index=_G})
-
-	local f, err = loadfile("/data/chats/"..name..".lua")
-	if not f and err then error(err) end
-	setfenv(f, setmetatable({
-		newChat = function(c) self:addChat(c) end,
-	}, {__index=data}))
-	self.default_id = f()
-end
-
---- Adds a chat to the list of possible chats
-function _M:addChat(c)
-	assert(c.id, "no chat id")
-	assert(c.text, "no chat text")
-	assert(c.answers, "no chat answers")
-	self.chats[c.id] = c
-	print("[CHAT] loaded", c.id, c)
-end
-
---- Invokes a chat
--- @param id the id of the first chat to run, if nil it will use the default one
-function _M:invoke(id)
-	if self.npc.onChat then self.npc:onChat() end
-	if self.player.onChat then self.player:onChat() end
-
-	local d = engine.dialogs.Chat.new(self, id or self.default_id)
-	game:registerDialog(d)
-end
-
---- Gets the chat with the given id
-function _M:get(id)
-	return self.chats[id]
-end
-
---- Replace some keywords in the given text
-function _M:replace(text)
-	text = text:gsub("@playername@", self.player.name):gsub("@npcname@", self.npc.name)
-	text = text:gsub("@playerdescriptor.(.-)@", function(what) return self.player.descriptor[what] end)
-	return text
-end
diff --git a/game/engine/DamageType.lua b/game/engine/DamageType.lua
deleted file mode 100644
index cbd9dbe73a544d2db143db45fc3f0059ae6af80a..0000000000000000000000000000000000000000
--- a/game/engine/DamageType.lua
+++ /dev/null
@@ -1,61 +0,0 @@
--- 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"
-
---- Handles actors stats
-module(..., package.seeall, class.make)
-
-_M.dam_def = {}
-
--- Default damage projector
-function _M.defaultProject(src, x, y, type, dam)
-	print("implement a projector!")
-end
-
---- Defines new damage type
--- Static!
-function _M:loadDefinition(file)
-	local f, err = loadfile(file)
-	if not f and err then error(err) end
-	setfenv(f, setmetatable({
-		DamageType = _M,
-		Map = require("engine.Map"),
-		setDefaultProjector = function(fct) self.defaultProjector = fct end,
-		newDamageType = function(t) self:newDamageType(t) end,
-	}, {__index=_G}))
-	f()
-end
-
---- Defines one ability type(group)
--- Static!
-function _M:newDamageType(t)
-	assert(t.name, "no ability type name")
-	assert(t.type, "no ability type type")
-	t.type = t.type:upper()
-	t.projector = t.projector or self.defaultProjector
-
-	table.insert(self.dam_def, t)
-	self[t.type] = #self.dam_def
-end
-
-function _M:get(id)
-	assert(_M.dam_def[id], "damage type "..tostring(id).." used but undefined")
-	return _M.dam_def[id]
-end
diff --git a/game/engine/DebugConsole.lua b/game/engine/DebugConsole.lua
deleted file mode 100644
index 2c915f247b6ed6c332f8ae5cc9778a5004eb0074..0000000000000000000000000000000000000000
--- a/game/engine/DebugConsole.lua
+++ /dev/null
@@ -1,116 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
--- Globals to all instances of the console
-offset = 0
-history = {}
-line = ""
-com_sel = 0
-commands = {}
-
-function _M:init()
-	engine.Dialog.init(self, "Lua Console", core.display.size())
-	self:keyCommands{
-		_RETURN = function()
-			table.insert(self.commands, self.line)
-			self.com_sel = #self.commands + 1
-			table.insert(self.history, self.line)
-			-- Handle assignment and simple printing
-			if self.line:match("^=") then self.line = "return "..self.line:sub(2) end
-			local f, err = loadstring(self.line)
-			if err then
-				table.insert(self.history, err)
-			else
-				local res = {pcall(f)}
-				for i, v in ipairs(res) do
-					if i > 1 then
-						table.insert(self.history, "    "..(i-1).." :=: "..tostring(v))
-						-- Handle printing a table
-						if type(v) == "table" then
-							for k, vv in pairs(v) do
-								table.insert(self.history, "        "..tostring(k).." :=: "..tostring(vv) )
-							end
-						end
-					end
-				end
-			end
-			self.line = ""
-			self.offset = 0
-			self.changed = true
-		end,
-		_UP = function()
-			self.com_sel = util.bound(self.com_sel - 1, 1, #self.commands)
-			if self.commands[self.com_sel] then
-				self.line = self.commands[self.com_sel]
-			end
-		end,
-		_DOWN = function()
-			self.com_sel = util.bound(self.com_sel + 1, 1, #self.commands)
-			if self.commands[self.com_sel] then
-				self.line = self.commands[self.com_sel]
-			end
-		end,
-		_ESCAPE = function()
-			game:unregisterDialog(self)
-		end,
-		_BACKSPACE = function()
-			self.line = self.line:sub(1, self.line:len() - 1)
-		end,
-		__TEXTINPUT = function(c)
-			self.line = self.line .. c
-			self.changed = true
-		end,
-	}
-	-- Scroll message log
-	game.mouse:registerZone(self.display_x, self.display_y, self.w, self.h, function(button)
-		if button == "wheelup" then self:scrollUp(1) end
-		if button == "wheeldown" then self:scrollUp(-1) end
-	end, {button=true})
-end
-
-function _M:drawDialog(s, w, h)
-	local buffer = (self.ih % self.font_h) / 2
-	local i, dh = #self.history - self.offset, self.ih - buffer - self.font:lineSkip()
-	-- Start at the bottom and work up
-	-- Draw the current command
-	s:drawStringBlended(self.font, self.line, 0, dh, 255, 255, 255)
-	dh = dh - self.font:lineSkip()
-	-- Now draw the history with any ofset
-	while dh > buffer do
-		if not self.history[i] then break end
-		s:drawStringBlended(self.font, self.history[i], 0, dh, 255, 255, 255)
-		i = i - 1
-		dh = dh - self.font:lineSkip()
-	end
-
-end
-
---- Scroll the zone
--- @param i number representing how many lines to scroll
-function _M:scrollUp(i)
-	self.offset = self.offset + i
-	if self.offset > #self.history - 1 then self.offset = #self.history - 1 end
-	if self.offset < 0 then self.offset = 0 end
-	self.changed = true
-end
\ No newline at end of file
diff --git a/game/engine/Dialog.lua b/game/engine/Dialog.lua
deleted file mode 100644
index f508fb95781b9d5c369744a14e137c35669a53b0..0000000000000000000000000000000000000000
--- a/game/engine/Dialog.lua
+++ /dev/null
@@ -1,353 +0,0 @@
--- 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"
-require "engine.Tiles"
-require "engine.KeyBind"
-
---- Handles dialog windows
-module(..., package.seeall, class.make)
-
-tiles = engine.Tiles.new(16, 16)
-
---- Requests a simple, press any key, dialog
-function _M:simplePopup(title, text, fct, no_leave)
-	local font = core.display.newFont("/data/font/Vera.ttf", 12)
-	local w, h = font:size(text)
-	local tw, th = font:size(title)
-	local d = new(title, math.max(w, tw) + 8, h + 25, nil, nil, nil, font)
-	if no_leave then
-		d:keyCommands{}
-	else
-		d:keyCommands{__DEFAULT=function() game:unregisterDialog(d) if fct then fct() end end}
-		d:mouseZones{{x=0, y=0, w=game.w, h=game.h, fct=function(b) if b ~= "none" then game:unregisterDialog(d) if fct then fct() end end end, norestrict=true}}
-	end
-	d.drawDialog = function(self, s)
-		s:drawColorStringCentered(self.font, text, 2, 2, self.iw - 2, self.ih - 2)
-	end
-	game:registerDialog(d)
-	return d
-end
-
---- Requests a simple, press any key, dialog
-function _M:simpleLongPopup(title, text, w, fct, no_leave)
-	local font = core.display.newFont("/data/font/Vera.ttf", 12)
-	local list = text:splitLines(w - 10, font)
-
-	local th = font:lineSkip()
-	local d = new(title, w + 8, th * #list + 35, nil, nil, nil, font)
-	if no_leave then
-		d:keyCommands{}
-	else
-		d:keyCommands{__DEFAULT=function() game:unregisterDialog(d) if fct then fct() end end}
-		d:mouseZones{{x=0, y=0, w=game.w, h=game.h, fct=function(b) if b ~= "none" then game:unregisterDialog(d) if fct then fct() end end end, norestrict=true}}
-	end
-	d.drawDialog = function(self, s)
-		local h = 4
-		local r, g, b
-		for i = 1, #list do
-			r, g, b = s:drawColorStringBlended(self.font, list[i], 5, h, r, g, b) h = h + th
-		end
-	end
-	game:registerDialog(d)
-	return d
-end
-
---- Requests a simple yes-no dialog
-function _M:yesnoPopup(title, text, fct, yes_text, no_text)
-	local font = core.display.newFont("/data/font/Vera.ttf", 12)
-	local w, h = font:size(text)
-	local tw, th = font:size(title)
-	local d = new(title, math.max(w, tw) + 8, h + 75, nil, nil, nil, font)
-	d.sel = 0
-	d:keyCommands({},
-	{
-		ACCEPT = function() game:unregisterDialog(d) if fct then fct(d.sel == 0) end end,
-		MOVE_LEFT = "MOVE_UP",
-		MOVE_RIGHT = "MOVE_DOWN",
-		MOVE_UP = function() d.sel = 0 d.changed = true end,
-		MOVE_DOWN = function() d.sel = 1 d.changed = true end,
-	})
-	d:mouseZones{{x=2, y=0, w=d.iw, h=d.ih, fct=function(b, _, _, _, _, x, y)
-		d.sel = (x < d.iw / 2) and 0 or 1
-		d.changed = true
-		if b ~= "none" then game:unregisterDialog(d) if fct then fct(d.sel == 0) end end
-	end}}
-	d.drawDialog = function(self, s)
-		s:drawColorStringCentered(self.font, text, 2, 2, self.iw - 2, 25 - 2)
-		if d.sel == 0 then
-			s:drawColorStringCentered(self.font, yes_text or "Yes", 2, 25, self.iw / 2 - 2, 50 - 2, 0, 255, 255)
-			s:drawColorStringCentered(self.font, no_text or "No", 2 + self.iw / 2, 25, self.iw / 2 - 2, 50 - 2, 255, 255, 255)
-		else
-			s:drawColorStringCentered(self.font, yes_text or "Yes", 2, 25, self.iw / 2 - 2, 50 - 2, 255, 255, 255)
-			s:drawColorStringCentered(self.font, no_text or "No", 2 + self.iw / 2, 25, self.iw / 2 - 2, 50 - 2, 0, 255, 255)
-		end
-	end
-	game:registerDialog(d)
-	return d
-end
-
---- Requests a long yes-no dialog
-function _M:yesnoLongPopup(title, text, w, fct, yes_text, no_text)
-	local font = core.display.newFont("/data/font/Vera.ttf", 12)
-	local list = text:splitLines(w - 10, font)
-
-	local th = font:lineSkip()
-	local d = new(title, w + 8, th * #list + 75, nil, nil, nil, font)
-	d.sel = 0
-	d:keyCommands({},
-	{
-		ACCEPT = function() game:unregisterDialog(d) if fct then fct(d.sel == 0) end end,
-		MOVE_LEFT = "MOVE_UP",
-		MOVE_RIGHT = "MOVE_DOWN",
-		MOVE_UP = function() d.sel = 0 d.changed = true end,
-		MOVE_DOWN = function() d.sel = 1 d.changed = true end,
-	})
-	d:mouseZones{{x=2, y=0, w=d.iw, h=d.ih, fct=function(b, _, _, _, _, x, y)
-		d.sel = (x < d.iw / 2) and 0 or 1
-		d.changed = true
-		if b ~= "none" then game:unregisterDialog(d) if fct then fct(d.sel == 0) end end
-	end}}
-	d.drawDialog = function(self, s)
-		local h = 4
-		local r, g, b
-		for i = 1, #list do
-			r, g, b = s:drawColorStringBlended(self.font, list[i], 5, h, r, g, b) h = h + th
-		end
-
-		if d.sel == 0 then
-			s:drawColorStringCentered(self.font, yes_text or "Yes", 2, 10 + h, self.iw / 2 - 2, 50 - 2, 0, 255, 255)
-			s:drawColorStringCentered(self.font, no_text or "No", 2 + self.iw / 2, 10 + h, self.iw / 2 - 2, 50 - 2, 255, 255, 255)
-		else
-			s:drawColorStringCentered(self.font, yes_text or "Yes", 2, 10 + h, self.iw / 2 - 2, 50 - 2, 255, 255, 255)
-			s:drawColorStringCentered(self.font, no_text or "No", 2 + self.iw / 2, 10 + h, self.iw / 2 - 2, 50 - 2, 0, 255, 255)
-		end
-		self.changed = false
-	end
-	game:registerDialog(d)
-	return d
-end
-
---- Create a Dialog
-function _M:init(title, w, h, x, y, alpha, font, showup)
-	self.title = title
-	self.controls = { }
-	self.tabindex = 0
-	self.state = ""
-	self.currenttabindex = 0
-	self.font = font
-	if not font then self.font = core.display.newFont("/data/font/Vera.ttf", 12) end
-	self.font_h = self.font:lineSkip()
-
-	self:resize(w, h, x, y, alpha)
-	if showup ~= nil then
-		self.__showup = showup
-	else
-		self.__showup = 2
-	end
-end
-
-function _M:resize(w, h, x, y, alpha)
-	self.w, self.h = math.floor(w), math.floor(h)
-	self.display_x = math.floor(x or (game.w - self.w) / 2)
-	self.display_y = math.floor(y or (game.h - self.h) / 2)
-	self.surface = core.display.newSurface(w, h)
-	self.iw, self.ih = w - 2 * 5, h - 8 - 16 - 3
-	self.internal_surface = core.display.newSurface(self.iw, self.ih)
-	self.surface:alpha(alpha or 220)
-	self.texture, self.texture_w, self.texture_h = self.surface:glTexture()
-	self.changed = true
-end
-
-function _M:display()
-	if not self.changed then return self.surface end
-
-	local s = self.surface
-	self.alpha = self.alpha or 200
-	s:erase(0,0,0,self.alpha)
-
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_7.png"), 0, 0)
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_9.png"), self.w - 8, 0)
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_1.png"), 0, self.h - 8)
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_3.png"), self.w - 8, self.h - 8)
-	for i = 8, self.w - 9 do
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_8.png"), i, 0)
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_8.png"), i, 20)
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_8.png"), i, self.h - 3)
-	end
-	for i = 8, self.h - 9 do
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_4.png"), 0, i)
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_4.png"), self.w - 3, i)
-	end
-
-	local tw, th = self.font:size(self.title)
-	s:drawColorStringBlended(self.font, self.title, (self.w - tw) / 2, 4, 255,255,255)
-
-	self.internal_surface:erase()
-	self:drawDialog(self.internal_surface)
-	s:merge(self.internal_surface, 5, 20 + 3)
-
-	-- Update texture
-	self.surface:updateTexture(self.texture)
-
-	return self.surface
-end
-
-function _M:toScreen(x, y)
-	-- Draw with only the texture
-	if self.__showup then
-		local zoom = self.__showup / 7
-		self.texture:toScreenFull(x + (self.w - self.w * zoom) / 2, y + (self.h - self.h * zoom) / 2, self.w * zoom, self.h * zoom, self.texture_w * zoom, self.texture_h * zoom)
-		self.__showup = self.__showup + 1
-		if self.__showup >= 7 then self.__showup = nil end
-	else
-		self.texture:toScreenFull(x, y, self.w, self.h, self.texture_w, self.texture_h)
-	end
-end
-
-function _M:addControl(control)
-	control.tabindex = self.tabindex
-	self.tabindex = self.tabindex + 1
-	self.controls[control.name] = control
-	table.sort(self.controls, function(a,b) return a.tabindex<b.tabindex end)
-end
-
-function _M:changeFocus(up)
-	local add = 1
-	if not up then add = -1 end
-	self.currenttabindex = self.currenttabindex + add
-	if (self.currenttabindex==self.tabindex) then self.currenttabindex = 0 end
-	if self.currenttabindex==-1 then self.currenttabindex=self.tabindex-1 end
-	local name = ""
-	for i, cntrl in pairs(self.controls) do
-		if cntrl.tabindex==self.currenttabindex then
-			if self.controls[self.state] and self.controls[self.state].unFocus then self.controls[self.state]:unFocus() end
-			cntrl.focused=true
-			name=i
-		end
-	end
-	return name
-end
-
-function _M:focusControl(focusOn)
-	if focusOn==self.state then return end
-	local oldstate = self.state
-	for i, cntrl in pairs(self.controls) do
-		if i==focusOn then cntrl.focused=true self.state=i self.currenttabindex=cntrl.tabindex end
-		if i==oldstate and cntrl.unFocus then cntrl:unFocus() end
-	end
-end
-
-
-function _M:databind()
-	local result = { }
-	for i, cntrl in pairs(self.controls or { }) do
-	    if cntrl.type and cntrl.type=="TextBox" then
-			result[cntrl.name] = cntrl.text
-		end
-	end
-	return result
-end
-
-
-function _M:drawControls(s)
-	for i, cntrl in pairs(self.controls or { }) do
-	    cntrl:drawControl(s)
-	end
-end
-
-function _M:drawDialog(s)
-end
-
-function _M:keyCommands(t, b)
-	self.key = engine.KeyBind.new()
-	if t then self.key:addCommands(t) end
-	if b then self.key:addBinds(b) end
-end
-
-function _M:mouseZones(t)
-	-- Offset the x and y with the window position and window title
-	if not t.norestrict then
-		for i, z in ipairs(t) do
-			z.x = z.x + self.display_x + 5
-			z.y = z.y + self.display_y + 20 + 3
-		end
-	end
-
-	self.mouse = engine.Mouse.new()
-	self.mouse:registerZones(t)
-end
-
-function _M:unload()
---[[
-	if self.old_key then
-		game.key = self.old_key
-		game.key:setCurrent()
-	end
-	if self.old_mouse then
-		game.mouse = self.old_mouse
-		game.mouse:setCurrent()
-	end
-]]
-end
-
-function _M:drawWBorder(s, x, y, w)
-	for i = x, x + w do
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_8.png"), i, y)
-	end
-end
-function _M:drawHBorder(s, x, y, h)
-	for i = y, y + h do
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_4.png"), x, i)
-	end
-end
-
-function _M:drawSelectionList(s, x, y, hskip, list, sel, prop, scroll, max, color, selcolor, max_size)
-	selcolor = selcolor or {0,255,255}
-	color = color or {255,255,255}
-	max = max or 99999
-	scroll = util.bound(scroll or 1, 1, #list)
-
-	for i = scroll, math.min(#list, scroll + max - 1) do
-		local v = list[i]
-		local vc = nil
-		if v then
-			if type(v) == "table" then vc = v.color end
-			if prop and type(v[prop]) == "string" then v = tostring(v[prop])
-			elseif prop and type(v[prop]) == "function" then v = tostring(v[prop](v))
-			else v = tostring(v) end
-
-			local lines
-			if max_size then lines = v:splitLines(max_size, self.font)
-			else lines = {v} end
-			for j = 1, #lines do
-				if sel == i then
-					local sx, sy = self.font:size(lines[j])
---					s:erase(selcolor[1]/3, selcolor[2]/3, selcolor[3]/3, 1, x, y, sx, sy)
-					s:drawColorStringBlended(self.font, lines[j], x, y, selcolor[1], selcolor[2], selcolor[3])
-				else
-					local r, g, b = color[1], color[2], color[3]
-					if vc then r, g, b = vc[1], vc[2], vc[3] end
-					s:drawColorStringBlended(self.font, lines[j], x, y, r, g, b)
-				end
-				y = y + hskip
-			end
-		end
-	end
-end
diff --git a/game/engine/DirectPath.lua b/game/engine/DirectPath.lua
deleted file mode 100644
index c5ec8cdd18bb3b5c75442f5b97256da9db0f74e6..0000000000000000000000000000000000000000
--- a/game/engine/DirectPath.lua
+++ /dev/null
@@ -1,52 +0,0 @@
--- 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"
-
---- Computes a direct line path from start to end
-module(..., package.seeall, class.make)
-
---- Initializes DirectPath for a map and an actor
-function _M:init(map, actor)
-	self.map = map
-	self.actor = actor
-end
-
---- Compute path from sx/sy to tx/ty
--- @param sx the start coord
--- @param sy the start coord
--- @param tx the end coord
--- @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)
-	local path = {}
-	local l = line.new(sx, sy, tx, ty)
-	local nx, ny = l()
-	while nx and ny do
-		if (not use_has_seen or self.map.has_seens(nx, ny)) and self.map:isBound(nx, ny) and not self.map:checkEntity(nx, ny, Map.TERRAIN, "block_move", self.actor, nil, true) then
-			path[#path+1] = {x=nx, y=ny}
-		else
-			break
-		end
-		nx, ny = l()
-	end
-	return path
-end
diff --git a/game/engine/Emote.lua b/game/engine/Emote.lua
deleted file mode 100644
index 34fd22d690378e5f656084f44906027dbdb4da5f..0000000000000000000000000000000000000000
--- a/game/engine/Emote.lua
+++ /dev/null
@@ -1,74 +0,0 @@
--- 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"
-require "engine.Tiles"
-
-module(..., package.seeall, class.make)
-
-local font = core.display.newFont(fontname or "/data/font/VeraBd.ttf", 16)
-local tiles = engine.Tiles.new(16, 16)
-
-function _M:init(text, dur, color)
-	local w, h = font:size(text)
-	w = w + 10
-	h = h + 15
-	self.dur = dur or 30
-	self.color = color or {r=0, g=0, b=0}
-	self.text = text
-	self.w = w
-	self.h = h
-	self:loaded()
-end
-
---- Serialization
-function _M:save()
-	return class.save(self, {
-		surface = true,
-	})
-end
-
-function _M:loaded()
-	local s = core.display.newSurface(self.w, self.h)
-	if not s then return end
-	s:erase(0, 0, 0, 255)
-
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "emote/7.png"), 0, 0)
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "emote/9.png"), self.w - 6, 0)
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "emote/1.png"), 0, self.h - 10)
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "emote/3.png"), self.w - 6, self.h - 10)
-	for i = 6, self.w - 6 do
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "emote/8.png"), i, 0)
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "emote/2.png"), i, self.h - 10)
-	end
-	for i = 6, self.h - 10 do
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "emote/4.png"), 0, i)
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "emote/6.png"), self.w - 6, i)
-	end
-	s:erase(255, 255, 255, 255, 6, 6, self.w - 6 - 6, self.h - 10 - 6)
-	s:erase(0, 0, 0, 0, 6, self.h - 4, self.w - 6, 4)
-
-	s:drawStringBlended(font, self.text, 5, 5, self.color.r, self.color.g, self.color.b)
-	self.surface = s
-end
-
-function _M:update()
-	self.dur = self.dur - 1
-	if self.dur < 0 then return true end
-end
diff --git a/game/engine/Entity.lua b/game/engine/Entity.lua
deleted file mode 100644
index b627c54fb1aaf6c36c709ddf673805f3dac26a6c..0000000000000000000000000000000000000000
--- a/game/engine/Entity.lua
+++ /dev/null
@@ -1,408 +0,0 @@
--- 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
-
---- A game entity
--- An entity is anything that goes on a map, terrain features, objects, monsters, player, ...
--- Usually there is no need to use it directly, and it is betetr to use specific engine.Grid, engine.Actor or engine.Object
--- classes. Most modules will want to subclass those anyway to add new comportments
-local Shader = require "engine.Shader"
-
-module(..., package.seeall, class.make)
-
-local next_uid = 1
-local entities_load_functions = {}
-
-_M.__mo_repo = {}
-_M.__mo_final_repo = {}
-_M._no_save_fields = {}
-
--- Setup the uids & MO repository as a weak value table, when the entities are no more used anywhere else they disappear from there too
-setmetatable(__uids, {__mode="v"})
-setmetatable(_M.__mo_repo, {__mode="v"})
-setmetatable(_M.__mo_final_repo, {__mode="k"})
-
---- Invalidates the whole MO repository
-function _M:invalidateAllMO()
-	for i, mo in ipairs(_M.__mo_repo) do
-		mo:invalidate()
-	end
-	_M.__mo_repo = {}
-	setmetatable(_M.__mo_repo, {__mode="v"})
-	setmetatable(_M.__mo_final_repo, {__mode="k"})
-end
-
-local function copy_recurs(dst, src, deep)
-	for k, e in pairs(src) do
-		if type(e) == "table" and e.__CLASSNAME then
-			dst[k] = e
-		elseif not dst[k] then
-			if deep then
-				dst[k] = {}
-				copy_recurs(dst[k], e, deep)
-			else
-				dst[k] = e
-			end
-		elseif type(dst[k]) == "table" and type(e) == "table" and not e.__CLASSNAME then
-			copy_recurs(dst[k], e, deep)
-		end
-	end
-end
-
---- Initialize an entity
--- Any subclass MUST call this constructor
--- @param t a table defining the basic properties of the entity
--- @usage Entity.new{display='#', color_r=255, color_g=255, color_b=255}
-function _M:init(t, no_default)
-	t = t or {}
-	self.uid = next_uid
-	__uids[self.uid] = self
-
-	for k, e in pairs(t) do
-		if k ~= "__CLASSNAME" then
-			local ee = e
-			if type(e) == "table" and not e.__CLASSNAME then ee = table.clone(e, true) end
-			self[k] = ee
-		end
-	end
-
-	if self.color then
-		self.color_r = self.color.r
-		self.color_g = self.color.g
-		self.color_b = self.color.b
-		self.color = nil
-	end
-	if self.back_color then
-		self.color_br = self.back_color.r
-		self.color_bg = self.back_color.g
-		self.color_bb = self.back_color.b
-		self.back_color = nil
-	end
-	if self.tint then
-		self.tint_r = self.tint.r / 255
-		self.tint_g = self.tint.g / 255
-		self.tint_b = self.tint.b / 255
-		self.tint = nil
-	end
-
-	if not no_default then
-		self.image = self.image or nil
-		self.display = self.display or '.'
-		self.color_r = self.color_r or 0
-		self.color_g = self.color_g or 0
-		self.color_b = self.color_b or 0
-		self.color_br = self.color_br or -1
-		self.color_bg = self.color_bg or -1
-		self.color_bb = self.color_bb or -1
-		self.tint_r = self.tint_r or 1
-		self.tint_g = self.tint_g or 1
-		self.tint_b = self.tint_b or 1
-	end
-
-	if self.unique and type(self.unique) ~= "string" then self.unique = self.name end
-
-	next_uid = next_uid + 1
-
-	self.changed = true
-	self.__particles = self.__particles or {}
-end
-
---- If we are cloned we need a new uid
-function _M:cloned()
-	self.uid = next_uid
-	__uids[self.uid] = self
-	next_uid = next_uid + 1
-
-	self.changed = true
-end
-
-_M.__autoload = {}
-_M.loadNoDelay = true
---- If we are loaded we need a new uid
-function _M:loaded()
-	local ouid = self.uid
-	self.uid = next_uid
-	__uids[self.uid] = self
-	next_uid = next_uid + 1
-
-	self.changed = true
-
-	-- hackish :/
-	if self.autoLoadedAI then self:autoLoadedAI() end
-end
-
---- Change the entity's uid
--- <strong>*WARNING*</strong>: ONLY DO THIS IF YOU KNOW WHAT YOU ARE DOING!. YOU DO NOT !
-function _M:changeUid(newuid)
-	__uids[self.uid] = nil
-	self.uid = newuid
-	__uids[self.uid] = self
-end
-
---- Create the "map object" representing this entity
--- Do not touch unless you *KNOW* what you are doing.<br/>
--- You do *NOT* need this, this is used by the engine.Map class automatically.<br/>
--- *DO NOT TOUCH!!!*
-function _M:makeMapObject(tiles, idx)
-	if idx > 1 and not tiles.use_images then return nil end
-	if idx > 1 then
-		if not self.add_displays or not self.add_displays[idx-1] then return nil end
-		return self.add_displays[idx-1]:makeMapObject(tiles, 1)
-	else
-		if self._mo and self._mo:isValid() then return self._mo, self.z end
-	end
-
-	-- Create the map object with 1 + additional textures
-	self._mo = core.map.newObject(
-		1 + (tiles.use_images and self.textures and #self.textures or 0),
-		self:check("display_on_seen"),
-		self:check("display_on_remember"),
-		self:check("display_on_unknown"),
-		self:check("display_x") or 0,
-		self:check("display_y") or 0,
-		self:check("display_scale") or 1
-	)
-	_M.__mo_repo[#_M.__mo_repo+1] = self._mo
-
-	-- Setup tint
-	self._mo:tint(self.tint_r, self.tint_g, self.tint_b)
-
-	-- Texture 0 is always the normal image/ascii tile
-	self._mo:texture(0, tiles:get(self.display, self.color_r, self.color_g, self.color_b, self.color_br, self.color_bg, self.color_bb, self.image, self._noalpha and 255, self.ascii_outline))
-
-	-- Setup additional textures
-	if tiles.use_images and self.textures then
-		for i = 1, #self.textures do
-			local t = self.textures[i]
-			if type(t) == "function" then local tex, is3d = t(self, tiles); if tex then self._mo:texture(i, tex, is3d) tiles.texture_store[tex] = true end
-			elseif type(t) == "table" then
-				if t[1] == "image" then local tex = tiles:get('', 0, 0, 0, 0, 0, 0, t[2]); self._mo:texture(i, tex, false) tiles.texture_store[tex] = true
-				end
-			end
-		end
-	end
-
-	-- Setup shader
-	if tiles.use_images and core.shader.active() and self.shader then
-		local shad = Shader.new(self.shader, self.shader_args)
-		if shad.shad then self._mo:shader(shad.shad) end
-	end
-
-	return self._mo, self.z
-end
-
---- Get all "map objects" representing this entity
--- Do not touch unless you *KNOW* what you are doing.<br/>
--- You do *NOT* need this, this is used by the engine.Map class automatically.<br/>
--- *DO NOT TOUCH!!!*
-function _M:getMapObjects(tiles, mos, z)
-	local i = -1
-	local mo, dz
-	repeat
-		i = i + 1
-		mo, dz = self:makeMapObject(tiles, 1+i)
-		if mo then
-			mos[dz or z+i] = mo
-		end
-	until not mo
-end
-
---- Get the entity image as an sdl surface and texture for the given tiles and size
--- @param tiles a Tiles instance that will handle the tiles (usualy pass it the current Map.tiles)
--- @param w the width
--- @param h the height
--- @return the sdl surface and the texture
-function _M:getEntityFinalSurface(tiles, w, h)
-	local id = w.."x"..h
-	if _M.__mo_final_repo[self] and _M.__mo_final_repo[self][id] then return _M.__mo_final_repo[self][id].surface, _M.__mo_final_repo[self][id].tex end
-
-	local Map = require "engine.Map"
-
-	local mos = {}
-	local list = {}
-	self:getMapObjects(tiles, mos, 1)
-	for i = 1, Map.zdepth do
-		if mos[i] then list[#list+1] = mos[i] end
-	end
-	local tex = core.map.mapObjectsToTexture(w, h, unpack(list))
-	_M.__mo_final_repo[self] = _M.__mo_final_repo[self] or {}
-	_M.__mo_final_repo[self][id] = {surface=tex:toSurface(), tex=tex}
-	return _M.__mo_final_repo[self][id].surface, _M.__mo_final_repo[self][id].tex
-end
-
---- Get a string that will display in text the texture of this entity
-function _M:getDisplayString()
-	if core.display.FBOActive() then
-		return "#UID:"..self.uid..":0#"
-	else
-		return ""
-	end
-end
-
---- Resolves an entity
--- This is called when generatingthe final clones of an entity for use in a level.<br/>
--- This can be used to make random enchants on objects, random properties on actors, ...<br/>
--- by default this only looks for properties with a table value containing a __resolver field
-function _M:resolve(t, last, on_entity)
-	t = t or self
-	for k, e in pairs(t) do
-		if type(e) == "table" and e.__resolver and (not e.__resolve_last or last) then
-			t[k] = resolvers.calc[e.__resolver](e, on_entity or self, self)
-		elseif type(e) == "table" and not e.__CLASSNAME then
-			self:resolve(e, last, on_entity)
-		end
-	end
-
-	-- Finish resolving stuff
-	if on_entity then return end
-	if t == self then
-		if last then
-			if self.resolveLevel then self:resolveLevel() end
-
-			if self.unique and type(self.unique) == "boolean" then
-				self.unique = self.name
-			end
-		else
-			-- Handle ided if possible
-			if self.resolveIdentify then self:resolveIdentify() end
-		end
-	end
-end
-
---- Call when the entity is actually added to a level/whatever
--- This helps ensuring uniqueness of uniques
-function _M:added()
-	if self.unique then
-		game.uniques[self.__CLASSNAME.."/"..self.unique] = true
-		print("Added unique", self.__CLASSNAME.."/"..self.unique)
-	end
-end
-
---- Call when the entity is actually removed from existance
--- This helps ensuring uniqueness of uniques.
--- This recursively remvoes inventories too, if you need anythign special, overload this
-function _M:removed()
-	if self.inven then
-		for _, inven in pairs(self.inven) do
-			for i, o in ipairs(inven) do
-				o:removed()
-			end
-		end
-	end
-
-	if self.unique then
-		game.uniques[self.__CLASSNAME.."/"..self.unique] = nil
-		print("Removed unique", self.__CLASSNAME.."/"..self.unique)
-	end
-end
-
---- Check for an entity's property
--- If not a function it returns it directly, otherwise it calls the function
--- with the extra parameters
--- @param prop the property name to check
-function _M:check(prop, ...)
-	if type(self[prop]) == "function" then return self[prop](self, ...)
-	else return self[prop]
-	end
-end
-
---- Loads a list of entities from a definition file
--- @param file the file to load from
--- @param no_default if true then no default values will be assigned
--- @param res the table to load into, defaults to a new one
--- @param mod an optional function to which will be passed each entity as they are created. Can be used to adjust some values on the fly
--- @usage MyEntityClass:loadList("/data/my_entities_def.lua")
-function _M:loadList(file, no_default, res, mod, loaded)
-	if type(file) == "table" then
-		res = res or {}
-		for i, f in ipairs(file) do
-			self:loadList(f, no_default, res, mod)
-		end
-		return res
-	end
-
-	no_default = no_default and true or false
-	res = res or {}
-
-	local f, err = nil, nil
-	if entities_load_functions[file] and entities_load_functions[file][no_default] then
-		print("Loading entities file from memory", file)
-		f = entities_load_functions[file][no_default]
-	elseif fs.exists(file) then
-		f, err = loadfile(file)
-		print("Loading entities file from file", file)
-		entities_load_functions[file] = entities_load_functions[file] or {}
-		entities_load_functions[file][no_default] = f
-	else
-		-- No data
-		f = function() end
-	end
-	if err then error(err) end
-
-	loaded = loaded or {}
-	loaded[file] = true
-
-	setfenv(f, setmetatable({
-		class = self,
-		loaded = loaded,
-		resolvers = resolvers,
-		DamageType = require "engine.DamageType",
-		entity_mod = mod,
-		rarity = function(add, mult) add = add or 0; mult = mult or 1; return function(e) if e.rarity then e.rarity = math.ceil(e.rarity * mult + add) end end end,
-		newEntity = function(t)
-			-- Do we inherit things ?
-			if t.base then
-				-- Append array part
-				for i = 1, #res[t.base] do
-					local b = res[t.base][i]
-					if type(b) == "table" and not b.__CLASSNAME then b = table.clone(b, true)
-					elseif type(b) == "table" and b.__CLASSNAME then b = b:clone()
-					end
-					table.insert(t, b)
-				end
-
-				for k, e in pairs(res[t.base]) do
-					if k ~= "define_as" and type(k) ~= "number" then
-						if type(t[k]) == "table" and type(e) == "table" then
-							copy_recurs(t[k], e)
-						elseif not t[k] and type(t[k]) ~= "boolean" then
-							t[k] = e
-						end
-					end
-				end
-				t.base = nil
-			end
-
-			local e = self.new(t, no_default)
-
-			if mod then mod(e) end
-
-			res[#res+1] = e
-			if t.define_as then res[t.define_as] = e end
-		end,
-		load = function(f, new_mod)
-			self:loadList(f, no_default, res, new_mod or mod, loaded)
-		end,
-		loadList = function(f, new_mod)
-			return self:loadList(f, no_default, nil, new_mod or mod, loaded)
-		end,
-	}, {__index=_G}))
-	f()
-
-	return res
-end
diff --git a/game/engine/Faction.lua b/game/engine/Faction.lua
deleted file mode 100644
index df64df8aecbe36a2cf05f5b2cf94425b4001cbf7..0000000000000000000000000000000000000000
--- a/game/engine/Faction.lua
+++ /dev/null
@@ -1,110 +0,0 @@
--- 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"
-
---- Defines factions
-module(..., package.seeall, class.make)
-
-_M.factions = {}
-
---- Adds a new faction.
--- Static method, and can be called during load.lua.
--- @param t the table describing the faction.
--- @param t.name the name of the added faction, REQUIRED.
--- @param t.short_name the internally referenced name, defaults to lowercase t.name with "-" for spaces.
--- @param t.reaction table of initial reactions to other factions, where keys are short_names.
--- @return t.short_name see above.
-function _M:add(t)
-	assert(t.name, "no faction name")
-	t.short_name = t.short_name or t.name:lower():gsub(" ", "-")
-	if self.factions[t.short_name] then print("[FACTION] tried to redefine", t.name) return t.short_name end
-
-	local r = {}
-	t.reaction = t.reaction or {}
-	for n, v in pairs(t.reaction) do
-		n = n:lower():gsub(" ", "-")
-		r[n] = v
-	end
-	t.reaction = r
-	self.factions[t.short_name] = t
-	return t.short_name
-end
-
---- Sets the initial reaction.
--- Static method, and can be called during load.lua.
--- @param f1 the source faction short_name.
--- @param f2 the target faction short_name.
--- @param reaction a numerical value representing the reaction, 0 is neutral, <0 is aggressive, >0 is friendly.
--- @param mutual if true the same status will be set for f2 toward f1.
-function _M:setInitialReaction(f1, f2, reaction, mutual)
-	print("[FACTION] initial", f1, f2, reaction, mutual)
-	-- Faction always like itself
-	if f1 == f2 then return end
-	if not self.factions[f1] then return end
-	if not self.factions[f2] then return end
-	self.factions[f1].reaction[f2] = reaction
-	if mutual then
-		self.factions[f2].reaction[f1] = reaction
-	end
-end
-
---- Returns the faction definition
-function _M:get(id)
-	return self.factions[id]
-end
-
---- Returns the status of faction f1 toward f2
--- @param f1 the source faction short_name.
--- @param f2 the target faction short_name.
--- @return reaction a numerical value representing the reaction, 0 is neutral, <0 is aggressive, >0 is friendly.
-function _M:factionReaction(f1, f2)
-	-- Faction always like itself
-	if f1 == f2 then return 100 end
-	if game.factions and game.factions[f1] and game.factions[f1][f2] then return game.factions[f1][f2] end
-	if not self.factions[f1] then return 0 end
-	return self.factions[f1].reaction[f2] or 0
-end
-
---- Sets the status of faction f1 toward f2.
--- This should only be used after the game has loaded (not in load.lua).
--- These changes will be saved to the savefile.
--- @param f1 the source faction short_name.
--- @param f2 the target faction short_name.
--- @param reaction a numerical value representing the reaction, 0 is neutral, <0 is aggressive, >0 is friendly.
--- @param mutual if true the same status will be set for f2 toward f1.
-function _M:setFactionReaction(f1, f2, reaction, mutual)
-	reaction = util.bound(reaction, -100, 100)
-	print("[FACTION]", f1, f2, reaction, mutual)
-	-- Faction always like itself
-	if f1 == f2 then return end
-	if not self.factions[f1] then return end
-	if not self.factions[f2] then return end
-	game.factions = game.factions or {}
-	game.factions[f1] = game.factions[f1] or {}
-	game.factions[f1][f2] = reaction
-	if mutual then
-		game.factions[f2] = game.factions[f2] or {}
-		game.factions[f2][f1] = reaction
-	end
-end
-
--- Add a few default factions
-_M:add{ name="Players", reaction={enemies=-100} }
-_M:add{ name="Enemies", reaction={players=-100} }
diff --git a/game/engine/FlyingText.lua b/game/engine/FlyingText.lua
deleted file mode 100644
index 853e0fb024812d2c9f2310a2dba33bee0f2b3524..0000000000000000000000000000000000000000
--- a/game/engine/FlyingText.lua
+++ /dev/null
@@ -1,72 +0,0 @@
--- 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"
-
-module(..., package.seeall, class.make)
-
-function _M:init(fontname, fontsize)
-	self.font = core.display.newFont(fontname or "/data/font/Vera.ttf", fontsize or 12)
-	self.bigfont = core.display.newFont(fontname or "/data/font/VeraBd.ttf", fontsize or 18)
-	self.font_h = self.font:lineSkip()
-	self.flyers = {}
-end
-
-function _M:add(x, y, duration, xvel, yvel, str, color, bigfont)
-	assert(x, "no x flyer")
-	assert(y, "no y flyer")
-	assert(str, "no str flyer")
-	color = color or {255,255,255}
-	local s = core.display.drawStringBlendedNewSurface(bigfont and self.bigfont or self.font, str, color[1], color[2], color[3])
-	if not s then return end
-	local f = {
-		x=x,
-		y=y,
-		duration=duration or 10,
-		xvel = xvel or 0,
-		yvel = yvel or 0,
-		s = s
-	}
-	self.flyers[f] = true
-	return f
-end
-
-function _M:empty()
-	self.flyers = {}
-end
-
-function _M:display()
-	if not next(self.flyers) then return end
-
-	local dels = {}
-
-	for fl, _ in pairs(self.flyers) do
-		fl.s:toScreen(fl.x, fl.y)
-		fl.x = fl.x + fl.xvel
-		fl.y = fl.y + fl.yvel
-		fl.duration = fl.duration - 1
-
-		-- Delete the flyer
-		if fl.duration == 0 then
-			dels[#dels+1] = fl
-		end
-	end
-
-	for i, fl in ipairs(dels) do self.flyers[fl] = nil end
-end
diff --git a/game/engine/Game.lua b/game/engine/Game.lua
deleted file mode 100644
index 18b0bc25780e67fc90d111c67d59bfd89a626a4a..0000000000000000000000000000000000000000
--- a/game/engine/Game.lua
+++ /dev/null
@@ -1,238 +0,0 @@
--- 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"
-require "engine.Mouse"
-require "engine.DebugConsole"
-
---- Represent a game
--- A module should subclass it and initialize anything it needs to play inside
-module(..., package.seeall, class.make)
-
---- Constructor
--- Sets up the default keyhandler.
--- Also requests the display size and stores it in "w" and "h" properties
-function _M:init(keyhandler)
-	self.key = keyhandler
-	self.level = nil
-	self.log = function() end
-	self.logSeen = function() end
-	self.w, self.h = core.display.size()
-	self.dialogs = {}
-	self.save_name = "player"
-	self.player_name = "player"
-
-	self.mouse = engine.Mouse.new()
-	self.mouse:setCurrent()
-
-	self.uniques = {}
-
-	self.__threads = {}
-end
-
-function _M:loaded()
-	self.w, self.h = core.display.size()
-	self.dialogs = {}
-	self.key = engine.Key.current
-	self.mouse = engine.Mouse.new()
-	self.mouse:setCurrent()
-
-	self.__threads = self.__threads or {}
-end
-
---- Defines the default fields to be saved by the savefile code
-function _M:defaultSavedFields(t)
-	local def = {
-		w=true, h=true, zone=true, player=true, level=true, entities=true,
-		energy_to_act=true, energy_per_tick=true, turn=true, paused=true, save_name=true,
-		always_target=true, gfxmode=true, uniques=true, object_known_types=true,
-		current_music=true, memory_levels=true, achievement_data=true, factions=true,
-	}
-	table.merge(def, t)
-	return def
-end
-
---- Sets the player name
-function _M:setPlayerName(name)
-	self.save_name = name
-	self.player_name = name
-end
-
---- Starts the game
--- Modules should reimplement it to do whatever their game needs
-function _M:run()
-end
-
---- Sets the current level
--- @param level an engine.Level (or subclass) object
-function _M:setLevel(level)
-	self.level = level
-end
-
---- Tells the game engine to play this game
-function _M:setCurrent()
-	core.game.set_current_game(self)
-	_M.current = self
-end
-
---- Displays the screen
--- Called by the engine core to redraw the screen every frame
-function _M:display()
-	for i, d in ipairs(self.dialogs) do
-		d:display()
-		d:toScreen(d.display_x, d.display_y)
-	end
-
-	if self.flyers then
-		self.flyers:display()
-	end
-end
-
---- Returns the player
--- Reimplement it in your module, this can just return nil if you dont want/need
--- the engine adjusting stuff to the player or if you have many players or whatever
-function _M:getPlayer()
-	return nil
-end
-
---- This is the "main game loop", do something here
-function _M:tick()
-end
-
---- Called when a zone leaves a level
--- Going from "old_lev" to "lev", leaving level "level"
-function _M:leaveLevel(level, lev, old_lev)
-end
-
---- Called by the engine when the user tries to close the window
-function _M:onQuit()
-end
-
---- Sets up a text flyers
-function _M:setFlyingText(fl)
-	self.flyers = fl
-end
-
---- Registers a dialog to display
-function _M:registerDialog(d)
-	table.insert(self.dialogs, d)
-	self.dialogs[d] = #self.dialogs
-	if d.key then d.key:setCurrent() end
-	if d.mouse then d.mouse:setCurrent() end
-	if d.on_register then d:on_register() end
-end
-
---- Undisplay a dialog, removing its own keyhandler if needed
-function _M:unregisterDialog(d)
-	if not self.dialogs[d] then return end
-	table.remove(self.dialogs, self.dialogs[d])
-	self.dialogs[d] = nil
-	d:unload()
-	-- Update positions
-	for i, id in ipairs(self.dialogs) do self.dialogs[id] = i end
-
-	local last = self.dialogs[#self.dialogs] or self
-	if last.key then last.key:setCurrent() end
-	if last.mouse then last.mouse:setCurrent() end
-	if last.on_recover_focus then last:on_recover_focus() end
-end
-
---- The C core gives us command line arguments
-function _M:commandLineArgs(args)
-	for i, a in ipairs(args) do
-		print("Command line: ", a)
-	end
-end
-
---- Called by savefile code to describe the current game
-function _M:getSaveDescription()
-	return {
-		name = "player",
-		description = [[Busy adventuring!]],
-	}
-end
-
---- Save a settings file
-function _M:saveSettings(file, data)
-	local restore = fs.getWritePath()
-	fs.setWritePath(engine.homepath)
-	local f = fs.open("/settings/"..file..".cfg", "w")
-	f:write(data)
-	f:close()
-	if restore then fs.setWritePath(restore) end
-end
-
-available_resolutions =
-{
-	["800x600"] = {800, 600, false},
-	["1024x768"] = {1024, 768, false},
-	["1200x1024"] = {1200, 1024, false},
-	["1600x1200"] = {1600, 1200, false},
-	["800x600 Fullscreen"] = {800, 600, true},
-	["1024x768 Fullscreen"] = {1024, 768, true},
-	["1200x1024 Fullscreen"] = {1200, 1024, true},
-	["1600x1200 Fullscreen"] = {1600, 1200, true},
-}
---- Change screen resolution
-function _M:setResolution(res)
-	if not available_resolutions[res] then return false, "unknown resolution" end
-
-	local old_w, old_h = self.w, self.h
-	core.display.setWindowSize(available_resolutions[res][1], available_resolutions[res][2], available_resolutions[res][3])
-	self.w, self.h = core.display.size()
-
-	if self.w ~= old_w or self.h ~= old_h then
-		self:onResolutionChange()
-
-		self:saveSettings("resolution", ("window.size = %q\n"):format(res))
-	end
-end
-
---- Called when screen resolution changes
-function _M:onResolutionChange()
-	self.w, self.h = core.display.size()
-end
-
---- Requests the game to save
-function _M:saveGame()
-end
-
---- Save a thread into the thread pool
--- Threads will be auto join'ed when the module exits or when it can<br/>
--- ALL THREADS registered *MUST* return true when they exit
-function _M:registerThread(th, linda)
-	print("[THREAD] registering", th, linda, #self.__threads+1)
-	self.__threads[#self.__threads+1] = {th=th, linda=linda}
-	return #self.__threads
-end
-
---- Try to join all registered threads
--- @param timeout the time in seconds to wait for each thread
-function _M:joinThreads(timeout)
-	for i = #self.__threads, 1, -1 do
-		local th = self.__threads[i].th
-		print("[THREAD] Thread join", i, th)
-		local v, err = th:join(timeout)
-		if err then print("[THREAD] error", th) error(err) end
-		if v then
-			print("[THREAD] Thread result", i, th, "=>", v)
-			table.remove(self.__threads, i)
-		end
-	end
-end
diff --git a/game/engine/GameEnergyBased.lua b/game/engine/GameEnergyBased.lua
deleted file mode 100644
index ce6d2622e4073f74c27d97cc3ef5cc46b139e52c..0000000000000000000000000000000000000000
--- a/game/engine/GameEnergyBased.lua
+++ /dev/null
@@ -1,109 +0,0 @@
--- 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"
-require "engine.Game"
-
---- A game type that gives each entities energy
--- When an entity reaches an energy level it is allowed to act (it calls the entity"s "act" method)
--- @inherit engine.Game
-module(..., package.seeall, class.inherit(engine.Game))
-
---- Setup the game
--- @param keyhandler the default keyhandler for this game
--- @energy_to_act how much energy does an entity need to act
--- @energy_per_tick how much energy does an entity recieves per game tick. This is multiplied by the entity energy.mod property
-function _M:init(keyhandler, energy_to_act, energy_per_tick)
-	self.energy_to_act, self.energy_per_tick = energy_to_act or 1000, energy_per_tick or 100
-	engine.Game.init(self, keyhandler)
-
-	self.entities = {}
-	self:loaded()
-end
-
-function _M:loaded()
-	engine.Game.loaded(self)
-
-	-- Loading the game has defined new uids for entities, yet we hard referenced the old ones
-	-- So we fix it
-	local nes = {}
-	for uid, e in pairs(self.entities) do
-		nes[e.uid] = e
-	end
-	self.entities = nes
-
-	-- Setup the entities repository as a weak value table, when the entities are no more used anywhere else they disappear from there too
-	setmetatable(self.entities, {__mode="v"})
-end
-
---- Gives energy and act if needed
-function _M:tick()
-	engine.Game.tick(self)
-
-	-- Give some energy to entities
-	if self.level then
-		local i, e
-		local arr = self.level.e_array
-		for i = 1, #arr do
-			e = arr[i]
-			if e and e.act and e.energy then
---				print("<ENERGY", e.name, e.uid, "::", e.energy.value, game.paused, "::", e.player)
-				if e.energy.value < self.energy_to_act then
-					e.energy.value = (e.energy.value or 0) + self.energy_per_tick * (e.energy.mod or 1)
-				end
-				if e.energy.value >= self.energy_to_act then
-					e.energy.used = false
-					e:act(self)
-				end
---				print(">ENERGY", e.name, e.uid, "::", e.energy.value, game.paused, "::", e.player)
-			end
-		end
-	end
-
-	local arr = self.entities
-	for i, e in pairs(arr) do
-		e = arr[i]
-		if e and e.act and e.energy then
-			if e.energy.value < self.energy_to_act then
-				e.energy.value = (e.energy.value or 0) + self.energy_per_tick * (e.energy.mod or 1)
-			end
-			if e.energy.value >= self.energy_to_act then
-				e.energy.used = false
-				e:act(self)
-			end
-		end
-	end
-end
-
---- Adds an entity to the game
--- This differs from Level:addEntity in that it's not specific to actors and the entities are not bound to
--- the current level. Also they are stored in a *WEAK* table, so this wont hold them from garbage
--- collecting if they are not
-function _M:addEntity(e)
-	if not e.canAct or not e:canAct() then return end
-	if self.entities[e.uid] and self.entities[e.uid] ~= e then error("Entity "..e.uid.." already present in the game and not the same") end
-	self.entities[e.uid] = e
-end
-
---- Removes an entity from the game
-function _M:removeEntity(e)
-	if not e.canAct or not e:canAct() then return end
-	if not self.entities[e.uid] then error("Entity "..e.uid.." not present in the game") end
-	self.entities[e.uid] = nil
-end
diff --git a/game/engine/GameTurnBased.lua b/game/engine/GameTurnBased.lua
deleted file mode 100644
index 27c30e187e5404e49a974d709eb191aa99bd3afd..0000000000000000000000000000000000000000
--- a/game/engine/GameTurnBased.lua
+++ /dev/null
@@ -1,59 +0,0 @@
--- 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"
-require "engine.GameEnergyBased"
-
---- Defines a turn based game
--- If this class is not used the game is realtime.
--- This game type pauses the ticking as long as its paused property is true.<br/>
--- To use it make your player "act" method set the game property paused to true and when an action is made to false
--- @inherit engine.GameEnergyBased
-module(..., package.seeall, class.inherit(engine.GameEnergyBased))
-
---- See engine.GameEnergyBased
-function _M:init(keyhandler, energy_to_act, energy_per_tick)
-	self.turn = 0
-	self.paused = false
-	engine.GameEnergyBased.init(self, keyhandler, energy_to_act, energy_per_tick)
-end
-
-function _M:tick()
-	if self.paused then
-		-- Auto unpause if the player has no energy to act
-		if game:getPlayer() and not game:getPlayer():enoughEnergy() then game.paused = false end
-
-		-- If we are paused do not get energy, but still process frames if needed
-		engine.Game.tick(self)
-	else
-		engine.GameEnergyBased.tick(self)
-		self.turn = self.turn + 1
-		self:onTurn()
-
-		-- Try to join threads if any, every hundred turns
-		if self.turn % 100 == 0 then
-			self:joinThreads(0)
-		end
-	end
-end
-
---- Called every game turns
--- Does nothing, you can override it
-function _M:onTurn()
-end
diff --git a/game/engine/Generator.lua b/game/engine/Generator.lua
deleted file mode 100644
index 6a862afa33128e1ed6b3e5a49850af391870d009..0000000000000000000000000000000000000000
--- a/game/engine/Generator.lua
+++ /dev/null
@@ -1,62 +0,0 @@
--- 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"
-module(..., package.seeall, class.make)
-
-function _M:init(zone, map, level, spots)
-	self.zone = zone
-	self.map = map
-	self.level = level
-	self.spots = spots
-
-	-- Setup the map's room-map
-	if not map.room_map then
-		map.room_map = {}
-		for i = 0, map.w - 1 do
-			map.room_map[i] = {}
-			for j = 0, map.h - 1 do
-				map.room_map[i][j] = {}
-			end
-		end
-	end
-end
-
-function _M:generate()
-end
-
-function _M:resolve(c, list, force)
-	local res = force and c or self.data[c]
-	if type(res) == "function" then
-		res = res()
-	elseif type(res) == "table" then
-		res = res[rng.range(1, #res)]
-	else
-		res = res
-	end
-	if not res then return end
-	res = (list or self.grid_list)[res]
-	if not res then return end
-	if res.force_clone then
-		res = res:clone()
-	end
-	res:resolve()
-	res:resolve(nil, true)
-	return res
-end
diff --git a/game/engine/Grid.lua b/game/engine/Grid.lua
deleted file mode 100644
index a9478cc7a9e151e7d661960fd5ee6bbaa41012a5..0000000000000000000000000000000000000000
--- a/game/engine/Grid.lua
+++ /dev/null
@@ -1,36 +0,0 @@
--- 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 Entity = require "engine.Entity"
-
-module(..., package.seeall, class.inherit(Entity))
-
--- When used on the map, do not draw alpha channel
-_M._noalpha = true
-
-_M.display_on_seen = true
-_M.display_on_remember = true
-_M.display_on_unknown = false
-
-function _M:init(t, no_default)
-	t = t or {}
-	self.name = t.name
-	Entity.init(self, t, no_default)
-end
diff --git a/game/engine/Heightmap.lua b/game/engine/Heightmap.lua
deleted file mode 100644
index 9bff0d1f1df955c3a5510fe497ad11789d89e608..0000000000000000000000000000000000000000
--- a/game/engine/Heightmap.lua
+++ /dev/null
@@ -1,108 +0,0 @@
--- 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"
-
---- Heightmap fractal generator
--- This can be used to create rooms, levels, world maps, whatever
-module(..., package.seeall, class.make)
-
-_M.max = 100000
-_M.min = 0
-
---- Creates the fractal generator for the specified heightmap size
-function _M:init(w, h, roughness, start)
-	self.w = w
-	self.h = h
-	self.roughness = roughness or 1.2
-	self.hmap = {}
-	self.start = start or {}
-
-	print("Making heightmap", w, h)
-
-	-- Init the hmap to 0
-	for i = 1, w do
-		self.hmap[i] = {}
-		for j = 1, h do
-			self.hmap[i][j] = 0
-		end
-	end
-end
-
---- Actually creates the heightmap
-function _M:generate()
-	local rects = {}
-
-	-- Init the four corners
-	self.hmap[1][1]           = self.start.up_left or rng.range(self.min, self.max)
-	self.hmap[1][self.h]      = self.start.down_left or rng.range(self.min, self.max)
-	self.hmap[self.w][1]      = self.start.up_right or rng.range(self.min, self.max)
-	self.hmap[self.w][self.h] = self.start.down_right or rng.range(self.min, self.max)
-	rects[#rects+1] = {1, 1, self.w, self.h, force_middle=self.start.middle}
-
-	-- While we have subzones to handle, handle them
-	while #rects > 0 do
-		local r = table.remove(rects, 1)
-
---		print("Doing rect", r[1], r[2], "::", r[3], r[3])
-
-		local w = r[3] - r[1]
-		local h = r[4] - r[2]
-		if w > 1 or h > 1 then
-			local nw = math.floor(w / 2)
-			local nh = math.floor(h / 2)
-
-			-- Compute "displacement" random value
-			local d = (w + h) / (self.w + self.h) * self.roughness
-			d = (rng.range(0, self.max) - self.max / 2) * d
-
-			-- Compute middles
-			self.hmap[r[1] + nw][r[2]] = (self.hmap[r[1]][r[2]] + self.hmap[r[3]][r[2]]) / 2
-			self.hmap[r[1] + nw][r[4]] = (self.hmap[r[1]][r[4]] + self.hmap[r[3]][r[4]]) / 2
-			self.hmap[r[1]][r[2] + nh] = (self.hmap[r[1]][r[2]] + self.hmap[r[1]][r[4]]) / 2
-			self.hmap[r[3]][r[2] + nh] = (self.hmap[r[3]][r[2]] + self.hmap[r[3]][r[4]]) / 2
-			if r.force_middle then
-				self.hmap[r[1] + nw][r[2] + nh] = r.force_middle
-			else
-				self.hmap[r[1] + nw][r[2] + nh] = (self.hmap[r[1]][r[2]] + self.hmap[r[1]][r[4]] + self.hmap[r[3]][r[2]] + self.hmap[r[3]][r[4]]) / 4 + d
-			end
-
-			-- Assign new rects
-			if nw > 1 or nh > 1 then rects[#rects+1] = {r[1], r[2], r[1] + nw, r[2] + nh} end
-			if r[3] - r[1] - nw > 1 or nh > 1 then rects[#rects+1] = {r[1] + nw, r[2], r[3], r[2] + nh} end
-			if nw > 1 or r[4] - r[2] - nh > 1 then rects[#rects+1] = {r[1], r[2] + nh, r[1] + nw, r[4]} end
-			if r[3] - r[1] - nw > 1 or r[4] - r[2] - nh > 1 then rects[#rects+1] = {r[1] + nw, r[2] + nh, r[3], r[4]} end
-		end
-	end
-
-	return self.hmap
-end
-
-function _M:displayDebug(symbs)
-	symbs = symbs or "abcdefghijklmnopqrstwxyzABCDEFGHIJKLMNOPQRSTWXYZ"
-	print("Dispalying heightmap", self.w, self.h)
-	for j = 1, self.h do
-		local str = ""
-		for i = 1, self.w do
-			local c = util.bound((math.floor(self.hmap[i][j] / self.max * symbs:len()) + 1), 1, symbs:len())
-			str = str..symbs:sub(c, c)
-		end
-		print(str)
-	end
-end
diff --git a/game/engine/HotkeysDisplay.lua b/game/engine/HotkeysDisplay.lua
deleted file mode 100644
index 9f03802852f34af42adc6ae96319ea5f19541c66..0000000000000000000000000000000000000000
--- a/game/engine/HotkeysDisplay.lua
+++ /dev/null
@@ -1,132 +0,0 @@
--- 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"
-
-module(..., package.seeall, class.make)
-
-function _M:init(actor, x, y, w, h, bgcolor)
-	self.actor = actor
-	self.bgcolor = bgcolor
-	self.font = core.display.newFont("/data/font/VeraMono.ttf", 10)
-	self.font_h = self.font:lineSkip()
-	self.clics = {}
-	self:resize(x, y, w, h)
-end
-
---- Resize the display area
-function _M:resize(x, y, w, h)
-	self.display_x, self.display_y = math.floor(x), math.floor(y)
-	self.w, self.h = math.floor(w), math.floor(h)
-	self.surface = core.display.newSurface(w, h)
-	if self.actor then self.actor.changed = true end
-
-	local cw, ch = self.font:size(" ")
-	self.font_w = cw
-	self.max_char_w = math.min(127, math.floor(w / self.font_w))
-end
-
-local page_to_hotkey = {"", "SECOND_", "THIRD_"}
-
--- Displays the hotkeys, keybinds & cooldowns
-function _M:display()
-	local a = self.actor
-	if not a or not a.changed then return self.surface end
-
-	local hks = {}
-	for i = 1, 12 do
-		local j = i + (12 * (a.hotkey_page - 1))
-		local ks = game.key:formatKeyString(game.key:findBoundKeys("HOTKEY_"..page_to_hotkey[a.hotkey_page]..i))
-		if a.hotkey[j] and a.hotkey[j][1] == "talent" then
-			hks[#hks+1] = {a.hotkey[j][2], j, "talent", ks}
-		elseif a.hotkey[j] and a.hotkey[j][1] == "inventory" then
-			hks[#hks+1] = {a.hotkey[j][2], j, "inventory", ks}
-		end
-	end
-
-	self.surface:erase(self.bgcolor[1], self.bgcolor[2], self.bgcolor[3])
-
-	local x = 0
-	local y = 0
-	self.clics = {}
-
-	for ii, ts in ipairs(hks) do
-		local s
-		local i = ts[2]
-		local txt, color = "", {0,255,0}
-		if ts[3] == "talent" then
-			local tid = ts[1]
-			local t = a:getTalentFromId(tid)
-			if a:isTalentCoolingDown(t) then
-				txt = ("%s (%d)"):format(t.name, a:isTalentCoolingDown(t))
-				color = {255,0,0}
-			elseif a:isTalentActive(t.id) then
-				txt = t.name
-				color = {255,255,0}
-			else
-				txt = t.name
-				color = {0,255,0}
-			end
-		elseif ts[3] == "inventory" then
-			local o = a:findInAllInventories(ts[1])
-			local cnt = 0
-			if o then cnt = o:getNumber() end
-			txt = ("%s (%d)"):format(ts[1], cnt)
-			if cnt == 0 then
-				color = {128,128,128}
-			end
-		end
-
-		txt = ("%2d) %-"..(self.max_char_w-4-24).."s Key: %s"):format(i, txt, ts[4])
-		local w, h = self.font:size(txt)
-		if self.cur_sel and self.cur_sel == i then self.surface:erase(0, 50, 120, nil, x, y, w+4, h+4) end
-		self.surface:drawStringBlended(self.font, txt, x+2, y+2, color[1], color[2], color[3])
-		self.clics[i] = {x,y,w+4,h+4}
-
-		if y + self.font_h * 2 > self.h then
-			x = x + self.w / 2
-			y = 0
-		else
-			y = y + self.font_h
-		end
-	end
-
-	return self.surface
-end
-
---- Call when a mouse event arrives in this zone
--- This is optional, only if you need mouse support
-function _M:onMouse(button, mx, my, click)
-	mx, my = mx - self.display_x, my - self.display_y
-	for i, zone in pairs(self.clics) do
-		if mx >= zone[1] and mx < zone[1] + zone[3] and my >= zone[2] and my < zone[2] + zone[4] then
-			if button == "left" and click then
-				self.actor:activateHotkey(i)
-			elseif button == "right" and click then
-				self.actor.hotkey[i] = nil
-				self.actor.changed = true
-			else
-				self.actor.changed = true
-				self.cur_sel = i
-			end
-			return
-		end
-	end
-	self.cur_sel = nil
-end
diff --git a/game/engine/Key.lua b/game/engine/Key.lua
deleted file mode 100644
index 09f6b21f33885ee50aea669cb2d4601900fb6a47..0000000000000000000000000000000000000000
--- a/game/engine/Key.lua
+++ /dev/null
@@ -1,312 +0,0 @@
--- 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"
-
---- Basic keypress handler
--- The engine calls receiveKey when a key is pressed
-module(..., package.seeall, class.make)
-
-function _M:init()
-	self.status = {}
-end
-
---- Called when a key is pressed
--- @param sym a number representing the key, see all the _FOO fields
--- @param ctrl is the control key pressed?
--- @param shift is the shit key pressed?
--- @param alt is the alt key pressed?
--- @param meta is the meta key pressed?
--- @param unicode the unicode representation of the key, if possible
--- @param isup true if the key was released, false if pressed
-function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup)
-	print(sym, ctrl, shift, alt, meta, unicode, isup)
-	self:handleStatus(sym, ctrl, shift, alt, meta, unicode, isup)
-end
-
---- Maintain the self.status table, which can be used to know if a key is currently pressed
-function _M:handleStatus(sym, ctrl, shift, alt, meta, unicode, isup)
-	self.status[sym] = not isup
-end
-
---- Setups as the current game keyhandler
-function _M:setCurrent()
-	core.key.set_current_handler(self)
---	if game then game.key = self end
-	_M.current = self
-end
-
-_UNKNOWN		= 0
-_FIRST		= 0
-_BACKSPACE		= 8
-_TAB		= 9
-_CLEAR		= 12
-_RETURN		= 13
-_PAUSE		= 19
-_ESCAPE		= 27
-_SPACE		= 32
-_EXCLAIM		= 33
-_QUOTEDBL		= 34
-_HASH		= 35
-_DOLLAR		= 36
-_AMPERSAND		= 38
-_QUOTE		= 39
-_LEFTPAREN		= 40
-_RIGHTPAREN		= 41
-_ASTERISK		= 42
-_PLUS		= 43
-_COMMA		= 44
-_MINUS		= 45
-_PERIOD		= 46
-_SLASH		= 47
-_0			= 48
-_1			= 49
-_2			= 50
-_3			= 51
-_4			= 52
-_5			= 53
-_6			= 54
-_7			= 55
-_8			= 56
-_9			= 57
-_COLON		= 58
-_SEMICOLON		= 59
-_LESS		= 60
-_EQUALS		= 61
-_GREATER		= 62
-_QUESTION		= 63
-_AT			= 64
-
-_LEFTBRACKET	= 91
-_BACKSLASH		= 92
-_RIGHTBRACKET	= 93
-_CARET		= 94
-_UNDERSCORE		= 95
-_BACKQUOTE		= 96
-_a			= 97
-_b			= 98
-_c			= 99
-_d			= 100
-_e			= 101
-_f			= 102
-_g			= 103
-_h			= 104
-_i			= 105
-_j			= 106
-_k			= 107
-_l			= 108
-_m			= 109
-_n			= 110
-_o			= 111
-_p			= 112
-_q			= 113
-_r			= 114
-_s			= 115
-_t			= 116
-_u			= 117
-_v			= 118
-_w			= 119
-_x			= 120
-_y			= 121
-_z			= 122
-_DELETE		= 127
--- End of ASCII mapped keysyms
-
--- International keyboard syms
-_WORLD_0		= 160		-- 0xA0
-_WORLD_1		= 161
-_WORLD_2		= 162
-_WORLD_3		= 163
-_WORLD_4		= 164
-_WORLD_5		= 165
-_WORLD_6		= 166
-_WORLD_7		= 167
-_WORLD_8		= 168
-_WORLD_9		= 169
-_WORLD_10		= 170
-_WORLD_11		= 171
-_WORLD_12		= 172
-_WORLD_13		= 173
-_WORLD_14		= 174
-_WORLD_15		= 175
-_WORLD_16		= 176
-_WORLD_17		= 177
-_WORLD_18		= 178
-_WORLD_19		= 179
-_WORLD_20		= 180
-_WORLD_21		= 181
-_WORLD_22		= 182
-_WORLD_23		= 183
-_WORLD_24		= 184
-_WORLD_25		= 185
-_WORLD_26		= 186
-_WORLD_27		= 187
-_WORLD_28		= 188
-_WORLD_29		= 189
-_WORLD_30		= 190
-_WORLD_31		= 191
-_WORLD_32		= 192
-_WORLD_33		= 193
-_WORLD_34		= 194
-_WORLD_35		= 195
-_WORLD_36		= 196
-_WORLD_37		= 197
-_WORLD_38		= 198
-_WORLD_39		= 199
-_WORLD_40		= 200
-_WORLD_41		= 201
-_WORLD_42		= 202
-_WORLD_43		= 203
-_WORLD_44		= 204
-_WORLD_45		= 205
-_WORLD_46		= 206
-_WORLD_47		= 207
-_WORLD_48		= 208
-_WORLD_49		= 209
-_WORLD_50		= 210
-_WORLD_51		= 211
-_WORLD_52		= 212
-_WORLD_53		= 213
-_WORLD_54		= 214
-_WORLD_55		= 215
-_WORLD_56		= 216
-_WORLD_57		= 217
-_WORLD_58		= 218
-_WORLD_59		= 219
-_WORLD_60		= 220
-_WORLD_61		= 221
-_WORLD_62		= 222
-_WORLD_63		= 223
-_WORLD_64		= 224
-_WORLD_65		= 225
-_WORLD_66		= 226
-_WORLD_67		= 227
-_WORLD_68		= 228
-_WORLD_69		= 229
-_WORLD_70		= 230
-_WORLD_71		= 231
-_WORLD_72		= 232
-_WORLD_73		= 233
-_WORLD_74		= 234
-_WORLD_75		= 235
-_WORLD_76		= 236
-_WORLD_77		= 237
-_WORLD_78		= 238
-_WORLD_79		= 239
-_WORLD_80		= 240
-_WORLD_81		= 241
-_WORLD_82		= 242
-_WORLD_83		= 243
-_WORLD_84		= 244
-_WORLD_85		= 245
-_WORLD_86		= 246
-_WORLD_87		= 247
-_WORLD_88		= 248
-_WORLD_89		= 249
-_WORLD_90		= 250
-_WORLD_91		= 251
-_WORLD_92		= 252
-_WORLD_93		= 253
-_WORLD_94		= 254
-_WORLD_95		= 255		-- 0xFF
-
--- Numeric keypad
-_KP0		= 256
-_KP1		= 257
-_KP2		= 258
-_KP3		= 259
-_KP4		= 260
-_KP5		= 261
-_KP6		= 262
-_KP7		= 263
-_KP8		= 264
-_KP9		= 265
-_KP_PERIOD		= 266
-_KP_DIVIDE		= 267
-_KP_MULTIPLY	= 268
-_KP_MINUS		= 269
-_KP_PLUS		= 270
-_KP_ENTER		= 271
-_KP_EQUALS		= 272
-
--- Arrows + Home/End pad
-_UP			= 273
-_DOWN		= 274
-_RIGHT		= 275
-_LEFT		= 276
-_INSERT		= 277
-_HOME		= 278
-_END		= 279
-_PAGEUP		= 280
-_PAGEDOWN		= 281
-
--- Function keys
-_F1			= 282
-_F2			= 283
-_F3			= 284
-_F4			= 285
-_F5			= 286
-_F6			= 287
-_F7			= 288
-_F8			= 289
-_F9			= 290
-_F10		= 291
-_F11		= 292
-_F12		= 293
-_F13		= 294
-_F14		= 295
-_F15		= 296
-
--- Key state modifier keys
-_NUMLOCK		= 300
-_CAPSLOCK		= 301
-_SCROLLOCK		= 302
-_RSHIFT		= 303
-_LSHIFT		= 304
-_RCTRL		= 305
-_LCTRL		= 306
-_RALT		= 307
-_LALT		= 308
-_RMETA		= 309
-_LMETA		= 310
-_LSUPER		= 311		-- Left "Windows" key
-_RSUPER		= 312		-- Right "Windows" key
-_MODE		= 313		-- "Alt Gr" key
-_COMPOSE		= 314		-- Multi-key compose key
-
--- Miscellaneous function keys
-_HELP		= 315
-_PRINT		= 316
-_SYSREQ		= 317
-_BREAK		= 318
-_MENU		= 319
-_POWER		= 320		-- Power Macintosh power key
-_EURO		= 321		-- Some european keyboards
-_UNDO		= 322		-- Atari keyboard has Undo
-
-__DEFAULT 	= -10000
-__TEXTINPUT 	= -10001
-
--- Reverse sym calc
-_M.sym_to_name = {}
-for k, e in pairs(_M) do
-	if type(k) == "string" and type(e) == "number" then
-		_M.sym_to_name[e] = k
-	end
-end
diff --git a/game/engine/KeyBind.lua b/game/engine/KeyBind.lua
deleted file mode 100644
index 09f6aac46afedb060ec9d1f9e8d2d35a970ed9e0..0000000000000000000000000000000000000000
--- a/game/engine/KeyBind.lua
+++ /dev/null
@@ -1,236 +0,0 @@
--- 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 "config"
-require "engine.class"
-require "engine.KeyCommand"
-
---- Handles key binds to "virtual" actions
-module(..., package.seeall, class.inherit(engine.KeyCommand))
-
-_M.binds_def = {}
-_M.binds_remap = {}
-_M.binds_loaded = {}
-_M.bind_order = 1
-
-function _M:defineAction(t)
-	assert(t.default, "no keybind default")
-	assert(t.name, "no keybind name")
-	t.desc = t.desc or t.name
-
-	t.order = _M.bind_order
-	_M.binds_def[t.type] = t
-	_M.bind_order = _M.bind_order + 1
-end
-
---- Loads a list of keybind definitions
--- Keybind definitions are in /data/keybinds/. Modules can define new ones.
--- @param a string representing the keybind, separated by commas. I.e: "move,hotkeys,actions,inventory"
-function _M:load(str)
-	local defs = str:split(",")
-	for i, def in ipairs(defs) do
-		if not _M.binds_loaded[def] then
-			local f, err = loadfile("/data/keybinds/"..def..".lua")
-			if not f and err then error(err) end
-			setfenv(f, setmetatable({
-				defineAction = function(t) self:defineAction(t) end
-			}, {__index=_G}))
-			f()
-
-			print("[KEYBINDER] Loaded keybinds: "..def)
-			_M.binds_loaded[def] = true
-		end
-	end
-end
-
---- Loads a keybinds remap
-function _M:loadRemap(file)
-	local f, err = loadfile(file)
-	if not f and err then error(err) end
-	local d = {}
-	setfenv(f, d)
-	f()
-
-	for virtual, keys in pairs(d) do
-		print("Remapping", virtual, keys)
-		_M.binds_remap[virtual] = keys
-	end
-end
-
---- Saves a keybinds remap
-function _M:saveRemap(file)
-	local restore = false
-	if not file then
-		restore = fs.getWritePath()
-		fs.setWritePath(engine.homepath)
-		file = "keybinds.cfg"
-	end
-
-	local f = fs.open(file, "w")
-
-	for virtual, keys in pairs(_M.binds_remap) do
-		if keys[1] and not keys[2] then
-			f:write(("%s = {%q,nil}\n"):format(virtual, keys[1]))
-		elseif not keys[1] and keys[2] then
-			f:write(("%s = {nil,%q}\n"):format(virtual, keys[2]))
-		elseif keys[1] and keys[2] then
-			f:write(("%s = {%q,%q}\n"):format(virtual, keys[1], keys[2]))
-		elseif not keys[1] and not keys[2] then
-			f:write(("%s = {nil,nil}\n"):format(virtual))
-		end
-	end
-
-	f:close()
-
-	if restore then
-		fs.setWritePath(restore)
-	end
-end
-
---- Returns the binding table for the given type
-function _M:getBindTable(type)
-	return _M.binds_remap[type.type] or type.default
-end
-
-function _M:init()
-	engine.KeyCommand.init(self)
-	self.virtuals = {}
-
-	self:bindKeys()
-end
-
---- Binds all virtuals to keys, either defaults or remapped ones
-function _M:bindKeys()
-	self.binds = {}
-	-- Bind defaults
-	for type, t in pairs(_M.binds_def) do
-		for i, ks in ipairs(_M.binds_remap[type] or t.default) do
-			self.binds[ks] = type
-		end
-	end
-end
-
-function _M:findBoundKeys(virtual)
-	local bs = {}
-	for ks, virt in pairs(self.binds) do
-		if virt == virtual then bs[#bs+1] = ks end
-	end
-	return unpack(bs)
-end
-
-function _M:makeKeyString(sym, ctrl, shift, alt, meta, unicode)
-	return ("sym:%s:%s:%s:%s:%s"):format(tostring(sym), tostring(ctrl), tostring(shift), tostring(alt), tostring(meta)), unicode and "uni:"..unicode
-end
-
-function _M:makeMouseString(button, ctrl, shift, alt, meta)
-	return ("mouse:%s:%s:%s:%s:%s"):format(tostring(button), tostring(ctrl), tostring(shift), tostring(alt), tostring(meta))
-end
-
-function _M:formatKeyString(ks)
-	if not ks then return "--" end
-
-	if ks:find("^uni:") then
-		return ks:sub(5)
-	elseif ks:find("^sym:") then
-		local i, j, sym, ctrl, shift, alt, meta = ks:find("^sym:([0-9]+):([a-z]+):([a-z]+):([a-z]+):([a-z]+)$")
-		if not i then return "--" end
-
-		ctrl = ctrl == "true" and true or false
-		shift = shift == "true" and true or false
-		alt = alt == "true" and true or false
-		meta = meta == "true" and true or false
-		sym = tonumber(sym) or sym
-		sym = _M.sym_to_name[sym] or sym
-		sym = sym:gsub("^_", "")
-
-		if ctrl then sym = "[ctrl]+"..sym end
-		if shift then sym = "[shift]+"..sym end
-		if alt then sym = "[alt]+"..sym end
-		if meta then sym = "[meta]+"..sym end
-
-		return sym
-	elseif ks:find("^mouse:") then
-		local i, j, sym, ctrl, shift, alt, meta = ks:find("^mouse:([a-zA-Z0-9]+):([a-z]+):([a-z]+):([a-z]+):([a-z]+)$")
-		if not i then return "--" end
-
-		ctrl = ctrl == "true" and true or false
-		shift = shift == "true" and true or false
-		alt = alt == "true" and true or false
-		meta = meta == "true" and true or false
-		sym = "mouse["..sym.."]"
-
-		if ctrl then sym = "[ctrl]+"..sym end
-		if shift then sym = "[shift]+"..sym end
-		if alt then sym = "[alt]+"..sym end
-		if meta then sym = "[meta]+"..sym end
-
-		return sym
-	end
-end
-
-function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup, ismouse)
-	self:handleStatus(sym, ctrl, shift, alt, meta, unicode, isup)
-
-	if self.any_key then self.any_key(sym, ctrl, shift, alt, meta, unicode, isup) end
-
-	local ks, us
-	if not ismouse then ks, us = self:makeKeyString(sym, ctrl, shift, alt, meta, unicode)
-	else ks = self:makeMouseString(sym, ctrl, shift, alt, meta) end
---	print("[BIND]", sym, ctrl, shift, alt, meta, unicode, " :=: ", ks, us, " ?=? ", self.binds[ks], us and self.binds[us])
-	if self.binds[ks] and self.virtuals[self.binds[ks]] then
-		if isup and not _M.binds_def[self.binds[ks]].updown then return end
-		self.virtuals[self.binds[ks]](sym, ctrl, shift, alt, meta, unicode, isup)
-		return
-	elseif us and self.binds[us] and self.virtuals[self.binds[us]] then
-		if isup and not _M.binds_def[self.binds[us]].updown then return end
-		self.virtuals[self.binds[us]](sym, ctrl, shift, alt, meta, unicode, isup)
-		return
-	end
-
-	if isup then return end
-
-	engine.KeyCommand.receiveKey(self, sym, ctrl, shift, alt, meta, unicode, isup)
-end
-
---- Adds a key/command combinaison
--- @param sym the key to handle
--- @param mods a table with the mod keys needed, i.e: {"ctrl", "alt"}
--- @param fct the function to call when the key is pressed
-function _M:addBind(virtual, fct)
-	self.virtuals[virtual] = fct
-end
-
---- Adds a key/command combinaison
--- @param sym the key to handle
--- @param mods a table with the mod keys needed, i.e: {"ctrl", "alt"}
--- @param fct the function to call when the key is pressed
-function _M:addBinds(t)
-	local later = {}
-	for virtual, fct in pairs(t) do
-		if type(fct) == "function" then
-		print("bind", virtual, fct)
-			self:addBind(virtual, fct)
-		else
-			later[virtual] = fct
-		end
-	end
-	for virtual, fct in pairs(later) do
-		self:addBind(virtual, self.virtuals[fct])
-	end
-end
diff --git a/game/engine/KeyCommand.lua b/game/engine/KeyCommand.lua
deleted file mode 100644
index 46847b219cdad8af2f2fe07fe020e3f9713a8bc1..0000000000000000000000000000000000000000
--- a/game/engine/KeyCommand.lua
+++ /dev/null
@@ -1,156 +0,0 @@
--- 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 "config"
-require "engine.class"
-require "engine.Key"
-
---- Receieves keypresses and acts upon them
-module(..., package.seeall, class.inherit(engine.Key))
-
-function _M:init()
-	engine.Key.init(self)
-	self.commands = {}
-	self.on_input = false
-	self.locale_convert = {}
-
-	-- Fullscreen toggle
-	self:addCommand(self._RETURN, {"alt"}, function() core.display.fullscreen() end)
-end
-
---- Adds the profiler keybind (ctrl, alt, chift, p)
-function _M:setupProfiler()
-	-- Profiler
-	self:addCommand(self._p, {"ctrl","alt","shift"}, function()
-		if not _G.profiling then
-			print("Starting profiler")
-			_G.profiling = true
-			profiler.start("profiler.log")
-		else
-			profiler.stop()
-			print("Stopped profiler")
-		end
-	end)
-end
-
-function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup)
-	self:handleStatus(sym, ctrl, shift, alt, meta, unicode, isup)
-
-	if isup then return end
-
-	-- Convert locale
-	sym = self.locale_convert[sym] or sym
-
-	if not self.commands[sym] and not self.commands[self.__DEFAULT] then
-		if self.on_input and unicode then self.on_input(unicode) end
-	elseif self.commands[sym] and (ctrl or shift or alt or meta) and not self.commands[sym].anymod then
-		local mods = {}
-		if alt then mods[#mods+1] = "alt" end
-		if ctrl then mods[#mods+1] = "ctrl" end
-		if meta then mods[#mods+1] = "meta" end
-		if shift then mods[#mods+1] = "shift" end
-		mods = table.concat(mods,',')
-		if self.commands[sym][mods] then
-			self.commands[sym][mods](sym, ctrl, shift, alt, meta, unicode)
-		end
-	elseif self.commands[sym] and self.commands[sym].plain then
-		self.commands[sym].plain(sym, ctrl, shift, alt, meta, unicode)
-	elseif self.commands[self.__DEFAULT] and self.commands[self.__DEFAULT].plain then
-		self.commands[self.__DEFAULT].plain(sym, ctrl, shift, alt, meta, unicode)
-	end
-
-	if self.atLast then self.atLast(sym, ctrl, shift, alt, meta, unicode) end
-end
-
---- Adds a key/command combinaison
--- @param sym the key to handle
--- @param mods a table with the mod keys needed, i.e: {"ctrl", "alt"}
--- @param fct the function to call when the key is pressed
-function _M:addCommand(sym, mods, fct, anymod)
-	if type(sym) == "string" then sym = self[sym] end
-	if not sym then return end
-
-	if sym == self.__TEXTINPUT then return self:setTextInput(mods) end
-
-	self.commands[sym] = self.commands[sym] or {}
-	if not fct then
-		self.commands[sym].plain = mods
-	else
-		table.sort(mods)
-		self.commands[sym][table.concat(mods,',')] = fct
-	end
-	if anymod then self.commands[sym].anymod = true end
-end
-
---- Adds many key/command at once
--- @usage self.key:addCommands{<br/>
---   _LEFT = function()<br/>
---     print("left")<br/>
---   end,<br/>
---   _RIGHT = function()<br/>
---     print("right")<br/>
---   end,<br/>
---   {{"x","ctrl"}] = function()<br/>
---     print("control+x")<br/>
---   end,<br/>
--- }
-
-function _M:addCommands(t)
-	local aliases = {}
-	for k, e in pairs(t) do
-		if type(e) == "function" then
-			if type(k) == "string" then
-				self:addCommand(k, e)
-			elseif type(k) == "table" then
-				local sym = table.remove(k, 1)
-				local anymod = false
-				if k[1] == "anymod" then k, e, anymod = e, nil, true end
-				self:addCommand(sym, k, e, anymod)
-			end
-		elseif e[1] == "alias" then
-			aliases[#aliases+1] = {k, e[2]}
-		end
-	end
-
-	for i, alias in ipairs(aliases) do
-		self:addCommands{[alias[1]] = self.commands[self[alias[2]]].plain}
-	end
-end
-
---- Receieves any unbound keys as UTF8 characters (if possible)
--- @param fct the function to call for each key, get a single parameter to pass the UTF8 string
-function _M:setTextInput(fct)
-	self.on_input = fct
-end
-
---- Loads a locale converter
--- WARNING: This only converts the "sym" key, *NOT* the unicode key
--- @param file the locale convertion file to load
-function _M:loadLocaleConvertion(file)
-	local f, err = loadfile(file)
-	if not f and err then error(err) end
-	setfenv(f, setmetatable({
-		locale = config.settings.keyboard.locale,
-	}, {__index=engine.Key}))
-	conv = f() or {}
-
-	for k, e in pairs(conv) do
-		self.locale_convert[k] = e
-	end
-end
diff --git a/game/engine/Level.lua b/game/engine/Level.lua
deleted file mode 100644
index bfcd51f2fe7032440ba5c87211f4b5d8516d9708..0000000000000000000000000000000000000000
--- a/game/engine/Level.lua
+++ /dev/null
@@ -1,160 +0,0 @@
--- 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"
-
---- Define a level
-module(..., package.seeall, class.make)
-
---- Initializes the level with a "level" and a map
-function _M:init(level, map)
-	self.level = level
-	self.map = map
-	self.e_array = {}
-	self.entities = {}
-	self.entities_list = {}
-end
-
---- Adds an entity to the level
--- Only entities that need to act need to be added. Terrain features do not need this usualy
-function _M:addEntity(e, after)
-	if self.entities[e.uid] then error("Entity "..e.uid.."("..e.name..") already present on the level") end
-	self.entities[e.uid] = e
-	if not after or not self:hasEntity(after) then
-	table.insert(self.e_array, e)
-	else
-		print("Adding entity", e.uid, "after", after.uid)
-		local pos = nil
-		for i = 1, #self.e_array do
-			if self.e_array[i] == after then
-				pos = i
-				break
-			end
-		end
-		table.insert(self.e_array, pos+1, e)
-	end
-	game:addEntity(e)
-end
-
---- Removes an entity from the level
-function _M:removeEntity(e)
-	if not self.entities[e.uid] then error("Entity "..e.uid.."("..e.name..") not present on the level") end
-	self.entities[e.uid] = nil
-	for i = 1, #self.e_array do
-		if self.e_array[i] == e then
-			table.remove(self.e_array, i)
-			break
-		end
-	end
-	game:removeEntity(e)
-	-- Tells it to delete itself if needed
-	if e.deleteFromMap then e:deleteFromMap(self.map) end
-end
-
---- Is the entity on the level?
-function _M:hasEntity(e)
-	return self.entities[e.uid]
-end
-
---- Serialization
-function _M:save()
-	return class.save(self, {
-	})
-end
-function _M:loaded()
-	-- Loading the game has defined new uids for entities, yet we hard referenced the old ones
-	-- So we fix it
-	local nes = {}
-	for uid, e in pairs(self.entities) do
-		nes[e.uid] = e
-	end
-	self.entities = nes
-end
-
---- Setup an entity list for the level, this allwos the Zone to pick objects/actors/...
-function _M:setEntitiesList(type, list)
-	self.entities_list[type] = list
-	print("Stored entities list", type, list)
-end
-
---- Gets an entity list for the level, this allows the Zone to pick objects/actors/...
-function _M:getEntitiesList(type)
-	return self.entities_list[type]
-end
-
---- Removed, so we remove all entities
-function _M:removed()
-	for i = 0, self.map.w - 1 do for j = 0, self.map.h - 1 do
-		local z = i + j * self.map.w
-		if self.map.map[z] then
-			for _, e in pairs(self.map.map[z]) do
-				e:removed()
-			end
-		end
-	end end
-end
-
---- Decay the level
--- Decaying means we look on the map for the given type of entities and if we are allowed to we delete them
--- @param what what Map feature to decay (ACTOR, OBJECT, ...)
--- @param check either a boolean or a function, if true the given entity will be decayed
--- @return the number of decayed entities and the total number of such entities remaining
-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 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)
-				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
-end
-
---- Pick a random spot matching the given filter
-function _M:pickSpot(filter)
-	local list = {}
-	for i, spot in ipairs(self.spots) do
-		if game.zone:checkFilter(spot, filter) then list[#list+1] = spot end
-	end
-	return rng.table(list)
-end
diff --git a/game/engine/LogDisplay.lua b/game/engine/LogDisplay.lua
deleted file mode 100644
index 8f4933311c04e95f1036eb1d880f66c0ff5a26d7..0000000000000000000000000000000000000000
--- a/game/engine/LogDisplay.lua
+++ /dev/null
@@ -1,109 +0,0 @@
--- 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"
-
---- Module that handles message history ina mouse wheel scrollable zone
-module(..., package.seeall, class.make)
-
---- Creates the log zone
-function _M:init(x, y, w, h, max, fontname, fontsize, color, bgcolor)
-	self.color = color or {255,255,255}
-	self.bgcolor = bgcolor or {0,0,0}
-	self.display_x, self.display_y = math.floor(x), math.floor(y)
-	self.w, self.h = math.floor(w), math.floor(h)
-	self.font = core.display.newFont(fontname or "/data/font/Vera.ttf", fontsize or 12)
-	self.font_h = self.font:lineSkip()
-	self.surface = core.display.newSurface(w, h)
-	self.log = {}
-	getmetatable(self).__call = _M.call
-	self.max = max or 4000
-	self.scroll = 0
-	self.changed = true
-end
-
---- Resize the display area
-function _M:resize(x, y, w, h)
-	self.display_x, self.display_y = math.floor(x), math.floor(y)
-	self.w, self.h = math.floor(w), math.floor(h)
-	self.surface = core.display.newSurface(w, h)
-	self.changed = true
-end
-
---- Appends text to the log
--- This method is set as the call methamethod too, this means it is usable like this:<br/>
--- log = LogDisplay.new(...)<br/>
--- log("foo %s", s)
-function _M:call(str, ...)
-	local lines = str:format(...):splitLines(self.w - 4, self.font)
-	for i = 1, #lines do
-		print("[LOG]", lines[i])
-		table.insert(self.log, 1, {lines[i], reset=(i==#lines)})
-	end
-	while #self.log > self.max do
-		table.remove(self.log)
-	end
-	self.changed = true
-end
-
---- Clear the log
-function _M:empty()
-	self.log = {}
-	self.changed = true
-end
-
---- Get Last Lines From Log
--- @param number number of lines to retrieve
-function _M:getLines(number)
-	local from = number
-	if from > #self.log then from = #self.log end
-	local lines = { }
-	for i = from, 1, -1 do
-		lines[#lines+1] = self.log[i][1]
-	end
-	return lines
-end
-
-function _M:display()
-	-- If nothing changed, return the same surface as before
-	if not self.changed then return self.surface end
-	self.changed = false
-
-	-- Erase and the display the map
-	self.surface:erase(self.bgcolor[1], self.bgcolor[2], self.bgcolor[3])
-	local i, dh = 1, 0
-	local r, g, b = self.color[1], self.color[2], self.color[3]
-	local buffer = (self.h % self.font_h) / 2
-	for i = math.floor(self.h / self.font_h), 1, -1 do
-		if self.log[self.scroll + i] then
-			r, g, b = self.surface:drawColorStringBlended(self.font, self.log[self.scroll + i][1], 0, self.h - buffer - (i) * self.font_h, r, g, b)
-			if self.log[self.scroll + i].reset then r, g, b = self.color[1], self.color[2], self.color[3] end
-		end
-	end
-	return self.surface
-end
-
---- Scroll the zone
--- @param i number representing how many lines to scroll
-function _M:scrollUp(i)
-	self.scroll = self.scroll + i
-	if self.scroll > #self.log - 1 then self.scroll = #self.log - 1 end
-	if self.scroll < 0 then self.scroll = 0 end
-	self.changed = true
-end
diff --git a/game/engine/LogFlasher.lua b/game/engine/LogFlasher.lua
deleted file mode 100644
index 90ee7cdaa8b77051cd8ba75302b2a4a021bb0b6e..0000000000000000000000000000000000000000
--- a/game/engine/LogFlasher.lua
+++ /dev/null
@@ -1,101 +0,0 @@
--- 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"
-
---- Module that handles a single message line, with pausing and flashing
-module(..., package.seeall, class.make)
-
-GOOD = 1
-NEUTRAL = 2
-BAD = 3
-
---- Creates the log zone
-function _M:init(x, y, w, h, max, fontname, fontsize, color, bgcolor)
-	self.color = color or {255,255,255}
-	self.bgcolor = bgcolor or {0,0,0}
-	self.display_x, self.display_y = math.floor(x), math.floor(y)
-	self.w, self.h = math.floor(w), math.floor(h)
-	self.font = core.display.newFont(fontname or "/data/font/Vera.ttf", fontsize or 16)
-	self.font_h = self.font:lineSkip()
-	self.surface = core.display.newSurface(w, h)
-	self.log = {}
-	getmetatable(self).__call = _M.call
-	self.flashing_style = NEUTRAL
-	self.flashing = 0
-	self.changed = true
-end
-
---- Resize the display area
-function _M:resize(x, y, w, h)
-	self.display_x, self.display_y = math.floor(x), math.floor(y)
-	self.w, self.h = math.floor(w), math.floor(h)
-	self.surface = core.display.newSurface(w, h)
-	self.changed = true
-end
-
---- Appends text to the log
--- This method is set as the call methamethod too, this means it is usable like this:<br/>
--- log = LogDisplay.new(...)<br/>
--- log("foo %s", s)
-function _M:call(style, str, ...)
-	if self.flashing == 0 and #self.log > 0 then self.log = {} end
-
-	local base = ""
-	if #self.log > 0 then base = table.remove(self.log) end
-
-	local lines = (base .. " " .. str:format(...)):splitLines(self.w - 4, self.font)
-	for i = 1, #lines do
-		table.insert(self.log, lines[i])
-	end
-	self.flashing_style = style
-	self.flashing = 20
-	self.changed = true
-end
-
---- Clear the log
-function _M:empty(force)
-	if self.flashing == 0 or force then
-		self.log = {}
-		self.flashing = 0
-		self.changed = true
-	end
-end
-
-function _M:display()
-	-- If nothing changed, return the same surface as before
-	if not self.changed then return self.surface end
-	self.changed = false
-
-	-- Erase and the display the map
-	if self.flashing_style == BAD then
-		self.surface:erase(self.bgcolor[1] + self.flashing * 10, self.bgcolor[2], self.bgcolor[3])
-	elseif self.flashing_style == NEUTRAL then
-		self.surface:erase(self.bgcolor[1], self.bgcolor[2], self.bgcolor[3] + self.flashing * 10)
-	else
-		self.surface:erase(self.bgcolor[1], self.bgcolor[2] + self.flashing * 10, self.bgcolor[3])
-        end
-	self.surface:drawColorStringBlended(self.font, self.log[1] or "", 0, 0, self.color[1], self.color[2], self.color[3])
-
-	self.flashing = self.flashing - 1
-	if self.flashing > 0 then self.changed = true
-	else table.remove(self.log, 1) end
-
-	return self.surface
-end
diff --git a/game/engine/Map.lua b/game/engine/Map.lua
deleted file mode 100644
index 3337a9fafe0c227edccf102e2b2a960d5d185ba8..0000000000000000000000000000000000000000
--- a/game/engine/Map.lua
+++ /dev/null
@@ -1,972 +0,0 @@
--- 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 Entity = require "engine.Entity"
-local Tiles = require "engine.Tiles"
-local Particles = require "engine.Particles"
-local Faction = require "engine.Faction"
-local DamageType = require "engine.DamageType"
-
---- Represents a level map, handles display and various low level map work
-module(..., package.seeall, class.make)
-
---- The map vertical depth storage
-zdepth = 18
-
---- The place of a terrain entity in a map grid
-TERRAIN = 1
---- The place of a terrain entity in a map grid
-TRAP = 50
---- The place of an actor entity in a map grid
-ACTOR = 100
---- The place of a projectile entity in a map grid
-PROJECTILE = 500
---- The place of an object entity in a map grid
-OBJECT = 1000
-
---- The order of display for grid seen
-searchOrder = { TERRAIN, TRAP, OBJECT, ACTOR }
-
-color_shown   = { 1, 1, 1, 1 }
-color_obscure = { 1, 1, 1, 0.6 }
-
--- The minimap data
-MM_FLOOR = 1
-MM_BLOCK = 2
-MM_OBJECT = 4
-MM_TRAP = 8
-MM_FRIEND = 16
-MM_NEUTRAL = 32
-MM_HOSTILE = 64
-MM_LEVEL_CHANGE = 128
-
-local s_floor = core.display.newSurface(4, 4)
-s_floor:erase(0, 0, 0, 255)
-local s_floor_gl = s_floor:glTexture()
-
-local s_block = core.display.newSurface(4, 4)
-s_block:erase(240, 240, 240, 255)
-local s_block_gl = s_block:glTexture()
-
-local s_level_change = core.display.newSurface(4, 4)
-s_level_change:erase(240, 0, 240, 255)
-local s_level_change_gl = s_level_change:glTexture()
-
-local s_hostile = core.display.newSurface(4, 4)
-s_hostile:erase(240, 0, 0, 255)
-local s_hostile_gl = s_hostile:glTexture()
-
-local s_friend = core.display.newSurface(4, 4)
-s_friend:erase(0, 240, 0, 255)
-local s_friend_gl = s_friend:glTexture()
-
-local s_neutral = core.display.newSurface(4, 4)
-s_neutral:erase(0, 0, 240, 255)
-local s_neutral_gl = s_neutral:glTexture()
-
-local s_object = core.display.newSurface(4, 4)
-s_object:erase(0, 0, 240, 255)
-local s_object_gl = s_object:glTexture()
-
-local s_trap = core.display.newSurface(4, 4)
-s_trap:erase(240, 240, 0, 255)
-local s_trap_gl = s_trap:glTexture()
-
-mm_blocks = {
-	[MM_FLOOR] = s_floor_gl,
-	[MM_BLOCK] = s_block_gl,
-	[MM_LEVEL_CHANGE] = s_level_change_gl,
-	[MM_HOSTILE] = s_hostile_gl,
-	[MM_FRIEND] = s_friend_gl,
-	[MM_NEUTRAL] = s_neutral_gl,
-	[MM_OBJECT] = s_object_gl,
-	[MM_TRAP] = s_trap_gl,
-}
-
---- Sets the viewport size
--- Static
--- @param x screen coordonate where the map will be displayed (this has no impact on the real display). This is used to compute mouse clicks
--- @param y screen coordonate where the map will be displayed (this has no impact on the real display). This is used to compute mouse clicks
--- @param w width
--- @param h height
--- @param tile_w width of a single tile
--- @param tile_h height of a single tile
--- @param fontname font parameters, can be nil
--- @param fontsize font parameters, can be nil
-function _M:setViewPort(x, y, w, h, tile_w, tile_h, fontname, fontsize, multidisplay, allow_backcolor)
-	self.allow_backcolor = allow_backcolor
-	self.multidisplay = multidisplay
-	self.display_x, self.display_y = math.floor(x), math.floor(y)
-	self.viewport = {width=math.floor(w), height=math.floor(h), mwidth=math.floor(w/tile_w), mheight=math.floor(h/tile_h)}
-	self.tile_w, self.tile_h = tile_w, tile_h
-	self.fontname, self.fontsize = fontname, fontsize
-	self:resetTiles()
-	self.zoom = 1
-end
-
---- Sets zoom level
--- @param zoom nil to reset to default, ortherwise a number to increment the zoom with
--- @param tmx make sure this coords are visible after zoom (can be nil)
--- @param tmy make sure this coords are visible after zoom (can be nil)
-function _M:setZoom(zoom, tmx, tmy)
-	self.changed = true
-	_M.zoom = util.bound(_M.zoom + zoom, 0.1, 4)
-	self.viewport.mwidth = math.floor(self.viewport.width / (self.tile_w * _M.zoom))
-	self.viewport.mheight = math.floor(self.viewport.height / (self.tile_h * _M.zoom))
-	print("[MAP] setting zoom level", _M.zoom, self.viewport.mwidth, self.viewport.mheight)
-
-	self._map:setZoom(
-		self.tile_w * self.zoom,
-		self.tile_h * self.zoom,
-		self.viewport.mwidth,
-		self.viewport.mheight
-	)
-	if tmx and tmy then
-		self:centerViewAround(tmx, tmy)
-	else
-		self:checkMapViewBounded()
-	end
-end
-
---- Defines the "obscure" factor of unseen map
--- By default it is 0.6, 0.6, 0.6, 1
-function _M:setObscure(r, g, b, a)
-	self.color_obscure = {r, g, b, a}
-	-- If we are used on a real map, set it localy
-	if self._map then self._map:setObscure(unpack(self.color_obscure)) end
-end
-
---- Defines the "shown" factor of seen map
--- By default it is 1, 1, 1, 1
-function _M:setShown(r, g, b, a)
-	self.color_shown= {r, g, b, a}
-	-- If we are used on a real map, set it localy
-	if self._map then self._map:setShown(unpack(self.color_shown)) end
-end
-
---- Create the tile repositories
-function _M:resetTiles()
-	Entity:invalidateAllMO()
-	self.tiles = Tiles.new(self.tile_w, self.tile_h, self.fontname, self.fontsize, true, self.allow_backcolor)
-	self.tilesSDL = Tiles.new(self.tile_w, self.tile_h, self.fontname, self.fontsize, false, self.allow_backcolor)
-	self.tilesTactic = Tiles.new(self.tile_w, self.tile_h, self.fontname, self.fontsize, true, false)
-	self.tilesSurface = Tiles.new(self.tile_w, self.tile_h, self.fontname, self.fontsize, true, true)
-end
-
---- Defines the faction of the person seeing the map
--- Usualy this will be the player's faction. If you do not want to use tactical display, dont use it
-function _M:setViewerFaction(faction, friend, neutral, enemy)
-	self.view_faction = faction
-	self.faction_friend = "tactical_friend.png"
-	self.faction_neutral = "tactical_neutral.png"
-	self.faction_enemy = "tactical_enemy.png"
-end
-
---- Defines the actor that sees the map
--- Usualy this will be the player. This is used to determine invisibility/...
-function _M:setViewerActor(player)
-	self.actor_player = player
-end
-
---- Creates a map
--- @param w width (in grids)
--- @param h height (in grids)
-function _M:init(w, h)
-	self.mx = 0
-	self.my = 0
-	self.w, self.h = w, h
-	self.map = {}
-	self.attrs = {}
-	self.lites = {}
-	self.seens = {}
-	self.has_seens = {}
-	self.remembers = {}
-	self.effects = {}
-	self.path_strings = {}
-	for i = 0, w * h - 1 do self.map[i] = {} end
-
-	self.particles = {}
-	self.emotes = {}
-
-	self:loaded()
-end
-
---- Serialization
-function _M:save()
-	return class.save(self, {
-		_check_entities = true,
-		_check_entities_store = true,
-		_map = true,
-		_fovcache = true,
-		surface = true,
-	})
-end
-
-function _M:makeCMap()
-	self._map = core.map.newMap(self.w, self.h, self.mx, self.my, self.viewport.mwidth, self.viewport.mheight, self.tile_w, self.tile_h, self.zdepth)
-	self._map:setObscure(unpack(self.color_obscure))
-	self._map:setShown(unpack(self.color_shown))
-	self._map:setupMiniMap(
-		mm_blocks[MM_FLOOR],
-		mm_blocks[MM_BLOCK],
-		mm_blocks[MM_OBJECT],
-		mm_blocks[MM_TRAP],
-		mm_blocks[MM_FRIEND],
-		mm_blocks[MM_NEUTRAL],
-		mm_blocks[MM_HOSTILE],
-		mm_blocks[MM_LEVEL_CHANGE]
-	)
-	self._fovcache =
-	{
-		block_sight = core.fov.newCache(self.w, self.h),
-		block_esp = core.fov.newCache(self.w, self.h),
-		block_sense = core.fov.newCache(self.w, self.h),
-		path_caches = {},
-	}
-	for i, ps in ipairs(self.path_strings) do
-		self._fovcache.path_caches[ps] = core.fov.newCache(self.w, self.h)
-	end
-end
-
---- Adds a "path string" to the map
--- "Path strings" are strings defining what terrain an actor can cross. Their format is left to the module to decide (by overloading Actor:getPathString() )<br/>
--- They are totally optional as they re only used to compute A* paths adn the likes and even then the algorithms still work without them, only slower<br/>
--- If you use them the block_move function of your Grid class must be able to handle either an actor or a "path string" as their third argument
-function _M:addPathString(ps)
-	for i, eps in ipairs(self.path_strings) do
-		if eps == ps then return end
-	end
-	self.path_strings[#self.path_strings+1] = ps
-	if self._fovcache then self._fovcache.path_caches[ps] = core.fov.newCache(self.w, self.h) end
-end
-
-function _M:loaded()
-	self:makeCMap()
-
-	local mapseen = function(t, x, y, v)
-		if x < 0 or y < 0 or x >= self.w or y >= self.h then return end
-		if v ~= nil then
-			t[x + y * self.w] = v
-			self._map:setSeen(x, y, v)
-			if v then self.has_seens[x + y * self.w] = true end
-			self.changed = true
-		end
-		return t[x + y * self.w]
-	end
-	local maphasseen = function(t, x, y, v)
-		if x < 0 or y < 0 or x >= self.w or y >= self.h then return end
-		if v ~= nil then
-			t[x + y * self.w] = v
-		end
-		return t[x + y * self.w]
-	end
-	local mapremember = function(t, x, y, v)
-		if x < 0 or y < 0 or x >= self.w or y >= self.h then return end
-		if v ~= nil then
-			t[x + y * self.w] = v
-			self._map:setRemember(x, y, v)
-			self.changed = true
-		end
-		return t[x + y * self.w]
-	end
-	local maplite = function(t, x, y, v)
-		if x < 0 or y < 0 or x >= self.w or y >= self.h then return end
-		if v ~= nil then
-			t[x + y * self.w] = v
-			self._map:setLite(x, y, v)
-			self.changed = true
-		end
-		return t[x + y * self.w]
-	end
-	local mapattrs = function(t, x, y, k, v)
-		if x < 0 or y < 0 or x >= self.w or y >= self.h then return end
-		if v ~= nil then
-			if not t[x + y * self.w] then t[x + y * self.w] = {} end
-			t[x + y * self.w][k] = v
-		end
-		return t[x + y * self.w] and t[x + y * self.w][k]
-	end
-
-	getmetatable(self).__call = _M.call
-	setmetatable(self.lites, {__call = maplite})
-	setmetatable(self.seens, {__call = mapseen})
-	setmetatable(self.has_seens, {__call = maphasseen})
-	setmetatable(self.remembers, {__call = mapremember})
-	setmetatable(self.attrs, {__call = mapattrs})
-
-	self._check_entities = {}
-	self._check_entities_store = {}
-
-	self.surface = core.display.newSurface(self.viewport.width, self.viewport.height)
-	self.changed = true
-	self.finished = true
-
-	self:redisplay()
-end
-
---- Recreate the internal map using new dimensions
-function _M:recreate()
-	self:makeCMap()
-	self.changed = true
-	self:redisplay()
-end
-
---- Redisplays the map, storing seen information
-function _M:redisplay()
-	for i = 0, self.w - 1 do for j = 0, self.h - 1 do
-		self._map:setSeen(i, j, self.seens(i, j))
-		self._map:setRemember(i, j, self.remembers(i, j))
-		self._map:setLite(i, j, self.lites(i, j))
-		self:updateMap(i, j)
-	end end
-end
-
---- Closes things in the object to allow it to be garbage collected
--- Map objects are NOT automatically garbage collected because they contain FOV C structure, which themselves have a reference
--- to the map. Cyclic references! BAD BAD BAD !<br/>
--- The closing should be handled automatically by the Zone class so no bother for authors
-function _M:close()
-end
-
---- Cleans the FOV infos (seens table)
-function _M:cleanFOV()
-	if not self.clean_fov then return end
-	self.clean_fov = false
-	for i = 0, self.w * self.h - 1 do self.seens[i] = nil end
-	self._map:cleanSeen()
-end
-
---- Updates the map on the given spot
--- This updates many things, from the C map object, the FOV caches, the minimap if it exists, ...
-function _M:updateMap(x, y)
-	local g = self(x, y, TERRAIN)
-	local o = self(x, y, OBJECT)
-	local a = self(x, y, ACTOR)
-	local t = self(x, y, TRAP)
-	local p = self(x, y, PROJECTILE)
-
-	-- Update minimap if any
-	local mm = MM_FLOOR
-	local mos = {}
-
-	if g then
-		-- Update path caches from path strings
-		for i = 1, #self.path_strings do
-			local ps = self.path_strings[i]
-			self._fovcache.path_caches[ps]:set(x, y, g:check("block_move", x, y, ps, false, true))
-		end
-
-		mm = mm + (g:check("block_move") and MM_BLOCK or 0)
-		mm = mm + (g:check("change_level") and MM_LEVEL_CHANGE or 0)
-		g:getMapObjects(self.tiles, mos, 1)
-	end
-	if t then
-		-- Handles invisibility and telepathy and other such things
-		if not self.actor_player or t:knownBy(self.actor_player) then
-			t:getMapObjects(self.tiles, mos, 4)
-			mm = mm + MM_TRAP
-		else
-			t = nil
-		end
-	end
-	if o then
-		o:getMapObjects(self.tiles, mos, 7)
-		mm = mm + MM_OBJECT
-	end
-	if a then
-		-- Handles invisibility and telepathy and other such things
-		if not self.actor_player or self.actor_player:canSee(a) then
-			local r = self.actor_player:reactionToward(a)
-			mm = mm + (r > 0 and MM_FRIEND or (r == 0 and MM_NEUTRAL or MM_HOSTILE))
-			a:getMapObjects(self.tiles, mos, 10)
-		end
-	end
-	if p then
-		p:getMapObjects(self.tiles, mos, 13)
-	end
-
-	-- Update entities checker for this spot
-	-- This is to improve speed, we create a function for each spot that checks entities it knows are there
-	-- This avoid a costly for iteration over a pairs() and this allows luajit to compile only code that is needed
-	local ce = {}
-	local fstr = [[p = m[%s]:check(what, x, y, ...) if p then return p end ]]
-	ce[#ce+1] = [[return function(self, x, y, what, ...) local p local m = self.map[x + y * self.w] ]]
-	for idx, e in pairs(self.map[x + y * self.w]) do ce[#ce+1] = fstr:format(idx) end
-	ce[#ce+1] = [[end]]
-	local ce = table.concat(ce)
-	self._check_entities[x + y * self.w] = self._check_entities_store[ce] or loadstring(ce)()
-	self._check_entities_store[ce] = self._check_entities[x + y * self.w]
-
-	-- Cache the map objects in the C map
-	self._map:setGrid(x, y, mm, mos)
-
-	-- Update FOV caches
-	if self:checkAllEntities(x, y, "block_sight", self.actor_player) then self._fovcache.block_sight:set(x, y, true)
-	else self._fovcache.block_sight:set(x, y, false) end
-	if self:checkAllEntities(x, y, "block_esp", self.actor_player) then self._fovcache.block_esp:set(x, y, true)
-	else self._fovcache.block_esp:set(x, y, false) end
-	if self:checkAllEntities(x, y, "block_sense", self.actor_player) then self._fovcache.block_sense:set(x, y, true)
-	else self._fovcache.block_sense:set(x, y, false) end
-end
-
---- Sets/gets a value from the map
--- It is defined as the function metamethod, so one can simply do: mymap(x, y, Map.TERRAIN)
--- @param x position
--- @param y position
--- @param pos what kind of entity to set(Map.TERRAIN, Map.OBJECT, Map.ACTOR)
--- @param entity the entity to set, if null it will return the current one
-function _M:call(x, y, pos, entity)
-	if x < 0 or y < 0 or x >= self.w or y >= self.h then return end
-	if entity then
-		self.map[x + y * self.w][pos] = entity
-		self.changed = true
-
-		self:updateMap(x, y)
-	else
-		if self.map[x + y * self.w] then
-			if not pos then
-				return self.map[x + y * self.w]
-			else
-				return self.map[x + y * self.w][pos]
-			end
-		end
-	end
-end
-
---- Removes an entity
--- @param x position
--- @param y position
--- @param pos what kind of entity to set(Map.TERRAIN, Map.OBJECT, Map.ACTOR)
-function _M:remove(x, y, pos)
-	if self.map[x + y * self.w] then
-		self.map[x + y * self.w][pos] = nil
-		self:updateMap(x, y)
-		self.changed = true
-	end
-end
-
---- Displays the minimap
--- @return a surface containing the drawn map
-function _M:minimapDisplay(dx, dy, x, y, w, h, transp)
-	self._map:toScreenMiniMap(dx, dy, x, y, w, h, transp or 0.6)
-end
-
---- Displays the map on a surface
--- @return a surface containing the drawn map
-function _M:display(x, y)
-	local ox, oy = self.display_x, self.display_y
-	self.display_x, self.display_y = x or self.display_x, y or self.display_y
-
-	self._map:toScreen(self.display_x, self.display_y)
-
-	-- Tactical display
-	if self.view_faction then
-		local e
-		local z
-		local friend
-		for i = self.mx, self.mx + self.viewport.mwidth - 1 do
-		for j = self.my, self.my + self.viewport.mheight - 1 do
-			local z = i + j * self.w
-
-			if self.seens[z] then
-				e = self(i, j, ACTOR)
-				if e and (not self.actor_player or self.actor_player:canSee(e)) then
-					-- Tactical overlay ?
-					if e.faction then
-						friend = Faction:factionReaction(self.view_faction, e.faction)
-						if friend > 0 then
-							self.tilesTactic:get(nil, 0,0,0, 0,0,0, self.faction_friend):toScreen(self.display_x + (i - self.mx) * self.tile_w * self.zoom, self.display_y + (j - self.my) * self.tile_h * self.zoom, self.tile_w * self.zoom, self.tile_h * self.zoom)
-						elseif friend < 0 then
-							self.tilesTactic:get(nil, 0,0,0, 0,0,0, self.faction_enemy):toScreen(self.display_x + (i - self.mx) * self.tile_w * self.zoom, self.display_y + (j - self.my) * self.tile_h * self.zoom, self.tile_w * self.zoom, self.tile_h * self.zoom)
-						else
-							self.tilesTactic:get(nil, 0,0,0, 0,0,0, self.faction_neutral):toScreen(self.display_x + (i - self.mx) * self.tile_w * self.zoom, self.display_y + (j - self.my) * self.tile_h * self.zoom, self.tile_w * self.zoom, self.tile_h * self.zoom)
-						end
-					end
-				end
-			end
-		end end
-	end
-
-	self:displayParticles()
-	self:displayEffects()
-	self:displayEmotes()
-
-	self.display_x, self.display_y = ox, oy
-
-	-- If nothing changed, return the same surface as before
-	if not self.changed then return end
-	self.changed = false
-	self.clean_fov = true
-end
-
---- Sets checks if a grid lets sigth pass through
--- Used by FOV code
-function _M:opaque(x, y)
-	if x < 0 or x >= self.w or y < 0 or y >= self.h then return false end
-	local e = self.map[x + y * self.w][TERRAIN]
-	if e and e:check("block_sight") then return true end
-end
-
---- Sets checks if a grid lets ESP pass through
--- Used by FOV ESP code
-function _M:opaqueESP(x, y)
-	if x < 0 or x >= self.w or y < 0 or y >= self.h then return false end
-	local e = self.map[x + y * self.w][TERRAIN]
-	if e and e:check("block_esp") then return true end
-end
-
---- Sets a grid as seen and remembered
--- Used by FOV code
-function _M:apply(x, y, v)
-	if x < 0 or x >= self.w or y < 0 or y >= self.h then return end
-	if self.lites[x + y * self.w] then
-		self.seens[x + y * self.w] = v or 1
-		self.has_seens[x + y * self.w] = true
-		self._map:setSeen(x, y, v or 1)
-		self.remembers[x + y * self.w] = true
-		self._map:setRemember(x, y, true)
-	end
-end
-
---- Sets a grid as seen, lited and remembered
--- Used by FOV code
-function _M:applyLite(x, y, v)
-	if x < 0 or x >= self.w or y < 0 or y >= self.h then return end
-	if self.lites[x + y * self.w] or self:checkEntity(x, y, TERRAIN, "always_remember") then
-		self.remembers[x + y * self.w] = true
-		self._map:setRemember(x, y, true)
-	end
-	self.seens[x + y * self.w] = v or 1
-	self.has_seens[x + y * self.w] = true
-	self._map:setSeen(x, y, v or 1)
-end
-
---- Sets a grid as seen if ESP'ed
--- Used by FOV code
-function _M:applyESP(x, y, v)
-	if not self.actor_player then return end
-	if x < 0 or x >= self.w or y < 0 or y >= self.h then return end
-	local a = self.map[x + y * self.w][ACTOR]
-	if a and self.actor_player:canSee(a, false, 0, true) then
-		self.seens[x + y * self.w] = v or 1
-		self._map:setSeen(x, y, v or 1)
-	end
-end
-
---- Check all entities of the grid for a property until it finds one/returns one
--- This will stop at the first entity with the given property (or if the property is a function, the return of the function that is not false/nil).
--- No guaranty is given about the iteration order
--- @param x position
--- @param y position
--- @param what property to check
-function _M:checkAllEntities(x, y, what, ...)
-	if x < 0 or x >= self.w or y < 0 or y >= self.h then return end
-	if self.map[x + y * self.w] then
-		return self._check_entities[x + y * self.w](self, x, y, what, ...)
-	end
-end
-
---- Check all entities of the grid for a property, discarding the results
--- This will iterate over all entities without stoping.
--- No guaranty is given about the iteration order
--- @param x position
--- @param y position
--- @param what property to check
-function _M:checkAllEntitiesNoStop(x, y, what, ...)
-	if x < 0 or x >= self.w or y < 0 or y >= self.h then return end
-	if self.map[x + y * self.w] then
-		for _, e in pairs(self.map[x + y * self.w]) do
-			e:check(what, x, y, ...)
-		end
-	end
-end
-
---- Check specified entity position of the grid for a property
--- @param x position
--- @param y position
--- @param pos entity position in the grid
--- @param what property to check
-function _M:checkEntity(x, y, pos, what, ...)
-	if x < 0 or x >= self.w or y < 0 or y >= self.h then return end
-	if self.map[x + y * self.w] then
-		if self.map[x + y * self.w][pos] then
-			local p = self.map[x + y * self.w][pos]:check(what, x, y, ...)
-			if p then return p end
-		end
-	end
-end
-
---- Lite all grids
-function _M:liteAll(x, y, w, h)
-	for i = x, x + w - 1 do for j = y, y + h - 1 do
-		self.lites(i, j, true)
-	end end
-end
-
---- Remember all grids
-function _M:rememberAll(x, y, w, h)
-	for i = x, x + w - 1 do for j = y, y + h - 1 do
-		self.remembers(i, j, true)
-	end end
-end
-
---- Sets the current view area with the given coords at the center
-function _M:centerViewAround(x, y)
-	self.mx = x - math.floor(self.viewport.mwidth / 2)
-	self.my = y - math.floor(self.viewport.mheight / 2)
-	self.changed = true
-	self:checkMapViewBounded()
-end
-
---- Sets the current view area if x and y are out of bounds
-function _M:moveViewSurround(x, y, marginx, marginy)
-	if self.mx + marginx >= x or self.mx + self.viewport.mwidth - marginx <= x then
-		self.mx = x - math.floor(self.viewport.mwidth / 2)
-		self.changed = true
-	end
-	if self.my + marginy >= y or self.my + self.viewport.mheight - marginy <= y then
-		self.my = y - math.floor(self.viewport.mheight / 2)
-		self.changed = true
-	end
-	self:checkMapViewBounded()
-end
-
---- Checks the map is bound to the screen (no "empty space" if the map is big enough)
-function _M:checkMapViewBounded()
-	if self.mx < 0 then self.mx = 0 self.changed = true end
-	if self.my < 0 then self.my = 0 self.changed = true end
-	if self.mx > self.w - self.viewport.mwidth then self.mx = self.w - self.viewport.mwidth self.changed = true end
-	if self.my > self.h - self.viewport.mheight then self.my = self.h - self.viewport.mheight self.changed = true end
-
-	-- Center if smaller than map viewport
-	if self.w < self.viewport.mwidth then self.mx = math.floor((self.w - self.viewport.mwidth) / 2) end
-	if self.h < self.viewport.mheight then self.my = math.floor((self.h - self.viewport.mheight) / 2) end
-
-	self._map:setScroll(self.mx, self.my)
-end
-
---- Gets the tile under the mouse
-function _M:getMouseTile(mx, my)
---	if mx < self.display_x or my < self.display_y or mx >= self.display_x + self.viewport.width or my >= self.display_y + self.viewport.height then return end
-	local tmx = math.floor((mx - self.display_x) / (self.tile_w * self.zoom)) + self.mx
-	local tmy = math.floor((my - self.display_y) / (self.tile_h * self.zoom)) + self.my
-	return tmx, tmy
-end
-
---- Get the screen position corresponding to a tile
-function _M:getTileToScreen(tx, ty)
-	local x = (tx - self.mx) * self.tile_w * self.zoom + self.display_x
-	local y = (ty - self.my) * self.tile_h * self.zoom + self.display_y
-	return x, y
-end
-
---- Checks the given coords to see if they are in bound
-function _M:isBound(x, y)
-	if x < 0 or x >= self.w or y < 0 or y >= self.h then return false end
-	return true
-end
-
---- Checks the given coords to see if they are displayed on screen
-function _M:isOnScreen(x, y)
-	if x >= self.mx and x < self.mx + self.viewport.mwidth and y >= self.my and y < self.my + self.viewport.mheight then
-		return true
-	end
-	return false
-end
-
---- Import a map into the current one
--- @param map the map to import
--- @param dx coordinate where to import it in the current map
--- @param dy coordinate where to import it in the current map
--- @param sx coordinate where to start importing the map, defaults to 0
--- @param sy coordinate where to start importing the map, defaults to 0
--- @param sw size of the imported map to get, defaults to map size
--- @param sh size of the imported map to get, defaults to map size
-function _M:import(map, dx, dy, sx, sy, sw, sh)
-	sx = sx or 0
-	sy = sy or 0
-	sw = sw or map.w
-	sh = sh or map.h
-
-	for i = sx, sx + sw - 1 do for j = sy, sy + sh - 1 do
-		local x, y = dx + i, dy + j
-		self.map[x + y * self.w] = map.map[i + j * map.w]
-		for z, e in pairs(self.map[x + y * self.w]) do
-			if e.move then e:move(x, y, true) end
-		end
-
-		self.remembers(x, y, map.remembers(i, j))
-		self.seens(x, y, map.seens(i, j))
-		self.lites(x, y, map.lites(i, j))
-
-		self:updateMap(x, y)
-	end end
-	self.changed = true
-end
-
---- Adds a zone (temporary) effect
--- @param src the source actor
--- @param x the epicenter coords
--- @param y the epicenter coords
--- @param duration the number of turns to persist
--- @param damtype the DamageType to apply
--- @param radius the radius of the effect
--- @param dir the numpad direction of the effect, 5 for a ball effect
--- @param overlay either a simple display entity to draw upon the map or a Particle class
--- @param update_fct optional function that will be called each time the effect is updated with the effect itself as parameter. Use it to change radius, move around ....
-function _M:addEffect(src, x, y, duration, damtype, dam, radius, dir, angle, overlay, update_fct, friendlyfire)
-	if friendlyfire == nil then friendlyfire = true end
-
-	local grids
-
-	-- Handle balls
-	if dir == 5 then
-		grids = core.fov.circle_grids(x, y, radius, true)
-	-- Handle beams
-	else
-		grids = core.fov.beam_grids(x, y, radius, dir, angle, true)
-	end
-
-	local e = {
-		src=src, x=x, y=y, duration=duration, damtype=damtype, dam=dam, radius=radius, dir=dir, angle=angle,
-		overlay=overlay.__CLASSNAME and overlay,
-		grids = grids,
-		update_fct=update_fct, friendlyfire=friendlyfire
-	}
-
-	if not overlay.__CLASSNAME then
-		e.particles = {}
-		for lx, ys in pairs(grids) do
-			for ly, _ in pairs(ys) do
-				e.particles[#e.particles+1] = self:particleEmitter(lx, ly, 1, overlay.type, overlay.args)
-			end
-		end
-	end
-
-	table.insert(self.effects, e)
-
-	self.changed = true
-end
-
---- Display the overlay effects, called by self:display()
-function _M:displayEffects()
-	for i, e in ipairs(self.effects) do
-		-- Dont bother with obviously out of screen stuff
-		if e.overlay and e.x + e.radius >= self.mx and e.x - e.radius < self.mx + self.viewport.mwidth and e.y + e.radius >= self.my and e.y - e.radius < self.my + self.viewport.mheight then
-			local s = self.tilesSurface:get(e.overlay.display, e.overlay.color_r, e.overlay.color_g, e.overlay.color_b, e.overlay.color_br, e.overlay.color_bg, e.overlay.color_bb, e.overlay.image, e.overlay.alpha)
-
-			-- Now display each grids
-			for lx, ys in pairs(e.grids) do
-				for ly, _ in pairs(ys) do
-					if self.seens(lx, ly) then
-						s:toScreen(self.display_x + (lx - self.mx) * self.tile_w * self.zoom, self.display_y + (ly - self.my) * self.tile_h * self.zoom, self.tile_w * self.zoom, self.tile_h * self.zoom)
-					end
-				end
-			end
-		end
-	end
-end
-
---- Process the overlay effects, call it from your tick function
-function _M:processEffects()
-	local todel = {}
-	for i, e in ipairs(self.effects) do
-		-- Now display each grids
-		for lx, ys in pairs(e.grids) do
-			for ly, _ in pairs(ys) do
-				if e.friendlyfire or not (lx == e.src.x and ly == e.src.y) then
-					DamageType:get(e.damtype).projector(e.src, lx, ly, e.damtype, e.dam)
-				end
-			end
-		end
-
-		e.duration = e.duration - 1
-		if e.duration <= 0 then
-			table.insert(todel, i)
-		elseif e.update_fct then
-			if e:update_fct() then
-				if e.dir == 5 then e.grids = core.fov.circle_grids(e.x, e.y, e.radius, true)
-				else e.grids = core.fov.beam_grids(e.x, e.y, e.radius, e.dir, e.angle, true) end
-				if e.particles then
-					for j, ps in ipairs(e.particles) do self:removeParticleEmitter(ps) end
-					e.particles = {}
-					for lx, ys in pairs(grids) do
-						for ly, _ in pairs(ys) do
-							e.particles[#e.particles+1] = self:particleEmitter(lx, ly, 1, overlay.type, overlay.args)
-						end
-					end
-				end
-			end
-		end
-	end
-
-	for i = #todel, 1, -1 do
-		if self.effects[todel[i]].particles then
-			for j, ps in ipairs(self.effects[todel[i]].particles) do self:removeParticleEmitter(ps) end
-		end
-		table.remove(self.effects, todel[i])
-	end
-end
-
-
--------------------------------------------------------------
--------------------------------------------------------------
--- Object functions
--------------------------------------------------------------
--------------------------------------------------------------
-function _M:addObject(x, y, o)
-	local i = self.OBJECT
-	-- Find the first "hole"
-	while self(x, y, i) do i = i + 1 end
-	-- Fill it
-	self(x, y, i, o)
-	return true
-end
-
-function _M:getObject(x, y, i)
-	-- Compute the map stack position
-	i = i - 1 + self.OBJECT
-	return self(x, y, i)
-end
-
-function _M:getObjectTotal(x, y)
-	-- Compute the map stack position
-	local i = 1
-	while self(x, y, i) do i = i + 1 end
-	return i - 1
-end
-
-function _M:removeObject(x, y, i)
-	-- Compute the map stack position
-	i = i - 1 + self.OBJECT
-	if not self(x, y, i) then return false end
-	-- Remove it
-	self:remove(x, y, i)
-	-- Move the last one to its position, to never get a "hole"
-	local j = i + 1
-	while self(x, y, j) do j = j + 1 end
-	j = j - 1
-	-- If the removed one was not the last
-	if j > i then
-		local o = self(x, y, j)
-		self:remove(x, y, j)
-		self(x, y, i, o)
-	end
-
-	return true
-end
-
--------------------------------------------------------------
--------------------------------------------------------------
--- Particle projector
--------------------------------------------------------------
--------------------------------------------------------------
-
---- Add a new particle emitter
-function _M:particleEmitter(x, y, radius, def, args)
-	local e = Particles.new(def, radius, args)
-	e.x = x
-	e.y = y
-
-	self.particles[e] = true
-	return e
-end
-
---- Adds an existing particle emitter to the map
-function _M:addParticleEmitter(e)
-	if self.particles[e] then return false end
-	self.particles[e] = true
-	return e
-end
-
---- Removes a particle emitter from the map
-function _M:removeParticleEmitter(e)
-	if not self.particles[e] then return false end
-	self.particles[e] = nil
-	return true
-end
-
---- Display the particle emiters, called by self:display()
-function _M:displayParticles()
-	local del = {}
-	local e = next(self.particles)
-	while e do
-		local alive = false
-
-		alive = not e.update(e)
-
-		-- Dont bother with obviously out of screen stuff
-		if alive and e.x + e.radius >= self.mx and e.x - e.radius < self.mx + self.viewport.mwidth and e.y + e.radius >= self.my and e.y - e.radius < self.my + self.viewport.mheight then
-			alive = e.ps:toScreen(self.display_x + (e.x - self.mx + 0.5) * self.tile_w * self.zoom, self.display_y + (e.y - self.my + 0.5) * self.tile_h * self.zoom, self.seens(e.x, e.y), self.zoom)
-		end
-
-		if not alive then
-			del[#del+1] = e
-			e.dead = true
-		end
-
-		e = next(self.particles, e)
-	end
-	for i = 1, #del do self.particles[del[i]] = nil end
-end
-
--------------------------------------------------------------
--------------------------------------------------------------
--- Emotes
--------------------------------------------------------------
--------------------------------------------------------------
-
---- Adds an existing emote to the map
-function _M:addEmote(e)
-	if self.emotes[e] then return false end
-	self.emotes[e] = true
-	print("[EMOTE] added", e.text, e.x, e.y)
-	return e
-end
-
---- Removes an emote from the map
-function _M:removeEmote(e)
-	if not self.emotes[e] then return false end
-	self.emotes[e] = nil
-	return true
-end
-
---- Display the emotes, called by self:display()
-function _M:displayEmotes()
-	local del = {}
-	local e = next(self.emotes)
-	while e do
-		-- Dont bother with obviously out of screen stuff
-		if e.x >= self.mx and e.x < self.mx + self.viewport.mwidth and e.y >= self.my and e.y < self.my + self.viewport.mheight and self.seens(e.x, e.y) then
-			e.surface:toScreen(
-				self.display_x + (e.x - self.mx + 0.5) * self.tile_w * self.zoom,
-				self.display_y + (e.y - self.my - 0.9) * self.tile_h * self.zoom
-			)
-		end
-
-		if e:update() then
-			del[#del+1] = e
-			e.dead = true
-		end
-
-		e = next(self.emotes, e)
-	end
-	for i = 1, #del do self.emotes[del[i]] = nil end
-end
diff --git a/game/engine/Module.lua b/game/engine/Module.lua
deleted file mode 100644
index e1f5f14b7f5f194eb9cf35b19486c6026a177835..0000000000000000000000000000000000000000
--- a/game/engine/Module.lua
+++ /dev/null
@@ -1,257 +0,0 @@
--- 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 lanes = require "lanes"
-local Dialog = require "engine.Dialog"
-local Savefile = require "engine.Savefile"
-
---- Handles dialog windows
-module(..., package.seeall, class.make)
-
---- List all available modules
--- Static
-function _M:listModules()
-	local ms = {}
-	fs.mount(engine.homepath, "/")
---	print("Search Path: ") for k,e in ipairs(fs.getSearchPath()) do print("*",k,e) end
-
-	for i, short_name in ipairs(fs.list("/modules/")) do
---print("!!", short_name)
-		local dir = "/modules/"..short_name
-		if fs.exists(dir.."/init.lua") then
-			local mod = self:loadDefinition(dir)
-			if mod then
-				table.insert(ms, mod)
-				ms[mod.short_name] = mod
-			end
-		elseif short_name:find(".team$") then
-			fs.mount(fs.getRealPath(dir), "/testload", false)
-			if fs.exists("/testload/mod/init.lua") then
-				local mod = self:loadDefinition("/testload", dir)
-				if mod then
-					table.insert(ms, mod)
-					ms[mod.short_name] = mod
-				end
-			end
-			fs.umount(fs.getRealPath(dir))
-		end
-	end
-
-	table.sort(ms, function(a, b)
-		if a.short_name == "tome" then return 1
-		elseif b.short_name == "tome" then return nil
-		else return a.name < b.name
-		end
-	end)
---	fs.umount(engine.homepath)
-
-	return ms
-end
-
---- Get a module definition from the module init.lua file
-function _M:loadDefinition(dir, team)
-	local mod_def = loadfile(team and (dir.."/mod/init.lua") or (dir.."/init.lua"))
-	if mod_def then
-		-- Call the file body inside its own private environment
-		local mod = {}
-		setfenv(mod_def, mod)
-		mod_def()
-
-		if not mod.long_name or not mod.name or not mod.short_name or not mod.version or not mod.starter then return end
-
-		-- Test engine version
-		if mod.engine[1] * 1000000 + mod.engine[2] * 1000 + mod.engine[3] > engine.version[1] * 1000000 + engine.version[2] * 1000 + engine.version[3] then
-			print("Module mismatch engine version", mod.short_name, mod.engine[1] * 1000000 + mod.engine[2] * 1000 + mod.engine[3], engine.version[1] * 1000000 + engine.version[2] * 1000 + engine.version[3])
-			return
-		end
-
-		-- Make a function to activate it
-		mod.load = function()
-			core.display.setWindowTitle(mod.long_name)
-			self:setupWrite(mod)
-			if not team then
-				fs.mount(fs.getRealPath(dir), "/mod", false)
-				fs.mount(fs.getRealPath(dir).."/data/", "/data", false)
-				if fs.exists(dir.."/engine") then fs.mount(fs.getRealPath(dir).."/engine/", "/engine", false) end
-			else
-				local src = fs.getRealPath(team)
-
-				fs.mount(src, "/", false)
-			end
-			profile:loadModuleProfile(mod.short_name)
-			local m = require(mod.starter)
-			m[1].__session_time_played_start = os.time()
-			m[1].__mod_info = mod
-			print("[MODULE LOADER] loading module", mod.long_name, "["..mod.starter.."]", "::", m[1] and m[1].__CLASSNAME, m[2] and m[2].__CLASSNAME)
-			return m[1], m[2]
-		end
-
-		return mod
-	end
-end
-
---- List all available savefiles
--- Static
-function _M:listSavefiles()
---	fs.mount(engine.homepath, "/tmp/listsaves")
-
-	local mods = self:listModules()
-	for _, mod in ipairs(mods) do
-		local lss = {}
-		for i, short_name in ipairs(fs.list("/"..mod.short_name.."/save/")) do
-			local dir = "/"..mod.short_name.."/save/"..short_name
-			if fs.exists(dir.."/game.teag") then
-				local def = self:loadSavefileDescription(dir)
-				if def then
-					table.insert(lss, def)
-				end
-			end
-		end
-		mod.savefiles = lss
-
-		table.sort(lss, function(a, b)
-			return a.name < b.name
-		end)
-	end
-
---	fs.umount(engine.homepath)
-
-	return mods
-end
-
---- Instanciate the given module, loading it and creating a new game / loading an existing one
--- @param mod the module definition as given by Module:loadDefinition()
--- @param name the savefile name
--- @param new_game true if the game must be created (aka new character)
-function _M:instanciate(mod, name, new_game)
-	local popup = Dialog:simplePopup("Loading module", "Please wait while loading the game module...")
-	popup.__showup = nil
-	core.display.forceRedraw()
-
-	profile.generic.modules_loaded = profile.generic.modules_loaded or {}
-	profile.generic.modules_loaded[mod.short_name] = (profile.generic.modules_loaded[mod.short_name] or 0) + 1
-	profile:saveGenericProfile("modules_loaded", profile.generic.modules_loaded)
-
-	-- Ok run the module
-	local M, W = mod.load()
-	_G.game = M.new()
-	_G.game:setPlayerName(name)
-
-	-- Load the world, or make a new one
-	if W then
-		local save = Savefile.new("")
-		_G.world = save:loadWorld()
-		save:close()
-		if not _G.world then
-			_G.world = W.new()
-		end
-		_G.world:run()
-	end
-
-	-- Load the savefile if it exists, or create a new one if not (or if requested)
-	local save = engine.Savefile.new(_G.game.save_name)
-	if save:check() and not new_game then
-		_G.game = save:loadGame()
-	else
-		save:delete()
-	end
-	save:close()
-
-	-- And now run it!
-	_G.game:run()
-end
-
---- Setup write dir for a module
--- Static
-function _M:setupWrite(mod)
-	-- Create module directory
-	fs.setWritePath(engine.homepath)
-	fs.mkdir(mod.short_name)
-	fs.mkdir(mod.short_name.."/save")
-
-	-- Enter module directory
-	local base = engine.homepath .. fs.getPathSeparator() .. mod.short_name
-	fs.setWritePath(base)
-	fs.mount(base, "/", false)
-end
-
---- Get a savefile description from the savefile desc.lua file
-function _M:loadSavefileDescription(dir)
-	local ls_def = loadfile(dir.."/desc.lua")
-	if ls_def then
-		-- Call the file body inside its own private environment
-		local ls = {}
-		setfenv(ls_def, ls)
-		ls_def()
-
-		if not ls.name or not ls.description then return end
-		ls.dir = dir
-		return ls
-	end
-end
-
---- Loads a list of modules from te4.org/modules.lualist
--- Calling this function starts a background thread, which can be waited on by the returned lina object
--- @param src the url to load the list from, if nil it will default to te4.org
--- @return a linda object (see lua lanes documentation) which should be waited upon like this <code>local mylist = l:receive("moduleslist")</code>. Also returns a thread handle
-function _M:loadRemoteList(src)
-	local l = lanes.linda()
-
-	function list_handler(src)
-		local http = require "socket.http"
-		local ltn12 = require "ltn12"
-
-		local t = {}
-		print("Downloading modules list from", src)
-		http.request{url = src, sink = ltn12.sink.table(t)}
-		local f, err = loadstring(table.concat(t))
-		if err then
-			print("Could not load modules list from ", src, ":", err)
-			l:send("moduleslist", {})
-			return
-		end
-
-		local list = {}
-		local dmods = {}
-		dmods.installableModule = function (t)
-			local ok = true
-
-			if not t.name or not t.long_name or not t.short_name or not t.author then ok = false end
-
-			if ok then
-				list[#list+1] = t
-			end
-		end
-		setfenv(f, dmods)
-		local ok, err = pcall(f)
-		if not ok and err then
-			print("Could not read modules list from ", src, ":", err)
-			l:send("moduleslist", {})
-			return
-		end
-
-		for k, e in ipairs(list) do print("[INSTALLABLE MODULE] ", e.name) end
-
-		l:send("moduleslist", list)
-	end
-
-	local h = lanes.gen("*", list_handler)(src or "http://te4.org/modules.lualist")
-	return l, h
-end
diff --git a/game/engine/Mouse.lua b/game/engine/Mouse.lua
deleted file mode 100644
index ae2d854860512c3db98c4288574cfb0b0064a42a..0000000000000000000000000000000000000000
--- a/game/engine/Mouse.lua
+++ /dev/null
@@ -1,81 +0,0 @@
--- 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"
-
---- Basic mousepress handler
--- The engine calls receiveMouse when a mouse is clicked
-module(..., package.seeall, class.make)
-
-function _M:init()
-	self.areas = {}
-	self.status = {}
-end
-
---- Called when a mouse is pressed
--- @param button
--- @param x coordinate of the click
--- @param y coordinate of the click
--- @param isup true if the key was released, false if pressed
-function _M:receiveMouse(button, x, y, isup)
-	self.status[button] = not isup
-	if not isup then return end
-
-	for i, m in ipairs(self.areas) do
-		if (not m.mode or m.mode.button) and (x >= m.x1 and x < m.x2 and y >= m.y1 and y < m.y2) then
-			m.fct(button, x, y, nil, nil, x-m.x1, y-m.y1)
-		end
-	end
-end
-
-function _M:receiveMouseMotion(button, x, y, xrel, yrel)
-	for i, m in ipairs(self.areas) do
-		if (not m.mode or m.mode.move) and (x >= m.x1 and x < m.x2 and y >= m.y1 and y < m.y2) then
-			m.fct(button, x, y, xrel, yrel, x-m.x1, y-m.y1)
-		end
-	end
-end
-
---- Setups as the current game keyhandler
-function _M:setCurrent()
-	core.mouse.set_current_handler(self)
---	if game then game.mouse = self end
-	_M.current = self
-end
-
---- Registers a click zone that when clicked will call the object's "onClick" method
-function _M:registerZone(x, y, w, h, fct, mode)
-	table.insert(self.areas, 1, {x1=x,y1=y,x2=x+w,y2=y+h, fct=fct, mode})
-end
-
-function _M:registerZones(t)
-	for i, z in ipairs(t) do
-		self:registerZone(z.x, z.y, z.w, z.h, z.fct, z.mode)
-	end
-end
-
-function _M:unregisterZone(fct)
-	for i, m in ipairs(self.areas) do
-		if m.fct == fct then table.remove(self.areas, i) break end
-	end
-end
-
-function _M:reset()
-	self.areas = {}
-end
diff --git a/game/engine/NameGenerator.lua b/game/engine/NameGenerator.lua
deleted file mode 100644
index 5214362bd55c598a3db743d963cde68edc995a7f..0000000000000000000000000000000000000000
--- a/game/engine/NameGenerator.lua
+++ /dev/null
@@ -1,89 +0,0 @@
--- 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 lpeg = require "lpeg"
-
-module(..., package.seeall, class.make)
-
-local number = lpeg.R"09" ^ 0
-local rule_pattern = "$" * lpeg.C(number) * lpeg.C(lpeg.S"smePpvc?")
-
---- Creates a random name generator with a set of rules
--- The lang_def parameter is a table that must look like this:<br/>
--- {<br/>
--- 	phonemesVocals = "a, e, i, o, u, y",<br/>
--- 	phonemesConsonants = "b, c, ch, ck, cz, d, dh, f, g, gh, h, j, k, kh, l, m, n, p, ph, q, r, rh, s, sh, t, th, ts, tz, v, w, x, z, zh",<br/>
--- 	syllablesStart = "Aer, Al, Am, An, Ar, Arm, Arth, B, Bal, Bar, Be, Bel, Ber, Bok, Bor, Bran, Breg, Bren, Brod, Cam, Chal, Cham, Ch, Cuth, Dag, Daim, Dair, Del, Dr, Dur, Duv, Ear, Elen, Er, Erel, Erem, Fal, Ful, Gal, G, Get, Gil, Gor, Grin, Gun, H, Hal, Han, Har, Hath, Hett, Hur, Iss, Khel, K, Kor, Lel, Lor, M, Mal, Man, Mard, N, Ol, Radh, Rag, Relg, Rh, Run, Sam, Tarr, T, Tor, Tul, Tur, Ul, Ulf, Unr, Ur, Urth, Yar, Z, Zan, Zer",<br/>
--- 	syllablesMiddle = "de, do, dra, du, duna, ga, go, hara, kaltho, la, latha, le, ma, nari, ra, re, rego, ro, rodda, romi, rui, sa, to, ya, zila",<br/>
--- 	syllablesEnd = "bar, bers, blek, chak, chik, dan, dar, das, dig, dil, din, dir, dor, dur, fang, fast, gar, gas, gen, gorn, grim, gund, had, hek, hell, hir, hor, kan, kath, khad, kor, lach, lar, ldil, ldir, leg, len, lin, mas, mnir, ndil, ndur, neg, nik, ntir, rab, rach, rain, rak, ran, rand, rath, rek, rig, rim, rin, rion, sin, sta, stir, sus, tar, thad, thel, tir, von, vor, yon, zor",<br/>
--- 	rules = "$s$v$35m$10m$e",<br/>
--- }<br/>
--- The rules field defines how names are generated. Any special character found inside (starting with a $, with an optional number and a character) will be
--- replaced by a random word from one of the lists.<br/>
--- $P = syllablesPre<br/>
--- $s = syllablesStart<br/>
--- $m = syllablesMiddle<br/>
--- $e = syllablesEnd<br/>
--- $p = syllablesPost<br/>
--- $v = phonemesVocals<br/>
--- $c = phonemesConsonants<br/>
--- If a number is give it is a percent chance for this part to exist
-function _M:init(lang_def)
-	local def = {}
-	if lang_def.phonemesVocals then def.v = lang_def.phonemesVocals:split(", ") end
-	if lang_def.phonemesConsonants then def.c = lang_def.phonemesConsonants:split(", ") end
-	if lang_def.syllablesPre then def.P = lang_def.syllablesPre:split(", ") end
-	if lang_def.syllablesStart then def.s = lang_def.syllablesStart:split(", ") end
-	if lang_def.syllablesMiddle then def.m = lang_def.syllablesMiddle:split(", ") end
-	if lang_def.syllablesEnd then def.e = lang_def.syllablesEnd:split(", ") end
-	if lang_def.syllablesPost then def.p = lang_def.syllablesPost:split(", ") end
-	if type(lang_def.rules) == "string" then def.rules = {{100, lang_def.rules}} else def = lang_def.rules end
-	self.lang_def = def
-end
-
---- Generates a name
--- @param if not nil this is a generation rule to use instead of a random one
-function _M:generate(rule)
-	while not rule do
-		rule = rng.table(self.lang_def.rules)
-		if rng.percent(rule[1]) then rule = rule[2] end
-	end
-
-	-- Generate the name, using lpeg pattern matching. Lpeg is nice. Love lpeg.
-	local name = rule:lpegSub(rule_pattern, function(chance, type)
-		if not chance or chance == "" or rng.percent(chance) then
-			return rng.table(self.lang_def[type])
-		else
-			return ""
-		end
-	end)
-
-	-- Check for double spaces
-	name = name:lpegSub("  ", " ")
-
-	-- Prunes repetitions
-	-- Those do tail calls in case of bad names
-	for i = 1, #name do
-		if name:sub(i, i+1) == name:sub(i+2, i+3) then return self:generate() end
-		if name:sub(i, i+2) == name:sub(i+3, i+4) then return self:generate() end
-	end
-
-	return name
-end
diff --git a/game/engine/Object.lua b/game/engine/Object.lua
deleted file mode 100644
index b82c591b3ec0a65689dab9895af3a42b91645733..0000000000000000000000000000000000000000
--- a/game/engine/Object.lua
+++ /dev/null
@@ -1,197 +0,0 @@
--- 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 Entity = require "engine.Entity"
-
-module(..., package.seeall, class.inherit(Entity))
-
-_M.display_on_seen = true
-_M.display_on_remember = true
-_M.display_on_unknown = false
-
-function _M:init(t, no_default)
-	t = t or {}
-
-	self.energy = t.energy or { value=0, mod=1 }
-	self.energy.value = self.energy.value or 0
-	self.energy.mod = self.energy.mod or 0
-
-	Entity.init(self, t, no_default)
-end
-
---- Resolves the object
--- This will call the entities resolver and then add to the game entities list
-function _M:resolve(t, last, on_entity)
-	engine.Entity.resolve(self, t, last, on_entity)
-
-	if not t and last then
-		-- Stackable property is the name by default
-		if self.stacking and type(self.stacking) == "boolean" then
-			self.stacking = self:getName{no_count=true, force_id=true}
-		end
-
-		-- Auto add all objects to the game, if they can act
-		game:addEntity(self)
-	end
-end
-
---- Can this object act at all
--- Most object will want to anwser false, only recharging and stuff needs them
-function _M:canAct()
-	return false
-end
-
---- Do something when its your turn
--- For objects this mostly is to recharge them
--- By default, does nothing at all
-function _M:act()
-end
-
---- Gets the color in which to display the object in lists
-function _M:getDisplayColor()
-	return {255,255,255}
-end
-
---- Gets the full name of the object
-function _M:getName(t)
-	t = t or {}
-	local qty = self:getNumber()
-	local name = self.name
-
-	if qty == 1 or t.no_count then return name
-	else return qty.." "..name
-	end
-end
-
---- Gets the full desc of the object
-function _M:getDesc()
-	return self.name
-end
-
---- Returns the inventory type an object is worn on
-function _M:wornInven()
-	if not self.slot then return nil end
-	local invens = require "engine.interface.ActorInventory"
-	return invens["INVEN_"..self.slot]
-end
-
---- Do we have enough energy
-function _M:enoughEnergy(val)
-	val = val or game.energy_to_act
-	return self.energy.value >= val
-end
-
---- Use some energy
-function _M:useEnergy(val)
-	val = val or game.energy_to_act
-	self.energy.value = self.energy.value - val
-end
-
---- Stackable, can it stack at all ?
-function _M:stackable()
-	return self.stacking
-end
-
---- Can it stacks with others of its kind ?
-function _M:canStack(o)
-	if not self.stacking or not o.stacking then return false end
-	if  self.stacking == o.stacking then return true end
-	return false
-end
-
---- Adds object to the stack
--- @return true if stacking worked, false if not
-function _M:stack(o)
-	if not self:canStack(o) then return false end
-	self.stacked = self.stacked or {}
-	self.stacked[#self.stacked+1] = o
-
-	-- Merge stacks
-	if o.stacked then
-		for i = 1, #o.stacked do
-			self.stacked[#self.stacked+1] = o.stacked[i]
-		end
-		o.stacked = nil
-	end
-	return true
-end
-
---- Removes an object of the stack
--- @return object, true if the last, or object, false if more
-function _M:unstack()
-	if not self:stackable() or not self.stacked or #self.stacked == 0 then return self, true end
-	local o = table.remove(self.stacked)
-	if #self.stacked == 0 then self.stacked = nil end
-	return o, false
-end
-
---- Applies a function to all items of the stack
-function _M:forAllStack(fct)
-	fct(self)
-	if not self.stacked then return end
-	for i, so in ipairs(self.stacked) do
-		if fct(so, i) then break end
-	end
-end
-
---- Returns the number of objects available
--- Always one for non stacking objects
-function _M:getNumber()
-	if not self.stacked then return 1 end
-	return 1 + #self.stacked
-end
-
---- Sorting by type function
--- By default, sort by type name
-function _M:getTypeOrder()
-	return self.type or ""
-end
-
---- Sorting by type function
--- By default, sort by subtype name
-function _M:getSubtypeOrder()
-	return self.subtype or ""
-end
-
---- Describe requirements
-function _M:getRequirementDesc(who)
-	local req = rawget(self, "require")
-	if not req then return nil end
-
-	local str = "Requires:\n"
-
-	if req.stat then
-		for s, v in pairs(req.stat) do
-			local c = (who:getStat(s) >= v) and "#00ff00#" or "#ff0000#"
-			str = str .. ("- %s%s %d\n"):format(c, who.stats_def[s].name, v)
-		end
-	end
-	if req.level then
-		local c = (who.level >= req.level) and "#00ff00#" or "#ff0000#"
-		str = str .. ("- %sLevel %d\n"):format(c, req.level)
-	end
-	if req.talent then
-		for _, tid in ipairs(req.talent) do
-			local c = who:knowTalent(tid) and "#00ff00#" or "#ff0000#"
-			str = str .. ("- %sTalent %s\n"):format(c, who:getTalentFromId(tid).name)
-		end
-	end
-	return str
-end
diff --git a/game/engine/Particles.lua b/game/engine/Particles.lua
deleted file mode 100644
index 3aa4718a6ab5eb8934fa88bfe241f40cdab85f98..0000000000000000000000000000000000000000
--- a/game/engine/Particles.lua
+++ /dev/null
@@ -1,74 +0,0 @@
--- 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"
-
---- Handles a particles system
--- Used by engine.Map
-module(..., package.seeall, class.make)
-
-_M.particles_def = {}
-
-_M.__particles_gl = { particle = core.display.loadImage("/data/gfx/particle.png"):glTexture() }
-
---- Make a particle emiter
-function _M:init(def, radius, args)
-	self.args = args
-	self.def = def
-	self.radius = radius or 1
-
-	self:loaded()
-end
-
---- Serialization
-function _M:save()
-	return class.save(self, {
-		ps = true,
-	})
-end
-
-function _M:cloned()
-	self:loaded()
-end
-
-function _M:loaded()
-	local def, fct, max, gl
-	if type(self.def) == "string" then
-		if _M.particles_def[self.def] then
-			setfenv(_M.particles_def[self.def], setmetatable(self.args or {}, {__index=_G}))
-			def, fct, max, gl = _M.particles_def[self.def]()
-		else
-			local odef = self.def
-			print("[PARTICLE] Loading from /data/gfx/particles/"..self.def..".lua")
-			local f, err = loadfile("/data/gfx/particles/"..self.def..".lua")
-			if not f and err then error(err) end
-			setfenv(f, setmetatable(self.args or {}, {__index=_G}))
-			def, fct, max, gl = f()
-			_M.particles_def[odef] = f
-		end
-	else error("unsupported particle type: "..type(self.def))
-	end
-
-	gl = gl or "particle"
-	if not self.__particles_gl[gl] then self.__particles_gl[gl] = core.display.loadImage("/data/gfx/"..gl..".png"):glTexture() end
-	gl = self.__particles_gl[gl]
-
-	self.update = fct
-	self.ps = core.particles.newEmitter(max or 1000, def, gl)
-end
diff --git a/game/engine/PlayerProfile.lua b/game/engine/PlayerProfile.lua
deleted file mode 100644
index 9e3fdc73acaa65e0283f64020173c15f39f91ae3..0000000000000000000000000000000000000000
--- a/game/engine/PlayerProfile.lua
+++ /dev/null
@@ -1,322 +0,0 @@
--- 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 http = require "socket.http"
-local url = require "socket.url"
-local ltn12 = require "ltn12"
-local lanes = require "lanes"
-require "Json2"
-
-------------------------------------------------------------
--- some simple serialization stuff
-------------------------------------------------------------
-local function basicSerialize(o)
-	if type(o) == "number" or type(o) == "boolean" then
-		return tostring(o)
-	elseif type(o) == "function" then
-		return string.format("loadstring(%q)", string.dump(o))
-	else   -- assume it is a string
-		return string.format("%q", o)
-	end
-end
-
-local function serialize_data(outf, name, value, saved, filter, allow, savefile, force)
-	saved = saved or {}       -- initial value
-	outf(name, " = ")
-	if type(value) == "number" or type(value) == "string" or type(value) == "boolean" or type(value) == "function" then
-		outf(basicSerialize(value), "\n")
-	elseif type(value) == "table" then
-			saved[value] = name   -- save name for next time
-			outf("{}\n")     -- create a new table
-
-			for k,v in pairs(value) do      -- save its fields
-				local fieldname
-				fieldname = string.format("%s[%s]", name, basicSerialize(k))
-				serialize_data(outf, fieldname, v, saved, {new=true}, false, savefile, false)
-			end
-	else
-		error("cannot save a " .. type(value) .. " ("..name..")")
-	end
-end
-
-local function serialize(data)
-	local tbl = {}
-	local outf = function(...) for i,str in ipairs{...} do table.insert(tbl, str) end end
-	for k, e in pairs(data) do
-		serialize_data(outf, tostring(k), e)
-	end
-	return table.concat(tbl)
-end
-------------------------------------------------------------
-
-
---- Handles the player profile, possibly online
-module(..., package.seeall, class.make)
-
-function _M:init(name)
-	self.generic = {}
-	self.modules = {}
-	self.name = name or "default"
-	self:loadGenericProfile()
-
-	self.auth = false
-
-	if self.generic.online and self.generic.online.login and self.generic.online.pass then
-		self.login = self.generic.online.login
-		self.pass = self.generic.online.pass
-		self:tryAuth()
-		self:getConfigs("generic")
-		self:syncOnline("generic")
-	end
-end
-
-function _M:loadData(f, where)
-	setfenv(f, where)
-	local ok, err = pcall(f)
-	if not ok and err then error(err) end
-end
-
---- Loads profile generic profile from disk
-function _M:loadGenericProfile()
-	local d = "/profiles/"..self.name.."/generic/"
-	fs.mount(engine.homepath, "/")
-	for i, file in ipairs(fs.list(d)) do
-
-		if file:find(".profile$") then
-			local f, err = loadfile(d..file)
-			if not f and err then error(err) end
-			local field = file:gsub(".profile$", "")
-			self.generic[field] = self.generic[field] or {}
-			self:loadData(f, self.generic[field])
-			if not self.generic[field].__uuid then self.generic[field].__uuid = util.uuid() end
-		end
-	end
-
-	fs.umount(engine.homepath)
-end
-
---- Loads profile module profile from disk
-function _M:loadModuleProfile(short_name)
-	local d = "/profiles/"..self.name.."/modules/"..short_name.."/"
-	fs.mount(engine.homepath, "/")
-	print("[Module Profile] ", engine.homepath.."/"..d)
-	self.modules[short_name] = self.modules[short_name] or {}
-	for i, file in ipairs(fs.list(d)) do
-		if file:find(".profile$") then
-			local f, err = loadfile(d..file)
-			if not f and err then error(err) end
-			local field = file:gsub(".profile$", "")
-			self.modules[short_name][field] = self.modules[short_name][field] or {}
-			self:loadData(f, self.modules[short_name][field])
-			if not self.modules[short_name][field].__uuid then self.modules[short_name][field].__uuid = util.uuid() end
-		end
-	end
-
-	fs.umount(engine.homepath)
-
-	self:getConfigs(short_name)
-	self:syncOnline(short_name)
-
-	self.mod = self.modules[short_name]
-	self.mod_name = short_name
-end
-
---- Saves a profile data
-function _M:saveGenericProfile(name, data, nosync)
-	data = serialize(data)
-
-	-- Check for readability
-	local f, err = loadstring(data)
-	setfenv(f, {})
-	if not f then print("[PROFILES] cannot save generic data ", name, data, "it does not parse:") error(err) end
-	local ok, err = pcall(f)
-	if not ok and err then print("[PROFILES] cannot save generic data", name, data, "it does not parse") error(err) end
-
-	local restore = fs.getWritePath()
-	fs.setWritePath(engine.homepath)
-	fs.mkdir("/profiles/"..self.name.."/generic/")
-	local f = fs.open("/profiles/"..self.name.."/generic/"..name..".profile", "w")
-	f:write(data)
-	f:close()
-	if restore then fs.setWritePath(restore) end
-
-	if not nosync then self:setConfigs("generic", name, data) end
-end
-
---- Saves a module profile data
-function _M:saveModuleProfile(name, data, module, nosync)
-	data = serialize(data)
-	module = module or self.mod_name
-
-	-- Check for readability
-	local f, err = loadstring(data)
-	setfenv(f, {})
-	if not f then print("[PROFILES] cannot save module data ", name, data, "it does not parse:") error(err) end
-	local ok, err = pcall(f)
-	if not ok and err then print("[PROFILES] cannot save module data", name, data, "it does not parse") error(err) end
-
-	local restore = fs.getWritePath()
-	fs.setWritePath(engine.homepath)
-	fs.mkdir("/profiles/"..self.name.."/modules/")
-	fs.mkdir("/profiles/"..self.name.."/modules/"..module.."/")
-	local f = fs.open("/profiles/"..self.name.."/modules/"..module.."/"..name..".profile", "w")
-	f:write(data)
-	f:close()
-	if restore then fs.setWritePath(restore) end
-
-	if not nosync then self:setConfigs(module, name, data) end
-end
-
-
------------------------------------------------------------------------
--- Online stuff
------------------------------------------------------------------------
-
-function _M:rpc(data)
-	-- We can work in asynchronous mode, to not delay the main game execution
-	if data.async and game and type(game) == "table" and not game.refuse_threads then
-		data.async = nil
-		local l = lanes.linda()
-
-		function handler(data)
-			local http = require "socket.http"
-			local url = require "socket.url"
-			require "Json2"
-
-			print("[ONLINE PROFILE] async rpc called", "http://te4.org/lua/profilesrpc.ws/"..data.action)
-			local body, status = http.request("http://te4.org/lua/profilesrpc.ws/"..data.action, "json="..url.escape(json.encode(data)))
-			if not body then l:send("final", nil)
-			else l:send("final", json.decode(body))
-			end
-			return true
-		end
-
-		local th = lanes.gen("*", handler)(data)
-		-- Tell the game to monitor this thread and end it when it's done
-		game:registerThread(th, l)
-	else
-		print("[ONLINE PROFILE] rpc called", "http://te4.org/lua/profilesrpc.ws/"..data.action)
-		local body, status = http.request("http://te4.org/lua/profilesrpc.ws/"..data.action, "json="..url.escape(json.encode(data)))
-		if not body then return end
-		return json.decode(body)
-	end
-end
-
-function _M:getNews()
-	print("[ONLINE PROFILE] get news")
-	local data = self:rpc{action="GetNews"}
-	if not data then print("[ONLINE PROFILE] no news") return end
-	print("[ONLINE PROFILE] news ", data.title)
-	return data
-end
-
-function _M:tryAuth()
-	print("[ONLINE PROFILE] auth")
-	local data = self:rpc{action="TryAuth", login=self.login, pass=self.pass}
-	if not data then print("[ONLINE PROFILE] not auth") return end
-	print("[ONLINE PROFILE] auth as ", data.name, data.hash)
-	self.auth = data
-end
-
-function _M:getConfigs(module)
-	if not self.auth then return end
-	local data = self:rpc{action="GetConfigs", login=self.login, hash=self.auth.hash, module=module}
-	if not data then print("[ONLINE PROFILE] get configs") return end
-	for name, val in pairs(data) do
-		print("[ONLINE PROFILE] config ", name)
-
-		local field = name
-		local f, err = loadstring(val)
-		if not f and err then error(err) end
-		if module == "generic" then
-			self.generic[field] = self.generic[field] or {}
-			self:loadData(f, self.generic[field])
-			self:saveGenericProfile(field, self.generic[field], true)
-		else
-			self.modules[module] = self.modules[module] or {}
-			self.modules[module][field] = self.modules[module][field] or {}
-			self:loadData(f, self.modules[module][field])
-			self:saveModuleProfile(field, self.modules[module][field], module, true)
-		end
-	end
-end
-
-function _M:setConfigs(module, name, val)
-	if not self.auth then return end
-	if name == "online" then return end
-
-	if type(val) ~= "string" then val = serialize(val) end
-
-	local data = self:rpc{async=true, action="SetConfigs", login=self.login, hash=self.auth.hash, module=module, data={[name] = val}}
-	if not data then return end
-	print("[ONLINE PROFILE] saved ", module, name, val)
-end
-
-function _M:syncOnline(module)
-	if not self.auth then return end
-	local sync = self.generic
-	if module ~= "generic" then sync = self.modules[module] end
-	if not sync then return end
-
-	local data = {}
-	for k, v in pairs(sync) do if k ~= "online" then data[k] = serialize(v) end end
-
-	local data = self:rpc{async=true, action="SetConfigs", login=self.login, hash=self.auth.hash, module=module, data=data}
-	if not data then return end
-	print("[ONLINE PROFILE] saved ", module)
-end
-
-function _M:newProfile(Login, Name, Password, Email)
-	print("[ONLINE PROFILE] profile options ", Login, Email, Name, Password)
-	local data = self:rpc{action="NewProfile", login=Login, email=Email, name=Name, pass=Password}
-	if not data then print("[ONLINE PROFILE] could not create") return end
-	print("[ONLINE PROFILE] profile id ", data.id)
-	self:performlogin(Login, Password, Name, Email)
-end
-
-function _M:performlogin(login, pass, name, email)
-	self.login=login
-	self.pass=pass
-	print("[ONLINE PROFILE] attempting log in ", self.login, self.pass)
-	self:tryAuth()
-	if (profile.auth) then
-		self.generic.online = { login=login, pass=pass,name=name or "", email=email or "" }
-		self:saveGenericProfile("online", self.generic.online)
-		self:getConfigs("generic")
-		self:syncOnline("generic")
-	end
-end
-
-function _M:logOut()
-	profile.generic.online = nil
-	profile.auth = nil
-	local d = "/profiles/"..self.name.."/generic/"
-	fs.mount(engine.homepath, "/")
-	fs.delete(d.."online.profile")
-end
-
-function _M:checkFirstRun()
-	local result = self.generic.firstrun
-	if not result then
-		firstrun = { When=os.time() }
-		self:saveGenericProfile("firstrun", firstrun, false)
-	end
-	return result
-end
diff --git a/game/engine/Projectile.lua b/game/engine/Projectile.lua
deleted file mode 100644
index 6424ef603846ea212e91507f9d10f1183255f1c6..0000000000000000000000000000000000000000
--- a/game/engine/Projectile.lua
+++ /dev/null
@@ -1,187 +0,0 @@
--- 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 Entity = require "engine.Entity"
-local Particles = require "engine.Particles"
-local Map = require "engine.Map"
-
-module(..., package.seeall, class.inherit(Entity))
-
-_M.display_on_seen = true
-_M.display_on_remember = false
-_M.display_on_unknown = false
-
-function _M:init(t, no_default)
-	t = t or {}
-	self.name = t.name or "projectile"
-	self.energy = t.energy or { value=game.energy_to_act, mod=2 }
-	self.energy.value = self.energy.value or game.energy_to_act
-	self.energy.mod = self.energy.mod or 10
-	Entity.init(self, t, no_default)
-end
-
---- Adds a particles emitter following the actor
-function _M:addParticles(ps)
-	self.__particles[ps] = true
-	if self.x and self.y and game.level and game.level.map then
-		ps.x = self.x
-		ps.y = self.y
-		game.level.map:addParticleEmitter(ps)
-	end
-	return ps
-end
-
---- Removes a particles emitter following the actor
-function _M:removeParticles(ps)
-	self.__particles[ps] = nil
-	if self.x and self.y and game.level and game.level.map then
-		ps.x = nil
-		ps.y = nil
-		game.level.map:removeParticleEmitter(ps)
-	end
-end
-
---- Moves an actor on the map
--- *WARNING*: changing x and y properties manualy is *WRONG* and will blow up in your face. Use this method. Always.
--- @param map the map to move onto
--- @param x coord of the destination
--- @param y coord of the destination
--- @param force if true do not check for the presence of an other entity. *Use wisely*
--- @return true if a move was *ATTEMPTED*. This means the actor will proably want to use energy
-function _M:move(x, y, force)
-	if self.dead then return true end
-	local map = game.level.map
-
-	if x < 0 then x = 0 end
-	if x >= map.w then x = map.w - 1 end
-	if y < 0 then y = 0 end
-	if y >= map.h then y = map.h - 1 end
-
-	if self.x and self.y then
-		map:remove(self.x, self.y, Map.PROJECTILE)
-	else
---		print("[MOVE] projectile moved without a starting position", self.name, x, y)
-	end
-	self.old_x, self.old_y = self.x or x, self.y or y
-	self.x, self.y = x, y
-	map(x, y, Map.PROJECTILE, self)
-
-	if self.travel_particle then
-		self:addParticles(Particles.new(self.travel_particle, 1, nil))
-		self.travel_particle = nil
-	end
-
-	-- Update particle emitters attached to that actor
-	local del = {}
-	for e, _ in pairs(self.__particles) do
-		if e.dead then del[#del+1] = e
-		else
-			e.x = x
-			e.y = y
-			map.particles[e] = true
-		end
-	end
-	for i = 1, #del do self.particles[del[i] ] = nil end
-
-	self:useEnergy()
-
-	return true
-end
-
-function _M:deleteFromMap(map)
-	if self.x and self.y and map then
-		map:remove(self.x, self.y, engine.Map.PROJECTILE)
-		for e, _ in pairs(self.__particles) do
-			e.x = nil
-			e.y = nil
-			map:removeParticleEmitter(e)
-		end
-	end
-end
-
---- Do we have enough energy
-function _M:enoughEnergy(val)
-	val = val or game.energy_to_act
-	return self.energy.value >= val
-end
-
---- Use some energy
-function _M:useEnergy(val)
-	val = val or game.energy_to_act
-	self.energy.value = self.energy.value - val
-	self.energy.used = true
-end
-
-function _M:tooltip()
-	return "Projectile: "..self.name
-end
-
-
---- Called by the engine when the projectile can move
-function _M:act()
-	if self.dead then return false end
-
-	while self:enoughEnergy() and not self.dead do
-		if self.project then
-			local x, y, act, stop = self.src:projectDoMove(self.project.def.typ, self.project.def.x, self.project.def.y, self.x, self.y, self.project.def.start_x, self.project.def.start_y)
-			if x and y then self:move(x, y) end
-			if act then self.src:projectDoAct(self.project.def.typ, self.project.def.tg, self.project.def.damtype, self.project.def.dam, self.project.def.particles, self.x, self.y, self.tmp_proj) end
-			if stop then
-				self.src:projectDoStop(self.project.def.typ, self.project.def.tg, self.project.def.damtype, self.project.def.dam, self.project.def.particles, self.x, self.y, self.tmp_proj)
-				game.level:removeEntity(self)
-				self.dead = true
-			end
-		end
-	end
-
-	return true
-end
-
---- Something moved in the same spot as us, hit ?
-function _M:on_move(x, y, target)
-	if self.project and self.project.def.typ.stop_block then
-		self.src:projectDoStop(self.project.def.typ, self.project.def.tg, self.project.def.damtype, self.project.def.dam, self.project.def.particles, self.x, self.y, self.tmp_proj)
-		game.level:removeEntity(self)
-		self.dead = true
-	end
-end
-
---- Generate a projectile for a project() call
-function _M:makeProject(src, display, def, do_move, do_act, do_stop)
-	display = display or {display='*'}
-	local speed = def.tg.speed
-	local name = def.tg.name
-	if def.tg.talent then
-		speed = src:getTalentProjectileSpeed(def.tg.talent)
-		name = def.tg.talent.name
-		def.tg.talent_id = def.tg.talent.id
-		def.tg.talent = nil
-	end
-	return _M.new{
-		name = name,
-		display = display.display or ' ', color = display.color or colors.WHITE, image = display.image or nil,
-		travel_particle = display.particle,
-		src = src,
-		src_x = src.x, src_y = src.y,
-		project = {def=def},
-		energy = {mod=speed or 10},
-		tmp_proj = {},
-	}
-end
diff --git a/game/engine/Quest.lua b/game/engine/Quest.lua
deleted file mode 100644
index 7f300d611e88827720a022ee7e6e96ce497e55ec..0000000000000000000000000000000000000000
--- a/game/engine/Quest.lua
+++ /dev/null
@@ -1,91 +0,0 @@
--- 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"
-
---- Handle quests
-module(..., package.seeall, class.make)
-
-PENDING = 0
-COMPLETED = 1
-DONE = 100
-FAILED = 101
-
-function _M:init(q, who)
-	for k, e in pairs(q) do
-		self[k] = e
-	end
-	self.status = PENDING
-	self.objectives = {}
-	self:check("on_grant", who)
-end
-
---- Checks if the quest (or sub-objective) is complete
--- @param sub a subobjective id or nil for the whole quest
--- @return true or false
-function _M:isCompleted(sub)
-	if sub then
-		if self.objectives[sub] and self.objectives[sub] == COMPLETED then return true else return false end
-	end
-	if self.status == COMPLETED then return true else return false end
-end
-
---- Checks if the quest is ended (DONE or FAILED)
--- @return true or false
-function _M:isEnded()
-	if self.status == DONE or self.status == FAILED then return true else return false end
-end
-
---- Check for an quest property
--- If not a function it returns it directly, otherwise it calls the function
--- with the extra parameters
--- @param prop the property name to check
-function _M:check(prop, ...)
-	if type(self[prop]) == "function" then return self[prop](self, ...)
-	else return self[prop]
-	end
-end
-
---- Sets the quests status or sub-objective status
--- @param status one of the possible quest status (PENDING, COMPLETED, DONE, FAILED)
-function _M:setStatus(status, sub, who)
-	if sub then
-		if self.objectives[sub] and self.objectives[sub] == status then return false end
-		self.objectives[sub] = status
-		self:check("on_status_change", who, status, sub)
-		return true
-	else
-		if self.status == status then return false end
-		self.status = status
-		self:check("on_status_change", who, status)
-		return true
-	end
-end
-
---- Checks the quests status or sub-objective status
--- @param status one of the possible quest status (PENDING, COMPLETED, DONE, FAILED)
-function _M:isStatus(status, sub)
-	if sub then
-		if self.objectives[sub] and self.objectives[sub] == status then return true end
-		return false
-	else
-		if self.status == status then return true end
-		return false
-	end
-end
diff --git a/game/engine/Savefile.lua b/game/engine/Savefile.lua
deleted file mode 100644
index bcb5e956cb336dca3360644a7c0102857a22c59d..0000000000000000000000000000000000000000
--- a/game/engine/Savefile.lua
+++ /dev/null
@@ -1,337 +0,0 @@
--- 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 Dialog = require "engine.Dialog"
-
---- Savefile code
--- T-Engine4 savefiles are direct serialization of in game objects<br/>
--- Basically the engine is told to save your Game instance and then it will
--- recursively save all that it contains: level, map, entities, your own objects, ...<br/>
--- The savefile structure is a zip file that contains one file per object to be saved. Unzip one, it is quite obvious<br/>
--- A simple object (that does not do anything too fancy in its constructor) will save/load without anything
--- to code, it's magic!<br/>
--- For more complex objects, look at the methods save() and loaded() in objects that have them
-module(..., package.seeall, class.make)
-
-_M.current_save = false
-
---- Init a savefile
--- @param savefile the name of the savefile, usually the player's name. It will be sanitized so dont bother doing it
-function _M:init(savefile)
-	self.short_name = savefile:gsub("[^a-zA-Z0-9_-.]", "_")
-	self.save_dir = "/save/"..self.short_name.."/"
-	self.quickbirth_file = "/save/"..self.short_name..".quickbirth"
-	self.load_dir = "/tmp/loadsave/"
-
-	self.tables = {}
-	self.process = {}
-	self.loaded = {}
-	self.delayLoad = {}
-	_M.current_save = self
-end
-
---- Finishes up a savefile
--- Always call it once done
-function _M:close()
-	self.tables = nil
-	self.process = nil
-	self.loaded = nil
-	self.delayLoad = nil
-	self.current_save_main = nil
-end
-
---- Delete the savefile, if needed
-function _M:delete()
-	for i, f in ipairs(fs.list(self.save_dir)) do
-		fs.delete(self.save_dir..f)
-	end
-	fs.delete(self.save_dir)
-end
-
-function _M:addToProcess(o)
-	if not self.tables[o] then
-		table.insert(self.process, o)
-		self.tables[o] = true
-	end
-end
-
-function _M:addDelayLoad(o)
---	print("add delayed", _M, "::", self, #self.delayLoad, o)
-	table.insert(self.delayLoad, 1, o)
-end
-
-function _M:getFileName(o)
-	if o == self.current_save_main then
-		return "main"
-	else
-		return o.__CLASSNAME.."-"..tostring(o):sub(8)
-	end
-end
-
-function _M:saveObject(obj, zip)
-	self.current_save_main = obj
-	self:addToProcess(obj)
-	while #self.process > 0 do
-		local tbl = table.remove(self.process)
-		self.tables[tbl] = self:getFileName(tbl)
-		zip:add(self:getFileName(tbl), tbl:save())
-	end
-	return self.tables[obj]
-end
-
---- Save the given world
-function _M:saveWorld(world)
-	collectgarbage("collect")
-
-	fs.mkdir(self.save_dir)
-
-	local popup = Dialog:simplePopup("Saving world", "Please wait while saving the world...")
-	popup.__showup = nil
-	core.display.forceRedraw()
-
-	local zip = fs.zipOpen(self.save_dir.."world.teaw")
-	self:saveObject(world, zip)
-	zip:close()
-
-	game:unregisterDialog(popup)
-end
-
---- Save the given birth descriptors, used for quick start
-function _M:saveQuickBirth(descriptor)
-	collectgarbage("collect")
-
-	local f = fs.open(self.quickbirth_file, "w")
-	for k, e in pairs(descriptor) do
-		f:write(("%s = %q\n"):format(tostring(k), tostring(e)))
-	end
-	f:close()
-end
-
---- Load the given birth descriptors, used for quick start
-function _M:loadQuickBirth()
-	collectgarbage("collect")
-
-	local f = loadfile(self.quickbirth_file)
-	print("[QUICK BIRTH]", f)
-	if f then
-		-- Call the file body inside its own private environment
-		local def = {}
-		setfenv(f, def)
-		if pcall(f) then
-			return def
-		end
-	end
-	return nil
-end
-
---- Save the given game
-function _M:saveGame(game)
-	collectgarbage("collect")
-
-	fs.mkdir(self.save_dir)
-
-	local popup = Dialog:simplePopup("Saving game", "Please wait while saving the game...")
-	popup.__showup = nil
-	core.display.forceRedraw()
-
-	local zip = fs.zipOpen(self.save_dir.."game.teag")
-	self:saveObject(game, zip)
-	zip:close()
-
-	local desc = game:getSaveDescription()
-	local f = fs.open(self.save_dir.."desc.lua", "w")
-	f:write(("name = %q\n"):format(desc.name))
-	f:write(("short_name = %q\n"):format(self.short_name))
-	f:write(("description = %q\n"):format(desc.description))
-	f:close()
-
-	game:unregisterDialog(popup)
-end
-
---- Save a zone
-function _M:saveZone(zone)
-	fs.mkdir(self.save_dir)
-
-	local popup = Dialog:simplePopup("Saving zone", "Please wait while saving the zone...")
-	popup.__showup = nil
-	core.display.forceRedraw()
-
-	local zip = fs.zipOpen(self.save_dir..("zone-%s.teaz"):format(zone.short_name))
-	self:saveObject(zone, zip)
-	zip:close()
-
-	game:unregisterDialog(popup)
-end
-
---- Save a level
-function _M:saveLevel(level)
-	fs.mkdir(self.save_dir)
-
-	local popup = Dialog:simplePopup("Saving level", "Please wait while saving the level...")
-	popup.__showup = nil
-	core.display.forceRedraw()
-
-	local zip = fs.zipOpen(self.save_dir..("level-%s-%d.teal"):format(level.data.short_name, level.level))
-	self:saveObject(level, zip)
-	zip:close()
-
-	game:unregisterDialog(popup)
-end
-
-local function resolveSelf(o, base, allow_object)
-	if o.__CLASSNAME and not allow_object then return end
-
-	local change = {}
-	for k, e in pairs(o) do
-		if type(e) == "table" then
-			if e == class.LOAD_SELF then change[#change+1] = k
-			else resolveSelf(e, base, false)
-			end
-		end
-	end
-	for i, k in ipairs(change) do o[k] = base end
-end
-
-function _M:loadReal(load)
-	if self.loaded[load] then return self.loaded[load] end
-	local f = fs.open(self.load_dir..load, "r")
---	print("loading", load)
-	local lines = {}
-	while true do
-		local l = f:read()
-		if not l then break end
-		lines[#lines+1] = l
-	end
-	f:close()
-	local o = class.load(table.concat(lines), load)
-
-	-- Resolve self referencing tables now
-	resolveSelf(o, o, true)
-
-	self.loaded[load] = o
-	return o
-end
-
---- Loads a world
-function _M:loadWorld()
-	local path = fs.getRealPath(self.save_dir.."world.teaw")
-	if not path or path == "" then return nil, "no savefile" end
-
-	fs.mount(path, self.load_dir)
-
-	local popup = Dialog:simplePopup("Loading world", "Please wait while loading the world...")
-	popup.__showup = nil
-	core.display.forceRedraw()
-
-	local loadedWorld = self:loadReal("main")
-
-	-- Delay loaded must run
-	for i, o in ipairs(self.delayLoad) do
---		print("loader executed for class", o, o.__CLASSNAME)
-		o:loaded()
-	end
-
-	fs.umount(path)
-
-	game:unregisterDialog(popup)
-
-	return loadedWorld
-end
-
---- Loads a game
-function _M:loadGame()
-	local path = fs.getRealPath(self.save_dir.."game.teag")
-	if not path or path == "" then return nil, "no savefile" end
-
-	fs.mount(path, self.load_dir)
-
-	local popup = Dialog:simplePopup("Loading game", "Please wait while loading the game...")
-	popup.__showup = nil
-	core.display.forceRedraw()
-
-	local loadedGame = self:loadReal("main")
-
-	-- Delay loaded must run
-	for i, o in ipairs(self.delayLoad) do
---		print("loader executed for class", o, o.__CLASSNAME)
-		o:loaded()
-	end
-
-	fs.umount(path)
-
-	game:unregisterDialog(popup)
-
-	return loadedGame
-end
-
---- Loads a zone
-function _M:loadZone(zone)
-	local path = fs.getRealPath(self.save_dir..("zone-%s.teaz"):format(zone))
-	if not path or path == "" then return false end
-
-	fs.mount(path, self.load_dir)
-
-	local popup = Dialog:simplePopup("Loading zone", "Please wait while loading the zone...")
-	popup.__showup = nil
-	core.display.forceRedraw()
-
-	local loadedZone = self:loadReal("main")
-
-	-- Delay loaded must run
-	for i, o in ipairs(self.delayLoad) do
---		print("loader executed for class", o, o.__CLASSNAME)
-		o:loaded()
-	end
-
-	game:unregisterDialog(popup)
-
-	fs.umount(path)
-	return loadedZone
-end
-
---- Loads a level
-function _M:loadLevel(zone, level)
-	local path = fs.getRealPath(self.save_dir..("level-%s-%d.teal"):format(zone, level))
-	if not path or path == "" then return false end
-
-	fs.mount(path, self.load_dir)
-
-	local popup = Dialog:simplePopup("Loading level", "Please wait while loading the level...")
-	popup.__showup = nil
-	core.display.forceRedraw()
-
-	local loadedLevel = self:loadReal("main")
-
-	-- Delay loaded must run
-	for i, o in ipairs(self.delayLoad) do
---		print("loader executed for class", o, o.__CLASSNAME)
-		o:loaded()
-	end
-
-	game:unregisterDialog(popup)
-
-	fs.umount(path)
-	return loadedLevel
-end
-
---- Checks for existence
-function _M:check()
-	return fs.exists(self.save_dir.."game.teag")
-end
diff --git a/game/engine/Shader.lua b/game/engine/Shader.lua
deleted file mode 100644
index 4ca66b1b07da767784cae1c307c4a403ca60574d..0000000000000000000000000000000000000000
--- a/game/engine/Shader.lua
+++ /dev/null
@@ -1,149 +0,0 @@
--- 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"
-
---- Handles a particles system
--- Used by engine.Map
-module(..., package.seeall, class.make)
-
-_M.verts = {}
-_M.frags = {}
-_M.progs = {}
-
---- Make a shader
-function _M:init(name, args)
-	self.args = args or {}
-	self.name = name
-	self.totalname = self:makeTotalName()
-	print("[SHADER] making shader from", name, " into ", self.totalname)
-
-	if core.shader.active() then self:loaded() end
-end
-
-function _M:makeTotalName()
-	local str = {}
-	for k, v in pairs(self.args) do
-		if type(v) == "number" then
-			str[#str+1] = v
-		elseif type(v) == "table" then
-			if v.texture then
-				if v.is3d then str[#str+1] = k.."=tex3d("..v.texture..")"
-				else str[#str+1] = k.."=tex3d("..v.texture..")" end
-			elseif #v == 2 then
-				str[#str+1] = k.."=vec2("..v[1]..","..v[2]..")"
-			elseif #v == 3 then
-				str[#str+1] = k.."=vec3("..v[1]..","..v[2]..","..v[3]..")"
-			elseif #v == 4 then
-				str[#str+1] = k.."=vec4("..v[1]..","..v[2]..","..v[3]..","..v[4]..")"
-			end
-		end
-	end
-	return self.name.."["..table.concat(str,",").."]"
-end
-
---- Serialization
-function _M:save()
-	return class.save(self, {
-		shad = true,
-	})
-end
-
-function _M:getFragment(name)
-	if not name then return nil end
-	if self.frags[name] then return self.frags[name] end
-	local f = fs.open("/data/gfx/shaders/"..name..".frag", "r")
-	local code = {}
-	while true do
-		local l = f:read(1)
-		if not l then break end
-		code[#code+1] = l
-	end
-	f:close()
-	self.frags[name] = core.shader.newShader(table.concat(code))
-	print("[SHADER] created fragment shader from /data/gfx/shaders/"..name..".frag")
-	return self.frags[name]
-end
-
-function _M:getVertex(name)
-	if not name then return nil end
-	if self.verts[name] then return self.verts[name] end
-	local f = fs.open("/data/gfx/shaders/"..name..".vert", "r")
-	local code = {}
-	while true do
-		local l = f:read(1)
-		if not l then break end
-		code[#code+1] = l
-	end
-	f:close()
-	self.verts[name] = core.shader.newShader(table.concat(code), true)
-	print("[SHADER] created vertex shader from /data/gfx/shaders/"..name..".vert")
-	return self.verts[name]
-end
-
-function _M:createProgram(def)
-	local shad = core.shader.newProgram()
-	if def.vert then shad:attach(self:getVertex(def.vert)) end
-	if def.frag then shad:attach(self:getFragment(def.frag)) end
-	if not shad:compile() then return nil end
-	return shad
-end
-
-function _M:loaded()
-	if _M.progs[self.totalname] then
-		self.shad = _M.progs[self.totalname]
-		print("[SHADER] using cached shader "..self.totalname)
-		self.shad = _M.progs[self.totalname]
-	else
-		print("[SHADER] Loading from /data/gfx/shaders/"..self.name..".lua")
-		local f, err = loadfile("/data/gfx/shaders/"..self.name..".lua")
-		if not f and err then error(err) end
-		setfenv(f, setmetatable(self.args or {}, {__index=_G}))
-		local def = f()
-		_M.progs[self.totalname] = self:createProgram(def)
-
-		self.shad = _M.progs[self.totalname]
-		if self.shad then
-			for k, v in pairs(def.args) do
-				self:setUniform(k, v)
-			end
-		end
-	end
-end
-
-function _M:setUniform(k, v)
-	if type(v) == "number" then
---		print("[SHADER] setting param", k, v)
-		self.shad:paramNumber(k, v)
-	elseif type(v) == "table" then
-		if v.texture then
---			print("[SHADER] setting texture param", k, v.texture)
-			self.shad:paramTexture(k, v.texture, v.is3d)
-		elseif #v == 2 then
---			print("[SHADER] setting vec2 param", k, v[1], v[2])
-			self.shad:paramNumber2(k, v[1], v[2])
-		elseif #v == 3 then
---			print("[SHADER] setting vec3 param", k, v[1], v[2], v[3])
-			self.shad:paramNumber3(k, v[1], v[2], v[3])
-		elseif #v == 4 then
---			print("[SHADER] setting vec4 param", k, v[1], v[2], v[3], v[4])
-			self.shad:paramNumber4(k, v[1], v[2], v[3], v[4])
-		end
-	end
-end
diff --git a/game/engine/Store.lua b/game/engine/Store.lua
deleted file mode 100644
index a22809fad99be35b53e09ff8645f410a0deb04a4..0000000000000000000000000000000000000000
--- a/game/engine/Store.lua
+++ /dev/null
@@ -1,187 +0,0 @@
--- 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 Entity = require "engine.Entity"
-local Dialog = require "engine.Dialog"
-local Inventory = require "engine.interface.ActorInventory"
-local ShowStore = require "engine.dialogs.ShowStore"
-local GetQuantity = require "engine.dialogs.GetQuantity"
-
-module(..., package.seeall, class.inherit(Entity, Inventory))
-
-function _M:init(t, no_default)
-	t = t or {}
-
-	t.body = {INVEN=10000}
-
-	Entity.init(self, t, no_default)
-	Inventory.init(self, t, no_default)
-end
-
---- Fill the store with goods
--- @param level the level to generate for (inctance of type engine.Level)
--- @param zone the zone to generate for
-function _M:loadup(level, zone)
-	local s = self.store
-	if not s then error("Store without a store field") end
-	if self.last_filled and game.turn and self.last_filled >= game.turn - s.restock_after then
-		print("[STORE] not restocking yet", game.turn, s.restock_after, self.last_filled)
-		return
-	end
-	local inven = self:getInven("INVEN")
-
-	if s.empty_before_restock then
-		for i = #inven, 1, -1 do
-			local e = inven[i]
-			inven[i] = nil
-			e:removed()
-		end
-	end
-
-	for i = 1, rng.range(s.min_fill, s.max_fill) - #inven do
-		local filter = rng.table(s.filters)
-		local e = zone:makeEntity(level, "object", filter, nil, true)
-		if e then
-			if filter.id then e:identify(filter.id) end
-			self:addObject(inven, e)
-			zone:addEntity(level, e, "object")
-			print("[STORE] stocking up: ", e.name)
-		end
-	end
-	self:sortInven(inven)
-	self.last_filled = game.turn
-end
-
---- Actor interacts with the store
--- @param who the actor who interracts
-function _M:interact(who)
-	local store, inven = self:getInven("INVEN"), who:getInven("INVEN")
-	local d; d = ShowStore.new("Store: "..self.name, store, inven, nil, nil, function(what, o, item)
-		if what == "buy" then
-			if o:getNumber() > 1 then
-				local q = GetQuantity.new(nil, nil, function(qty) self:doBuy(who, o, item, qty, d) end)
-				q.qty = o:getNumber()
-				game:registerDialog(q)
-			else
-				self:doBuy(who, o, item, 1, d)
-			end
-		else
-			if o:getNumber() > 1 then
-				local q
-				q = GetQuantity.new(nil, nil, function(qty) self:doSell(who, o, item, qty, d) end)
-				q.qty = o:getNumber()
-				game:registerDialog(q)
-			else
-				self:doSell(who, o, item, 1, d)
-			end
-		end
-	end, function(what, o)
-		return self:descObject(who, what, o)
-	end)
-	game:registerDialog(d)
-end
-
-function _M:doBuy(who, o, item, nb, store_dialog)
-	local max_nb = o:getNumber()
-	nb = math.min(nb, max_nb)
-	nb = self:tryBuy(who, o, item, nb)
-	if nb then
-		Dialog:yesnoPopup("Buy", ("Buy %d %s"):format(nb, o:getName{do_color=true, no_count=true}), function(ok) if ok then
-			local store, inven = self:getInven("INVEN"), who:getInven("INVEN")
-			for i = 1, nb do
-				local o = self:removeObject(store, item)
-				who:addObject(inven, o)
-			end
-			self:sortInven(store)
-			who:sortInven(inven)
-			self.changed = true
-			who.changed = true
-			self:onBuy(who, o, item, nb)
-			if store_dialog then store_dialog:updateStore() end
-		end end)
-	end
-end
-
-function _M:doSell(who, o, item, nb, store_dialog)
-	local max_nb = o:getNumber()
-	nb = math.min(nb, max_nb)
-	nb = self:trySell(who, o, item, nb)
-	if nb then
-		Dialog:yesnoPopup("Sell", ("Sell %d %s"):format(nb, o:getName{do_color=true, no_count=true}), function(ok) if ok then
-			local store, inven = self:getInven("INVEN"), who:getInven("INVEN")
-			for i = 1, nb do
-				local o = who:removeObject(inven, item)
-				self:addObject(store, o)
-			end
-			self:sortInven(store)
-			who:sortInven(inven)
-			self.changed = true
-			who.changed = true
-			self:onSell(who, o, item, nb)
-			if store_dialog then store_dialog:updateStore() end
-		end end)
-	end
-end
-
---- Called on object purchase try
--- @param who the actor buying
--- @param o the object trying to be purchased
--- @param item the index in the inventory
--- @param nb number of items (if stacked) to buy
--- @return a number (or nil) if allowed to buy, giving the number of objects to buy
-function _M:tryBuy(who, o, item, nb)
-	return nb
-end
-
---- Called on object sale try
--- @param who the actor selling
--- @param o the object trying to be sold
--- @param item the index in the inventory
--- @param nb number of items (if stacked) to sell
--- @return a number (or nil) if allowed to sell, giving the number of objects to sell
-function _M:trySell(who, o, item, nb)
-	return nb
-end
-
-
---- Called on object purchase
--- @param who the actor buying
--- @param o the object trying to be purchased
--- @param item the index in the inventory
--- @param nb number of items (if stacked) to buy
-function _M:onBuy(who, o, item, nb)
-end
-
---- Called on object sale
--- @param who the actor selling
--- @param o the object trying to be sold
--- @param item the index in the inventory
--- @param nb number of items (if stacked) to sell
-function _M:onSell(who, o, item, nb)
-end
-
---- Called to describe an object, being to sell or to buy
--- @param who the actor
--- @param what either "sell" or "buy"
--- @param o the object
--- @return a string (possibly multiline) describing the object
-function _M:descObject(what, o)
-	return o:getDesc()
-end
diff --git a/game/engine/Target.lua b/game/engine/Target.lua
deleted file mode 100644
index 92da5ba70eb1615a3d8db93d27f7b1300957463b..0000000000000000000000000000000000000000
--- a/game/engine/Target.lua
+++ /dev/null
@@ -1,213 +0,0 @@
--- 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"
-
---- handles targetting
-module(..., package.seeall, class.make)
-
-function _M:init(map, source_actor)
-	self.display_x, self.display_y = map.display_x, map.display_y
-	self.w, self.h = map.viewport.width, map.viewport.height
-	self.tile_w, self.tile_h = map.tile_w, map.tile_h
-	self.active = false
-	self.target_type = {}
-
-	self.cursor = core.display.loadImage(engine.Tiles.prefix.."target_cursor.png"):glTexture()
-
-	self.sr = core.display.newSurface(map.tile_w, map.tile_h)
-	self.sr:erase(255, 0, 0, 90)
-	self.sr = self.sr:glTexture()
-	self.sb = core.display.newSurface(map.tile_w, map.tile_h)
-	self.sb:erase(0, 0, 255, 90)
-	self.sb = self.sb:glTexture()
-	self.sg = core.display.newSurface(map.tile_w, map.tile_h)
-	self.sg:erase(0, 255, 0, 90)
-	self.sg = self.sg:glTexture()
-
-	self.source_actor = source_actor
-
-	-- Setup the tracking target table
-	-- Notice its values are set to weak references, this has no effects on the number for x and y
-	-- but it means if the entity field is set to an entity, when it disappears this link wont prevent
-	-- the garbage collection
-	self.target = {x=self.source_actor.x, y=self.source_actor.y, entity=nil}
---	setmetatable(self.target, {__mode='v'})
-end
-
-function _M:display(dispx, dispy)
-	-- Entity tracking, if possible and if visible
-	if self.target.entity and self.target.entity.x and self.target.entity.y and game.level.map.seens(self.target.entity.x, self.target.entity.y) then
-		self.target.x, self.target.y = self.target.entity.x, self.target.entity.y
-	end
-	self.target.x = self.target.x or self.source_actor.x
-	self.target.y = self.target.y or self.source_actor.y
-
-	-- Do not display if not requested
-	if not self.active then return end
-
-	local ox, oy = self.display_x, self.display_y
-	self.display_x, self.display_y = dispx or self.display_x, dispy or self.display_y
-
-	local s = self.sb
-	local l = line.new(self.source_actor.x, self.source_actor.y, self.target.x, self.target.y)
-	local lx, ly = l()
-	local initial_dir = lx and coord_to_dir[lx - self.source_actor.x][ly - self.source_actor.y] or 5
-	local stopx, stopy = self.source_actor.x, self.source_actor.y
-	while lx and ly do
-		if s == self.sb then stopx, stopy = lx, ly end
-		if not self.target_type.no_restrict then
-			if not game.level.map.seens(lx, ly) then s = self.sr end
-			if self.target_type.stop_block and game.level.map:checkAllEntities(lx, ly, "block_move") then s = self.sr
-			elseif game.level.map:checkEntity(lx, ly, Map.TERRAIN, "block_move") then s = self.sr end
-		end
-		if self.target_type.range and math.sqrt((self.source_actor.x-lx)^2 + (self.source_actor.y-ly)^2) > self.target_type.range then s = self.sr end
-		s:toScreen(self.display_x + (lx - game.level.map.mx) * self.tile_w * Map.zoom, self.display_y + (ly - game.level.map.my) * self.tile_h * Map.zoom, self.tile_w * Map.zoom, self.tile_h * Map.zoom)
-		lx, ly = l()
-	end
-	self.cursor:toScreen(self.display_x + (self.target.x - game.level.map.mx) * self.tile_w * Map.zoom, self.display_y + (self.target.y - game.level.map.my) * self.tile_h * Map.zoom, self.tile_w * Map.zoom, self.tile_h * Map.zoom)
-
-	if s == self.b then stopx, stopy = self.target.x, self.target.y end
-
-	if self.target_type.ball and self.target_type.ball > 0 then
-		core.fov.calc_circle(stopx, stopy, self.target_type.ball, function(_, lx, ly)
-			self.sg:toScreen(self.display_x + (lx - game.level.map.mx) * self.tile_w * Map.zoom, self.display_y + (ly - game.level.map.my) * self.tile_h * Map.zoom, self.tile_w * Map.zoom, self.tile_h * Map.zoom)
-			if not self.target_type.no_restrict and game.level.map:checkEntity(lx, ly, Map.TERRAIN, "block_move") then return true end
-		end, function()end, nil)
-	elseif self.target_type.cone and self.target_type.cone > 0 then
-		core.fov.calc_beam(stopx, stopy, self.target_type.cone, initial_dir, self.target_type.cone_angle, function(_, lx, ly)
-			self.sg:toScreen(self.display_x + (lx - game.level.map.mx) * self.tile_w * Map.zoom, self.display_y + (ly - game.level.map.my) * self.tile_h * Map.zoom, self.tile_w * Map.zoom, self.tile_h * Map.zoom)
-			if not self.target_type.no_restrict and game.level.map:checkEntity(lx, ly, Map.TERRAIN, "block_move") then return true end
-		end, function()end, nil)
-	end
-
-	self.display_x, self.display_y = ox, oy
-end
-
---- Returns data for the given target type
--- Hit: simple project in LOS<br/>
--- Beam: hits everything in LOS<br/>
--- Bolt: hits first thing in path<br/>
--- Ball: hits everything in a ball aounrd the target<br/>
--- Cone: hits everything in a cone in the direction<br/>
-function _M:getType(t)
-	if not t or not t.type then return {} end
-	t.range = t.range or 20
-	if t.friendlyfire == nil then t.friendlyfire = true end
-	if t.type == "hit" then
-		return {range=t.range, friendlyfire=t.friendlyfire, no_restrict=t.no_restrict}
-	elseif t.type == "beam" then
-		return {range=t.range, friendlyfire=t.friendlyfire, no_restrict=t.no_restrict, line=true}
-	elseif t.type == "bolt" then
-		return {range=t.range, friendlyfire=t.friendlyfire, no_restrict=t.no_restrict, stop_block=true}
-	elseif t.type == "ball" then
-		return {range=t.range, friendlyfire=t.friendlyfire, no_restrict=t.no_restrict, ball=t.radius}
-	elseif t.type == "cone" then
-		return {range=t.range, friendlyfire=t.friendlyfire, no_restrict=t.no_restrict, cone=t.radius, cone_angle=t.cone_angle or 55}
-	elseif t.type == "ballbolt" then
-		return {range=t.range, friendlyfire=t.friendlyfire, no_restrict=t.no_restrict, ball=t.radius, stop_block=true}
-	elseif t.type == "conebolt" then
-		return {range=t.range, friendlyfire=t.friendlyfire, no_restrict=t.no_restrict, cone=t.radius, cone_angle=t.cone_angle or 55, stop_block=true}
-	elseif t.type == "ballbeam" then
-		return {range=t.range, friendlyfire=t.friendlyfire, no_restrict=t.no_restrict, ball=t.radius, line=true}
-	elseif t.type == "conebeam" then
-		return {range=t.range, friendlyfire=t.friendlyfire, no_restrict=t.no_restrict, cone=t.radius, cone_angle=t.cone_angle or 55, line=true}
-	else
-		return {}
-	end
-end
-
-function _M:setActive(v, type)
-	if v == nil then
-		return self.active
-	else
-		self.active = v
-		if v and type then
-			self.target_type = self:getType(type)
-		else
-			self.target_type = {}
-		end
-	end
-end
-
-function _M:freemove(dir)
-	local d = dir_to_coord[dir]
-	self.target.x = self.target.x + d[1]
-	self.target.y = self.target.y + d[2]
-	self.target.entity = game.level.map(self.target.x, self.target.y, engine.Map.ACTOR)
-end
-
-function _M:setSpot(x, y)
-	self.target.x = x
-	self.target.y = y
-	self.target.entity = game.level.map(self.target.x, self.target.y, engine.Map.ACTOR)
-end
-
-function _M:scan(dir, radius, sx, sy, filter)
-	sx = sx or self.target.x
-	sy = sy or self.target.y
-	radius = radius or 20
-	local actors = {}
-	local checker = function(_, x, y)
-		if sx == x and sy == y then return false end
-		if game.level.map.seens(x, y) and game.level.map(x, y, engine.Map.ACTOR) then
-			local a = game.level.map(x, y, engine.Map.ACTOR)
-
-			if (not self.source_actor or self.source_actor:canSee(a)) and (not filter or filter(a)) then
-				table.insert(actors, {
-					a = a,
-					dist = math.abs(sx - x)*math.abs(sx - x) + math.abs(sy - y)*math.abs(sy - y)
-				})
-				actors[a] = true
-			end
-		end
-		return false
-	end
-
-	if dir ~= 5 then
-		-- Get a list of actors in the direction given
-		core.fov.calc_beam(sx, sy, radius, dir, 55, checker, function()end, nil)
-	else
-		-- Get a list of actors all around
-		core.fov.calc_circle(sx, sy, radius, checker, function()end, nil)
-	end
-
-	table.sort(actors, function(a,b) return a.dist<b.dist end)
-	if #actors > 0 then
-		self.target.entity = actors[1].a
-		self.target.x = self.target.entity.x
-		self.target.y = self.target.entity.y
-	end
-end
-
---- Returns the point at distance from the source on a line to the destination
-function _M:pointAtRange(srcx, srcy, destx, desty, dist)
-	local l = line.new(srcx, srcy, destx, desty)
-	local lx, ly = l()
-	while lx and ly do
-		if core.fov.distance(srcx, srcy, lx, ly) >= dist then break end
-		lx, ly = l()
-	end
-	if not lx then
-		return destx, desty
-	else
-		return lx, ly
-	end
-end
diff --git a/game/engine/TextBox.lua b/game/engine/TextBox.lua
deleted file mode 100644
index 2ac1ea114147d8e82c5ffbecad127a18ec795986..0000000000000000000000000000000000000000
--- a/game/engine/TextBox.lua
+++ /dev/null
@@ -1,128 +0,0 @@
--- 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"
-require "engine.Tiles"
-require "engine.Mouse"
-require "engine.KeyBind"
-require "engine.interface.ControlCursorSupport"
---- Handles textbox input control
-module(..., package.seeall, class.inherit(
-		engine.interface.ControlCursorSupport))
-
-tiles = engine.Tiles.new(16, 16)
-
-function _M:init(dialogdef, owner, font, mask, fct)
-	--name, title, min, max, x, y, w, height
-	self.type = "TextBox"
-	self.name = dialogdef.name
-	self.title = dialogdef.title
-	self.min = dialogdef.min or 2
-	self.max = dialogdef.max or 25
-	self.h = dialogdef.h or 30
-	self.font = font
-	self.w = dialogdef.w or 200
-	self.x = dialogdef.x
-	self.y = dialogdef.y
-	self.private = dialogdef.private
-	self.text = ""
-	self.owner = owner
-	self.btn = 	{
-		h = dialogdef.h,
-		mouse_over= function(button)
-						if self.owner.state ~= self.name then self.focused=true self.owner:focusControl(self.name) end
-						if button == "right" then
-							self.text=""
-							self.ownwer.changed=true
-						end
-					end
-				}
-	self.owner.mouse:registerZone(self.owner.display_x + self.x, self.owner.display_y + self.y + self.h, self.w, self.h, self.btn.mouse_over)
-	self:startCursor()
-end
-
-function _M:delete()
-	if (self.cursorPosition>=self.maximumCurosrPosition) then return end
-	local temptext = self.text:sub(1, self.cursorPosition)
-	if self.cursorPosition < self.maximumCurosrPosition - 1 then temptext = temptext..self.text:sub(self.cursorPosition + 2, self.text:len()) end
-	self.text =  temptext
-	self.maximumCurosrPosition = self.maximumCurosrPosition - 1
-end
-
-function _M:backSpace()
-	if (self.cursorPosition==0) then return end
-	local temptext = self.text:sub(1, self.cursorPosition - 1)
-	if self.cursorPosition < self.maximumCurosrPosition then temptext = temptext..self.text:sub(self.cursorPosition + 1, self.text:len()) end
-	self.text =  temptext
-	self.maximumCurosrPosition = self.maximumCurosrPosition - 1
-	self.cursorPosition = self.cursorPosition - 1
-end
-
-function _M:textInput(c)
-	if self.text:len() < self.max then
-		local temp=nil
-		if self.cursorPosition < self.maximumCurosrPosition then temp=self.text:sub(self.cursorPosition + 1, self.text:len()) end
-		self.text = self.text:sub(1,self.cursorPosition) .. c
-		if temp then self.text=self.text..temp end
-		self.owner.changed = true
-		self:moveRight(1, true)
-	end
-end
-
-function _M:unFocus()
-	self.focused = false
-end
-
-
-function _M:drawControl(s)
-
-	local r, g, b
-	local w = self.w
-	local h = self.h
-	local tw, th = self.font:size(self.title)
-	tw = tw + 10
-	local title=self.title
-	if self.owner.state==self.name then
-		title = title.."*"
-	end
-	r, g, b = s:drawColorStringBlended(self.font, title, self.x, self.y + ((h - th) / 2), r, g, b)
-
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_7"..(sel and "_sel" or "")..".png"), self.x + tw, self.y)
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_9"..(sel and "_sel" or "")..".png"), w + self.x - 8, self.y)
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_1"..(sel and "_sel" or "")..".png"), self.x + tw, self.y + h - 8)
-	s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_3"..(sel and "_sel" or "")..".png"), self.x + w - 8, self.y + h - 8)
-	for i = 8, w - tw - 9 do
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_8.png"), self.x + tw + i, self.y)
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_8.png"), self.x + tw + i, self.y + h - 3)
-	end
-	for i = 8, h - 9 do
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_4.png"), self.x + tw, self.y + i)
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_4.png"), self.x + w - 3, self.y + i)
-	end
-
-	local text = self.text
-	if text=="" then text=self.mask or "" end
-	if self.private then text = text:gsub('.', '*') end
-	local sw, sh = self.font:size(text)
-
-	local baseX = self.x + tw + 10
-
-	s:drawColorStringBlended(self.font, text, baseX, self.y + h - sh - 8)
-	self:drawCursor(s, baseX, text)
-end
diff --git a/game/engine/Tiles.lua b/game/engine/Tiles.lua
deleted file mode 100644
index f48945bd46340017bda199d47058dc230213833c..0000000000000000000000000000000000000000
--- a/game/engine/Tiles.lua
+++ /dev/null
@@ -1,103 +0,0 @@
--- 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"
-
---- Handles tiles
--- Used by engine.Map to reduce processing needed. Module authors wont use it directly mostly.
-module(..., package.seeall, class.make)
-
-prefix = "/data/gfx/"
-use_images = true
-
-function _M:init(w, h, fontname, fontsize, texture, allow_backcolor)
-	self.allow_backcolor = allow_backcolor
-	self.texture = texture
-	self.w, self.h = w, h
-	self.font = core.display.newFont(fontname or "/data/font/VeraMoBd.ttf", fontsize or 14)
-	self.repo = {}
-	self.texture_store = {}
-end
-
-function _M:get(char, fr, fg, fb, br, bg, bb, image, alpha, do_outline)
-	alpha = alpha or 0
-	local dochar = char
-	local fgidx = 65536 * fr + 256 * fg + fb
-	local bgidx
-	if br >= 0 and bg >= 0 and bb >= 0 then
-		bgidx = 65536 * br + 256 * bg + bb
-	else
-		bgidx = "none"
-	end
-
-	if (self.use_images or not dochar) and image then char = image end
-
-	if self.repo[char] and self.repo[char][fgidx] and self.repo[char][fgidx][bgidx] then
-		return self.repo[char][fgidx][bgidx]
-	else
-		local s
-		local is_image = false
-		if (self.use_images or not dochar) and image then
-			print("Loading tile", image)
-			s = core.display.loadImage(self.prefix..image)
-			if s then is_image = true end
-		end
-		if not s then
-			local w, h = self.font:size(dochar)
---[[
-			s = core.display.newSurface(self.w, self.h)
-			if br >= 0 then
-				s:erase(br, bg, bb, alpha)
-			else
-				s:erase(0, 0, 0, alpha)
-			end
-
-			s:drawString(self.font, char, (self.w - w) / 2, (self.h - h) / 2, fr, fg, fb)
-]]
-			if not self.allow_backcolor or br < 0 then br = nil end
-			if not self.allow_backcolor or bg < 0 then bg = nil end
-			if not self.allow_backcolor or bb < 0 then bb = nil end
-			if not self.allow_backcolor then alpha = 0 end
-			s = core.display.newTile(self.w, self.h, self.font, dochar, (self.w - w) / 2, (self.h - h) / 2, fr, fg, fb, br or 0, bg or 0, bb or 0, alpha, self.use_images)
---			s = core.display.drawStringNewSurface(self.font, char, fr, fg, fb)
-		end
-
-		if self.texture then
-			s = s:glTexture()
-			if not is_image and do_outline then
-				if type(do_outline) == "boolean" then
-					s = s:makeOutline(2, 2, self.w, self.h, 0, 0, 0, 1) or s
-				else
-					s = s:makeOutline(do_outline.x, do_outline.y, self.w, self.h, do_outline.r, do_outline.g, do_outline.b, do_outline.a) or s
-				end
-			end
-		end
-
-		self.repo[char] = self.repo[char] or {}
-		self.repo[char][fgidx] = self.repo[char][fgidx] or {}
-		self.repo[char][fgidx][bgidx] = s
-		return s
-	end
-end
-
-function _M:clean()
-	self.repo = {}
-	self.texture_store = {}
-	collectgarbage("collect")
-end
diff --git a/game/engine/Tooltip.lua b/game/engine/Tooltip.lua
deleted file mode 100644
index 8d61e4e0e97a456809196b732cb05d9a4377eb2d..0000000000000000000000000000000000000000
--- a/game/engine/Tooltip.lua
+++ /dev/null
@@ -1,147 +0,0 @@
--- 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"
-
---- Displays a tooltip
-module(..., package.seeall, class.make)
-
-tiles = engine.Tiles.new(16, 16)
-
-function _M:init(fontname, fontsize, color, bgcolor, max)
-	self.color = color or {255,255,255}
-	self.bgcolor = bgcolor or {0,0,0}
-	self.font = core.display.newFont(fontname or "/data/font/Vera.ttf", fontsize or 12)
-	self.font_h = self.font:lineSkip()
-	self.max = max or 300
-	self.changed = true
-	self.old_tmx, self.old_tmy = -1,-1
-	self.old_turn = -1
-end
-
---- Set the tooltip text
-function _M:set(str, ...)
-	self.text = str:format(...):splitLines(self.max, self.font)
-	self.w, self.h = 0, 0
-	for i, l in ipairs(self.text) do
-		local w, h = self.font:size(l)
-		if w > self.w then self.w = w end
-		self.h = self.h + self.font_h
-	end
-	self.w = math.min(self.w, self.max) + 8
-	self.h = self.h + 8
-	self.changed = true
-end
-
-function _M:drawWBorder(s, x, y, w)
-	for i = x, x + w do
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_8.png"), i, y)
-	end
-end
-
-function _M:erase()
-	self.surface = nil
-end
-
-function _M:display()
-	-- If nothing changed, return the same surface as before
-	if not self.changed then return self.surface end
-	self.changed = false
-
-	self.surface = core.display.newSurface(self.w, self.h)
-
-	-- Erase and the display the tooltip
-	self.surface:erase(self.bgcolor[1], self.bgcolor[2], self.bgcolor[3], 200)
-
-	self.surface:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_7.png"), 0, 0)
-	self.surface:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_9.png"), self.w - 8, 0)
-	self.surface:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_1.png"), 0, self.h - 8)
-	self.surface:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_3.png"), self.w - 8, self.h - 8)
-	for i = 8, self.w - 9 do
-		self.surface:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_8.png"), i, 0)
-		self.surface:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_8.png"), i, self.h - 3)
-	end
-	for i = 8, self.h - 9 do
-		self.surface:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_4.png"), 0, i)
-		self.surface:merge(tiles:get(nil, 0,0,0, 0,0,0, "border_4.png"), self.w - 3, i)
-	end
-
-	local i = 1
-	local y = 0
-	local r, g, b = self.color[1], self.color[2], self.color[3], nil
-	for ii, l in ipairs(self.text) do
-		if self.text[i] == "---" then
-			self:drawWBorder(self.surface, 4, 4 + y + 0.5 * self.font_h, self.w - 8)
-			i = i + 1
-			y = y + self.font_h
-		else
-			r, g, b = self.surface:drawColorStringBlended(self.font, self.text[i], 4, 4 + y, self.color[1], self.color[2], self.color[3])
-			i = i + 1
-			y = y + self.font_h
-		end
-	end
-	self.texture = self.surface:glTexture()
-end
-
-function _M:toScreen(x, y)
-	if self.surface then
-		self.surface:toScreenWithTexture(self.texture, x, y)
-	end
-end
-
---- Displays the tooltip at the given map coordinates
--- @param tmx the map coordinate to get tooltip from
--- @param tmy the map coordinate to get tooltip from
--- @param mx the screen coordinate to display at, if nil it will be computed from tmx
--- @param my the screen coordinate to display at, if nil it will be computed from tmy
-function _M:displayAtMap(tmx, tmy, mx, my)
-	if not mx then
-		mx, my = game.level.map:getTileToScreen(tmx, tmy)
-	end
-
-	if self.old_tmx ~= tmx or self.old_tmy ~= tmy or (game.paused and self.old_turn ~= game.turn) then
-		self.old_tmx, self.old_tmy = tmx, tmy
-		self.old_turn = game.turn
-		local tt = {}
-		local seen = game.level.map.seens(tmx, tmy)
-		local remember = game.level.map.remembers(tmx, tmy)
-		tt[#tt+1] = seen and game.level.map:checkEntity(tmx, tmy, Map.PROJECTILE, "tooltip", game.level.map.actor_player) or nil
-		tt[#tt+1] = seen and game.level.map:checkEntity(tmx, tmy, Map.ACTOR, "tooltip", game.level.map.actor_player) or nil
-		tt[#tt+1] = seen and game.level.map:checkEntity(tmx, tmy, Map.OBJECT, "tooltip", game.level.map.actor_player) or nil
-		tt[#tt+1] = seen and game.level.map:checkEntity(tmx, tmy, Map.TRAP, "tooltip", game.level.map.actor_player) or nil
-		tt[#tt+1] = remember and game.level.map:checkEntity(tmx, tmy, Map.TERRAIN, "tooltip", game.level.map.actor_player) or nil
-		if #tt > 0 then
-			self:set("%s", table.concat(tt, "\n---\n"))
-			self:display()
-		else
-			self:erase()
-		end
-	end
-
-	if self.surface then
-		mx = mx - self.w / 2 + game.level.map.tile_w / 2
-		my = my - self.h
-		if mx < 0 then mx = 0 end
-		if my < 0 then my = 0 end
-		if mx > game.w - self.w then mx = game.w - self.w end
-		if my > game.h - self.h then my = game.h - self.h end
-		self.surface:toScreenWithTexture(self.texture, mx, my)
-	end
-end
diff --git a/game/engine/Trap.lua b/game/engine/Trap.lua
deleted file mode 100644
index 7fb75503bcbc8fc319621ee9498bf2c25a38909a..0000000000000000000000000000000000000000
--- a/game/engine/Trap.lua
+++ /dev/null
@@ -1,152 +0,0 @@
--- 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 Entity = require "engine.Entity"
-local Map = require "engine.Map"
-
---- Describes a trap
-module(..., package.seeall, class.inherit(Entity))
-
-_M.display_on_seen = true
-_M.display_on_remember = true
-_M.display_on_unknown = false
-
-function _M:init(t, no_default)
-	t = t or {}
-
-	assert(t.triggered, "no trap triggered action")
-
-	Entity.init(self, t, no_default)
-
-	if self.disarmable == nil then
-		self.disarmable = true
-	end
-
-	self.detect_power = self.detect_power or 1
-	self.disarm_power = self.disarm_power or 1
-
-	self.known_by = {}
-	self:loaded()
-end
-
-function _M:loaded()
-	Entity.loaded(self)
-	-- known_by table is a weak table on keys, so taht it does not prevent garbage collection of actors
-	setmetatable(self.known_by, {__mode="k"})
-end
-
---- Do we have enough energy
-function _M:enoughEnergy(val)
-	val = val or game.energy_to_act
-	return self.energy.value >= val
-end
-
---- Use some energy
-function _M:useEnergy(val)
-	val = val or game.energy_to_act
-	self.energy.value = self.energy.value - val
-end
-
---- Get trap name
--- Can be overloaded to do trap identification if needed
-function _M:getName()
-	return self.name
-end
-
---- Setup the trap
-function _M:setup()
-end
-
---- Set the known status for the given actor
-function _M:setKnown(actor, v)
-	self.known_by[actor] = v
-end
-
---- Get the known status for the given actor
-function _M:knownBy(actor)
-	return self.known_by[actor]
-end
-
---- Can we disarm this trap?
-function _M:canDisarm(x, y, who)
-	if not self.disarmable then return false end
-	return true
-end
-
---- Try to disarm the trap
-function _M:disarm(x, y, who)
-	if not self:canDisarm(x, y, who) then
-		game.logSeen(who, "%s fails to disarm a trap (%s).", who.name:capitalize(), self:getName())
-		return false
-	end
-	game.level.map:remove(x, y, Map.TRAP)
-	if self.removed then
-		self:removed(x, y, who)
-	end
-	game.logSeen(who, "%s disarms a trap (%s).", who.name:capitalize(), self:getName())
-	self:onDisarm(x, y, who)
-	return true
-end
-
---- Trigger the trap
-function _M:trigger(x, y, who)
-	-- Try to disarm
-	if self:knownBy(who) then
-		-- Try to disarm
-		if self:disarm(x, y, who) then
-			return
-		end
-	end
-
-	if not self:canTrigger(x, y, who) then return end
-
-	if not self.message then
-		game.logSeen(who, "%s triggers a trap (%s)!", who.name:capitalize(), self:getName())
-	else
-		local tname = who.name
-		local str =self.message
-		str = str:gsub("@target@", tname)
-		str = str:gsub("@Target@", tname:capitalize())
-		game.logSeen(who, "%s", str)
-	end
-	local known, del = self:triggered(x, y, who)
-	if known then
-		self:setKnown(who, true)
-		game.level.map:updateMap(x, y)
-	end
-	if del then
-		game.level.map:remove(x, y, Map.TRAP)
-		if self.removed then self:removed(x, y, who) end
-	end
-end
-
---- When moving on a trap, trigger it
-function _M:on_move(x, y, who, forced)
-	if not forced then self:trigger(x, y, who) end
-end
-
---- Called when disarmed
-function _M:onDisarm(x, y, who)
-end
-
---- Called when triggered
-function _M:canTrigger(x, y, who)
-	return true
-end
diff --git a/game/engine/World.lua b/game/engine/World.lua
deleted file mode 100644
index ee1f5ef5416c418e5b7b45425dd12fd2a3908f8f..0000000000000000000000000000000000000000
--- a/game/engine/World.lua
+++ /dev/null
@@ -1,32 +0,0 @@
--- 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"
-
---- Represents a game world, that is persistent across characters
-module(..., package.seeall, class.make)
-
---- Initializes the world
-function _M:init()
-end
-
---- Run the world
--- This is called after creation or loading of the world
-function _M:run()
-end
diff --git a/game/engine/Zone.lua b/game/engine/Zone.lua
deleted file mode 100644
index 6e13115e536ae216595a3ee5e8dbafa2fe5843f1..0000000000000000000000000000000000000000
--- a/game/engine/Zone.lua
+++ /dev/null
@@ -1,610 +0,0 @@
--- 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 Savefile = require "engine.Savefile"
-local Dialog = require "engine.Dialog"
-local Map = require "engine.Map"
-local Astar = require "engine.Astar"
-local print = function() end
-
---- Defines a zone: a set of levels, with depth, nps, objects, level generator, ...
-module(..., package.seeall, class.make)
-
---- Setup classes to use for level generation
--- Static method
--- @param t table that contains the name of the classes to use
--- @usage Required fields:
--- npc_class (default engine.Actor)
--- grid_class (default engine.Grid)
--- object_class (default engine.Object)
-function _M:setup(t)
-	self.map_class = require(t.map_class or "engine.Map")
-	self.level_class = require(t.level_class or "engine.Level")
-	self.npc_class = require(t.npc_class or "engine.Actor")
-	self.grid_class = require(t.grid_class or "engine.Grid")
-	self.trap_class = require(t.trap_class or "engine.Trap")
-	self.object_class = require(t.object_class or "engine.Object")
-end
-
---- Loads a zone definition
--- @param short_name the short name of the zone to load, if should correspond to a directory in your module data/zones/short_name/ with a zone.lua, npcs.lua, grids.lua and objects.lua files inside
-function _M:init(short_name, dynamic)
-	self.short_name = short_name
-	if not self:load(dynamic) then
-		self.level_range = self.level_range or {1,1}
-		if type(self.level_range) == "number" then self.level_range = {self.level_range, self.level_range} end
-		self.level_scheme = self.level_scheme or "fixed"
-		assert(self.max_level, "no zone max level")
-		self.levels = self.levels or {}
-		if not dynamic then
-			self.npc_list = self.npc_class:loadList("/data/zones/"..self.short_name.."/npcs.lua")
-			self.grid_list = self.grid_class:loadList("/data/zones/"..self.short_name.."/grids.lua")
-			self.object_list = self.object_class:loadList("/data/zones/"..self.short_name.."/objects.lua")
-			self.trap_list = self.trap_class:loadList("/data/zones/"..self.short_name.."/traps.lua")
-		end
-
-		-- Determine a zone base level
-		self.base_level = self.level_range[1]
-		if self.level_scheme == "player" then
-			local plev = game:getPlayer().level
-			self.base_level = util.bound(plev, self.level_range[1], self.level_range[2])
-		end
-		print("Initiated zone", self.name, "with base_level", self.base_level)
-	else
-		print("Loaded zone", self.name, "with base_level", self.base_level)
-	end
-end
-
---- Leaves a zone
--- Saves the zone to a .teaz file if requested with persistant="zone" flag
-function _M:leave()
-	if type(self.persistant) == "string" and self.persistant == "zone" then
-		local save = Savefile.new(game.save_name)
-		save:saveZone(self)
-		save:close()
-	end
-	game.level = nil
-end
-
---- Parses the npc/objects list and compute rarities for random generation
--- ONLY entities with a rarity properties will be considered.<br/>
--- This means that to get a never-random entity you simply do not put a rarity property on it.
-function _M:computeRarities(type, list, level, filter, add_level, rarity_field)
-	rarity_field = rarity_field or "rarity"
-	local r = { total=0 }
-	print("******************", level.level)
-	for i, e in ipairs(list) do
-		if e[rarity_field] and e.level_range and (not filter or filter(e)) then
---			print("computing rarity of", e.name)
-			local lev = self.base_level + (level.level - 1) + (add_level or 0)
-
-			local max = 10000
-			if lev < e.level_range[1] then max = 10000 / (3 * (e.level_range[1] - lev))
-			elseif e.level_range[2] and lev > e.level_range[2] then max = 10000 / (lev - e.level_range[2])
-			end
-			local genprob = math.floor(max / e[rarity_field])
-			print(("Entity(%30s) got %3d (=%3d / %3d) chance to generate. Level range(%2d-%2s), current %2d"):format(e.name, math.floor(genprob), math.floor(max), e[rarity_field], e.level_range[1], e.level_range[2] or "--", lev))
-
-			-- Generate and store egos list if needed
-			if e.egos and e.egos_chance then
-				if _G.type(e.egos_chance) == "number" then e.egos_chance = {e.egos_chance} end
-				for ie, edata in pairs(e.egos_chance) do
-					local etype = ie
-					if _G.type(ie) == "number" then etype = "" end
-					if not level:getEntitiesList(type.."/"..e.egos..":"..etype) then
-						print("Generating specific ego list", type.."/"..e.egos..":"..etype)
-						local egos = self:getEgosList(level, type, e.egos, e.__CLASSNAME)
-						if egos then
-							local egos_prob = self:computeRarities(type, egos, level, etype ~= "" and function(e) return e[etype] end or nil)
-							level:setEntitiesList(type.."/"..e.egos..":"..etype, egos_prob)
-							level:setEntitiesList(type.."/base/"..e.egos..":"..etype, egos)
-						end
-					end
-				end
-			end
-
-			if genprob > 0 then
---				genprob = math.ceil(genprob / 10 * math.sqrt(genprob))
-				r.total = r.total + genprob
-				r[#r+1] = { e=e, genprob=r.total, level_diff = lev - level.level }
-			end
-		end
-	end
-	table.sort(r, function(a, b) return a.genprob < b.genprob end)
-
-	local prev = 0
-	local tperc = 0
-	for i, ee in ipairs(r) do
-		local perc = 100 * (ee.genprob - prev) / r.total
-		tperc = tperc + perc
-		print(("entity chance %2d : chance(%4d : %4.5f%%): %s"):format(i, ee.genprob, perc, ee.e.name))
-		prev = ee.genprob
-	end
-	print("*DONE", r.total, tperc.."%")
-
-	return r
-end
-
---- Checks an entity against a filter
-function _M:checkFilter(e, filter)
-	if e.unique and game.uniques[e.__CLASSNAME.."/"..e.unique] then print("refused unique", e.name, e.__CLASSNAME.."/"..e.unique) return false end
-
-	if not filter then return true end
-	if filter.ignore and self:checkFilter(e, filter.ignore) then return false end
-
-	if filter.type and filter.type ~= e.type then return false end
-	if filter.subtype and filter.subtype ~= e.subtype then return false end
-	if filter.name and filter.name ~= e.name then return false end
-	if e.checkFilter and not e:checkFilter(filter) then return end
-	if filter.special and not filter.special(e) then return end
-
-	if e.unique then print("accepted unique", e.name, e.__CLASSNAME.."/"..e.unique) end
-
-	return true
-end
-
---- Return a string describing the filter
-function _M:filterToString(filter)
-	local ps = ""
-	for what, check in pairs(filter) do
-		ps = ps .. what.."="..check..","
-	end
-	return ps
-end
-
---- Picks an entity from a computed probability list
-function _M:pickEntity(list)
-	if #list == 0 then return nil end
-	local r = rng.range(1, list.total)
-	for i = 1, #list do
---		print("test", r, ":=:", list[i].genprob)
-		if r < list[i].genprob then
---			print(" * select", list[i].e.name)
-			return list[i].e
-		end
-	end
-	return nil
-end
-
---- Gets the possible egos
-function _M:getEgosList(level, type, group, class)
-	-- Already loaded ? use it
-	local list = level:getEntitiesList(type.."/"..group)
-	if list then return list end
-
-	-- otehrwise loads it and store it
-	list = require(class):loadList(group, true)
-	level:setEntitiesList(type.."/"..group, list)
-
-	return list
-end
-
---- Picks and resolve an entity
--- @param level a Level object to generate for
--- @param type one of "object" "terrain" "actor" "trap"
--- @param filter a filter table
--- @param force_level if not nil forces the current level for resolvers to this one
--- @param prob_filter if true a new probability list based on this filter will be generated, ensuring to find objects better but at a slightly slower cost (maybe)
--- @return the fully resolved entity, ready to be used on a level. Or nil if a filter was given an nothing found
-function _M:makeEntity(level, type, filter, force_level, prob_filter)
-	resolvers.current_level = self.base_level + level.level - 1
-	if force_level then resolvers.current_level = force_level end
-
-	local e
-	-- No probability list, use the default one and apply filter
-	if not prob_filter then
-		local list = level:getEntitiesList(type)
-		local tries = filter and filter.nb_tries or 500
-		-- CRUDE ! Brute force ! Make me smarter !
-		while tries > 0 do
-			e = self:pickEntity(list)
-			if e and self:checkFilter(e, filter) then break end
-			tries = tries - 1
-		end
-		if tries == 0 then return nil end
-	-- Generate a specific probability list, slower to generate but no need to "try and be lucky"
-	elseif filter then
-		local base_list = nil
-		if type == "actor" then base_list = self.npc_list
-		elseif type == "object" then base_list = self.object_list
-		elseif type == "trap" then base_list = self.trap_list
-		else return nil end
-		local list = self:computeRarities(type, base_list, level, function(e) return self:checkFilter(e, filter) end, filter.add_levels, filter.special_rarity)
-		e = self:pickEntity(list)
-		print("[MAKE ENTITY] prob list generation", e and e.name, "from list size", #list)
-		if not e then return nil end
-	-- No filter
-	else
-		local list = level:getEntitiesList(type)
-		e = self:pickEntity(list)
-		if not e then return nil end
-	end
-
-	if filter then e.force_ego = filter.force_ego end
-
-	e = self:finishEntity(level, type, e, filter and filter.ego_chance)
-
-	return e
-end
-
---- Find a given entity and resolve it
--- @return the fully resolved entity, ready to be used on a level. Or nil if a filter was given an nothing found
-function _M:makeEntityByName(level, type, name)
-	resolvers.current_level = self.base_level + level.level - 1
-
-	local e
-	if type == "actor" then e = self.npc_list[name]
-	elseif type == "object" then e = self.object_list[name]
-	elseif type == "grid" or type == "terrain" then e = self.grid_list[name]
-	elseif type == "trap" then e = self.trap_list[name]
-	end
-	if not e then return nil end
-
-	if e.unique and game.uniques[e.__CLASSNAME.."/"..e.unique] then print("refused unique", e.name, e.__CLASSNAME.."/"..e.unique) return nil end
-
-	e = self:finishEntity(level, type, e)
-
-	return e
-end
-
---- Finishes generating an entity
-function _M:finishEntity(level, type, e, ego_chance)
-	e = e:clone()
-	e:resolve()
-
-	-- Add "ego" properties, sometimes
-	if not e.unique and e.egos and (e.force_ego or e.egos_chance) then
-		local egos_list = {}
-		if not e.force_ego then
-			if _G.type(e.egos_chance) == "number" then e.egos_chance = {e.egos_chance} end
-			-- Pick an ego, then an other and so until we get no more
-			local picked_etype = {}
-			local etype = rng.tableIndex(e.egos_chance, picked_etype)
-			local echance = etype and e.egos_chance[etype]
-			while etype and rng.percent(util.bound(echance + (ego_chance or 0), 0, 100)) do
-				picked_etype[etype] = true
-				if _G.type(etype) == "number" then etype = "" end
-				local egos = level:getEntitiesList(type.."/"..e.egos..":"..etype)
-				egos_list[#egos_list+1] = self:pickEntity(egos)
-				if egos_list[#egos_list] then print("Picked ego", type.."/"..e.egos..":"..etype, ":=>", egos_list[#egos_list].name) else print("Picked ego", type.."/"..e.egos..":"..etype, ":=>", #egos_list) end
-
-				etype = rng.tableIndex(e.egos_chance, picked_etype)
-				echance = e.egos_chance[etype]
-			end
-		else
-			local name = e.force_ego
-			if _G.type(name) == "table" then name = rng.table(name) end
-			print("Forcing ego", name)
-			local egos = level:getEntitiesList(type.."/base/"..e.egos..":")
-			egos_list = {egos[name]}
-			e.force_ego = nil
-		end
-
-		if #egos_list > 0 then
-			for ie, ego in ipairs(egos_list) do
-				print("ego", ego.__CLASSNAME, ego.name, getmetatable(ego))
-				ego = ego:clone()
-				local newname
-				if ego.prefix then newname = ego.name .. e.name
-				else newname = e.name .. ego.name end
-				print("applying ego", ego.name, "to ", e.name, "::", newname, "///", e.unided_name, ego.unided_name)
-				ego.unided_name = nil
-				-- The ego requested instant resolving before merge ?
-				if ego.instant_resolve then ego:resolve(nil, nil, e) end
-				ego.instant_resolve = nil
-				-- Void the uid, we dont want to erase the base entity's one
-				ego.uid = nil
-				-- Merge additively but with array appending, so that nameless resolvers are not lost
-				table.mergeAddAppendArray(e, ego, true)
-				e.name = newname
-				e.egoed = true
-			end
-			-- Re-resolve with the (possibly) new resolvers
-			e:resolve()
-		end
-		e.egos = nil e.egos_chance = nil e.force_ego = nil
-	end
-
-	-- Generate a stack ?
-	if e.generate_stack then
-		local s = {}
-		while e.generate_stack > 0 do
-			s[#s+1] = e:clone()
-			e.generate_stack = e.generate_stack - 1
-		end
-		for i = 1, #s do e:stack(s[i]) end
-	end
-
-	e:resolve(nil, true)
-
-	return e
-end
-
---- Do the various stuff needed to setup an entity on the level
--- Grids do not really need that, this is mostly done for traps, objects and actors<br/>
--- This will do all the corect initializations and setup required
--- @param level the level on which to add the entity
--- @param e the entity to add
--- @param typ the type of entity, one of "actor", "object", "trap" or "terrain"
--- @param x the coordinates where to add it. This CAN be null in which case it wont be added to the map
--- @param y the coordinates where to add it. This CAN be null in which case it wont be added to the map
-function _M:addEntity(level, e, typ, x, y)
-	if typ == "actor" then
-		-- We are additing it, this means there is no old position
-		e.x = nil
-		e.y = nil
-		if x and y then e:move(x, y, true) end
-		level:addEntity(e)
-		e:added()
-
-		-- Levelup ?
-		if self.actor_adjust_level and e.forceLevelup then
-			local newlevel = self:actor_adjust_level(level, e)
-			e:forceLevelup(newlevel)
-		end
-	elseif typ == "projectile" then
-		-- We are additing it, this means there is no old position
-		e.x = nil
-		e.y = nil
-		if x and y then e:move(x, y, true) end
-		if e.src then level:addEntity(e, e.src)
-		else level:addEntity(e) end
-		e:added()
-	elseif typ == "object" then
-		if x and y then level.map:addObject(x, y, e) end
-		e:added()
-	elseif typ == "trap" then
-		if x and y then level.map(x, y, Map.TRAP, e) end
-		e:added()
-	elseif typ == "terrain" or typ == "grid" then
-		if x and y then level.map(x, y, Map.TERRAIN, e) end
-	end
-	e:check("addedToLevel", level, x, y)
-	e:check("on_added", level, x, y)
-end
-
-function _M:load(dynamic)
-	local ret = true
-	-- Try to load from a savefile
-	local save = Savefile.new(game.save_name)
-	local data = save:loadZone(self.short_name)
-	save:close()
-
-	if not data and not dynamic then
-		local f, err = loadfile("/data/zones/"..self.short_name.."/zone.lua")
-		if err then error(err) end
-		data = f()
-		ret = false
-	elseif not data and dynamic then
-		data = dynamic
-		ret = false
-	end
-	for k, e in pairs(data) do self[k] = e end
-	return ret
-end
-
-local recurs = function(t)
-	local nt = {}
-	for k, e in pairs(nt) do if k ~= "__CLASSNAME" then nt[k] = e end end
-	return nt
-end
-function _M:getLevelData(lev)
-	local res = table.clone(self, true)
-	if self.levels[lev] then
-		table.merge(res, self.levels[lev], true)
-	end
-	-- Make sure it is not considered a class
-	res.__CLASSNAME = nil
-	return res
-end
-
---- Leave the level, forgetting uniques and such
-function _M:leaveLevel(no_close, lev, old_lev)
-	-- Before doing anything else, close the current level
-	if not no_close and game.level and game.level.map then
-		game:leaveLevel(game.level, lev, old_lev)
-
-		if type(game.level.data.persistant) == "string" and game.level.data.persistant == "zone" then
-			print("[LEVEL] persisting to zone memory", game.level.id)
-			self.memory_levels = self.memory_levels or {}
-			self.memory_levels[game.level.level] = game.level
-		elseif type(game.level.data.persistant) == "string" and game.level.data.persistant == "memory" then
-			print("[LEVEL] persisting to memory", game.level.id)
-			game.memory_levels = game.memory_levels or {}
-			game.memory_levels[game.level.id] = game.level
-		elseif game.level.data.persistant then
-			print("[LEVEL] persisting to disk file", game.level.id)
-			local save = Savefile.new(game.save_name)
-			save:saveLevel(game.level)
-			save:close()
-		else
-			game.level:removed()
-		end
-
-		game.level.map:close()
-	end
-end
-
---- Asks the zone to generate a level of level "lev"
--- @param lev the level (from 1 to zone.max_level)
--- @return a Level object
-function _M:getLevel(game, lev, old_lev, no_close)
-	self:leaveLevel(no_close, lev, old_lev)
-
-	local level_data = self:getLevelData(lev)
-
-	local level
-	-- Load persistant level?
-	if type(level_data.persistant) == "string" and level_data.persistant == "zone" then
-		self.memory_levels = self.memory_levels or {}
-		level = self.memory_levels[lev]
-
-		if level then
-			-- Setup the level in the game
-			game:setLevel(level)
-			-- Recreate the map because it could have been saved with a different tileset or whatever
-			-- This is not needed in case of a direct to file persistance becuase the map IS recreated each time anyway
-			level.map:recreate()
-		end
-	elseif type(level_data.persistant) == "string" and level_data.persistant == "memory" then
-		game.memory_levels = game.memory_levels or {}
-		level = game.memory_levels[self.short_name.."-"..lev]
-
-		if level then
-			-- Setup the level in the game
-			game:setLevel(level)
-			-- Recreate the map because it could have been saved with a different tileset or whatever
-			-- This is not needed in case of a direct to file persistance becuase the map IS recreated each time anyway
-			level.map:recreate()
-		end
-	elseif level_data.persistant then
-		local save = Savefile.new(game.save_name)
-		level = save:loadLevel(self.short_name, lev)
-		save:close()
-
-		if level then
-			-- Setup the level in the game
-			game:setLevel(level)
-		end
-	end
-
-	-- In any cases, make one if none was found
-	if not level then
-		local popup = Dialog:simplePopup("Generating level", "Please wait while generating the level...")
-		popup.__showup = nil
-		core.display.forceRedraw()
-
-		level = self:newLevel(level_data, lev, old_lev, game)
-
-		game:unregisterDialog(popup)
-	end
-
-	-- Clean up things
-	collectgarbage("collect")
-
-	return level
-end
-
-function _M:getGenerator(what, level, spots)
-	assert(level.data.generator[what], "requested zone generator of type "..tostring(what).." but it is not defined")
-	assert(level.data.generator[what].class, "requested zone generator of type "..tostring(what).." but it has no class field")
-	print("[GENERATOR] requiring", what, level.data.generator and level.data.generator[what] and level.data.generator[what].class)
-	return require(level.data.generator[what].class).new(
-			self,
-			level.map,
-			level,
-			spots
-		)
-end
-
-function _M:newLevel(level_data, lev, old_lev, game)
-	local map = self.map_class.new(level_data.width, level_data.height)
-	if level_data.all_lited then map:liteAll(0, 0, map.w, map.h) end
-	if level_data.all_remembered then map:rememberAll(0, 0, map.w, map.h) end
-
-	-- Setup the entities list
-	local level = self.level_class.new(lev, map)
-	level:setEntitiesList("actor", self:computeRarities("actor", self.npc_list, level, nil))
-	level:setEntitiesList("object", self:computeRarities("object", self.object_list, level, nil))
-	level:setEntitiesList("trap", self:computeRarities("trap", self.trap_list, level, nil))
-
-	-- Save level data
-	level.data = level_data
-	level.id = self.short_name.."-"..lev
-
-	-- Setup the level in the game
-	game:setLevel(level)
-
-	-- Generate the map
-	local generator = require(level_data.generator.map.class).new(
-		self,
-		map,
-		level,
-		level_data.generator.map
-	)
-	local ux, uy, dx, dy, spots = generator:generate(lev, old_lev)
-	spots = spots or {}
-
-	for i = 1, #spots do print("[NEW LEVEL] spot", spots[i].x, spots[i].y, spots[i].type, spots[i].subtype) end
-
-	level.default_up = {x=ux, y=uy}
-	level.default_down = {x=dx, y=dy}
-	level.spots = spots
-
-	-- Generate objects
-	if level_data.generator.object and level_data.generator.object.class then
-		local generator = self:getGenerator("object", level, spots)
-		generator:generate()
-	end
-
-	-- Generate traps
-	if level_data.generator.trap and level_data.generator.trap.class then
-		local generator = self:getGenerator("trap", level, spots)
-		generator:generate()
-	end
-
-	-- Generate actors
-	if level_data.generator.actor and level_data.generator.actor.class then
-		local generator = self:getGenerator("actor", level, spots)
-		generator:generate()
-	end
-
-	-- Adjust shown & obscure colors
-	if level_data.color_shown then map:setShown(unpack(level_data.color_shown)) end
-	if level_data.color_obscure then map:setObscure(unpack(level_data.color_obscure)) end
-
-	-- Call a finisher
-	if level_data.post_process then
-		level_data.post_process(level)
-	end
-
-	-- Delete the room_map, now useless
-	map.room_map = nil
-
-	-- Check for connectivity from entrance to exit
-	if not level_data.no_level_connectivity then
-		local a = Astar.new(map, game:getPlayer())
-		print("[LEVEL GENERATION] checking entrance to exit A*", ux, uy, "to", dx, dy)
-		if ux and uy and dx and dy and (ux ~= dx or uy ~= dy)  and not a:calc(ux, uy, dx, dy) then
-			print("Level unconnected, no way from entrance to exit", ux, uy, "to", dx, dy)
-			level:removed()
-			return self:newLevel(level_data, lev, old_lev, game)
-		end
-		for i = 1, #spots do
-			local spot = spots[i]
-			if spot.check_connectivity then
-				local cx, cy
-				if type(spot.check_connectivity) == "string" and spot.check_connectivity == "entrance" then cx, cy = ux, uy
-				elseif type(spot.check_connectivity) == "string" and spot.check_connectivity == "exit" then cx, cy = dx, dy
-				else cx, cy = spot.check_connectivity.x, spot.check_connectivity.y
-				end
-
-				print("[LEVEL GENERATION] checking A*", spot.x, spot.y, "to", cx, cy)
-				if spot.x and spot.y and cx and cy and (spot.x ~= cx or spot.y ~= cy) and not a:calc(spot.x, spot.y, cx, cy) then
-					print("Level unconnected, no way from", spot.x, spot.y, "to", cx, cy)
-					level:removed()
-					return self:newLevel(level_data, lev, old_lev, game)
-				end
-			end
-		end
-	end
-
-	return level
-end
diff --git a/game/engine/ai/simple.lua b/game/engine/ai/simple.lua
deleted file mode 100644
index 58b2957c08db3db662e2a4592bb5dde0470d01bf..0000000000000000000000000000000000000000
--- a/game/engine/ai/simple.lua
+++ /dev/null
@@ -1,122 +0,0 @@
--- 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
-
--- Defines a simple AI building blocks
--- Target nearest and move/attack it
-
-local Astar = require "engine.Astar"
-
-newAI("move_simple", function(self)
-	if self.ai_target.actor then
-		local tx, ty = self:aiSeeTargetPos(self.ai_target.actor)
-		return self:moveDirection(tx, ty)
-	end
-end)
-
-newAI("move_dmap", function(self)
-	if self.ai_target.actor then
-		local a = self.ai_target.actor
-		if self:hasLOS(a.x, a.y) then return self:runAI("move_simple") end
-
-		local c = a:distanceMap(self.x, self.y)
-		if not c then return self:runAI("move_simple") end
-		local dir = 5
-		for i = 1, 9 do
-			local sx, sy = util.coordAddDir(self.x, self.y, i)
-			local cd = a:distanceMap(sx, sy)
---			print("looking for dmap", dir, i, "::", c, cd)
-			if cd and cd > c and self:canMove(sx, sy) then c = cd; dir = i end
-		end
-
-		return self:moveDirection(util.coordAddDir(self.x, self.y, dir))
-	end
-end)
-
-newAI("flee_dmap", function(self)
-	if self.ai_target.actor then
-		local a = self.ai_target.actor
-
-		local c = a:distanceMap(self.x, self.y)
-		if not c then return end
-		local dir = 5
-		for i = 1, 9 do
-			local sx, sy = util.coordAddDir(self.x, self.y, i)
-			local cd = a:distanceMap(sx, sy)
---			print("looking for dmap", dir, i, "::", c, cd)
-			if not cd or (c and (cd < c and self:canMove(sx, sy))) then c = cd; dir = i end
-		end
-
-		return self:moveDirection(util.coordAddDir(self.x, self.y, dir))
-	end
-end)
-
-newAI("move_astar", function(self)
-	if self.ai_target.actor then
-		local tx, ty = self:aiSeeTargetPos(self.ai_target.actor)
-		local a = Astar.new(game.level.map, self)
-		local path = a:calc(self.x, self.y, tx, ty)
-		if not path then
-			return self:runAI("move_simple")
-		else
-			return self:move(path[1].x, path[1].y)
-		end
-	end
-end)
-
--- Find an hostile target
--- this requires the ActorFOV interface, or an interface that provides self.fov.actors*
-newAI("target_simple", function(self)
-	if self.ai_target.actor and not self.ai_target.actor.dead and rng.percent(90) then return true end
-
-	-- Find closer ennemy and target it
-	-- Get list of actors ordered by distance
-	local arr = self.fov.actors_dist
-	local act
-	for i = 1, #arr do
-		act = self.fov.actors_dist[i]
---		print("AI looking for target", self.uid, self.name, "::", act.uid, act.name, self.fov.actors[act].sqdist)
-		-- find the closest ennemy
-		if act and self:reactionToward(act) < 0 and not act.dead then
-			self.ai_target.actor = act
-			self:check("on_acquire_target", act)
-			return true
-		end
-	end
-end)
-
-newAI("target_player", function(self)
-	self.ai_target.actor = game.player
-	return true
-end)
-
-newAI("simple", function(self)
-	if self:runAI(self.ai_state.ai_target or "target_simple") then
-		return self:runAI(self.ai_state.ai_move or "move_simple")
-	end
-	return false
-end)
-
-newAI("dmap", function(self)
-	if self:runAI(self.ai_state.ai_target or "target_simple") then
-		return self:runAI(self.ai_state.ai_move or "move_dmap")
-	end
-	return false
-end)
-
-newAI("none", function(self) end)
diff --git a/game/engine/ai/special_movements.lua b/game/engine/ai/special_movements.lua
deleted file mode 100644
index db7365a5edf46d8ee4587d1e524a11e961ca0b30..0000000000000000000000000000000000000000
--- a/game/engine/ai/special_movements.lua
+++ /dev/null
@@ -1,58 +0,0 @@
--- 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
-
--- Defines some special movement AIs
-
--- Ghoul AI: move, pause, move pause, ...
-newAI("move_ghoul", function(self)
-	if self.ai_target.actor then
-		if not rng.percent(self.ai_state.pause_chance or 30) then
-			local tx, ty = self:aiSeeTargetPos(self.ai_target.actor)
-			return self:moveDirection(tx, ty)
-		else
-			self:useEnergy()
-			return true
-		end
-	end
-end)
-
--- Snake AI: move in the general direction but "slide" along
-newAI("move_snake", function(self)
-	if self.ai_target.actor then
-		local tx, ty = self:aiSeeTargetPos(self.ai_target.actor)
-		-- We we are in striking distance, strike!
-		if self:isNear(tx, ty) then
-			return self:moveDirection(tx, ty)
-		else
-			local rd = rng.range(1, 3)
-			if rd == 1 then
-				-- nothing, we move in the coerct direction
-			elseif rd == 2 then
-				-- move to the left
-				local dir = util.getDir(tx, ty, self.x, self.y)
-				tx, ty = util.coordAddDir(self.x, self.y, dir_sides[dir].left)
-			elseif rd == 3 then
-				-- move to the right
-				local dir = util.getDir(tx, ty, self.x, self.y)
-				tx, ty = util.coordAddDir(self.x, self.y, dir_sides[dir].right)
-			end
-			return self:moveDirection(tx, ty)
-		end
-	end
-end)
diff --git a/game/engine/ai/talented.lua b/game/engine/ai/talented.lua
deleted file mode 100644
index 70aa9dd3315a2decdf23e21baf5f9315d24c2e14..0000000000000000000000000000000000000000
--- a/game/engine/ai/talented.lua
+++ /dev/null
@@ -1,57 +0,0 @@
--- 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
-
--- Defines AIs that can use talents, either smartly or "dumbly"
-
--- Randomly use talents
-newAI("dumb_talented", function(self)
-	-- Find available talents
-	local avail = {}
-	local target_dist = math.floor(core.fov.distance(self.x, self.y, self.ai_target.actor.x, self.ai_target.actor.y))
-	for tid, _ in pairs(self.talents) do
-		local t = self:getTalentFromId(tid)
---		print(self.name, self.uid, "dumb ai talents can try use", t.name, tid, "::", t.mode, not self:isTalentCoolingDown(t), target_dist <= self:getTalentRange(t), self:preUseTalent(t, true), self:canProject({type="bolt"}, self.ai_target.actor.x, self.ai_target.actor.y))
-		if t.mode == "activated" and not self:isTalentCoolingDown(t) and target_dist <= self:getTalentRange(t) and self:preUseTalent(t, true, true) and self:canProject({type="bolt"}, self.ai_target.actor.x, self.ai_target.actor.y) and self:hasLOS(self.ai_target.actor.x, self.ai_target.actor.y) then
-			avail[#avail+1] = tid
-			print(self.name, self.uid, "dumb ai talents can use", t.name, tid)
-		elseif t.mode == "sustained" and not self:isTalentCoolingDown(t) and not self:isTalentActive(t.id) and self:preUseTalent(t, true, true) then
-			avail[#avail+1] = tid
-			print(self.name, self.uid, "dumb ai talents can activate", t.name, tid)
-		end
-	end
-	if #avail > 0 then
-		local tid = avail[rng.range(1, #avail)]
-		print("dumb ai uses", tid)
-		self:useTalent(tid)
-		return true
-	end
-end)
-
-newAI("dumb_talented_simple", function(self)
-	if self:runAI(self.ai_state.ai_target or "target_simple") then
-		-- One in "talent_in" chance of using a talent
-		if rng.chance(self.ai_state.talent_in or 6) and self:reactionToward(self.ai_target.actor) < 0 then
-			self:runAI("dumb_talented")
-		end
-		if not self.energy.used then
-			self:runAI(self.ai_state.ai_move or "move_simple")
-		end
-		return true
-	end
-end)
diff --git a/game/engine/class.lua b/game/engine/class.lua
deleted file mode 100644
index 50a696abe74c6bb83fbd9c3982294581c4aeaca5..0000000000000000000000000000000000000000
--- a/game/engine/class.lua
+++ /dev/null
@@ -1,246 +0,0 @@
--- 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
-
-module("class", package.seeall)
-
-local base = _G
-
-local function search(k, plist)
-	for i=1, #plist do
-		local v = plist[i][k]     -- try `i'-th superclass
-		if v then return v end
-	end
-end
-
-
-function make(c)
-	setmetatable(c, {__index=_M})
-	c.new = function(...)
-		local obj = {}
-		obj.__CLASSNAME = c._NAME
-		setmetatable(obj, {__index=c})
-		if obj.init then obj:init(...) end
-		return obj
-	end
-	return c
-end
-
-function inherit(base, ...)
-	local ifs = {...}
-	return function(c)
-		if #ifs == 0 then
-			setmetatable(c, {__index=base})
-		else
-			for i, _if in ipairs(ifs) do
-				for k, e in pairs(_if) do
-					if k ~= "init" and k ~= "_NAME" and k ~= "_M" and k ~= "_PACKAGE" and k ~= "new" then
-						c[k] = e
---						print(("caching interface value %s (%s) from %s to %s"):format(k, tostring(e), _if._NAME, c._NAME))
-					end
-				end
-			end
-			setmetatable(c, {__index=base})
-		end
-		c.new = function(...)
-			local obj = {}
-			obj.__CLASSNAME = c._NAME
-			setmetatable(obj, {__index=c})
-			if obj.init then obj:init(...) end
-			return obj
-		end
-		return c
-	end
-end
-
-function _M:getClassName()
-	return self.__CLASSNAME
-end
-
-function _M:getClass()
-	return getmetatble(self).__index
-end
-
-local function clonerecurs(d)
-	local n = {}
-	for k, e in pairs(d) do
-		local nk, ne = k, e
-		if type(k) == "table" and not k.__CLASSNAME then nk = clonerecurs(k) end
-		if type(e) == "table" and not e.__CLASSNAME then ne = clonerecurs(e) end
-		n[nk] = ne
-	end
-	return n
-end
---[[
-local function cloneadd(dest, src)
-	for k, e in pairs(src) do
-		local nk, ne = k, e
-		if type(k) == "table" then nk = cloneadd(k) end
-		if type(e) == "table" then ne = cloneadd(e) end
-		dest[nk] = ne
-	end
-end
-]]
-function _M:clone(t)
-	local n = clonerecurs(self)
-	if t then
---		error("cloning mutation not yet implemented")
---		cloneadd(n, t)
-		for k, e in pairs(t) do n[k] = e end
-	end
-	setmetatable(n, getmetatable(self))
-	if n.cloned then n:cloned(self) end
-	return n
-end
-
---- Replaces the object with an other, by copying (not deeply)
-function _M:replaceWith(t)
-	-- Delete fields
-	for k, e in pairs(self) do
-		self[k] = nil
-	end
-	for k, e in pairs(t) do
-		self[k] = e
-	end
-	setmetatable(self, getmetatable(t))
-end
-
--- ---------------------------------------------------------------------
--- ---------------------------------------------------------------------
--- LOAD & SAVE
--- ---------------------------------------------------------------------
--- ---------------------------------------------------------------------
-local function basicSerialize(o, t)
-	if t == "number" or t == "boolean" then
-		return tostring(o)
-	elseif t == "function" then
-		return string.format("loadstring(%q)", string.dump(o))
-	else   -- assume it is a string
-		return string.format("%q", o)
-	end
-end
-
-local function serialize_data(outf, name, value, saved, filter, allow, savefile, force)
-	saved = saved or {}       -- initial value
-	outf(name, " = ")
-	local tvalue = type(value)
-	if tvalue == "number" or tvalue == "string" or tvalue == "boolean" or tvalue == "function" then
-		outf(basicSerialize(value, tvalue), "\n")
-	elseif tvalue == "table" then
-		if not force and value.__CLASSNAME then
-			savefile:addToProcess(value)
-			outf("loadObject('", savefile:getFileName(value), "')\n")
-		elseif saved[value] then    -- value already saved?
-			outf(saved[value], "\n")  -- use its previous name
-		else
-			saved[value] = name   -- save name for next time
-			outf("{}\n")     -- create a new table
-
-			-- If we are the base table, decalre ourselves
-			if name == "data" then
-				outf('setLoaded("'..savefile:getFileName(value)..'", data)\n')
-			end
-
-			local k, v = next(value)
-			local tk
-			local fieldname
-			while k do
---				print(allow, k , filter[k], v, "will dump", (not allow and not filter[k]) or (allow and filter[k]))
-				if (not allow and not filter[k]) or (allow and filter[k]) then
-					-- Special case to handle index by objects
-					tk = type(k)
-					if tk == "table" and k.__CLASSNAME then
-						savefile:addToProcess(k)
-						fieldname = string.format("%s[loadObject('%s')]", name, savefile:getFileName(k))
-					else
-						fieldname = string.format("%s[%s]", name, basicSerialize(k, tk))
-					end
-					serialize_data(outf, fieldname, v, saved, {new=true}, false, savefile, false)
-				end
-				k, v = next(value, k)
-			end
-		end
-	else
-		error("cannot save a " .. tvalue .. " ("..name..")")
-	end
-end
-
-local function serialize(data, filter, allow, savefile)
-	local tbl = {}
-	local outf = function(...) local args={...} for i = 1, #args do tbl[#tbl+1] = args[i] end end
-	serialize_data(outf, "data", data, nil, filter, allow, savefile, true)
-	table.insert(tbl, "return data\n")
-	return tbl
-end
-
-function _M:save(filter, allow, savefile)
-	filter = filter or {}
-	if self._no_save_fields then table.merge(filter, self._no_save_fields) end
-	if not allow then
-		filter.new = true
-		filter._no_save_fields = true
-		filter._mo = true
-		filter._mo_final = true
-	else
-		filter.__CLASSNAME = true
-	end
-	local mt = getmetatable(self)
-	setmetatable(self, {})
-	local res = table.concat(serialize(self, filter, allow, engine.Savefile.current_save))
-	setmetatable(self, mt)
-	return res
-end
-
-_M.LOAD_SELF = {}
-
-local function deserialize(string, src)
-	local f, err = loadstring(string)
-	if err then print("error deserializing", string, err) end
-	setfenv(f, {
-		setLoaded = function(name, t)
---			print("[setLoaded]", name, t)
-			engine.Savefile.current_save.loaded[name] = t
-		end,
-		loadstring = loadstring,
-		loadObject = function(n)
-			if n == src then
-				return _M.LOAD_SELF
-			else
-				return engine.Savefile.current_save:loadReal(n)
-			end
-		end,
-	})
-	return f()
-end
-
-function load(str, delayloading)
-	local obj = deserialize(str, delayloading)
-	if obj then
---		print("setting obj class", obj.__CLASSNAME)
-		setmetatable(obj, {__index=require(obj.__CLASSNAME)})
-		if obj.loaded then
---			print("loader found for class", obj, obj.__CLASSNAME)
-			if delayloading and not obj.loadNoDelay then
-				engine.Savefile.current_save:addDelayLoad(obj)
-			else
-				obj:loaded()
-			end
-		end
-	end
-	return obj
-end
diff --git a/game/engine/colors.lua b/game/engine/colors.lua
deleted file mode 100644
index 0173a5a36e0ec85675c2ad2e68a72d336e759964..0000000000000000000000000000000000000000
--- a/game/engine/colors.lua
+++ /dev/null
@@ -1,82 +0,0 @@
--- 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
-
-colors = {}
-
-function defineColor(name, r, g, b, br, bg, bb)
-	colors[name] = {r=r, g=g, b=b, br=br, bg=bg, bb=bb}
-end
-
-defineColor('WHITE', 0xFF, 0xFF, 0xFF)
-defineColor('SLATE', 0x8C, 0x8C, 0x8C)
-defineColor('ORANGE', 0xFF, 0x77, 0x00)
-defineColor('RED', 0xC9, 0x00, 0x00)
-defineColor('GREEN', 0x00, 0x86, 0x45)
-defineColor('BLUE', 0x00, 0x00, 0xE3)
-defineColor('UMBER', 0x8E, 0x45, 0x00)
-defineColor('LIGHT_DARK', 0x50, 0x50, 0x50)
-defineColor('LIGHT_SLATE', 0xD1, 0xD1, 0xD1)
-defineColor('VIOLET', 0xC0, 0x00, 0xAF)
-defineColor('YELLOW', 0xFF, 0xFF, 0x00)
-defineColor('LIGHT_RED', 0xFF, 0x00, 0x68)
-defineColor('LIGHT_GREEN', 0x00, 0xFF, 0x00)
-defineColor('LIGHT_BLUE', 0x51, 0xDD, 0xFF)
-defineColor('LIGHT_UMBER', 0xD7, 0x8E, 0x45)
-defineColor('DARK_UMBER', 0x57, 0x5E, 0x25)
-
-defineColor('DARK_GREY', 67, 67, 67)
-defineColor('GREY', 127, 127, 127)
-
-defineColor('ROYAL_BLUE', 65, 105, 225)
-defineColor('AQUAMARINE', 127, 255, 212)
-defineColor('CADET_BLUE', 95, 158, 160)
-defineColor('STEEL_BLUE', 70, 130, 180)
-defineColor('TEAL', 0, 128, 128)
-defineColor('LIGHT_STEEL_BLUE', 176, 196, 222)
-defineColor('DARK_BLUE', 0x00, 0x00, 0x93)
-
-defineColor('PINK', 255, 192, 203)
-defineColor('GOLD', 255, 215, 0)
-defineColor('FIREBRICK', 178, 34, 34)
-defineColor('DARK_RED', 100, 0, 0)
-defineColor('VERY_DARK_RED', 50, 0, 0)
-defineColor('CRIMSON', 220, 20, 60)
-defineColor('MOCCASIN', 255, 228, 181)
-defineColor('KHAKI', 240, 230, 130)
-defineColor('SANDY_BROWN', 244, 164, 96)
-defineColor('SALMON', 250, 128, 114)
-
-defineColor('DARK_ORCHID', 153, 50, 204)
-defineColor('ORCHID', 218, 112, 214)
-defineColor('PURPLE', 128, 0, 139)
-
-defineColor('CHOCOLATE', 210, 105, 30)
-defineColor('DARK_KHAKI', 189, 183, 107)
-defineColor('TAN', 210, 180, 140)
-defineColor('DARK_TAN', 110, 80, 40)
-
-defineColor('HONEYDEW', 240, 255, 240)
-defineColor('ANTIQUE_WHITE', 250, 235, 215)
-defineColor('OLD_LACE', 253, 245, 230)
-defineColor('DARK_SLATE_GRAY', 47, 79, 79)
-
-defineColor('OLIVE_DRAB', 107, 142, 35)
-defineColor('DARK_SEA_GREEN', 143, 188, 143)
-defineColor('YELLOW_GREEN', 154, 205, 50)
-defineColor('DARK_GREEN', 50, 77, 12)
diff --git a/game/engine/dialogs/Chat.lua b/game/engine/dialogs/Chat.lua
deleted file mode 100644
index 434655889e6f8549861e48fcd179f43d6e74e448..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/Chat.lua
+++ /dev/null
@@ -1,137 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(chat, id)
-	self.cur_id = id
-	self.chat = chat
-	self.npc = chat.npc
-	self.player = chat.player
-	engine.Dialog.init(self, self.npc.name, 500, 400)
-
-	self:generateList()
-
-	self.sel = 1
-	self.scroll = 1
-	self.max = math.floor((self.ih - 5) / self.font_h) - 1
-
-	self:keyCommands({
-		__TEXTINPUT = function(c)
-			if c:find("^[a-z]$") then
-				self.sel = util.bound(1 + string.byte(c) - string.byte('a'), 1, #self.list)
-				self:use()
-			end
-		end,
-	},{
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		ACCEPT = function() self:use() end,
-	})
-	self:mouseZones{
-		{ x=0, y=0, w=self.w, h=self.h, fct=function(button, x, y, xrel, yrel, tx, ty)
-			if y >= self.start_answer_y then
-				ty = ty - self.start_answer_y
-				self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
-				self.changed = true
-				if button == "left" then self:use()
-				elseif button == "right" then
-				end
-			end
-		end },
-	}
-end
-
-function _M:use(a)
-	a = a or self.chat:get(self.cur_id).answers[self.list[self.sel].answer]
-	if not a then return end
-
-	self.changed = true
-
-	print("[CHAT] selected", a[1], a.action, a.jump)
-	if a.action then
-		local id = a.action(self.npc, self.player, self)
-		if id then
-			self.cur_id = id
-			self:regen()
-			return
-		end
-	end
-	if a.jump then
-		self.cur_id = a.jump
-		self:regen()
-	else
-		game:unregisterDialog(self)
-		return
-	end
-end
-
-function _M:regen()
-	self.changed = true
-	self:generateList()
-	self.sel = 1
-	self.scroll = 1
-end
-
-function _M:resolveAuto()
-	if not self.chat:get(self.cur_id).auto then return end
-	for i, a in ipairs(self.chat:get(self.cur_id).answers) do
-		if not a.cond or a.cond(self.npc, self.player) then
-			if not self:use(a) then return
-			else return self:resolveAuto()
-			end
-		end
-	end
-end
-
-function _M:generateList()
-	self:resolveAuto()
-
-	-- Makes up the list
-	local list = {}
-	local nb = 1
-	for i, a in ipairs(self.chat:get(self.cur_id).answers) do
-		if not a.cond or a.cond(self.npc, self.player) then
-			list[#list+1] = { name=string.char(string.byte('a')+nb-1)..") "..a[1], answer=i, color=a.color}
-			nb = nb + 1
-		end
-	end
-	self.list = list
-	return true
-end
-
-function _M:drawDialog(s)
-	local h = 5
-	local lines = self.chat:replace(self.chat:get(self.cur_id).text):splitLines(self.iw - 10, self.font)
-	local r, g, b
-	for i = 1, #lines do
-		r, g, b = s:drawColorStringBlended(self.font, lines[i], 5, 2 + h, r, g, b)
-		h = h + self.font:lineSkip()
-	end
-
-	self:drawWBorder(s, 5, h + 0.5 * self.font:lineSkip(), self.iw - 10)
-
-	-- Answers
-	self.start_answer_y = h + 1.5 * self.font:lineSkip()
-	self:drawSelectionList(s, 5, h + 1.5 * self.font:lineSkip(), self.font_h, self.list, self.sel, "name", self.scroll, self.max, nil, nil, self.iw - 10)
-	self.changed = false
-end
diff --git a/game/engine/dialogs/DisplayResolution.lua b/game/engine/dialogs/DisplayResolution.lua
deleted file mode 100644
index 5a146f633a453637bf60cd570b8ecb7856bdaff7..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/DisplayResolution.lua
+++ /dev/null
@@ -1,91 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init()
-	self:generateList()
-
-	engine.Dialog.init(self, "Switch Resolution", 300, #self.list * 30 + 20)
-
-	self.sel = 1
-	self.scroll = 1
-	self.max = math.floor((self.ih - 5) / self.font_h) - 1
-
-	self:keyCommands({
-		__TEXTINPUT = function(c)
-			if c:find("^[a-z]$") then
-				self.sel = util.bound(1 + string.byte(c) - string.byte('a'), 1, #self.list)
-				self:use()
-			end
-		end,
-	},{
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		ACCEPT = function() self:use() end,
-		EXIT = function() game:unregisterDialog(self) end,
-	})
-	self:mouseZones{
-		{ x=2, y=5, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
-			self.changed = true
-			self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
-			if button == "left" then self:use()
-			elseif button == "right" then
-			end
-		end },
-	}
-end
-
-function _M:use()
-	game:setResolution(self.list[self.sel].r)
-	game:unregisterDialog(self)
-end
-
-function _M:generateList()
-	local l = {}
-	for r, _ in pairs(game.available_resolutions) do
-		l[#l+1] = r
-	end
-	table.sort(l, function(a,b)
-		if game.available_resolutions[a][2] == game.available_resolutions[b][2] then
-			return (game.available_resolutions[a][3] and 1 or 0) < (game.available_resolutions[b][3] and 1 or 0)
-		elseif game.available_resolutions[a][1] == game.available_resolutions[b][1] then
-			return game.available_resolutions[a][2] < game.available_resolutions[b][2]
-		else
-			return game.available_resolutions[a][1] < game.available_resolutions[b][1]
-		end
-	end)
-
-	-- Makes up the list
-	local list = {}
-	local i = 0
-	for _, r in ipairs(l) do
-		list[#list+1] = { name=string.char(string.byte('a') + i)..")  "..r, r=r }
-		i = i + 1
-	end
-	self.list = list
-end
-
-function _M:drawDialog(s)
-	self:drawSelectionList(s, 2, 5, self.font_h, self.list, self.sel, "name", self.scroll, self.max)
-	self.chanegd = false
-end
diff --git a/game/engine/dialogs/DownloadDialog.lua b/game/engine/dialogs/DownloadDialog.lua
deleted file mode 100644
index 1dd07951ee4ef2571161c8e346b59d4b21652d90..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/DownloadDialog.lua
+++ /dev/null
@@ -1,85 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(title, url, on_finish)
-	self.url = url
-	self.received = 0
-	self.on_finish = on_finish
-
-	local font = core.display.newFont("/data/font/Vera.ttf", 12)
-	engine.Dialog.init(self, title or "Downloading...", math.max(400, font:size("From: "..url) + 10), 75, nil, nil, nil, font)
-
-	self:keyCommands({
-	},{
-	})
-end
-
-function _M:drawDialog(s)
-	if self.th then
-		local t = self.linda:receive(0, "final")
-		local len = self.linda:receive(0, "received")
-		while len do
-			len = self.linda:receive(0, "received")
-			if len then self.received = len end
-		end
-
-		local v, err = self.th:join(0)
-		if err then error(err) end
-
-		if t then
-			self.changed = false
-			self.linda = nil
-			self.th = nil
-			game:unregisterDialog(self)
-			self:on_finish(t)
-		end
-	end
-
-	s:drawStringBlended(self.font, "From: "..self.url, 2, 2, 255, 255, 255)
-	s:drawStringBlended(self.font, "Received: "..self.received, 2, 25, 255, 255, 255)
-end
-
-function _M:startDownload()
-	local l = lanes.linda()
-
-	function list_handler(src)
-		local http = require "socket.http"
-		local ltn12 = require "ltn12"
-
-		local t = {}
-		local size = 0
-		http.request{url = src, sink = function(chunk, err)
-			if chunk then
-				size = size + #chunk
-				l:send(0, "received", size)
-				table.insert(t, chunk)
-			end
-			return 1
-		end}
-		l:send("final", t)
-	end
-
-	self.th = lanes.gen("*", list_handler)(self.url)
-	self.linda = l
-end
diff --git a/game/engine/dialogs/GameMenu.lua b/game/engine/dialogs/GameMenu.lua
deleted file mode 100644
index fc2d4342d9c40ccc94e1117a0f6a6f9233f7c6db..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/GameMenu.lua
+++ /dev/null
@@ -1,110 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(actions)
-	self:generateList(actions)
-
-	engine.Dialog.init(self, "Game Menu", 300, #self.list * 30 + 20)
-
-	self.sel = 1
-	self.scroll = 1
-	self.max = math.floor((self.ih - 5) / self.font_h) - 1
-
-	self:keyCommands({
-		__TEXTINPUT = function(c)
-			if c:find("^[a-z]$") then
-				self.sel = util.bound(1 + string.byte(c) - string.byte('a'), 1, #self.list)
-				self.changed = true
-				self:use()
-			end
-		end,
-	},{
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		ACCEPT = function() self:use() end,
-		EXIT = function() game:unregisterDialog(self) end,
-	})
-	self:mouseZones{
-		{ x=2, y=5, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
-			self.changed = true
-			self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
-			if button == "left" then self:use()
-			elseif button == "right" then
-			end
-		end },
-	}
-end
-
-function _M:use()
-	self.list[self.sel].fct()
-end
-
-function _M:generateList(actions)
-	local default_actions = {
-		resume = { "Resume", function() game:unregisterDialog(self) end },
-		keybinds = { "Key Bindings", function()
-			game:unregisterDialog(self)
-			local menu = require("engine.dialogs.KeyBinder").new(game.normal_key)
-			game:registerDialog(menu)
-		end },
-		resolution = { "Display Resolution", function()
-			game:unregisterDialog(self)
-			local menu = require("engine.dialogs.DisplayResolution").new()
-			game:registerDialog(menu)
-		end },
-		achievements = { "Show Achievements", function()
-			game:unregisterDialog(self)
-			local menu = require("engine.dialogs.ShowAchievements").new()
-			game:registerDialog(menu)
-		end },
-		sound = { "Sound & Music", function()
-			game:unregisterDialog(self)
-			local menu = require("engine.dialogs.SoundMusic").new()
-			game:registerDialog(menu)
-		end },
-		save = { "Save Game", function() game:saveGame() end },
-		quit = { "Save and Exit", function() game:onQuit() end },
-	}
-
-	-- Makes up the list
-	local list = {}
-	local i = 0
-	for _, act in ipairs(actions) do
-		if type(act) == "string" then
-			local a = default_actions[act]
-			list[#list+1] = { name=string.char(string.byte('a') + i)..")  "..a[1], fct=a[2] }
-			i = i + 1
-		else
-			local a = act
-			list[#list+1] = { name=string.char(string.byte('a') + i)..")  "..a[1], fct=a[2] }
-			i = i + 1
-		end
-	end
-	self.list = list
-end
-
-function _M:drawDialog(s)
-	self:drawSelectionList(s, 2, 5, self.font_h, self.list, self.sel, "name", self.scroll, self.max)
-	self.changed = false
-end
diff --git a/game/engine/dialogs/GetQuantity.lua b/game/engine/dialogs/GetQuantity.lua
deleted file mode 100644
index bb67d0bf0be74d69680063b9ad9c9e326968a39e..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/GetQuantity.lua
+++ /dev/null
@@ -1,67 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(title, prompt, act)
-	engine.Dialog.init(self, title or "Quantity?", 300, 100)
-	self.prompt = prompt
-	self.act = act
-	self.qty = 0
-	self.first = true
-	self:keyCommands{
-		_ESCAPE = function()
-			game:unregisterDialog(self)
-		end,
-		_RETURN = function()
-			game:unregisterDialog(self)
-			act(self.qty)
-		end,
-		_BACKSPACE = function()
-			local b = tostring(self.qty)
-			b = b:sub(1, b:len() - 1)
-			if b == '' then self.qty = 0
-			else self.qty = tonumber(b)
-			end
-			self.changed = true
-		end,
-		__TEXTINPUT = function(c)
-			if not (c == '0' or c == '1' or c == '2' or c == '3' or c == '4' or c == '5' or c == '6' or c == '7' or c == '8' or c == '9') then return end
-			if self.qty >= 10000000 then return end
-			local b = tostring(self.qty)
-			if self.qty == 0 then b = "" end
-			if self.first then
-				self.qty = tonumber(c)
-				self.first = false
-			else
-				self.qty = tonumber(b .. c)
-			end
-			self.changed = true
-		end,
-	}
-end
-
-function _M:drawDialog(s, w, h)
-	s:drawColorStringBlendedCentered(self.font, self.prompt or "Quantity:", 2, 2, self.iw - 2, self.ih - 2 - self.font:lineSkip())
-	s:drawColorStringBlendedCentered(self.font, tostring(self.qty), 2, 2 + self.font:lineSkip(), self.iw - 2, self.ih - 2 - self.font:lineSkip())
-	self.changed = false
-end
diff --git a/game/engine/dialogs/GetText.lua b/game/engine/dialogs/GetText.lua
deleted file mode 100644
index 287454870849fc9a0c7a2a729dc7668f3cb24db9..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/GetText.lua
+++ /dev/null
@@ -1,60 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(title, text, min, max, action)
-	engine.Dialog.init(self, title, 300, 100)
-	self.text = text
-	self.min = min or 2
-	self.max = max or 25
-	self.name = ""
-	self:keyCommands({
-		_RETURN = function()
-			if self.name:len() >= self.min then
-				game:unregisterDialog(self)
-				action(self.name)
-			else
-				engine.Dialog:simplePopup("Error", "Must be between 2 and 25 characters.")
-			end
-		end,
-		_BACKSPACE = function()
-			self.name = self.name:sub(1, self.name:len() - 1)
-		end,
-		__TEXTINPUT = function(c)
-			if self.name:len() < self.max then
-				self.name = self.name .. c
-				self.changed = true
-			end
-		end,
-	},{
-		EXIT = function()
-			game:unregisterDialog(self)
-			action(nil)
-		end
-	})
-end
-
-function _M:drawDialog(s, w, h)
-	s:drawColorStringCentered(self.font, self.text..":", 2, 2, self.iw - 2, self.ih - 2 - self.font:lineSkip())
-	s:drawColorStringCentered(self.font, self.name, 2, 2 + self.font:lineSkip(), self.iw - 2, self.ih - 2 - self.font:lineSkip())
-end
diff --git a/game/engine/dialogs/KeyBinder.lua b/game/engine/dialogs/KeyBinder.lua
deleted file mode 100644
index be6fb9f1f9988d6d327a2a574a7b44161560c4ad..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/KeyBinder.lua
+++ /dev/null
@@ -1,170 +0,0 @@
--- 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"
-require "engine.Dialog"
-local KeyBind = require "engine.KeyBind"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(key_source)
-	engine.Dialog.init(self, "Key bindings", 600, game.h / 1.2)
-
-	self:generateList(key_source)
-
-	self.key_source = key_source
-
-	self.selcol = 1
-	self.sel = 1
-	self.scroll = 1
-	self.max = math.floor((self.ih - 5) / self.font_h) - 1
-
-	self:keyCommands({
-	},{
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_LEFT = function() self.selcol = util.boundWrap(self.selcol - 1, 1, 2) self.changed = true end,
-		MOVE_RIGHT = function() self.selcol = util.boundWrap(self.selcol + 1, 1, 2) self.changed = true end,
-		ACCEPT = function() self:use() end,
-		EXIT = function()
-			game:unregisterDialog(self)
-			self.key_source:bindKeys()
-			KeyBind:saveRemap()
-		end,
-	})
-	self:mouseZones{
-		{ x=2, y=5, w=600, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
-			if tx < 430 then
-				self.selcol = 1
-			else
-				self.selcol = 2
-			end
-			self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
-			self.changed = true
-			if button == "left" then self:use()
-			elseif button == "right" then
-			end
-		end },
-	}
-end
-
-function _M:use()
-	local t = self.list[self.sel]
-
-	--
-	-- Make a dialog to ask for the key
-	--
-	local title = "Press a key (or escape) for: "..t.name
-	local font = self.font
-	local w, h = font:size(title)
-	local d = engine.Dialog.new(title, w + 8, h + 25, nil, nil, nil, font)
-	d:keyCommands{__DEFAULT=function(sym, ctrl, shift, alt, meta, unicode)
-		-- Modifier keys are not treated
-		if sym == KeyBind._LCTRL or sym == KeyBind._RCTRL or
-		   sym == KeyBind._LSHIFT or sym == KeyBind._RSHIFT or
-		   sym == KeyBind._LALT or sym == KeyBind._RALT or
-		   sym == KeyBind._LMETA or sym == KeyBind._RMETA then
-			return
-		end
-
-		if sym == KeyBind._BACKSPACE then
-			t["bind"..self.selcol] = nil
-			KeyBind.binds_remap[t.type] = KeyBind.binds_remap[t.type] or t.k.default
-			KeyBind.binds_remap[t.type][self.selcol] = nil
-		elseif sym ~= KeyBind._ESCAPE then
-			local ks = KeyBind:makeKeyString(sym, ctrl, shift, alt, meta, unicode)
-			print("Binding", t.name, "to", ks)
-			t["bind"..self.selcol] = ks
-
-			KeyBind.binds_remap[t.type] = KeyBind.binds_remap[t.type] or t.k.default
-			KeyBind.binds_remap[t.type][self.selcol] = ks
-		end
-		game:unregisterDialog(d)
-	end}
-
-	d:mouseZones{ norestrict=true,
-		{ x=0, y=0, w=game.w, h=game.h, fct=function(button, x, y, xrel, yrel, tx, ty)
-			if xrel or yrel then return end
-			if button == "left" then return end
-
-			local ks = KeyBind:makeMouseString(
-				button,
-				core.key.modState("ctrl") and true or false,
-				core.key.modState("shift") and true or false,
-				core.key.modState("alt") and true or false,
-				core.key.modState("meta") and true or false
-			)
-			print("Binding", t.name, "to", ks)
-			t["bind"..self.selcol] = ks
-
-			KeyBind.binds_remap[t.type] = KeyBind.binds_remap[t.type] or t.k.default
-			KeyBind.binds_remap[t.type][self.selcol] = ks
-			game:unregisterDialog(d)
-		end },
-	}
-
-	d.drawDialog = function(self, s)
-		s:drawColorStringBlendedCentered(self.font, self.selcol == 1 and "Bind key" or "Bind alternate key", 2, 2, self.iw - 2, self.ih - 2)
-	end
-	game:registerDialog(d)
-end
-
-function _M:generateList(key_source)
-	local l = {}
-
-	for virtual, t in pairs(KeyBind.binds_def) do
-		if key_source.virtuals[virtual] then
-			l[#l+1] = t
-		end
-	end
-	table.sort(l, function(a,b)
-		if a.group ~= b.group then
-			return a.group < b.group
-		else
-			return a.order < b.order
-		end
-	end)
-
-	-- Makes up the list
-	local list = {}
-	local i = 0
-	for _, k in ipairs(l) do
-		local binds = KeyBind:getBindTable(k)
-		list[#list+1] = {
-			k = k,
-			name = k.name,
-			type = k.type,
-			bind1 = binds[1],
-			bind2 = binds[2],
-			b1 = function(v) return KeyBind:formatKeyString(v.bind1) end,
-			b2 = function(v) return KeyBind:formatKeyString(v.bind2) end,
-		}
-		i = i + 1
-	end
-	self.list = list
-end
-
-function _M:drawDialog(s)
-	local col = {155,155,0}
-	local selcol = {255,255,0}
-
-	self:drawSelectionList(s, 2,   5, self.font_h, self.list, self.sel, "name", self.scroll, self.max)
-	self:drawSelectionList(s, 230, 5, self.font_h, self.list, self.sel, "b1", self.scroll, self.max, col, self.selcol == 1 and selcol or col)
-	self:drawSelectionList(s, 430, 5, self.font_h, self.list, self.sel, "b2", self.scroll, self.max, col, self.selcol == 2 and selcol or col)
-end
diff --git a/game/engine/dialogs/ShowAchievements.lua b/game/engine/dialogs/ShowAchievements.lua
deleted file mode 100644
index b25d5b835407c73c61a1ada58798168997273c34..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/ShowAchievements.lua
+++ /dev/null
@@ -1,83 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(title)
-	local total = #world.achiev_defs
-	local nb = 0
-	for id, data in pairs(world.achieved) do nb = nb + 1 end
-
-	engine.Dialog.init(self, (title or "Achievements").." ("..nb.."/"..total..")", game.w * 0.8, game.h * 0.8, nil, nil, nil, core.display.newFont("/data/font/VeraMono.ttf", 12))
-
-	self:generateList()
-
-	self.sel = 1
-	self.scroll = 1
-	self.max = math.floor((self.ih - 5) / self.font_h) - 1
-
-	self:keyCommands({},{
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		EXIT = function() game:unregisterDialog(self) end,
-	})
-	self:mouseZones{
-		{ x=2, y=5, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
-			self.changed = true
-			self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
-		end },
-	}
-end
-
-function _M:generateList()
-	-- Makes up the list
-	local list = {}
-	local i = 0
-	for id, data in pairs(world.achieved) do
-		local a = world:getAchievementFromId(id)
-		list[#list+1] = { name=a.name,  desc=a.desc, when=data.when, who=data.who, order=a.order }
-		i = i + 1
-	end
-	table.sort(list, function(a, b) return a.order < b.order end)
-	self.list = list
-end
-
-function _M:drawDialog(s)
-	-- Description part
-	self:drawHBorder(s, self.iw / 2, 2, self.ih - 4)
-
-	local h = 2
-	if self.list[self.sel] then
-		local str = ("#GOLD#Achieved on:#LAST# %s\n#GOLD#Achieved by:#LAST# %s\n\n#GOLD#Description:#LAST# %s"):format(self.list[self.sel].when, self.list[self.sel].who, self.list[self.sel].desc)
-		lines = str:splitLines(self.iw / 2 - 10, self.font)
-	else
-		lines = {}
-	end
-	self:drawWBorder(s, self.iw / 2 + self.iw / 6, h - 0.5 * self.font:lineSkip(), self.iw / 6)
-	for i = 1, #lines do
-		s:drawColorStringBlended(self.font, lines[i], self.iw / 2 + 5, 2 + h)
-		h = h + self.font:lineSkip()
-	end
-
-	self:drawSelectionList(s, 2, 5, self.font_h, self.list, self.sel, "name", self.scroll, self.max)
-	self.changed = false
-end
diff --git a/game/engine/dialogs/ShowEquipInven.lua b/game/engine/dialogs/ShowEquipInven.lua
deleted file mode 100644
index e47a74e8e1c681c8339901deb73de18d2bb5b046..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/ShowEquipInven.lua
+++ /dev/null
@@ -1,192 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(title, actor, filter, action)
-	self.action = action
-	self.filter = filter
-	self.actor = actor
-
-	engine.Dialog.init(self, title or "Inventory", game.w * 0.8, game.h * 0.8, nil, nil, nil, core.display.newFont("/data/font/VeraMono.ttf", 12))
-
-	self:generateList()
-
-	self.list = self.inven_list
-	self.sel = 1
-	self.scroll = 1
-	self.max = math.floor((self.ih * 0.8 - 5) / self.font_h) - 1
-
-	self:keyCommands({
-		__TEXTINPUT = function(c)
-			if self.list.chars[c] then
-				self.sel = self.list.chars[c]
-				self:use()
-			end
-		end,
-	},{
-		HOTKEY_1 = function() self:defineHotkey(1) end,
-		HOTKEY_2 = function() self:defineHotkey(2) end,
-		HOTKEY_3 = function() self:defineHotkey(3) end,
-		HOTKEY_4 = function() self:defineHotkey(4) end,
-		HOTKEY_5 = function() self:defineHotkey(5) end,
-		HOTKEY_6 = function() self:defineHotkey(6) end,
-		HOTKEY_7 = function() self:defineHotkey(7) end,
-		HOTKEY_8 = function() self:defineHotkey(8) end,
-		HOTKEY_9 = function() self:defineHotkey(9) end,
-		HOTKEY_10 = function() self:defineHotkey(10) end,
-		HOTKEY_11 = function() self:defineHotkey(11) end,
-		HOTKEY_12 = function() self:defineHotkey(12) end,
-		HOTKEY_SECOND_1 = function() self:defineHotkey(13) end,
-		HOTKEY_SECOND_2 = function() self:defineHotkey(14) end,
-		HOTKEY_SECOND_3 = function() self:defineHotkey(15) end,
-		HOTKEY_SECOND_4 = function() self:defineHotkey(16) end,
-		HOTKEY_SECOND_5 = function() self:defineHotkey(17) end,
-		HOTKEY_SECOND_6 = function() self:defineHotkey(18) end,
-		HOTKEY_SECOND_7 = function() self:defineHotkey(19) end,
-		HOTKEY_SECOND_8 = function() self:defineHotkey(20) end,
-		HOTKEY_SECOND_9 = function() self:defineHotkey(21) end,
-		HOTKEY_SECOND_10 = function() self:defineHotkey(22) end,
-		HOTKEY_SECOND_11 = function() self:defineHotkey(23) end,
-		HOTKEY_SECOND_12 = function() self:defineHotkey(24) end,
-		HOTKEY_THIRD_1 = function() self:defineHotkey(25) end,
-		HOTKEY_THIRD_2 = function() self:defineHotkey(26) end,
-		HOTKEY_THIRD_3 = function() self:defineHotkey(27) end,
-		HOTKEY_THIRD_4 = function() self:defineHotkey(28) end,
-		HOTKEY_THIRD_5 = function() self:defineHotkey(29) end,
-		HOTKEY_THIRD_6 = function() self:defineHotkey(30) end,
-		HOTKEY_THIRD_7 = function() self:defineHotkey(31) end,
-		HOTKEY_THIRD_8 = function() self:defineHotkey(31) end,
-		HOTKEY_THIRD_9 = function() self:defineHotkey(33) end,
-		HOTKEY_THIRD_10 = function() self:defineHotkey(34) end,
-		HOTKEY_THIRD_11 = function() self:defineHotkey(35) end,
-		HOTKEY_THIRD_12 = function() self:defineHotkey(36) end,
-
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_LEFT = function() self.list = self.equip_list self.sel = util.bound(self.sel, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_RIGHT = function() self.list = self.inven_list self.sel = util.bound(self.sel, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		ACCEPT = function() self:use() end,
-		EXIT = function() game:unregisterDialog(self) end,
-	})
-	self:mouseZones{
-		{ x=2, y=5, w=self.iw, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
-			if tx < self.iw / 2 then
-				self.list = self.equip_list
-			else
-				self.list = self.inven_list
-			end
-			self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
-			self.changed = true
-
-			if button == "left" then self:use()
-			elseif button == "right" then
-			end
-		end },
-	}
-end
-
-function _M:defineHotkey(id)
-	if not self.actor or not self.actor.hotkey then return end
-
-	self.actor.hotkey[id] = {"inventory", self.list[self.sel].object:getName{no_count=true}}
-	self:simplePopup("Hotkey "..id.." assigned", self.list[self.sel].object:getName{no_count=true}:capitalize().." assigned to hotkey "..id)
-	self.actor.changed = true
-end
-
-function _M:use()
-	if self.list[self.sel] and self.list[self.sel].item then
-		if self.action(self.list[self.sel].object, self.list[self.sel].inven, self.list[self.sel].item) then
-			game:unregisterDialog(self)
-		end
-	end
-end
-
-function _M:generateList()
-	-- Makes up the list
-	local list = {}
-	local chars = {}
-	local i = 0
-	for inven_id =  1, #self.actor.inven_def do
-		if self.actor.inven[inven_id] and self.actor.inven_def[inven_id].is_worn then
-			list[#list+1] = { name=self.actor.inven_def[inven_id].name, color={0x90, 0x90, 0x90}, inven=inven_id }
-
-			for item, o in ipairs(self.actor.inven[inven_id]) do
-				if not self.filter or self.filter(o) then
-					local char = string.char(string.byte('a') + i)
-					list[#list+1] = { name=char..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=inven_id, item=item }
-					chars[char] = #list
-					i = i + 1
-				end
-			end
-		end
-	end
-	list.chars = chars
-	self.equip_list = list
-
-	-- Makes up the list
-	local list = {}
-	local chars = {}
-	local i = 0
-	for item, o in ipairs(self.actor:getInven("INVEN")) do
-		if not self.filter or self.filter(o) then
-			local char = string.char(string.byte('a') + i)
-			list[#list+1] = { name=char..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=self.actor.INVEN_INVEN, item=item }
-			chars[char] = #list
-			i = i + 1
-		end
-	end
-	list.chars = chars
-	self.inven_list = list
-	self.changed = true
-
-	self.list = self.inven_list
-	self.sel = 1
-	self.scroll = 1
-end
-
-function _M:on_recover_focus()
-	self:generateList()
-end
-
-function _M:drawDialog(s)
-	if self.list[self.sel] and not self.list[self.sel].item then
-		lines = self.actor.inven_def[self.list[self.sel].inven].description:splitLines(self.iw / 2 - 10, self.font)
-	elseif self.list[self.sel] and self.list[self.sel] and self.list[self.sel].object then
-		lines = self.list[self.sel].object:getDesc():splitLines(self.iw - 10, self.font)
-	else
-		lines = {}
-	end
-
-	local sh = self.ih - 4 - #lines * self.font:lineSkip()
-	h = sh
-	self:drawWBorder(s, 3, sh, self.iw - 6)
-	for i = 1, #lines do
-		s:drawColorStringBlended(self.font, lines[i], 5, 2 + h)
-		h = h + self.font:lineSkip()
-	end
-
-	self:drawSelectionList(s, 2, 5, self.font_h, self.equip_list, self.list == self.equip_list and self.sel or -1, "name", self.scroll, self.max)
-	self:drawHBorder(s, self.iw / 2, 2, sh - 4)
-	self:drawSelectionList(s, self.iw / 2 + 5, 5, self.font_h, self.inven_list, self.list == self.inven_list and self.sel or -1, "name", self.scroll, self.max)
-	self.changed = false
-end
diff --git a/game/engine/dialogs/ShowEquipment.lua b/game/engine/dialogs/ShowEquipment.lua
deleted file mode 100644
index cedfdf1081fd1ed065eb717a995ca1b32a596912..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/ShowEquipment.lua
+++ /dev/null
@@ -1,123 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(title, actor, filter, action)
-	self.actor = actor
-	self.filter = filter
-	self.action = action
-	engine.Dialog.init(self, title or "Equipment", game.w * 0.8, game.h * 0.8, nil, nil, nil, core.display.newFont("/data/font/VeraMono.ttf", 12))
-
-	self:generateList()
-
-	self.sel = 1
-	self.scroll = 1
-	self.max = math.floor((self.ih - 5) / self.font_h) - 1
-
-	self:keyCommands({
-		__TEXTINPUT = function(c)
-			if self.chars[c] then
-				self.sel = self.chars[c]
-				self:use()
-			end
-		end,
-	}, {
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		ACCEPT = function() self:use() end,
-		EXIT = function() game:unregisterDialog(self) end,
-	})
-	self:mouseZones{
-		{ x=2, y=5, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
-			self.changed = true
-			self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
-			if button == "left" then self:use()
-			elseif button == "right" then
-			end
-		end },
-	}
-end
-
-function _M:use()
-	if self.list[self.sel] then
-		self.action(self.list[self.sel].object, self.list[self.sel].inven, self.list[self.sel].item)
-	end
-	game:unregisterDialog(self)
-end
-
-function _M:generateList()
-	-- Makes up the list
-	local list = {}
-	local chars = {}
-	local i = 0
-	for inven_id =  1, #self.actor.inven_def do
-		if self.actor.inven[inven_id] and self.actor.inven_def[inven_id].is_worn then
-			list[#list+1] = { name=self.actor.inven_def[inven_id].name, color={0x90, 0x90, 0x90}, inven=inven_id }
-
-			for item, o in ipairs(self.actor.inven[inven_id]) do
-				if not self.filter or self.filter(o) then
-					local char = string.char(string.byte('a') + i)
-					list[#list+1] = { name=char..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=inven_id, item=item }
-					chars[char] = #list
-					i = i + 1
-				end
-			end
-		end
-	end
-	self.list = list
-	self.chars = chars
-end
-
-function _M:drawDialog(s)
-	-- Description part
-	self:drawHBorder(s, self.iw / 2, 2, self.ih - 4)
-
-	local talentshelp = ([[Keyboard: #00FF00#up key/down key#FFFFFF# to select an object; #00FF00#enter#FFFFFF# to use.
-Mouse: #00FF00#Left click#FFFFFF# to use.
-]]):splitLines(self.iw / 2 - 10, self.font)
-
-	local lines = {}
-	local h = 2
-	for i = 1, #talentshelp do
-		s:drawColorStringBlended(self.font, talentshelp[i], self.iw / 2 + 5, h)
-		h = h + self.font:lineSkip()
-	end
-
-	h = h + self.font:lineSkip()
-	if not self.list[self.sel].item then
-		lines = self.actor.inven_def[self.list[self.sel].inven].description:splitLines(self.iw / 2 - 10, self.font)
-	elseif self.list[self.sel] then
-		lines = self.list[self.sel].object:getDesc():splitLines(self.iw / 2 - 10, self.font)
-	else
-		lines = {}
-	end
-	self:drawWBorder(s, self.iw / 2 + self.iw / 6, h - 0.5 * self.font:lineSkip(), self.iw / 6)
-	for i = 1, #lines do
-		s:drawColorStringBlended(self.font, lines[i], self.iw / 2 + 5, 2 + h)
-		h = h + self.font:lineSkip()
-	end
-
-	-- Talents
-	self:drawSelectionList(s, 2, 5, self.font_h, self.list, self.sel, "name", self.scroll, self.max)
-	self.changed = false
-end
diff --git a/game/engine/dialogs/ShowInventory.lua b/game/engine/dialogs/ShowInventory.lua
deleted file mode 100644
index ee698ea73d89cb6e7c6b35f250dee8ec6fdad549..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/ShowInventory.lua
+++ /dev/null
@@ -1,165 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(title, inven, filter, action, actor)
-	self.inven = inven
-	self.filter = filter
-	self.action = action
-	self.actor = actor
-	engine.Dialog.init(self, title or "Inventory", game.w * 0.8, game.h * 0.8, nil, nil, nil, core.display.newFont("/data/font/VeraMono.ttf", 12))
-
-	self:generateList()
-
-	self.sel = 1
-	self.scroll = 1
-	self.max = math.floor((self.ih - 5) / self.font_h) - 1
-
-	self:keyCommands({
-		__TEXTINPUT = function(c)
-			if c:find("^[a-z]$") then
-				self.sel = util.bound(1 + string.byte(c) - string.byte('a'), 1, #self.list)
-				self:use()
-			end
-		end,
-	},{
-		HOTKEY_1 = function() self:defineHotkey(1) end,
-		HOTKEY_2 = function() self:defineHotkey(2) end,
-		HOTKEY_3 = function() self:defineHotkey(3) end,
-		HOTKEY_4 = function() self:defineHotkey(4) end,
-		HOTKEY_5 = function() self:defineHotkey(5) end,
-		HOTKEY_6 = function() self:defineHotkey(6) end,
-		HOTKEY_7 = function() self:defineHotkey(7) end,
-		HOTKEY_8 = function() self:defineHotkey(8) end,
-		HOTKEY_9 = function() self:defineHotkey(9) end,
-		HOTKEY_10 = function() self:defineHotkey(10) end,
-		HOTKEY_11 = function() self:defineHotkey(11) end,
-		HOTKEY_12 = function() self:defineHotkey(12) end,
-		HOTKEY_SECOND_1 = function() self:defineHotkey(13) end,
-		HOTKEY_SECOND_2 = function() self:defineHotkey(14) end,
-		HOTKEY_SECOND_3 = function() self:defineHotkey(15) end,
-		HOTKEY_SECOND_4 = function() self:defineHotkey(16) end,
-		HOTKEY_SECOND_5 = function() self:defineHotkey(17) end,
-		HOTKEY_SECOND_6 = function() self:defineHotkey(18) end,
-		HOTKEY_SECOND_7 = function() self:defineHotkey(19) end,
-		HOTKEY_SECOND_8 = function() self:defineHotkey(20) end,
-		HOTKEY_SECOND_9 = function() self:defineHotkey(21) end,
-		HOTKEY_SECOND_10 = function() self:defineHotkey(22) end,
-		HOTKEY_SECOND_11 = function() self:defineHotkey(23) end,
-		HOTKEY_SECOND_12 = function() self:defineHotkey(24) end,
-		HOTKEY_THIRD_1 = function() self:defineHotkey(25) end,
-		HOTKEY_THIRD_2 = function() self:defineHotkey(26) end,
-		HOTKEY_THIRD_3 = function() self:defineHotkey(27) end,
-		HOTKEY_THIRD_4 = function() self:defineHotkey(28) end,
-		HOTKEY_THIRD_5 = function() self:defineHotkey(29) end,
-		HOTKEY_THIRD_6 = function() self:defineHotkey(30) end,
-		HOTKEY_THIRD_7 = function() self:defineHotkey(31) end,
-		HOTKEY_THIRD_8 = function() self:defineHotkey(31) end,
-		HOTKEY_THIRD_9 = function() self:defineHotkey(33) end,
-		HOTKEY_THIRD_10 = function() self:defineHotkey(34) end,
-		HOTKEY_THIRD_11 = function() self:defineHotkey(35) end,
-		HOTKEY_THIRD_12 = function() self:defineHotkey(36) end,
-
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		ACCEPT = function() self:use() end,
-		EXIT = function() game:unregisterDialog(self) end,
-	})
-	self:mouseZones{
-		{ x=2, y=5, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
-			self.changed = true
-			self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
-			if button == "left" then self:use()
-			elseif button == "right" then
-			end
-		end },
-	}
-end
-
-function _M:defineHotkey(id)
-	if not self.actor or not self.actor.hotkey then return end
-
-	self.actor.hotkey[id] = {"inventory", self.list[self.sel].object:getName{no_count=true}}
-	self:simplePopup("Hotkey "..id.." assigned", self.list[self.sel].object:getName{no_count=true}:capitalize().." assigned to hotkey "..id)
-	self.actor.changed = true
-end
-
-function _M:use()
-	if self.list[self.sel] then
-		self.action(self.list[self.sel].object, self.list[self.sel].item)
-	end
-	game:unregisterDialog(self)
-end
-
-function _M:generateList()
-	-- Makes up the list
-	local list = {}
-	local i = 0
-	for item, o in ipairs(self.inven) do
-		if not self.filter or self.filter(o) then
-			list[#list+1] = { name=string.char(string.byte('a') + i)..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, item=item }
-			i = i + 1
-		end
-	end
-	self.list = list
-end
-
-function _M:drawDialog(s)
-	-- Description part
-	self:drawHBorder(s, self.iw / 2, 2, self.ih - 4)
-
-	local help
-	if self.actor and self.actor.hotkey then
-		help = [[Keyboard: #00FF00#up key/down key#FFFFFF# to select an object; #00FF00#enter#FFFFFF# to use. #00FF00#1-0#FFFFFF# to assign a hotkey.
-Mouse: #00FF00#Left click#FFFFFF# to use.
-]]
-	else
-		help = [[Keyboard: #00FF00#up key/down key#FFFFFF# to select an object; #00FF00#enter#FFFFFF# to use.
-Mouse: #00FF00#Left click#FFFFFF# to use.
-]]
-	end
-	local talentshelp = help:splitLines(self.iw / 2 - 10, self.font)
-
-	local lines = {}
-	local h = 2
-	for i = 1, #talentshelp do
-		s:drawColorStringBlended(self.font, talentshelp[i], self.iw / 2 + 5, h)
-		h = h + self.font:lineSkip()
-	end
-
-	h = h + self.font:lineSkip()
-	if self.list[self.sel] then
-		lines = self.list[self.sel].object:getDesc():splitLines(self.iw / 2 - 10, self.font)
-	else
-		lines = {}
-	end
-	self:drawWBorder(s, self.iw / 2 + self.iw / 6, h - 0.5 * self.font:lineSkip(), self.iw / 6)
-	for i = 1, #lines do
-		s:drawColorStringBlended(self.font, lines[i], self.iw / 2 + 5, 2 + h)
-		h = h + self.font:lineSkip()
-	end
-
-	-- Talents
-	self:drawSelectionList(s, 2, 5, self.font_h, self.list, self.sel, "name", self.scroll, self.max)
-	self.changed = false
-end
diff --git a/game/engine/dialogs/ShowPickupFloor.lua b/game/engine/dialogs/ShowPickupFloor.lua
deleted file mode 100644
index d12f914da4bf687eddbdcdfc896dcafa6e80ec8f..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/ShowPickupFloor.lua
+++ /dev/null
@@ -1,127 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(title, x, y, filter, action)
-	self.x, self.y = x, y
-	self.filter = filter
-	self.action = action
-	engine.Dialog.init(self, title or "Pickup", game.w * 0.8, game.h * 0.8, nil, nil, nil, core.display.newFont("/data/font/VeraMono.ttf", 12))
-
-	self:generateList()
-
-	self.sel = 1
-	self.scroll = 1
-	self.max = math.floor((self.ih - 5) / self.font_h) - 1
-
-	self:keyCommands({
-		_ASTERISK = function() while self:use() do end end,
-		__TEXTINPUT = function(c)
-			if c:find("^[a-z]$") then
-				self.sel = util.bound(1 + string.byte(c) - string.byte('a'), 1, #self.list)
-				self:use()
-			end
-		end,
-	},{
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		ACCEPT = function() self:use() end,
-		EXIT = function() game:unregisterDialog(self) end,
-	})
-	self:mouseZones{
-		{ x=2, y=5, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
-			self.changed = true
-			self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
-			if button == "left" then self:use()
-			elseif button == "right" then
-			end
-		end },
-	}
-end
-
-function _M:used()
-	self:generateList()
-	if #self.list == 0 then
-		game:unregisterDialog(self)
-		return false
-	end
-	return true
-end
-
-function _M:use()
-	if self.list[self.sel] then
-		self.action(self.list[self.sel].object, self.list[self.sel].item)
-	end
-	return self:used()
-end
-
-function _M:generateList()
-	-- Makes up the list
-	local list = {}
-	local idx = 1
-	local i = 1
-	while true do
-		local o = game.level.map:getObject(self.x, self.y, idx)
-		if not o then break end
-		if not self.filter or self.filter(o) then
-			list[#list+1] = { name=string.char(string.byte('a') + i - 1)..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, item=idx }
-			i = i + 1
-		end
-		idx = idx + 1
-	end
-	self.list = list
-	self.sel = 1
-	self.changed = true
-end
-
-function _M:drawDialog(s)
-	-- Description part
-	self:drawHBorder(s, self.iw / 2, 2, self.ih - 4)
-
-	local talentshelp = ([[Keyboard: #00FF00#up key/down key#FFFFFF# to select an object; #00FF00#enter#FFFFFF# to use.
-Mouse: #00FF00#Left click#FFFFFF# to pickup.
-]]):splitLines(self.iw / 2 - 10, self.font)
-
-	local lines = {}
-	local h = 2
-	for i = 1, #talentshelp do
-		s:drawColorStringBlended(self.font, talentshelp[i], self.iw / 2 + 5, h)
-		h = h + self.font:lineSkip()
-	end
-
-	h = h + self.font:lineSkip()
-	if self.list[self.sel] then
-		lines = self.list[self.sel].object:getDesc():splitLines(self.iw / 2 - 10, self.font)
-	else
-		lines = {}
-	end
-	self:drawWBorder(s, self.iw / 2 + self.iw / 6, h - 0.5 * self.font:lineSkip(), self.iw / 6)
-	for i = 1, #lines do
-		s:drawColorStringBlended(self.font, lines[i], self.iw / 2 + 5, 2 + h)
-		h = h + self.font:lineSkip()
-	end
-
-	-- Talents
-	self:drawSelectionList(s, 2, 5, self.font_h, self.list, self.sel, "name", self.scroll, self.max)
-	self.changed = false
-end
diff --git a/game/engine/dialogs/ShowQuests.lua b/game/engine/dialogs/ShowQuests.lua
deleted file mode 100644
index e4ac3885993a2b19f06ae20e65b16298c746c6b6..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/ShowQuests.lua
+++ /dev/null
@@ -1,106 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(actor)
-	self.actor = actor
-	actor.hotkey = actor.hotkey or {}
-	engine.Dialog.init(self, "Quest Log for "..actor.name, game.w, game.h)
-
-	self:generateList()
-
-	self.sel = 1
-	self.scroll = 1
-	self.max = math.floor((self.ih - 5) / self.font_h) - 1
-
-	self:keyCommands({
-		_t = function()
-			self.sel = 1
-			self.scroll = 1
-			self.show_ended = not self.show_ended
-			self:generateList()
-			self.changed = true        print("plop")
-		end,
-	},{
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		EXIT = function() game:unregisterDialog(self) end,
-	})
-	self:mouseZones{
-		{ x=2, y=5, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
-			self.changed = true
-			self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
-			if button == "left" then
-			elseif button == "right" then
-			end
-		end },
-	}
-end
-
-function _M:generateList()
-	-- Makes up the list
-	local list = {}
-	for id, q in pairs(self.actor.quests or {}) do
-		if not q:isEnded() or self.show_ended then
-			list[#list+1] = { name=q.name, quest=q, color = q:isCompleted() and {0,255,0} or nil }
-		end
-	end
-	if game.turn then
-		table.sort(list, function(a, b) return a.quest.gained_turn < b.quest.gained_turn end)
-	else
-		table.sort(list, function(a, b) return a.quest.name < b.quest.name end)
-	end
-	self.list = list
-end
-
-function _M:drawDialog(s)
-	-- Description part
-	self:drawHBorder(s, self.iw / 2, 2, self.ih - 4)
-
-	local r, g, b
-	local help = [[Keyboard: #00FF00#up key/down key#FFFFFF# to select a quest; #00FF00#t#FFFFFF# to toggle finished quests.
-]]
-	local talentshelp = help:splitLines(self.iw / 2 - 10, self.font)
-
-	local lines = {}
-	if self.list[self.sel] then
-		lines = self.list[self.sel].quest:desc(self.actor):splitLines(self.iw / 2 - 10, self.font)
-	end
-
-	local h = 2
-	for i = 1, #talentshelp do
-		s:drawColorStringBlended(self.font, talentshelp[i], self.iw / 2 + 5, h)
-		h = h + self.font:lineSkip()
-	end
-
-	h = h + self.font:lineSkip()
-	self:drawWBorder(s, self.iw / 2 + self.iw / 6, h - 0.5 * self.font:lineSkip(), self.iw / 6)
-	for i = 1, #lines do
-		r, g, b = s:drawColorStringBlended(self.font, lines[i], self.iw / 2 + 5, 2 + h, r, g, b)
-		h = h + self.font:lineSkip()
-	end
-
-	-- Talents
-	self:drawSelectionList(s, 2, 5, self.font_h, self.list, self.sel, "name", self.scroll, self.max)
-	self.changed = false
-end
diff --git a/game/engine/dialogs/ShowStore.lua b/game/engine/dialogs/ShowStore.lua
deleted file mode 100644
index 747e16c18dd3994b3103c3079558995fb7042c4f..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/ShowStore.lua
+++ /dev/null
@@ -1,135 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(title, store_inven, actor_inven, store_filter, actor_filter, action, desc)
-	self.action = action
-	self.desc = desc
-	self.store_inven = store_inven
-	self.actor_inven = actor_inven
-	self.store_filter = store_filter
-	self.actor_filter = actor_filter
-	engine.Dialog.init(self, title or "Store", game.w * 0.8, game.h * 0.8, nil, nil, nil, core.display.newFont("/data/font/VeraMono.ttf", 12))
-
-	self:generateList()
-
-	self.list = self.store_list
-	self.sel = 1
-	self.scroll = 1
-	self.max = math.floor((self.ih * 0.8 - 5) / self.font_h) - 1
-
-	self:keyCommands({
-		__TEXTINPUT = function(c)
-			if c:find("^[a-z]$") then
-				self.sel = util.bound(1 + string.byte(c) - string.byte('a'), 1, #self.list)
-				self:use()
-			end
-		end,
-	},{
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_LEFT = function() self.list = self.store_list self.sel = util.bound(self.sel, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_RIGHT = function() self.list = self.actor_list self.sel = util.bound(self.sel, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		ACCEPT = function() self:use() end,
-		EXIT = function() game:unregisterDialog(self) end,
-	})
-	self:mouseZones{
-		{ x=2, y=5, w=self.iw, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
-			if tx < self.iw / 2 then
-				self.list = self.store_list
-			else
-				self.list = self.actor_list
-			end
-			self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
-			self.changed = true
-			if button == "left" then self:use()
-			elseif button == "right" then
-			end
-		end },
-	}
-end
-
-function _M:updateStore()
-	self:generateList()
-	self.list = #self.store_list > 0 and self.store_list or self.actor_list
-	self.sel = util.bound(self.sel, 1, #self.list)
-	self.scroll = util.scroll(self.sel, self.scroll, self.max)
-	self.changed = true
-end
-
-function _M:use()
-	if self.list[self.sel] then
-		if self.list == self.store_list then
-			self.action("buy", self.list[self.sel].object, self.list[self.sel].item)
-			self:updateStore()
-		else
-			self.action("sell", self.list[self.sel].object, self.list[self.sel].item)
-			self:updateStore()
-		end
-	end
-end
-
-function _M:generateList()
-	-- Makes up the list
-	local list = {}
-	local i = 0
-	for item, o in ipairs(self.store_inven) do
-		if not self.store_filter or self.store_filter(o) then
-			list[#list+1] = { name=string.char(string.byte('a') + i)..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, item=item }
-			i = i + 1
-		end
-	end
-	self.store_list = list
-
-	-- Makes up the list
-	local list = {}
-	local i = 0
-	for item, o in ipairs(self.actor_inven) do
-		if not self.actor_filter or self.actor_filter(o) then
-			list[#list+1] = { name=string.char(string.byte('a') + i)..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, item=item }
-			i = i + 1
-		end
-	end
-	self.actor_list = list
-end
-
-function _M:drawDialog(s)
-	if self.list[self.sel] then
-		lines = self.desc(self.list == self.store_list and "buy" or "sell", self.list[self.sel].object):splitLines(self.iw - 10, self.font)
-	else
-		lines = {}
-	end
-
-	local sh = self.ih - 4 - #lines * self.font:lineSkip()
-	h = sh
-	self:drawWBorder(s, 3, sh, self.iw - 6)
-	for i = 1, #lines do
-		s:drawColorStringBlended(self.font, lines[i], 5, 2 + h)
-		h = h + self.font:lineSkip()
-	end
-
-	self:drawSelectionList(s, 2, 5, self.font_h, self.store_list, self.list == self.store_list and self.sel or -1, "name", self.scroll, self.max)
-	self:drawHBorder(s, self.iw / 2, 2, sh - 4)
-	self:drawSelectionList(s, self.iw / 2 + 5, 5, self.font_h, self.actor_list, self.list == self.actor_list and self.sel or -1, "name", self.scroll, self.max)
-	self.changed = false
-end
diff --git a/game/engine/dialogs/ShowText.lua b/game/engine/dialogs/ShowText.lua
deleted file mode 100644
index 6a8d350b00a1927924ffe38eb906a9f9362ca90d..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/ShowText.lua
+++ /dev/null
@@ -1,74 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(title, file, replace, w, h)
-	w = math.floor(w or game.w * 0.6)
-	h = math.floor(h or game.h * 0.8)
-
-	self.iw = w - 2 * 5 -- Cheat, this is normaly done by Dialog:init but we need it to generate the list and we needto generate it before init
-	self.font = core.display.newFont("/data/font/Vera.ttf", 12)
-	self:generateList(file, replace)
-	h = math.min(4 + (#self.list) * self.font:lineSkip(), h)
-
-	engine.Dialog.init(self, title or "Text", w, h, nil, nil, nil, self.font)
-
-	self.sel = 1
-	self.max = math.floor((self.ih - 5) / self.font_h) - 1
-
-	self:keyCommands({
-	},{
---		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.changed = true end,
---		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.changed = true end,
-		ACCEPT = function() game:unregisterDialog(self) end,
-		EXIT = "ACCEPT",
-	})
-	self:mouseZones{
-		{ x=0, y=0, w=self.w, h=self.h, fct=function(button, x, y, xrel, yrel, tx, ty)
-		end },
-	}
-end
-
-function _M:generateList(file, replace)
-	local f, err = loadfile("/data/texts/"..file..".lua")
-	if not f and err then error(err) end
-	setfenv(f, setmetatable({}, {__index=_G}))
-	local str = f()
-
-	str = str:gsub("@([^@]+)@", function(what)
-		if not replace[what] then return "" end
-		return util.getval(replace[what])
-	end)
-
-	self.list = str:splitLines(self.iw - 10, self.font)
-	return true
-end
-
-function _M:drawDialog(s)
-	for ii = self.sel, #self.list do
-		local i = ii - self.sel + 1
-		if not self.list[i] or 4 + (i) * self.font:lineSkip() >= self.ih then break end
-		s:drawColorStringBlended(self.font, self.list[i], 5, 4 + (i-1) * self.font:lineSkip())
-	end
-	self.changed = false
-end
diff --git a/game/engine/dialogs/SoundMusic.lua b/game/engine/dialogs/SoundMusic.lua
deleted file mode 100644
index d306483a357d6c6091e0cb828dde993b2e0927c4..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/SoundMusic.lua
+++ /dev/null
@@ -1,106 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init()
-	self:generateList()
-
-	engine.Dialog.init(self, "Sound & Music", 300, #self.list * 30 + 40)
-
-	self.sel = 1
-	self.scroll = 1
-	self.max = math.floor((self.ih - 5) / self.font_h) - 1
-
-	self:keyCommands({
-		__TEXTINPUT = function(c)
-			if c:find("^[a-z]$") then
-				self.sel = util.bound(1 + string.byte(c) - string.byte('a'), 1, #self.list)
-				self:use()
-			end
-		end,
-	},{
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_LEFT = function() self:changeVol(-5) self.changed = true end,
-		MOVE_RIGHT = function() self:changeVol(5) self.changed = true end,
-		ACCEPT = function() self:use() end,
-		EXIT = function() game:unregisterDialog(self) end,
-	})
-	self:mouseZones{
-		{ x=2, y=5, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
-			self.changed = true
-			self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
-			if button == "left" then self:use(true)
-			elseif button == "right" then self:use(false)
-			end
-		end },
-	}
-end
-
-function _M:changeVol(v)
-	print("vv", v, self.list[self.sel].act)
-	if self.list[self.sel].act == "music_volume" then
-		print("v<<v", v)
-		game:volumeMusic(game:volumeMusic() + v)
-		self:generateList()
-	elseif self.list[self.sel].act == "sound_volume" then
---		self:changeVol(v and 5 or -5)
-	end
-end
-
-function _M:use(v)
-	if self.list[self.sel].act == "enable" then
-		game:soundSystemStatus(true)
-		self:generateList()
-	elseif self.list[self.sel].act == "disable" then
-		game:soundSystemStatus(false)
-		self:generateList()
-	elseif self.list[self.sel].act == "music_volume" then
-		self:changeVol(v and 5 or -5)
-	elseif self.list[self.sel].act == "sound_volume" then
-		self:changeVol(v and 5 or -5)
-	end
---	game:unregisterDialog(self)
-end
-
-function _M:generateList()
-	-- Makes up the list
-	local list = {}
-	local i = 0
-
-	if game:soundSystemStatus() then
-		list[#list+1] = { name=string.char(string.byte('a') + i)..")  Disable sound & music", act="disable" } i = i + 1
-	else
-		list[#list+1] = { name=string.char(string.byte('a') + i)..")  Enable sound & music", act="enable" } i = i + 1
-	end
-	list[#list+1] = { name=string.char(string.byte('a') + i)..")  Music volume ("..game:volumeMusic().."%)", act="music_volume" } i = i + 1
---	list[#list+1] = { name=string.char(string.byte('a') + i)..")  Sound volume", act="sound_volume" } i = i + 1
-
-	self.list = list
-	self.changed = true
-end
-
-function _M:drawDialog(s)
-	self:drawSelectionList(s, 2, 5, self.font_h, self.list, self.sel, "name", self.scroll, self.max)
-	self.changed = false
-end
diff --git a/game/engine/dialogs/UseTalents.lua b/game/engine/dialogs/UseTalents.lua
deleted file mode 100644
index 23d6f73adf62f6c23aeacb09d162e1490afa2fd6..0000000000000000000000000000000000000000
--- a/game/engine/dialogs/UseTalents.lua
+++ /dev/null
@@ -1,192 +0,0 @@
--- 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"
-require "engine.Dialog"
-
-module(..., package.seeall, class.inherit(engine.Dialog))
-
-function _M:init(actor)
-	self.actor = actor
-	actor.hotkey = actor.hotkey or {}
-	engine.Dialog.init(self, "Use Talents: "..actor.name, game.w / 2, game.h / 2)
-
-	self:generateList()
-
-	self.scroll = 1
-	self.max = math.floor((self.ih - 5) / self.font_h) - 1
-
-	self:keyCommands({
-		__TEXTINPUT = function(c)
-			if c:find("^[a-zA-Z]$") then
-				local sel = self.keybind[c]
-				if sel then
-					self.sel = sel
-					self:use()
-				end
-			end
-		end,
-	},{
-		HOTKEY_1 = function() self:defineHotkey(1) end,
-		HOTKEY_2 = function() self:defineHotkey(2) end,
-		HOTKEY_3 = function() self:defineHotkey(3) end,
-		HOTKEY_4 = function() self:defineHotkey(4) end,
-		HOTKEY_5 = function() self:defineHotkey(5) end,
-		HOTKEY_6 = function() self:defineHotkey(6) end,
-		HOTKEY_7 = function() self:defineHotkey(7) end,
-		HOTKEY_8 = function() self:defineHotkey(8) end,
-		HOTKEY_9 = function() self:defineHotkey(9) end,
-		HOTKEY_10 = function() self:defineHotkey(10) end,
-		HOTKEY_11 = function() self:defineHotkey(11) end,
-		HOTKEY_12 = function() self:defineHotkey(12) end,
-		HOTKEY_SECOND_1 = function() self:defineHotkey(13) end,
-		HOTKEY_SECOND_2 = function() self:defineHotkey(14) end,
-		HOTKEY_SECOND_3 = function() self:defineHotkey(15) end,
-		HOTKEY_SECOND_4 = function() self:defineHotkey(16) end,
-		HOTKEY_SECOND_5 = function() self:defineHotkey(17) end,
-		HOTKEY_SECOND_6 = function() self:defineHotkey(18) end,
-		HOTKEY_SECOND_7 = function() self:defineHotkey(19) end,
-		HOTKEY_SECOND_8 = function() self:defineHotkey(20) end,
-		HOTKEY_SECOND_9 = function() self:defineHotkey(21) end,
-		HOTKEY_SECOND_10 = function() self:defineHotkey(22) end,
-		HOTKEY_SECOND_11 = function() self:defineHotkey(23) end,
-		HOTKEY_SECOND_12 = function() self:defineHotkey(24) end,
-		HOTKEY_THIRD_1 = function() self:defineHotkey(25) end,
-		HOTKEY_THIRD_2 = function() self:defineHotkey(26) end,
-		HOTKEY_THIRD_3 = function() self:defineHotkey(27) end,
-		HOTKEY_THIRD_4 = function() self:defineHotkey(28) end,
-		HOTKEY_THIRD_5 = function() self:defineHotkey(29) end,
-		HOTKEY_THIRD_6 = function() self:defineHotkey(30) end,
-		HOTKEY_THIRD_7 = function() self:defineHotkey(31) end,
-		HOTKEY_THIRD_8 = function() self:defineHotkey(31) end,
-		HOTKEY_THIRD_9 = function() self:defineHotkey(33) end,
-		HOTKEY_THIRD_10 = function() self:defineHotkey(34) end,
-		HOTKEY_THIRD_11 = function() self:defineHotkey(35) end,
-		HOTKEY_THIRD_12 = function() self:defineHotkey(36) end,
-
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		ACCEPT = function() self:use() end,
-		EXIT = function() game:unregisterDialog(self) end,
-	})
-	self:mouseZones{
-		{ x=2, y=5, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty)
-			self.changed = true
-			self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
-			if button == "left" then self:use()
-			elseif button == "right" then
-			end
-		end },
-	}
-end
-
-function _M:defineHotkey(id)
-	if not self.actor.hotkey then return end
-
-	self.actor.hotkey[id] = {"talent", self.list[self.sel].talent}
-	self:simplePopup("Hotkey "..id.." assigned", self.actor:getTalentFromId(self.list[self.sel].talent).name:capitalize().." assigned to hotkey "..id)
-	self.actor.changed = true
-end
-
-function _M:use()
-	game:unregisterDialog(self)
-	self.actor:useTalent(self.list[self.sel].talent)
-end
-
-function _M:makeKey(letter)
-	if letter >= 26 then
-		return string.char(string.byte('A') + letter - 26)
-	else
-		return string.char(string.byte('a') + letter)
-	end
-end
-
-function _M:generateList()
-	-- Makes up the list
-	local list = {}
-	local keybind = {}
-	local letter = 0
-	for i, tt in ipairs(self.actor.talents_types_def) do
-		local cat = tt.type:gsub("/.*", "")
-		local where = #list
-		local added = false
-
-		-- Find all talents of this school
-		for j, t in ipairs(tt.talents) do
-			if self.actor:knowTalent(t.id) and t.mode ~= "passive" then
-				local typename = "talent"
-				if t.type[1]:find("^spell/") then typename = "spell" end
-				list[#list+1] = { name=self:makeKey(letter)..")    "..t.name.." ("..typename..")"..(self.actor:isTalentActive(t.id) and " <sustaining>" or ""), talent=t.id }
-				keybind[self:makeKey(letter)] = #list + 1
-				if not self.sel then self.sel = #list + 1 end
-				letter = letter + 1
-				added = true
-			end
-		end
-
-		if added then
-			table.insert(list, where+1, { name=cat:capitalize().." / "..tt.name:capitalize(), type=tt.type, color={0x80, 0x80, 0x80} })
-		end
-	end
-	self.list = list
-	self.keybind = keybind
-end
-
-function _M:drawDialog(s)
-	-- Description part
-	self:drawHBorder(s, self.iw / 2, 2, self.ih - 4)
-
-	local help
-	if not self.actor.hotkey then
-		help = [[Keyboard: #00FF00#up key/down key#FFFFFF# to select a stat; #00FF00#enter#FFFFFF# to use.
-Mouse: #00FF00#Left click#FFFFFF# to use.
-]]
-	else
-		help = [[Keyboard: #00FF00#up key/down key#FFFFFF# to select a stat; #00FF00#enter#FFFFFF# to use.
-#00FF00#1-0#FFFFFF# to assign a hotkey.
-Mouse: #00FF00#Left click#FFFFFF# to use.
-]]
-	end
-	local talentshelp = help:splitLines(self.iw / 2 - 10, self.font)
-
-	local lines = {}
-	if self.list[self.sel].type then
-		lines = self.actor:getTalentTypeFrom(self.list[self.sel].type).description:splitLines(self.iw / 2 - 10, self.font)
-	else
-		local t = self.actor:getTalentFromId(self.list[self.sel].talent)
-		lines = self.actor:getTalentFullDescription(t):splitLines(self.iw / 2 - 10, self.font)
-	end
-
-	local h = 2
-	for i = 1, #talentshelp do
-		s:drawColorStringBlended(self.font, talentshelp[i], self.iw / 2 + 5, h)
-		h = h + self.font:lineSkip()
-	end
-
-	h = h + self.font:lineSkip()
-	self:drawWBorder(s, self.iw / 2 + self.iw / 6, h - 0.5 * self.font:lineSkip(), self.iw / 6)
-	for i = 1, #lines do
-		s:drawColorStringBlended(self.font, lines[i], self.iw / 2 + 5, 2 + h)
-		h = h + self.font:lineSkip()
-	end
-
-	-- Talents
-	self:drawSelectionList(s, 2, 5, self.font_h, self.list, self.sel, "name", self.scroll, self.max)
-	self.changed = false
-end
diff --git a/game/engine/generator/actor/Random.lua b/game/engine/generator/actor/Random.lua
deleted file mode 100644
index 6cf338e71629a0155909204c439ab07354065d80..0000000000000000000000000000000000000000
--- a/game/engine/generator/actor/Random.lua
+++ /dev/null
@@ -1,88 +0,0 @@
--- 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"
-require "engine.Generator"
-module(..., package.seeall, class.inherit(engine.Generator))
-
-function _M:init(zone, map, level, spots)
-	engine.Generator.init(self, zone, map, level, spots)
-	local data = level.data.generator.actor
-
-	if data.adjust_level then
-		self.adjust_level = {base=zone.base_level, lev = self.level.level, min=data.adjust_level[1], max=data.adjust_level[2]}
-	else
-		self.adjust_level = {base=zone.base_level, lev = self.level.level, min=0, max=0}
-	end
-	self.filters = data.filters
-	self.nb_npc = data.nb_npc or {10, 20}
-	self.area = data.area or {x1=0, x2=self.map.w-1, y1=0, y2=self.map.h-1}
-	self.guardian = data.guardian
-	self.post_generation = data.post_generation
-end
-
-function _M:generate()
-	self:regenFrom(1)
-
-	if self.level.level < self.zone.max_level then return end
-
-	if self.guardian then
-		local m = self.zone:makeEntityByName(self.level, "actor", self.guardian)
-		if m then
-			local x, y = rng.range(self.area.x1, self.area.x2), rng.range(self.area.y1, self.area.y2)
-			local tries = 0
-			while (not m:canMove(x, y) or self.map.room_map[x][y].special) and tries < 100 do
-				x, y = rng.range(self.area.x1, self.area.x2), rng.range(self.area.y1, self.area.y2)
-				tries = tries + 1
-			end
-			if tries < 100 then
-				self.spots[#self.spots+1] = {x=x, y=y, gardian=true, check_connectivity="entrance"}
-				self.zone:addEntity(self.level, m, "actor", x, y)
-				print("Guardian allocated: ", self.guardian, m.uid, m.name)
-			end
-		else
-			print("WARNING: Guardian not found: ", self.guardian)
-		end
-	end
-end
-
-function _M:generateOne()
-	local f = nil
-	if self.filters then f = self.filters[rng.range(1, #self.filters)] end
-	local m = self.zone:makeEntity(self.level, "actor", f, nil, true)
-	if m then
-		local x, y = rng.range(self.area.x1, self.area.x2), rng.range(self.area.y1, self.area.y2)
-		local tries = 0
-		while (not m:canMove(x, y) or self.map.room_map[x][y].special) and tries < 100 do
-			x, y = rng.range(self.area.x1, self.area.x2), rng.range(self.area.y1, self.area.y2)
-			tries = tries + 1
-		end
-		if tries < 100 then
-			self.zone:addEntity(self.level, m, "actor", x, y)
-			if self.post_generation then self.post_generation(m) end
-		end
-	end
-end
-
-function _M:regenFrom(current)
-	for i = current, rng.range(self.nb_npc[1], self.nb_npc[2]) do
-		self:generateOne()
-	end
-end
diff --git a/game/engine/generator/map/Cavern.lua b/game/engine/generator/map/Cavern.lua
deleted file mode 100644
index 9ecb6946bebf69c0946f7fda039c0fac6ec8822a..0000000000000000000000000000000000000000
--- a/game/engine/generator/map/Cavern.lua
+++ /dev/null
@@ -1,135 +0,0 @@
--- 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"
-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 = zone.grid_list
-	self.zoom = data.zoom or 12
-	self.hurst = data.hurst or 0.2
-	self.lacunarity = data.lacunarity or 4
-	self.octave = data.octave or 1
-	self.min_floor = data.min_floor or 900
-	self.noise = data.noise or "simplex"
-end
-
-function _M:generate(lev, old_lev)
-	print("Generating cavern")
-	local noise = core.noise.new(2, self.hurst, self.lacunarity)
-	local fills = {}
-	local opens = {}
-	local list = {}
-	for i = 0, self.map.w - 1 do
-		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:resolve("floor"))
-				opens[i][j] = #list+1
-				list[#list+1] = {x=i, y=j}
-			else
-				self.map(i, j, Map.TERRAIN, self:resolve("wall"))
-			end
-		end
-	end
-
-	local floodFill floodFill = function(x, y)
-		local q = {{x=x,y=y}}
-		local closed = {}
-		while #q > 0 do
-			local n = table.remove(q, 1)
-			if opens[n.x] and opens[n.x][n.y] then
-				closed[#closed+1] = n
-				list[opens[n.x][n.y]] = nil
-				opens[n.x][n.y] = nil
-				q[#q+1] = {x=n.x-1, y=n.y}
-				q[#q+1] = {x=n.x, y=n.y+1}
-				q[#q+1] = {x=n.x+1, y=n.y}
-				q[#q+1] = {x=n.x, y=n.y-1}
-
-				q[#q+1] = {x=n.x+1, y=n.y-1}
-				q[#q+1] = {x=n.x+1, y=n.y+1}
-				q[#q+1] = {x=n.x-1, y=n.y-1}
-				q[#q+1] = {x=n.x-1, y=n.y+1}
-			end
-		end
-		return closed
-	end
-
-	-- Process all open spaces
-	local groups = {}
-	while next(list) do
-		local i, l = next(list)
-		local closed = floodFill(l.x, l.y)
-		groups[#groups+1] = {id=id, list=closed}
-		print("Floodfill group", i, #closed)
-	end
-	-- If nothing exists, regen
-	if #groups == 0 then return self:generate(lev, old_lev) end
-
-	-- Sort to find the biggest group
-	table.sort(groups, function(a,b) return #a.list < #b.list end)
-	local g = groups[#groups]
-	if #g.list >= self.min_floor then
-		print("Ok floodfill")
-		for i = 1, #groups-1 do
-			for j = 1, #groups[i].list do
-				local jn = groups[i].list[j]
-				self.map(jn.x, jn.y, Map.TERRAIN, self:resolve("wall"))
-			end
-		end
-	else
-		return self:generate(lev, old_lev)
-	end
-
-	return self:makeStairsInside(lev, old_lev, {})
-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/engine/generator/map/Empty.lua b/game/engine/generator/map/Empty.lua
deleted file mode 100644
index bc6ccef51edd4f764c997972f422dc33d24cd94e..0000000000000000000000000000000000000000
--- a/game/engine/generator/map/Empty.lua
+++ /dev/null
@@ -1,40 +0,0 @@
--- 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"
-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.grid_list = zone.grid_list
-	self.floor = self:resolve("floor")
-	self.up = self:resolve("up")
-end
-
-function _M:generate()
-	for i = 0, self.map.w - 1 do for j = 0, self.map.h - 1 do
-		self.map(i, j, Map.TERRAIN, self.floor)
-	end end
-	-- Always starts at 1, 1
-	self.map(1, 1, Map.TERRAIN, self.up)
-	self.map.room_map[1][1].special = "exit"
-	return 1, 1
-end
diff --git a/game/engine/generator/map/Forest.lua b/game/engine/generator/map/Forest.lua
deleted file mode 100644
index 57b67c80407a5ae5d5579d92742a176db74b026f..0000000000000000000000000000000000000000
--- a/game/engine/generator/map/Forest.lua
+++ /dev/null
@@ -1,200 +0,0 @@
--- 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"
-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.noise = data.noise or "fbm_perlin"
-	self.zoom = data.zoom or 5
-	self.max_percent = data.max_percent or 80
-	self.sqrt_percent = data.sqrt_percent or 30
-	self.hurst = data.hurst or nil
-	self.lacunarity = data.lacunarity or nil
-	self.octave = data.octave or 4
-	self.do_ponds = data.do_ponds
-	if self.do_ponds then
-		self.do_ponds.zoom = self.do_ponds.zoom or 5
-		self.do_ponds.octave = self.do_ponds.octave or 5
-		self.do_ponds.hurst = self.do_ponds.hurst or nil
-		self.do_ponds.lacunarity = self.do_ponds.lacunarity or nil
-	end
-end
-
-function _M:addPond(x, y, spots)
-	local noise = core.noise.new(2, self.do_ponds.size.w, self.do_ponds.size.h)
-	local nmap = {}
-	local lowest = {v=100, x=nil, y=nil}
-	for i = 1, self.do_ponds.size.w do
-		nmap[i] = {}
-		for j = 1, self.do_ponds.size.h do
-			nmap[i][j] = noise:fbm_simplex(self.do_ponds.zoom * i / self.do_ponds.size.w, self.do_ponds.zoom * j / self.do_ponds.size.h, self.do_ponds.octave)
-			if nmap[i][j] < lowest.v then lowest.v = nmap[i][j]; lowest.x = i; lowest.y = j end
-		end
-	end
---	print("Lowest pond point", lowest.x, lowest.y," ::", lowest.v)
-
-	local quadrant = function(i, j)
-		local highest = {v=-100, x=nil, y=nil}
-		local l = line.new(lowest.x, lowest.y, i, j)
-		local lx, ly = l()
-		while lx do
---			print(lx, ly, nmap[lx][ly])
-			if nmap[lx][ly] > highest.v then highest.v = nmap[lx][ly]; highest.x = lx; highest.y = ly end
-			lx, ly = l()
-		end
---		print("Highest pond point", highest.x, highest.y," ::", highest.v)
-		local split = (highest.v + lowest.v)
-
-		local l = line.new(lowest.x, lowest.y, i, j)
-		local lx, ly = l()
-		while lx do
-			local stop = true
-			for _ = 1, #self.do_ponds.pond do
-				if nmap[lx][ly] < split * self.do_ponds.pond[_][1] then
-					self.map(lx-1+x, ly-1+y, Map.TERRAIN, self:resolve(self.do_ponds.pond[_][2], self.grid_list, true))
-					stop = false
-					break
-				end
-			end
-			if stop then break end
-			lx, ly = l()
-		end
-	end
-
-	for i = 1, self.do_ponds.size.w do
-		quadrant(i, 1)
-		quadrant(i, self.do_ponds.size.h)
-	end
-	for i = 1, self.do_ponds.size.h do
-		quadrant(1, i)
-		quadrant(self.do_ponds.size.w, i)
-	end
-
-	spots[#spots+1] = {x=x, y=y, type="pond", subtype="pond"}
-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("floor"))
-	end end
-
-	-- make the noise
-	local noise = core.noise.new(2, self.hurst, self.lacunarity)
-	for i = 1, self.map.w do
-		for j = 1, self.map.h do
-			local v = math.floor((noise[self.noise](noise, self.zoom * i / self.map.w, self.zoom * j / self.map.h, self.octave) / 2 + 0.5) * self.max_percent)
-			if (v >= self.sqrt_percent and rng.percent(v)) or (v < self.sqrt_percent and rng.percent(math.sqrt(v))) then
-				self.map(i-1, j-1, Map.TERRAIN, self:resolve("wall"))
-			else
-				self.map(i-1, j-1, Map.TERRAIN, self:resolve("floor"))
-			end
-		end
-	end
-
-	local spots = {}
-
-	if self.do_ponds then
-		for i = 1, rng.range(self.do_ponds.nb[1], self.do_ponds.nb[2]) do
-			self:addPond(rng.range(self.do_ponds.size.w, self.map.w - self.do_ponds.size.w), rng.range(self.do_ponds.size.h, self.map.h - self.do_ponds.size.h), spots)
-		end
-	end
-
-	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: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
-
---- 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: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:resolve("up"))
-			self.map.room_map[ux][uy].special = "exit"
-			break
-		end
-	end
-
-	return ux, uy, dx, dy, spots
-end
diff --git a/game/engine/generator/map/GOL.lua b/game/engine/generator/map/GOL.lua
deleted file mode 100644
index 71b1ca591c5eaf8d17d9c8745edc77dc41a5d509..0000000000000000000000000000000000000000
--- a/game/engine/generator/map/GOL.lua
+++ /dev/null
@@ -1,69 +0,0 @@
--- 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"
-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.grid_list = zone.grid_list
-	self.floor = self:resolve("floor")
-	self.wall = self:resolve("wall")
-	self.up = self:resolve("up")
-end
-
-function _M:generate()
-	for i = 0, self.map.w - 1 do for j = 0, self.map.h - 1 do
-		if rng.percent(45) then
-			self.map(i, j, Map.TERRAIN, self.floor)
-		else
-			self.map(i, j, Map.TERRAIN, self.wall)
-		end
-	end end
-
-	self:evolve()
-	self:evolve()
-	self:evolve()
---	self:evolve()
-
-	-- Always starts at 1, 1
-	self.map(1, 1, Map.TERRAIN, self.up)
-	self.map.room_map[1][1].special = "exit"
-	return 1, 1
-end
-
-function _M:evolve()
-	for i = 0, self.map.w - 1 do for j = 0, self.map.h - 1 do
-		self:liveOrDie(i, j)
-	end end
-end
-
-function _M:liveOrDie(x, y)
-	local nb = 0
-	for i = -1, 1 do for j = -1, 1 do if i ~= 0 or j ~= 0 then
-		local g = self.map(x+i, y+j, Map.TERRAIN)
-		if g and g == self.wall then nb = nb + 1 end
-	end end end
-
-	if nb < 4 or nb > 7 then self.map(x, y, Map.TERRAIN, self.floor)
-	elseif nb == 5 or nb == 6 then self.map(x, y, Map.TERRAIN, self.wall)
-	end
-end
diff --git a/game/engine/generator/map/Heightmap.lua b/game/engine/generator/map/Heightmap.lua
deleted file mode 100644
index 0a223680c24e8b329744c8418d9ff7c10fd74829..0000000000000000000000000000000000000000
--- a/game/engine/generator/map/Heightmap.lua
+++ /dev/null
@@ -1,66 +0,0 @@
--- 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 Heightmap = require "engine.Heightmap"
-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 = zone.grid_list
-	self.floor = self:resolve("floor")
-	self.wall = self:resolve("wall")
-	self.up = self:resolve("up")
-end
-
-function _M:generate()
-	for i = 0, self.map.w - 1 do for j = 0, self.map.h - 1 do
-		self.map(i, j, Map.TERRAIN, self.floor)
-	end end
-
-	-- make the fractal heightmap
-	local hm = Heightmap.new(self.map.w, self.map.h, 4, {
-		middle =	Heightmap.max,
-		up_left =	rng.range(Heightmap.min, Heightmap.max / 2),
-		down_left =	rng.range(Heightmap.min, Heightmap.max / 2),
-		up_right =	rng.range(Heightmap.min, Heightmap.max / 2),
-		down_right =	rng.range(Heightmap.min, Heightmap.max / 2)
-	})
-	hm:generate()
-
-	for i = 1, self.map.w do
-		for j = 1, self.map.h do
-			for z = #self.data.tiles, 1, -1 do
-				local t = self.data.tiles[z]
-				if hm.hmap[i][j] >= Heightmap.max * t[1] then
-					self.map(i-1, j-1, Map.TERRAIN, self.zone.grid_list[t[2]])
-					break
-				end
-			end
-		end
-	end
-
-	-- Always starts at 1, 1
-	self.map(1, 1, Map.TERRAIN, self.up)
-	self.map.room_map[1][1].special = "exit"
-	return 1, 1
-end
diff --git a/game/engine/generator/map/Maze.lua b/game/engine/generator/map/Maze.lua
deleted file mode 100644
index 97c3ea5b7bee91eb46a2fc4b997409da0712e5d7..0000000000000000000000000000000000000000
--- a/game/engine/generator/map/Maze.lua
+++ /dev/null
@@ -1,93 +0,0 @@
--- 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"
-require "engine.Generator"
-module(..., package.seeall, class.inherit(engine.Generator))
-
-function _M:init(zone, map, grid_list, data)
-	engine.Generator.init(self, zone, map, level)
-	self.data = data
-	self.grid_list = zone.grid_list
-	self.floor = self:resolve("floor")
-	self.wall = self:resolve("wall")
-	self.up = self:resolve("up")
-	self.down = self:resolve("down")
-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.wall)
-	end end
-
-	local xpos, ypos = 1, 1
-	local moves = {{xpos,ypos}}
-	while #moves > 0 do
-		local dir = {}
-		if self.map(xpos+2, ypos, Map.TERRAIN) == self.wall and xpos+2>0 and xpos+2<self.map.w-1 then
-			dir[#dir+1] = 6
-		end
-		if self.map(xpos-2, ypos, Map.TERRAIN) == self.wall and xpos-2>0 and xpos-2<self.map.w-1 then
-			dir[#dir+1] = 4
-		end
-		if self.map(xpos, ypos-2, Map.TERRAIN) == self.wall and ypos-2>0 and ypos-2<self.map.h-1 then
-			dir[#dir+1] = 8
-		end
-		if self.map(xpos, ypos+2, Map.TERRAIN) == self.wall and ypos+2>0 and ypos+2<self.map.h-1 then
-			dir[#dir+1] = 2
-		end
-
-		if #dir > 0 then
-			local d = dir[rng.range(1, #dir)]
-			if d == 4 then
-				self.map(xpos-2, ypos, Map.TERRAIN, self.floor)
-				self.map(xpos-1, ypos, Map.TERRAIN, self.floor)
-				xpos = xpos - 2
-			elseif d == 6 then
-				self.map(xpos+2, ypos, Map.TERRAIN, self.floor)
-				self.map(xpos+1, ypos, Map.TERRAIN, self.floor)
-				xpos = xpos + 2
-			elseif d == 8 then
-				self.map(xpos, ypos-2, Map.TERRAIN, self.floor)
-				self.map(xpos, ypos-1, Map.TERRAIN, self.floor)
-				ypos = ypos - 2
-			elseif d == 2 then
-				self.map(xpos, ypos+2, Map.TERRAIN, self.floor)
-				self.map(xpos, ypos+1, Map.TERRAIN, self.floor)
-				ypos = ypos + 2
-			end
-			table.insert(moves, {xpos, ypos})
-		else
-			local back = table.remove(moves)
-			xpos = back[1]
-			ypos = back[2]
-		end
-	end
-	-- Always starts at 1, 1
-	local ux, uy = 1, 1
-	local dx, dy = math.floor(self.map.w/2)*2-1-2*(1-math.mod(self.map.w,2)), math.floor(self.map.h/2)*2-1-2*(1-math.mod(self.map.h,2))
-	self.map(ux, uy, Map.TERRAIN, self.up)
-	self.map.room_map[ux][uy].special = "exit"
-	if lev < self.zone.max_level or self.data.force_last_stair then
-		self.map(dx, dy, Map.TERRAIN, self.down)
-		self.map.room_map[dx][dy].special = "exit"
-	end
-	return ux, uy, dx, dy
-end
diff --git a/game/engine/generator/map/Roomer.lua b/game/engine/generator/map/Roomer.lua
deleted file mode 100644
index 469aa91006e006aa74df51380f368cd16c6fa091..0000000000000000000000000000000000000000
--- a/game/engine/generator/map/Roomer.lua
+++ /dev/null
@@ -1,396 +0,0 @@
--- 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"
-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.data.tunnel_change = self.data.tunnel_change or 30
-	self.data.tunnel_random = self.data.tunnel_random or 10
-	self.data.door_chance = self.data.door_chance or 50
-	self.data.lite_room_chance = self.data.lite_room_chance or 25
-	self.grid_list = zone.grid_list
-
-	self.rooms = {}
-	for i, file in ipairs(data.rooms) do
-		if type(file) == "table" then
-			table.insert(self.rooms, {self:loadRoom(file[1]), chance_room=file[2]})
-		else
-			table.insert(self.rooms, self:loadRoom(file))
-		end
-	end
-end
-
-function _M:loadRoom(file)
-	local f, err = loadfile("/data/rooms/"..file..".lua")
-	if not f and err then error(err) end
-	setfenv(f, setmetatable({
-		Map = require("engine.Map"),
-	}, {__index=_G}))
-	local ret, err = f()
-	if not ret and err then error(err) end
-
-	-- We got a room generator function, save it for later
-	if type(ret) == "function" then
-		print("loaded room generator",file,ret)
-		return ret
-	end
-
-	-- Init the room with name and size
-	local t = { name=file, w=ret[1]:len(), h=#ret }
-
-	-- Read the room map
-	for j, line in ipairs(ret) do
-		local i = 1
-		for c in line:gmatch(".") do
-			t[i] = t[i] or {}
-			t[i][j] = c
-			i = i + 1
-		end
-	end
-	print("loaded room",file,t.w,t.h)
-
-	return t
-end
-
---- Make up a room
-function _M:roomAlloc(room, id, lev, old_lev)
-	if type(room) == 'function' then
-		print("room generator", room, "is making a room")
-		room = room(self, id, lev, old_lev)
-	end
-	print("alloc", room.name)
-	-- Sanity check
-	if self.map.w - 2 - room.w < 2 or self.map.h - 2 - room.h < 2 then return false end
-
-	local tries = 100
-	while tries > 0 do
-		local ok = true
-		local x, y = rng.range(1, self.map.w - 2 - room.w), rng.range(1, self.map.h - 2 - room.h)
-
-		-- Do we stomp ?
-		for i = 1, room.w do
-			for j = 1, room.h do
-				if self.map.room_map[i-1+x][j-1+y].room then ok = false break end
-			end
-			if not ok then break end
-		end
-
-		if ok then
-			local is_lit = rng.percent(self.data.lite_room_chance)
-
-			-- ok alloc it using the default generator or a specific one
-			if room.generator then
-				room:generator(x, y, is_lit)
-			else
-				for i = 1, room.w do
-					for j = 1, room.h do
-						self.map.room_map[i-1+x][j-1+y].room = id
-						local c = room[i][j]
-						if c == '!' then
-							self.map.room_map[i-1+x][j-1+y].room = nil
-							self.map.room_map[i-1+x][j-1+y].can_open = true
-							self.map(i-1+x, j-1+y, Map.TERRAIN, self:resolve('#'))
-						else
-							self.map(i-1+x, j-1+y, Map.TERRAIN, self:resolve(c))
-						end
-						if is_lit then self.map.lites(i-1+x, j-1+y, true) end
-					end
-				end
-			end
-			print("room allocated at", x, y,"with center",math.floor(x+(room.w-1)/2), math.floor(y+(room.h-1)/2))
-			return { id=id, x=x, y=y, cx=math.floor(x+(room.w-1)/2), cy=math.floor(y+(room.h-1)/2), room=room }
-		end
-		tries = tries - 1
-	end
-	return false
-end
-
---- Random tunnel dir
-function _M:randDir()
-	local dirs = {4,6,8,2}
-	local d = dir_to_coord[dirs[rng.range(1, #dirs)]]
-	return d[1], d[2]
-end
-
---- Find the direction in which to tunnel
-function _M:tunnelDir(x1, y1, x2, y2)
-	local xdir = (x1 == x2) and 0 or ((x1 < x2) and 1 or -1)
-	local ydir = (y1 == y2) and 0 or ((y1 < y2) and 1 or -1)
-	if xdir ~= 0 and ydir ~= 0 then
-		if rng.percent(50) then xdir = 0
-		else ydir = 0
-		end
-	end
-	return xdir, ydir
-end
-
-local mark_dirs = {
-	[4] = {9,6,3},
-	[6] = {7,4,1},
-	[8] = {1,2,3},
-	[2] = {7,8,9},
-}
---- Marks a tunnel as a tunnel and the space behind it
-function _M:markTunnel(x, y, xdir, ydir, id)
-	-- Disable the many prints of tunnelling
-	local print = function()end
-
-	x, y = x - xdir, y - ydir
-	local dir = coord_to_dir[xdir][ydir]
-	for i, d in ipairs(mark_dirs[dir]) do
-		local xd, yd = dir_to_coord[d][1], dir_to_coord[d][2]
-		if self.map:isBound(x+xd, y+yd) and not self.map.room_map[x+xd][y+yd].tunnel then self.map.room_map[x+xd][y+yd].tunnel = id print("mark tunnel", x+xd, y+yd , id) end
-	end
-	if not self.map.room_map[x][y].tunnel then self.map.room_map[x][y].tunnel = id print("mark tunnel", x, y , id) end
-end
-
---- Tunnel from x1,y1 to x2,y2
-function _M:tunnel(x1, y1, x2, y2, id)
-	if x1 == x2 and y1 == y2 then return end
-	-- Disable the many prints of tunnelling
-	local print = function()end
-
-	local xdir, ydir = self:tunnelDir(x1, y1, x2, y2)
---	print("tunneling from",x1, y1, "to", x2, y2, "initial dir", xdir, ydir)
-
-	local startx, starty = x1, y1
-	local tun = {}
-
-	local tries = 2000
-	local no_move_tries = 0
-	while tries > 0 do
-		if rng.percent(self.data.tunnel_change) then
-			if rng.percent(self.data.tunnel_random) then xdir, ydir = self:randDir()
-			else xdir, ydir = self:tunnelDir(x1, y1, x2, y2)
-			end
-		end
-
-		local nx, ny = x1 + xdir, y1 + ydir
-		while true do
-			if self.map:isBound(nx, ny) then break end
-
-			if rng.percent(self.data.tunnel_random) then xdir, ydir = self:randDir()
-			else xdir, ydir = self:tunnelDir(x1, y1, x2, y2)
-			end
-			nx, ny = x1 + xdir, y1 + ydir
-		end
-		print(feat, "try pos", nx, ny, "dir", coord_to_dir[xdir][ydir])
-
-		if self.map.room_map[nx][ny].special then
-			print(feat, "refuse special")
-		elseif self.map.room_map[nx][ny].room then
-			tun[#tun+1] = {nx,ny}
-			x1, y1 = nx, ny
-			print(feat, "accept room")
-		elseif self.map.room_map[nx][ny].can_open ~= nil then
-			if self.map.room_map[nx][ny].can_open then
-				print(feat, "tunnel crossing can_open", nx,ny)
-				for i = -1, 1 do for j = -1, 1 do if self.map:isBound(nx + i, ny + j) and self.map.room_map[nx + i][ny + j].can_open then
-					self.map.room_map[nx + i][ny + j].can_open = false
-					print(feat, "forbiding crossing at ", nx+i,ny+j)
-				end end end
-				tun[#tun+1] = {nx,ny,true}
-				x1, y1 = nx, ny
-				print(feat, "accept can_open")
-			else
-				print(feat, "reject can_open")
-			end
-		elseif self.map.room_map[nx][ny].tunnel then
-			if self.map.room_map[nx][ny].tunnel ~= id or no_move_tries >= 15 then
-				tun[#tun+1] = {nx,ny}
-				x1, y1 = nx, ny
-				print(feat, "accept tunnel", self.map.room_map[nx][ny].tunnel, id)
-			else
-				print(feat, "reject tunnel", self.map.room_map[nx][ny].tunnel, id)
-			end
-		else
-			tun[#tun+1] = {nx,ny}
-			x1, y1 = nx, ny
-			print(feat, "accept normal")
-		end
-
-		if x1 == nx and y1 == ny then
-			self:markTunnel(x1, y1, xdir, ydir, id)
-			no_move_tries = 0
-		else
-			no_move_tries = no_move_tries + 1
-		end
-
-		if x1 == x2 and y1 == y2 then print(feat, "done") break end
-
-		tries = tries - 1
-	end
-
-	for _, t in ipairs(tun) do
-		local nx, ny = t[1], t[2]
-		if t[3] and self.data.door and rng.percent(self.data.door_chance) then
-			self.map(nx, ny, Map.TERRAIN, self:resolve("door"))
-		else
-			self.map(nx, ny, Map.TERRAIN, self:resolve('.'))
-		end
-	end
-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
-
---- Create the stairs on the sides
-function _M:makeStairsSides(lev, old_lev, sides, rooms, 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(1, self.map.h - 1)
-			elseif sides[2] == 6 then dx, dy = self.map.w - 1, rng.range(1, self.map.h - 1)
-			elseif sides[2] == 8 then dx, dy = rng.range(1, self.map.w - 1), 0
-			elseif sides[2] == 2 then dx, dy = rng.range(1, self.map.w - 1), self.map.h - 1
-			end
-
-			if not self.map.room_map[dx][dy].special then
-				local i = rng.range(1, #rooms)
-				self:tunnel(dx, dy, rooms[i].cx, rooms[i].cy, rooms[i].id)
-				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
-		if     sides[1] == 4 then ux, uy = 0, rng.range(1, self.map.h - 1)
-		elseif sides[1] == 6 then ux, uy = self.map.w - 1, rng.range(1, self.map.h - 1)
-		elseif sides[1] == 8 then ux, uy = rng.range(1, self.map.w - 1), 0
-		elseif sides[1] == 2 then ux, uy = rng.range(1, self.map.w - 1), self.map.h - 1
-		end
-
-		if not self.map.room_map[ux][uy].special then
-			local i = rng.range(1, #rooms)
-			self:tunnel(ux, uy, rooms[i].cx, rooms[i].cy, rooms[i].id)
-			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
-
---- Make rooms and connect them with tunnels
-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 nb_room = self.data.nb_rooms or 10
-	local rooms = {}
-	while nb_room > 0 do
-		local rroom
-		while true do
-			rroom = self.rooms[rng.range(1, #self.rooms)]
-			if type(rroom) == "table" and rroom.chance_room then
-				if rng.percent(rroom.chance_room) then
-					rroom = rroom[1]
-					break
-				end
-			else
-				break
-			end
-		end
-
-		local r = self:roomAlloc(rroom, #rooms+1, lev, old_lev)
-		if r then rooms[#rooms+1] = r end
-		nb_room = nb_room - 1
-	end
-
-	-- Tunnels !
-	if not self.data.no_tunnels then
-		print("Begin tunnel", #rooms, rooms[1])
-		local tx, ty = rooms[1].cx, rooms[1].cy
-		for ii = 2, #rooms + 1 do
-			local i = util.boundWrap(ii, 1, #rooms)
-			self:tunnel(tx, ty, rooms[i].cx, rooms[i].cy, rooms[i].id)
-			tx, ty = rooms[i].cx, rooms[i].cy
-		end
-	end
-
-	-- Forced tunnels
-	if self.data.force_tunnels then
-		for _, t in ipairs(self.data.force_tunnels) do
-			local sx, sy, ex, ey
-			if type(t[1]) == "string" then
-				local i = rng.range(1, #rooms)
-				sx, sy = rooms[i].cx, rooms[i].cy
-			else
-				sx, sy = t[1][1], t[1][2]
-			end
-			if type(t[2]) == "string" then
-				local i = rng.range(1, #rooms)
-				ex, ey = rooms[i].cx, rooms[i].cy
-			else
-				ex, ey = t[2][1], t[2][2]
-			end
-			self:tunnel(sx, sy, ex, ey, t.id)
-		end
-	end
-
-	-- Find out "interresting" spots
-	local spots = {}
-	for i, r in ipairs(rooms) do
-		spots[#spots+1] = {x=rooms[i].cx, y=rooms[i].cy, type="room", subtype=rooms[i].room.name}
-	end
-
-	if self.data.edge_entrances then
-		return self:makeStairsSides(lev, old_lev, self.data.edge_entrances, rooms, spots)
-	else
-		return self:makeStairsInside(lev, old_lev, spots)
-	end
-end
diff --git a/game/engine/generator/map/Rooms.lua b/game/engine/generator/map/Rooms.lua
deleted file mode 100644
index c8b4c7c754bf5885dd29958a7b8658289c35ac97..0000000000000000000000000000000000000000
--- a/game/engine/generator/map/Rooms.lua
+++ /dev/null
@@ -1,86 +0,0 @@
--- 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"
-require "engine.Generator"
-
---- Generator that makes a map
-module(..., package.seeall, class.inherit(engine.Generator))
-
-function _M:init(zone, map, level, data)
-	engine.Generator.init(self, zone, map, level)
-	self.grid_list = zone.grid_list
-	self.floor = self:resolve("floor")
-	self.wall = self:resolve("wall")
-	self.door = self:resolve("door")
-	self.up = self:resolve("up")
-	self.down = self:resolve("down")
-	self.spots = {}
-end
-
-function _M:doRooms(room, no, tab)
-	if room.w * room.h >= 60 and room.w >= 5 and room.h >= 5 and not room.no_touch and no > 0 then
-		local sy, sx = rng.range(3, room.h - 2), rng.range(3, room.w - 2)
-		local axis = rng.percent(50)
-		if room.w < (room.h * 3) then axis = true else axis = false end
-		if axis then
-			for z = 0, room.w - 1 do
-				self.map(room.x + z, room.y + sy, Map.TERRAIN, self.wall)
-			end
-			self:doRooms({ y=room.y, x=room.x, h=sy, w=room.w}, no-1,"  "..tab)
-			self:doRooms({ y=room.y + sy + 1, x=room.x, h=room.h - sy - 1, w=room.w}, no-1,"  "..tab)
-		else
-			for z = 0, room.h - 1 do
-				self.map(room.x + sx, room.y + z, Map.TERRAIN, self.wall)
-			end
-			self:doRooms({ y=room.y, x=room.x,      h=room.h, w=sx}, no-1,"  "..tab)
-			self:doRooms({ y=room.y, x=room.x + sx + 1, h=room.h, w=room.w - sx - 1}, no-1,"  "..tab)
-		end
-		self.map(room.x + sx, room.y + sy, Map.TERRAIN, self.door)
-	else
-		-- Final room, select an interresting "spot"
-		local spotx, spoty = rng.range(room.x, room.x + room.w - 1), rng.range(room.y, room.y + room.h - 1)
-		table.insert(self.spots, {x=spotx, y=spoty})
-	end
-end
-
-function _M:generate(lev, old_lev)
-	for i = 0, self.map.w - 1 do for j = 0, self.map.h - 1 do
-		if j == 0 or j == self.map.h - 1 or i == 0 or i == self.map.w - 1 then
-			self.map(i, j, Map.TERRAIN, self.wall)
-		else
-			self.map(i, j, Map.TERRAIN, self.floor)
-		end
-	end end
-
-	self:doRooms({ x=1, y=1, h=self.map.h - 2, w=self.map.w - 2 }, 10, "#")
-
-	-- Select 2 spots, one for up and one for down, remove the up one, we dont want an actor generator to get smart
-	-- and place a monster where the player should be!
-	local up_spot = table.remove(self.spots, rng.range(1, #self.spots))
-	local down_spot = self.spots[rng.range(1, #self.spots)]
-	self.map(up_spot.x, up_spot.y, Map.TERRAIN, self.up)
-	self.map.room_map[up_spot.x][up_spot.y].special = "exit"
-	if lev < self.zone.max_level then
-		self.map(down_spot.x, down_spot.y, Map.TERRAIN, self.down)
-		self.map.room_map[down_spot.x][down_spot.y].special = "exit"
-	end
-	return up_spot.x, up_spot.y, self.spots
-end
diff --git a/game/engine/generator/map/Static.lua b/game/engine/generator/map/Static.lua
deleted file mode 100644
index 8e04f927672f57d19986eadd92fd8f510797e0a7..0000000000000000000000000000000000000000
--- a/game/engine/generator/map/Static.lua
+++ /dev/null
@@ -1,223 +0,0 @@
--- 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"
-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.grid_list = zone.grid_list
-	self.subgen = {}
-	self.spots = {}
-	self.data = data
-
-	if data.adjust_level then
-		self.adjust_level = {base=zone.base_level, lev = self.level.level, min=data.adjust_level[1], max=data.adjust_level[2]}
-	else
-		self.adjust_level = {base=zone.base_level, lev = self.level.level, min=0, max=0}
-	end
-
-	self:loadMap(data.map)
-end
-
-function _M:loadMap(file)
-	local t = {}
-
-	print("Static generator using file", "/data/maps/"..file..".lua")
-	local f, err = loadfile("/data/maps/"..file..".lua")
-	if not f and err then error(err) end
-	local g = {
-		Map = require("engine.Map"),
-		subGenerator = function(g)
-			self.subgen[#self.subgen+1] = g
-		end,
-		defineTile = function(char, grid, obj, actor, trap, status, spot)
-			t[char] = {grid=grid, object=obj, actor=actor, trap=trap, status=status, define_spot=spot}
-		end,
-		quickEntity = function(char, e, status, spot)
-			if type(e) == "table" then
-				local e = self.zone.grid_class.new(e)
-				t[char] = {grid=e, status=status, define_spot=spot}
-			else
-				t[char] = t[e]
-			end
-		end,
-		prepareEntitiesList = function(type, class, file)
-			local list = require(class):loadList(file)
-			self.level:setEntitiesList(type, list)
-		end,
-		addData = function(t)
-			table.merge(self.level.data, t, true)
-		end,
-		getMap = function(t)
-			return self.map
-		end,
-		checkConnectivity = function(dst, src, type, subtype)
-			self.spots[#self.spots+1] = {x=dst[1], y=dst[2], check_connectivity=src, type=type or "static", subtype=subtype or "static"}
-		end,
-		addSpot = function(dst, type, subtype)
-			self.spots[#self.spots+1] = {x=dst[1], y=dst[2], type=type or "static", subtype=subtype or "static"}
-		end,
-	}
-	setfenv(f, setmetatable(g, {__index=_G}))
-	local ret, err = f()
-	if not ret and err then error(err) end
-	if type(ret) == "string" then ret = ret:split("\n") end
-
-	local m = { w=ret[1]:len(), h=#ret }
-
-	-- Read the map
-	for j, line in ipairs(ret) do
-		local i = 1
-		for c in line:gmatch(".") do
-			m[i] = m[i] or {}
-			m[i][j] = c
-			i = i + 1
-		end
-	end
-
-	m.startx = g.startx or math.floor(m.w / 2)
-	m.starty = g.starty or math.floor(m.h / 2)
-	m.endx = g.endx or math.floor(m.w / 2)
-	m.endy = g.endy or math.floor(m.h / 2)
-
-	self.gen_map = m
-	self.tiles = t
-
-	self.map.w = m.w
-	self.map.h = m.h
-	print("[STATIC MAP] size", m.w, m.h)
-end
-
-function _M:resolve(typ, c)
-	if not self.tiles[c] or not self.tiles[c][typ] then return end
-	local res = self.tiles[c][typ]
-	if type(res) == "function" then
-		return self.grid_list[res()]
-	elseif type(res) == "table" and res.__CLASSNAME then
-		return res
-	elseif type(res) == "table" then
-		return self.grid_list[res[rng.range(1, #res)]]
-	else
-		return self.grid_list[res]
-	end
-end
-
-function _M:generate(lev, old_lev)
-	local spots = {}
-
-	for i = 1, self.gen_map.w do for j = 1, self.gen_map.h do
-		local c = self.gen_map[i][j]
-		local g = self:resolve("grid", c)
-		if g then
-			g = g:clone()
-			g:resolve()
-			g:resolve(nil, true)
-			self.map(i-1, j-1, Map.TERRAIN, g)
-		end
-
-		local actor = self.tiles[c] and self.tiles[c].actor
-		local trap = self.tiles[c] and self.tiles[c].trap
-		local object = self.tiles[c] and self.tiles[c].object
-		local status = self.tiles[c] and self.tiles[c].status
-		local define_spot = self.tiles[c] and self.tiles[c].define_spot
-
-		if object then
-			local o
-			if type(object) == "string" then o = self.zone:makeEntityByName(self.level, "object", object)
-			elseif type(object) == "table" and object.random_filter then o = self.zone:makeEntity(self.level, "object", object.random_filter, nil, true)
-			else o = self.zone:finishEntity(self.level, "object", object)
-			end
-
-			if o then
-				self.zone:addEntity(self.level, o, "object", i-1, j-1)
-			end
-		end
-
-		if trap then
-			local t
-			if type(trap) == "string" then t = self.zone:makeEntityByName(self.level, "trap", trap)
-			elseif type(trap) == "table" and trap.random_filter then t = self.zone:makeEntity(self.level, "trap", trap.random_filter, nil, true)
-			else t = self.zone:finishEntity(self.level, "trap", trap)
-			end
-			if t then
-				self.zone:addEntity(self.level, t, "trap", i-1, j-1)
-			end
-		end
-
-		if actor then
-			local m
-			if type(actor) == "string" then m = self.zone:makeEntityByName(self.level, "actor", actor)
-			elseif type(actor) == "table" and actor.random_filter then m = self.zone:makeEntity(self.level, "actor", actor.random_filter, nil, true)
-			else m = self.zone:finishEntity(self.level, "actor", actor)
-			end
-			if m then
-				self.zone:addEntity(self.level, m, "actor", i-1, j-1)
-			end
-		end
-
-		if status then
-			if status.lite then self.level.map.lites(i-1, j-1, true) status.lite = nil end
-			if status.remember then self.level.map.remembers(i-1, j-1, true) status.remember = nil end
-			if pairs(status) then for k, v in pairs(status) do self.level.map.attrs(i-1, j-1, k, v) end end
-		end
-
-		if define_spot then
-			define_spot = table.clone(define_spot)
-			assert(define_spot.type, "defineTile auto spot without type field")
-			assert(define_spot.subtype, "defineTile auto spot without subtype field")
-			define_spot.x = i-1
-			define_spot.y = j-1
-			self.spots[#self.spots+1] = define_spot
-		end
-	end end
-
-	for i = 1, #self.subgen do
-		local g = self.subgen[i]
-		local data = g.data
-		if type(data) == "string" and data == "pass" then data = self.data end
-
-		local map = self.zone.map_class.new(g.w, g.h)
-		local generator = require(g.generator).new(
-			self.zone,
-			map,
-			self.level,
-			data
-		)
-		local ux, uy, dx, dy, subspots = generator:generate(lev, old_lev)
-
-		self.map:import(map, g.x, g.y)
-		map:close()
-
-		table.append(self.spots, subspots)
-
-		if g.define_up then self.gen_map.startx, self.gen_map.starty = ux + g.x, uy + g.y end
-		if g.define_down then self.gen_map.endx, self.gen_map.endy = dx + g.x, dy + g.y end
-	end
-
-	if self.gen_map.startx and self.gen_map.starty then
-		self.map.room_map[self.gen_map.startx][self.gen_map.starty].special = "exit"
-	end
-	if self.gen_map.startx and self.gen_map.starty then
-		self.map.room_map[self.gen_map.endx][self.gen_map.endy].special = "exit"
-	end
-	return self.gen_map.startx, self.gen_map.starty, self.gen_map.endx, self.gen_map.endy, self.spots
-end
diff --git a/game/engine/generator/map/TileSet.lua b/game/engine/generator/map/TileSet.lua
deleted file mode 100644
index 9b928bc58e83847852409730e4122b955954b073..0000000000000000000000000000000000000000
--- a/game/engine/generator/map/TileSet.lua
+++ /dev/null
@@ -1,390 +0,0 @@
--- 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"
-require "engine.Generator"
-module(..., package.seeall, class.inherit(engine.Generator))
-
--- Deactaivte too many prints
-local print = function() end
-
-function _M:init(zone, map, level, data)
-	engine.Generator.init(self, zone, map, level)
-	self.data = data
-	self.grid_list = zone.grid_list
-	self.tiles, self.raw = {}, {}
-	if type(data.tileset) == "string" then self:loadTiles(data.tileset)
-	else for i, ts in ipairs(data.tileset) do self:loadTiles(ts) end end
-	self.matching_tiles = {}
-
-	self.block = self.raw.base
-	self.cols = math.floor(self.map.w / self.block.w)
-	self.rows = math.floor(self.map.h / self.block.h)
-	self.room_map = {}
-	for i = 0, self.cols do
-		self.room_map[i] = {}
-		for j = 0, self.rows do
-			self.room_map[i][j] = false
-		end
-	end
-end
-
-function _M:findOpenings(t, c, i, j, mx, my)
-	local d = self.raw
-	if self:isOpening(c, d) and (i == 1 or i == mx or j == 1 or j == my) then
-		if i == 1 and j == 1 then
---			table.insert(t.openings, {i, j, 7})
-		elseif i == 1 and j == my then
---			table.insert(t.openings, {i, j, 1})
-		elseif i == mx and j == my then
---			table.insert(t.openings, {i, j, 3})
-		elseif i == mx and j == 1 then
---			table.insert(t.openings, {i, j, 9})
-		elseif i == 1 then
-			table.insert(t.openings, {i, j, 4})
-		elseif i == mx then
-			table.insert(t.openings, {i, j, 6})
-		elseif j == 1 then
-			table.insert(t.openings, {i, j, 8})
-		elseif j == my then
-			table.insert(t.openings, {i, j, 2})
-		end
-	end
-end
-
-function _M:loadTiles(tileset)
-	local f, err = loadfile("/data/tilesets/"..tileset..".lua")
-	if not f and err then error(err) end
-	local d = self.raw
-	setfenv(f, setmetatable(d, {__index=_G}))
-	local ret, err = f()
-	if not ret and err then error(err) end
-
-	local tiles = self.tiles
-	for idx, ts in ipairs(d.tiles) do
-		local t = { id=#tiles+1, openings={}, type=ts.type }
-		if not ts.no_random then tiles[#tiles+1] = t end
-		if ts.define_as then tiles[ts.define_as] = t end
-
-		-- X symetric tile definition
-		if ts.base and ts.symetric and ts.symetric == "x" then
-			local ts = tiles[ts.base]
-			local mx, my = #ts, #ts[1]
-			for j = 1, my do for ri = 1, mx do
-				local i = mx - ri + 1
-				t[i] = t[i] or {}
-				t[i][j] = ts[ri][j]
-				self:findOpenings(t, t[i][j], i, j, mx, my)
-			end end
-			t.sizew, t.sizeh = mx / d.base.w, my / d.base.h
-
-		-- Y symetric tile definition
-		elseif ts.base and ts.symetric and ts.symetric == "y" then
-			local ts = tiles[ts.base]
-			local mx, my = #ts, #ts[1]
-			for rj = 1, my do for i = 1, mx do
-				local j = my - rj + 1
-				t[i] = t[i] or {}
-				t[i][j] = ts[i][rj]
-				self:findOpenings(t, t[i][j], i, j, mx, my)
-			end end
-			t.sizew, t.sizeh = mx / d.base.w, my / d.base.h
-
-		-- 90degree rotation
-		elseif ts.base and ts.rotation and ts.rotation == "90" then
-			local ts = tiles[ts.base]
-			local mx, my = #ts[1], #ts
-			for j = 1, my do for ri = 1, mx do
-				local i = mx - ri + 1
-				t[i] = t[i] or {}
-				t[i][j] = ts[j][ri]
-				self:findOpenings(t, t[i][j], i, j, mx, my)
-			end end
-			t.sizew, t.sizeh = mx / d.base.w, my / d.base.h
-
-		-- 180degree rotation
-		elseif ts.base and ts.rotation and ts.rotation == "180" then
-			local ts = tiles[ts.base]
-			local mx, my = #ts, #ts[1]
-			for rj = 1, my do for ri = 1, mx do
-				local i = mx - ri + 1
-				local j = my - rj + 1
-				t[i] = t[i] or {}
-				t[i][j] = ts[ri][rj]
-				self:findOpenings(t, t[i][j], i, j, mx, my)
-			end end
-			t.sizew, t.sizeh = mx / d.base.w, my / d.base.h
-
-		-- 270degree rotation
-		elseif ts.base and ts.rotation and ts.rotation == "270" then
-			local ts = tiles[ts.base]
-			local mx, my = #ts[1], #ts
-			for rj = 1, my do for i = 1, mx do
-				local j = my - rj + 1
-				t[i] = t[i] or {}
-				t[i][j] = ts[rj][i]
-				self:findOpenings(t, t[i][j], i, j, mx, my)
-			end end
-			t.sizew, t.sizeh = mx / d.base.w, my / d.base.h
-
-		-- Normal tile definition
-		else
-			local my = #ts
-			for j, line in ipairs(ts) do
-				local i = 1
-				local mx = line:len()
-				for c in line:gmatch(".") do
-					t[i] = t[i] or {}
-					t[i][j] = c
-					self:findOpenings(t, c, i, j, mx, my)
-
-					i = i + 1
-				end
-				t.sizew, t.sizeh = mx / d.base.w, my / d.base.h
-			end
-		end
-	end
-end
-
-function _M:roomAlloc(bx, by, bw, bh, rid)
-	print("trying room at", bx,by,bw,bh)
-	if bx + bw - 1 > self.cols or by + bh - 1 > self.rows then return false end
-	if bx < 0 or by < 0 then return false end
-
-	-- Do we stomp ?
-	for i = bx, bx + bw - 1 do
-		for j = by, by + bh - 1 do
-			if self.room_map[i][j] then return false end
-		end
-	end
-
-	-- ok alloc it
-	for i = bx, bx + bw - 1 do
-		for j = by, by + bh - 1 do
-			self.room_map[i][j] = true
-		end
-	end
-	print("room allocated at", bx,by,bw,bh)
-
-	return true
-end
-
-function _M:isOpening(c, d)
-	return d.is_opening(c)
-end
-
-function _M:matchTile(t1, t2)
-	return self.raw.matcher(t1, t2)
-end
-
-function _M:findMatchingTiles(st, dir, type)
-	-- If no type is given choose one
-	if not type then
-		type = "room"
-		if rng.percent(self.data.tunnel_chance or 50) then type = "tunnel" end
-	end
-
-	if self.matching_tiles[st] and self.matching_tiles[st][dir] and self.matching_tiles[st][dir][type] then return self.matching_tiles[st][dir][type], type end
-
-	local m = {}
-
-	-- Examine all the size of the tile, and only the sides (for >1 base size tiles)
-	-- This is extremely convoluted but the idea is simplistic:
-	-- check each combinaison of position of tiles and find matching ones
-	for stw = 1, st.sizew do for sth = 1, st.sizeh do if stw == 1 or stw == st.sizew or sth == 1 or sth == st.sizeh then
-		local stwr, sthr = (stw-1) * self.block.w, (sth-1) * self.block.h
-
-		-- Now look for matching tiles
-		for _, dt in ipairs(self.tiles) do if dt.type == type then
-
-			-- On all their subtile if they are big
-			for dtw = 1, dt.sizew do for dth = 1, dt.sizeh do if dtw == 1 or dtw == dt.sizew or dth == 1 or dth == dt.sizeh then
-				local dtwr, dthr = (dtw-1) * self.block.w, (dth-1) * self.block.h
-
-				local ok = true
-				local fullok = false
-
-				-- Check each directions, for the correct side and see if the tile matches
-				if dir == 8 and sth == 1 and dth == dt.sizeh then
-					for i = 1, self.block.w do
-						local ret, fo = self:matchTile(st[i+stwr][1], dt[i+dtwr][self.block.h*dt.sizeh])
-						fullok = fullok or fo
-						if not ret then ok = false end
-					end
-				elseif dir == 2 and sth == st.sizeh and dth == 1 then
-					for i = 1, self.block.w do
-						local ret, fo = self:matchTile(st[i+stwr][self.block.h*st.sizeh], dt[i+dtwr][1])
-						fullok = fullok or fo
-						if not ret then ok = false end
-					end
-				elseif dir == 4 and stw == 1 and dtw == dt.sizew then
-					for j = 1, self.block.h do
-						local ret, fo = self:matchTile(st[1][j+sthr], dt[self.block.w*dt.sizew][j+dthr])
-						fullok = fullok or fo
-						if not ret then ok = false end
-					end
-				elseif dir == 6 and stw == st.sizew and dtw == 1 then
-					for j = 1, self.block.h do
-						local ret, fo = self:matchTile(st[self.block.w*st.sizew][j+sthr], dt[1][j+dthr])
-						fullok = fullok or fo
-						if not ret then ok = false end
-					end
-				end
-
-				-- if the tile matches, and there is a passageway then remember it
-				if ok and fullok then
-					m[#m+1] = {tile=dt, stw=stw-1, sth=sth-1, dtw=dtw-1, dth=dth-1}
-					print("found matching tile in dir", dir, "from", st.id, stw, sth, "to", dt.id, dtw, dth)
-					for j = 1, self.block.h * dt.sizeh do
-						local s = ""
-						for i = 1, self.block.w * dt.sizew do
-							s = s..dt[i][j]
-						end
-						print(s)
-					end
-				end
-			end end end
-		end end
-	end end end
-
-	self.matching_tiles[st] = self.matching_tiles[st] or {}
-	self.matching_tiles[st][dir] = self.matching_tiles[st][dir] or {}
-	self.matching_tiles[st][dir][type] = m
-
-	return m, type
-end
-
-function _M:buildTile(tile, bx, by, rid)
-	local bw, bh = tile.sizew, tile.sizeh
-
-	if not self:roomAlloc(bx, by, bw, bh, rid) then return false end
-
-	print("building tile", tile.id, #tile, #tile[1])
-	for j = 1, #tile[1] do
-		for i = 1, #tile do
-			if self.map.room_map[bx * self.block.w + i - 1] and self.map.room_map[bx * self.block.w + i - 1][by * self.block.h + j - 1] then
-				self.map.room_map[bx * self.block.w + i - 1][by * self.block.h + j - 1].symbol = tile[i][j]
-			end
-		end
-	end
-	local opens = {}
-	for i, o in ipairs(tile.openings) do
-		print(" * opening in dir ", o[3], "::", o[1], o[2])
-		local coord = dir_to_coord[o[3]]
-		local mts, type = self:findMatchingTiles(tile, o[3])
-		-- if we found no match for the given type try the other one
-		if #mts == 0 then mts, type = self:findMatchingTiles(tile, o[3], type == "room" and "tunnel" or "room") end
-
-		if #mts > 0 then
-			local mt = mts[rng.range(1, #mts)]
-			opens[#opens+1] = {bx + coord[1] + mt.stw, by + coord[2] + mt.sth, tile=mt.tile}
-			print("room at ",bx,by,"opens to",o[3],"::",bx + coord[1], by + coord[2])
-		end
-	end
-
-	return opens
-end
-
-function _M:createMap()
-	for i = 0, self.map.w - 1 do for j = 0, self.map.h - 1 do
-		local c = self.map.room_map[i][j].symbol
-		if self.raw.filler then c = self.raw.filler(c, i, j, self.map.room_map, self.data) end
-		self.map(i, j, Map.TERRAIN, self:resolve(c))
-	end end
-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
-
---- Create the stairs on the sides
-function _M:makeStairsSides(lev, old_lev, sides, spots)
-	error("Side stairs not supported by TileSet map generator")
-end
-
-function _M:placeStartTiles(tiles, process)
-	for i, td in ipairs(tiles) do
-		local tile = td.tile or rng.range(1, #self.tiles)
-		local x, y = td.x or math.floor(self.cols / 2), td.y or math.floor(self.rows / 2)
-		process[#process+1] = {x, y, tile=self.tiles[tile]}
-	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:resolve("#"))
-	end end
-
-	local process = {}
-	local id = 1
-
-	if not self.data.start_tiles then
-		process[#process+1] = {math.floor(self.cols / 2), math.floor(self.rows / 2), tile=self.tiles[rng.range(1, #self.tiles)]}
-	else
-		self:placeStartTiles(self.data.start_tiles, process)
-	end
-	while #process > 0 do
-		local b = table.remove(process)
-
-		local opens = self:buildTile(b.tile, b[1], b[2], id)
-		if opens then
-			id = id + 1
-
-			-- Add openings
-			for i, o in ipairs(opens) do process[#process+1] = o end
-		end
-	end
-
-	-- Fill the map with the real entities based on the map.room_map symbols
-	self:createMap()
-
-	-- Make stairs
-	local spots = {}
-	if self.data.edge_entrances then
-		return self:makeStairsSides(lev, old_lev, self.data.edge_entrances, spots)
-	else
-		return self:makeStairsInside(lev, old_lev, spots)
-	end
-end
diff --git a/game/engine/generator/map/Town.lua b/game/engine/generator/map/Town.lua
deleted file mode 100644
index 3f35d1e4ecf51fc641fffcf1a7a999c2606f2223..0000000000000000000000000000000000000000
--- a/game/engine/generator/map/Town.lua
+++ /dev/null
@@ -1,205 +0,0 @@
--- 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: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: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: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: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: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: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: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: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: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: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: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: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: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:resolve("door"))
-	end
-end
-
-function _M:building(leaf, spots)
-	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:resolve("wall"))
-			door_grids[#door_grids+1] = {x=i,y=j}
-		else
-			self.map(i, j, Map.TERRAIN, 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: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
-
-	spots[#spots+1] = {x=math.floor((x1+x2)/2), y=math.floor((y1+y2)/2), type="building", subtype="building"}
-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("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")
-	local spots = {}
-	for z, leaf in ipairs(bsp.leafs) do
-		if rng.percent(self.building_chance) then
-			self:building(leaf, spots)
-		end
-	end
-
-	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: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
-
---- 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: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:resolve("up"))
-			self.map.room_map[ux][uy].special = "exit"
-			break
-		end
-	end
-
-	return ux, uy, dx, dy, spots
-end
diff --git a/game/engine/generator/object/Random.lua b/game/engine/generator/object/Random.lua
deleted file mode 100644
index cc54f4f182bc276dea8604f85ac2489cad1013ea..0000000000000000000000000000000000000000
--- a/game/engine/generator/object/Random.lua
+++ /dev/null
@@ -1,62 +0,0 @@
--- 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"
-require "engine.Generator"
-module(..., package.seeall, class.inherit(engine.Generator))
-
-function _M:init(zone, map, level)
-	engine.Generator.init(self, zone, map, level)
-	local data = level.data.generator.object
-
-	if data.adjust_level_to_player and game:getPlayer() then
-		self.adjust_level_to_player = {base=game:getPlayer().level, min=data.adjust_level_to_player[1], max=data.adjust_level_to_player[2]}
-	end
-	self.filters = data.filters
-	self.nb_object = data.nb_object or {10, 20}
-	self.level_range = data.level_range or {level, level}
-end
-
-function _M:generate()
-	self:regenFrom(1)
-end
-
-function _M:generateOne()
-	local f = nil
-	if self.filters then f = self.filters[rng.range(1, #self.filters)] end
-	local o = self.zone:makeEntity(self.level, "object", f, nil, true)
-	if o then
-		local x, y = rng.range(0, self.map.w-1), rng.range(0, self.map.h-1)
-		local tries = 0
-		while (self.map:checkEntity(x, y, Map.TERRAIN, "block_move") or self.map(x, y, Map.OBJECT) or self.map.room_map[x][y].special) and tries < 100 do
-			x, y = rng.range(0, self.map.w-1), rng.range(0, self.map.h-1)
-			tries = tries + 1
-		end
-		if tries < 100 then
-			self.zone:addEntity(self.level, o, "object", x, y)
-		end
-	end
-end
-
-function _M:regenFrom(current)
-	for i = current, rng.range(self.nb_object[1], self.nb_object[2]) do
-		self:generateOne()
-	end
-end
diff --git a/game/engine/generator/trap/Random.lua b/game/engine/generator/trap/Random.lua
deleted file mode 100644
index 3a195918c6fc1e5040b4d3cbeda42674ce40dde2..0000000000000000000000000000000000000000
--- a/game/engine/generator/trap/Random.lua
+++ /dev/null
@@ -1,59 +0,0 @@
--- 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"
-require "engine.Generator"
-module(..., package.seeall, class.inherit(engine.Generator))
-
-function _M:init(zone, map, level)
-	engine.Generator.init(self, zone, map, level)
-	local data = level.data.generator.trap
-
-	self.filters = data.filters
-	self.nb_trap = data.nb_trap or {10, 20}
-	self.level_range = data.level_range or {level, level}
-end
-
-function _M:generate()
-	self:regenFrom(1)
-end
-
-function _M:generateOne()
-	local f = nil
-	if self.filters then f = self.filters[rng.range(1, #self.filters)] end
-	local o = self.zone:makeEntity(self.level, "trap", f, nil, true)
-	if o then
-		local x, y = rng.range(0, self.map.w-1), rng.range(0, self.map.h-1)
-		local tries = 0
-		while (self.map:checkEntity(x, y, Map.TERRAIN, "block_move") or self.map(x, y, Map.TRAP) or self.map.room_map[x][y].special) and tries < 100 do
-			x, y = rng.range(0, self.map.w-1), rng.range(0, self.map.h-1)
-			tries = tries + 1
-		end
-		if tries < 100 then
-			self.zone:addEntity(self.level, o, "trap", x, y)
-		end
-	end
-end
-
-function _M:generate()
-	for i = 1, rng.range(self.nb_trap[1], self.nb_trap[2]) do
-		self:generateOne()
-	end
-end
diff --git a/game/engine/init.lua b/game/engine/init.lua
deleted file mode 100644
index 65ecc955c06040e2a44641b89bff156360530e67..0000000000000000000000000000000000000000
--- a/game/engine/init.lua
+++ /dev/null
@@ -1,88 +0,0 @@
--- 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
-
--- load some utility functions
-dofile("/engine/utils.lua")
-dofile("/engine/colors.lua")
-
--- load resolver functions for entities cloning
-dofile("/engine/resolvers.lua")
-
-require "config"
-require "engine.Game"
-require "engine.interface.GameMusic"
-require "engine.KeyBind"
-require "engine.Savefile"
-require "engine.Tiles"
-require "engine.PlayerProfile"
-engine.Tiles.prefix = "/data/gfx/"
-
--- Engine Version
-engine.version = {0,9,10}
-
--- Setup the user directory
-engine.homepath = fs.getUserPath()..fs.getPathSeparator()..fs.getHomePath()..fs.getPathSeparator().."4.0"
-fs.setWritePath(fs.getUserPath())
-fs.mkdir(fs.getHomePath())
-fs.mkdir(fs.getHomePath().."/4.0/")
-fs.mkdir(fs.getHomePath().."/4.0/profiles/")
-fs.mkdir(fs.getHomePath().."/4.0/settings/")
-fs.setWritePath(fs.getHomePath())
-
--- Loads default config & user config
-fs.mount(engine.homepath, "/")
-config.loadString[[
-window.size = "800x600"
-sound.enabled = true
-music.volume = 60
-]]
-for i, file in ipairs(fs.list("/settings/")) do
-	if file:find(".cfg$") then
-		config.load("/settings/"..file)
-	end
-end
-
--- Load default keys
-engine.KeyBind:load("move,actions")
-
--- Load remaps
-if fs.exists("/keybinds.cfg") then
-	engine.KeyBind:loadRemap("/keybinds.cfg")
-end
-
-fs.umount(engine.homepath)
-
--- Setup a default key handler
-local key = engine.KeyBind.new()
-key:setCurrent()
-
--- Load the game module
-game = false
-
--- Setup resolution
-engine.Game:setResolution(config.settings.window.size)
-
--- Setup musics
-engine.interface.GameMusic:soundSystemStatus(config.settings.sound.enabled, true)
-core.sound.activateMusicCallback()
-
--- Load profile configs
-profile = engine.PlayerProfile.new()
-
-util.showMainMenu(true)
diff --git a/game/engine/interface/ActorAI.lua b/game/engine/interface/ActorAI.lua
deleted file mode 100644
index fb4d9dbbd599bc7a28fe4adc6ca2e9d89597b8aa..0000000000000000000000000000000000000000
--- a/game/engine/interface/ActorAI.lua
+++ /dev/null
@@ -1,168 +0,0 @@
--- 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"
-require "engine.Actor"
-local Map = require "engine.Map"
-
---- Handles actors artificial intelligence (or dumbness ... ;)
-module(..., package.seeall, class.make)
-
-_M.ai_def = {}
-
---- Deinfe AI
-function _M:newAI(name, fct)
-	_M.ai_def[name] = fct
-end
-
---- Defines AIs
--- Static!
-function _M:loadDefinition(dir)
-	for i, file in ipairs(fs.list(dir)) do
-		if file:find("%.lua$") then
-			local f, err = loadfile(dir.."/"..file)
-			if not f and err then error(err) end
-			setfenv(f, setmetatable({
-				Map = require("engine.Map"),
-				newAI = function(name, fct) self:newAI(name, fct) end,
-			}, {__index=_G}))
-			f()
-		end
-	end
-end
-
-function _M:init(t)
-	self.ai_state = self.ai_state or {}
-	self.ai_target = {}
-	self:autoLoadedAI()
-end
-
-function _M:autoLoadedAI()
-	-- Make the table with weak values, so that threat list does not prevent garbage collection
-	setmetatable(self.ai_target, {__mode='v'})
-end
-
-local coords = {
-	[1] = { 4, 2, 7, 3 },
-	[2] = { 1, 3, 4, 6 },
-	[3] = { 2, 6, 1, 9 },
-	[4] = { 7, 1, 8, 2 },
-	[5] = {},
-	[6] = { 9, 3, 8, 2 },
-	[7] = { 4, 8, 1, 9 },
-	[8] = { 7, 9, 4, 6 },
-	[9] = { 8, 6, 7, 3 },
-}
-
-function _M:aiCanPass(x, y)
-	-- Nothing blocks, just go on
-	if not game.level.map:checkAllEntities(x, y, "block_move", self, true) then return true end
-
-	-- If there is an otehr actor, check hostility, if hostile, we move to attack
-	local target = game.level.map(x, y, Map.ACTOR)
-	if target and self:reactionToward(target) < 0 then return true end
-
-	-- If there is a target (not hostile) and we can move it, do so
-	if target and self:attr("move_body") then return true end
-
-	return false
-end
-
---- Move one step to the given target if possible
--- This tries the most direct route, if not available it checks sides and always tries to get closer
-function _M:moveDirection(x, y)
-	local l = line.new(self.x, self.y, x, y)
-	local lx, ly = l()
-	if lx and ly then
-		local target = game.level.map(lx, ly, Map.ACTOR)
-
-		-- if we are blocked, try some other way
-		if not self:aiCanPass(lx, ly) then
-			local dirx = lx - self.x
-			local diry = ly - self.y
-			local dir = coord_to_dir[dirx][diry]
-
-			local list = coords[dir]
-			local l = {}
-			-- Find posiblities
-			for i = 1, #list do
-				local dx, dy = self.x + dir_to_coord[list[i]][1], self.y + dir_to_coord[list[i]][2]
-				if self:aiCanPass(dx, dy) then
-					l[#l+1] = {dx,dy, (dx-x)^2 + (dy-y)^2}
-				end
-			end
-			-- Move to closest
-			if #l > 0 then
-				table.sort(l, function(a,b) return a[3]<b[3] end)
-				return self:move(l[1][1], l[1][2])
-			end
-		else
-			return self:move(lx, ly)
-		end
-	end
-end
-
---- Main entry point for AIs
-function _M:doAI()
-	if not self.ai then return end
---	if self.x < game.player.x - 10 or self.x > game.player.x + 10 or self.y < game.player.y - 10 or self.y > game.player.y + 10 then return end
-
-	-- If we have a target but it is dead (it was not yet garbage collected but it'll come)
-	-- we forget it
-	if self.ai_target.actor and self.ai_target.actor.dead then self.ai_target.actor = nil end
-
-	return self:runAI(self.ai)
-end
-
-function _M:runAI(ai)
-	return _M.ai_def[ai](self)
-end
-
---- Returns the current target
-function _M:getTarget(typ)
-	local tx, ty = self:aiSeeTargetPos(self.ai_target.actor)
-	return tx, ty, self.ai_target.actor
-end
-
---- Sets the current target
-function _M:setTarget(target)
-	self.ai_target.actor = target
-end
-
---- Returns the seen coords of the target
--- This will usualy return the exact coords, but if the target is only partialy visible (or not at all)
--- it will return estimates, to throw the AI a bit off
--- @param target the target we are tracking
--- @return x, y coords to move/cast to
-function _M:aiSeeTargetPos(target)
-	if not target then return self.x, self.y end
-	local tx, ty = target.x, target.y
-	local see, chance = self:canSee(target)
-
-	-- Directly seeing it, no spread at all
-	if see then
-		return tx, ty
-	-- Ok we can see it, spread coords around, the less chance to see it we had the more we spread
-	else
-		chance = math.floor((100 - chance) / 10)
-		tx = tx + rng.range(0, chance * 2) - chance
-		ty = ty + rng.range(0, chance * 2) - chance
-		return tx, ty
-	end
-end
diff --git a/game/engine/interface/ActorFOV.lua b/game/engine/interface/ActorFOV.lua
deleted file mode 100644
index d26bf033b005402d083c60a5af9d588bcedca734..0000000000000000000000000000000000000000
--- a/game/engine/interface/ActorFOV.lua
+++ /dev/null
@@ -1,130 +0,0 @@
--- 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"
-
---- Handles actors field of view
--- When an actor moves it computes a field of view and stores it in self.fov<br/>
--- When an other actor moves it can update the fov of seen actors
-module(..., package.seeall, class.make)
-
-_M.__do_distance_map = false
-
---- Initialises stats with default values if needed
-function _M:init(t)
-	self.distance_map = {}
-	self.fov = {actors={}, actors_dist={}}
-	self.fov_computed = false
-	self.fov_last_x = -1
-	self.fov_last_y = -1
-	self.fov_last_turn = -1
-	self.fov_last_change = -1
-end
-
---- Computes actor's FOV
--- @param radius the FOV radius, defaults to 20
--- @param block the property to look for FOV blocking, defaults to "block_sight"
--- @param apply an apply function that will be called on each seen grids, defaults to nil
--- @param force set to true to force a regeneration even if we did not move
--- @param no_store do not store FOV informations
--- @param cache if true it will use the cache given by the map, for the map actor. It can be used for other actors is they have the same block settings
-function _M:computeFOV(radius, block, apply, force, no_store, cache)
-	-- If we did not move, do not update
-	if not force and self.fov_last_x == self.x and self.fov_last_y == self.y and self.fov_computed then return end
-	radius = radius or 20
-	block = block or "block_sight"
-
-	-- Simple FOV compute no storage
-	if no_store and apply then
-		local map = game.level.map
-		core.fov.calc_circle(self.x, self.y, radius, function(_, x, y)
-			if map:checkAllEntities(x, y, block, self) then return true end
-		end, function(_, x, y, dx, dy, sqdist)
-			apply(x, y, dx, dy, sqdist)
-		end, cache and game.level.map._fovcache[block])
-
-	-- FOV + storage
-	elseif not no_store then
-		local fov = {actors={}, actors_dist={}}
-		setmetatable(fov.actors, {__mode='k'})
-		setmetatable(fov.actors_dist, {__mode='v'})
-
-		local map = game.level.map
-		core.fov.calc_circle(self.x, self.y, radius, function(_, x, y)
-			if map:checkAllEntities(x, y, block, self) then return true end
-		end, function(_, x, y, dx, dy, sqdist)
-			if apply then apply(x, y, dx, dy, sqdist) end
-
-			if self.__do_distance_map then self:distanceMap(x, y, game.turn + radius - math.sqrt(sqdist)) end
-
-			-- Note actors
-			local a = map(x, y, Map.ACTOR)
-			if a and a ~= self and not a.dead then
-				local t = {x=x,y=y, dx=dx, dy=dy, sqdist=sqdist}
-				fov.actors[a] = t
-				fov.actors_dist[#fov.actors_dist+1] = a
-				a.__sqdist = sqdist
-				a:check("seen_by", self)
-				a:updateFOV(self, t.sqdist)
-			end
-		end, cache and game.level.map._fovcache[block])
-
-		-- Sort actors by distance (squared but we do not care)
-		table.sort(fov.actors_dist, "__sqdist")
---		table.sort(fov.actors_dist, function(a, b) return a.__sqdist < b.__sqdist end)
---		for i = 1, #fov.actors_dist do fov.actors_dist[i].i = i end
---		print("Computed FOV for", self.uid, self.name, ":: seen ", #fov.actors_dist, "actors closeby")
-
-		self.fov = fov
-		self.fov_last_x = self.x
-		self.fov_last_y = self.y
-		self.fov_last_turn = game.turn
-		self.fov_last_change = game.turn
-		self.fov_computed = true
-	end
-end
-
---- Update our fov to include the given actor at the given dist
--- @param a the actor to include
--- @param sqdist the squared distance to that actor
-function _M:updateFOV(a, sqdist)
-	-- If we are from this turn no need to update
-	if self.fov_last_turn == game.turn then return end
-
-	local t = {x=a.x, y=a.y, dx=a.x-self.x, dy=a.y-self.y, sqdist=sqdist}
-
-	local fov = self.fov
-	if not fov.actors[a] then
-		fov.actors_dist[#fov.actors_dist+1] = a
-	end
-	fov.actors[a] = t
---	print("Updated FOV for", self.uid, self.name, ":: seen ", #fov.actors_dist, "actors closeby; from", a, sqdist)
-	table.sort(fov.actors_dist, function(a, b) if a and b then return fov.actors[a].sqdist < fov.actors[b].sqdist elseif a then return 1 else return nil end end)
-	self.fov_last_change = game.turn
-end
-
---- Unused
-function _M:distanceMap(x, y, v)
-	if v == nil then
-		return self.distance_map[x + y * game.level.map.w]
-	else
-		self.distance_map[x + y * game.level.map.w] = v
-	end
-end
diff --git a/game/engine/interface/ActorInventory.lua b/game/engine/interface/ActorInventory.lua
deleted file mode 100644
index 28ea4aa6ba3730d177889955aa06addde3ffa4c6..0000000000000000000000000000000000000000
--- a/game/engine/interface/ActorInventory.lua
+++ /dev/null
@@ -1,428 +0,0 @@
--- 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 ShowInventory = require "engine.dialogs.ShowInventory"
-local ShowEquipment = require "engine.dialogs.ShowEquipment"
-local ShowEquipInven = require "engine.dialogs.ShowEquipInven"
-local ShowPickupFloor = require "engine.dialogs.ShowPickupFloor"
-
---- Handles actors stats
-module(..., package.seeall, class.make)
-
-_M.inven_def = {}
-
---- Defines stats
--- Static!
-function _M:defineInventory(short_name, name, is_worn, desc)
-	assert(name, "no inventory slot name")
-	assert(short_name, "no inventory slot short_name")
-	assert(desc, "no inventory slot desc")
-	table.insert(self.inven_def, {
-		name = name,
-		short_name = short_name,
-		description = desc,
-		is_worn = is_worn,
-	})
-	self.inven_def[#self.inven_def].id = #self.inven_def
-	self.inven_def[short_name] = self.inven_def[#self.inven_def]
-	self["INVEN_"..short_name:upper()] = #self.inven_def
-	print("[INVENTORY] define slot", #self.inven_def, self.inven_def[#self.inven_def].name)
-end
-
--- Auto define the inventory
-_M:defineInventory("INVEN", "In inventory", false, "")
-
---- Initialises inventories with default values if needed
-function _M:init(t)
-	self.inven = t.inven or {}
-	self:initBody()
-end
-
-function _M:initBody()
-	if self.body then
-		for inven, max in pairs(self.body) do
-			self.inven[self["INVEN_"..inven]] = {max=max, worn=self.inven_def[self["INVEN_"..inven]].is_worn}
-		end
-		self.body = nil
-	end
-end
-
---- Returns the content of an inventory as a table
-function _M:getInven(id)
-	if type(id) == "number" then
-		return self.inven[id]
-	elseif type(id) == "string" then
-		return self.inven[self["INVEN_"..id]]
-	else
-		return id
-	end
-end
-
---- Adds an object to an inventory
--- @return false if the object could not be added
-function _M:addObject(inven_id, o)
-	local inven
-	if type(inven_id) == "number" then
-		inven = self.inven[inven_id]
-	else
-		inven = inven_id
-	end
-
-	-- No room ?
-	if #inven >= inven.max then return false end
-
-	if o:check("on_preaddobject", self, inven) then return false end
-
-	-- Ok add it
-	table.insert(inven, o)
-
-	-- Do whatever is needed when wearing this object
-	if inven.worn then
-		o:check("on_wear", self)
-		self:onWear(o)
-	end
-
-	self:onAddObject(o)
-
-	return true
-end
-
---- Rerturns the position of an item in the given inventory, or nil
-function _M:itemPosition(inven, o)
-	inven = self:getInven(inven)
-	for i, p in ipairs(inven) do
-		local found = nil
-		o:forAllStack(function(so)
-			if p.name == so.name then found = i return true end
-		end)
-		if found then return found end
-	end
-	return nil
-end
-
---- Picks an object from the floor
-function _M:pickupFloor(i, vocal, no_sort)
-	local o = game.level.map:getObject(self.x, self.y, i)
-	if o then
-		local prepickup = o:check("on_prepickup", self, i)
-		if not prepickup and self:addObject(self.INVEN_INVEN, o) then
-			game.level.map:removeObject(self.x, self.y, i)
-			if not no_sort then self:sortInven(self.INVEN_INVEN) end
-
-			o:check("on_pickup", self)
-			self:check("on_pickup_object", o)
-
-			local letter = string.char(string.byte('a') + (self:itemPosition(self.INVEN_INVEN, o) - 1 or 0))
-			if vocal then game.logSeen(self, "%s picks up (%s.): %s.", self.name:capitalize(), letter, o:getName{do_color=true}) end
-		elseif not prepickup then
-			if vocal then game.logSeen(self, "%s has no room for: %s.", self.name:capitalize(), o:getName{do_color=true}) end
-		end
-	else
-		if vocal then game.logSeen(self, "There is nothing to pickup there.") end
-	end
-end
-
---- Removes an object from inventory
--- @param inven the inventory to drop from
--- @param item the item id to drop
--- @param no_unstack if the item was a stack takes off the whole stack if true
--- @return the object removed or nil if no item existed and a boolean saying if there is no more objects
-function _M:removeObject(inven, item, no_unstack)
-	if type(inven) == "number" then inven = self.inven[inven] end
-
-	if not inven[item] then return false, true end
-
-	local o, finish = inven[item], true
-
-	if o:check("on_preremoveobject", self, inven) then return false, true end
-
-	if not no_unstack then
-		o, finish = o:unstack()
-	end
-	if finish then
-		table.remove(inven, item)
-	end
-
-	-- Do whatever is needed when takingoff this object
-	if inven.worn then
-		o:check("on_takeoff", self)
-		self:onTakeoff(o)
-	end
-
-	self:onRemoveObject(o)
-
-	return o, finish
-end
-
---- Called upon adding an object
-function _M:onAddObject(o)
-	if self.__allow_carrier then
-		-- Apply carrier properties
-		o.carried = {}
-		if o.carrier then
-			for k, e in pairs(o.carrier) do
-				o.carried[k] = self:addTemporaryValue(k, e)
-			end
-		end
-	end
-end
-
---- Called upon removing an object
-function _M:onRemoveObject(o)
-	if o.carried then
-		for k, id in pairs(o.carried) do
-			self:removeTemporaryValue(k, id)
-		end
-	end
-	o.carried = nil
-end
-
---- Drop an object on the floor
--- @param inven the inventory to drop from
--- @param item the item id to drop
--- @return the object removed or nil if no item existed
-function _M:dropFloor(inven, item, vocal, all)
-	local o = self:getInven(inven)[item]
-	if not o then
-		if vocal then game.logSeen(self, "There is nothing to drop.") end
-		return
-	end
-	if o:check("on_drop", self) then return false end
-	o = self:removeObject(inven, item, all)
-	game.level.map:addObject(self.x, self.y, o)
-	if vocal then game.logSeen(self, "%s drops on the floor: %s.", self.name:capitalize(), o:getName{do_color=true}) end
-	return true
-end
-
---- Show combined equipment/inventory dialog
--- @param inven the inventory (from self:getInven())
--- @param filter nil or a function that filters the objects to list
--- @param action a function called when an object is selected
-function _M:showEquipInven(title, filter, action, allow_keybind)
-	local d = ShowEquipInven.new(title, self, filter, action, allow_keybind and self)
-	game:registerDialog(d)
-	return d
-end
-
---- Show inventory dialog
--- @param inven the inventory (from self:getInven())
--- @param filter nil or a function that filters the objects to list
--- @param action a function called when an object is selected
-function _M:showInventory(title, inven, filter, action, allow_keybind)
-	local d = ShowInventory.new(title, inven, filter, action, allow_keybind and self)
-	game:registerDialog(d)
-	return d
-end
-
---- Show equipment dialog
--- @param filter nil or a function that filters the objects to list
--- @param action a function called when an object is selected
-function _M:showEquipment(title, filter, action, allow_keybind)
-	local d = ShowEquipment.new(title, self, filter, action, allow_keybind and self)
-	game:registerDialog(d)
-	return d
-end
-
---- Show floor pickup dialog
--- @param filter nil or a function that filters the objects to list
--- @param action a function called when an object is selected
-function _M:showPickupFloor(title, filter, action)
-	local d = ShowPickupFloor.new(title, self.x, self.y, filter, action)
-	game:registerDialog(d)
-	return d
-end
-
---- Can we wear this item?
-function _M:canWearObject(o, try_slot)
-	local req = rawget(o, "require")
-
-	-- Check prerequisites
-	if req then
-		-- Obviously this requires the ActorStats interface
-		if req.stat then
-			for s, v in pairs(req.stat) do
-				if self:getStat(s) < v then return nil, "not enough stat" end
-			end
-		end
-		if req.level and self.level < req.level then
-			return nil, "not enough levels"
-		end
-		if req.talent then
-			for _, tid in ipairs(req.talent) do
-				if not self:knowTalent(tid) then return nil, "missing dependency" end
-			end
-		end
-	end
-
-	-- Check forbidden slot
-	if o.slot_forbid then
-		local inven = self:getInven(o.slot_forbid)
-		-- If the object cant coexist with that inventory slot and it exists and is not empty, refuse wearing
-		if inven and #inven > 0 then
-			return nil, "cannot use currently due to an other worn object"
-		end
-	end
-
-	-- Check that we are not the forbidden slot of any other worn objects
-	for id, inven in pairs(self.inven) do
-		if self.inven_def[id].is_worn then
-			for i, wo in ipairs(inven) do
-				print("fight: ", o.name, wo.name, "::", wo.slot_forbid, try_slot or o.slot)
-				if wo.slot_forbid and wo.slot_forbid == (try_slot or o.slot) then
-					return nil, "cannot use currently due to an other worn object"
-				end
-			end
-		end
-	end
-
-	return true
-end
-
---- Returns the possible offslot
-function _M:getObjectOffslot(o)
-	return o.offslot
-end
-
---- Wear/wield an item
-function _M:wearObject(o, replace, vocal)
-	local inven = o:wornInven()
-	if not inven then
-		if vocal then game.logSeen(self, "%s is not wearable.", o:getName{do_color=true}) end
-		return false
-	end
-	print("wear slot", inven)
-	local ok, err = self:canWearObject(o)
-	if not ok then
-		if vocal then game.logSeen(self, "%s can not wear: %s (%s).", self.name:capitalize(), o:getName{do_color=true}, err) end
-		return false
-	end
-	if o:check("on_canwear", self, inven) then return false end
-	local offslot = self:getObjectOffslot(o)
-
-	if self:addObject(inven, o) then
-		if vocal then game.logSeen(self, "%s wears: %s.", self.name:capitalize(), o:getName{do_color=true}) end
-		return true
-	elseif offslot and self:getInven(offslot) and #(self:getInven(offslot)) < self:getInven(offslot).max and self:canWearObject(o, offslot) then
-		if vocal then game.logSeen(self, "%s wears(offslot): %s.", self.name:capitalize(), o:getName{do_color=true}) end
-		-- Warning: assume there is now space
-		self:addObject(self:getInven(offslot), o)
-		return true
-	elseif replace then
-		local ro = self:removeObject(inven, 1, true)
-
-		if vocal then game.logSeen(self, "%s wears: %s.", self.name:capitalize(), o:getName{do_color=true}) end
-
-		-- Can we stack the old and new one ?
-		if o:stack(ro) then ro = true end
-
-		-- Warning: assume there is now space
-		self:addObject(inven, o)
-		return ro
-	else
-		if vocal then game.logSeen(self, "%s can not wear: %s.", self.name:capitalize(), o:getName{do_color=true}) end
-		return false
-	end
-end
-
---- Takeoff item
-function _M:takeoffObject(inven, item)
-	local o = self:getInven(inven)[item]
-	if o:check("on_cantakeoff", self, inven) then return false end
-
-	o = self:removeObject(inven, item, true)
-	return o
-end
-
---- Call when an object is worn
-function _M:onWear(o)
-	-- Apply wielder properties
-	o.wielded = {}
-	if o.wielder then
-		for k, e in pairs(o.wielder) do
-			o.wielded[k] = self:addTemporaryValue(k, e)
-		end
-	end
-end
-
---- Call when an object is taken off
-function _M:onTakeoff(o)
-	if o.wielded then
-		for k, id in pairs(o.wielded) do
-			self:removeTemporaryValue(k, id)
-		end
-	end
-	o.wielded = nil
-end
-
---- Re-order inventory, sorting and stacking it
-function _M:sortInven(inven)
-	if not inven then inven = self.inven[self.INVEN_INVEN] end
-	inven = self:getInven(inven)
-
-	-- Stack objects first, from bottom
-	for i = #inven, 1, -1 do
-		-- If it is stackable, look for obejcts before it that it could stack into
-		if inven[i]:stackable() then
-			for j = i - 1, 1, -1 do
-				if inven[j]:stack(inven[i]) then
-					table.remove(inven, i)
-					break
-				end
-			end
-		end
-	end
-
-	-- Sort them
-	table.sort(inven, function(a, b)
-		local ta, tb = a:getTypeOrder(), b:getTypeOrder()
-		local sa, sb = a:getSubtypeOrder(), b:getSubtypeOrder()
-		if ta == tb then
-			if sa == sb then
-				return a.name < b.name
-			else
-				return sa < sb
-			end
-		else
-			return ta < tb
-		end
-	end)
-end
-
---- Finds an object by name in an inventory
--- @param inven the inventory to look into
--- @param name the name to look for
--- @param getname the parameters to pass to getName(), if nil the default is {no_count=true, force_id=true}
-function _M:findInInventory(inven, name, getname)
-	getname = getname or {no_count=true, force_id=true}
-	for item, o in ipairs(inven) do
-		if o:getName(getname) == name then return o, item end
-	end
-end
-
---- Finds an object by name in all the actor's inventories
--- @param name the name to look for
--- @param getname the parameters to pass to getName(), if nil the default is {no_count=true, force_id=true}
-function _M:findInAllInventories(name, getname)
-	for inven_id, inven in pairs(self.inven) do
-		local o, item = self:findInInventory(inven, name, getname)
-		if o and item then return o, item, inven_id end
-	end
-end
diff --git a/game/engine/interface/ActorLevel.lua b/game/engine/interface/ActorLevel.lua
deleted file mode 100644
index 7278d96a93a9a79edaf664be79021d5797c3643e..0000000000000000000000000000000000000000
--- a/game/engine/interface/ActorLevel.lua
+++ /dev/null
@@ -1,122 +0,0 @@
--- 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"
-
---- Interface to add leveling capabilities to actors
--- Defines the exp property, which is the current experience, level which is the current level and exp_worth which is a multiplicator
--- to the monster level default exp
-module(..., package.seeall, class.make)
-
-_M.actors_max_level = false
-
-_M.exp_chart = function(level)
-	local exp = 10
-	local mult = 10
-	for i = 2, level do
-		exp = exp + level * mult
-		mult = mult + 1
-	end
-	return exp
-end
-
-function _M:init(t)
-	if t.level_range then
-		self.level = 1
-		self.start_level = t.level_range[1]
-		self.max_level = t.level_range[2]
-	else
-		self.level = 1
-		self.start_level = t.level or 1
-	end
-	self.exp = t.exp or 0
-	self.exp_mod = t.exp_mod or 1
-	self.exp_worth = t.exp_worth or 1
-end
-
---- Resolves the correct level
--- called by self:resolve()
-function _M:resolveLevel()
-	self:forceLevelup(self.start_level)
-end
-
---- Defines the experience chart used
--- Static!
--- @param chart either a table of format "[level] = exp_needed" or a function that takes one parameter, a level, and returns the experience needed to reach it.
-function _M:defineExperienceChart(chart)
-	assert(type(chart) == "table" or type(chart) == "function", "chart is neither table nor function")
-	_M.exp_chart = chart
-end
-
---- Defines the max level attainable
--- @param max the maximun level. Can be nil to not have a limit
--- Static!
-function _M:defineMaxLevel(max)
-	_M.actors_max_level = max
-end
-
---- Get the exp needed for the given level
--- @param level the level to check exp for
--- @return the exp needed, or nil if this level is not achievable
-function _M:getExpChart(level)
-	if type(self.exp_chart) == "table" then
-		return self.exp_chart[level] * self.exp_mod
-	else
-		return self.exp_chart(level) * self.exp_mod
-	end
-end
-
---- Gains some experience
--- If a levelup happens it calls self:levelup(), modules are encourraged to rewrite it to do whatever is needed.
-function _M:gainExp(value)
-	self.changed = true
-	self.exp = math.max(0, self.exp + value)
-	while self:getExpChart(self.level + 1) and self.exp >= self:getExpChart(self.level + 1) and (not self.actors_max_level or self.level < self.actors_max_level) do
-		-- At max level, if any
-		if self.actors_max_level and self.level >= self.actors_max_level then return end
-		if self.max_level and self.level >= self.max_level then return end
-
-		self.level = self.level + 1
-		self.exp = self.exp - self:getExpChart(self.level)
-		self:levelup()
-	end
-end
-
---- How much experience is this actor worth
--- @param target to whom is the exp rewarded
--- @return the experience rewarded
-function _M:worthExp(target)
-	return self.level * self.exp_worth
-end
-
---- Method called when leveing up, module author rewrite it to do as you please
-function _M:levelup()
-end
-
---- Forces an actor to levelup to "lev"
-function _M:forceLevelup(lev)
-	while self.level < lev do
-		-- At max level, if any
-		if self.max_level and self.level >= self.max_level then break end
-
-		self.level = self.level + 1
-		self.exp = 0
-		self:levelup()
-	end
-end
diff --git a/game/engine/interface/ActorLife.lua b/game/engine/interface/ActorLife.lua
deleted file mode 100644
index 9cfdd8d65eb5230ca1c0e99e62c8499f0f76737c..0000000000000000000000000000000000000000
--- a/game/engine/interface/ActorLife.lua
+++ /dev/null
@@ -1,86 +0,0 @@
--- 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 Target = require "engine.Target"
-local DamageType = require "engine.DamageType"
-
---- Handles actors life and death
-module(..., package.seeall, class.make)
-
-function _M:init(t)
-	self.max_life = t.max_life or 100
-	self.life = t.life or self.max_life
-	self.life_regen = t.life_regen or 0
-end
-
---- Checks if something bumps in us
--- If it happens the method attack is called on the target with the attacker as parameter.
--- Do not touch!
-function _M:block_move(x, y, e, can_attack)
-	-- Dont bump yourself!
-	if e and e ~= self and can_attack then
-		e:attack(self)
-	end
-	return true
-end
-
---- Regenerate life, call it from your actor class act() method
-function _M:regenLife()
-	if self.life_regen then
-		self.life = util.bound(self.life + self.life_regen, 0, self.max_life)
-	end
-end
-
---- Heal some
-function _M:heal(value, src)
-	self.life = util.bound(self.life + value, 0, self.max_life)
-	self.changed = true
-end
-
---- Remove some HP from an actor
--- If HP is reduced to 0 then remove from the level and call the die method.<br/>
--- When an actor dies its dead property is set to true, to wait until garbage collection deletes it
-function _M:takeHit(value, src)
-	if self.onTakeHit then value = self:onTakeHit(value, src) end
-	self.life = self.life - value
-	self.changed = true
-	if self.life <= 0 then
-		game.logSeen(self, "%s killed %s!", src.name:capitalize(), self.name)
-		return self:die(src)
-	end
-end
-
---- Called when died
-function _M:die(src)
-	if game.level:hasEntity(self) then game.level:removeEntity(self) end
-	self.dead = true
-	self.changed = true
-
-	self:check("on_die", src)
-end
-
---- Actor is being attacked!
--- Module authors should rewrite it to handle combat, dialog, ...
--- @param target the actor attacking us
-function _M:attack(target)
-	game.logSeen(target, "%s attacks %s.", self.name:capitalize(), target.name:capitalize())
-	target:takeHit(10, self)
-end
diff --git a/game/engine/interface/ActorProject.lua b/game/engine/interface/ActorProject.lua
deleted file mode 100644
index 49997ad03146bf78c671ba288c1a9fca1480f673..0000000000000000000000000000000000000000
--- a/game/engine/interface/ActorProject.lua
+++ /dev/null
@@ -1,278 +0,0 @@
--- 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 Target = require "engine.Target"
-local DamageType = require "engine.DamageType"
-
---- Handles actors projecting damage to zones/targets
-module(..., package.seeall, class.make)
-
-function _M:init(t)
-end
-
---- Project damage to a distance
--- @param t a type table describing the attack, passed to engine.Target:getType() for interpretation
--- @param x target coords
--- @param y target coords
--- @param damtype a damage type ID from the DamageType class
--- @param dam damage to be done
--- @param particles particles effect configuration, or nil
-function _M:project(t, x, y, damtype, dam, particles)
-	-- Call the on project of the target grid if possible
-	if not t.bypass and game.level.map:checkAllEntities(x, y, "on_project", self, t, x, y, damtype, dam, particles) then
-		return
-	end
-
-	if type(particles) ~= "table" then particles = nil end
-
---	if type(dam) == "number" and dam < 0 then return end
-	local typ = Target:getType(t)
-
-	local grids = {}
-	local function addGrid(x, y)
-		if not grids[x] then grids[x] = {} end
-		grids[x][y] = true
-	end
-
-	local srcx, srcy = t.x or self.x, t.y or self.y
-
-	-- Stop at range or on block
-	local lx, ly = x, y
-	local l = line.new(srcx, srcy, x, y)
-	lx, ly = l()
-	local initial_dir = lx and coord_to_dir[lx - srcx][ly - srcy] or 5
-	while lx and ly do
-		if not typ.no_restrict then
-			if typ.stop_block and game.level.map:checkAllEntities(lx, ly, "block_move") then break
-			elseif game.level.map:checkEntity(lx, ly, Map.TERRAIN, "block_move") then break end
-			if typ.range and math.sqrt((srcx-lx)^2 + (srcy-ly)^2) > typ.range then break end
-		end
-
-		-- Deam damage: beam
-		if typ.line then addGrid(lx, ly) end
-
-		lx, ly = l()
-	end
-	-- Ok if we are at the end reset lx and ly for the next code
-	if not lx and not ly then lx, ly = x, y end
-
-	if typ.ball then
-		core.fov.calc_circle(lx, ly, typ.ball, function(_, px, py)
-			-- Deal damage: ball
-			addGrid(px, py)
-			if not typ.no_restrict and game.level.map:checkEntity(px, py, Map.TERRAIN, "block_move") then return true end
-		end, function()end, nil)
-		addGrid(lx, ly)
-	elseif typ.cone then
-		core.fov.calc_beam(lx, ly, typ.cone, initial_dir, typ.cone_angle, function(_, px, py)
-			-- Deal damage: cone
-			addGrid(px, py)
-			if not typ.no_restrict and game.level.map:checkEntity(px, py, Map.TERRAIN, "block_move") then return true end
-		end, function()end, nil)
-		addGrid(lx, ly)
-	else
-		-- Deam damage: single
-		addGrid(lx, ly)
-	end
-
-	-- Now project on each grid, one type
-	local tmp = {}
-	if type(damtype) == "function" then
-		local stop = false
-		for px, ys in pairs(grids) do
-			for py, _ in pairs(ys) do
-				if particles then
-					game.level.map:particleEmitter(px, py, 1, particles.type)
-				end
-				if damtype(px, py, tg, self) then stop=true break end
-			end
-			if stop then break end
-		end
-	else
-		for px, ys in pairs(grids) do
-			for py, _ in pairs(ys) do
-				-- Call the projected method of the target grid if possible
-				if not game.level.map:checkAllEntities(x, y, "projected", self, t, x, y, damtype, dam, particles) then
-					-- Friendly fire ?
-					if px == self.x and py == self.y then
-						if t.friendlyfire then
-							DamageType:get(damtype).projector(self, px, py, damtype, dam, tmp)
-							if particles then
-								game.level.map:particleEmitter(px, py, 1, particles.type)
-							end
-						end
-					else
-						DamageType:get(damtype).projector(self, px, py, damtype, dam, tmp)
-						if particles then
-							game.level.map:particleEmitter(px, py, 1, particles.type)
-						end
-					end
-				end
-			end
-		end
-	end
-	return grids
-end
-
---- Can we project to this grid ?
--- @param t a type table describing the attack, passed to engine.Target:getType() for interpretation
--- @param x target coords
--- @param y target coords
-function _M:canProject(t, x, y)
-	local typ = Target:getType(t)
-
-	-- Stop at range or on block
-	local lx, ly = x, y
-	local l = line.new(self.x, self.y, x, y)
-	lx, ly = l()
-	while lx and ly do
-		if not typ.no_restrict then
-			if typ.stop_block and game.level.map:checkAllEntities(lx, ly, "block_move") then break
-			elseif game.level.map:checkEntity(lx, ly, Map.TERRAIN, "block_move") then break end
-			if typ.range and math.sqrt((self.x-lx)^2 + (self.y-ly)^2) > typ.range then break end
-		end
-
-		lx, ly = l()
-	end
-	-- Ok if we are at the end reset lx and ly for the next code
-	if not lx and not ly then lx, ly = x, y end
-
-	if lx == x and ly == y then return true, lx, ly end
-	return false, lx, ly
-end
-
-_M.projectile_class = "engine.Projectile"
-
---- Project damage to a distance using a moving projectile
--- @param t a type table describing the attack, passed to engine.Target:getType() for interpretation
--- @param x target coords
--- @param y target coords
--- @param damtype a damage type ID from the DamageType class
--- @param dam damage to be done
--- @param particles particles effect configuration, or nil
-function _M:projectile(t, x, y, damtype, dam, particles)
-	-- Call the on project of the target grid if possible
---	if not t.bypass and game.level.map:checkAllEntities(x, y, "on_project", self, t, x, y, damtype, dam, particles) then
---		return
---	end
-
-	if type(particles) ~= "function" and type(particles) ~= "table" then particles = nil end
-
---	if type(dam) == "number" and dam < 0 then return end
-	local typ = Target:getType(t)
-
-	local proj = require(self.projectile_class):makeProject(self, t.display, {x=x, y=y, start_x = t.x or self.x, start_y = t.y or self.y, damtype=damtype, tg=t, typ=typ, dam=dam, particles=particles})
-	game.zone:addEntity(game.level, proj, "projectile", self.x, self.y)
-end
-
-function _M:projectDoMove(typ, tgtx, tgty, x, y, srcx, srcy)
-	-- Stop at range or on block
-	local l = line.new(srcx, srcy, tgtx, tgty)
-	local lx, ly = srcx, srcy
-	-- Look for our current position
-	while lx and ly and not (lx == x and ly == y) do lx, ly = l() end
-	-- Now get the next position
-	if lx and ly then lx, ly = l() end
-
-	if lx and ly then
-		if not typ.no_restrict then
-			if typ.stop_block and game.level.map:checkAllEntities(lx, ly, "block_move") then return lx, ly, false, true
-			elseif game.level.map:checkEntity(lx, ly, Map.TERRAIN, "block_move") then return lx, ly, false, true end
-			if typ.range and math.sqrt((srcx-lx)^2 + (srcy-ly)^2) > typ.range then return lx, ly, false, true end
-		end
-
-		-- End of the map
-		if lx < 0 or lx >= game.level.map.w or ly < 0 or ly >= game.level.map.h then return lx, ly, false, true end
-
-		-- Deam damage: beam
-		if typ.line then return lx, ly, true, false end
-	end
-	-- Ok if we are at the end
-	if (not lx and not ly) then return lx, ly, false, true end
-	return lx, ly, false, false
-end
-
-
-function _M:projectDoAct(typ, tg, damtype, dam, particles, px, py, tmp)
-	-- Now project on each grid, one type
-	if type(damtype) == "function" then
-		if particles and type(particles) == "table" then
-			game.level.map:particleEmitter(px, py, 1, particles.type)
-		end
-		if damtype(px, py, tg, self) then return true end
-		return false
-	else
-		-- Call the projected method of the target grid if possible
-		if not game.level.map:checkAllEntities(px, py, "projected", self, typ, px, py, damtype, dam, particles) then
-			-- Friendly fire ?
-			if px == self.x and py == self.y then
-				if tg.friendlyfire then
-					DamageType:get(damtype).projector(self, px, py, damtype, dam, tmp)
-					if particles and type(particles) == "table" then
-						game.level.map:particleEmitter(px, py, 1, particles.type)
-					end
-				end
-			else
-				DamageType:get(damtype).projector(self, px, py, damtype, dam, tmp)
-				if particles and type(particles) == "table" then
-					game.level.map:particleEmitter(px, py, 1, particles.type)
-				end
-			end
-		end
-	end
-end
-
-function _M:projectDoStop(typ, tg, damtype, dam, particles, lx, ly, tmp)
-	local grids = {}
-	local function addGrid(x, y)
-		if not grids[x] then grids[x] = {} end
-		grids[x][y] = true
-	end
-
-	if typ.ball then
-		core.fov.calc_circle(lx, ly, typ.ball, function(_, px, py)
-			-- Deal damage: ball
-			addGrid(px, py)
-			if not typ.no_restrict and game.level.map:checkEntity(px, py, Map.TERRAIN, "block_move") then return true end
-		end, function()end, nil)
-		addGrid(lx, ly)
-	elseif typ.cone then
-		local initial_dir = lx and util.getDir(lx, ly, x, y) or 5
-		core.fov.calc_beam(lx, ly, typ.cone, initial_dir, typ.cone_angle, function(_, px, py)
-			-- Deal damage: cone
-			addGrid(px, py)
-			if not typ.no_restrict and game.level.map:checkEntity(px, py, Map.TERRAIN, "block_move") then return true end
-		end, function()end, nil)
-		addGrid(lx, ly)
-	else
-		-- Deam damage: single
-		addGrid(lx, ly)
-	end
-
-	for px, ys in pairs(grids) do
-		for py, _ in pairs(ys) do
-			if self:projectDoAct(typ, tg, damtype, dam, particles, px, py, tmp) then break end
-		end
-	end
-	if particles and type(particles) == "function" then
-		particles(self, tg, lx, ly, grids)
-	end
-end
diff --git a/game/engine/interface/ActorQuest.lua b/game/engine/interface/ActorQuest.lua
deleted file mode 100644
index f85acf92c2f292abecc48439879ce21654165af8..0000000000000000000000000000000000000000
--- a/game/engine/interface/ActorQuest.lua
+++ /dev/null
@@ -1,78 +0,0 @@
--- 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"
-
---- Handles actors quests
-module(..., package.seeall, class.make)
-
-_M.quest_class = "engine.Quest"
-
---- Grants a quest to an actor from the given quest definition
-function _M:grantQuest(quest, args)
-	if type(quest) == "string" then
-		local f, err = loadfile("/data/quests/"..quest..".lua")
-		if not f and err then error(err) end
-		local ret = args or {}
-		setfenv(f, setmetatable(ret, {__index=_G}))
-		f()
-		ret.id = ret.id or quest
-		quest = ret
-	end
-	if not quest.id then quest.id = quest.name end
-	if self:hasQuest(quest.id) then return end
-
-	assert(quest.name, "no quest name")
-	assert(quest.desc, "no quest desc")
-
-	self.quests = self.quests or {}
-	self.quests[quest.id] = require(_M.quest_class).new(quest, self)
-	self.quests[quest.id].gained_turn = game.turn
-	print("[QUEST] given to", self, quest.id)
-	self:check("on_quest_grant", quest)
-end
-
---- Sets the status of a quest for an actor
--- If the actor does not have the quest, does nothing
-function _M:setQuestStatus(quest, status, sub)
-	print("[QUEST] try update status on", self.name, quest, status, sub)
-	if not self.quests then return end
-	if type(quest) == "table" then quest = quest.id end
-	local q = self.quests[quest]
-	if not q then return end
-	if q:setStatus(status, sub, self) then
-		self:check("on_quest_status", q, status, sub)
-	end
-end
-
---- Checks if the actor has this quest
-function _M:hasQuest(id)
-	if not self.quests then return false end
-	return self.quests[id]
-end
-
---- Checks the status of the given quest
--- If the actor does not have the quest, does nothing
-function _M:isQuestStatus(quest, status, sub)
-	if not self.quests then return end
-	if type(quest) == "table" then quest = quest.id end
-	local q = self.quests[quest]
-	if not q then return end
-	return q:isStatus(status, sub)
-end
diff --git a/game/engine/interface/ActorResource.lua b/game/engine/interface/ActorResource.lua
deleted file mode 100644
index 2d66992cb86066cbfcf6f2e8b1a1b092d5c9facc..0000000000000000000000000000000000000000
--- a/game/engine/interface/ActorResource.lua
+++ /dev/null
@@ -1,99 +0,0 @@
--- 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"
-
---- Handles actors life and death
-module(..., package.seeall, class.make)
-
-_M.resources_def = {}
-
---- Defines resource
--- Static!
--- All actors will now have :getResourcename() and :incResourcename() methods as well as a .max_resourcename and .resourcename
--- properties. It is advised to NOT access .resourcename directly and use the get/inc methods. They handle talent
--- dependencies
-function _M:defineResource(name, short_name, talent, regen_prop, desc)
-	assert(name, "no resource name")
-	assert(short_name, "no resource short_name")
-	table.insert(self.resources_def, {
-		name = name,
-		short_name = short_name,
-		talent = talent,
-		regen_prop = regen_prop,
-		description = desc,
-		maxname = "max_"..short_name,
-	})
-	self.resources_def[#self.resources_def].id = #self.resources_def
-	self.resources_def[short_name] = self.resources_def[#self.resources_def]
-	self["RS_"..short_name:upper()] = #self.resources_def
-	local maxname = "max_"..short_name
-	self["inc"..short_name:lower():capitalize()] = function(self, v)
-		self[short_name] = util.bound(self[short_name] + v, 0, self[maxname])
-	end
-	self["incMax"..short_name:lower():capitalize()] = function(self, v)
-		self[maxname] = self[maxname] + v
-	end
-	if talent then
-		-- if there is an associated talent, check for it
-		self["get"..short_name:lower():capitalize()] = function(self)
-			if self:knowTalent(talent) then
-				return self[short_name]
-			else
-				return 0
-			end
-		end
-		-- if there is an associated talent, check for it
-		self["getMax"..short_name:lower():capitalize()] = function(self)
-			if self:knowTalent(talent) then
-				return self[maxname]
-			else
-				return 0
-			end
-		end
-	else
-		self["get"..short_name:lower():capitalize()] = function(self)
-			return self[short_name]
-		end
-		self["getMax"..short_name:lower():capitalize()] = function(self)
-			return self[maxname]
-		end
-	end
-end
-
-function _M:init(t)
-	for i, r in ipairs(_M.resources_def) do
-		self["max_"..r.short_name] = t["max_"..r.short_name] or 100
-		self[r.short_name] = t[r.short_name] or self["max_"..r.short_name]
-		if r.regen_prop then
-			self[r.regen_prop] = t[r.regen_prop] or 0
-		end
-	end
-end
-
---- Regen resources, shout be called in your actor's act() method
-function _M:regenResources()
-	local r
-	for i = 1, #_M.resources_def do
-		r = _M.resources_def[i]
-		if r.regen_prop then
-			self[r.short_name] = util.bound(self[r.short_name] + self[r.regen_prop], 0, self[r.maxname])
-		end
-	end
-end
diff --git a/game/engine/interface/ActorStats.lua b/game/engine/interface/ActorStats.lua
deleted file mode 100644
index 232e14cfec2c117d0d91ea6bb57ff3586df5af9d..0000000000000000000000000000000000000000
--- a/game/engine/interface/ActorStats.lua
+++ /dev/null
@@ -1,132 +0,0 @@
--- 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"
-
---- Handles actors stats
-module(..., package.seeall, class.make)
-
-_M.stats_def = {}
-
---- Defines stats
--- Static!
-function _M:defineStat(name, short_name, default_value, min, max, desc)
-	assert(name, "no stat name")
-	assert(short_name, "no stat short_name")
-	local no_max = false
-	if type(max) == "table" then no_max = max.no_max; max = max[1] end
-	table.insert(self.stats_def, {
-		name = name,
-		short_name = short_name,
-		description = desc,
-		def = default_value or 10,
-		min = min or 1,
-		max = max or 100,
-		no_max = no_max,
-	})
-	self.stats_def[#self.stats_def].id = #self.stats_def
-	self.stats_def[short_name] = self.stats_def[#self.stats_def]
-	self["STAT_"..short_name:upper()] = #self.stats_def
-	self["get"..short_name:lower():capitalize()] = function(self, scale, raw)
-		return self:getStat(_M["STAT_"..short_name:upper()], scale, raw)
-	end
-end
-
---- Initialises stats with default values if needed
-function _M:init(t)
-	self.stats = t.stats or {}
-	self.inc_stats = t.inc_stats or {}
-	for i, s in ipairs(_M.stats_def) do
-		if self.stats[i] then
-		elseif self.stats[s.short_name] then
-			self.stats[i] = self.stats[s.short_name]
-			self.stats[s.short_name] = nil
-		else
-			self.stats[i] = s.def
-		end
-		if not self.inc_stats[i] then self.inc_stats[i] = 0 end
-	end
-end
-
---- Increases a stat
--- @param stat the stat id to change
--- @param val the increment to add/substract
-function _M:incStat(stat, val)
-	if type(stat) == "string" then
-		stat = _M.stats_def[stat].id
-	end
-
-	local old = self:getStat(stat)
-	if _M.stats_def[stat].no_max then
-		self.stats[stat] = math.max(self.stats[stat] + val, _M.stats_def[stat].min)
-	else
-		self.stats[stat] = math.max(math.min(self.stats[stat] + val, _M.stats_def[stat].max), _M.stats_def[stat].min)
-	end
-	if self:getStat(stat) ~= old then
-		self:onStatChange(stat, self:getStat(stat) - old)
-	end
-	self.changed = true
-	return self:getStat(stat) - old
-end
-
---- Gets a stat value
--- Not that the engine also auto-defines stat specific methods on the form: self:getShortname().
--- If you stat short name is STR then it becomes getStr()
--- @param stat the stat id
--- @param scale a scaling factor, nil means max stat value
--- @param raw false if the scaled result must be rounded down
--- @param no_inc if true it wont include stats gained by self.inc_stats
-function _M:getStat(stat, scale, raw, no_inc)
-	local val, inc
-	if type(stat) == "string" then
-		val = self.stats[_M.stats_def[stat].id]
-		inc = self.inc_stats[_M.stats_def[stat].id]
-	else
-		val = self.stats[stat]
-		inc = self.inc_stats[stat]
-	end
-	if _M.stats_def[stat].no_max then
-		val = math.max(val, _M.stats_def[stat].min) + ((not no_inc) and inc or 0)
-	else
-		val = util.bound(val, _M.stats_def[stat].min, _M.stats_def[stat].max) + ((not no_inc) and inc or 0)
-	end
-	if scale then
-		if not raw then
-			val = math.floor(val * scale / _M.stats_def[stat].max)
-		else
-			val = val * scale / _M.stats_def[stat].max
-		end
-	end
-	return val
-end
-
---- Is the stat maxed ?
-function _M:isStatMax(stat)
-	local val
-	if type(stat) == "string" then
-		val = self.stats[_M.stats_def[stat].id]
-	else
-		val = self.stats[stat]
-	end
-	if math.floor(val) >= _M.stats_def[stat].max then return true end
-end
-
---- Notifies a change of stat value
-function _M:onStatChange(stat, v)
-end
diff --git a/game/engine/interface/ActorTalents.lua b/game/engine/interface/ActorTalents.lua
deleted file mode 100644
index d2e427dea3a7cae4b310df84379ff63de10419a7..0000000000000000000000000000000000000000
--- a/game/engine/interface/ActorTalents.lua
+++ /dev/null
@@ -1,507 +0,0 @@
--- 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"
-
---- Handles actors stats
-module(..., package.seeall, class.make)
-
-_M.talents_def = {}
-_M.talents_types_def = {}
-
---- Defines actor talents
--- Static!
-function _M:loadDefinition(file, env)
-	local f, err = loadfile(file)
-	if not f and err then error(err) end
-	setfenv(f, setmetatable(env or {
-		DamageType = require("engine.DamageType"),
-		Particles = require("engine.Particles"),
-		Talents = self,
-		Map = require("engine.Map"),
-		newTalent = function(t) self:newTalent(t) end,
-		newTalentType = function(t) self:newTalentType(t) end,
-		load = function(f) self:loadDefinition(f, getfenv(2)) end
-	}, {__index=_G}))
-	f()
-end
-
---- Defines one talent type(group)
--- Static!
-function _M:newTalentType(t)
-	assert(t.name, "no talent type name")
-	assert(t.type, "no talent type type")
-	t.description = t.description or ""
-	t.points = t.points or 1
-	t.talents = {}
-	table.insert(self.talents_types_def, t)
-	self.talents_types_def[t.type] = t
-end
-
---- Defines one talent
--- Static!
-function _M:newTalent(t)
-	assert(t.name, "no talent name")
-	assert(t.type, "no or unknown talent type")
-	if type(t.type) == "string" then t.type = {t.type, 1} end
-	if not t.type[2] then t.type[2] = 1 end
-	t.short_name = t.short_name or t.name
-	t.short_name = t.short_name:upper():gsub("[ ]", "_")
-	t.mode = t.mode or "activated"
-	t.points = t.points or 1
-	assert(t.mode == "activated" or t.mode == "sustained" or t.mode == "passive", "wrong talent mode, requires either 'activated' or 'sustained'")
-	assert(t.info, "no talent info")
-
-	-- Can pass a string, make it into a function
-	if type(t.info) == "string" then
-		local infostr = t.info
-		t.info = function() return infostr end
-	end
-	-- Remove line stat with tabs to be cleaner ..
-	local info = t.info
-	t.info = function(self, t) return info(self, t):gsub("\n\t+", "\n") end
-
-	table.insert(self.talents_def, t)
-	t.id = #self.talents_def
-	assert(not self["T_"..t.short_name], "talent already exists with id T_"..t.short_name)
-	self["T_"..t.short_name] = #self.talents_def
-	print("[TALENT]", t.name, t.short_name, #self.talents_def)
-
-	-- Register in the type
-	table.insert(self.talents_types_def[t.type[1]].talents, t)
-end
-
---- Initialises stats with default values if needed
-function _M:init(t)
-	self.talents = t.talents or {}
-	self.talents_types = t.talents_types or {}
-	self.talents_types_mastery = {}
-	self.talents_cd = {}
-	self.sustain_talents = {}
-end
-
---- Make the actor use the talent
-function _M:useTalent(id, who, force_level, ignore_cd, force_target)
-	who = who or self
-	local ab = _M.talents_def[id]
-	assert(ab, "trying to cast talent "..tostring(id).." but it is not defined")
-
-	if ab.mode == "activated" and ab.action then
-		if self:isTalentCoolingDown(ab) and not ignore_cd then
-			game.logPlayer(who, "%s is still on cooldown for %d turns.", ab.name:capitalize(), self.talents_cd[ab.id])
-			return
-		end
-		if not self:preUseTalent(ab) then return end
-		local co = coroutine.create(function()
-			print("USING", ab, ab.name)
-			local old_level
-			local old_target
-			if force_level then old_level = who.talents[id]; who.talents[id] = force_level end
-			if force_target then old_target = rawget(who, "getTarget"); who.getTarget = function() return force_target.x, force_target.y, force_target end end
-			local ret = ab.action(who, ab)
-			if force_target then who.getTarget = old_target end
-			if force_level then who.talents[id] = old_level end
-
-			if not self:postUseTalent(ab, ret) then return end
-
-			-- Everything went ok? then start cooldown if any
-			if not ignore_cd then self:startTalentCooldown(ab) end
-		end)
-		local ok, err = coroutine.resume(co)
-		if not ok and err then print(debug.traceback(co)) error(err) end
-	elseif ab.mode == "sustained" and ab.activate and ab.deactivate then
-		if self:isTalentCoolingDown(ab) and not ignore_cd then
-			game.logPlayer(who, "%s is still on cooldown for %d turns.", ab.name:capitalize(), self.talents_cd[ab.id])
-			return
-		end
-		if not self:preUseTalent(ab) then return end
-		local co = coroutine.create(function()
-			if not self.sustain_talents[id] then
-				local old_level
-				if force_level then old_level = who.talents[id]; who.talents[id] = force_level end
-				local ret = ab.activate(who, ab)
-				if force_level then who.talents[id] = old_level end
-
-				if not self:postUseTalent(ab, ret) then return end
-
-				self.sustain_talents[id] = ret
-			else
-				local old_level
-				if force_level then old_level = who.talents[id]; who.talents[id] = force_level end
-				local ret = ab.deactivate(who, ab, self.sustain_talents[id])
-				if force_level then who.talents[id] = old_level end
-
-				if not self:postUseTalent(ab, ret) then return end
-
-				-- Everything went ok? then start cooldown if any
-				if not ignore_cd then self:startTalentCooldown(ab) end
-				self.sustain_talents[id] = nil
-			end
-		end)
-		local ret, err = coroutine.resume(co)
-		if not ret and err then print(debug.traceback(co)) error(err) end
-	else
-		error("Activating non activable or sustainable talent: "..id.." :: "..ab.name.." :: "..ab.mode)
-	end
-	self.changed = true
-	return true
-end
-
---- Replace some markers in a string with info on the talent
-function _M:useTalentMessage(ab)
-	if not ab.message then return nil end
-	local str = ab.message
-	local _, _, target = self:getTarget()
-	local tname = "unknown"
-	if target then tname = target.name end
-	str = str:gsub("@Source@", self.name:capitalize())
-	str = str:gsub("@source@", self.name)
-	str = str:gsub("@target@", tname)
-	str = str:gsub("@Target@", tname:capitalize())
-	return str
-end
-
---- Called before an talent is used
--- Redefine as needed
--- @param ab the talent (not the id, the table)
--- @return true to continue, false to stop
-function _M:preUseTalent(talent)
-	return true
-end
-
---- Called before an talent is used
--- Redefine as needed
--- @param ab the talent (not the id, the table)
--- @param ret the return of the talent action
--- @return true to continue, false to stop
-function _M:postUseTalent(talent, ret)
-	return true
-end
-
---- Is the sustained talent activated ?
-function _M:isTalentActive(t_id)
-	return self.sustain_talents[t_id]
-end
-
---- Returns how many talents of this type the actor knows
--- @param type the talent type to count
--- @param exlude_id if not nil the count will ignore this talent id
-function _M:numberKnownTalent(type, exlude_id)
-	local nb = 0
-	for id, _ in pairs(self.talents) do
-		local t = _M.talents_def[id]
-		if t.type[1] == type and (not exlude_id or exlude_id ~= id) then nb = nb + 1 end
-	end
-	return nb
-end
-
---- Actor learns a talent
--- @param t_id the id of the talent to learn
--- @return true if the talent was learnt, nil and an error message otherwise
-function _M:learnTalent(t_id, force, nb)
-	local t = _M.talents_def[t_id]
-
-	if not force then
-		local ok, err = self:canLearnTalent(t)
-		if not ok and err then return nil, err end
-	end
-
-	if not self.talents[t_id] then
-		-- Auto assign to hotkey
-		if t.mode ~= "passive" and self.hotkey then
-			for i = 1, 36 do
-				if not self.hotkey[i] then
-					self.hotkey[i] = {"talent", t_id}
-					break
-				end
-			end
-		end
-	end
-
-	self.talents[t_id] = (self.talents[t_id] or 0) + (nb or 1)
-
-	if t.on_learn then t.on_learn(self, t) end
-
-	self.changed = true
-	return true
-end
-
---- Actor forgets a talent
--- @param t_id the id of the talent to learn
--- @return true if the talent was unlearnt, nil and an error message otherwise
-function _M:unlearnTalent(t_id)
-	local t = _M.talents_def[t_id]
-
-	if self.talents[t_id] and self.talents[t_id] == 1 then
-		if self.hotkey then
-			for i, known_t_id in pairs(self.hotkey) do
-				if known_t_id[1] == "talent" and known_t_id[2] == t_id then self.hotkey[i] = nil end
-			end
-		end
-	end
-
-	self.talents[t_id] = self.talents[t_id] - 1
-	if self.talents[t_id] == 0 then self.talents[t_id] = nil end
-
-	if t.on_unlearn then t.on_unlearn(self, t) end
-
-	self.changed = true
-	return true
-end
-
---- Checks the talent if learnable
--- @param t the talent to check
--- @param offset the level offset to check, defaults to 1
-function _M:canLearnTalent(t, offset)
-	-- Check prerequisites
-	if t.require then
-		local req = t.require
-		if type(req) == "function" then req = req(self, t) end
-		local tlev = self:getTalentLevelRaw(t) + (offset or 1)
-
-		-- Obviously this requires the ActorStats interface
-		if req.stat then
-			for s, v in pairs(req.stat) do
-				v = util.getval(v, tlev)
-				if self:getStat(s) < v then return nil, "not enough stat" end
-			end
-		end
-		if req.level then
-			if self.level < util.getval(req.level, tlev) then
-				return nil, "not enough levels"
-			end
-		end
-		if req.talent then
-			for _, tid in ipairs(req.talent) do
-				if type(tid) == "table" then
-					if type(tid[2]) == "boolean" and tid[2] == false then
-						if self:knowTalent(tid[1]) then return nil, "missing dependency" end
-					else
-						if self:getTalentLevelRaw(tid[1]) < tid[2] then return nil, "missing dependency" end
-					end
-				else
-					if not self:knowTalent(tid) then return nil, "missing dependency" end
-				end
-			end
-		end
-	end
-
-	if not self:knowTalentType(t.type[1]) and not t.type_no_req then return nil, "unknown talent type" end
-
-	-- Check talent type
-	local known = self:numberKnownTalent(t.type[1], t.id)
-	if t.type[2] and known < t.type[2] - 1 then
-		return nil, "not enough talents of this type known"
-	end
-
-	-- Ok!
-	return true
-end
-
---- Formats the requirements as a (multiline) string
--- @param t_id the id of the talent to desc
--- @param levmod a number (1 should be the smartest) to add to current talent level to display requirements, defaults to 0
-function _M:getTalentReqDesc(t_id, levmod)
-	local t = _M.talents_def[t_id]
-	local req = t.require
-	if not req then return "" end
-	if type(req) == "function" then req = req(self, t) end
-
-	local tlev = self:getTalentLevelRaw(t_id) + (levmod or 0)
-
-	local str = ""
-
-	if not t.type_no_req then
-		str = str .. (self:knowTalentType(t.type[1]) and "#00ff00#" or "#ff0000#") .. "- Talent category known\n"
-	end
-
-	if t.type[2] and t.type[2] > 1 then
-		local known = self:numberKnownTalent(t.type[1], t.id)
-		local c = (known >= t.type[2] - 1) and "#00ff00#" or "#ff0000#"
-		str = str .. ("- %sTalents of the same category: %d\n"):format(c, t.type[2] - 1)
-	end
-
-	-- Obviously this requires the ActorStats interface
-	if req.stat then
-		for s, v in pairs(req.stat) do
-			v = util.getval(v, tlev)
-			local c = (self:getStat(s) >= v) and "#00ff00#" or "#ff0000#"
-			str = str .. ("- %s%s %d\n"):format(c, self.stats_def[s].name, v)
-		end
-	end
-	if req.level then
-		local v = util.getval(req.level, tlev)
-		local c = (self.level >= v) and "#00ff00#" or "#ff0000#"
-		str = str .. ("- %sLevel %d\n"):format(c, v)
-	end
-	if req.talent then
-		for _, tid in ipairs(req.talent) do
-			if type(tid) == "table" then
-				if type(tid[2]) == "boolean" and tid[2] == false then
-					local c = (not self:knowTalent(tid[1])) and "#00ff00#" or "#ff0000#"
-					str = str .. ("- %sTalent %s (not known)\n"):format(c, self:getTalentFromId(tid[1]).name)
-				else
-					local c = (self:getTalentLevelRaw(tid[1]) >= tid[2]) and "#00ff00#" or "#ff0000#"
-					str = str .. ("- %sTalent %s (%d)\n"):format(c, self:getTalentFromId(tid[1]).name, tid[2])
-				end
-			else
-				local c = self:knowTalent(tid) and "#00ff00#" or "#ff0000#"
-				str = str .. ("- %sTalent %s\n"):format(c, self:getTalentFromId(tid).name)
-			end
-		end
-	end
-
-	return str
-end
-
---- Return the full description of a talent
--- You may overload it to add more data (like power usage, ...)
-function _M:getTalentFullDescription(t)
-	return t.info(self, t)
-end
-
---- Do we know this talent type
-function _M:knowTalentType(name)
-	return self.talents_types[name]
-end
-
---- Do we know this talent
-function _M:knowTalent(id)
-	if type(id) == "table" then id = id.id end
-	return (self:getTalentLevelRaw(id) > 0) and true or false
-end
-
---- Talent level, 0 if not known
-function _M:getTalentLevelRaw(id)
-	if type(id) == "table" then id = id.id end
-	return self.talents[id] or 0
-end
-
---- Talent level, 0 if not known
--- Includes mastery
-function _M:getTalentLevel(id)
-	local t
-
-	if type(id) == "table" then
-		t, id = id, id.id
-	else
-		t = _M.talents_def[id]
-	end
-	return (self:getTalentLevelRaw(id)) * (self.talents_types_mastery[t.type[1]] or 1)
-end
-
---- Talent type level, sum of all raw levels of talents inside
-function _M:getTalentTypeLevelRaw(tt)
-	local nb = 0
-	for tid, lev in pairs(self.talents) do
-		local t = self:getTalentFromId(tid)
-		if t.type[1] == tt then nb = nb + lev end
-	end
-	return nb
-end
-
---- Return talent type mastery
-function _M:getTalentTypeMastery(tt)
-	return self.talents_types_mastery[tt] or 1
-end
-
---- Sets talent type mastery
-function _M:setTalentTypeMastery(tt, v)
-	self.talents_types_mastery[tt] = v
-end
-
---- Return talent definition from id
-function _M:getTalentFromId(id)
-	return _M.talents_def[id]
-end
-
---- Return talent definition from id
-function _M:getTalentTypeFrom(id)
-	return _M.talents_types_def[id]
-end
-
---- Actor learns a talent type
--- @param t_id the id of the talent to learn
--- @return true if the talent was learnt, nil and an error message otherwise
-function _M:learnTalentType(tt, v)
-	if v == nil then v = true end
-	if self.talents_types[tt] then return end
-	self.talents_types[tt] = v
-	self.talents_types_mastery[tt] = self.talents_types_mastery[tt] or 1
-	self.changed = true
-	return true
-end
-
---- Actor forgets a talent type
--- @param t_id the id of the talent to learn
--- @return true if the talent was unlearnt, nil and an error message otherwise
-function _M:unlearnTalentType(tt)
-	self.talents_types[tt] = false
-	self.changed = true
-	return true
-end
-
---- Starts a talent cooldown
--- @param t the talent to cooldown
-function _M:startTalentCooldown(t)
-	if not t.cooldown then return end
-	local cd = t.cooldown
-	if type(cd) == "function" then cd = cd(self, t) end
-	self.talents_cd[t.id] = cd
-	self.changed = true
-end
-
---- Is talent in cooldown?
-function _M:isTalentCoolingDown(t)
-	if not t.cooldown then return false end
-	if self.talents_cd[t.id] and self.talents_cd[t.id] > 0 then return self.talents_cd[t.id] else return false end
-end
-
---- Returns the range of a talent
-function _M:getTalentRange(t)
-	if not t.range then return 1 end
-	if type(t.range) == "function" then return t.range(self, t) end
-	return t.range
-end
-
---- Returns the projectile speed of a talent
-function _M:getTalentProjectileSpeed(t)
-	if not t.proj_speed then return nil end
-	if type(t.proj_speed) == "function" then return t.proj_speed(self, t) end
-	return t.proj_speed
-end
-
---- Cooldown all talents by one
--- This should be called in your actors "act()" method
-function _M:cooldownTalents()
-	for tid, c in pairs(self.talents_cd) do
-		self.changed = true
-		self.talents_cd[tid] = self.talents_cd[tid] - 1
-		if self.talents_cd[tid] == 0 then
-			self.talents_cd[tid] = nil
-			if self.onTalentCooledDown then self:onTalentCooledDown(tid) end
-		end
-	end
-end
-
---- Show usage dialog
-function _M:useTalents()
-	local d = require("engine.dialogs.UseTalents").new(self)
-	game:registerDialog(d)
-end
diff --git a/game/engine/interface/ActorTemporaryEffects.lua b/game/engine/interface/ActorTemporaryEffects.lua
deleted file mode 100644
index 933896986968d889b5180641c9c46b9195f527bf..0000000000000000000000000000000000000000
--- a/game/engine/interface/ActorTemporaryEffects.lua
+++ /dev/null
@@ -1,152 +0,0 @@
--- 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"
-
---- Handles actors temporary effects (temporary boost of a stat, ...)
-module(..., package.seeall, class.make)
-
-_M.tempeffect_def = {}
-
---- Defines actor temporary effects
--- Static!
-function _M:loadDefinition(file)
-	local f, err = loadfile(file)
-	if not f and err then error(err) end
-	setfenv(f, setmetatable({
-		DamageType = require "engine.DamageType",
-		newEffect = function(t) self:newEffect(t) end,
-		load = function(f) self:loadDefinition(f) end
-	}, {__index=_G}))
-	f()
-end
-
---- Defines one effect
--- Static!
-function _M:newEffect(t)
-	assert(t.name, "no effect name")
-	assert(t.desc, "no effect desc")
-	assert(t.type, "no effect type")
-	t.name = t.name:upper()
-	t.activation = t.activation or function() end
-	t.deactivation = t.deactivation or function() end
-	t.parameters = t.parameters or {}
-	t.type = t.type or "physical"
-	t.status = t.status or "detrimental"
-
-	table.insert(self.tempeffect_def, t)
-	t.id = #self.tempeffect_def
-	self["EFF_"..t.name] = #self.tempeffect_def
-end
-
-
-function _M:init(t)
-	self.tmp = {}
-end
-
---- Counts down timed effects, call from your actors "act" method
---
-function _M:timedEffects()
-	local todel = {}
-	for eff, p in pairs(self.tmp) do
-		if p.dur <= 0 then
-			todel[#todel+1] = eff
-		else
-			if _M.tempeffect_def[eff].on_timeout then
-				if _M.tempeffect_def[eff].on_timeout(self, p) then
-					todel[#todel+1] = eff
-				end
-			end
-		end
-		p.dur = p.dur - 1
-	end
-
-	while #todel > 0 do
-		self:removeEffect(table.remove(todel))
-	end
-end
-
---- Sets a timed effect on the actor
--- @param eff_id the effect to set
--- @param dur the number of turns to go on
--- @param p a table containing the effects parameters
--- @parm silent true to suppress messages
-function _M:setEffect(eff_id, dur, p, silent)
-	-- Beware, setting to 0 means removing
-	if dur <= 0 then return self:removeEffect(eff_id) end
-
-	-- If we already have it, we check if it knows how to "merge", or else we remove it and re-add it
-	if self:hasEffect(eff_id) then
-		if _M.tempeffect_def[eff_id].on_merge then
-			p.dur = dur
-			self.tmp[eff_id] = _M.tempeffect_def[eff_id].on_merge(self, self.tmp[eff_id], p)
-			self.changed = true
-			return
-		else
-			self:removeEffect(eff_id, true)
-		end
-	end
-
-	for k, e in pairs(_M.tempeffect_def[eff_id].parameters) do
-		if not p[k] then p[k] = e end
-	end
-	p.dur = dur
-	self.tmp[eff_id] = p
-	if _M.tempeffect_def[eff_id].on_gain then
-		local ret, fly = _M.tempeffect_def[eff_id].on_gain(self, p)
-		if not silent then
-			if ret then
-				game.logSeen(self, ret:gsub("#Target#", self.name:capitalize()):gsub("#target#", self.name))
-			end
-			if fly and game.flyers and game.level.map.seens(self.x, self.y) then
-				local sx, sy = game.level.map:getTileToScreen(self.x, self.y)
-				game.flyers:add(sx, sy, 20, (rng.range(0,2)-1) * 0.5, -3, fly, {255,100,80})
-			end
-		end
-	end
-	if _M.tempeffect_def[eff_id].activate then _M.tempeffect_def[eff_id].activate(self, p) end
-	self.changed = true
-end
-
---- Check timed effect
--- @param eff_id the effect to check for
--- @return either nil or the parameters table for the effect
-function _M:hasEffect(eff_id)
-	return self.tmp[eff_id]
-end
-
---- Removes the effect
-function _M:removeEffect(eff, silent)
-	local p = self.tmp[eff]
-	self.tmp[eff] = nil
-	self.changed = true
-	if _M.tempeffect_def[eff].on_lose then
-		local ret, fly = _M.tempeffect_def[eff].on_lose(self, p)
-		if not silent then
-			if ret then
-				game.logSeen(self, ret:gsub("#Target#", self.name:capitalize()):gsub("#target#", self.name))
-			end
-			if fly and game.flyers then
-				local sx, sy = game.level.map:getTileToScreen(self.x, self.y)
-				game.flyers:add(sx, sy, 20, (rng.range(0,2)-1) * 0.5, -3, fly, {255,100,80})
-			end
-		end
-	end
-	if _M.tempeffect_def[eff].deactivate then _M.tempeffect_def[eff].deactivate(self, p) end
-end
diff --git a/game/engine/interface/BloodyDeath.lua b/game/engine/interface/BloodyDeath.lua
deleted file mode 100644
index f219accfb6794dfa06ddf7c92d11cb8a4296e8bd..0000000000000000000000000000000000000000
--- a/game/engine/interface/BloodyDeath.lua
+++ /dev/null
@@ -1,51 +0,0 @@
--- 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"
-
---- Interface to add a bloodyDeath() method to actors
--- When this method is called, the floor or walls around the late actor is covered in blood
-module(..., package.seeall, class.make)
-
---- Makes the bloody death happen
--- @param tint true if the color is applied as a tint, false if it changes the actual color
-function _M:bloodyDeath(tint)
-	if not self.has_blood then return end
-	local color = {255,0,100}
-	local done = 3
-	if type(self.has_blood) == "table" then
-		done = self.has_blood.nb or 3
-		color = self.has_blood.color
-	end
-	for i = 1, done do
-		local x, y = rng.range(self.x - 1, self.x + 1), rng.range(self.y - 1, self.y + 1)
-		if game.level.map(x, y, engine.Map.TERRAIN) then
-			-- Get the grid, clone it and alter its color
-			if tint then
-				game.level.map(x, y, engine.Map.TERRAIN, game.level.map(x, y, engine.Map.TERRAIN):clone{
-					tint_r=color[1],tint_g=color[2],tint_b=color[3]
-				})
-			else
-				game.level.map(x, y, engine.Map.TERRAIN, game.level.map(x, y, engine.Map.TERRAIN):clone{
-					color_r=color[1],color_g=color[2],color_b=color[3]
-				})
-			end
-		end
-	end
-end
diff --git a/game/engine/interface/ControlCursorSupport.lua b/game/engine/interface/ControlCursorSupport.lua
deleted file mode 100644
index bc24dadf0fe19cc721add6b94e095923beff47e7..0000000000000000000000000000000000000000
--- a/game/engine/interface/ControlCursorSupport.lua
+++ /dev/null
@@ -1,58 +0,0 @@
--- 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"
-require "engine.Tiles"
-
-local Dialog = require "engine.Dialog"
-
-tiles = engine.Tiles.new(16, 16)
-
---- Handles control Cursor
--- This should work for anything that has a surface and x,y,w,h,font properties.
-module(..., package.seeall, class.make)
-
-function _M:startCursor()	
-	self.cursorPosition = 0
-	self.maximumCurosrPosition = 0
-	self.focused = false
-end
-
-function _M:moveRight(x, add)	
-	if add and self.cursorPosition + x > self.maximumCurosrPosition then self.maximumCurosrPosition = self.cursorPosition + x end
-	if self.cursorPosition + x <= self.maximumCurosrPosition then
-		self.cursorPosition = self.cursorPosition + x
-	end
-end
-
-function _M:moveLeft(x)
-	if self.cursorPosition - x >= 0 then
-		self.cursorPosition = self.cursorPosition - x
-	end
-end
-
--- @param s surface to draw on
-function _M:drawCursor(s, baseX, text)
-	local sw, sh = self.font:size(text:sub(1, self.cursorPosition))	
-	local t = os.time() % 2	
-	if t < 1 and self.focused then
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "cursor.png"), sw + baseX, self.y + self.h - sh - 2)
-		s:merge(tiles:get(nil, 0,0,0, 0,0,0, "cursor.png"), sw + baseX, self.y + self.h - sh - 10)
-	end
-end
\ No newline at end of file
diff --git a/game/engine/interface/GameMusic.lua b/game/engine/interface/GameMusic.lua
deleted file mode 100644
index d309171414efc0a2b3534fd4976590d871db0962..0000000000000000000000000000000000000000
--- a/game/engine/interface/GameMusic.lua
+++ /dev/null
@@ -1,89 +0,0 @@
--- 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"
-
---- Handles music in the game
-module(..., package.seeall, class.make)
-
---- Initializes musics
-function _M:init()
-	self.current_music = nil
-	self.next_music = nil
-	self.loaded_musics = {}
-end
-
-function _M:loaded()
-	self.loaded_musics = self.loaded_musics or {}
-end
-
-function _M:playMusic(name, loop)
-	name = name or self.current_music
-	if not name then return end
-	local m = self.loaded_musics[name]
-	if not m then
-		self.loaded_musics[name] = core.sound.newMusic("/data/music/"..name)
-		m = self.loaded_musics[name]
-	end
-	if not m then return end
-	print("[MUSIC] playing", name, m, " :: current ? ", self.playing_music)
-	if self.current_music == name and self.playing_music then return end
-	if self.current_music then
-		core.sound.musicStop()
-	end
-	m:play(loop or -1)
-	self.current_music = name
-	self.playing_music = true
-end
-
-function _M:stopMusic(fadeout)
-	if not self.loaded_musics[self.current_music] then return end
-	core.sound.musicStop(fadeout)
-	self.current_music = nil
-	self.playing_music = false
-end
-
-function _M:volumeMusic(vol)
-	if vol then
-		self:saveSettings("music", ("music.volume = %q\n"):format(vol))
-	end
-	return core.sound.musicVolume(vol)
-end
-
---- Called by the C core when the current music stops
-function _M:onMusicStop()
-end
-
-function _M:soundSystemStatus(act, init_setup)
-	if type(act) == "boolean" then
-		core.sound.soundSystemStatus(act)
-		if not init_setup then
-			self:saveSettings("sound", ("sound.enabled = %s\n"):format(act and "true" or "false"))
-			if act then
-				self:playMusic()
-			else
-				local o = self.current_music
-				self:stopMusic()
-				self.current_music = o
-			end
-		end
-	else
-		return core.sound.soundSystemStatus()
-	end
-end
diff --git a/game/engine/interface/GameSound.lua b/game/engine/interface/GameSound.lua
deleted file mode 100644
index 7483d13493d218764f2283d72f3c8036e27dac07..0000000000000000000000000000000000000000
--- a/game/engine/interface/GameSound.lua
+++ /dev/null
@@ -1,59 +0,0 @@
--- 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"
-
---- Handles sounds in the game
-module(..., package.seeall, class.make)
-
---- Initializes
-function _M:init()
-	self.loaded_sounds = {}
-end
-
-function _M:loaded()
-	self.loaded_sounds = self.loaded_sounds or {}
-end
-
-function _M:playSound(name)
-	local s = self.loaded_sounds[name]
-	if not s then
-		local def
-		if fs.exists("/data/sound/"..name..".lua") then
-			local f = loadfile("/data/sound/"..name..".lua")
-			setfenv(f, setmetatable({}, {__index=_G}))
-			def = f()
-			print("[SOUND] loading from", "/data/sound/"..name..".lua", ":=:", "/data/sound/"..def.file, ":>")
-			def.file = core.sound.newSound("/data/sound/"..def.file)
-			print("[SOUND] :=>", def.file)
-			if def.volume and def.file then def.file:setVolume(def.volume) end
-		elseif fs.exists("/data/sound/"..name..".wav") then
-			def = {file = core.sound.newSound("/data/sound/"..name..".wav")}
-			print("[SOUND] loading from", "/data/sound/"..name..".wav", ":=:", def.file)
-		else
-			def = {}
-		end
-
-		self.loaded_sounds[name] = def
-		s = self.loaded_sounds[name]
-	end
-	if not s or not s.file then return end
-	local chan = s.file:play(s.loop, s.timed)
-	if chan and s.fadeout then core.sound.channelFadeOut(chan, s.fadeout) end
-end
diff --git a/game/engine/interface/GameTargeting.lua b/game/engine/interface/GameTargeting.lua
deleted file mode 100644
index c96809dca607608d88151d0c73ae63fd15b912f6..0000000000000000000000000000000000000000
--- a/game/engine/interface/GameTargeting.lua
+++ /dev/null
@@ -1,225 +0,0 @@
--- 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"
-require "engine.KeyBind"
-local Dialog = require "engine.Dialog"
-local Map = require "engine.Map"
-local Target = require "engine.Target"
-
---- Handles default targeting interface & display
-module(..., package.seeall, class.make)
-
---- Initializes targeting
-function _M:init()
-	self.target = Target.new(Map, self.player)
-	self.target.target.entity = self.player
-	self.old_tmx, self.old_tmy = 0, 0
-	self.target_style = "lock"
-end
-
---- Maintain the current target each tick
--- Make sure the target still exists
-function _M:targetOnTick()
-	if self.target.target.entity and not self.level:hasEntity(self.target.target.entity) then self.target.target.entity = false end
-end
-
---- Display the tooltip, if any
-function _M:targetDisplayTooltip(dx, dy)
-	-- Tooltip is displayed over all else
-	if self.level and self.level.map and self.level.map.finished then
-		-- Display a tooltip if available
-		if self.tooltip_x then
-			local tmx, tmy = self.level.map:getMouseTile(self.tooltip_x , self.tooltip_y)
-			self.tooltip:displayAtMap(tmx, tmy, dx, dy)
-		end
-
-		-- Move target around
-		if self.old_tmx ~= tmx or self.old_tmy ~= tmy then
-			self.target.target.x, self.target.target.y = tmx, tmy
-		end
-		self.old_tmx, self.old_tmy = tmx, tmy
-	end
-end
-
---- Enter/leave targeting mode
--- This is the "meat" of this interface, do not expect to understand it easily, it mixes some nasty stuff
--- This require the Game to have both a "key" field (this is the default) and a "normal_key" field<br/>
--- It will switch over to a special keyhandler and then restore the "normal_key" one
-function _M:targetMode(v, msg, co, typ)
-	local old = self.target_mode
-	self.target_mode = v
-
-	if not v then
-		Map:setViewerFaction(self.always_target and self.player.faction or nil)
-		if msg then self.log(type(msg) == "string" and msg or "Tactical display disabled. Press shift+'t' to enable.") end
-		self.level.map.changed = true
-		self.target:setActive(false)
-
-		if tostring(old) == "exclusive" then
-			local fct = function(ok)
-				if not ok then
-					self.target.target.entity = nil
-					self.target.target.x = nil
-					self.target.target.y = nil
-				end
-
-				self.key = self.normal_key
-				self.key:setCurrent()
-				if self.target_co then
-					local co = self.target_co
-					self.target_co = nil
-					local ok, err = coroutine.resume(co, self.target.target.x, self.target.target.y, self.target.target.entity)
-					if not ok and err then print(debug.traceback(co)) error(err) end
-				end
-			end
-			if self.target_warning and self.target.target.x == self.player.x and self.target.target.y == self.player.y then
-				Dialog:yesnoPopup("Target yourself?", "Are you sure you want to target yourself?", fct)
-			else
-				fct(true)
-			end
-		end
-	else
-		Map:setViewerFaction(self.player.faction)
-		if msg then self.log(type(msg) == "string" and msg or "Tactical display enabled. Press shift+'t' to disable.") end
-		self.level.map.changed = true
-		self.target:setActive(true, typ)
-		self.target_style = "lock"
-		self.target_warning = true
-
-		-- Exclusive mode means we disable the current key handler and use a specific one
-		-- that only allows targetting and resumes talent coroutine when done
-		if tostring(v) == "exclusive" then
-			self.target_co = co
-			self.key = self.targetmode_key
-			self.key:setCurrent()
-
-			if self.target.target.entity and self.level.map.seens(self.target.target.entity.x, self.target.target.entity.y) and self.player ~= self.target.target.entity then
-			else
-				local filter = nil
-				if type(typ) == "table" and typ.first_target and typ.first_target == "friend" then
-					filter = function(a) return self.player:reactionToward(a) >= 0 end
-				else
-					filter = function(a) return self.player:reactionToward(a) < 0 end
-				end
-				self.target:scan(5, nil, self.player.x, self.player.y, filter)
-			end
-		end
-		if self.target.target.x then
-			self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y)
-		end
-	end
-end
-
---- This setups the default keybindings for targeting
-function _M:targetSetupKey()
-	self.targetmode_key = engine.KeyBind.new()
-	self.targetmode_key:addCommands{ _SPACE=function() self:targetMode(false, false) self.tooltip_x, self.tooltip_y = nil, nil end, }
-	self.targetmode_key:addBinds
-	{
-		TACTICAL_DISPLAY = function()
-			self:targetMode(false, false)
-			self.tooltip_x, self.tooltip_y = nil, nil
-		end,
-		ACCEPT = function()
-			self:targetMode(false, false)
-			self.tooltip_x, self.tooltip_y = nil, nil
-		end,
-		EXIT = function()
-			self.target.target.entity = nil
-			self.target.target.x = nil
-			self.target.target.y = nil
-			self:targetMode(false, false)
-			self.tooltip_x, self.tooltip_y = nil, nil
-		end,
-		-- Targeting movement
-		RUN_LEFT = function() self.target:freemove(4) self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		RUN_RIGHT = function() self.target:freemove(6) self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		RUN_UP = function() self.target:freemove(8) self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		RUN_DOWN = function() self.target:freemove(2) self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		RUN_LEFT_DOWN = function() self.target:freemove(1) self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		RUN_RIGHT_DOWN = function() self.target:freemove(3) self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		RUN_LEFT_UP = function() self.target:freemove(7) self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		RUN_RIGHT_UP = function() self.target:freemove(9) self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-
-		MOVE_LEFT = function() if self.target_style == "lock" then self.target:scan(4) else self.target:freemove(4) end self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		MOVE_RIGHT = function() if self.target_style == "lock" then self.target:scan(6) else self.target:freemove(6) end self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		MOVE_UP = function() if self.target_style == "lock" then self.target:scan(8) else self.target:freemove(8) end self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		MOVE_DOWN = function() if self.target_style == "lock" then self.target:scan(2) else self.target:freemove(2) end self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		MOVE_LEFT_DOWN = function() if self.target_style == "lock" then self.target:scan(1) else self.target:freemove(1) end self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		MOVE_RIGHT_DOWN = function() if self.target_style == "lock" then self.target:scan(3) else self.target:freemove(3) end self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		MOVE_LEFT_UP = function() if self.target_style == "lock" then self.target:scan(7) else self.target:freemove(7) end self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-		MOVE_RIGHT_UP = function() if self.target_style == "lock" then self.target:scan(9) else self.target:freemove(9) end self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y) end,
-	}
-end
-
---- Handle mouse event for targeting
--- @return true if the event was handled
-function _M:targetMouse(button, mx, my, xrel, yrel)
-	-- Move tooltip
-	self.tooltip_x, self.tooltip_y = mx, my
-	local tmx, tmy = self.level.map:getMouseTile(mx, my)
-
-	if self.key == self.targetmode_key then
-		-- Target with mouse
-		if button == "none" and xrel and yrel then
-			self.target:setSpot(tmx, tmy)
-		-- Cancel target
-		elseif button ~= "left" and not xrel and not yrel then
-			self:targetMode(false, false)
-			self.tooltip_x, self.tooltip_y = nil, nil
-		-- Accept target
-		elseif not xrel and not yrel then
-			self.target.target.entity = nil
-			self.target.target.x = nil
-			self.target.target.y = nil
-			self:targetMode(false, false)
-			self.tooltip_x, self.tooltip_y = nil, nil
-		end
-		return true
-	end
-end
-
---- Player requests a target
--- This method should be called by your Player:getTarget() method, it will handle everything
--- @param typ the targeting parameters
-function _M:targetGetForPlayer(typ)
-	if self.target.forced then return unpack(self.target.forced) end
-	if coroutine.running() then
-		local msg
-		if type(typ) == "string" then msg, typ = typ, nil
-		elseif type(typ) == "table" then
-			if typ.default_target then self.target.target.entity = typ.default_target end
-			msg = typ.msg
-		end
-		self:targetMode("exclusive", msg, coroutine.running(), typ)
-		if typ.nolock then self.target_style = "free" end
-		if typ.nowarning then self.target_warning = false end
-		return coroutine.yield()
-	end
-	return self.target.target.x, self.target.target.y, self.target.target.entity
-end
-
---- Player wants to set its target
--- This method should be called by your Player:setTarget() method, it will handle everything
-function _M:targetSetForPlayer(target)
-	self.target.target.entity = target
-	self.target.target.x = target.x
-	self.target.target.y = target.y
-end
diff --git a/game/engine/interface/ObjectActivable.lua b/game/engine/interface/ObjectActivable.lua
deleted file mode 100644
index 729e4de18bebe1d9ae0878df1e6977fce13f8107..0000000000000000000000000000000000000000
--- a/game/engine/interface/ObjectActivable.lua
+++ /dev/null
@@ -1,91 +0,0 @@
--- 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"
-
---- Handles activable objects, much more simple than actor's resource
--- It can define simple activations, complex ones that use power and it can also activate talent (ActorTalents interface must also be used on the Object class in this case)
-module(..., package.seeall, class.make)
-
-function _M:init(t)
-	if t.max_power then
-		self.power = t.max_power
-		self.max_power = t.max_power
-		self.power_regen = t.power_regen or 0
-	end
-end
-
---- Regen resources, shout be called in your actor's act() method
-function _M:regenPower()
-	if self.power_regen then self.power = util.bound(self.power + self.power_regen, 0, self.max_power) end
-end
-
-function _M:canUseObject()
-	if self.use_simple or self.use_power or self.use_talent then
-		return true
-	end
-end
-
-function _M:getUseDesc()
-	if self.use_power then
-		return ("It can be used to %s, costing %d power out of %d/%d."):format(self.use_power.name, self.use_power.power, self.power, self.max_power)
-	elseif self.use_simple then
-		return ("It can be used to %s."):format(self.use_simple.name)
-	elseif self.use_talent then
-		if not self.use_talent.power then                                                                        print(self:getTalentFromId(self.use_talent.id),self.use_talent.id)
-			return ("It can be used to activate talent: %s (level %d)."):format(self:getTalentFromId(self.use_talent.id).name, self.use_talent.level)
-		else
-			return ("It can be used to activate talent: %s (level %d), costing %d power out of %d/%d."):format(self:getTalentFromId(self.use_talent.id).name, self.use_talent.level, self.use_talent.power, self.power, self.max_power)
-		end
-	end
-end
-
-function _M:useObject(who)
-	if self.use_power then
-		if self.power >= self.use_power.power then
-			local co = coroutine.create(function() return self.use_power.use(self, who) end)
-			local ok, ret, no_power = coroutine.resume(co)
-			if not ok and ret then print(debug.traceback(co)) error(ret) end
-			if not no_power then self.power = self.power - self.use_power.power end
-			return ret
-		else
-			if self.power_regen and self.power_regen ~= 0 then
-				game.logPlayer(who, "%s is still recharging.", self:getName{no_count=true})
-			else
-				game.logPlayer(who, "%s can not be used anymore.", self:getName{no_count=true})
-			end
-		end
-	elseif self.use_simple then
-		local co = coroutine.create(function() return self.use_simple.use(self, who) end)
-		local ok, ret = coroutine.resume(co)
-		if not ok and ret then print(debug.traceback(co)) error(ret) end
-		return ret
-	elseif self.use_talent then
-		if not self.use_talent.power or self.power >= self.use_talent.power then
-			self.power = self.power - self.use_talent.power
-			return self:useTalent(self.use_talent.id, who, self.use_talent.level)
-		else
-			if self.power_regen and self.power_regen ~= 0 then
-				game.logPlayer(who, "%s is still recharging.", self:getName{no_count=true})
-			else
-				game.logPlayer(who, "%s can not be used anymore.", self:getName{no_count=true})
-			end
-		end
-	end
-end
diff --git a/game/engine/interface/ObjectIdentify.lua b/game/engine/interface/ObjectIdentify.lua
deleted file mode 100644
index 82b0f31d6b456facb270633301b2edfd4d68ff80..0000000000000000000000000000000000000000
--- a/game/engine/interface/ObjectIdentify.lua
+++ /dev/null
@@ -1,77 +0,0 @@
--- 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"
-
---- Handles unidentified objects, and their identification
-module(..., package.seeall, class.make)
-
-function _M:init(t)
-	if t.identified ~= nil then
-		self.identified = t.identified
-	else
-		self.identified = false
-	end
-end
-
---- Defines the default ided status
-function _M:resolveIdentify()
-	if not self.unided_name then
-		self.unided_name = self.name
-	end
-end
-
---- Can this object be identified at all ?
--- Defaults to true, you can overload it
-function _M:canIdentify()
-	return true
-end
-
---- Is the object identified ?
-function _M:isIdentified()
-	-- Auto id by type ?
-	if game.object_known_types and game.object_known_types[self.type] and game.object_known_types[self.type][self.subtype] and game.object_known_types[self.type][self.subtype][self.name] then
-		self.identified = game.object_known_types[self.type][self.subtype][self.name]
-	end
-
-	if self.auto_id then
-		self.identified = self.auto_id
-	end
-
-	return self.identified
-end
-
---- Identify the object
-function _M:identify(id)
-	print("[Identify]", self.name, true)
-	self:forAllStack(function(so)
-		so.identified = id
-		if so.id_by_type then
-			game.object_known_types = game.object_known_types or {}
-			game.object_known_types[so.type] = game.object_known_types[so.type] or {}
-			game.object_known_types[so.type][so.subtype] = game.object_known_types[so.type][so.subtype] or {}
-			game.object_known_types[so.type][so.subtype][so.name] = id
-		end
-	end)
-end
-
---- Get the unided name
-function _M:getUnidentifiedName()
-	return self.unided_name
-end
diff --git a/game/engine/interface/PlayerHotkeys.lua b/game/engine/interface/PlayerHotkeys.lua
deleted file mode 100644
index f7ce06bfb15ac0fa773745cf4c79df4415f1728f..0000000000000000000000000000000000000000
--- a/game/engine/interface/PlayerHotkeys.lua
+++ /dev/null
@@ -1,81 +0,0 @@
--- 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 Dialog = require "engine.Dialog"
-
---- Handles player hotkey interface
--- This provides methods to bind and manage hotkeys as well as using them<br/>
--- This interface is designed to work with the engine.HotkeysDisplay class to display current hotkeys to the player
-module(..., package.seeall, class.make)
-
-function _M:init(t)
-	self.hotkey = {}
-	self.hotkey_page = 1
-end
-
---- Uses an hotkeyed talent
--- This requires the ActorTalents interface to use talents and a method player:playerUseItem(o, item, inven) to use inventory objects
-function _M:activateHotkey(id)
-	if self.hotkey[id] then
-		if self.hotkey[id][1] == "talent" then
-			self:useTalent(self.hotkey[id][2])
-		elseif self.hotkey[id][1] == "inventory" then
-			local o, item, inven = self:findInAllInventories(self.hotkey[id][2])
-			if not o then
-				Dialog:simplePopup("Item not found", "You do not have any "..self.hotkey[id][2]..".")
-			else
-				self:playerUseItem(o, item, inven)
-			end
-		end
-	else
-		Dialog:simplePopup("Hotkey not defined", "You may define a hotkey by pressing 'm' and following the inscructions there.")
-	end
-end
-
---- Switch to previous hotkey page
-function _M:prevHotkeyPage()
-	self.hotkey_page = util.boundWrap(self.hotkey_page - 1, 1, 3)
-	self.changed = true
-end
---- Switch to next hotkey page
-function _M:nextHotkeyPage()
-	self.hotkey_page = util.boundWrap(self.hotkey_page + 1, 1, 3)
-	self.changed = true
-end
---- Switch to hotkey page
-function _M:setHotkeyPage(v)
-	self.hotkey_page = v
-	self.changed = true
-end
-
--- Autoadd talents to hotkeys
-function _M:hotkeyAutoTalents()
-	for tid, _ in pairs(self.talents) do
-		local t = self:getTalentFromId(tid)
-		if t.mode == "activated" or t.mode == "sustained" then
-			for i = 1, 36 do
-				if not self.hotkey[i] then
-					self.hotkey[i] = {"talent", tid}
-					break
-				end
-			end
-		end
-	end
-end
diff --git a/game/engine/interface/PlayerMouse.lua b/game/engine/interface/PlayerMouse.lua
deleted file mode 100644
index 330477442afc1ea6562f5d4514fef27d409dc0c9..0000000000000000000000000000000000000000
--- a/game/engine/interface/PlayerMouse.lua
+++ /dev/null
@@ -1,133 +0,0 @@
--- 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 Astar = require"engine.Astar"
-local DirectPath = require"engine.DirectPath"
-
---- Handles player default mouse actions
--- Defines some methods to help use the mouse in an uniform way in all modules
-module(..., package.seeall, class.make)
-
---- Runs to the clicked mouse spot
--- if no monsters in sight it will try to make an A* path, if it fails it will do a direct path<br/>
--- if there are monsters in sight it will move one stop in the direct path direction<br/>
--- this method requires to use PlayerRun interface
--- @param tmx the coords clicked
--- @param tmy the coords clicked
--- @param spotHostiles a function taking only the player as a parameter that must return true if hostiles are in sight
-function _M:mouseMove(tmx, tmy, spotHostiles)
-	tmx = util.bound(tmx, 0, game.level.map.w - 1)
-	tmy = util.bound(tmy, 0, game.level.map.h - 1)
-
-	if config.settings.tome.cheat and core.key.modState("ctrl") then
-		game.log("[CHEAT] teleport to %dx%d", tmx, tmy)
-		self:move(tmx, tmy, true)
-	else
-		-- Just spend a turn
-		if self.x == tmx and self.y == ny then self:move(self.x, self.y) end
-
-		-- If hostiles, attack!
-		if (spotHostiles and spotHostiles(self)) or math.floor(core.fov.distance(self.x, self.y, tmx, tmy)) == 1 then
-			local l = line.new(self.x, self.y, tmx, tmy)
-			local nx, ny = l()
-			self:move(nx or self.x, ny or self.y)
-			return
-		end
-
-		local a = Astar.new(game.level.map, self)
-		local path = a:calc(self.x, self.y, tmx, tmy, true)
-		-- No Astar path ? jsut be dumb and try direct line
-		if not path then
-			local d = DirectPath.new(game.level.map, self)
-			path = d:calc(self.x, self.y, tmx, tmy, true)
-		end
-
-		if path then
-			-- Should we just try to move in the direction, aka: attack!
-			if path[1] and game.level.map:checkAllEntities(path[1].x, path[1].y, "block_move", self) then self:move(path[1].x, path[1].y) return end
-
-			 -- Insert the player coords, running needs to find the player
-			table.insert(path, 1, {x=self.x, y=self.y})
-
-			-- Move along the projected A* path
-			self:runFollow(path)
-		end
-	end
-end
-
-local moving_around = false
-local derivx, derivy = 0, 0
-
---- Handles mouse scrolling the map
--- @param map the Map to scroll
--- @param xrel the x movement velocity, gotten from a mouse event
--- @param yrel the y movement velocity, gotten from a mouse event
-function _M:mouseScrollMap(map, xrel, yrel)
-	derivx = derivx + xrel
-	derivy = derivy + yrel
-	map.changed = true
-	if derivx >= map.tile_w then
-		map.mx = map.mx - 1
-		derivx = derivx - map.tile_w
-	elseif derivx <= -map.tile_w then
-		map.mx = map.mx + 1
-		derivx = derivx + map.tile_w
-	end
-	if derivy >= map.tile_h then
-		map.my = map.my - 1
-		derivy = derivy - map.tile_h
-	elseif derivy <= -map.tile_h then
-		map.my = map.my + 1
-		derivy = derivy + map.tile_h
-	end
-	map._map:setScroll(map.mx, map.my)
-end
-
---- Handles global mouse event
--- This will handle events like this:<ul>
--- <li>Left click: player mouse movement</li>
--- <li>Shift + left click: map scroll</li>
--- <li>Any other click: pass on the click as a key event, to allow actiosnto be bound to the mouse</li>
--- </ul>
--- @param key the Key object to which to pass the event if not treated, this should be your game default key handler probably
--- @param allow_move true if this will allow player movement (you should use it to check that you are not in targetting mode)
-function _M:mouseHandleDefault(key, allow_move, button, mx, my, xrel, yrel)
-	local tmx, tmy = game.level.map:getMouseTile(mx, my)
-
-	-- Move
-	if button == "left" and not core.key.modState("shift") and not moving_around and not xrel and not yrel then
-		if allow_move then self:mouseMove(tmx, tmy) end
-
-	-- Move map around
-	elseif button == "left" and xrel and yrel and core.key.modState("shift") then
-		self:mouseScrollMap(game.level.map, xrel, yrel)
-		moving_around = true
-	-- Zoom map
---	elseif button == "wheelup" then
---		game.level.map:setZoom(0.1, tmx, tmy)
---	elseif button == "wheeldown" then
---		game.level.map:setZoom(-0.1, tmx, tmy)
-	-- Pass any other buttons to the keybinder
-	elseif button ~= "none" and not xrel and not yrel then
-		key:receiveKey(button, core.key.modState("ctrl") and true or false, core.key.modState("shift") and true or false, core.key.modState("alt") and true or false, core.key.modState("meta") and true or false, nil, false, true)
-	end
-
-	if not xrel and not yrel then moving_around = false end
-end
diff --git a/game/engine/interface/PlayerRest.lua b/game/engine/interface/PlayerRest.lua
deleted file mode 100644
index e4edbf773b0399c7b9fad57053428657a807537b..0000000000000000000000000000000000000000
--- a/game/engine/interface/PlayerRest.lua
+++ /dev/null
@@ -1,87 +0,0 @@
--- 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 Dialog = require "engine.Dialog"
-
---- Handles player resting
-module(..., package.seeall, class.make)
-
---- Initializes resting
-function _M:restInit(turns, what, past, on_end)
-	what = what or "resting"
-	past = past or "rested"
-	self.resting = {
-		rest_turns = turns,
-		past = past,
-		on_end = on_end,
-		cnt = 1,
-		dialog = Dialog:simplePopup(what:capitalize().."...", "You are "..what..", press any key to stop.", function()
-			self:restStop()
-		end),
-	}
-	self.resting.dialog.__showup = nil
-	self:useEnergy()
-	game.log(what:capitalize().." starts...")
-end
-
---- Rest a turn
--- For a turn based game you want in you player's act() something like that:<br/>
--- <pre>
--- if not self:restStep() then game.paused = true end
--- </pre>
--- @return true if we can continue to rest, false otherwise
-function _M:restStep()
-	if not self.resting then return false end
-
-	local ret, msg = self:restCheck()
-	if ret and self.resting and self.resting.rest_turns and self.resting.cnt > self.resting.rest_turns then ret = false msg = nil end
-	if not ret then
-		self:restStop(msg)
-		return false
-	else
-		self:useEnergy()
-		self.resting.cnt = self.resting.cnt + 1
-		return true
-	end
-end
-
---- Can we continue resting ?
--- Rewrite this method to check for mana, life, whatever. By default we alawys return false so resting will never work
--- @return true if we can continue to rest, false otherwise
-function _M:restCheck()
-	return false, "player:restCheck() method not defined"
-end
-
---- Stops resting
-function _M:restStop(msg)
-	if not self.resting then return false end
-
-	game:unregisterDialog(self.resting.dialog)
-
-	if msg then
-		game.log(self.resting.past:capitalize().." for %d turns (stop reason: %s).", self.resting.cnt, msg)
-	else
-		game.log(self.resting.past:capitalize().." for %d turns.", self.resting.cnt)
-	end
-
-	if self.resting.on_end then self.resting.on_end(self.resting.cnt, self.resting.rest_turns) end
-	self.resting = nil
-	return true
-end
diff --git a/game/engine/interface/PlayerRun.lua b/game/engine/interface/PlayerRun.lua
deleted file mode 100644
index e2fa83b4256d7f309d9601729583836b72cc5d5d..0000000000000000000000000000000000000000
--- a/game/engine/interface/PlayerRun.lua
+++ /dev/null
@@ -1,239 +0,0 @@
--- 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 Dialog = require "engine.Dialog"
-
---- Handles player running
--- This should work for running inside tunnel, alongside walls, in open spaces.<br/>
-module(..., package.seeall, class.make)
-
-local sides =
-{
-	[1] = {left=2, right=4},
-	[2] = {left=3, right=1},
-	[3] = {left=6, right=2},
-	[4] = {left=1, right=7},
-	[6] = {left=9, right=3},
-	[7] = {left=4, right=8},
-	[8] = {left=7, right=9},
-	[9] = {left=8, right=6},
-}
-
-local turn =
-{
-	[1] = {left=3, right=7},
-	[2] = {left=6, right=4},
-	[3] = {left=9, right=1},
-	[4] = {left=2, right=8},
-	[6] = {left=8, right=2},
-	[7] = {left=1, right=9},
-	[8] = {left=4, right=6},
-	[9] = {left=7, right=3},
-}
-
-local function checkDir(a, dir, dist)
-	dist = dist or 1
-	local dx, dy = dir_to_coord[dir][1], dir_to_coord[dir][2]
-	local x, y = a.x + dx * dist, a.y + dy * dist
-	return game.level.map:checkAllEntities(x, y, "block_move", a) and true or false
-end
-local function isEdge(a, dir, dist)
-	dist = dist or 1
-	local dx, dy = dir_to_coord[dir][1], dir_to_coord[dir][2]
-	local x, y = a.x + dx * dist, a.y + dy * dist
-	return not game.level.map:isBound(x, y) and true or false
-end
-
---- Initializes running
--- We check the direction sides to know if we are in a tunnel, along a wall or in open space.
-function _M:runInit(dir)
-	local block_left, block_right = false, false
-
-	-- Check sides
-	if checkDir(self, sides[dir].left) then block_left = true end
-	if checkDir(self, sides[dir].right) then block_right = true end
-
-	self.running = {
-		dir = dir,
-		block_left = block_left,
-		block_right = block_right,
-		cnt = 1,
-		dialog = Dialog:simplePopup("Running...", "You are running, press any key to stop.", function()
-			self:runStop()
-		end),
-	}
-	self.running.dialog.__showup = nil
-
-	self:runStep()
-end
-
---- Initializes running to a specific position using the given path
--- This does not use the normal running algorithm
-function _M:runFollow(path)
-	local found = false
-	local runpath = {}
-
-	-- Find ourself along the path
-	for i, c in ipairs(path) do
-		if found then runpath[#runpath+1] = c
-		elseif c.x == self.x and c.y == self.y then found = true end
-	end
-
-	if #runpath == 0 then
-		game.logPlayer(self, "Invalid running path.")
-		return
-	end
-
-	self.running = {
-		path = runpath,
-		cnt = 1,
-		dialog = Dialog:simplePopup("Running...", "You are running, press any key to stop.", function()
-			self:runStop()
-		end),
-	}
-	self.running.dialog.__showup = nil
-
-	self:runStep()
-end
-
---- Run a turn
--- For a turn based game you want in you player's act() something like that:<br/>
--- <pre>
--- if not self:runStep() then game.paused = true end
--- </pre><br/>
--- This will move the actor using the :move() method, this SHOULD have been redefined by the module
--- to use energy, otherwise running will be free.
--- @return true if we can continue to run, false otherwise
-function _M:runStep()
-	if not self.running then return false end
-
-	local ret, msg = self:runCheck()
-	if not ret and self.running.cnt > 1 then
-		self:runStop(msg)
-		return false
-	else
-		local oldx, oldy = self.x, self.y
-		if self.running.path then
-			if not self.running.path[self.running.cnt] then self:runStop()
-			else self:move(self.running.path[self.running.cnt].x, self.running.path[self.running.cnt].y) end
-		else
-			if isEdge(self, self.running.dir) then self:runStop()
-			else self:moveDir(self.running.dir) end
-		end
-		self:runMoved()
-
-		-- Did not move ? no use in running
-		if self.x == oldx and self.y == oldy then self:runStop() end
-
-		if not self.running then return false end
-		self.running.cnt = self.running.cnt + 1
-
-		if self.running.newdir then
-			self.running.dir = self.running.newdir
-			self.running.newdir = nil
-		end
-		if self.running.ignore_left then
-			self.running.ignore_left = self.running.ignore_left - 1
-			if self.running.ignore_left <= 0 then self.running.ignore_left = nil end
-		end
-		if self.running.ignore_right then
-			self.running.ignore_right = self.running.ignore_right - 1
-			if self.running.ignore_right <= 0 then self.running.ignore_right = nil end
-		end
-
-		return true
-	end
-end
-
---- Can we continue running ?
--- Rewrite this method to hostiles, interresting terrain, whatever.
--- This method should be called by its submethod, it tries to detect changes in the terrain.<br/>
--- It will also try to follow tunnels when they simply change direction.
--- @return true if we can continue to run, false otherwise
-function _M:runCheck()
-	if not self.running.path then
-		-- Do we change run direction ? We can only choose to change for left or right, never backwards.
-		-- We must also be in a tunnel (both sides blocked)
-		if self.running.block_left and self.running.block_right then
-			-- Turn left
-			if not checkDir(self, self.running.dir) and checkDir(self, self.running.dir, 2) and not checkDir(self, sides[self.running.dir].left) and checkDir(self, sides[self.running.dir].right) then
-				self.running.newdir = turn[self.running.dir].left
-				self.running.ignore_left = 2
-				return true
-			end
-
-			-- Turn right
-			if not checkDir(self, self.running.dir) and checkDir(self, self.running.dir, 2) and checkDir(self, sides[self.running.dir].left) and not checkDir(self, sides[self.running.dir].right) then
-				self.running.newdir = turn[self.running.dir].right
-				self.running.ignore_right = 2
-				return true
-			end
-		end
-
-		if not self.running.ignore_left and self.running.block_left ~= checkDir(self, sides[self.running.dir].left) then return false, "terrain change on left side" end
-		if not self.running.ignore_right and self.running.block_right ~= checkDir(self, sides[self.running.dir].right) then return false, "terrain change on right side" end
-		if checkDir(self, self.running.dir) then return false, "terrain ahead blocks" end
-	end
-
-	return true
-end
-
---- Stops running
-function _M:runStop(msg)
-	if not self.running then return false end
-
-	game:unregisterDialog(self.running.dialog)
-
-	if msg then
-		game.log("Ran for %d turns (stop reason: %s).", self.running.cnt, msg)
-	end
-
-	self.running = nil
-	return true
-end
-
---- Scan the run direction and sides with the given function
-function _M:runScan(fct)
-	fct(self.x, self.y)
-	if not self.running.path then
-		-- Ahead
-		local dx, dy = dir_to_coord[self.running.dir][1], dir_to_coord[self.running.dir][2]
-		local x, y = self.x + dx, self.y + dy
-		fct(x, y)
-
-		-- Ahead left
-		local dx, dy = dir_to_coord[sides[self.running.dir].left][1], dir_to_coord[sides[self.running.dir].left][2]
-		local x, y = self.x + dx, self.y + dy
-		fct(x, y)
-
-		-- Ahead right
-		local dx, dy = dir_to_coord[sides[self.running.dir].right][1], dir_to_coord[sides[self.running.dir].right][2]
-		local x, y = self.x + dx, self.y + dy
-		fct(x, y)
-	elseif self.running.path[self.running.cnt] then
-		-- Ahead
-		local x, y = self.running.path[self.running.cnt].x, self.running.path[self.running.cnt].y
-		fct(x, y)
-	end
-end
-
---- Called after running a step
-function _M:runMoved()
-end
diff --git a/game/engine/interface/PlayerSlide.lua b/game/engine/interface/PlayerSlide.lua
deleted file mode 100644
index 7f5b4a1925c68518d79c74112f4409984632b8bd..0000000000000000000000000000000000000000
--- a/game/engine/interface/PlayerSlide.lua
+++ /dev/null
@@ -1,43 +0,0 @@
--- 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"
-
---- Makes the player "slide" along walls when possible
--- Simply call x, y = self:tryPlayerSlide(x, y, force) in your player's move() method
-module(..., package.seeall, class.make)
-
-function _M:tryPlayerSlide(x, y, force)
-	-- Try to slide along walls if possible
-	if game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move", self, false) and not force then
-		local dir = util.getDir(x, y, self.x, self.y)
-		local ldir, rdir = dir_sides[dir].left, dir_sides[dir].right
-		local lx, ly = util.coordAddDir(self.x, self.y, ldir)
-		local rx, ry = util.coordAddDir(self.x, self.y, rdir)
-		-- Slide left
-		if not game.level.map:checkEntity(lx, ly, Map.TERRAIN, "block_move", self, false) and game.level.map:checkEntity(rx, ry, Map.TERRAIN, "block_move", self, false) then
-			x, y = lx, ly
-		-- Slide right
-		elseif game.level.map:checkEntity(lx, ly, Map.TERRAIN, "block_move", self, false) and not game.level.map:checkEntity(rx, ry, Map.TERRAIN, "block_move", self, false) then
-			x, y = rx, ry
-		end
-	end
-	return x, y
-end
diff --git a/game/engine/interface/WorldAchievements.lua b/game/engine/interface/WorldAchievements.lua
deleted file mode 100644
index 4e8933528f6e196bb0058f7dd0ecc76eb83b9fcf..0000000000000000000000000000000000000000
--- a/game/engine/interface/WorldAchievements.lua
+++ /dev/null
@@ -1,135 +0,0 @@
--- 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 Dialog = require "engine.Dialog"
-
---- Handles archievements in a world
-module(..., package.seeall, class.make)
-
-_M.achiev_defs = {}
-
---- Loads achievements
-function _M:loadDefinition(dir)
-	for i, file in ipairs(fs.list(dir)) do
-		if file:find("%.lua$") then
-			local f, err = loadfile(dir.."/"..file)
-			if not f and err then error(err) end
-			setfenv(f, setmetatable({
-				newAchievement = function(t) self:newAchievement(t) end,
-			}, {__index=_G}))
-			f()
-		end
-	end
-end
-
---- Make a new achivement with a name and desc
-function _M:newAchievement(t)
-	assert(t.name, "no achivement name")
-	assert(t.desc, "no achivement desc")
-
-	t.mode = t.mode or "none"
-	t.id = t.id or t.name
-	t.id = t.id:upper():gsub("[ ]", "_")
-	t.order = #self.achiev_defs+1
-
-	self.achiev_defs[t.id] = t
-	self.achiev_defs[#self.achiev_defs+1] = t
-	print("[ACHIEVEMENT] defined", t.order, t.id)
-end
-
-function _M:loadAchievements()
-	self.achieved = {}
-	self.playerachieved = {}
-
-	for k, e in pairs(profile.mod) do
-		if k:find('^achievement%.') then
-			local id = k:gsub('^achievement%.', '')
-			if self.achiev_defs[id] then
-				self.achieved[id] = e
-			end
-		end
-	end
-end
-
-function _M:getAchievementFromId(id)
-	return self.achiev_defs[id]
-end
-
-
---- Gain Personal achievement for player only
--- @param silent suppress the message to the player
--- @param id the achivement to gain
--- @param src who did it
-function _M:gainPersonalAchievement(silent, id, src, ...)
-	local a = self.achiev_defs[id]
-	if src.resolveSource then src = src:resolveSource() end
-
-	src.achievements = src.achievements or {}
-	if src.achievements[id] then return end
-
-	src.achievements[id] = {turn=game.turn, when=os.date("%Y-%m-%d %H:%M:%S")}
-	if not silent then
-		game.log("#LIGHT_GREEN#Personal New Achievement: %s!", a.name)
-		Dialog:simplePopup("Personal New Achievement: #LIGHT_GREEN#"..a.name, a.desc)
-	end
-end
-
---- Gain an achievement
--- @param id the achivement to gain
--- @param src who did it
-function _M:gainAchievement(id, src, ...)
-	local a = self.achiev_defs[id]
-	if not a then error("Unknown achievement "..id) return end
-
-	if self.achieved[id] and src.achievements and src.achievements[id] then return end
-
-	if a.can_gain then
-		local data = nil
-		if a.mode == "world" then
-			self.achievement_data = self.achievement_data or {}
-			self.achievement_data[id] = self.achievement_data[id] or {}
-			data = self.achievement_data[id]
-		elseif a.mode == "game" then
-			game.achievement_data = game.achievement_data or {}
-			game.achievement_data[id] = game.achievement_data[id] or {}
-			data = game.achievement_data[id]
-		elseif a.mode == "player" then
-			src.achievement_data = src.achievement_data or {}
-			src.achievement_data[id] = src.achievement_data[id] or {}
-			data = src.achievement_data[id]
-		end
-		if not a.can_gain(data, src, ...) then return end
-	end
-
-	if self.achieved[id] then self:gainPersonalAchievement(false, id, src, ...) return end
-	self:gainPersonalAchievement(true, id, src, ...)
-
-	self.achieved[id] = {turn=game.turn, who=self:achievementWho(src), when=os.date("%Y-%m-%d %H:%M:%S")}
-	profile:saveModuleProfile("achievement."..id, self.achieved[id])
-	game.log("#LIGHT_GREEN#New Achievement: %s!", a.name)
-	Dialog:simplePopup("New Achievement: #LIGHT_GREEN#"..a.name, a.desc)
-end
-
---- Format an achievement source
--- By default just uses the actor's name, you can overload it to do more
--- @param src the actor who did it
-function _M:achievementWho(src)
-	return src.name
-end
diff --git a/game/engine/pre-init.lua b/game/engine/pre-init.lua
deleted file mode 100644
index 541ce8625e33c3584eb82a663476afd216912d4a..0000000000000000000000000000000000000000
--- a/game/engine/pre-init.lua
+++ /dev/null
@@ -1,28 +0,0 @@
--- 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
-
--- Turn on LuaJIT if available
-pcall(require, "jit")
-if jit then
-	jit.on()
-	require("jit.opt").start(2)
-	print("LuaVM:", jit.version, jit.arch)
-else
-	print("LuaVM:", _VERSION)
-end
diff --git a/game/engine/resolvers.lua b/game/engine/resolvers.lua
deleted file mode 100644
index c4fef90a3e85b09d774cf5017d339388a880b151..0000000000000000000000000000000000000000
--- a/game/engine/resolvers.lua
+++ /dev/null
@@ -1,86 +0,0 @@
--- 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
-
-resolvers = {}
-resolvers.calc = {}
-
---- Resolves a rng range
-function resolvers.rngrange(x, y)
-	return {__resolver="rngrange", x, y}
-end
-function resolvers.calc.rngrange(t)
-	return rng.range(t[1], t[2])
-end
-
---- Average random
-function resolvers.rngavg(x, y)
-	return {__resolver="rngavg", x, y}
-end
-function resolvers.calc.rngavg(t)
-	return rng.avg(t[1], t[2])
-end
-
---- Random table element
-function resolvers.rngtable(t)
-	return {__resolver="rngtable", t}
-end
-function resolvers.calc.rngtable(t)
-	return rng.table(t[1])
-end
-
---- Random bonus based on level
-resolvers.current_level = 1
-resolvers.mbonus_max_level = 50
-function resolvers.mbonus(max, add)
-	return {__resolver="mbonus", max, add}
-end
-function resolvers.calc.mbonus(t)
-	return rng.mbonus(t[1], resolvers.current_level, resolvers.mbonus_max_level) + (t[2] or 0)
-end
-
---- Talents resolver
-function resolvers.talents(list)
-	return {__resolver="talents", list}
-end
-function resolvers.calc.talents(t, e)
-	for tid, level in pairs(t[1]) do e:learnTalent(tid, true, level) end
-	return nil
-end
-
---- Talents masteries
-function resolvers.tmasteries(list)
-	return {__resolver="tmasteries", list}
-end
-function resolvers.calc.tmasteries(t, e)
-	local ts = {}
-	for tt, level in pairs(t[1]) do
-		assert(e.talents_types_def[tt], "unknown talent type "..tt)
-		e.talents_types[tt] = true
-		e.talents_types_mastery[tt] = level
-	end
-	return nil
-end
-
---- Generic resolver, takes a function
-function resolvers.generic(fct)
-	return {__resolver="generic", fct}
-end
-function resolvers.calc.generic(t, e)
-	return t[1](e)
-end
diff --git a/game/engine/utils.lua b/game/engine/utils.lua
deleted file mode 100644
index 0bec443bec6b228f090aecf2677c1dbdeba8e736..0000000000000000000000000000000000000000
--- a/game/engine/utils.lua
+++ /dev/null
@@ -1,581 +0,0 @@
--- 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
-
-local lpeg = require "lpeg"
-
-function lpeg.anywhere (p)
-	return lpeg.P{ p + 1 * lpeg.V(1) }
-end
-
-function table.clone(tbl, deep)
-	local n = {}
-	for k, e in pairs(tbl) do
-		-- Deep copy subtables, but not objects!
-		if deep and type(e) == "table" and not e.__CLASSNAME then
-			n[k] = table.clone(e, true)
-		else
-			n[k] = e
-		end
-	end
-	return n
-end
-
-function table.merge(dst, src, deep)
-	for k, e in pairs(src) do
-		if deep and dst[k] and type(e) == "table" and type(dst[k]) == "table" and not e.__CLASSNAME then
-			table.merge(dst[k], e, true)
-		elseif deep and not dst[k] and type(e) == "table" and not e.__CLASSNAME then
-			dst[k] = table.clone(e, true)
-		else
-			dst[k] = e
-		end
-	end
-end
-
-function table.mergeAdd(dst, src, deep)
-	for k, e in pairs(src) do
-		if deep and dst[k] and type(e) == "table" and type(dst[k]) == "table" and not e.__CLASSNAME then
-			table.mergeAdd(dst[k], e, true)
-		elseif deep and not dst[k] and type(e) == "table" and not e.__CLASSNAME then
-			dst[k] = table.clone(e, true)
-		elseif dst[k] and type(e) == "number" then
-			dst[k] = dst[k] + e
-		else
-			dst[k] = e
-		end
-	end
-end
-
---- Merges additively the named fields and append the array part
--- Yes this is weird and you'll probably not need it, but the engine does :)
-function table.mergeAddAppendArray(dst, src, deep)
-	-- Append the array part
-	for i = 1, #src do
-		local b = src[i]
-		if deep and type(b) == "table" and not b.__CLASSNAME then b = table.clone(b, true)
-		elseif deep and type(b) == "table" and b.__CLASSNAME then b = b:clone()
-		end
-		table.insert(dst, b)
-	end
-
-	-- Copy the table part
-	for k, e in pairs(src) do
-		if type(k) ~= "number" then
-			if deep and dst[k] and type(e) == "table" and type(dst[k]) == "table" and not e.__CLASSNAME then
-				-- WARNING we do not recurse on ourself but instead of the simple mergeAdd, we do not want to do the array stuff for subtables
-				-- yes I warned you this is weird
-				table.mergeAdd(dst[k], e, true)
-			elseif deep and not dst[k] and type(e) == "table" and not e.__CLASSNAME then
-				dst[k] = table.clone(e, true)
-			elseif dst[k] and type(e) == "number" then
-				dst[k] = dst[k] + e
-			else
-				dst[k] = e
-			end
-		end
-	end
-end
-
-function table.append(dst, src)
-	for i = 1, #src do dst[#dst+1] = src[i] end
-end
-
-function table.reverse(t)
-	local tt = {}
-	for i, e in ipairs(t) do tt[e] = i end
-	return tt
-end
-function table.listify(t)
-	local tt = {}
-	for k, e in pairs(t) do tt[#tt+1] = {k, e} print("listify", #tt, k, e) end
-	return tt
-end
-
-function string.ordinal(number)
-	local suffix = "th"
-	number = tonumber(number)
-	if number == 1 then
-		suffix = "st"
-	elseif number == 2 then
-		suffix = "nd"
-	elseif number == 3 then
-		suffix = "rd"
-	end
-	return number..suffix
-end
-
-function string.capitalize(str)
-	if #str > 1 then
-		return string.upper(str:sub(1, 1))..str:sub(2)
-	elseif #str == 1 then
-		return str:upper()
-	else
-		return str
-	end
-end
-
-function string.bookCapitalize(str)
-	local words = str:split(' ')
-
-	for i = 1, #words do
-		local word = words[i]
-
-		-- Don't capitalize certain words unless they are at the begining
-		-- of the string.
-		if i == 1 or (word ~= "of" and word ~= "the" and word ~= "and" and word ~= "a" and word ~= "an")
-		then
-			words[i] = word:gsub("^(.)",
-							function(x)
-								return x:upper()
-							end)
-		end
-	end
-
-	return table.concat(words, " ")
-end
-
-function string.lpegSub(s, patt, repl)
-	patt = lpeg.P(patt)
-	patt = lpeg.Cs((patt / repl + 1)^0)
-	return lpeg.match(patt, s)
-end
-
--- Those matching patterns are used both by splitLine and drawColorString*
-local Puid = "UID:" * lpeg.R"09"^1 * ":" * lpeg.R"09"
-local Puid_cap = "UID:" * lpeg.C(lpeg.R"09"^1) * ":" * lpeg.C(lpeg.R"09")
-local Pcolorname = (lpeg.R"AZ" + "_")^3
-local Pcode = (lpeg.R"af" + lpeg.R"09" + lpeg.R"AF")
-local Pcolorcode = Pcode * Pcode
-local Pcolorcodefull = Pcolorcode * Pcolorcode * Pcolorcode
-
-function string.removeColorCodes(str)
-	return str:lpegSub("#" * (Puid + Pcolorcodefull + Pcolorname) * "#", "")
-end
-
-function string.splitLine(str, max_width, font)
-	local space_w = font:size(" ")
-	local lines = {}
-	local cur_line, cur_size = "", 0
-	for _, v in ipairs(str:split(lpeg.S"\n ")) do
-		local shortv = v:lpegSub("#" * (Puid + Pcolorcodefull + Pcolorname) * "#", "")
-		local w, h = font:size(shortv)
-
-		if cur_size + space_w + w < max_width then
-			cur_line = cur_line..(cur_size==0 and "" or " ")..v
-			cur_size = cur_size + (cur_size==0 and 0 or space_w) + w
-		else
-			lines[#lines+1] = cur_line
-			cur_line = v
-			cur_size = w
-		end
-	end
-	if cur_size > 0 then lines[#lines+1] = cur_line end
-	return lines
-end
-
-function string.splitLines(str, max_width, font)
-	local lines = {}
-	for _, v in ipairs(str:split(lpeg.S"\n")) do
-		local ls = v:splitLine(max_width, font)
-		if #ls > 0 then
-			for i, l in ipairs(ls) do
-				lines[#lines+1] = l
-			end
-		else
-			lines[#lines+1] = ""
-		end
-	end
-	return lines
-end
-
--- Split a string by the given character(s)
-function string.split(str, char, keep_separator)
-	char = lpeg.P(char)
-	if keep_separator then char = lpeg.C(char) end
-	local elem = lpeg.C((1 - char)^0)
-	local p = lpeg.Ct(elem * (char * elem)^0)
-	return lpeg.match(p, str)
-end
-
-local hex_to_dec = {
-	["0"] = 0,
-	["1"] = 1,
-	["2"] = 2,
-	["3"] = 3,
-	["4"] = 4,
-	["5"] = 5,
-	["6"] = 6,
-	["7"] = 7,
-	["8"] = 8,
-	["9"] = 9,
-	["a"] = 10,
-	["b"] = 11,
-	["c"] = 12,
-	["d"] = 13,
-	["e"] = 14,
-	["f"] = 15,
-}
-local hexcache = {}
-function string.parseHex(str)
-	if hexcache[str] then return hexcache[str] end
-	local res = 0
-	local power = 1
-	str = str:lower()
-	for i = 1, #str do
-		res = res + power * (hex_to_dec[str:sub(#str-i+1,#str-i+1)] or 0)
-		power = power * 16
-	end
-	hexcache[str] = res
-	return res
-end
-
-local tmps = core.display.newSurface(1, 1)
-getmetatable(tmps).__index.drawColorString = function(s, font, str, x, y, r, g, b)
-	local list = str:split("#" * (Puid + Pcolorcodefull + Pcolorname) * "#", true)
-	r = r or 255
-	g = g or 255
-	b = b or 255
-	local oldr, oldg, oldb = r, g, b
-	local max_h = 0
-	for i, v in ipairs(list) do
-		local nr, ng, nb = lpeg.match("#" * lpeg.C(Pcolorcode) * lpeg.C(Pcolorcode) * lpeg.C(Pcolorcode) * "#", v)
-		local col = lpeg.match("#" * lpeg.C(Pcolorname) * "#", v)
-		local uid, mo = lpeg.match("#" * Puid_cap * "#", v)
-		if nr and ng and nb then
-			oldr, oldg, oldb = r, g, b
-			r, g, b = nr:parseHex(), ng:parseHex(), nb:parseHex()
-		elseif col then
-			if col == "LAST" then
-				r, g, b = oldr, oldg, oldb
-			else
-				oldr, oldg, oldb = r, g, b
-				r, g, b = colors[col].r, colors[col].g, colors[col].b
-			end
-		elseif uid and mo and game.level then
-			uid = tonumber(uid)
-			mo = tonumber(mo)
-			local e = __uids[uid]
-			if e then
-				local surf = e:getEntityFinalSurface(game.level.map.tiles, font:lineSkip(), font:lineSkip())
-				local w, h = surf:getSize()
-				s:merge(surf, x, y)
-				if h > max_h then max_h = h end
-				x = x + (w or 0)
-			end
-		else
-			local w, h = font:size(v)
-			if h > max_h then max_h = h end
-			s:drawString(font, v, x, y, r, g, b)
-			x = x + w
-		end
-	end
-	return r, g, b, max_h
-end
-
-getmetatable(tmps).__index.drawColorStringCentered = function(s, font, str, dx, dy, dw, dh, r, g, b)
-	local w, h = font:size(str)
-	local x, y = dx + (dw - w) / 2, dy + (dh - h) / 2
-	s:drawColorString(font, str, x, y, r, g, b)
-end
-
-
-getmetatable(tmps).__index.drawColorStringBlended = function(s, font, str, x, y, r, g, b)
-	local list = str:split("#" * (Puid + Pcolorcodefull + Pcolorname) * "#", true)
-	r = r or 255
-	g = g or 255
-	b = b or 255
-	local oldr, oldg, oldb = r, g, b
-	local max_h = 0
-	for i, v in ipairs(list) do
-		local nr, ng, nb = lpeg.match("#" * lpeg.C(Pcolorcode) * lpeg.C(Pcolorcode) * lpeg.C(Pcolorcode) * "#", v)
-		local col = lpeg.match("#" * lpeg.C(Pcolorname) * "#", v)
-		local uid, mo = lpeg.match("#" * Puid_cap * "#", v)
-		if nr and ng and nb then
-			oldr, oldg, oldb = r, g, b
-			r, g, b = nr:parseHex(), ng:parseHex(), nb:parseHex()
-		elseif col then
-			if col == "LAST" then
-				r, g, b = oldr, oldg, oldb
-			else
-				oldr, oldg, oldb = r, g, b
-				r, g, b = colors[col].r, colors[col].g, colors[col].b
-			end
-		elseif uid and mo and game.level then
-			uid = tonumber(uid)
-			mo = tonumber(mo)
-			local e = __uids[uid]
-			if e then
-				local surf = e:getEntityFinalSurface(game.level.map.tiles, font:lineSkip(), font:lineSkip())
-				local w, h = surf:getSize()
-				s:merge(surf, x, y)
-				if h > max_h then max_h = h end
-				x = x + (w or 0)
-			end
-		else
-			local w, h = font:size(v)
-			if h > max_h then max_h = h end
-			s:drawStringBlended(font, v, x, y, r, g, b)
-			x = x + w
-		end
-	end
-	return r, g, b, max_h
-end
-
-getmetatable(tmps).__index.drawColorStringBlendedCentered = function(s, font, str, dx, dy, dw, dh, r, g, b)
-	local w, h = font:size(str)
-	local x, y = dx + (dw - w) / 2, dy + (dh - h) / 2
-	s:drawColorStringBlended(font, str, x, y, r, g, b)
-end
-
-dir_to_coord = {
-	[1] = {-1, 1},
-	[2] = { 0, 1},
-	[3] = { 1, 1},
-	[4] = {-1, 0},
-	[5] = { 0, 0},
-	[6] = { 1, 0},
-	[7] = {-1,-1},
-	[8] = { 0,-1},
-	[9] = { 1,-1},
-}
-coord_to_dir = {
-	[-1] = {
-		[-1] = 7,
-		[ 0] = 4,
-		[ 1] = 1,
-	},
-	[ 0] = {
-		[-1] = 8,
-		[ 0] = 5,
-		[ 1] = 2,
-	},
-	[ 1] = {
-		[-1] = 9,
-		[ 0] = 6,
-		[ 1] = 3,
-	},
-}
-
-dir_sides =
-{
-	[1] = {left=2, right=4},
-	[2] = {left=3, right=1},
-	[3] = {left=6, right=2},
-	[4] = {left=1, right=7},
-	[6] = {left=9, right=3},
-	[7] = {left=4, right=8},
-	[8] = {left=7, right=9},
-	[9] = {left=8, right=6},
-}
-
-util = {}
-
-function util.getDir(x1, y1, x2, y2)
-	local xd, yd = x1 - x2, y1 - y2
-	if xd ~= 0 then xd = xd / math.abs(xd) end
-	if yd ~= 0 then yd = yd / math.abs(yd) end
-	return coord_to_dir[xd][yd], xd, yd
-end
-
-function util.coordAddDir(x, y, dir)
-	return x + dir_to_coord[dir][1], y + dir_to_coord[dir][2]
-end
-
-function util.boundWrap(i, min, max)
-	if i < min then i = max
-	elseif i > max then i = min end
-	return i
-end
-function util.bound(i, min, max)
-	if i < min then i = min
-	elseif i > max then i = max end
-	return i
-end
-function util.scroll(sel, scroll, max)
-	if sel > scroll + max - 1 then scroll = sel - max + 1 end
-	if sel < scroll then scroll = sel end
-	return scroll
-end
-
-function util.getval(val, ...)
-	if type(val) == "function" then return val(...)
-	elseif type(val) == "table" then return val[rng.range(1, #val)]
-	else return val
-	end
-end
-
-function core.fov.circle_grids(x, y, radius, block)
-	if radius == 0 then return {[x]={[y]=true}} end
-	local grids = {}
-	core.fov.calc_circle(x, y, radius, function(_, lx, ly)
-		if not grids[lx] then grids[lx] = {} end
-		grids[lx][ly] = true
-
-		if block and game.level.map:checkEntity(lx, ly, engine.Map.TERRAIN, "block_move") then return true end
-	end, function()end, nil)
-
-	-- point of origin
-	if not grids[x] then grids[x] = {} end
-	grids[x][y] = true
-
-	return grids
-end
-
-function core.fov.beam_grids(x, y, radius, dir, angle, block)
-	if radius == 0 then return {[x]={[y]=true}} end
-	local grids = {}
-	core.fov.calc_beam(x, y, radius, dir, angle, function(_, lx, ly)
-		if not grids[lx] then grids[lx] = {} end
-		grids[lx][ly] = true
-
-		if block and game.level.map:checkEntity(lx, ly, engine.Map.TERRAIN, "block_move") then return true end
-	end, function()end, nil)
-
-	-- point of origin
-	if not grids[x] then grids[x] = {} end
-	grids[x][y] = true
-
-	return grids
-end
-
---- Finds free grids around coords in a radius.
--- This will return a random grid, the closest possible to the epicenter
--- @param sx the epicenter coordinates
--- @param sy the epicenter coordinates
--- @param radius the radius in which to search
--- @param block true if we only consider line of sight
--- @param what a table which can have the fields Map.ACTOR, Map.OBJECT, ..., set to true. If so it will only return grids that are free of this kind of entities.
-function util.findFreeGrid(sx, sy, radius, block, what)
-	what = what or {}
-	local grids = core.fov.circle_grids(sx, sy, radius, block)
-	local gs = {}
-	for x, yy in pairs(grids) do for y, _ in pairs(yy) do
-		local ok = true
-		for w, _ in pairs(what) do
---			print("findFreeGrid test", x, y, w, ":=>", game.level.map(x, y, w))
-			if game.level.map(x, y, w) then ok = false end
-		end
-		if game.level.map:checkEntity(x, y, game.level.map.TERRAIN, "block_move") then ok = false end
---		print("findFreeGrid", x, y, "from", sx,sy,"=>", ok)
-		if ok then
-			gs[#gs+1] = {x, y, math.floor(core.fov.distance(sx, sy, x, y)), rng.range(1, 1000)}
-		end
-	end end
-
-	if #gs == 0 then return nil end
-
-	table.sort(gs, function(a, b)
-		if a[3] == b[3] then
-			return a[4] < b[4]
-		else
-			return a[3] < b[3]
-		end
-	end)
-
---	print("findFreeGrid using", gs[1][1], gs[1][2])
-	return gs[1][1], gs[1][2]
-end
-
-function util.showMainMenu(no_reboot)
-	if game and type(game) == "table" and game.__session_time_played_start then
-		profile.generic.modules_played = profile.generic.modules_played or {}
-		profile.generic.modules_played[game.__mod_info.short_name] = (profile.generic.modules_played[game.__mod_info.short_name] or 0) + (os.time() - game.__session_time_played_start)
-		profile:saveGenericProfile("modules_played", profile.generic.modules_played)
-	end
-
-	-- Join threads
-	if game and type(game) == "table" then game:joinThreads(30) end
-
-	if no_reboot then
-		local Menu = require("special.mainmenu.class.Game")
-		game = Menu.new()
-		game:run()
-	else
-		-- Tell the C engine to discard the current lua state and make a new one
-		print("[MAIN] rebooting lua state")
-		core.game.reboot()
-	end
-end
-
-function rng.mbonus(max, level, max_level)
-	if level > max_level - 1 then level = max_level - 1 end
-
-	local bonus = (max * level) / max_level
-	local extra = (max * level) % max_level
-	if rng.range(0, max_level - 1) < extra then bonus = bonus + 1 end
-
-	local stand = max / 4
-	extra = max % 4
-	if rng.range(0, 3) < extra then stand = stand + 1 end
-
-	local val = rng.normal(bonus, stand)
-	if val < 0 then val = 0 end
-	if val > max then val = max end
-
-	return val
-end
-
-function rng.table(t)
-	local id = rng.range(1, #t)
-	return t[id], id
-end
-
-function rng.tableRemove(t)
-	local id = rng.range(1, #t)
-	return table.remove(t, id)
-end
-
-function rng.tableIndex(t, ignore)
-	local rt = {}
-	if not ignore then ignore = {} end
-	for k, e in pairs(t) do if not ignore[k] then rt[#rt+1] = k end end
-	return rng.table(rt)
-end
-
-function util.factorial(n)
-	if n == 0 then
-		return 1
-	else
-		return n * util.factorial(n - 1)
-	end
-end
-
-function rng.poissonProcess(k, turn_scale, rate)
-	return math.exp(-rate*turn_scale) * ((rate*turn_scale) ^ k)/ util.factorial(k)
-end
-
-function util.show_backtrace()
-	local level = 2
-
-	print("backtrace:")
-	while true do
-		local stacktrace = debug.getinfo(level, "nlS")
-		if stacktrace == nil then break end
-		print(("    function: %s (%s) at %s:%d"):format(stacktrace.name or "???", stacktrace.what, stacktrace.source or stacktrace.short_src or "???", stacktrace.currentline))
-		level = level + 1
-	end
-end
-
-function util.uuid()
-	local x = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}
-	local y = {'8', '9', 'a', 'b'}
-	local tpl = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
-	local uuid = tpl:gsub("[xy]", function(c) if c=='y' then return rng.table(y) else return rng.table(x) end end)
-	return uuid
-end