X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=api.lua;h=c6ee2eb7057e9f172e88d331e5eb5b8cd113f5ee;hb=dfece5275ef289d9f1da4a0b5a74c4811709a5c2;hp=0e659d62d2ccf22d32191561e89f7e5fa9e10708;hpb=01e2adaa46c7ea58cd25ef15a0a64a6a6784d413;p=signs_lib.git diff --git a/api.lua b/api.lua index 0e659d6..c6ee2eb 100644 --- a/api.lua +++ b/api.lua @@ -63,23 +63,88 @@ signs_lib.wall_fdir_to_back = { { 1, 0 }, } +signs_lib.fdir_flip_to_back = { + [0] = { 0, 2 }, + [1] = { 2, 0 }, + [2] = { 0, -2 }, + [3] = { -2, 0 } +} + +signs_lib.wall_fdir_flip_to_back = { + [2] = { 2, 0 }, + [3] = { -2, 0 }, + [4] = { 0, 2 }, + [5] = { 0, -2 }, +} + +signs_lib.fdir_to_back_left = { + [0] = { -1, 1 }, + [1] = { 1, 1 }, + [2] = { 1, -1 }, + [3] = { -1, -1 } +} + +signs_lib.wall_fdir_to_back_left = { + [2] = { 1, 1 }, + [3] = { -1, -1 }, + [4] = { -1, 1 }, + [5] = { 1, -1 } +} + +signs_lib.rotate_walldir = { + [0] = 4, + [1] = 0, + [2] = 5, + [3] = 1, + [4] = 2, + [5] = 3 +} + +signs_lib.rotate_walldir_simple = { + [0] = 4, + [1] = 4, + [2] = 5, + [3] = 4, + [4] = 2, + [5] = 3 +} + signs_lib.rotate_facedir = { [0] = 1, - [1] = 6, + [1] = 2, [2] = 3, - [3] = 0, - [4] = 2, + [3] = 4, + [4] = 6, [5] = 6, - [6] = 4 + [6] = 0 } -signs_lib.rotate_walldir = { +signs_lib.rotate_facedir_simple = { [0] = 1, - [1] = 5, + [1] = 2, + [2] = 3, + [3] = 0, + [4] = 0, + [5] = 0 +} + +signs_lib.flip_facedir = { + [0] = 2, + [1] = 3, [2] = 0, - [3] = 4, - [4] = 2, - [5] = 3 + [3] = 1, + [4] = 6, + [5] = 4, + [6] = 4 +} + +signs_lib.flip_walldir = { + [0] = 1, + [1] = 0, + [2] = 3, + [3] = 2, + [4] = 5, + [5] = 4 } -- Initialize character texture cache @@ -92,7 +157,8 @@ minetest.register_entity("signs_lib:text", { visual = "mesh", mesh = "signs_lib_standard_wall_sign_entity.obj", textures = {}, - static_save = false + static_save = false, + backface_culling = false }) function signs_lib.delete_objects(pos) @@ -162,33 +228,64 @@ end -- rotation -function signs_lib.wallmounted_rotate(pos, node, user, mode) - if not signs_lib.can_modify(pos, user) then return false end - - if mode ~= screwdriver.ROTATE_FACE or string.match(node.name, "_onpole") then +function signs_lib.handle_rotation(pos, node, user, mode) + if not signs_lib.can_modify(pos, user) + or mode ~= screwdriver.ROTATE_FACE then return false 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 + if not string.match(node.name, "_horiz") then + 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 }) - signs_lib.delete_objects(pos) - signs_lib.update_sign(pos) - return true -end + if def.paramtype2 ~= "wallmounted" then + newparam2 = signs_lib.rotate_facedir_simple[node.param2] or 0 + t = signs_lib.fdir_to_back_left + end -function signs_lib.facedir_rotate(pos, node, user, mode) - if not signs_lib.can_modify(pos, user) then return false end + tpos = { + x = pos.x + t[node.param2][1], + y = pos.y, + z = pos.z + t[node.param2][2] + } + else + -- flip the sign to the other side of the horizontal pole + newparam2 = signs_lib.flip_walldir[node.param2] or 4 + local t = signs_lib.wall_fdir_flip_to_back - if mode ~= screwdriver.ROTATE_FACE or string.match(node.name, "_onpole") then - return false - end + if def.paramtype2 ~= "wallmounted" then + newparam2 = signs_lib.flip_facedir[node.param2] or 0 + t = signs_lib.fdir_flip_to_back + end - local newparam2 = signs_lib.rotate_facedir[node.param2] or 0 + tpos = { + x = pos.x + t[node.param2][1], + y = pos.y, + z = pos.z + t[node.param2][2] + } + end + local node2 = minetest.get_node(tpos) + 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 - minetest.swap_node(pos, { name = node.name, param2 = newparam2 }) - signs_lib.delete_objects(pos) - signs_lib.update_sign(pos) + signs_lib.delete_objects(tpos) + signs_lib.update_sign(tpos) return true end @@ -501,7 +598,11 @@ end local function make_widefont_nodename(name) if string.find(name, "_widefont") then return name end if string.find(name, "_onpole") then - return string.gsub(name, "_onpole", "_widefont_onpole") + if string.find(name, "_horiz") then + return string.gsub(name, "_onpole_horiz", "_widefont_onpole_horiz") + else + return string.gsub(name, "_onpole", "_widefont_onpole") + end elseif string.find(name, "_hanging") then return string.gsub(name, "_hanging", "_widefont_hanging") else @@ -651,20 +752,46 @@ function signs_lib.check_for_pole(pos, pointed_thing) local pdef = minetest.registered_items[pnode.name] if (signs_lib.allowed_poles[pnode.name] - or (pdef and pdef.drawtype == "fencelike") - or string.find(pnode.name, "default:fence_") - or string.find(pnode.name, "_post") - or string.find(pnode.name, "fencepost") - or string.find(pnode.name, "streets:streetlamp_basic_top") - or (pnode.name == "streets:bigpole" and pnode.param2 < 4) - or (pnode.name == "streets:bigpole" and pnode.param2 > 19 and pnode.param2 < 24) - ) - and - (pos.x ~= ppos.x or pos.z ~= ppos.z) then + or (pdef and pdef.drawtype == "fencelike") + or string.find(pnode.name, "default:fence_") + or string.find(pnode.name, "_post") + or string.find(pnode.name, "fencepost") + or string.find(pnode.name, "streets:streetlamp_basic_top") + or (pnode.name == "streets:bigpole" and pnode.param2 < 4) + or (pnode.name == "streets:bigpole" and pnode.param2 > 19 and pnode.param2 < 24) ) + and (pos.x ~= ppos.x or pos.z ~= ppos.z) then return true end end +function signs_lib.check_for_horizontal_pole(pos, pointed_thing) + local node = minetest.get_node(pos) + local def = minetest.registered_items[node.name] + local ppos = minetest.get_pointed_thing_position(pointed_thing) + local pnode = minetest.get_node(ppos) + if pnode.name == "streets:bigpole" and pnode.param2 > 3 and pnode.param2 < 12 then + if def.paramtype2 == "wallmounted" then + if node.param2 == 2 or node.param2 == 3 -- E/W + then return true + end + else + if node.param2 == 1 or node.param2 == 3 -- E/W + then return true + end + end + elseif pnode.name == "streets:bigpole" and pnode.param2 > 11 and pnode.param2 < 20 then + if def.paramtype2 == "wallmounted" then + if node.param2 == 4 or node.param2 == 5 then + return true + end + else + if node.param2 == 0 or node.param2 == 2 then + return true + end + end + end +end + function signs_lib.check_for_ceiling(pointed_thing) if pointed_thing.above.x == pointed_thing.under.x and pointed_thing.above.z == pointed_thing.under.z @@ -673,6 +800,14 @@ function signs_lib.check_for_ceiling(pointed_thing) 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) local playername = placer:get_player_name() local def = minetest.registered_items[itemstack:get_name()] @@ -680,14 +815,34 @@ function signs_lib.after_place_node(pos, placer, itemstack, pointed_thing, locke local ppos = minetest.get_pointed_thing_position(pointed_thing) local pnode = minetest.get_node(ppos) 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 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) - 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_onpole_horizontal and signs_lib.check_for_horizontal_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) + minetest.swap_node(pos, {name = itemstack:get_name().."_onpole_horiz", param2 = newparam2}) elseif def.allow_hanging and signs_lib.check_for_ceiling(pointed_thing) then local newparam2 = minetest.dir_to_facedir(placer:get_look_dir()) local node = minetest.get_node(pos) 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 if locked then local meta = minetest.get_meta(pos) @@ -742,16 +897,8 @@ local function register_sign(name, rdef) def.wield_image = rdef.wield_image or def.inventory_image def.drop = rdef.drop or name 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" - - 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 + def.on_rotate = rdef.on_rotate or signs_lib.handle_rotation if rdef.groups then def.groups = rdef.groups @@ -771,9 +918,9 @@ local function register_sign(name, rdef) minetest.register_node(":"..name, def) table.insert(signs_lib.lbm_restore_nodes, name) - if rdef.allow_onpole ~= false then + local opdef = table.copy(def) - local opdef = table.copy(def) + if rdef.allow_onpole or rdef.allow_onpole_horizontal then local offset = 0.3125 if opdef.uses_slim_pole_mount then @@ -798,18 +945,32 @@ local function register_sign(name, rdef) end opdef.groups.not_in_creative_inventory = 1 - opdef.tiles[3] = "signs_lib_pole_mount.png" opdef.mesh = string.gsub(opdef.mesh, ".obj$", "_onpole.obj") - opdef.on_rotate = nil - if opdef.entity_info then opdef.entity_info.mesh = string.gsub(opdef.entity_info.mesh, ".obj$", "_onpole.obj") end + end + + -- setting one of item 3 or 4 to a texture and leaving the other "blank", + -- reveals either the vertical or horizontal pole mount part of the model + + if rdef.allow_onpole then + opdef.tiles[3] = "signs_lib_pole_mount.png" + opdef.tiles[4] = "signs_lib_blank.png" minetest.register_node(":"..name.."_onpole", opdef) table.insert(signs_lib.lbm_restore_nodes, name.."_onpole") end + local ophdef = table.copy(opdef) + + if rdef.allow_onpole_horizontal then + ophdef.tiles[3] = "signs_lib_blank.png" + ophdef.tiles[4] = "signs_lib_pole_mount.png" + minetest.register_node(":"..name.."_onpole_horiz", ophdef) + table.insert(signs_lib.lbm_restore_nodes, name.."_onpole_horiz") + end + if rdef.allow_hanging then local hdef = table.copy(def) @@ -823,7 +984,6 @@ local function register_sign(name, rdef) hdef.groups.not_in_creative_inventory = 1 hdef.tiles[3] = "signs_lib_hangers.png" hdef.mesh = string.gsub(string.gsub(hdef.mesh, "_facedir.obj", ".obj"), ".obj$", "_hanging.obj") - hdef.on_rotate = nil if hdef.entity_info then hdef.entity_info.mesh = string.gsub(string.gsub(hdef.entity_info.mesh, "_facedir.obj", ".obj"), ".obj$", "_hanging.obj") @@ -861,8 +1021,15 @@ signs_lib.register_sign("foo:my_cool_sign", { * default def assumes a wallmounted sign with on-pole being allowed. -*For signs that can't support onpole, include in the def: - allow_onpole = false, +*For signs that can support being on a pole, include in the def: + allow_onpole = true, + (defaults to disabled) + +*For signs that can support being on a horizontal pole, include in the def: + allow_onpole_horizontal = true, + (defaults to disabled) + +* onpole/onpole_horizontal are independent; one may be allowed without the other * "standard" entity info implies the standard wood/steel sign model, in wallmounted mode. For facedir signs using the standard model, use: