diff --git a/game/engines/default/engine/Map.lua b/game/engines/default/engine/Map.lua index 790357e699747ce0ba3ea9ce77e5f7c65b2787ef..c41db862a8d17137d8499ef27b92fb7de308442c 100644 --- a/game/engines/default/engine/Map.lua +++ b/game/engines/default/engine/Map.lua @@ -581,7 +581,7 @@ function _M:checkAllEntities(x, y, what, ...) end end ---- Check all entities of the grid for a property, discarding the results +--- Check all entities of the grid for a property -- This will iterate over all entities without stopping. -- No guaranty is given about the iteration order -- @param x position @@ -609,6 +609,34 @@ function _M:checkAllEntitiesNoStop(x, y, what, ...) return ret end +--- Check all entities of the grid for a property +-- This will iterate over all entities without stopping. +-- No guaranty is given about the iteration order +-- @param x position +-- @param y position +-- @param what property to check +-- @return a table containing all return values, indexed by a list of {layer, entity} +function _M:checkAllEntitiesLayersNoStop(x, y, what, ...) + if not x or not y or x < 0 or x >= self.w or y < 0 or y >= self.h then return {} end + local ret = {} + local tile = self.map[x + y * self.w] + if tile then + -- Collect the keys so we can modify the table while iterating + local keys = {} + for k, _ in pairs(tile) do + table.insert(keys, k) + end + -- Now iterate over the stored keys, checking if the entry exists + for i = 1, #keys do + local e = tile[keys[i]] + if e then + ret[{keys[i],e}] = e:check(what, x, y, ...) + end + end + end + return ret +end + --- Check all entities of the grid for a property, counting the results -- This will iterate over all entities without stopping. -- No guaranty is given about the iteration order diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 6f74a83ea025b115f39279faa9487f1b48ddd6c0..e8f090f52333cb2f7658438e706eb95a9d61c3a5 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -48,6 +48,12 @@ function _M:bumpInto(target, x, y) elseif self.move_others and not target.cant_be_moved then if target.move_others and self ~= game.player then return end + -- Check we can both walk in the tile we will end up in + local blocks = game.level.map:checkAllEntitiesLayersNoStop(target.x, target.y, "block_move", self) + for kind, v in pairs(blocks) do if kind[1] ~= Map.ACTOR and v then return end end + blocks = game.level.map:checkAllEntitiesLayersNoStop(self.x, self.y, "block_move", target) + for kind, v in pairs(blocks) do if kind[1] ~= Map.ACTOR and v then return end end + -- Displace local tx, ty, sx, sy = target.x, target.y, self.x, self.y target.x = nil target.y = nil