The video shows the results of the new methods compared to the old ones with Map Markers: https://docs.google.com/file/d/0B2rfBgD ... NwRllvZFE/
To use the new methods, you simply need to pop the following code into your dungeon in a script_entity called 'fix' (or whatever you like really). Then you need to change all of your calls to entitiesAt or allEntities to; fix.newEntitiesAt(level, x, y) and fix.newAllEntities(level). Feel free to rename the methods if you prefer, but you cannot use the name allEntities and entitiesAt in a script_entity or you get a stack overflow (hence me giving it the longer name).
Code: Select all
-- Script: entitesAt and allEntities Fix
-- Version: 0.9.1
-- Date: 25th August 2013
-- Author: John Wordsworth
--
-- Thanks to Diarmuid for the optimised version of the newAllEntities method. I didn't
-- realise that it was so slow until you did a performance check on it!
--
-- Provides a fix for the bug in Legend of Grimrock 1.3.7 where the entitiesAt()
-- and allEntities() methods will simply stop returning objects in a for loop if
-- they hit a 'Map Marker' entity in the level. This means that if the user has
-- placed a Map Marker on the level, allEntities will almost definitely fail, where
-- as entitiesAt will fail if the marker is on the same space.
--
-- Usage: Drop this into a script_entity called 'fix' in your dungeon.
-- From then onwards, call
-- fix.newEntitiesAt(level,x,y)
-- and
-- fix.newAllEntities(level)
-- instead of the standard methods in your code.
--
--
-- This entitiesAt method fixes the bug. The built-in iterator returns nil when it hits a map
-- marker, but the iterator itself still exists and is able to continue. So we simply keep
-- the underlying iterator object around and try to iterate over it twice if we hit a nil object.
-- This works on the assumption that you can only ever have one map marker in a space (so we only
-- have to skip 1 nil entry).
--
function newEntitiesAt(level, x, y)
local it = entitiesAt(level, x, y);
return function()
local e = it();
if ( e == nil ) then
e = it();
end
if ( e ) then
return e;
end
end
end
--
-- This iterator simply uses the fixed newEntitiesAt iterator
-- over and over to return entities in spaces.
--
function newAllEntities(level)
local it = allEntities(level);
local c = 0;
return function()
local e = it();
while ( e == nil and c < 100) do
e = it();
c = c + 1
end
if ( e ) then
return e;
end
end
end