mirror of
https://github.com/pyrollo/display_modpack.git
synced 2024-11-15 06:40:30 +01:00
Ongoing devs
This commit is contained in:
parent
1c15814156
commit
e8b62b234e
|
@ -1,7 +1,5 @@
|
||||||
# Display Modpack
|
# Display Modpack
|
||||||
Version 1.3
|
Version 1.3.1
|
||||||
|
|
||||||
**Important**: If using Minetest 5 and above, disable `display_rotation_restriction` in settings and enjoy rotation of display nodes in every direction!
|
|
||||||
|
|
||||||
This modpack provides mods with dynamic display. Mods are :
|
This modpack provides mods with dynamic display. Mods are :
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,11 @@ This method triggers entities update for the display node at pos. Actual entity
|
||||||
This is a helper to register entities used for display.
|
This is a helper to register entities used for display.
|
||||||
|
|
||||||
`entity_name`: Name of the entity to register.
|
`entity_name`: Name of the entity to register.
|
||||||
|
### is\_rotation\_restricted
|
||||||
|
**display\_api.is\_rotation\_restricted()**
|
||||||
|
|
||||||
|
When using Minetest before version 5.0, only upright entities were allowed. Not all node rotations where possible. This functions indicates if the rotation is restricted (true) or not.
|
||||||
|
|
||||||
## Provided callback implementations
|
## Provided callback implementations
|
||||||
### on_place
|
### on_place
|
||||||
**display\_api.on\_place(itemstack, placer, pointed\_thing)**
|
**display\_api.on\_place(itemstack, placer, pointed\_thing)**
|
||||||
|
|
|
@ -22,37 +22,16 @@
|
||||||
-- variable as spacing between entity and node
|
-- variable as spacing between entity and node
|
||||||
display_api.entity_spacing = 0.002
|
display_api.entity_spacing = 0.002
|
||||||
|
|
||||||
-- Settings
|
|
||||||
display_api.rotation_restriction =
|
|
||||||
minetest.settings:get_bool("display_rotation_restriction", true)
|
|
||||||
|
|
||||||
if display_api.rotation_restriction then
|
|
||||||
minetest.log("action", "[display_api] Legacy rotation restriction in effect")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Maximum entity position relative to the node pos
|
-- Maximum entity position relative to the node pos
|
||||||
local max_entity_pos = 1.5
|
local max_entity_pos = 1.5
|
||||||
|
|
||||||
local wallmounted_rotations, facedir_rotations
|
local wallmounted_rotations = {
|
||||||
|
|
||||||
if display_api.rotation_restriction then
|
|
||||||
-- Legacy rotations (MT<5.0)
|
|
||||||
wallmounted_rotations = {
|
|
||||||
[2]={x=0, y=3, z=0}, [3]={x=0, y=1, z=0},
|
|
||||||
[4]={x=0, y=0, z=0}, [5]={x=0, y=2, z=0},
|
|
||||||
}
|
|
||||||
facedir_rotations = {
|
|
||||||
[0]={x=0, y=0, z=0}, [1]={x=0, y=3, z=0},
|
|
||||||
[2]={x=0, y=2, z=0}, [3]={x=0, y=1, z=0},
|
|
||||||
}
|
|
||||||
else
|
|
||||||
-- Full rotations (MT>=5.0)
|
|
||||||
wallmounted_rotations = {
|
|
||||||
[0]={x=1, y=0, z=0}, [1]={x=3, y=0, z=0},
|
[0]={x=1, y=0, z=0}, [1]={x=3, y=0, z=0},
|
||||||
[2]={x=0, y=3, z=0}, [3]={x=0, y=1, z=0},
|
[2]={x=0, y=3, z=0}, [3]={x=0, y=1, z=0},
|
||||||
[4]={x=0, y=0, z=0}, [5]={x=0, y=2, z=0},
|
[4]={x=0, y=0, z=0}, [5]={x=0, y=2, z=0},
|
||||||
}
|
}
|
||||||
facedir_rotations = {
|
|
||||||
|
local facedir_rotations = {
|
||||||
[ 0]={x=0, y=0, z=0}, [ 1]={x=0, y=3, z=0},
|
[ 0]={x=0, y=0, z=0}, [ 1]={x=0, y=3, z=0},
|
||||||
[ 2]={x=0, y=2, z=0}, [ 3]={x=0, y=1, z=0},
|
[ 2]={x=0, y=2, z=0}, [ 3]={x=0, y=1, z=0},
|
||||||
[ 4]={x=3, y=0, z=0}, [ 5]={x=0, y=3, z=3},
|
[ 4]={x=3, y=0, z=0}, [ 5]={x=0, y=3, z=3},
|
||||||
|
@ -66,7 +45,6 @@ else
|
||||||
[20]={x=0, y=0, z=2}, [21]={x=0, y=1, z=2},
|
[20]={x=0, y=0, z=2}, [21]={x=0, y=1, z=2},
|
||||||
[22]={x=0, y=2, z=2}, [23]={x=0, y=3, z=2},
|
[22]={x=0, y=2, z=2}, [23]={x=0, y=3, z=2},
|
||||||
}
|
}
|
||||||
end
|
|
||||||
|
|
||||||
-- Compute other useful values depending on wallmounted and facedir param
|
-- Compute other useful values depending on wallmounted and facedir param
|
||||||
local wallmounted_values = {}
|
local wallmounted_values = {}
|
||||||
|
@ -86,7 +64,9 @@ local function compute_values(r)
|
||||||
for _ = 1, r.x do d, w, h = rx(d), rx(w), rx(h) end
|
for _ = 1, r.x do d, w, h = rx(d), rx(w), rx(h) end
|
||||||
for _ = 1, r.y do d, w, h = ry(d), ry(w), ry(h) end
|
for _ = 1, r.y do d, w, h = ry(d), ry(w), ry(h) end
|
||||||
|
|
||||||
return {rotation=r, depth=d, width=w, height=h}
|
return {
|
||||||
|
rotation=r, depth=d, width=w, height=h,
|
||||||
|
restricted=(r.x==0 and r.z==0) }
|
||||||
end
|
end
|
||||||
|
|
||||||
for i, r in pairs(facedir_rotations) do
|
for i, r in pairs(facedir_rotations) do
|
||||||
|
@ -97,7 +77,38 @@ for i, r in pairs(wallmounted_rotations) do
|
||||||
wallmounted_values[i] = compute_values(r)
|
wallmounted_values[i] = compute_values(r)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_values(node)
|
-- Detect rotation restriction
|
||||||
|
local rotation_restricted = nil
|
||||||
|
minetest.register_entity('display_api:dummy_entity', {
|
||||||
|
collisionbox = { 0, 0, 0, 0, 0, 0 },
|
||||||
|
visual = "upright_sprite",
|
||||||
|
textures = {} })
|
||||||
|
|
||||||
|
function display_api.is_rotation_restricted()
|
||||||
|
if rotation_restricted == nil then
|
||||||
|
local objref = minetest.add_entity(
|
||||||
|
{x=0, y=0, z=0}, 'display_api:dummy_entity')
|
||||||
|
if objref then
|
||||||
|
rotation_restricted = objref.set_rotation == nil
|
||||||
|
objref:remove()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return rotation_restricted
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Clip position property to maximum entity position
|
||||||
|
|
||||||
|
local function clip_pos_prop(posprop)
|
||||||
|
if posprop then
|
||||||
|
return math.max(-max_entity_pos, math.min(max_entity_pos, posprop))
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get values needed for orientation computation of node
|
||||||
|
|
||||||
|
local function get_orientation_values(node)
|
||||||
local ndef = minetest.registered_nodes[node.name]
|
local ndef = minetest.registered_nodes[node.name]
|
||||||
|
|
||||||
if ndef then
|
if ndef then
|
||||||
|
@ -106,12 +117,17 @@ local function get_values(node)
|
||||||
return wallmounted_values[node.param2 % 8]
|
return wallmounted_values[node.param2 % 8]
|
||||||
elseif paramtype2 == "facedir" or paramtype2 == "colorfacedir" then
|
elseif paramtype2 == "facedir" or paramtype2 == "colorfacedir" then
|
||||||
return facedir_values[node.param2 % 32]
|
return facedir_values[node.param2 % 32]
|
||||||
|
else
|
||||||
|
-- No orientation or unknown orientation type
|
||||||
|
return facedir_values[0]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Gets the display entities attached with a node. Removes extra ones
|
-- Gets the display entities attached with a node.
|
||||||
local function get_entities(pos)
|
-- Add missing and remove duplicates
|
||||||
|
|
||||||
|
local function get_display_objrefs(pos, create)
|
||||||
local objrefs = {}
|
local objrefs = {}
|
||||||
local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
|
local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
|
||||||
if ndef and ndef.display_entities then
|
if ndef and ndef.display_entities then
|
||||||
|
@ -127,85 +143,57 @@ local function get_entities(pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
if create then
|
||||||
return objrefs
|
-- Add missing
|
||||||
end
|
for name, _ in pairs(ndef.display_entities) do
|
||||||
|
if not objrefs[name] then
|
||||||
local function clip_pos_prop(posprop)
|
objrefs[name] = minetest.add_entity(pos, name,
|
||||||
if posprop then
|
|
||||||
return math.max(-max_entity_pos, math.min(max_entity_pos, 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 v = get_values(node)
|
|
||||||
local objrefs = get_entities(pos)
|
|
||||||
|
|
||||||
if v 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,
|
|
||||||
minetest.serialize({ nodepos = pos }))
|
minetest.serialize({ nodepos = pos }))
|
||||||
end
|
end
|
||||||
|
|
||||||
objrefs[entity_name]:set_pos({
|
|
||||||
x = pos.x + v.depth.x*depth + v.width.x*right - v.height.x*top,
|
|
||||||
y = pos.y + v.depth.y*depth + v.width.y*right - v.height.y*top,
|
|
||||||
z = pos.z + v.depth.z*depth + v.width.z*right - v.height.z*top,
|
|
||||||
})
|
|
||||||
|
|
||||||
if objrefs[entity_name].set_rotation then
|
|
||||||
objrefs[entity_name]:set_rotation({
|
|
||||||
x = v.rotation.x*math.pi/2,
|
|
||||||
y = v.rotation.y*math.pi/2 + (props.yaw or 0),
|
|
||||||
z = v.rotation.z*math.pi/2,
|
|
||||||
})
|
|
||||||
else -- For minetest < 5.0 -- TODO: To be removed in the future
|
|
||||||
objrefs[entity_name]:set_yaw(values.rotation.y + (props.yaw or 0))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return objrefs
|
return objrefs
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Entity update
|
--- Force entity update : position and texture
|
||||||
function update_entity(entity)
|
|
||||||
if not entity then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
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)
|
|
||||||
else
|
|
||||||
-- Display node has been removed, remove entity also
|
|
||||||
entity.object:remove()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Force entity update
|
|
||||||
function display_api.update_entities(pos)
|
function display_api.update_entities(pos)
|
||||||
for _, objref in pairs(place_entities(pos)) do
|
|
||||||
update_entity(objref:get_luaentity())
|
local node = minetest.get_node(pos)
|
||||||
|
local ndef = minetest.registered_nodes[node.name]
|
||||||
|
local ov = get_orientation_values(node)
|
||||||
|
|
||||||
|
for _, objref in pairs(get_display_objrefs(pos, true)) do
|
||||||
|
local edef = ndef.display_entities[objref:get_luaentity().name]
|
||||||
|
local depth = clip_pos_prop(edef.depth)
|
||||||
|
local right = clip_pos_prop(edef.right)
|
||||||
|
local top = clip_pos_prop(edef.top)
|
||||||
|
|
||||||
|
objref:set_pos({
|
||||||
|
x = pos.x + ov.depth.x*depth + ov.width.x*right - ov.height.x*top,
|
||||||
|
y = pos.y + ov.depth.y*depth + ov.width.y*right - ov.height.y*top,
|
||||||
|
z = pos.z + ov.depth.z*depth + ov.width.z*right - ov.height.z*top,
|
||||||
|
})
|
||||||
|
|
||||||
|
if objref.set_rotation then
|
||||||
|
objref:set_rotation({
|
||||||
|
x = ov.rotation.x*math.pi/2,
|
||||||
|
y = ov.rotation.y*math.pi/2 + (edef.yaw or 0),
|
||||||
|
z = ov.rotation.z*math.pi/2,
|
||||||
|
})
|
||||||
|
else
|
||||||
|
if ov.rotation.x ~=0 or ov.rotation.y ~= 0 then
|
||||||
|
minetest.log("warning", string.format(
|
||||||
|
"[display_api] unable to rotate correctly entity for node at %s without set_rotation method.",
|
||||||
|
minetest.pos_to_string(pos)))
|
||||||
|
end
|
||||||
|
objref:set_yaw(ov.rotation.y*math.pi/2 + (edef.yaw or 0))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Call on_display_update callback of a node for one of its display entities
|
||||||
|
if edef.on_display_update then
|
||||||
|
edef.on_display_update(pos, objref)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -220,7 +208,23 @@ function display_api.on_activate(entity, staticdata)
|
||||||
end
|
end
|
||||||
entity.object:set_armor_groups({immortal=1})
|
entity.object:set_armor_groups({immortal=1})
|
||||||
end
|
end
|
||||||
update_entity(entity)
|
|
||||||
|
if entity.nodepos then
|
||||||
|
local node = minetest.get_node(entity.nodepos)
|
||||||
|
local ndef = minetest.registered_nodes[node.name]
|
||||||
|
if ndef and ndef.display_entities then
|
||||||
|
local edef = ndef.display_entities[entity.name]
|
||||||
|
if edef then
|
||||||
|
-- Call on_display_update callback of the entity to build texture
|
||||||
|
if edef.on_display_update then
|
||||||
|
edef.on_display_update(entity.nodepos, entity.object)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- If we got here, this display entity is buggy and should be removed
|
||||||
|
entity.object:remove()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -235,7 +239,9 @@ function display_api.on_place(itemstack, placer, pointed_thing, override_param2)
|
||||||
z = pointed_thing.under.z - pointed_thing.above.z,
|
z = pointed_thing.under.z - pointed_thing.above.z,
|
||||||
}
|
}
|
||||||
|
|
||||||
if display_api.rotation_restriction then
|
local rotation_restriction = display_api.is_rotation_restricted()
|
||||||
|
|
||||||
|
if rotation_restriction then
|
||||||
-- If item is not placed on a wall, use the player's view direction instead
|
-- If item is not placed on a wall, use the player's view direction instead
|
||||||
if dir.x == 0 and dir.z == 0 then
|
if dir.x == 0 and dir.z == 0 then
|
||||||
dir = placer:get_look_dir()
|
dir = placer:get_look_dir()
|
||||||
|
@ -251,7 +257,7 @@ function display_api.on_place(itemstack, placer, pointed_thing, override_param2)
|
||||||
|
|
||||||
elseif ndef.paramtype2 == "facedir" or
|
elseif ndef.paramtype2 == "facedir" or
|
||||||
ndef.paramtype2 == "colorfacedir" then
|
ndef.paramtype2 == "colorfacedir" then
|
||||||
param2 = minetest.dir_to_facedir(dir, not display_api.rotation_restriction)
|
param2 = minetest.dir_to_facedir(dir, not rotation_restriction)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return minetest.item_place(itemstack, placer, pointed_thing,
|
return minetest.item_place(itemstack, placer, pointed_thing,
|
||||||
|
@ -267,17 +273,20 @@ end
|
||||||
--- On_destruct callback for display_api items.
|
--- On_destruct callback for display_api items.
|
||||||
-- Removes entities.
|
-- Removes entities.
|
||||||
function display_api.on_destruct(pos)
|
function display_api.on_destruct(pos)
|
||||||
for _, objref in pairs(get_entities(pos)) do
|
for _, objref in pairs(get_display_objrefs(pos)) do
|
||||||
objref:remove()
|
objref:remove()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- On_rotate (screwdriver) callback for display_api items. Prevents invalid rotations and reorients entities.
|
-- On_rotate (screwdriver) callback for display_api items. Prevents invalid
|
||||||
|
-- rotations and reorients entities.
|
||||||
function display_api.on_rotate(pos, node, user, _, new_param2)
|
function display_api.on_rotate(pos, node, user, _, new_param2)
|
||||||
|
local ov = get_orientation_values(node)
|
||||||
node.param2 = new_param2
|
node.param2 = new_param2
|
||||||
if get_values(node) then
|
|
||||||
|
if ov.restricted or not display_api.is_rotation_restricted() then
|
||||||
minetest.swap_node(pos, node)
|
minetest.swap_node(pos, node)
|
||||||
place_entities(pos)
|
display_api.update_entities(pos)
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
display_rotation_restriction(Legacy nodes rotation restriction MT<5.0) bool true
|
|
|
@ -91,6 +91,7 @@ end
|
||||||
function signs_api.on_place_direction(itemstack, placer, pointed_thing)
|
function signs_api.on_place_direction(itemstack, placer, pointed_thing)
|
||||||
local name = itemstack:get_name()
|
local name = itemstack:get_name()
|
||||||
local ndef = minetest.registered_nodes[name]
|
local ndef = minetest.registered_nodes[name]
|
||||||
|
local restriction = display_api.is_rotation_restricted()
|
||||||
|
|
||||||
local bdir = {
|
local bdir = {
|
||||||
x = pointed_thing.under.x - pointed_thing.above.x,
|
x = pointed_thing.under.x - pointed_thing.above.x,
|
||||||
|
@ -103,12 +104,12 @@ function signs_api.on_place_direction(itemstack, placer, pointed_thing)
|
||||||
|
|
||||||
if ndef.paramtype2 == "facedir" then
|
if ndef.paramtype2 == "facedir" then
|
||||||
-- If legacy mode, only accept upright nodes
|
-- If legacy mode, only accept upright nodes
|
||||||
if display_api.rotation_restriction and bdir.x == 0 and bdir.z == 0 then
|
if restriction and bdir.x == 0 and bdir.z == 0 then
|
||||||
-- Ceiling or floor pointed (facedir chosen from player dir)
|
-- Ceiling or floor pointed (facedir chosen from player dir)
|
||||||
ndir = minetest.dir_to_facedir({x=pdir.x, y=0, z=pdir.z})
|
ndir = minetest.dir_to_facedir({x=pdir.x, y=0, z=pdir.z})
|
||||||
else
|
else
|
||||||
-- Wall pointed or no rotation restriction
|
-- Wall pointed or no rotation restriction
|
||||||
ndir = minetest.dir_to_facedir(bdir, not display_api.rotation_restriction)
|
ndir = minetest.dir_to_facedir(bdir, not restriction)
|
||||||
end
|
end
|
||||||
|
|
||||||
test = { [0]=-pdir.x, pdir.z, pdir.x, -pdir.z, -pdir.x, [8]=pdir.x }
|
test = { [0]=-pdir.x, pdir.z, pdir.x, -pdir.z, -pdir.x, [8]=pdir.x }
|
||||||
|
@ -117,7 +118,7 @@ function signs_api.on_place_direction(itemstack, placer, pointed_thing)
|
||||||
if ndef.paramtype2 == "wallmounted" then
|
if ndef.paramtype2 == "wallmounted" then
|
||||||
ndir = minetest.dir_to_wallmounted(bdir)
|
ndir = minetest.dir_to_wallmounted(bdir)
|
||||||
-- If legacy mode, only accept upright nodes
|
-- If legacy mode, only accept upright nodes
|
||||||
if display_api.rotation_restriction and (ndir == 0 or ndir == 1) then
|
if restriction and (ndir == 0 or ndir == 1) then
|
||||||
ndir = minetest.dir_to_wallmounted({x=pdir.x, y=0, z=pdir.z})
|
ndir = minetest.dir_to_wallmounted({x=pdir.x, y=0, z=pdir.z})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -166,7 +167,7 @@ end
|
||||||
|
|
||||||
-- Legacy mode with rotation restriction
|
-- Legacy mode with rotation restriction
|
||||||
-- TODO:When MT < 5.0 no more in use, to be removed
|
-- TODO:When MT < 5.0 no more in use, to be removed
|
||||||
if display_api.rotation_restriction then
|
if display_api.is_rotation_restricted() then
|
||||||
signs_api.on_rotate = function(pos, node, player, mode, new_param2)
|
signs_api.on_rotate = function(pos, node, player, mode, new_param2)
|
||||||
-- If rotation mode is 2 and sign is directional, swap direction.
|
-- If rotation mode is 2 and sign is directional, swap direction.
|
||||||
-- Otherwise use display_api's on_rotate function.
|
-- Otherwise use display_api's on_rotate function.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user