diff --git a/game/engine/interface/GameTargeting.lua b/game/engine/interface/GameTargeting.lua
new file mode 100644
index 0000000000000000000000000000000000000000..3b626849a0f7c805b1f6d74de421fb2755e8d88b
--- /dev/null
+++ b/game/engine/interface/GameTargeting.lua
@@ -0,0 +1,221 @@
+-- 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 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()
+	-- 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 self.tooltip:displayAtMap(self.level.map:getMouseTile(self.tooltip_x , self.tooltip_y)) 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/PlayerMouse.lua b/game/engine/interface/PlayerMouse.lua
new file mode 100644
index 0000000000000000000000000000000000000000..11b9bda6ae3f223e4319d119f1a1066a9abd9c3a
--- /dev/null
+++ b/game/engine/interface/PlayerMouse.lua
@@ -0,0 +1,127 @@
+-- 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)
+	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
+		-- 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/modules/example/class/Game.lua b/game/modules/example/class/Game.lua
index 3f8bfadd944ad5435651ce0678bf198091517bf8..6e23d5e0371fdef13688ad1de6128ea72fc6b28d 100644
--- a/game/modules/example/class/Game.lua
+++ b/game/modules/example/class/Game.lua
@@ -19,12 +19,12 @@
 
 require "engine.class"
 require "engine.GameTurnBased"
+require "engine.interface.GameTargeting"
 require "engine.KeyBind"
 local Savefile = require "engine.Savefile"
 local DamageType = require "engine.DamageType"
 local Zone = require "engine.Zone"
 local Map = require "engine.Map"
-local Target = require "engine.Target"
 local Level = require "engine.Level"
 local Birther = require "engine.Birther"
 
@@ -41,7 +41,7 @@ local Tooltip = require "engine.Tooltip"
 
 local QuitDialog = require "mod.dialogs.Quit"
 
-module(..., package.seeall, class.inherit(engine.GameTurnBased, engine.interface.GameMusic, engine.interface.GameSound))
+module(..., package.seeall, class.inherit(engine.GameTurnBased, engine.interface.GameTargeting))
 
 function _M:init()
 	engine.GameTurnBased.init(self, engine.KeyBind.new(), 1000, 100)
@@ -74,10 +74,7 @@ function _M:run()
 	if not self.player then self:newGame() end
 
 	-- Setup the targetting system
-	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"
+	engine.interface.GameTargeting.init(self)
 
 	-- Ok everything is good to go, activate the game in the engine!
 	self:setCurrent()
@@ -180,7 +177,7 @@ end
 
 function _M:tick()
 	if self.level then
-		if self.target.target.entity and not self.level:hasEntity(self.target.target.entity) then self.target.target.entity = false end
+		self:targetOnTick()
 
 		engine.GameTurnBased.tick(self)
 		-- Fun stuff: this can make the game realtime, although callit it in display() will make it work better
@@ -219,112 +216,21 @@ function _M:display()
 		-- Display the targetting system if active
 		self.target:display()
 
-		-- Display a tooltip if available
-		if self.tooltip_x then
-			local mx, my = self.tooltip_x , self.tooltip_y
-			local tmx, tmy = self.level.map:getMouseTile(mx, my)
-			self.tooltip:displayAtMap(tmx, tmy, mx, my)
-		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
-
 		-- And the minimap
 		self.level.map:minimapDisplay(self.w - 200, 20, util.bound(self.player.x - 25, 0, self.level.map.w - 50), util.bound(self.player.y - 25, 0, self.level.map.h - 50), 50, 50, 0.6)
 	end
 
-	engine.GameTurnBased.display(self)
-end
+	-- Tooltip is displayed over all else
+	self:targetDisplayTooltip()
 
---- Targeting mode
--- Now before this is an hard piece of code. You probably wont need to change it much.<br/>
--- This uses a coroutine to allow a talent to request a target without interruption, yet while preserving the realtime-ness of the engine
-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 "players" or nil)
-		if msg then self.log(type(msg) == "string" and msg or "Tactical display disabled. Press shift+'t' or right mouse click to enable.") end
-		self.level.map.changed = true
-		self.target:setActive(false)
-
-		if tostring(old) == "exclusive" then
-			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
-	else
-		Map:setViewerFaction("players")
-		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"
-
-		-- 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
-				self.target:scan(5, nil, self.player.x, self.player.y)
-			end
-		end
-		self.tooltip_x, self.tooltip_y = self.level.map:getTileToScreen(self.target.target.x, self.target.target.y)
-	end
+	engine.GameTurnBased.display(self)
 end
 
 --- Setup the keybinds
 function _M:setupCommands()
-	-- One key handler for targeting
-	self.targetmode_key = engine.KeyBind.new()
-	self.targetmode_key:addCommands{ _SPACE=function() self:targetMode(false, false) end, }
-	self.targetmode_key:addBinds
-	{
-		TACTICAL_DISPLAY = function() self:targetMode(false, false) 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,
-	}
-
+	-- Make targeting work
 	self.normal_key = self.key
+	self:targetSetupKey()
 
 	-- One key handled for normal function
 	self.key:addBinds
@@ -453,72 +359,13 @@ function _M:setupCommands()
 end
 
 function _M:setupMouse(reset)
-	-- Those 2 locals will be "absorbed" into the mosue event handler function, this is a closure
-	local derivx, derivy = 0, 0
-	local moving_around = false
-
 	if reset then self.mouse:reset() end
 	self.mouse:registerZone(Map.display_x, Map.display_y, Map.viewport.width, Map.viewport.height, function(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
-		end
-
-		-- Move
-		if button == "left" and not core.key.modState("shift") and not moving_around and not xrel and not yrel then
-			if self.key == self.normal_key then self.player:mouseMove(tmx, tmy) end
-
-		-- Move map around
-		elseif button == "left" and xrel and yrel and core.key.modState("shift") then
-			derivx = derivx + xrel
-			derivy = derivy + yrel
-			game.level.map.changed = true
-			if derivx >= game.level.map.tile_w then
-				game.level.map.mx = game.level.map.mx - 1
-				derivx = derivx - game.level.map.tile_w
-			elseif derivx <= -game.level.map.tile_w then
-				game.level.map.mx = game.level.map.mx + 1
-				derivx = derivx + game.level.map.tile_w
-			end
-			if derivy >= game.level.map.tile_h then
-				game.level.map.my = game.level.map.my - 1
-				derivy = derivy - game.level.map.tile_h
-			elseif derivy <= -game.level.map.tile_h then
-				game.level.map.my = game.level.map.my + 1
-				derivy = derivy + game.level.map.tile_h
-			end
-			game.level.map._map:setScroll(game.level.map.mx, game.level.map.my)
-			moving_around = true
-		elseif button ~= "none" and not xrel and not yrel then
-			self.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
+		-- Handle targeting
+		if self:targetMouse(button, mx, my, xrel, yrel) then return end
 
-		if not xrel and not yrel then moving_around = false end
+		-- Handle the mouse movement/scrolling
+		self.player:mouseHandleDefault(self.key, self.key == self.normal_key, button, mx, my, xrel, yrel)
 	end)
 	-- Scroll message log
 	self.mouse:registerZone(self.logdisplay.display_x, self.logdisplay.display_y, self.w, self.h, function(button)
diff --git a/game/modules/example/class/Player.lua b/game/modules/example/class/Player.lua
index d55f46694174ba03ee5fb73f3fc80b1e4da6f95e..4182b135a95fa1e0c4b7ae48fcfb4cbcb08ca7fe 100644
--- a/game/modules/example/class/Player.lua
+++ b/game/modules/example/class/Player.lua
@@ -21,6 +21,7 @@ require "engine.class"
 require "mod.class.Actor"
 require "engine.interface.PlayerRest"
 require "engine.interface.PlayerRun"
+require "engine.interface.PlayerMouse"
 require "engine.interface.PlayerHotkeys"
 local Map = require "engine.Map"
 local Dialog = require "engine.Dialog"
@@ -36,6 +37,7 @@ module(..., package.seeall, class.inherit(
 	mod.class.Actor,
 	engine.interface.PlayerRest,
 	engine.interface.PlayerRun,
+	engine.interface.PlayerMouse,
 	engine.interface.PlayerHotkeys
 ))
 
@@ -134,30 +136,13 @@ function _M:levelup()
 end
 
 --- Tries to get a target from the user
--- *WARNING* If used inside a coroutine it will yield and resume it later when a target is found.
--- This is usualy just what you want so dont think too much about it :)
 function _M:getTarget(typ)
-	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 game.target.target.entity = typ.default_target end
-			msg = typ.msg
-		end
-		game:targetMode("exclusive", msg, coroutine.running(), typ)
-		if typ.nolock then
-			game.target_style = "free"
-		end
-		return coroutine.yield()
-	end
-	return game.target.target.x, game.target.target.y, game.target.target.entity
+	return game:targetGetForPlayer(typ)
 end
 
 --- Sets the current target
 function _M:setTarget(target)
-	game.target.target.entity = target
-	game.target.target.x = target.x
-	game.target.target.y = target.y
+	return game:targetSetForPlayer(target)
 end
 
 local function spotHostiles(self)
@@ -201,40 +186,8 @@ function _M:runCheck()
 	return engine.interface.PlayerRun.runCheck(self)
 end
 
-
---- 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
--- if there are monsters in sight it will move one stop in the direct path direction
+--- Move with the mouse
+-- We just feed our spotHostile to the interface mouseMove
 function _M:mouseMove(tmx, tmy)
-	if config.settings.tome.cheat and game.key.status[game.key._LSHIFT] and game.key.status[game.key._LCTRL] then
-		game.log("[CHEAT] teleport to %dx%d", tmx, tmy)
-		self:move(tmx, tmy, true)
-	else
-		-- If hostiles, attack!
-		if 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
+	return engine.interface.PlayerMouse.mouseMove(self, tmx, tmy, spotHostiles)
 end
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index fa669b596296b7f61ffb9f7f824cf3ec1918de1b..18ea885e04029d75df7a1ac5e6b1d0c84d9c05bf 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -21,12 +21,12 @@ require "engine.class"
 require "engine.GameTurnBased"
 require "engine.interface.GameMusic"
 require "engine.interface.GameSound"
+require "engine.interface.GameTargeting"
 local KeyBind = require "engine.KeyBind"
 local Savefile = require "engine.Savefile"
 local DamageType = require "engine.DamageType"
 local Zone = require "engine.Zone"
 local Map = require "engine.Map"
-local Target = require "engine.Target"
 local Level = require "engine.Level"
 local Birther = require "engine.Birther"
 local Astar = require "engine.Astar"
@@ -58,7 +58,7 @@ local Calendar = require "engine.Calendar"
 local Dialog = require "engine.Dialog"
 local QuitDialog = require "mod.dialogs.Quit"
 
-module(..., package.seeall, class.inherit(engine.GameTurnBased, engine.interface.GameMusic, engine.interface.GameSound))
+module(..., package.seeall, class.inherit(engine.GameTurnBased, engine.interface.GameMusic, engine.interface.GameSound, engine.interface.GameTargeting))
 
 -- Difficulty settings
 DIFFICULTY_EASY = 1
@@ -107,10 +107,7 @@ function _M:run()
 	self.hotkeys_display.actor = self.player
 	self.npcs_display.actor = self.player
 
-	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"
+	engine.interface.GameTargeting.init(self)
 
 	-- Ok everything is good to go, activate the game in the engine!
 	self:setCurrent()
@@ -220,8 +217,7 @@ function _M:setupDisplayMode()
 	end
 	if self.level then
 		self.level.map:recreate()
-		self.target = Target.new(Map, self.player)
-		self.target.target.entity = self.player
+		engine.interface.GameTargeting.init(self)
 		self.level.map:moveViewSurround(self.player.x, self.player.y, 8, 8)
 	end
 	self:setupMiniMap()
@@ -368,7 +364,7 @@ end
 
 function _M:tick()
 	if self.level then
-		if self.target.target.entity and not self.level:hasEntity(self.target.target.entity) then self.target.target.entity = false end
+		self:targetOnTick()
 
 		engine.GameTurnBased.tick(self)
 		-- Fun stuff: this can make the game realtime, although callit it in display() will make it work better
@@ -448,126 +444,16 @@ function _M:display()
 	if self.player then self.player.changed = false end
 
 	-- 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 self.tooltip:displayAtMap(self.level.map:getMouseTile(self.tooltip_x , self.tooltip_y)) 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
+	self:targetDisplayTooltip()
 
 	engine.GameTurnBased.display(self)
 end
 
-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' or right mouse click 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 == game.player.x and self.target.target.y == game.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
-
 function _M:setupCommands()
-	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,
-	}
-
+	-- Make targeting work
 	self.normal_key = self.key
+	self:targetSetupKey()
+
 	-- Activate profiler keybinds
 	self.key:setupProfiler()
 
@@ -793,79 +679,13 @@ function _M:setupCommands()
 end
 
 function _M:setupMouse(reset)
-	-- Those 2 locals will be "absorbed" into the mouse event handler function, this is a closure
-	local derivx, derivy = 0, 0
-	local zoom = 1
-	local moving_around = false
-
 	if reset then self.mouse:reset() end
 	self.mouse:registerZone(Map.display_x, Map.display_y, Map.viewport.width, Map.viewport.height, function(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
-		end
-
-		-- Move
-		if button == "left" and not core.key.modState("shift") and not moving_around and not xrel and not yrel then
-			if self.key == self.normal_key then self.player:mouseMove(tmx, tmy) end
-
-		-- Move map around
-		elseif button == "left" and xrel and yrel and core.key.modState("shift") then
-			derivx = derivx + xrel
-			derivy = derivy + yrel
-			game.level.map.changed = true
-			if derivx >= game.level.map.tile_w then
-				game.level.map.mx = game.level.map.mx - 1
-				derivx = derivx - game.level.map.tile_w
-			elseif derivx <= -game.level.map.tile_w then
-				game.level.map.mx = game.level.map.mx + 1
-				derivx = derivx + game.level.map.tile_w
-			end
-			if derivy >= game.level.map.tile_h then
-				game.level.map.my = game.level.map.my - 1
-				derivy = derivy - game.level.map.tile_h
-			elseif derivy <= -game.level.map.tile_h then
-				game.level.map.my = game.level.map.my + 1
-				derivy = derivy + game.level.map.tile_h
-			end
-			game.level.map._map:setScroll(game.level.map.mx, game.level.map.my)
-			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
-			self.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
+		-- Handle targeting
+		if self:targetMouse(button, mx, my, xrel, yrel) then return end
 
-		if not xrel and not yrel then moving_around = false end
+		-- Handle the mouse movement/scrolling
+		self.player:mouseHandleDefault(self.key, self.key == self.normal_key, button, mx, my, xrel, yrel)
 	end)
 	-- Scroll message log
 	self.mouse:registerZone(self.logdisplay.display_x, self.logdisplay.display_y, self.w, self.h, function(button)
diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua
index 7fb1129e8127e5210cc54f039c681a0aadded5c3..3f1552033c5ecf1b5b9ec15bb7ee70ad9ebc6e20 100644
--- a/game/modules/tome/class/Player.lua
+++ b/game/modules/tome/class/Player.lua
@@ -23,14 +23,13 @@ require "engine.interface.PlayerRest"
 require "engine.interface.PlayerRun"
 require "engine.interface.PlayerHotkeys"
 require "engine.interface.PlayerSlide"
+require "engine.interface.PlayerMouse"
 local Map = require "engine.Map"
 local Dialog = require "engine.Dialog"
 local ActorTalents = require "engine.interface.ActorTalents"
 local LevelupStatsDialog = require "mod.dialogs.LevelupStatsDialog"
 local LevelupTalentsDialog = require "mod.dialogs.LevelupTalentsDialog"
 local DeathDialog = require "mod.dialogs.DeathDialog"
-local Astar = require"engine.Astar"
-local DirectPath = require"engine.DirectPath"
 
 --- Defines the player for ToME
 -- It is a normal actor, with some redefined methods to handle user interaction.<br/>
@@ -40,6 +39,7 @@ module(..., package.seeall, class.inherit(
 	engine.interface.PlayerRest,
 	engine.interface.PlayerRun,
 	engine.interface.PlayerHotkeys,
+	engine.interface.PlayerMouse,
 	engine.interface.PlayerSlide
 ))
 
@@ -293,30 +293,13 @@ function _M:levelup()
 end
 
 --- Tries to get a target from the user
--- *WARNING* If used inside a coroutine it will yield and resume it later when a target is found.
--- This is usualy just what you want so dont think too much about it :)
 function _M:getTarget(typ)
-	if game.target.forced then return unpack(game.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 game.target.target.entity = typ.default_target end
-			msg = typ.msg
-		end
-		game:targetMode("exclusive", msg, coroutine.running(), typ)
-		if typ.nolock then game.target_style = "free" end
-		if typ.nowarning then game.target_warning = false end
-		return coroutine.yield()
-	end
-	return game.target.target.x, game.target.target.y, game.target.target.entity
+	return game:targetGetForPlayer(typ)
 end
 
 --- Sets the current target
 function _M:setTarget(target)
-	game.target.target.entity = target
-	game.target.target.x = target.x
-	game.target.target.y = target.y
+	return game:targetSetForPlayer(target)
 end
 
 local function spotHostiles(self)
@@ -384,6 +367,12 @@ function _M:runCheck()
 	return engine.interface.PlayerRun.runCheck(self)
 end
 
+--- Move with the mouse
+-- We just feed our spotHostile to the interface mouseMove
+function _M:mouseMove(tmx, tmy)
+	return engine.interface.PlayerMouse.mouseMove(self, tmx, tmy, spotHostiles)
+end
+
 --- Called after running a step
 function _M:runMoved()
 	self:playerFOV()
@@ -541,43 +530,6 @@ function _M:playerLevelup(on_finish)
 	end
 end
 
---- 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
--- if there are monsters in sight it will move one stop in the direct path direction
-function _M:mouseMove(tmx, tmy)
-	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
-		-- If hostiles, attack!
-		if 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
-
 --- Use a portal with the orb of many ways
 function _M:useOrbPortal(portal)
 	if portal.change_wilderness then