Index: game/modules/tome/class/Game.lua =================================================================== --- game/modules/tome/class/Game.lua (revision 4644) +++ game/modules/tome/class/Game.lua (working copy) @@ -1203,19 +1203,22 @@ RUN_AUTO = function() if self.level and self.zone then - local seen = false + local seen = {} -- Check for visible monsters. Only see LOS actors, so telepathy wont prevent it core.fov.calc_circle(self.player.x, self.player.y, self.level.map.w, self.level.map.h, self.player.sight or 10, function(_, x, y) return self.level.map:opaque(x, y) end, function(_, x, y) local actor = self.level.map(x, y, self.level.map.ACTOR) if actor and actor ~= self.player and self.player:reactionToward(actor) < 0 and - self.player:canSee(actor) and self.level.map.seens(x, y) then seen = true end + self.player:canSee(actor) and self.level.map.seens(x, y) then seen[#seen + 1] = {x=x, y=y, actor=actor} end end, nil) if self.zone.no_autoexplore or self.level.no_autoexplore then self.log("You may not auto-explore this level.") - elseif seen then - self.log("You may not auto-explore with hostile enemies in sight!") + elseif #seen > 0 then + self.log("You may not auto-explore with enemies in sight!") + for _, node in ipairs(seen) do + node.actor:addParticles(engine.Particles.new("notice_enemy", 1)) + end elseif not self.player:autoExplore() then self.log("There is nowhere left to explore.") end Index: game/modules/tome/class/Player.lua =================================================================== --- game/modules/tome/class/Player.lua (revision 4644) +++ game/modules/tome/class/Player.lua (working copy) @@ -548,12 +548,12 @@ end local function spotHostiles(self) - local seen = false + local seen = {} -- Check for visible monsters, only see LOS actors, so telepathy wont prevent resting - core.fov.calc_circle(self.x, self.y, game.level.map.w, game.level.map.h, 20, function(_, x, y) return game.level.map:opaque(x, y) end, function(_, x, y) + core.fov.calc_circle(self.x, self.y, game.level.map.w, game.level.map.h, self.sight or 10, function(_, x, y) return game.level.map:opaque(x, y) end, function(_, x, y) local actor = game.level.map(x, y, game.level.map.ACTOR) if actor and self:reactionToward(actor) < 0 and self:canSee(actor) and game.level.map.seens(x, y) then - seen = {x=x,y=y,actor=actor} + seen[#seen + 1] = {x=x,y=y,actor=actor} end end, nil) return seen @@ -563,7 +563,12 @@ -- We can rest if no hostiles are in sight, and if we need life/mana/stamina/psi (and their regen rates allows them to fully regen) function _M:restCheck() local spotted = spotHostiles(self) - if spotted then return false, ("hostile spotted (%s%s)"):format(spotted.actor.name, game.level.map:isOnScreen(spotted.x, spotted.y) and "" or " - offscreen") end + if #spotted > 0 then + for _, node in ipairs(spotted) do + node.actor:addParticles(engine.Particles.new("notice_enemy", 1)) + end + return false, ("hostile spotted (%s%s)"):format(spotted[1].actor.name, game.level.map:isOnScreen(spotted[1].x, spotted[1].y) and "" or " - offscreen") + end -- Resting improves regen for act, def in pairs(game.party.members) do if game.level:hasEntity(act) and not act.dead then @@ -619,7 +624,7 @@ -- 'ignore_memory' is only used when checking for paths around traps. This ensures we don't remember items "obj_seen" that we aren't supposed to function _M:runCheck(ignore_memory) local spotted = spotHostiles(self) - if spotted then return false, ("hostile spotted (%s%s)"):format(spotted.actor.name, game.level.map:isOnScreen(spotted.x, spotted.y) and "" or " - offscreen") end + if #spotted > 0 then return false, ("hostile spotted (%s%s)"):format(spotted[1].actor.name, game.level.map:isOnScreen(spotted[1].x, spotted[1].y) and "" or " - offscreen") end if self.air_regen < 0 then return false, "losing breath!" end @@ -697,6 +702,12 @@ function _M:runStopped() game.level.map.clean_fov = true self:playerFOV() + local spotted = spotHostiles(self) + if #spotted > 0 then + for _, node in ipairs(spotted) do + node.actor:addParticles(engine.Particles.new("notice_enemy", 1)) + end + end end --- Activates a hotkey with a type "inventory" Index: game/modules/tome/data/gfx/particles/notice_enemy.lua =================================================================== --- game/modules/tome/data/gfx/particles/notice_enemy.lua (revision 0) +++ game/modules/tome/data/gfx/particles/notice_enemy.lua (revision 0) @@ -0,0 +1,57 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010, 2011 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 . +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +base_size = 32 + +local nb = 0 + +return { generator = function() + local f = 1.5 - nb/36 + local life = 32 + + local xv = rng.float(-1, 1) + local yv = rng.float(-1, 1) + local tv = math.max(math.abs(xv), math.abs(yv)) + xv = 0.9 * base_size / life * xv / tv + yv = 0.9 * base_size / life * yv / tv + + return { + trail = 1, + life = life / f, + size = 3, sizev = 0, sizea = 0, + + x = -1, xv = xv, xa = -xv / life / f, + y = -1, yv = yv, ya = -yv / life / f, + dir = 0, dirv = 0, dira = 0, + vel = 0, velv = 0, vela = 0, + + r = 0.80, rv = 0, ra = 0, + g = 0.08, gv = 0, ga = 0, + b = 0.08, bv = 0, ba = 0, + a = 0.7, av = -0.6 * f / life, aa = 0, + } +end, }, +function(self) + if nb == 0 then self.ps:emit(300) + elseif nb == 18 then self.ps:emit(300) + end + + nb = nb + 1 +end, +600, nil, true Index: game/modules/tome/class/interface/PlayerExplore.lua =================================================================== --- game/modules/tome/class/interface/PlayerExplore.lua (revision 4644) +++ game/modules/tome/class/interface/PlayerExplore.lua (working copy) @@ -135,12 +135,12 @@ --Dir 5 (all adjacent, slow) function(node, cardinal_tiles, diagonal_tiles) local x, y, c, val = node[1], node[2], node[3], node[4]+1 - + local left_okay = x > 0 local right_okay = x < game.level.map.w - 1 local lower_okay = y > 0 local upper_okay = y < game.level.map.h - 1 - + if upper_okay then cardinal_tiles[#cardinal_tiles+1] = {x, y + 1, c + game.level.map.w, val, 2 } end if left_okay then cardinal_tiles[#cardinal_tiles+1] = {x - 1, y, c - 1, val, 4 } end if right_okay then cardinal_tiles[#cardinal_tiles+1] = {x + 1, y, c + 1, val, 6 } end @@ -511,16 +511,17 @@ min_diagonal = values[node[3]] end end + local plus_one = 0 if min_cardinal > min_diagonal then for _, node in ipairs(listAdjacentTiles(c, false, true)) do if values[node[3]] then add_values[node[3]] = values[node[3]] + 1 - door_values[c] = door_val + 1 + plus_one = 1 end end end - local dist = core.fov.distance(self.x, self.y, x, y, true) + 10*door_values[c] + local dist = core.fov.distance(self.x, self.y, x, y, true) + 10*(door_values[c] + plus_one) distances[c] = dist if dist < mindist then mindist = dist @@ -738,7 +739,7 @@ } self.running.dialog.__showup = nil self.running.dialog.__hidden = true - + self:runStep() end return true @@ -788,7 +789,7 @@ if terrain.notice then self:runStop("interesting terrain") return false - elseif self.running.explore == "unseen" then + elseif self.running.explore == "unseen" then return self:autoExplore() else self:runStop("the path is blocked")