aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre-Yves Rollo <dev@pyrollo.com>2019-03-14 09:36:41 +0100
committerGitHub <noreply@github.com>2019-03-14 09:36:41 +0100
commit0ca85ac5c18f405df565d89dc92d572d18cbebc5 (patch)
treed7de55aeb3072d86ff93724d36d65ecbfb0b7c9f
parent882af249e00ebe87572abcc0d5ef42bb62622cb7 (diff)
downloaddisplay_modpack_no_craft-0ca85ac5c18f405df565d89dc92d572d18cbebc5.tar.gz
display_modpack_no_craft-0ca85ac5c18f405df565d89dc92d572d18cbebc5.zip
Detect rotation restriction (#29)
Autodetect rotation restrictions if on MT<5.0
-rw-r--r--README.md9
-rw-r--r--display_api/API.md1
-rw-r--r--display_api/README.md8
-rw-r--r--display_api/display.lua247
-rw-r--r--display_api/settingtypes.txt1
-rw-r--r--signs_api/README.md4
-rw-r--r--signs_api/init.lua9
7 files changed, 147 insertions, 132 deletions
diff --git a/README.md b/README.md
index 5839d10..c37a469 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,5 @@
# Display Modpack
-Version 1.3
-
-**Important**: If using Minetest 5 and above, disable `display_rotation_restriction` in settings and enjoy rotation of display nodes in every direction!
+Version 1.3.1
This modpack provides mods with dynamic display. Mods are :
@@ -40,10 +38,13 @@ Following objects are deprecated, shows a warning in log when used:
These objects will be removed in the future.
## Changelog
+### 2019-03-14 (Version 1.3.1)
+- __dispay_api__: Display API now detects automatically whenr rotation restrictions have to be applied.
+- __sign_api__: Screwdriver behavior changed. Now, left click rotates and changes direction.
### 2019-03-09 (Version 1.3)
- __display_api__: Display nodes can be rotated in every directions (if running Minetest 5 or above).
-- __display_api__: New setting to restrict rotations to Minetest 0.4 abilities (**restriction enabled by default**).
+- __display_api__: New setting to restrict rotations to Minetest 0.4 abilities (restriction enabled by default).
- __sign_api__: Changed behavior of screwdriver if no rotation restriction.
### 2018-12-14 (Version 1.2.3)
diff --git a/display_api/API.md b/display_api/API.md
index e69ae60..acfd867 100644
--- a/display_api/API.md
+++ b/display_api/API.md
@@ -14,6 +14,7 @@ This method triggers entities update for the display node at pos. Actual entity
This is a helper to register entities used for display.
`entity_name`: Name of the entity to register.
+
## Provided callback implementations
### on_place
**display\_api.on\_place(itemstack, placer, pointed\_thing)**
diff --git a/display_api/README.md b/display_api/README.md
index a0f0f6e..73acdf9 100644
--- a/display_api/README.md
+++ b/display_api/README.md
@@ -2,9 +2,7 @@
This library's purpose is to ease creation of nodes with one or more displays on sides. For example, signs and clocks. Display can be dynamic and/or different for each node instance.
-**Limitations**: This lib uses entities to draw display. This means display has to be vertical (and "upside up") on Minetest before version 5.0. This restriction can be set in settings.
-
-**Settings**: `display_rotation_restriction` should be set to false if using Minetest 5.0 and above, true otherwise.
+**Limitations**: This lib uses entities to draw display. This means display has to be vertical (and "upside up") on Minetest before version 5.0.
**Dependancies**:default
@@ -25,10 +23,12 @@ Following objects are deprecated, shows a warning in log when used:
These objects will be removed in the future.
## Change log
+### 2019-03-14
+- __dispay_api__: Display API now detects automatically whenr rotation restrictions have to be applied.
### 2019-03-09
- __display_api__: Display nodes can be rotated in every directions (if running Minetest 5 or above).
-- __display_api__: New setting to restrict rotations to Minetest 0.4 abilities (**restriction enabled by default**).
+- __display_api__: New setting to restrict rotations to Minetest 0.4 abilities (restriction enabled by default).
### 2018-12-14
- __display_api__: New `yaw` attributes, entities can now have different angles with node.
diff --git a/display_api/display.lua b/display_api/display.lua
index 3ed1f02..2fed40f 100644
--- a/display_api/display.lua
+++ b/display_api/display.lua
@@ -22,51 +22,29 @@
-- variable as spacing between entity and node
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
local max_entity_pos = 1.5
-local wallmounted_rotations, facedir_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},
- [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},
- [ 4]={x=3, y=0, z=0}, [ 5]={x=0, y=3, z=3},
- [ 6]={x=1, y=0, z=2}, [ 7]={x=0, y=1, z=1},
- [ 8]={x=1, y=0, z=0}, [ 9]={x=0, y=3, z=1},
- [10]={x=3, y=0, z=2}, [11]={x=0, y=1, z=3},
- [12]={x=0, y=0, z=1}, [13]={x=3, y=0, z=1},
- [14]={x=2, y=0, z=1}, [15]={x=1, y=0, z=1},
- [16]={x=0, y=0, z=3}, [17]={x=1, y=0, z=3},
- [18]={x=2, y=0, z=3}, [19]={x=3, y=0, z=3},
- [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},
- }
-end
+local wallmounted_rotations = {
+ [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},
+ [4]={x=0, y=0, z=0}, [5]={x=0, y=2, z=0},
+}
+
+local 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},
+ [ 4]={x=3, y=0, z=0}, [ 5]={x=0, y=3, z=3},
+ [ 6]={x=1, y=0, z=2}, [ 7]={x=0, y=1, z=1},
+ [ 8]={x=1, y=0, z=0}, [ 9]={x=0, y=3, z=1},
+ [10]={x=3, y=0, z=2}, [11]={x=0, y=1, z=3},
+ [12]={x=0, y=0, z=1}, [13]={x=3, y=0, z=1},
+ [14]={x=2, y=0, z=1}, [15]={x=1, y=0, z=1},
+ [16]={x=0, y=0, z=3}, [17]={x=1, y=0, z=3},
+ [18]={x=2, y=0, z=3}, [19]={x=3, y=0, z=3},
+ [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},
+}
-- Compute other useful values depending on wallmounted and facedir param
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.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
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)
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]
if ndef then
@@ -106,12 +117,17 @@ local function get_values(node)
return wallmounted_values[node.param2 % 8]
elseif paramtype2 == "facedir" or paramtype2 == "colorfacedir" then
return facedir_values[node.param2 % 32]
+ else
+ -- No orientation or unknown orientation type
+ return facedir_values[0]
end
end
end
---- Gets the display entities attached with a node. Removes extra ones
-local function get_entities(pos)
+-- Gets the display entities attached with a node.
+-- Add missing and remove duplicates
+
+local function get_display_objrefs(pos, create)
local objrefs = {}
local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
if ndef and ndef.display_entities then
@@ -127,85 +143,57 @@ local function get_entities(pos)
end
end
end
+ if create then
+ -- Add missing
+ for name, _ in pairs(ndef.display_entities) do
+ if not objrefs[name] then
+ objrefs[name] = minetest.add_entity(pos, name,
+ minetest.serialize({ nodepos = pos }))
+ end
+ end
+ end
end
return objrefs
end
-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
+--- Force entity update : position and texture
+function display_api.update_entities(pos)
---- (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 }))
- end
+ 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,
+ })
- 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 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,
})
-
- 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(v.rotation.y*math.pi/2 + (props.yaw or 0))
+ 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
- end
- return objrefs
-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
- 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)
- for _, objref in pairs(place_entities(pos)) do
- update_entity(objref:get_luaentity())
+ if edef.on_display_update then
+ edef.on_display_update(pos, objref)
+ end
end
end
@@ -220,7 +208,23 @@ function display_api.on_activate(entity, staticdata)
end
entity.object:set_armor_groups({immortal=1})
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
@@ -235,7 +239,9 @@ function display_api.on_place(itemstack, placer, pointed_thing, override_param2)
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 dir.x == 0 and dir.z == 0 then
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
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
return minetest.item_place(itemstack, placer, pointed_thing,
@@ -267,17 +273,20 @@ end
--- On_destruct callback for display_api items.
-- Removes entities.
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()
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)
node.param2 = new_param2
- if get_values(node) then
+ local ov = get_orientation_values(node)
+
+ if ov.restricted or not display_api.is_rotation_restricted() then
minetest.swap_node(pos, node)
- place_entities(pos)
+ display_api.update_entities(pos)
return true
else
return false
diff --git a/display_api/settingtypes.txt b/display_api/settingtypes.txt
deleted file mode 100644
index 58a0108..0000000
--- a/display_api/settingtypes.txt
+++ /dev/null
@@ -1 +0,0 @@
-display_rotation_restriction(Legacy nodes rotation restriction MT<5.0) bool true
diff --git a/signs_api/README.md b/signs_api/README.md
index 99ff20a..38e8d96 100644
--- a/signs_api/README.md
+++ b/signs_api/README.md
@@ -27,3 +27,7 @@ Handles screwdriver rotation. Direction is affected for direction signs.
### `signs_api.register_sign(mod, name, model)`
A method to quickly register signs.
+
+## Changelog
+### 2019-03-14
+- __sign_api__: Screwdriver behavior changed. Now, left click rotates and changes direction.
diff --git a/signs_api/init.lua b/signs_api/init.lua
index 4b20486..1bd00d6 100644
--- a/signs_api/init.lua
+++ b/signs_api/init.lua
@@ -91,6 +91,7 @@ end
function signs_api.on_place_direction(itemstack, placer, pointed_thing)
local name = itemstack:get_name()
local ndef = minetest.registered_nodes[name]
+ local restriction = display_api.is_rotation_restricted()
local bdir = {
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 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)
ndir = minetest.dir_to_facedir({x=pdir.x, y=0, z=pdir.z})
else
-- 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
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
ndir = minetest.dir_to_wallmounted(bdir)
-- 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})
end
@@ -166,7 +167,7 @@ end
-- Legacy mode with rotation restriction
-- 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)
-- If rotation mode is 2 and sign is directional, swap direction.
-- Otherwise use display_api's on_rotate function.