diff --git a/game/engines/default/engine/Entity.lua b/game/engines/default/engine/Entity.lua
index 2b318a01e8a984b59d90bd47fcb5a6ab75643ece..ca0bf1223be89b7c1bc49bed23216ce5884e2218 100644
--- a/game/engines/default/engine/Entity.lua
+++ b/game/engines/default/engine/Entity.lua
@@ -741,24 +741,9 @@ function _M:loadList(file, no_default, res, mod, loaded)
 		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
+				local temp = table.clone(res[t.base], true, {define_as = true})
+				table.mergeAppendArray(temp, t, true)
+				t = temp
 				t.base = nil
 			end
 
diff --git a/game/engines/default/engine/utils.lua b/game/engines/default/engine/utils.lua
index 5c5cc62cd1ea5745fa1626a74c399bf61f34637b..7f4b09e88af4fb5f3a8bdd7b442bb0c873b079a7 100644
--- a/game/engines/default/engine/utils.lua
+++ b/game/engines/default/engine/utils.lua
@@ -37,14 +37,19 @@ function table.print(src, offset)
 	end
 end
 
-function table.clone(tbl, deep, k_filter)
+--- Returns a clone of a table
+-- @param tbl The original table to be cloned
+-- @param deep Boolean to determine if recursive cloning occurs
+-- @param k_skip A table containing key values set to true if you want to skip them.
+-- @return The cloned table.
+function table.clone(tbl, deep, k_skip)
 	local n = {}
-	k_filter = k_filter or {}
+	k_skip = k_skip or {}
 	for k, e in pairs(tbl) do
-		if not k_filter[k] then
+		if not k_skip[k] then
 			-- Deep copy subtables, but not objects!
 			if deep and type(e) == "table" and not e.__CLASSNAME then
-				n[k] = table.clone(e, true, k_filter)
+				n[k] = table.clone(e, true, k_skip)
 			else
 				n[k] = e
 			end
@@ -53,14 +58,34 @@ function table.clone(tbl, deep, k_filter)
 	return n
 end
 
-function table.merge(dst, src, deep, k_filter)
-	k_filter = k_filter or {}
+table.NIL_MERGE = {}
+
+--- Merges two tables in-place.
+-- The table.NIL_MERGE is a special value that will nil out the corresponding dst key.
+-- @param dst The destination table, which will have all merged values.
+-- @param src The source table, supplying values to be merged.
+-- @param deep Boolean that determines if tables will be recursively merged.
+-- @param k_skip A table containing key values set to true if you want to skip them.
+-- @param k_skip_deep Like k_skip, except this table is passed on to the deep recursions.
+-- @param addnumbers Boolean that determines if two numbers will be added rather than replaced.
+function table.merge(dst, src, deep, k_skip, k_skip_deep, addnumbers)
+	k_skip = k_skip or {}
+	k_skip_deep = k_skip_deep or {}
 	for k, e in pairs(src) do
-		if not k_filter[k] then
+		if not k_skip[k] and not k_skip_deep[k] then
+			-- Recursively merge tables
 			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, k_filter)
+				table.merge(dst[k], e, deep, nil, k_skip_deep, addnumbers)
+			-- Clone tables if into the destination
 			elseif deep and not dst[k] and type(e) == "table" and not e.__CLASSNAME then
-				dst[k] = table.clone(e, true, k_filter)
+				dst[k] = table.clone(e, deep, nil, k_skip_deep)
+			-- Nil out any NIL_MERGE entries
+			elseif e == table.NIL_MERGE then
+				dst[k] = nil
+			-- Add number entries if "add" is set
+			elseif addnumbers and dst[k] and type(dst[k]) == "number" and type(e) == "number" then
+				dst[k] = dst[k] + e
+			-- Or simply replace/set with the src value
 			else
 				dst[k] = e
 			end
@@ -69,49 +94,33 @@ function table.merge(dst, src, deep, k_filter)
 	return dst
 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
-	return dst
-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)
+function table.mergeAppendArray(dst, src, deep, k_skip, k_skip_deep, addnumbers)
 	-- Append the array part
+	k_skip = k_skip or {}
 	for i = 1, #src do
+		k_skip[i] = true
 		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
+		if deep and type(b) == "table" then
+			if b.__CLASSNAME then
+				b = b:clone()
 			else
-				dst[k] = e
+				b = table.clone(b, true)
 			end
 		end
+		table.insert(dst, b)
 	end
+	-- Copy the table part
+	return table.merge(dst, src, deep, k_skip, k_skip_deep, addnumbers)
+end
+
+function table.mergeAdd(dst, src, deep, k_skip, k_skip_deep)
+	return table.merge(dst, src, deep, k_skip, k_skip_deep, true)
+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, k_skip, k_skip_deep)
+	return table.mergeAppendArray(dst, src, deep, k_skip, k_skip_deep, true)
 end
 
 function table.append(dst, src)
@@ -153,13 +162,16 @@ function table.from_list(t, k, v)
 	for i, e in ipairs(t) do tt[e[k or 1]] = e[v or 2] end
 	return tt
 end
-
+--- Adds missing keys from the src table to the dst table.
+-- @param dst The destination table, which will have all merged values.
+-- @param src The source table, supplying values to be merged.
+-- @param deep Boolean that determines if tables will be recursively merged.
 function table.update(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.update(dst[k], e, true)
+			table.update(dst[k], e, deep)
 		elseif deep and not dst[k] and type(e) == "table" and not e.__CLASSNAME then
-			dst[k] = table.clone(e, true)
+			dst[k] = table.clone(e, deep)
 		elseif not dst[k] and type(dst[k]) ~= "boolean" then
 			dst[k] = e
 		end
@@ -1531,11 +1543,11 @@ end
 
 function util.browserOpenUrl(url)
 	local tries = {
-		"rundll32 url.dll,FileProtocolHandler %s",  -- Windows
-		"open %s",  -- OSX
-		"xdg-open %s",  -- Linux - portable way
+		"rundll32 url.dll,FileProtocolHandler %s",	-- Windows
+		"open %s",	-- OSX
+		"xdg-open %s",	-- Linux - portable way
 		"gnome-open %s",  -- Linux - Gnome
-		"kde-open %s",  -- Linux - Kde
+		"kde-open %s",	-- Linux - Kde
 		"firefox %s",  -- Linux - try to find something
 		"mozilla-firefox %s",  -- Linux - try to find something
 	}
diff --git a/game/modules/tome/ai/shadow.lua b/game/modules/tome/ai/shadow.lua
index b7465549a3ce37495321de10a53ef39cb4958e45..01858fc53fd340506b0b834a1f5ec12b778fc680 100644
--- a/game/modules/tome/ai/shadow.lua
+++ b/game/modules/tome/ai/shadow.lua
@@ -168,9 +168,9 @@ local function shadowMoveToLocationTarget(self)
 		-- try to move around actors..if we fail we will just try a a new target
 		if not self:canMove(tx, ty, false) then
 			local dir = util.getDir(tx, ty, self.x, self.y)
-			tx, ty = util.coordAddDir(self.x, self.y, dir_sides[dir].left)
+			tx, ty = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).left)
 			if not self:canMove(tx, ty, false) then
-				tx, ty = util.coordAddDir(self.x, self.y, dir_sides[dir].right)
+				tx, ty = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).right)
 				if not self:canMove(tx, ty, false) then
 					--game.logPlayer(self.summoner, "#PINK#%s move fails", self.name:capitalize())
 					return false
diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
index 7c13562791c881f1f3499364f6e93a55943984b7..2e9a9ead6e716f12a1acda160380cd73a2a351a4 100644
--- a/game/modules/tome/class/interface/Combat.lua
+++ b/game/modules/tome/class/interface/Combat.lua
@@ -483,9 +483,9 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam)
 
 	-- Onslaught
 	if hitted and self:attr("onslaught") then
-		local dir = util.getDir(target.x, target.y, self.x, self.y)
-		local lx, ly = util.coordAddDir(self.x, self.y, dir_sides[dir or 6].left)
-		local rx, ry = util.coordAddDir(self.x, self.y, dir_sides[dir or 6].right)
+		local dir = util.getDir(target.x, target.y, self.x, self.y) or 6
+		local lx, ly = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).left)
+		local rx, ry = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).right)
 		local lt, rt = game.level.map(lx, ly, Map.ACTOR), game.level.map(rx, ry, Map.ACTOR)
 
 		if target:checkHit(self:combatAttack(weapon), target:combatPhysicalResist(), 0, 95, 10) and target:canBe("knockback") then
@@ -1070,7 +1070,7 @@ function _M:physicalCrit(dam, weapon, target, atk, def)
 	if target:hasHeavyArmor() and target:knowTalent(target.T_ARMOUR_TRAINING) then
 		chance = chance - target:getTalentLevel(target.T_ARMOUR_TRAINING) * 1.9
 	end
-	
+
 	if target:attr("combat_critreduction") then
 		chance = chance - target:attr("combat_critreduction")
 	end
diff --git a/game/modules/tome/data/talents/techniques/dualweapon.lua b/game/modules/tome/data/talents/techniques/dualweapon.lua
index 93ce71c14144ea71a2517cfbc97459c60e0857d3..7395b54f5a8125f726ca1522960ab5ff60f16773 100644
--- a/game/modules/tome/data/talents/techniques/dualweapon.lua
+++ b/game/modules/tome/data/talents/techniques/dualweapon.lua
@@ -214,8 +214,8 @@ newTalent{
 
 		local dir = util.getDir(x, y, self.x, self.y)
 		if dir == 5 then return nil end
-		local lx, ly = util.coordAddDir(self.x, self.y, dir_sides[dir].left)
-		local rx, ry = util.coordAddDir(self.x, self.y, dir_sides[dir].right)
+		local lx, ly = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).left)
+		local rx, ry = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).right)
 		local lt, rt = game.level.map(lx, ly, Map.ACTOR), game.level.map(rx, ry, Map.ACTOR)
 
 		local hit
diff --git a/game/modules/tome/data/talents/techniques/pugilism.lua b/game/modules/tome/data/talents/techniques/pugilism.lua
index 9ce5f6b464895a2a51bf4fbfac3b86cc4c051c61..007c6fb0c628ed24a4882f99fc0dbab22dd86e03 100644
--- a/game/modules/tome/data/talents/techniques/pugilism.lua
+++ b/game/modules/tome/data/talents/techniques/pugilism.lua
@@ -201,8 +201,8 @@ newTalent{
 		if core.fov.distance(self.x, self.y, x, y) == 1 then
 			-- get left and right side
 			local dir = util.getDir(x, y, self.x, self.y)
-			local lx, ly = util.coordAddDir(self.x, self.y, dir_sides[dir].left)
-			local rx, ry = util.coordAddDir(self.x, self.y, dir_sides[dir].right)
+			local lx, ly = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).left)
+			local rx, ry = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).right)
 			local lt, rt = game.level.map(lx, ly, Map.ACTOR), game.level.map(rx, ry, Map.ACTOR)
 
 			hit1 = self:attackTarget(target, nil, damage, true)
diff --git a/game/modules/tome/dialogs/ArenaFinish.lua b/game/modules/tome/dialogs/ArenaFinish.lua
index 954c637e6b83c3c7e84b5e4bc3feeada66f084f5..a23a4f7d303bd5e130f4b91f98d6d14f512c296f 100644
--- a/game/modules/tome/dialogs/ArenaFinish.lua
+++ b/game/modules/tome/dialogs/ArenaFinish.lua
@@ -149,7 +149,7 @@ function _M:use(item)
 	elseif act == "dump" then
 		game:registerDialog(require("mod.dialogs.CharacterSheet").new(self.actor))
 	elseif act == "log" then
-		game:registerDialog(require("mod.dialogs.ShowChatLog").new("Message Log", 0.6, game.logdisplay, profile.chat))
+		game:registerDialog(require("mod.dialogs.ShowChatLog").new("Message Log", 0.6, game.uiset.logdisplay, profile.chat))
 	end
 end
 
diff --git a/game/modules/tome/dialogs/DeathDialog.lua b/game/modules/tome/dialogs/DeathDialog.lua
index a5b40917134c0afc5ce33f1f53590466727c25a1..10099a4ddd5ca78cb0f52c7e3a0563fc081f4234 100644
--- a/game/modules/tome/dialogs/DeathDialog.lua
+++ b/game/modules/tome/dialogs/DeathDialog.lua
@@ -109,13 +109,13 @@ function _M:resurrectBasic(actor)
 	game:unregisterDialog(self)
 	game.level.map:redisplay()
 	actor.energy.value = game.energy_to_act
-	
+
 	-- apply cursed equipment
 	if actor.hasTalent and actor.hasTalent(actor.T_DEFILING_TOUCH) then
 		local t = self:getTalentFromId(self.T_DEFILING_TOUCH)
 		t.updateCurses(self, t, true)
 	end
-	
+
 	actor.changed = true
 	game.paused = true
 end
@@ -195,7 +195,7 @@ function _M:use(item)
 	elseif act == "dump" then
 		game:registerDialog(require("mod.dialogs.CharacterSheet").new(self.actor))
 	elseif act == "log" then
-		game:registerDialog(require("mod.dialogs.ShowChatLog").new("Message Log", 0.6, game.logdisplay, profile.chat))
+		game:registerDialog(require("mod.dialogs.ShowChatLog").new("Message Log", 0.6, game.uiset.logdisplay, profile.chat))
 	elseif act == "cheat" then
 		game.logPlayer(self.actor, "#LIGHT_BLUE#You resurrect! CHEATER!")
 
@@ -247,7 +247,7 @@ end
 function _M:generateList()
 	local list = {}
 	local allow_res = true
-	
+
 	-- Pause the game
 	game:onTickEnd(function()
 		game.paused = true
diff --git a/src/map.c b/src/map.c
index 6ef9442aac3fb5de921e17ecc55059aea8cfbd9e..69ed2b6d9c466780d77a17b4b1f0d1ba08b8b8ef 100644
--- a/src/map.c
+++ b/src/map.c
@@ -957,8 +957,8 @@ static void map_update_seen_texture(map_type *map)
 		for (ii = 0; ii < map->w+10; ii++)
 		{
 			int i = ii, j = jj;
-			ptr = (((1+f)*j + (i & f)) * map->seens_map_w + (1+f)*i) * 4;
 			int ri = i-5, rj = j-5;
+			ptr = (((1+f)*j + (ri & f)) * map->seens_map_w + (1+f)*i) * 4;
 			ri = (ri < 0) ? 0 : (ri >= map->w) ? map->w-1 : ri;
 			rj = (rj < 0) ? 0 : (rj >= map->h) ? map->h-1 : rj;
 			if ((i < 0) || (j < 0) || (i >= map->w+10) || (j >= map->h+10))