commit f83a2d49b27df1e326efa3d9fe2e2541200a26f2 Author: osmal Date: Fri Mar 18 23:09:46 2022 +0100 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..b0eebdb --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +The mod will serve to add various tools mainly for **your-land** server. + +# Chest +Shared with any players who can build at that area. Check [issue #1507](https://gitea.your-land.de/your-land/bugtracker/issues/1507). \ No newline at end of file diff --git a/chest.lua b/chest.lua new file mode 100644 index 0000000..423737c --- /dev/null +++ b/chest.lua @@ -0,0 +1,249 @@ +yl_tools.chest = {} +yl_tools.chest.open_chests = {} + +--[[ Pipeworks Support ]] +if( minetest.get_modpath( 'pipeworks' )) then + local entry = "^pipeworks_tube_connection_wooden.png" + yl_tools.chest.tiles = { + "default_chest_top.png^[colorize:red:100" .. entry, + "default_chest_top.png^[colorize:red:100" .. entry, + "default_chest_side.png^[colorize:red:100" .. entry, + "default_chest_side.png^[colorize:red:100" .. entry, + "default_chest_lock.png^[colorize:red:100", + "default_chest_inside.png" + } + yl_tools.chest.groups = {choppy = 2, oddly_breakable_by_hand = 2, tubedevice = 1, tubedevice_receiver = 1 }; + yl_tools.chest.tube = { + insert_object = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:add_item("main", stack) + end, + can_insert = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:room_for_item("main", stack) + end, + input_inventory = "main", + connect_sides = {left=1, right=1, back=1, bottom=1, top=1} + } +end + + + + +function yl_tools.chest.get_formspec(pos) + local spos = pos.x .. "," .. pos.y .. "," .. pos.z + local formspec = + "size[8,9]" .. + "list[nodemeta:" .. spos .. ";main;0,0.3;8,4;]" .. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6.08;8,3;8]" .. + "listring[nodemeta:" .. spos .. ";main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,4.85) + return formspec +end + +function yl_tools.chest.chest_lid_obstructed(pos) + local above = {x = pos.x, y = pos.y + 1, z = pos.z} + local def = minetest.registered_nodes[minetest.get_node(above).name] + -- allow ladders, signs, wallmounted things and torches to not obstruct + if def and + (def.drawtype == "airlike" or + def.drawtype == "signlike" or + def.drawtype == "torchlike" or + (def.drawtype == "nodebox" and def.paramtype2 == "wallmounted")) then + return false + end + return true +end + +function yl_tools.chest.chest_lid_close(pn) + local chest_open_info = yl_tools.chest.open_chests[pn] + local pos = chest_open_info.pos + local sound = chest_open_info.sound + local swap = chest_open_info.swap + + yl_tools.chest.open_chests[pn] = nil + for k, v in pairs(yl_tools.chest.open_chests) do + if v.pos.x == pos.x and v.pos.y == pos.y and v.pos.z == pos.z then + return true + end + end + + local node = minetest.get_node(pos) + minetest.after(0.2, minetest.swap_node, pos, { name = swap, + param2 = node.param2 }) + minetest.sound_play(sound, {gain = 0.3, pos = pos, + max_hear_distance = 10}, true) +end + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "yl_tools:chest_protected" then + return + end + if not player or not fields.quit then + return + end + local pn = player:get_player_name() + + if not yl_tools.chest.open_chests[pn] then + return + end + + yl_tools.chest.chest_lid_close(pn) + return true +end) + +minetest.register_on_leaveplayer(function(player) + local pn = player:get_player_name() + if yl_tools.chest.open_chests[pn] then + yl_tools.chest.chest_lid_close(pn) + end +end) + +function yl_tools.chest.register_chest(prefixed_name, d) + local name = prefixed_name:sub(1,1) == ':' and prefixed_name:sub(2,-1) or prefixed_name + local def = table.copy(d) + def.drawtype = "mesh" + def.visual = "mesh" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.legacy_facedir_simple = true + def.is_ground_content = false + + if def.protected then + def.on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Protected Chest") + meta:set_string("owner", "") + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + end + def.after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string("owner", placer:get_player_name() or "") + meta:set_string("infotext", "Protected Chest (owned by " .. meta:get_string("owner") .. ")") + end + def.can_dig = function(pos,player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("main") and + yl_tools.can_interact(pos, player) + end + def.allow_metadata_inventory_move = function(pos, from_list, from_index, + to_list, to_index, count, player) + if not yl_tools.can_interact(pos, player) then + return 0 + end + return count + end + def.allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if not yl_tools.can_interact(pos, player) then + return 0 + end + return stack:get_count() + end + def.allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if not yl_tools.can_interact(pos, player) then + return 0 + end + return stack:get_count() + end + def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if not yl_tools.can_interact(pos, clicker) then + return itemstack + end + + minetest.sound_play(def.sound_open, {gain = 0.3, + pos = pos, max_hear_distance = 10}, true) + if not yl_tools.chest.chest_lid_obstructed(pos) then + minetest.swap_node(pos, + { name = name .. "_open", + param2 = node.param2 }) + end + minetest.after(0.1, minetest.show_formspec, + clicker:get_player_name(), + "yl_tools:chest_protected", yl_tools.chest.get_formspec(pos)) + yl_tools.chest.open_chests[clicker:get_player_name()] = { pos = pos, + sound = def.sound_close, swap = name } + end + def.on_blast = function() end + end + + def.on_metadata_inventory_move = function(pos, from_list, from_index, + to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in protected chest at " .. minetest.pos_to_string(pos)) + end + def.on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves " .. stack:get_name() .. + " to protected chest at " .. minetest.pos_to_string(pos)) + end + def.on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes " .. stack:get_name() .. + " from protected chest at " .. minetest.pos_to_string(pos)) + end + + local def_opened = table.copy(def) + local def_closed = table.copy(def) + + def_opened.mesh = "chest_open.obj" + for i = 1, #def_opened.tiles do + if type(def_opened.tiles[i]) == "string" then + def_opened.tiles[i] = {name = def_opened.tiles[i], backface_culling = true} + elseif def_opened.tiles[i].backface_culling == nil then + def_opened.tiles[i].backface_culling = true + end + end + def_opened.drop = name + def_opened.groups.not_in_creative_inventory = 1 + def_opened.selection_box = { + type = "fixed", + fixed = { -1/2, -1/2, -1/2, 1/2, 3/16, 1/2 }, + } + def_opened.can_dig = function() + return false + end + def_opened.on_blast = function() end + + def_closed.mesh = nil + def_closed.drawtype = nil + def_closed.tiles[6] = def.tiles[5] -- swap textures around for "normal" + def_closed.tiles[5] = def.tiles[3] -- drawtype to make them match the mesh + def_closed.tiles[3] = def.tiles[3].."^[transformFX" + + minetest.register_node(prefixed_name, def_closed) + minetest.register_node(prefixed_name .. "_open", def_opened) + +end + +yl_tools.chest.register_chest("yl_tools:chest_protected", { + description = "Protected Chest", + tiles = yl_tools.chest.tiles or { + "default_chest_top.png^[colorize:red:100", + "default_chest_top.png^[colorize:red:100", + "default_chest_side.png^[colorize:red:100", + "default_chest_side.png^[colorize:red:100", + "default_chest_lock.png^[colorize:red:100", + "default_chest_inside.png" + }, + sounds = default.node_sound_wood_defaults(), + sound_open = "default_chest_open", + sound_close = "default_chest_close", + groups = yl_tools.chest.groups or {choppy = 2, oddly_breakable_by_hand = 2}, + tube = yl_tools.chest.tube or {}, + protected = true, +}) + + + +minetest.register_craft({ + output = "yl_tools:chest_protected", + type = "shapeless", + recipe = { "default:mese_crystal_fragment", "default:chest_locked" }, +}) \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..720d707 --- /dev/null +++ b/init.lua @@ -0,0 +1,32 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + +yl_tools = {} + + +function yl_tools.can_interact(pos, player) + if player and player:is_player() then + if minetest.check_player_privs(player, "protection_bypass") then + return true + end + else + return false + end + + local player_name = player:get_player_name() + local meta = minetest.get_meta(pos) + local owner = meta:get_string("owner") + + if not owner or owner == "" or owner == player_name then + return true + end + + if not minetest.is_protected(pos, player_name) then + return true + end + + return false +end + + +dofile(modpath.."/chest.lua") \ No newline at end of file diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..8556943 --- /dev/null +++ b/mod.conf @@ -0,0 +1,5 @@ +name = yl_tools +description = Various Tools. +author = OSMAL +title = YL Tools +depends = default \ No newline at end of file