diff --git a/game/engines/default/engine/ai/simple.lua b/game/engines/default/engine/ai/simple.lua
index c1c5a98bd80dd024b9e5d2351da9e2fea4be9570..152b1b921eaf68c8f38d4f207a60056260461798 100644
--- a/game/engines/default/engine/ai/simple.lua
+++ b/game/engines/default/engine/ai/simple.lua
@@ -24,7 +24,13 @@ 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)
+		local tx, ty
+		-- Move towards the last seen position if we have one
+		if self.ai_state.target_last_seen then
+			tx, ty = self.ai_state.target_last_seen.x, self.ai_state.target_last_seen.y
+		else
+			tx, ty = self:aiSeeTargetPos(self.ai_target.actor)
+		end
 		return self:moveDirection(tx, ty)
 	end
 end)
@@ -167,25 +173,44 @@ newAI("move_blocked_astar", function(self)
 	end
 end)
 
+newAI("move_wander", function(self)
+	local coords = {}
+	for _, coor in pairs(util.adjacentCoords(self.x, self.y)) do
+		if self:canMove(coor[1], coor[2]) then
+			coords[#coords+1] = coor
+		end
+	end
+	if #coords > 0 then
+		local selected = rng.table(coords)
+		return self:moveDirection(selected[1], selected[2])
+	end
+end)
+
 newAI("move_complex", function(self)
 	if self.ai_target.actor and self.x and self.y then
 		local tx, ty = self:aiSeeTargetPos(self.ai_target.actor)
 		local moved
+		
 		-- Can we use A* due to damage?
 		if not moved and self.ai_state.damaged_turns and self.ai_state.damaged_turns > 0 then
 			moved = self:runAI("move_astar")
 		end
 
+		-- Wander if it has been a while since we last saw the target
+		if not moved and self.ai_state.target_last_seen and (game.turn - (self.ai_state.target_last_seen.turn or game.turn)) / (game.energy_to_act / game.energy_per_tick) > 10 then
+			moved = self:runAI("move_wander")
+		end
+
 		-- Check if we can use dmap
 		if not moved then
 			moved = self:runAI("move_dmap")
 		end
 
 		-- Check blocking
-		if not moved then 
+		if not moved and self:hasLOS(tx, ty) then 
 			-- Make sure that we are indeed blocked
 			moved = self:runAI("move_simple")
-			if not moved and self:hasLOS(tx, ty) then
+			if not moved then
 				-- Wait at least 5 turns of not moving before switching to blocked_astar
 				-- add 2 since we remove 1 every turn
 				self.ai_state.blocked_turns = (self.ai_state.blocked_turns or 0) + 2
diff --git a/game/engines/default/engine/ai/talented.lua b/game/engines/default/engine/ai/talented.lua
index b49356ebdf1cc855d67ce515e4a14c2c6deefb53..e0150260ba69f55a0c1bce533ab3c6418e6155c1 100644
--- a/game/engines/default/engine/ai/talented.lua
+++ b/game/engines/default/engine/ai/talented.lua
@@ -23,7 +23,8 @@
 newAI("dumb_talented", function(self)
 	-- Find available talents
 	local avail = {}
-	local target_dist = core.fov.distance(self.x, self.y, self.ai_target.actor.x, self.ai_target.actor.y)
+	local tx, ty = self:aiSeeTargetPos(self.ai_target.actor)
+	local target_dist = core.fov.distance(self.x, self.y, tx, ty)
 	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))
@@ -33,7 +34,7 @@ newAI("dumb_talented", function(self)
 		local tg = {type=util.getval(t.direct_hit, self, t) and "hit" or "bolt", range=total_range}
 		if t.mode == "activated" and not t.no_npc_use and
 		   not self:isTalentCoolingDown(t) and self:preUseTalent(t, true, true) and
-		   (not self:getTalentRequiresTarget(t) or self:canProject(tg, self.ai_target.actor.x, self.ai_target.actor.y))
+		   (not self:getTalentRequiresTarget(t) or self:canProject(tg, tx, ty))
 		   then
 			avail[#avail+1] = tid
 			print(self.name, self.uid, "dumb ai talents can use", t.name, tid)
diff --git a/game/engines/default/engine/interface/ActorAI.lua b/game/engines/default/engine/interface/ActorAI.lua
index 933ca4af7bc7b2c0221e2f0b9912916c7849a020..3df5ba6f7203d35042cbd9cf90af33e1435a545b 100644
--- a/game/engines/default/engine/interface/ActorAI.lua
+++ b/game/engines/default/engine/interface/ActorAI.lua
@@ -154,14 +154,18 @@ end
 function _M:aiSeeTargetPos(target)
 	if not target then return self.x, self.y end
 	local tx, ty = target.x, target.y
-	if target == self.ai_target.actor and self.ai_state.target_last_seen then tx, ty = self.ai_state.target_last_seen.x, self.ai_state.target_last_seen.y end
+	local spread = 0
+
+	if target == self.ai_target.actor and self.ai_state.target_last_seen and not self:hasLOS(self.ai_state.target_last_seen.x, self.ai_state.target_last_seen.y) then
+		tx, ty = self.ai_state.target_last_seen.x, self.ai_state.target_last_seen.y
+		spread = spread + math.floor((game.turn - (self.ai_state.target_last_seen.turn or game.turn)) / (game.energy_to_act / game.energy_per_tick))
+	end
+	
 	local see, chance = self:canSee(target)
 
 	-- Compute the maximum spread if we need to obfuscate 
 	local spread = see and 0 or math.floor((100 - chance) / 10)
 	
-	-- Additional spread due to last_seen
-	spread = spread + math.floor((game.turn - (self.ai_state.target_last_seen and self.ai_state.target_last_seen.turn or game.turn)) / (game.energy_to_act / game.energy_per_tick))
 
 	-- We don't know the exact position, so we obfuscate
 	if spread > 0 then
diff --git a/game/modules/tome/ai/tactical.lua b/game/modules/tome/ai/tactical.lua
index 1d332f4dbf9a301a672782508d39b8976d3536c2..39f6520ae96d2cb615fbbc74321fbd3546bcd40c 100644
--- a/game/modules/tome/ai/tactical.lua
+++ b/game/modules/tome/ai/tactical.lua
@@ -25,8 +25,9 @@ local canFleeDmapKeepLos = function(self)
 	if self.never_move then return false end -- Dont move, dont flee
 	if self.ai_target.actor then
 		local act = self.ai_target.actor
+		local ax, ay = self:aiSeeTargetPos(self.ai_target.actor)
 		local dir, c
-		if self:hasLOS(act.x, act.y) then
+		if self:hasLOS(ax, ay) then
 			dir = 5
 			c = act:distanceMap(self.x, self.y)
 			if not c then return end
@@ -34,7 +35,7 @@ local canFleeDmapKeepLos = function(self)
 		for _, i in ipairs(util.adjacentDirs()) do
 			local sx, sy = util.coordAddDir(self.x, self.y, i)
 			-- Check LOS first
-			if self:hasLOS(act.x, act.y, nil, nil, sx, sy) then
+			if self:hasLOS(ax, ay, nil, nil, sx, sy) then
 				local cd = act:distanceMap(sx, sy)
 	--			print("looking for dmap", dir, i, "::", c, cd)
 				if not cd or ((not c or cd < c) and self:canMove(sx, sy)) then c = cd; dir = i end