Yes, that's exactly what I did. I stared blankly at your timers code for like three hours and then suddenly understood how tables could be objects...
Here's the code I made:
Code: Select all
function extend(entity)
if not(entity) then return nil end
objects[entity.id] = {}
objects[entity.id].name = entity.name
objects[entity.id].id = entity.id
objects[entity.id].level = entity.level
objects[entity.id].x = entity.x
objects[entity.id].y = entity.y
objects[entity.id].facing = entity.facing
objects[entity.id].class = entity.class
return addExtendedMethods(objects[entity.id])
end
function addExtendedMethods(object)
local methods
if object.class == "Monster" then
methods = {
-- Default Grimrock methods
setAIState = function(self, state)
findEntity(self.id):setAIState(state)
end,
setHealth = function(self, health)
findEntity(self.id):setHealth(health)
end,
getHealth = function(self)
return findEntity(self.id):getHealth()
end,
setLevel = function(self, level)
findEntity(self.id):setLevel(level)
end,
getLevel = function(self)
return findEntity(self.id):getLevel()
end,
setPosition = function(self, x, y, level, facing)
findEntity(self.id):setPosition(x, y, level, facing)
end,
addItem = function(self, item)
findEntity(self.id):addItem(item)
end,
destroy = function(self)
findEntity(self.id):destroy()
end,
-- Extended methods
hold = exsp._hold,
unhold = exsp._unhold,
isHeld = exsp._isHeld,
onUnhold = exsp._onUnhold,
freeze = exsp._freeze,
unfreeze = exsp._unfreeze,
isFrozen = exsp._isFrozen,
onUnfreeze = exsp._onUnfreeze,
makeInvulnerable = exsp._makeInvulnerable,
unmakeInvulnerable = exsp._unmakeInvulnerable,
isInvulnerable = exsp._isInvulnerable,
onUnmakeInvulnerable = exsp._onUmakeInvulnerable,
move = exsp._move,
addMonsterHooks = exsp.addMonsterHooks,
executeMonsterHooks = exsp.executeMonsterHooks,
}
else
return nil
end
for k, v in pairs(methods) do
object[k] = v
end
return object
end
My main issue was that the wrapper was not dynamic for level, x, y, facing. Then I did some research and found about metatables, and was like, YEEEEES!!!!! and then saw Legend of Grimrock didn't support them and went NOOOOOO...
But I had a very fast timer (0.05) detecting spells in the dungeon running anyway, so I put the following code inside:
Code: Select all
for id, object in pairs(objects) do
if findEntity(id) then
object.level = findEntity(id).level
object.x = findEntity(id).x
object.y = findEntity(id).y
object.facing = findEntity(id).facing
else
object = nil
end
end
That way the dynamic properties are really updated in (almost) real time, and if the monster dies, the extended object is deleted instantly as well.
Thus:
Code: Select all
local monster = exsp.extend(snail_1)
print(monster.x, monster.y)
Will always return the true current x and y properties. So now monster objects can be "extended" and used in scripts exactly like normal monster objects, but with new methods and the advantage that you can store them in variables without serialization errors.
I also plan to extend other things, like Projectiles, so I made the exsp.extend wrapper flexible.