-- functions for working with entities inexplicably missing
-- from the game API
local fn = {}
-- WARNING: INEFFICIENT AS FUCK
fn.identify = function(objref) --> objectid
for _, o in pairs(minetest.get_connected_players()) do
if objref == o then return o:get_player_name(), 'player' end
end
for id, le in pairs(minetest.luaentities) do
if le.object == objref then return id, 'entity' end
end
end
fn.handle = sorcery.lib.class {
__newindex = function(self,key,newval)
local hnd if self.player
then hnd = minetest.get_player_by_name(self._id)
else hnd = minetest.luaentities[self._id]
end
if key == 'id' then
if type(newval) == 'string' then
local p = minetest.get_player_by_name(newval)
if p then
self._id = newval
self.player = true
return
end
end
if minetest.luaentities[newval] then
self._id = newval
self.player = false
else error('attempted to assign invalid ID to entity handle') end
elseif key == 'obj' then
local no, kind = fn.identify(newval)
if no then
self._id = no
if kind == 'player'
then self.player = true
else self.player = false
end
else error('attempted to assign invalid ObjectRef to entity handle') end
elseif key == 'stack' and self.kind == 'item' then
hnd:set_item(newval)
end
end;
__index = function(self,key)
local hnd if self.player then
hnd = minetest.get_player_by_name(self._id)
else
hnd = minetest.luaentities[self._id]
end
if key == 'online' then
return hnd ~= nil
elseif key == 'id' then
if self.player then return nil
else return self._id end
elseif key == 'obj' then
if self.player
then return hnd
else return hnd.object
end
elseif key == 'kind' then
if self.player then return 'player'
elseif hnd.name == '__builtin:item' then return 'item'
else return 'object' end
elseif key == 'name' then
if self.player then return self._id
elseif self.kind == 'item' then
return ItemStack(hnd.itemstring):get_name()
else return hnd.name end
elseif key == 'stack' and self.kind == 'item' then
return ItemStack(hnd.itemstring)
elseif key == 'height' then
if kind == 'item' then return 0.5
elseif kind == 'player' then
local eh = hnd.object:get_properties().eye_height
return eh and (eh*1.2) or 1
else
local box = hnd.object:get_properties().collisionbox
if box then
local miny,maxy = box[2], box[5]
return maxy-miny, miny
else return 0 end
end
end
end;
construct = function(h)
local kind, id
if type(h) == 'string' and minetest.get_player_by_name(h) ~= nil then
kind = 'player';
id = h
elseif minetest.luaentities[h] then
kind = 'entity';
id = h
else id, kind = fn.identify(h) end
if not id then
error('attempted to construct object handle from invalid value')
end
return {
player = kind == 'player';
_id = id;
}
end;
}
return fn