From 9ca3474360aaa9caf9de72ef116618704bcaae61 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Thu, 29 Nov 2018 14:27:36 +0100 Subject: [PATCH] Atempt to fix "unknown object" issue + code rework --- init.lua | 106 ++++++++++++++++++++++++++----------------------------- 1 file changed, 50 insertions(+), 56 deletions(-) diff --git a/init.lua b/init.lua index b65eb89..c9d8c19 100644 --- a/init.lua +++ b/init.lua @@ -24,6 +24,9 @@ display_api = {} -- variable as spacing between entity and node display_api.entity_spacing = 0.002 +-- Maximum entity position relative to the node pos +local max_entity_pos = 1.5 + -- Miscelaneous values depending on wallmounted param2 local wallmounted_values = { [2]={dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2}, @@ -43,7 +46,7 @@ local facedir_values = { -- dx/dy = depth vector, rx/ly = right vector, yaw = yaw of entity, local function get_values(node) local ndef = minetest.registered_nodes[node.name] - + if ndef then local paramtype2 = ndef.paramtype2 if paramtype2 == "wallmounted" or paramtype2 == "colorwallmounted" then @@ -54,27 +57,18 @@ local function get_values(node) end end ---- Checks if the object is related to the given position -local function check_entity_pos(pos, objref) - local real_pos = vector.round(objref:get_pos()) - local pos_hash = objref:get_luaentity().pos - if pos_hash == nil then - return vector.equals(real_pos, vector.round(pos)) - else - return vector.equals(minetest.get_position_from_hash(pos_hash), pos) - end -end - --- Gets the display entities attached with a node. Removes extra ones local function get_entities(pos) local objrefs = {} local ndef = minetest.registered_nodes[minetest.get_node(pos).name] if ndef and ndef.display_entities then - for _, objref in ipairs(minetest.get_objects_inside_radius(pos, 1.5)) do + for _, objref in + ipairs(minetest.get_objects_inside_radius(pos, max_entity_pos)) do local entity = objref:get_luaentity() - if entity and ndef.display_entities[entity.name] and check_entity_pos(pos, objref) then + if entity and ndef.display_entities[entity.name] and + entity.nodepos and vector.equals(pos, entity.nodepos) then if objrefs[entity.name] then - objref:remove() + objref:remove() -- Remove duplicates else objrefs[entity.name] = objref end @@ -86,7 +80,7 @@ end local function clip_pos_prop(posprop) if posprop then - return math.max(-1.5, math.min(1.5, posprop)) + return math.max(-max_entity_pos, math.min(max_entity_pos, posprop)) else return 0 end @@ -98,43 +92,52 @@ local function place_entities(pos) local ndef = minetest.registered_nodes[node.name] local values = get_values(node) local objrefs = get_entities(pos) - + if values and ndef and ndef.display_entities then - for entity_name, props in pairs(ndef.display_entities) do local depth = clip_pos_prop(props.depth) local right = clip_pos_prop(props.right) local top = clip_pos_prop(props.top) if not objrefs[entity_name] then - objrefs[entity_name] = minetest.add_entity(pos, entity_name) + objrefs[entity_name] = minetest.add_entity(pos, entity_name, + minetest.serialize({ nodepos = pos })) end - + objrefs[entity_name]:setpos({ x = pos.x - values.dx * depth + values.rx * right, y = pos.y - top, z = pos.z - values.dz * depth + values.rz * right}) - + objrefs[entity_name]:setyaw(values.yaw) end end return objrefs end ---- Call on_display_update callback of a node for one of its display entities -local function call_node_on_display_update(pos, objref) - local ndef = minetest.registered_nodes[minetest.get_node(pos).name] - local entity = objref:get_luaentity() - if ndef and ndef.display_entities and entity and ndef.display_entities[entity.name] then - ndef.display_entities[entity.name].on_display_update(pos, objref) + +--- Entity update +function update_entity(entity) + if not entity.nodepos then + entity.object:remove() -- Remove old/buggy entity + return + end + + local node = minetest.get_node(entity.nodepos) + local ndef = minetest.registered_nodes[node.name] + if ndef and ndef.display_entities and + ndef.display_entities[entity.name] and + ndef.display_entities[entity.name].on_display_update + then + -- Call on_display_update callback of a node for one of its display entities + ndef.display_entities[entity.name].on_display_update(entity.nodepos, + entity.object) end end --- Force entity update function display_api.update_entities(pos) - local objrefs = place_entities(pos) - for _, objref in pairs(objrefs) do - objref:get_luaentity().pos = minetest.hash_node_position(pos) - call_node_on_display_update(pos, objref) + for _, objref in pairs(place_entities(pos)) do + update_entity(objref:get_luaentity()) end end @@ -145,36 +148,28 @@ function display_api.on_activate(entity, staticdata) if string.sub(staticdata, 1, string.len("return")) == "return" then local data = core.deserialize(staticdata) if data and type(data) == "table" then - entity.pos = data.pos + entity.nodepos = data.nodepos end + entity.object:set_armor_groups({immortal=1}) end - entity.object:set_armor_groups({immortal=1}) - local pos - if entity.pos then - pos = minetest.get_position_from_hash(entity.pos) - else - pos = entity.object:getpos() - end - display_api.update_entities(pos) + update_entity(entity) end end ---- On_place callback for display_api items. Does nothing more than preventing item ---- from being placed on ceiling or ground +--- On_place callback for display_api items. +-- Does nothing more than preventing node from being placed on ceiling or ground function display_api.on_place(itemstack, placer, pointed_thing, override_param2) local ndef = itemstack:get_definition() local above = pointed_thing.above local under = pointed_thing.under - local dir = {x = under.x - above.x, - y = 0, - z = under.z - above.z} - + local dir = {x = under.x - above.x, y = 0, z = under.z - above.z} + -- If item is not placed on a wall, use the player's view direction instead if dir.x == 0 and dir.z == 0 then dir = placer:get_look_dir() dir.y = 0 end - + local param2 = 0 if ndef then local paramtype2 = ndef.paramtype2 @@ -184,19 +179,20 @@ function display_api.on_place(itemstack, placer, pointed_thing, override_param2) param2 = minetest.dir_to_facedir(dir) end end - return minetest.item_place(itemstack, placer, pointed_thing, param2 + (override_param2 or 0)) + return minetest.item_place(itemstack, placer, pointed_thing, + param2 + (override_param2 or 0)) end ---- On_construct callback for display_api items. Creates entities and update them. +--- On_construct callback for display_api items. +-- Creates entities and update them. function display_api.on_construct(pos) display_api.update_entities(pos) end ---- On_destruct callback for display_api items. Removes entities. +--- On_destruct callback for display_api items. +-- Removes entities. function display_api.on_destruct(pos) - local objrefs = get_entities(pos) - - for _, objref in pairs(objrefs) do + for _, objref in pairs(get_entities(pos)) do objref:remove() end end @@ -222,9 +218,7 @@ function display_api.register_display_entity(entity_name) textures = {}, on_activate = display_api.on_activate, get_staticdata = function(self) - return minetest.serialize({ - pos = self.pos, - }) + return minetest.serialize({ nodepos = self.nodepos }) end, }) end