From 286206acc2b04ae2aab4856b54ad0bacecdaa987 Mon Sep 17 00:00:00 2001 From: DarkGod <darkgod@net-core.org> Date: Fri, 4 Oct 2019 15:15:52 +0200 Subject: [PATCH] Greatly simplified Creeping Darkness code, it now simply blocks sight for all unless they have Dark Vision --- game/modules/tome/class/Actor.lua | 47 ++++--------------- game/modules/tome/class/NPC.lua | 47 +------------------ game/modules/tome/class/Player.lua | 29 ------------ .../tome/data/talents/cursed/darkness.lua | 10 +++- 4 files changed, 19 insertions(+), 114 deletions(-) diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index bbce488522..a12e124637 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -7061,48 +7061,17 @@ function _M:hasLOS(x, y, what, range, source_x, source_y) if range and core.fov.distance(source_x, source_y, x, y) <= range then range = nil end local lx, ly, is_corner_blocked local last_x, last_y = source_x, source_y - if what == "block_sight" then - local darkVisionRange - if self:knowTalent(self.T_DARK_VISION) then - local t = self:getTalentFromId(self.T_DARK_VISION) - darkVisionRange = self:getTalentRange(t) + local l = core.fov.line(source_x, source_y, x, y, what) + lx, ly, is_corner_blocked = l:step() + while lx and ly and not is_corner_blocked do + -- Check for the range + if range and core.fov.distance(source_x, source_y, lx, ly) > range then + break end + last_x, last_y = lx, ly + if game.level.map:checkAllEntities(lx, ly, what) then break end - local l = core.fov.line(source_x, source_y, x, y, "block_sight") - local inCreepingDark = false lx, ly, is_corner_blocked = l:step() - while lx and ly and not is_corner_blocked do - -- Check for the range - if range and core.fov.distance(source_x, source_y, lx, ly) > range then - break - end - last_x, last_y = lx, ly - if game.level.map:checkAllEntities(lx, ly, "block_sight") then - if darkVisionRange and game.level.map:checkAllEntities(lx, ly, "creepingDark") then - inCreepingDark = true - else - break - end - end - if inCreepingDark and darkVisionRange and core.fov.distance(source_x, source_y, lx, ly) > darkVisionRange then - break - end - - lx, ly, is_corner_blocked = l:step() - end - else - local l = core.fov.line(source_x, source_y, x, y, what) - lx, ly, is_corner_blocked = l:step() - while lx and ly and not is_corner_blocked do - -- Check for the range - if range and core.fov.distance(source_x, source_y, lx, ly) > range then - break - end - last_x, last_y = lx, ly - if game.level.map:checkAllEntities(lx, ly, what) then break end - - lx, ly, is_corner_blocked = l:step() - end end if last_x == x and last_y == y then return true, last_x, last_y end diff --git a/game/modules/tome/class/NPC.lua b/game/modules/tome/class/NPC.lua index 067dae2895..28f70f0701 100644 --- a/game/modules/tome/class/NPC.lua +++ b/game/modules/tome/class/NPC.lua @@ -168,55 +168,12 @@ function _M:lineFOV(tx, ty, extra_block, block, sx, sy) local sees_target = core.fov.distance(sx, sy, tx, ty) <= self.sight and game.level.map.lites(tx, ty) or act and self:canSee(act) and core.fov.distance(sx, sy, tx, ty) <= math.min(self.sight, math.max(self.heightened_senses or 0, self.infravision or 0)) - local darkVisionRange - if self:knowTalent(self.T_DARK_VISION) then - local t = self:getTalentFromId(self.T_DARK_VISION) - darkVisionRange = self:getTalentRange(t) - end - local inCreepingDark = false - extra_block = type(extra_block) == "function" and extra_block or type(extra_block) == "string" and function(_, x, y) return game.level.map:checkAllEntities(x, y, extra_block) end -- This block function can be called *a lot*, so every conditional statement we move outside the function helps - block = block or sees_target and (darkVisionRange and - -- target is seen and source actor has dark vision - function(_, x, y) - if game.level.map:checkAllEntities(x, y, "creepingDark") then - inCreepingDark = true - end - if inCreepingDark and core.fov.distance(sx, sy, x, y) > darkVisionRange then - return true - end - return game.level.map:checkAllEntities(x, y, "block_sight") or - game.level.map:checkEntity(x, y, engine.Map.TERRAIN, "block_move") and not game.level.map:checkEntity(x, y, engine.Map.TERRAIN, "pass_projectile") or - extra_block and extra_block(self, x, y) - end - -- target is seen and source actor does NOT have dark vision - or function(_, x, y) - return game.level.map:checkAllEntities(x, y, "block_sight") or - game.level.map:checkEntity(x, y, engine.Map.TERRAIN, "block_move") and not game.level.map:checkEntity(x, y, engine.Map.TERRAIN, "pass_projectile") or - extra_block and extra_block(self, x, y) - end) - or darkVisionRange and - -- target is NOT seen and source actor has dark vision (do we even need to check for creepingDark in this case?) - function(_, x, y) - if game.level.map:checkAllEntities(x, y, "creepingDark") then - inCreepingDark = true - end - if inCreepingDark and core.fov.distance(sx, sy, x, y) > darkVisionRange then - return true - end - if core.fov.distance(sx, sy, x, y) <= self.sight and game.level.map.lites(x, y) then - return game.level.map:checkEntity(x, y, engine.Map.TERRAIN, "block_sight") or - game.level.map:checkEntity(x, y, engine.Map.TERRAIN, "block_move") and not game.level.map:checkEntity(x, y, engine.Map.TERRAIN, "pass_projectile") or - extra_block and extra_block(self, x, y) - else - return true - end - end - or - -- target is NOT seen and the source actor does NOT have dark vision + block = block or sees_target and + -- target is NOT seen function(_, x, y) if core.fov.distance(sx, sy, x, y) <= self.sight and game.level.map.lites(x, y) then return game.level.map:checkEntity(x, y, engine.Map.TERRAIN, "block_sight") or diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua index 88c70200e3..dafaddf663 100644 --- a/game/modules/tome/class/Player.lua +++ b/game/modules/tome/class/Player.lua @@ -634,19 +634,6 @@ function _M:playerFOV() end if not self:attr("blind") then - -- Handle dark vision; same as infravision, but also sees past creeping dark - -- this is treated as a sense, but is filtered by custom LOS code - if self:knowTalent(self.T_DARK_VISION) then - local t = self:getTalentFromId(self.T_DARK_VISION) - local range = self:getTalentRange(t) - self:computeFOV(range, "block_sense", function(x, y) - local actor = game.level.map(x, y, game.level.map.ACTOR) - if actor and self:hasLOS(x, y) then - game.level.map.seens(x, y, 0.6) - end - end, true, true, true) - end - -- Handle infravision/heightened_senses which allow to see outside of lite radius but with LOS -- Note: Overseer of Nations bonus already factored into attributes if self:attr("infravision") or self:attr("heightened_senses") then @@ -701,26 +688,10 @@ function _M:lineFOV(tx, ty, extra_block, block, sx, sy) local act = game.level.map(x, y, Map.ACTOR) local sees_target = game.level.map.seens(tx, ty) - local darkVisionRange - if self:knowTalent(self.T_DARK_VISION) then - local t = self:getTalentFromId(self.T_DARK_VISION) - darkVisionRange = self:getTalentRange(t) - end - local inCreepingDark = false - extra_block = type(extra_block) == "function" and extra_block or type(extra_block) == "string" and function(_, x, y) return game.level.map:checkAllEntities(x, y, extra_block) end block = block or function(_, x, y) - if darkVisionRange then - if game.level.map:checkAllEntities(x, y, "creepingDark") then - inCreepingDark = true - end - if inCreepingDark and core.fov.distance(sx, sy, x, y) > darkVisionRange then - return true - end - end - if sees_target then return game.level.map:checkAllEntities(x, y, "block_sight") or game.level.map:checkEntity(x, y, engine.Map.TERRAIN, "block_move") and not game.level.map:checkEntity(x, y, engine.Map.TERRAIN, "pass_projectile") or diff --git a/game/modules/tome/data/talents/cursed/darkness.lua b/game/modules/tome/data/talents/cursed/darkness.lua index 09cc7c4600..8868607bf6 100644 --- a/game/modules/tome/data/talents/cursed/darkness.lua +++ b/game/modules/tome/data/talents/cursed/darkness.lua @@ -202,7 +202,12 @@ newTalent{ createDark = function(summoner, x, y, damage, duration, creep, creepChance, initialCreep) local e = Object.new{ name = summoner.name:capitalize() .. "'s creeping dark", - block_sight=true, + block_sight=function(self, x, y, who) + if who and who.attr and who:attr("pierce_creeping_darkness") and x and who.x and core.fov.distance(x, y, who.x, who.y) <= who:attr("pierce_creeping_darkness") then + return false + end + return true + end, canAct = false, canCreep = true, x = x, y = y, @@ -355,6 +360,9 @@ newTalent{ getMovementSpeedChange = function(self, t) return self:combatTalentScale(t, 0.75, 2.5, 0.75) end, + passives = function(self, t, p) + self:talentTemporaryValue(p, "pierce_creeping_darkness", self:getTalentRange(t)) + end, info = function(self, t) local range = self:getTalentRange(t) local movementSpeedChange = t.getMovementSpeedChange(self, t) -- GitLab