From 58e6a3be151eb71de3318fa7dcaa8a8f24d94820 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Mon, 27 May 2013 14:16:13 +0000
Subject: [PATCH] Tentacles can not be summoned out of range Ambuscade shadow
 can not teleport When a summon dies/disappears, any NPCs targetting it will
 start looking for the summoner

git-svn-id: http://svn.net-core.org/repos/t-engine4@6785 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engines/default/engine/interface/ActorAI.lua |  7 ++++++-
 game/modules/tome/ai/target.lua                   |  5 +++++
 game/modules/tome/class/Actor.lua                 |  1 +
 game/modules/tome/class/NPC.lua                   | 13 +++++++++++++
 game/modules/tome/class/NicerTiles.lua            |  1 +
 game/modules/tome/data/talents/cunning/ambush.lua |  4 +++-
 game/modules/tome/data/talents/misc/npcs.lua      |  2 ++
 7 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/game/engines/default/engine/interface/ActorAI.lua b/game/engines/default/engine/interface/ActorAI.lua
index 46304fddd2..ecbc0ae0d0 100644
--- a/game/engines/default/engine/interface/ActorAI.lua
+++ b/game/engines/default/engine/interface/ActorAI.lua
@@ -104,6 +104,11 @@ function _M:moveDirection(x, y, force)
 	end
 end
 
+--- Responsible for clearing ai target if needed
+function _M:clearAITarget()
+	if self.ai_target.actor and self.ai_target.actor.dead then self.ai_target.actor = nil end
+end
+
 --- Main entry point for AIs
 function _M:doAI()
 	if not self.ai then return end
@@ -112,7 +117,7 @@ function _M:doAI()
 
 	-- 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
+	self:clearAITarget()
 
 	-- Update the ai_target table
 	local target_pos = self.ai_target.actor and self.fov and self.fov.actors and self.fov.actors[self.ai_target.actor]
diff --git a/game/modules/tome/ai/target.lua b/game/modules/tome/ai/target.lua
index e9ebf79c34..3711b6f68b 100644
--- a/game/modules/tome/ai/target.lua
+++ b/game/modules/tome/ai/target.lua
@@ -22,6 +22,11 @@
 -- This is ToME specific, overriding the engine default target_simple to account for lite, infravision, ...
 newAI("target_simple", function(self)
 	if not self.x then return end
+
+	if self.ai_target.actor and (self.ai_target.actor.dead or not game.level:hasEntity(self.ai_target.actor)) and self.ai_target.actor.summoner then
+		self.ai_target.actor = self.ai_target.actor.summoner
+	end
+
 	if self.ai_target.actor and not self.ai_target.actor.dead and game.level:hasEntity(self.ai_target.actor) and rng.percent(90) and not self.ai_target.actor:attr("invulnerable") then return true end
 
 	-- Find closer enemy and target it
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 1ad4f2dd2a..0fcd85e474 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -1164,6 +1164,7 @@ end
 -- @return true if the teleport worked
 function _M:teleportRandom(x, y, dist, min_dist)
 	if self:attr("encased_in_ice") then return end
+	if self:attr("cant_teleport") then return end
 	if game.level.data.no_teleport_south and y + dist > self.y then
 		y = self.y - dist
 	end
diff --git a/game/modules/tome/class/NPC.lua b/game/modules/tome/class/NPC.lua
index ef991ed956..613834f79d 100644
--- a/game/modules/tome/class/NPC.lua
+++ b/game/modules/tome/class/NPC.lua
@@ -424,6 +424,19 @@ function _M:addedToLevel(level, x, y)
 	return mod.class.Actor.addedToLevel(self, level, x, y)
 end
 
+--- Responsible for clearing ai target if needed
+-- Pass target to summoner if any
+function _M:clearAITarget()
+	if self.ai_target.actor and (self.ai_target.actor.dead or not game.level:hasEntity(self.ai_target.actor)) and self.ai_target.actor.summoner then
+		self.ai_target.actor = self.ai_target.actor.summoner
+		-- You think you can cheat with summons ? let's cheat back !
+		-- yeah it's logical because .. hum .. yeah because the npc saw were the summon came from!
+		self.ai_state.target_last_seen = {x=self.ai_target.actor.x, y=self.ai_target.actor.y, turn=game.turn}
+	end
+
+	if self.ai_target.actor and self.ai_target.actor.dead then self.ai_target.actor = nil end
+end
+
 local shove_algorithm = function(self)
 	return 3 * self.rank + self.size_category * self.size_category
 end
diff --git a/game/modules/tome/class/NicerTiles.lua b/game/modules/tome/class/NicerTiles.lua
index a59eb2ea74..b5e6309132 100644
--- a/game/modules/tome/class/NicerTiles.lua
+++ b/game/modules/tome/class/NicerTiles.lua
@@ -686,6 +686,7 @@ rift = { method="walls", type="riftwall", forbid={}, use_type=true, extended=tru
 	default6={add_displays={{image="terrain/rift/rift_ver_edge_right_01.png", display_x=1}}, min=1, max=1},
 },
 }
+_M.generic_borders_defs = defs
 
 
 --- Make water have nice transition to other stuff
diff --git a/game/modules/tome/data/talents/cunning/ambush.lua b/game/modules/tome/data/talents/cunning/ambush.lua
index 5afc88be14..60afcd6d0a 100644
--- a/game/modules/tome/data/talents/cunning/ambush.lua
+++ b/game/modules/tome/data/talents/cunning/ambush.lua
@@ -151,6 +151,7 @@ newTalent{
 		m.clone_on_hit = nil
 		m.exp_worth = 0
 		m.no_inventory_access = true
+		m.cant_teleport = true
 		m.stealth = t.getStealthPower(self, t)
 		m:unlearnTalent(m.T_AMBUSCADE,m:getTalentLevelRaw(m.T_AMBUSCADE))
 		m:unlearnTalent(m.T_PROJECTION,m:getTalentLevelRaw(m.T_PROJECTION)) -- no recurssive projections
@@ -181,7 +182,7 @@ newTalent{
 				end,
 				on_uncontrol = function(self)
 					self.summoner.ai = self.summoner.ambuscade_ai
-					game:onTickEnd(function() game.party:removeMember(self) end)
+					game:onTickEnd(function() game.party:removeMember(self) self:disappear() end)
 				end,
 			})
 		end
@@ -224,6 +225,7 @@ newTalent{
 		local res = t.getDamageRes(self, t)
 		return ([[You veil yourself in shadows for %d turns, and let them control you.
 		While veiled, you become immune to status effects and gain %d%% all damage reduction. Each turn, you blink to a nearby foe (within range %d), hitting it for %d%% darkness weapon damage.
+		The shadow can not teleport.
 		While this goes on, you cannot be stopped unless you are killed, and you cannot control your character.]]):
 		format(duration, res, t.getBlinkRange(self, t) ,100 * damage)
 	end,
diff --git a/game/modules/tome/data/talents/misc/npcs.lua b/game/modules/tome/data/talents/misc/npcs.lua
index 71def1cfa0..5dedd9fcaa 100644
--- a/game/modules/tome/data/talents/misc/npcs.lua
+++ b/game/modules/tome/data/talents/misc/npcs.lua
@@ -1149,6 +1149,8 @@ newTalent{
 		local tg = {type="hit", range=self:getTalentRange(t), talent=t}
 		local tx, ty = self:getTarget(tg)
 		if not tx or not ty then return nil end
+		local _ _, _, _, tx, ty = self:canProject(tg, tx, ty)
+		if not tx or not ty then return nil end
 
 		-- Find space
 		local x, y = util.findFreeGrid(tx, ty, 3, true, {[Map.ACTOR]=true})
-- 
GitLab