1
0
mirror of https://github.com/mt-mods/signs_lib.git synced 2025-06-28 22:06:20 +02:00

Compare commits

...

10 Commits

Author SHA1 Message Date
c66c1b70bd disable backface culling on the sign entity
(allows for transparent signs i.e. glass)
2019-09-19 01:02:44 -04:00
831055095c remove debug prints 2019-09-18 20:28:42 -04:00
f0bc18154e fix corner case
Placing a "wallmounted" sign onto a streets lamp would cause a
weird rotation if you're pointing downward too far.  Now it
enforces NESW direction according to your yaw.

Also fixes bad orientation when you're really close to a post.
2019-09-18 20:25:41 -04:00
4eeaf90ae3 allow placement of "facedir" signs flat on floor
(and on ceiling, if hanging isn't available)
mimics the way wallmounted signs behave
2019-09-18 20:12:31 -04:00
906ddbbcc5 rotation fixups
* combine rotation functions -- one no longer needs to choose
  a particular rotation function for the node's paramtype2,
  it'll figure it out automatically.
* fix glitch in wallmounted rotation
* re-order rotation facing order to N, E, S, W, floor, ceiling.
* limit yard sign to simple NESW-only rotation
* allow rotation of hanging signs (NESW only)
* allow rotation of signs on poles/posts if there's nothing in
  the way of where the sign has to move to (NESW only).
2019-09-18 20:07:20 -04:00
01e2adaa46 allow visible text on
floor and when flat on a ceiling
2019-09-18 17:23:07 -04:00
03bd471230 fix a couple of global warnings 2019-09-18 16:33:56 -04:00
e5d525c272 in fact, just bail out if the sign needs no entity 2019-09-18 14:21:56 -04:00
a907f9535c bail out of make_sign_texture is the node is unknown 2019-09-18 14:08:17 -04:00
bbd580acb1 remove debug prints 2019-09-18 13:57:57 -04:00

186
api.lua
View File

@ -63,25 +63,57 @@ signs_lib.wall_fdir_to_back = {
{ 1, 0 }, { 1, 0 },
} }
signs_lib.rotate_facedir = { signs_lib.fdir_to_back_left = {
[0] = 1, [0] = { -1, 1 },
[1] = 6, [1] = { 1, 1 },
[2] = 3, [2] = { 1, -1 },
[3] = 0, [3] = { -1, -1 }
[4] = 2, }
[5] = 6,
[6] = 4 signs_lib.wall_fdir_to_back_left = {
[2] = { 1, 1 },
[3] = { -1, -1 },
[4] = { -1, 1 },
[5] = { 1, -1 }
} }
signs_lib.rotate_walldir = { signs_lib.rotate_walldir = {
[0] = 1, [0] = 4,
[1] = 5, [1] = 0,
[2] = 0, [2] = 5,
[3] = 1,
[4] = 2,
[5] = 3
}
signs_lib.rotate_walldir_simple = {
[0] = 4,
[1] = 4,
[2] = 5,
[3] = 4, [3] = 4,
[4] = 2, [4] = 2,
[5] = 3 [5] = 3
} }
signs_lib.rotate_facedir = {
[0] = 1,
[1] = 2,
[2] = 3,
[3] = 4,
[4] = 6,
[5] = 6,
[6] = 0
}
signs_lib.rotate_facedir_simple = {
[0] = 1,
[1] = 2,
[2] = 3,
[3] = 0,
[4] = 0,
[5] = 0
}
-- Initialize character texture cache -- Initialize character texture cache
local ctexcache = {} local ctexcache = {}
@ -92,11 +124,11 @@ minetest.register_entity("signs_lib:text", {
visual = "mesh", visual = "mesh",
mesh = "signs_lib_standard_wall_sign_entity.obj", mesh = "signs_lib_standard_wall_sign_entity.obj",
textures = {}, textures = {},
static_save = false static_save = false,
backface_culling = false
}) })
function signs_lib.delete_objects(pos) function signs_lib.delete_objects(pos)
print("delete_objects()")
local objects = minetest.get_objects_inside_radius(pos, 0.5) local objects = minetest.get_objects_inside_radius(pos, 0.5)
for _, v in ipairs(objects) do for _, v in ipairs(objects) do
v:remove() v:remove()
@ -104,10 +136,9 @@ function signs_lib.delete_objects(pos)
end end
function signs_lib.spawn_entity(pos, texture) function signs_lib.spawn_entity(pos, texture)
print("spawn_entity()")
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local def = minetest.registered_items[node.name] local def = minetest.registered_items[node.name]
if not def or not def.entity_info or not def.entity_info.yaw[node.param2 + 1] then return end if not def or not def.entity_info then return end
local text_scale = (node and node.text_scale) or signs_lib.default_text_scale local text_scale = (node and node.text_scale) or signs_lib.default_text_scale
local objects = minetest.get_objects_inside_radius(pos, 0.5) local objects = minetest.get_objects_inside_radius(pos, 0.5)
@ -119,7 +150,33 @@ function signs_lib.spawn_entity(pos, texture)
obj = minetest.add_entity(pos, "signs_lib:text") obj = minetest.add_entity(pos, "signs_lib:text")
end end
obj:setyaw(def.entity_info.yaw[node.param2 + 1]) local yaw = def.entity_info.yaw[node.param2 + 1]
local pitch = 0
if not string.find(node.name, "onpole") and not string.find(node.name, "hanging") then
local rot90 = math.pi/2
if def.paramtype2 == "wallmounted" then
if node.param2 == 1 then -- on floor
pitch = -rot90
yaw = 0
elseif node.param2 == 0 then -- on ceiling
pitch = rot90
yaw = math.pi
end
elseif def.paramtype2 == "facedir" then
if node.param2 == 4 then
pitch = -rot90
yaw = 0
elseif node.param2 == 6 then
pitch = rot90
yaw = math.pi
end
end
end
if yaw then
obj:set_rotation({x = pitch, y = yaw, z=0})
if not texture then if not texture then
obj:set_properties({ obj:set_properties({
@ -134,36 +191,54 @@ function signs_lib.spawn_entity(pos, texture)
}) })
end end
end end
end
-- rotation -- rotation
function signs_lib.wallmounted_rotate(pos, node, user, mode) function signs_lib.handle_rotation(pos, node, user, mode)
if not signs_lib.can_modify(pos, user) then return false end if not signs_lib.can_modify(pos, user)
or mode ~= screwdriver.ROTATE_FACE then
if mode ~= screwdriver.ROTATE_FACE or string.match(node.name, "_onpole") then
return false return false
end end
local newparam2
local tpos = pos
local def = minetest.registered_items[node.name]
local newparam2 = signs_lib.rotate_walldir[node.param2] or 0 if string.match(node.name, "_onpole") then
local newparam2 = signs_lib.rotate_walldir_simple[node.param2] or 4
local t = signs_lib.wall_fdir_to_back_left
minetest.swap_node(pos, { name = node.name, param2 = newparam2 }) if def.paramtype2 ~= "wallmounted" then
signs_lib.delete_objects(pos) newparam2 = signs_lib.rotate_facedir_simple[node.param2] or 0
signs_lib.update_sign(pos) t = signs_lib.fdir_to_back_left
return true
end end
function signs_lib.facedir_rotate(pos, node, user, mode) tpos = {
if not signs_lib.can_modify(pos, user) then return false end x = pos.x + t[node.param2][1],
y = pos.y,
z = pos.z + t[node.param2][2]
}
if mode ~= screwdriver.ROTATE_FACE or string.match(node.name, "_onpole") then local node2 = minetest.get_node(tpos)
return false local def2 = minetest.registered_items[node2.name]
if not def2 or not def2.buildable_to then return true end -- undefined, or not buildable_to.
minetest.set_node(tpos, {name = node.name, param2 = newparam2})
minetest.get_meta(tpos):from_table(minetest.get_meta(pos):to_table())
minetest.remove_node(pos)
signs_lib.delete_objects(pos)
elseif string.match(node.name, "_hanging") or string.match(node.name, "yard") then
minetest.swap_node(tpos, { name = node.name, param2 = signs_lib.rotate_facedir_simple[node.param2] or 0 })
elseif minetest.registered_items[node.name].paramtype2 == "wallmounted" then
minetest.swap_node(tpos, { name = node.name, param2 = signs_lib.rotate_walldir[node.param2] or 0 })
else
minetest.swap_node(tpos, { name = node.name, param2 = signs_lib.rotate_facedir[node.param2] or 0 })
end end
local newparam2 = signs_lib.rotate_facedir[node.param2] or 0 signs_lib.delete_objects(tpos)
signs_lib.update_sign(tpos)
minetest.swap_node(pos, { name = node.name, param2 = newparam2 })
signs_lib.delete_objects(pos)
signs_lib.update_sign(pos)
return true return true
end end
@ -421,6 +496,7 @@ end
local function make_sign_texture(lines, pos) local function make_sign_texture(lines, pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local def = minetest.registered_items[node.name] local def = minetest.registered_items[node.name]
if not def or not def.entity_info then return end
local font_size local font_size
local line_width local line_width
@ -465,7 +541,6 @@ function signs_lib.split_lines_and_words(text)
end end
function signs_lib.set_obj_text(pos, text) function signs_lib.set_obj_text(pos, text)
print("set_obj_text()")
local split = signs_lib.split_lines_and_words local split = signs_lib.split_lines_and_words
local text_ansi = Utf8ToAnsi(text) local text_ansi = Utf8ToAnsi(text)
local n = minetest.registered_nodes[minetest.get_node(pos).name] local n = minetest.registered_nodes[minetest.get_node(pos).name]
@ -648,8 +723,15 @@ function signs_lib.check_for_ceiling(pointed_thing)
end end
end end
function signs_lib.check_for_floor(pointed_thing)
if pointed_thing.above.x == pointed_thing.under.x
and pointed_thing.above.z == pointed_thing.under.z
and pointed_thing.above.y > pointed_thing.under.y then
return true
end
end
function signs_lib.after_place_node(pos, placer, itemstack, pointed_thing, locked) function signs_lib.after_place_node(pos, placer, itemstack, pointed_thing, locked)
print("after_place_node")
local playername = placer:get_player_name() local playername = placer:get_player_name()
local def = minetest.registered_items[itemstack:get_name()] local def = minetest.registered_items[itemstack:get_name()]
@ -658,12 +740,23 @@ function signs_lib.after_place_node(pos, placer, itemstack, pointed_thing, locke
local pdef = minetest.registered_items[pnode.name] local pdef = minetest.registered_items[pnode.name]
if (def.allow_onpole ~= false) and signs_lib.check_for_pole(pos, pointed_thing) then if (def.allow_onpole ~= false) and signs_lib.check_for_pole(pos, pointed_thing) then
local newparam2
local lookdir = minetest.yaw_to_dir(placer:get_look_horizontal())
if def.paramtype2 == "wallmounted" then
newparam2 = minetest.dir_to_wallmounted(lookdir)
else
newparam2 = minetest.dir_to_facedir(lookdir)
end
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
minetest.swap_node(pos, {name = itemstack:get_name().."_onpole", param2 = node.param2}) minetest.swap_node(pos, {name = itemstack:get_name().."_onpole", param2 = newparam2})
elseif def.allow_hanging and signs_lib.check_for_ceiling(pointed_thing) then elseif def.allow_hanging and signs_lib.check_for_ceiling(pointed_thing) then
local newparam2 = minetest.dir_to_facedir(placer:get_look_dir()) local newparam2 = minetest.dir_to_facedir(placer:get_look_dir())
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
minetest.swap_node(pos, {name = itemstack:get_name().."_hanging", param2 = newparam2}) minetest.swap_node(pos, {name = itemstack:get_name().."_hanging", param2 = newparam2})
elseif def.paramtype2 == "facedir" and signs_lib.check_for_ceiling(pointed_thing) then
minetest.swap_node(pos, {name = itemstack:get_name(), param2 = 6})
elseif def.paramtype2 == "facedir" and signs_lib.check_for_floor(pointed_thing) then
minetest.swap_node(pos, {name = itemstack:get_name(), param2 = 4})
end end
if locked then if locked then
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
@ -718,16 +811,8 @@ local function register_sign(name, rdef)
def.wield_image = rdef.wield_image or def.inventory_image def.wield_image = rdef.wield_image or def.inventory_image
def.drop = rdef.drop or name def.drop = rdef.drop or name
def.sounds = rdef.sounds or signs_lib.standard_wood_sign_sounds def.sounds = rdef.sounds or signs_lib.standard_wood_sign_sounds
def.on_rotate = rdef.on_rotate or signs_lib.wallmounted_rotate
def.paramtype2 = rdef.paramtype2 or "wallmounted" def.paramtype2 = rdef.paramtype2 or "wallmounted"
def.on_rotate = rdef.on_rotate or signs_lib.handle_rotation
if rdef.on_rotate then
def.on_rotate = rdef.on_rotate
elseif rdef.drawtype == "wallmounted" then
def.on_rotate = signs_lib.wallmounted_rotate
else
def.on_rotate = signs_lib.facedir_rotate
end
if rdef.groups then if rdef.groups then
def.groups = rdef.groups def.groups = rdef.groups
@ -735,7 +820,7 @@ local function register_sign(name, rdef)
def.groups = signs_lib.standard_wood_groups def.groups = signs_lib.standard_wood_groups
end end
local cbox = signs_lib.make_selection_boxes(35, 25, allow_onpole) local cbox = signs_lib.make_selection_boxes(35, 25)
def.selection_box = rdef.selection_box or cbox def.selection_box = rdef.selection_box or cbox
def.node_box = table.copy(rdef.node_box or rdef.selection_box or cbox) def.node_box = table.copy(rdef.node_box or rdef.selection_box or cbox)
@ -776,8 +861,6 @@ local function register_sign(name, rdef)
opdef.groups.not_in_creative_inventory = 1 opdef.groups.not_in_creative_inventory = 1
opdef.tiles[3] = "signs_lib_pole_mount.png" opdef.tiles[3] = "signs_lib_pole_mount.png"
opdef.mesh = string.gsub(opdef.mesh, ".obj$", "_onpole.obj") opdef.mesh = string.gsub(opdef.mesh, ".obj$", "_onpole.obj")
opdef.on_rotate = nil
if opdef.entity_info then if opdef.entity_info then
opdef.entity_info.mesh = string.gsub(opdef.entity_info.mesh, ".obj$", "_onpole.obj") opdef.entity_info.mesh = string.gsub(opdef.entity_info.mesh, ".obj$", "_onpole.obj")
@ -791,7 +874,7 @@ local function register_sign(name, rdef)
local hdef = table.copy(def) local hdef = table.copy(def)
hdef.paramtype2 = "facedir" hdef.paramtype2 = "facedir"
local hcbox = signs_lib.make_selection_boxes(35, 32, false, 0, 3, -18.5, true) local hcbox = signs_lib.make_selection_boxes(35, 32, nil, 0, 3, -18.5, true)
hdef.selection_box = rdef.hanging_selection_box or hcbox hdef.selection_box = rdef.hanging_selection_box or hcbox
hdef.node_box = rdef.hanging_node_box or rdef.hanging_selection_box or hcbox hdef.node_box = rdef.hanging_node_box or rdef.hanging_selection_box or hcbox
@ -799,7 +882,6 @@ local function register_sign(name, rdef)
hdef.groups.not_in_creative_inventory = 1 hdef.groups.not_in_creative_inventory = 1
hdef.tiles[3] = "signs_lib_hangers.png" hdef.tiles[3] = "signs_lib_hangers.png"
hdef.mesh = string.gsub(string.gsub(hdef.mesh, "_facedir.obj", ".obj"), ".obj$", "_hanging.obj") hdef.mesh = string.gsub(string.gsub(hdef.mesh, "_facedir.obj", ".obj"), ".obj$", "_hanging.obj")
hdef.on_rotate = nil
if hdef.entity_info then if hdef.entity_info then
hdef.entity_info.mesh = string.gsub(string.gsub(hdef.entity_info.mesh, "_facedir.obj", ".obj"), ".obj$", "_hanging.obj") hdef.entity_info.mesh = string.gsub(string.gsub(hdef.entity_info.mesh, "_facedir.obj", ".obj"), ".obj$", "_hanging.obj")
@ -855,7 +937,7 @@ function signs_lib.register_sign(name, rdef)
if rdef.allow_widefont then if rdef.allow_widefont then
wdef = table.copy(minetest.registered_items[name]) local wdef = table.copy(minetest.registered_items[name])
wdef.groups.not_in_creative_inventory = 1 wdef.groups.not_in_creative_inventory = 1
wdef.horiz_scaling = wdef.horiz_scaling / 2 wdef.horiz_scaling = wdef.horiz_scaling / 2