The setting: boss level of the necromancer pride. I enter the level in LOS of the boss, fight him for a few turns and then teleport away. I am in the process of clearing out the corner I landed into when I see some bone shield particle effects turn the corner at my back. I was expecting the boss to find me soon, but I will admit the warning the particle effects gave me severly undercut the tension.
So I started digging to understand how all of this work. It looks like the NPC's tile goes invisible in the engine.Map:updateMap call:
Code: Select all
if a then
-- Handles invisibility and telepathy and other such things
if not self.actor_player or self.actor_player:canSee(a) then
a:getMapObjects(self.tiles, mos, 10)
a:setupMinimapInfo(a._mo, self)
end
end
...
-- Cache the map objects in the C map
self._map:setGrid(x, y, mos)
Code: Select all
function _M:displayParticles(nb_keyframes)
...
if nb_keyframes == 0 and e.x and e.y then
-- Just display it, not updating, no emitting
if e.x + e.radius >= self.mx and e.x - e.radius < self.mx + self.viewport.mwidth and e.y + e.radius >= self.my and e.y - e.radius < self.my + self.viewport.mheight then
e.ps:toScreen(self.display_x + (adx + e.x - self.mx + 0.5) * self.tile_w * self.zoom, self.display_y + (ady + e.y - self.my + 0.5) * self.tile_h * self.zoom, self.seens(e.x, e.y), e.zoom * self.zoom)
end
elseif e.x and e.y then
alive = e.ps:isAlive()
-- Update more, if needed
if alive and e.x + e.radius >= self.mx and e.x - e.radius < self.mx + self.viewport.mwidth and e.y + e.radius >= self.my and e.y - e.radius < self.my + self.viewport.mheight then
e.ps:toScreen(self.display_x + (adx + e.x - self.mx + 0.5) * self.tile_w * self.zoom, self.display_y + (ady + e.y - self.my + 0.5) * self.tile_h * self.zoom, self.seens(e.x, e.y))
end
if not alive then
del[#del+1] = e
e.dead = true
end
else
del[#del+1] = e
e.dead = true
end
...
How then are particles attached to actors handled? Well they are added to the actor's __particles table, which is then used by engine.Actor:move:
Code: Select all
-- Update particle emitters attached to that actor
local del = {}
for e, _ in pairs(self.__particles) do
if e.dead then del[#del+1] = e
else
e.x = x
e.y = y
map.particles[e] = true
-- Give it our main _mo for display coords
e._mo = self._mo
end
end
for i = 1, #del do self.__particles[del[i]] = nil end