Skip to content
Snippets Groups Projects
Commit dfd22fc0 authored by Hachem_Muche's avatar Hachem_Muche
Browse files

NPC's will tell allies about enemies at slightly greater range (affected by...

NPC's will tell allies about enemies at slightly greater range (affected by game difficulty) and guesses for the position of unseen hostiles will be a bit better.
parent ae8b84b8
No related branches found
No related tags found
1 merge request!157Npc target passing fixes
......@@ -147,12 +147,12 @@ function _M:setTarget(target, last_seen)
if last_seen then
self.ai_state.target_last_seen = last_seen
else
local target_pos = target and self.fov and self.fov.actors and self.fov.actors[self.ai_target.actor] or {x=self.x, y=self.y}
local target_pos = target and (self.fov and self.fov.actors and self.fov.actors[target] or {x=target.x, y=target.y}) or {x=self.x, y=self.y} --No FOV: aiSeeTargetPos will assume new target position is ~3 turns old by default (AI_LOCATION_GUESS_ERROR)
self.ai_state.target_last_seen=table.merge(self.ai_state.target_last_seen or {}, {x=target_pos.x, y=target_pos.y, turn=game.turn}) -- Merge to keep obfuscation data
end
end
_M.AI_SEEN_CACHE_DELAY = 10 * 100
_M.AI_LOCATION_GUESS_ERROR = 3 -- Start position guess errors at ~3 grids
--- Returns the seen coords of the target
-- This will usually return the exact coords, but if the target is only partially visible (or not at all)
......@@ -167,12 +167,12 @@ function _M:aiSeeTargetPos(target)
local spread = 0
-- Guess Cache turn to update position guess (so it's consistent during a turn)
-- Start at -1000 to make sure ti gets run the first time.
LSeen.GCache_turn = LSeen.GCache_turn or game.turn - self.AI_SEEN_CACHE_DELAY
-- Set last cache turn before game turn to make sure it gets run the first time.
LSeen.GCache_turn = LSeen.GCache_turn or game.turn - self.AI_LOCATION_GUESS_ERROR * game.energy_to_act/game.energy_per_tick
-- Guess Cache known turn for spread calculation (self.ai_state.target_last_seen.turn
-- can't be used because it's needed by FOV code)
LSeen.GCknown_turn = LSeen.GCknown_turn or game.turn - self.AI_SEEN_CACHE_DELAY
LSeen.GCknown_turn = LSeen.GCknown_turn or game.turn - self.AI_LOCATION_GUESS_ERROR * game.energy_to_act/game.energy_per_tick
-- Check if target is currently seen
local see, chance = self:canSee(target)
......@@ -188,6 +188,10 @@ function _M:aiSeeTargetPos(target)
if LSeen.GCache_x then -- update guess with new random position. Could use util.findFreeGrid here at cost of speed
tx = math.floor(LSeen.GCache_x + (tx-LSeen.GCache_x)/2)
ty = math.floor(LSeen.GCache_y + (ty-LSeen.GCache_y)/2)
if not target:canMove(tx, ty, true) then -- find a reasonable spot if target can't be at that position
local nx, ny = util.findFreeGrid(tx, ty, spread, false)
if nx then tx, ty = nx, ny end
end
end
LSeen.GCache_x, LSeen.GCache_y = tx, ty
LSeen.GCache_turn = game.turn
......
......@@ -246,14 +246,20 @@ function _M:seen_by(who)
end
return
end
-- Only trust the ally if they can actually see the target
if not who:canSee(who.ai_target.actor) then return end
if who.ai_state and who.ai_state.target_last_seen and type(who.ai_state.target_last_seen) == "table" then
-- Don't believe allies if they saw the target far, far away
if who.ai_state.target_last_seen.x and who.ai_state.target_last_seen.y and core.fov.distance(self.x, self.y, who.ai_state.target_last_seen.x, who.ai_state.target_last_seen.y) > self.sight then return end
-- Don't believe allies if they think the target is too far (away based on distance to ally plus ally to hostile estimate (1.3 * sight range, usually))
local tx, ty = who:aiSeeTargetPos(who.ai_target.actor)
local distallyhostile = core.fov.distance(who.x, who.y, tx, ty) or 100
local range_factor = 1.2 + (tonumber(game.difficulty) or 1)/20 -- NPC's pass targets more freely at higher difficulties
if distallyhostile + core.fov.distance(self.x, self.y, who.x, who.y) > math.min(10, math.max(self.sight, self.infravision or 0, self.heightened_senses or 0, self.sense_radius or 0))*range_factor then return end
-- Don't believe allies if they saw the target over 10 turns ago
if (game.turn - (who.ai_state.target_last_seen.turn or game.turn)) / (game.energy_to_act / game.energy_per_tick) > 10 then return end
end
-- And only trust the ally if they can actually see the target
if not who:canSee(who.ai_target.actor) then return end
self:setTarget(who.ai_target.actor, who.ai_state.target_last_seen)
print("[TARGET] Passing target", self.name, "from", who.name, "to", who.ai_target.actor.name)
......
......@@ -255,6 +255,7 @@ newEntity{ base = "TRAP_COMPLEX",
type = "trap", subtype = "arcane",
combatSpellpower = function(self) return self.dam end,
getTarget = function(self) return self.x, self.y end,
targetable = false,
dam = self.dam,
x = x, y = y,
faction = self.faction,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment