From f3970f641eb60bf92492b6715084273cc1bceb74 Mon Sep 17 00:00:00 2001 From: Thomas--S Date: Thu, 1 Feb 2018 16:54:55 +0100 Subject: Seperate signs API from signs definitions Change modnames from *_lib to *_api --- display_api/init.lua | 242 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 display_api/init.lua (limited to 'display_api/init.lua') diff --git a/display_api/init.lua b/display_api/init.lua new file mode 100644 index 0000000..7439119 --- /dev/null +++ b/display_api/init.lua @@ -0,0 +1,242 @@ +--[[ + display_api mod for Minetest - Library to add dynamic display + capabilities to nodes + (c) Pierre-Yves Rollo + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +--]] + +display_api = {} + +-- Prefered gap between node and entity +-- Entity positionment is up to mods but it is a good practice to use this +-- variable as spacing between entity and node +display_api.entity_spacing = 0.002 + +-- Miscelaneous values depending on wallmounted param2 +local wallmounted_values = { + [0]={dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, -- Should never be used + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=1}, -- Should never be used + {dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=5}, + {dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2, rotate=4}, + {dx=0, dz=-1, rx=1, rz=0, yaw=0, rotate=2}, + {dx=0, dz=1, rx=-1, rz=0, yaw=math.pi, rotate=3} +} + +-- Miscelaneous values depending on facedir param2 +local facedir_values = { + [0]={dx=0, dz=-1, rx=1, rz=0, yaw=0, rotate=1}, + {dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=2}, + {dx=0, dz=1, rx=-1, rz=0, yaw=math.pi, rotate=3}, + {dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2, rotate=0}, + -- Forbiden values : + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + } + +-- dx/dy = depth vector, rx/ly = right vector, yaw = yaw of entity, +-- rotate = next facedir/wallmount on rotate + +local function get_values(node) + local ndef = minetest.registered_nodes[node.name] + + if ndef then + if ndef.paramtype2 == "wallmounted" then + return wallmounted_values[node.param2] + end + if ndef.paramtype2 == "facedir" then + return facedir_values[node.param2] + end + 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, 0.5)) do + local entity = objref:get_luaentity() + if entity and ndef.display_entities[entity.name] then + if objrefs[entity.name] then + objref:remove() + else + objrefs[entity.name] = objref + end + end + end + end + return objrefs +end + +local function clip_pos_prop(posprop) + if posprop then + return math.max(-0.5, math.min(0.5, posprop)) + else + return 0 + end +end + +--- (Create and) place display entities according to the node orientation +local function place_entities(pos) + local node = minetest.get_node(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 height = clip_pos_prop(props.height) + local right = clip_pos_prop(props.right) + if not objrefs[entity_name] then + objrefs[entity_name] = minetest.add_entity(pos, entity_name) + end + + objrefs[entity_name]:setpos({ + x = pos.x - values.dx * depth + values.rx * right, + y = pos.y + height, + 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) + end +end + +--- Force entity update +function display_api.update_entities(pos) + local objrefs = place_entities(pos) + for _, objref in pairs(objrefs) do + call_node_on_display_update(pos, objref) + end +end + +--- On_activate callback for display_api entities. Calls on_display_update callbacks +--- of corresponding node for each entity. +function display_api.on_activate(entity, staticdata) + if entity then + entity.object:set_armor_groups({immortal=1}) + call_node_on_display_update(entity.object:getpos(), entity.object) + end +end + +--- On_place callback for display_api items. Does nothing more than preventing item +--- from being placed on ceiling or ground +function display_api.on_place(itemstack, placer, pointed_thing) + local ndef = itemstack:get_definition() + local above = pointed_thing.above + local under = pointed_thing.under + local dir = {x = under.x - above.x, + y = under.y - above.y, + z = under.z - above.z} + + if ndef then + if ndef.paramtype2 == "wallmounted" then + + local wdir = minetest.dir_to_wallmounted(dir) + + if wdir == 0 or wdir == 1 then + dir = placer:get_look_dir() + dir.y = 0 + wdir = minetest.dir_to_wallmounted(dir) + end + + return minetest.item_place(itemstack, placer, pointed_thing, wdir) + else + return minetest.item_place(itemstack, placer, pointed_thing, minetest.dir_to_facedir(dir)) + end + end + +end + +--- 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. +function display_api.on_destruct(pos) + local objrefs = get_entities(pos) + + for _, objref in pairs(objrefs) do + objref:remove() + end +end + +-- On_rotate (screwdriver) callback for display_api items. Prevents axis rotation and reorients entities. +function display_api.on_rotate(pos, node, user, mode, new_param2) + if mode ~= 1 then return false end + + local values = get_values(node) + + if values then + minetest.swap_node(pos, {name = node.name, param1 = node.param1, param2 = values.rotate}) + place_entities(pos) + return true + else + return false + end +end + +--- Creates display entity with some fields and the on_activate callback +function display_api.register_display_entity(entity_name) + if not minetest.registered_entity then + minetest.register_entity(':'..entity_name, { + collisionbox = { 0, 0, 0, 0, 0, 0 }, + visual = "upright_sprite", + textures = {}, + on_activate = display_api.on_activate, + }) + end +end + +minetest.register_lbm({ + label = "Update display_api entities", + name = "display_api:update_entities", + run_at_every_load = true, + nodenames = {"group:display_modpack_node", "group:display_lib_node"}, + action = function(pos, node) display_api.update_entities(pos) end, +}) + +-- Compatibility +display_lib = display_api \ No newline at end of file -- cgit v1.2.3 From ec48743fb9a51b9e88914ad231af6b99fa0cd2ec Mon Sep 17 00:00:00 2001 From: Thomas--S Date: Thu, 15 Feb 2018 17:26:59 +0100 Subject: Allow a greater object offset This allows e.g. polemounted signs. Required for display_modpack to be usable in the streets mod. Backwards compatible. --- display_api/init.lua | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) (limited to 'display_api/init.lua') diff --git a/display_api/init.lua b/display_api/init.lua index 7439119..240ce21 100644 --- a/display_api/init.lua +++ b/display_api/init.lua @@ -79,14 +79,25 @@ 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, 0.5)) do + for _, objref in ipairs(minetest.get_objects_inside_radius(pos, 1.5)) do local entity = objref:get_luaentity() - if entity and ndef.display_entities[entity.name] then + if entity and ndef.display_entities[entity.name] and check_entity_pos(pos, objref) then if objrefs[entity.name] then objref:remove() else @@ -100,7 +111,7 @@ end local function clip_pos_prop(posprop) if posprop then - return math.max(-0.5, math.min(0.5, posprop)) + return math.max(-1.5, math.min(1.5, posprop)) else return 0 end @@ -147,6 +158,7 @@ end 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) end end @@ -154,10 +166,22 @@ end --- On_activate callback for display_api entities. Calls on_display_update callbacks --- of corresponding node for each entity. function display_api.on_activate(entity, staticdata) - if entity then - entity.object:set_armor_groups({immortal=1}) - call_node_on_display_update(entity.object:getpos(), entity.object) - end + if entity then + 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 + end + 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) + end end --- On_place callback for display_api items. Does nothing more than preventing item @@ -226,6 +250,11 @@ function display_api.register_display_entity(entity_name) visual = "upright_sprite", textures = {}, on_activate = display_api.on_activate, + get_staticdata = function(self) + return minetest.serialize({ + pos = self.pos, + }) + end, }) end end -- cgit v1.2.3 From 8c7557e45d4744fe35ad058950062cf771640126 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Fri, 13 Jul 2018 20:41:53 +0200 Subject: Rework all nodes displaying text according to new font_api --- display_api/init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'display_api/init.lua') diff --git a/display_api/init.lua b/display_api/init.lua index 240ce21..2cd15a0 100644 --- a/display_api/init.lua +++ b/display_api/init.lua @@ -128,15 +128,15 @@ local function place_entities(pos) for entity_name, props in pairs(ndef.display_entities) do local depth = clip_pos_prop(props.depth) - local height = clip_pos_prop(props.height) 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) end objrefs[entity_name]:setpos({ x = pos.x - values.dx * depth + values.rx * right, - y = pos.y + height, + y = pos.y - top, z = pos.z - values.dz * depth + values.rz * right}) objrefs[entity_name]:setyaw(values.yaw) @@ -268,4 +268,4 @@ minetest.register_lbm({ }) -- Compatibility -display_lib = display_api \ No newline at end of file +display_lib = display_api -- cgit v1.2.3 From dfaf64cd619550df24bcc7f7e45901202eabd759 Mon Sep 17 00:00:00 2001 From: 12Me21 <12Me21.MC@gmail.com> Date: Thu, 20 Sep 2018 16:07:43 -0400 Subject: Improved on_place Now uses player view direction when trying to place nodes on the floor or ceiling, for both wallmounted and facedir nodes. Also supports nodes where paramtype2 is not wallmounted or facedir. --- display_api/init.lua | 80 +++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 41 deletions(-) (limited to 'display_api/init.lua') diff --git a/display_api/init.lua b/display_api/init.lua index 2cd15a0..ca7b779 100644 --- a/display_api/init.lua +++ b/display_api/init.lua @@ -37,30 +37,30 @@ local wallmounted_values = { -- Miscelaneous values depending on facedir param2 local facedir_values = { [0]={dx=0, dz=-1, rx=1, rz=0, yaw=0, rotate=1}, - {dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=2}, - {dx=0, dz=1, rx=-1, rz=0, yaw=math.pi, rotate=3}, + {dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=2}, + {dx=0, dz=1, rx=-1, rz=0, yaw=math.pi, rotate=3}, {dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2, rotate=0}, - -- Forbiden values : - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + -- Forbiden values : + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, } -- dx/dy = depth vector, rx/ly = right vector, yaw = yaw of entity, @@ -103,7 +103,7 @@ local function get_entities(pos) else objrefs[entity.name] = objref end - end + end end end return objrefs @@ -160,7 +160,7 @@ function display_api.update_entities(pos) for _, objref in pairs(objrefs) do objref:get_luaentity().pos = minetest.hash_node_position(pos) call_node_on_display_update(pos, objref) - end + end end --- On_activate callback for display_api entities. Calls on_display_update callbacks @@ -191,26 +191,24 @@ function display_api.on_place(itemstack, placer, pointed_thing) local above = pointed_thing.above local under = pointed_thing.under local dir = {x = under.x - above.x, - y = under.y - above.y, - z = under.z - above.z} - + 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 if ndef then if ndef.paramtype2 == "wallmounted" then - - local wdir = minetest.dir_to_wallmounted(dir) - - if wdir == 0 or wdir == 1 then - dir = placer:get_look_dir() - dir.y = 0 - wdir = minetest.dir_to_wallmounted(dir) - end - - return minetest.item_place(itemstack, placer, pointed_thing, wdir) - else - return minetest.item_place(itemstack, placer, pointed_thing, minetest.dir_to_facedir(dir)) + param2 = minetest.dir_to_wallmounted(dir) + elseif ndef.paramtype2 == "facedir" then + param2 = minetest.dir_to_facedir(dir) end end - + return minetest.item_place(itemstack, placer, pointed_thing, param2) end --- On_construct callback for display_api items. Creates entities and update them. -- cgit v1.2.3 From 12b556e92907e934a029297b6c6cc8db0bed2c70 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Fri, 21 Sep 2018 19:37:38 +0200 Subject: Turned display_api into a submodule --- display_api | 1 + display_api/init.lua | 269 --------------------------------------------------- 2 files changed, 1 insertion(+), 269 deletions(-) create mode 160000 display_api delete mode 100644 display_api/init.lua (limited to 'display_api/init.lua') diff --git a/display_api b/display_api new file mode 160000 index 0000000..246b7f9 --- /dev/null +++ b/display_api @@ -0,0 +1 @@ +Subproject commit 246b7f958863e7f6b7f604b09361696226928a7b diff --git a/display_api/init.lua b/display_api/init.lua deleted file mode 100644 index ca7b779..0000000 --- a/display_api/init.lua +++ /dev/null @@ -1,269 +0,0 @@ ---[[ - display_api mod for Minetest - Library to add dynamic display - capabilities to nodes - (c) Pierre-Yves Rollo - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . ---]] - -display_api = {} - --- Prefered gap between node and entity --- Entity positionment is up to mods but it is a good practice to use this --- variable as spacing between entity and node -display_api.entity_spacing = 0.002 - --- Miscelaneous values depending on wallmounted param2 -local wallmounted_values = { - [0]={dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, -- Should never be used - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=1}, -- Should never be used - {dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=5}, - {dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2, rotate=4}, - {dx=0, dz=-1, rx=1, rz=0, yaw=0, rotate=2}, - {dx=0, dz=1, rx=-1, rz=0, yaw=math.pi, rotate=3} -} - --- Miscelaneous values depending on facedir param2 -local facedir_values = { - [0]={dx=0, dz=-1, rx=1, rz=0, yaw=0, rotate=1}, - {dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=2}, - {dx=0, dz=1, rx=-1, rz=0, yaw=math.pi, rotate=3}, - {dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2, rotate=0}, - -- Forbiden values : - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - } - --- dx/dy = depth vector, rx/ly = right vector, yaw = yaw of entity, --- rotate = next facedir/wallmount on rotate - -local function get_values(node) - local ndef = minetest.registered_nodes[node.name] - - if ndef then - if ndef.paramtype2 == "wallmounted" then - return wallmounted_values[node.param2] - end - if ndef.paramtype2 == "facedir" then - return facedir_values[node.param2] - end - 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 - local entity = objref:get_luaentity() - if entity and ndef.display_entities[entity.name] and check_entity_pos(pos, objref) then - if objrefs[entity.name] then - objref:remove() - else - objrefs[entity.name] = objref - end - end - end - end - return objrefs -end - -local function clip_pos_prop(posprop) - if posprop then - return math.max(-1.5, math.min(1.5, posprop)) - else - return 0 - end -end - ---- (Create and) place display entities according to the node orientation -local function place_entities(pos) - local node = minetest.get_node(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) - 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) - 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) - end -end - ---- On_activate callback for display_api entities. Calls on_display_update callbacks ---- of corresponding node for each entity. -function display_api.on_activate(entity, staticdata) - if entity then - 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 - end - 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) - end -end - ---- On_place callback for display_api items. Does nothing more than preventing item ---- from being placed on ceiling or ground -function display_api.on_place(itemstack, placer, pointed_thing) - 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} - - -- 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 - if ndef then - if ndef.paramtype2 == "wallmounted" then - param2 = minetest.dir_to_wallmounted(dir) - elseif ndef.paramtype2 == "facedir" then - param2 = minetest.dir_to_facedir(dir) - end - end - return minetest.item_place(itemstack, placer, pointed_thing, param2) -end - ---- 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. -function display_api.on_destruct(pos) - local objrefs = get_entities(pos) - - for _, objref in pairs(objrefs) do - objref:remove() - end -end - --- On_rotate (screwdriver) callback for display_api items. Prevents axis rotation and reorients entities. -function display_api.on_rotate(pos, node, user, mode, new_param2) - if mode ~= 1 then return false end - - local values = get_values(node) - - if values then - minetest.swap_node(pos, {name = node.name, param1 = node.param1, param2 = values.rotate}) - place_entities(pos) - return true - else - return false - end -end - ---- Creates display entity with some fields and the on_activate callback -function display_api.register_display_entity(entity_name) - if not minetest.registered_entity then - minetest.register_entity(':'..entity_name, { - collisionbox = { 0, 0, 0, 0, 0, 0 }, - visual = "upright_sprite", - textures = {}, - on_activate = display_api.on_activate, - get_staticdata = function(self) - return minetest.serialize({ - pos = self.pos, - }) - end, - }) - end -end - -minetest.register_lbm({ - label = "Update display_api entities", - name = "display_api:update_entities", - run_at_every_load = true, - nodenames = {"group:display_modpack_node", "group:display_lib_node"}, - action = function(pos, node) display_api.update_entities(pos) end, -}) - --- Compatibility -display_lib = display_api -- cgit v1.2.3 From d22362a4acfffa2853974a0682b953a8f867e4e4 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Fri, 21 Sep 2018 21:19:48 +0200 Subject: Reverting submodule change until zip file does not include submodule --- display_api | 1 - display_api/init.lua | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+), 1 deletion(-) delete mode 160000 display_api create mode 100644 display_api/init.lua (limited to 'display_api/init.lua') diff --git a/display_api b/display_api deleted file mode 160000 index 246b7f9..0000000 --- a/display_api +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 246b7f958863e7f6b7f604b09361696226928a7b diff --git a/display_api/init.lua b/display_api/init.lua new file mode 100644 index 0000000..ca7b779 --- /dev/null +++ b/display_api/init.lua @@ -0,0 +1,269 @@ +--[[ + display_api mod for Minetest - Library to add dynamic display + capabilities to nodes + (c) Pierre-Yves Rollo + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +--]] + +display_api = {} + +-- Prefered gap between node and entity +-- Entity positionment is up to mods but it is a good practice to use this +-- variable as spacing between entity and node +display_api.entity_spacing = 0.002 + +-- Miscelaneous values depending on wallmounted param2 +local wallmounted_values = { + [0]={dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, -- Should never be used + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=1}, -- Should never be used + {dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=5}, + {dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2, rotate=4}, + {dx=0, dz=-1, rx=1, rz=0, yaw=0, rotate=2}, + {dx=0, dz=1, rx=-1, rz=0, yaw=math.pi, rotate=3} +} + +-- Miscelaneous values depending on facedir param2 +local facedir_values = { + [0]={dx=0, dz=-1, rx=1, rz=0, yaw=0, rotate=1}, + {dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=2}, + {dx=0, dz=1, rx=-1, rz=0, yaw=math.pi, rotate=3}, + {dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2, rotate=0}, + -- Forbiden values : + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, + } + +-- dx/dy = depth vector, rx/ly = right vector, yaw = yaw of entity, +-- rotate = next facedir/wallmount on rotate + +local function get_values(node) + local ndef = minetest.registered_nodes[node.name] + + if ndef then + if ndef.paramtype2 == "wallmounted" then + return wallmounted_values[node.param2] + end + if ndef.paramtype2 == "facedir" then + return facedir_values[node.param2] + end + 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 + local entity = objref:get_luaentity() + if entity and ndef.display_entities[entity.name] and check_entity_pos(pos, objref) then + if objrefs[entity.name] then + objref:remove() + else + objrefs[entity.name] = objref + end + end + end + end + return objrefs +end + +local function clip_pos_prop(posprop) + if posprop then + return math.max(-1.5, math.min(1.5, posprop)) + else + return 0 + end +end + +--- (Create and) place display entities according to the node orientation +local function place_entities(pos) + local node = minetest.get_node(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) + 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) + 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) + end +end + +--- On_activate callback for display_api entities. Calls on_display_update callbacks +--- of corresponding node for each entity. +function display_api.on_activate(entity, staticdata) + if entity then + 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 + end + 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) + end +end + +--- On_place callback for display_api items. Does nothing more than preventing item +--- from being placed on ceiling or ground +function display_api.on_place(itemstack, placer, pointed_thing) + 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} + + -- 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 + if ndef then + if ndef.paramtype2 == "wallmounted" then + param2 = minetest.dir_to_wallmounted(dir) + elseif ndef.paramtype2 == "facedir" then + param2 = minetest.dir_to_facedir(dir) + end + end + return minetest.item_place(itemstack, placer, pointed_thing, param2) +end + +--- 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. +function display_api.on_destruct(pos) + local objrefs = get_entities(pos) + + for _, objref in pairs(objrefs) do + objref:remove() + end +end + +-- On_rotate (screwdriver) callback for display_api items. Prevents axis rotation and reorients entities. +function display_api.on_rotate(pos, node, user, mode, new_param2) + if mode ~= 1 then return false end + + local values = get_values(node) + + if values then + minetest.swap_node(pos, {name = node.name, param1 = node.param1, param2 = values.rotate}) + place_entities(pos) + return true + else + return false + end +end + +--- Creates display entity with some fields and the on_activate callback +function display_api.register_display_entity(entity_name) + if not minetest.registered_entity then + minetest.register_entity(':'..entity_name, { + collisionbox = { 0, 0, 0, 0, 0, 0 }, + visual = "upright_sprite", + textures = {}, + on_activate = display_api.on_activate, + get_staticdata = function(self) + return minetest.serialize({ + pos = self.pos, + }) + end, + }) + end +end + +minetest.register_lbm({ + label = "Update display_api entities", + name = "display_api:update_entities", + run_at_every_load = true, + nodenames = {"group:display_modpack_node", "group:display_lib_node"}, + action = function(pos, node) display_api.update_entities(pos) end, +}) + +-- Compatibility +display_lib = display_api -- cgit v1.2.3 From 44b911be9e57dccea606da2b6907135af75d5033 Mon Sep 17 00:00:00 2001 From: 12Me21 <12Me21.MC@gmail.com> Date: Wed, 26 Sep 2018 13:41:30 -0400 Subject: Improve on_rotate functions (#21) Fixed bugs and improve on_rotate and support color- paramtype2s --- display_api/init.lua | 93 +++++++++++++++++++--------------------------------- 1 file changed, 33 insertions(+), 60 deletions(-) (limited to 'display_api/init.lua') diff --git a/display_api/init.lua b/display_api/init.lua index ca7b779..b65eb89 100644 --- a/display_api/init.lua +++ b/display_api/init.lua @@ -26,55 +26,30 @@ display_api.entity_spacing = 0.002 -- Miscelaneous values depending on wallmounted param2 local wallmounted_values = { - [0]={dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, -- Should never be used - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=1}, -- Should never be used - {dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=5}, - {dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2, rotate=4}, - {dx=0, dz=-1, rx=1, rz=0, yaw=0, rotate=2}, - {dx=0, dz=1, rx=-1, rz=0, yaw=math.pi, rotate=3} + [2]={dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2}, + [3]={dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2 }, + [4]={dx=0, dz=-1, rx=1, rz=0, yaw=0 }, + [5]={dx=0, dz=1, rx=-1, rz=0, yaw=math.pi } } -- Miscelaneous values depending on facedir param2 local facedir_values = { - [0]={dx=0, dz=-1, rx=1, rz=0, yaw=0, rotate=1}, - {dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2, rotate=2}, - {dx=0, dz=1, rx=-1, rz=0, yaw=math.pi, rotate=3}, - {dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2, rotate=0}, - -- Forbiden values : - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - {dx=0, dz=0, rx=0, rz=0, yaw=0, rotate=0}, - } + [0]={dx=0, dz=-1, rx=1, rz=0, yaw=0 }, + [1]={dx=-1, dz=0, rx=0, rz=-1, yaw=-math.pi/2}, + [2]={dx=0, dz=1, rx=-1, rz=0, yaw=math.pi }, + [3]={dx=1, dz=0, rx=0, rz=1, yaw=math.pi/2 } +} -- dx/dy = depth vector, rx/ly = right vector, yaw = yaw of entity, --- rotate = next facedir/wallmount on rotate - local function get_values(node) local ndef = minetest.registered_nodes[node.name] - + if ndef then - if ndef.paramtype2 == "wallmounted" then - return wallmounted_values[node.param2] - end - if ndef.paramtype2 == "facedir" then - return facedir_values[node.param2] + local paramtype2 = ndef.paramtype2 + if paramtype2 == "wallmounted" or paramtype2 == "colorwallmounted" then + return wallmounted_values[node.param2 % 8] + elseif paramtype2 == "facedir" or paramtype2 == "colorfacedir" then + return facedir_values[node.param2 % 32] end end end @@ -97,9 +72,9 @@ local function get_entities(pos) if ndef and ndef.display_entities then for _, objref in ipairs(minetest.get_objects_inside_radius(pos, 1.5)) 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 check_entity_pos(pos, objref) then if objrefs[entity.name] then - objref:remove() + objref:remove() else objrefs[entity.name] = objref end @@ -123,9 +98,9 @@ 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) @@ -133,12 +108,12 @@ local function place_entities(pos) if not objrefs[entity_name] then objrefs[entity_name] = minetest.add_entity(pos, entity_name) 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 @@ -151,7 +126,7 @@ local function call_node_on_display_update(pos, objref) 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) - end + end end --- Force entity update @@ -186,7 +161,7 @@ end --- On_place callback for display_api items. Does nothing more than preventing item --- from being placed on ceiling or ground -function display_api.on_place(itemstack, placer, pointed_thing) +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 @@ -200,15 +175,16 @@ function display_api.on_place(itemstack, placer, pointed_thing) dir.y = 0 end - local param2 + local param2 = 0 if ndef then - if ndef.paramtype2 == "wallmounted" then + local paramtype2 = ndef.paramtype2 + if paramtype2 == "wallmounted" or paramtype2 == "colorwallmounted" then param2 = minetest.dir_to_wallmounted(dir) - elseif ndef.paramtype2 == "facedir" then + elseif paramtype2 == "facedir" or paramtype2 == "colorfacedir" then param2 = minetest.dir_to_facedir(dir) end end - return minetest.item_place(itemstack, placer, pointed_thing, param2) + 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. @@ -225,14 +201,11 @@ function display_api.on_destruct(pos) end end --- On_rotate (screwdriver) callback for display_api items. Prevents axis rotation and reorients entities. -function display_api.on_rotate(pos, node, user, mode, new_param2) - if mode ~= 1 then return false end - - local values = get_values(node) - - if values then - minetest.swap_node(pos, {name = node.name, param1 = node.param1, param2 = values.rotate}) +-- On_rotate (screwdriver) callback for display_api items. Prevents invalid rotations and reorients entities. +function display_api.on_rotate(pos, node, user, _, new_param2) + node.param2 = new_param2 + if get_values(node) then + minetest.swap_node(pos, node) place_entities(pos) return true else -- cgit v1.2.3 From 03983f081ed98ba6793e4f2c9ab461f89938c3b5 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Thu, 29 Nov 2018 14:27:36 +0100 Subject: Atempt to fix "unknown object" issue + code rework --- display_api/init.lua | 106 ++++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 56 deletions(-) (limited to 'display_api/init.lua') diff --git a/display_api/init.lua b/display_api/init.lua index b65eb89..c9d8c19 100644 --- a/display_api/init.lua +++ b/display_api/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 -- cgit v1.2.3 From bcc181cb154b614007e595b1b991ab218534cdce Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Sat, 1 Dec 2018 20:44:10 +0100 Subject: Replaced core reference by usual minetest reference --- display_api/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'display_api/init.lua') diff --git a/display_api/init.lua b/display_api/init.lua index c9d8c19..4c0be22 100644 --- a/display_api/init.lua +++ b/display_api/init.lua @@ -146,7 +146,7 @@ end function display_api.on_activate(entity, staticdata) if entity then if string.sub(staticdata, 1, string.len("return")) == "return" then - local data = core.deserialize(staticdata) + local data = minetest.deserialize(staticdata) if data and type(data) == "table" then entity.nodepos = data.nodepos end -- cgit v1.2.3 From b88f67f01512f878486eb34b9160aeb2ba9794ac Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Sun, 2 Dec 2018 15:22:37 +0100 Subject: Avoid crash if entity not defined. --- display_api/init.lua | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'display_api/init.lua') diff --git a/display_api/init.lua b/display_api/init.lua index 4c0be22..bf95ded 100644 --- a/display_api/init.lua +++ b/display_api/init.lua @@ -117,6 +117,10 @@ end --- Entity update function update_entity(entity) + if not entity then + return + end + if not entity.nodepos then entity.object:remove() -- Remove old/buggy entity return -- cgit v1.2.3