From c5a9d9fff984359a01dc474723fc1f940e2b5d04 Mon Sep 17 00:00:00 2001 From: FaceDeer Date: Tue, 24 Oct 2017 21:25:46 -0600 Subject: [PATCH] add locked Digtron crate --- nodes/node_crate.lua | 408 +++++++++++++++++++++++++------------- nodes/recipes.lua | 12 ++ textures/digtron_lock.png | Bin 0 -> 288 bytes 3 files changed, 281 insertions(+), 139 deletions(-) create mode 100644 textures/digtron_lock.png diff --git a/nodes/node_crate.lua b/nodes/node_crate.lua index b0a5741..4073993 100644 --- a/nodes/node_crate.lua +++ b/nodes/node_crate.lua @@ -4,68 +4,138 @@ local S, NS = dofile(MP.."/intllib.lua") local modpath_awards = minetest.get_modpath("awards") + +local player_permitted = function(pos, player) + if player then + if minetest.check_player_privs(player, "protection_bypass") then + return true + end + else + return false + end + + local meta = minetest.get_meta(pos) + local owner = meta:get_string("owner") + + if not owner or owner == "" or owner == player:get_player_name() then + return true + end +end + +local store_digtron = function(pos, clicker, loaded_node_name, protected) + local layout = DigtronLayout.create(pos, clicker) + local protection_prefix = "" + local protection_suffix = "" + if protected then + protection_prefix = S("Digtron Crate") .. "\n" .. S("Owned by @1", clicker:get_player_name() or "") + protection_suffix = S("Owned by @1", clicker:get_player_name() or "") + end + + if layout.contains_protected_node then + local meta = minetest.get_meta(pos) + minetest.sound_play("buzzer", {gain=0.5, pos=pos}) + meta:set_string("infotext", protection_prefix .. "\n" .. S("Digtron can't be packaged, it contains protected blocks")) + -- no stealing other peoples' digtrons + return + end + + if #layout.all == 1 then + local meta = minetest.get_meta(pos) + minetest.sound_play("buzzer", {gain=0.5, pos=pos}) + meta:set_string("infotext", protection_prefix .. "\n" .. S("No Digtron components adjacent to package")) + return + end + + digtron.award_crate(layout, clicker:get_player_name()) + + local layout_string = layout:serialize() + + -- destroy everything. Note that this includes the empty crate, which will be bundled up with the layout. + for _, node_image in pairs(layout.all) do + local old_pos = node_image.pos + local old_node = node_image.node + minetest.remove_node(old_pos) + + if modpath_awards then + -- We're about to tell the awards mod that we're digging a node, but we + -- don't want it to count toward any actual awards. Pre-decrement. + local data = awards.players[clicker:get_player_name()] + awards.increment_item_counter(data, "count", old_node.name, -1) + end + + for _, callback in ipairs(minetest.registered_on_dignodes) do + -- Copy pos and node because callback can modify them + local pos_copy = {x=old_pos.x, y=old_pos.y, z=old_pos.z} + local oldnode_copy = {name=old_node.name, param1=old_node.param1, param2=old_node.param2} + callback(pos_copy, oldnode_copy, clicker) + end + end + + -- Create the loaded crate node + minetest.set_node(pos, {name=loaded_node_name}) + minetest.sound_play("machine1", {gain=1.0, pos=pos}) + + local meta = minetest.get_meta(pos) + meta:set_string("crated_layout", layout_string) + meta:set_string("title", S("Crated Digtron")) + meta:set_string("infotext", S("Crated Digtron") .. "\n" .. protection_suffix) +end + minetest.register_node("digtron:empty_crate", { description = S("Digtron Crate (Empty)"), _doc_items_longdesc = digtron.doc.empty_crate_longdesc, _doc_items_usagehelp = digtron.doc.empty_crate_usagehelp, groups = {cracky = 3, oddly_breakable_by_hand=3}, - drop = "digtron:empty_crate", sounds = default.node_sound_wood_defaults(), tiles = {"digtron_crate.png"}, is_ground_content = false, drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + }, paramtype = "light", on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - local layout = DigtronLayout.create(pos, clicker) - if layout.contains_protected_node then - local meta = minetest.get_meta(pos) - minetest.sound_play("buzzer", {gain=0.5, pos=pos}) - meta:set_string("infotext", S("Digtron can't be packaged, it contains protected blocks")) - -- no stealing other peoples' digtrons - return - end - - if #layout.all == 1 then - local meta = minetest.get_meta(pos) - minetest.sound_play("buzzer", {gain=0.5, pos=pos}) - meta:set_string("infotext", S("No Digtron components adjacent to package")) - return - end + store_digtron(pos, clicker, "digtron:loaded_crate") + end +}) - digtron.award_crate(layout, clicker:get_player_name()) - - local layout_string = layout:serialize() - - -- destroy everything. Note that this includes the empty crate, which will be bundled up with the layout. - for _, node_image in pairs(layout.all) do - local old_pos = node_image.pos - local old_node = node_image.node - minetest.remove_node(old_pos) - - if modpath_awards then - -- We're about to tell the awards mod that we're digging a node, but we - -- don't want it to count toward any actual awards. Pre-decrement. - local data = awards.players[clicker:get_player_name()] - awards.increment_item_counter(data, "count", old_node.name, -1) - end - - for _, callback in ipairs(minetest.registered_on_dignodes) do - -- Copy pos and node because callback can modify them - local pos_copy = {x=old_pos.x, y=old_pos.y, z=old_pos.z} - local oldnode_copy = {name=old_node.name, param1=old_node.param1, param2=old_node.param2} - callback(pos_copy, oldnode_copy, clicker) - end - end - - -- Create the loaded crate node - minetest.set_node(pos, {name="digtron:loaded_crate", param1=node.param1, param2=node.param2}) - minetest.sound_play("machine1", {gain=1.0, pos=pos}) - +minetest.register_node("digtron:empty_locked_crate", { + description = S("Digtron Locked Crate (Empty)"), + _doc_items_longdesc = digtron.doc.empty_locked_crate_longdesc, + _doc_items_usagehelp = digtron.doc.empty_locked_crate_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand=3}, + sounds = default.node_sound_wood_defaults(), + tiles = {"digtron_crate.png","digtron_crate.png","digtron_crate.png^digtron_lock.png","digtron_crate.png^digtron_lock.png","digtron_crate.png^digtron_lock.png","digtron_crate.png^digtron_lock.png"}, + is_ground_content = false, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + }, + paramtype = "light", + on_construct = function(pos) local meta = minetest.get_meta(pos) - meta:set_string("crated_layout", layout_string) - meta:set_string("title", S("Crated Digtron")) - meta:set_string("infotext", S("Crated Digtron")) + meta:set_string("owner", "") + meta:set_string("infotext", "") + end, + 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", S("Digtron Crate") .. "\n" .. S("Owned by @1", placer:get_player_name() or "")) + end, + can_dig = function(pos,player) + return player_permitted(pos,player) + end, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if player_permitted(pos,clicker) then + store_digtron(pos, clicker, "digtron:loaded_locked_crate", true) + end end, }) @@ -101,11 +171,110 @@ else "tooltip[unpack;" .. S("Attempts to unpack the Digtron on this location") .. "]" end - local loaded_formspec = function(pos, meta) return loaded_formspec_string end +local loaded_on_recieve = function(pos, fields, sender, protected) + local meta = minetest.get_meta(pos) + + if fields.unpack or fields.save or fields.show or fields.key_enter then + meta:set_string("title", minetest.formspec_escape(fields.title)) + end + local title = meta:get_string("title") + + if protected then + infotext = title .. "\n" .. S("Owned by @1", sender:get_player_name()) + else + infotext = title + end + meta:set_string("infotext", infotext) + + if fields.help and minetest.get_modpath("doc") then --check for mod in case someone disabled it after this digger was built + minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", "digtron:loaded_crate", true) + end + + if not (fields.unpack or fields.show) then + return + end + + local layout_string = meta:get_string("crated_layout") + local layout = DigtronLayout.deserialize(layout_string) + + if layout == nil then + meta:set_string("infotext", infotext .. "\n" .. S("Unable to read layout from crate metadata, regrettably this Digtron may be corrupted.")) + minetest.sound_play("buzzer", {gain=0.5, pos=pos}) + -- Something went horribly wrong + return + end + + local protected_node = false + local obstructed_node = false + + local pos_diff = vector.subtract(pos, layout.controller) + layout.controller = pos + for _, node_image in pairs(layout.all) do + node_image.pos = vector.add(pos_diff, node_image.pos) + if not vector.equals(pos, node_image.pos) then + if minetest.is_protected(node_image.pos, sender:get_player_name()) and not minetest.check_player_privs(sender, "protection_bypass") then + protected_node = true + minetest.add_entity(node_image.pos, "digtron:marker_crate_bad") + elseif not minetest.registered_nodes[minetest.get_node(node_image.pos).name].buildable_to then + obstructed_node = true + minetest.add_entity(node_image.pos, "digtron:marker_crate_bad") + else + minetest.add_entity(node_image.pos, "digtron:marker_crate_good") + end + end + end + + if not fields.unpack then + return + end + + if protected_node then + meta:set_string("infotext", infotext .. "\n" .. S("Unable to deploy Digtron due to protected blocks in target area")) + minetest.sound_play("buzzer", {gain=0.5, pos=pos}) + return + end + + if obstructed_node then + meta:set_string("infotext", infotext .. "\n" .. S("Unable to deploy Digtron due to obstruction in target area")) + minetest.sound_play("buzzer", {gain=0.5, pos=pos}) + return + end + + -- build digtron. Since the empty crate was included in the layout, that will overwrite this loaded crate and destroy it. + minetest.sound_play("machine2", {gain=1.0, pos=pos}) + layout:write_layout_image(sender) +end + +local loaded_on_dig = function(pos, player, loaded_node_name) + local meta = minetest.get_meta(pos) + local to_serialize = {title=meta:get_string("title"), layout=meta:get_string("crated_layout")} + + local stack = ItemStack({name=loaded_node_name, count=1, wear=0, metadata=minetest.serialize(to_serialize)}) + local inv = player:get_inventory() + local stack = inv:add_item("main", stack) + if stack:get_count() > 0 then + minetest.add_item(pos, stack) + end + -- call on_dignodes callback + minetest.remove_node(pos) +end + +local loaded_after_place = function(pos, itemstack) + local deserialized = minetest.deserialize(itemstack:get_metadata()) + if deserialized then + local meta = minetest.get_meta(pos) + + meta:set_string("crated_layout", deserialized.layout) + meta:set_string("title", deserialized.title) + meta:set_string("infotext", deserialized.title) + --meta:set_string("formspec", loaded_formspec(pos, meta)) -- not needed, on_construct handles this + end +end + minetest.register_node("digtron:loaded_crate", { description = S("Digtron Crate (Loaded)"), _doc_items_longdesc = digtron.doc.loaded_crate_longdesc, @@ -123,102 +292,63 @@ minetest.register_node("digtron:loaded_crate", { end, on_receive_fields = function(pos, formname, fields, sender) - local meta = minetest.get_meta(pos) - - if fields.unpack or fields.save or fields.show then - meta:set_string("title", fields.title) - meta:set_string("infotext", fields.title) - end - - if fields.help and minetest.get_modpath("doc") then --check for mod in case someone disabled it after this digger was built - minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", "digtron:loaded_crate", true) - end - - if not (fields.unpack or fields.show) then - return - end - - local layout_string = meta:get_string("crated_layout") - local layout = DigtronLayout.deserialize(layout_string) - - if layout == nil then - meta:set_string("infotext", meta:get_string("title") .. "\n" .. S("Unable to read layout from crate metadata, regrettably this Digtron may be corrupted or lost.")) - minetest.sound_play("buzzer", {gain=0.5, pos=pos}) - -- Something went horribly wrong - return - end - - local protected_node = false - local obstructed_node = false - - local pos_diff = vector.subtract(pos, layout.controller) - layout.controller = pos - for _, node_image in pairs(layout.all) do - node_image.pos = vector.add(pos_diff, node_image.pos) - if not vector.equals(pos, node_image.pos) then - if minetest.is_protected(node_image.pos, sender:get_player_name()) and not minetest.check_player_privs(sender, "protection_bypass") then - protected_node = true - minetest.add_entity(node_image.pos, "digtron:marker_crate_bad") - elseif not minetest.registered_nodes[minetest.get_node(node_image.pos).name].buildable_to then - obstructed_node = true - minetest.add_entity(node_image.pos, "digtron:marker_crate_bad") - else - minetest.add_entity(node_image.pos, "digtron:marker_crate_good") - end - end - end - - if not fields.unpack then - return - end - - if protected_node then - meta:set_string("infotext", meta:get_string("title") .. "\n" .. S("Unable to deploy Digtron due to protected blocks in target area")) - minetest.sound_play("buzzer", {gain=0.5, pos=pos}) - return - end - - if obstructed_node then - meta:set_string("infotext", meta:get_string("title") .. "\n" .. S("Unable to deploy Digtron due to obstruction in target area")) - minetest.sound_play("buzzer", {gain=0.5, pos=pos}) - return - end - - -- build digtron. Since the empty crate was included in the layout, that will overwrite this loaded crate and destroy it. - minetest.sound_play("machine2", {gain=1.0, pos=pos}) - layout:write_layout_image(sender) + return loaded_on_recieve(pos, fields, sender) end, on_dig = function(pos, node, player) + return loaded_on_dig(pos, player, "digtron:loaded_crate") + end, + after_place_node = function(pos, placer, itemstack, pointed_thing) + loaded_after_place(pos, itemstack) + end, +}) + +minetest.register_node("digtron:loaded_locked_crate", { + description = S("Digtron Locked Crate (Loaded)"), + _doc_items_longdesc = digtron.doc.loaded_locked_crate_longdesc, + _doc_items_usagehelp = digtron.doc.loaded_locked_crate_usagehelp, + groups = {cracky = 3, oddly_breakable_by_hand=3, not_in_creative_inventory=1, digtron_protected=1}, + stack_max = 1, + sounds = default.node_sound_wood_defaults(), + tiles = {"digtron_plate.png^digtron_crate.png","digtron_plate.png^digtron_crate.png","digtron_plate.png^digtron_crate.png^digtron_lock.png","digtron_plate.png^digtron_crate.png^digtron_lock.png","digtron_plate.png^digtron_crate.png^digtron_lock.png","digtron_plate.png^digtron_crate.png^digtron_lock.png"}, + is_ground_content = false, + + on_construct = function(pos) local meta = minetest.get_meta(pos) - local to_serialize = {title=meta:get_string("title"), layout=meta:get_string("crated_layout")} - - local stack = ItemStack({name="digtron:loaded_crate", count=1, wear=0, metadata=minetest.serialize(to_serialize)}) - local inv = player:get_inventory() - local stack = inv:add_item("main", stack) - if stack:get_count() > 0 then - minetest.add_item(pos, stack) - end - -- call on_dignodes callback - minetest.remove_node(pos) + meta:set_string("owner", "") end, - on_place = function(itemstack, placer, pointed_thing) - local pos = minetest.get_pointed_thing_position(pointed_thing, true) - local deserialized = minetest.deserialize(itemstack:get_metadata()) - if pos and deserialized then - minetest.set_node(pos, {name="digtron:loaded_crate"}) - local meta = minetest.get_meta(pos) - - meta:set_string("crated_layout", deserialized.layout) - meta:set_string("title", deserialized.title) - meta:set_string("infotext", deserialized.title) - --meta:set_string("formspec", loaded_formspec(pos, meta)) -- not needed, on_construct handles this - - itemstack:take_item(1) - return itemstack + on_dig = function(pos, node, player) + if player_permitted(pos,player) then + return loaded_on_dig(pos, player, "digtron:loaded_locked_crate") + else + return false end - -- after-place callbacks end, -}) \ No newline at end of file + + after_place_node = function(pos, placer, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + meta:set_string("owner", placer:get_player_name() or "") + loaded_after_place(pos, itemstack) + meta:set_string("infotext", meta:get_string("infotext") .. "\n" .. S("Owned by @1", meta:get_string("owner"))) + end, + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if player_permitted(pos,clicker) then + local meta = minetest.get_meta(pos) + minetest.show_formspec( + clicker:get_player_name(), + "digtron:loaded_locked_crate"..minetest.pos_to_string(pos), + loaded_formspec_string:gsub("${title}", meta:get_string("title"), 1)) + end + end, +}) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname:sub(1, 27) == "digtron:loaded_locked_crate" then + local pos = minetest.string_to_pos(formname:sub(28, -1)) + loaded_on_recieve(pos, fields, player, true) + return true + end +end) \ No newline at end of file diff --git a/nodes/recipes.lua b/nodes/recipes.lua index baef07f..313c4a9 100644 --- a/nodes/recipes.lua +++ b/nodes/recipes.lua @@ -147,6 +147,18 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = "digtron:empty_locked_crate", + type = "shapeless", + recipe = {"default:steel_ingot", "digtron:empty_crate"}, +}) + +minetest.register_craft({ + output = "digtron:empty_crate", + type = "shapeless", + recipe = {"digtron:empty_locked_crate"}, +}) + minetest.register_craft({ output = "digtron:duplicator", recipe = { diff --git a/textures/digtron_lock.png b/textures/digtron_lock.png new file mode 100644 index 0000000000000000000000000000000000000000..c382950ad9072d15ef559cc74b68b8489f001642 GIT binary patch literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=DinK$vl=HlH+5kiEpy*OmPtmn5@Y&#E3a;Uk{@}WO>S94w*S|O*Uzlk`tO?j+~R%a2@cQiurVmIFx@ye z>)XuR63h%N2NrHLanNkNXYH}*+OBB_Bc#`EozF8(K=7DEq}RfZ59@=g-p>qr^!dv5 ZJ&bX!I{)@$a|MDN>gnp|vd$@?2>?lZXZrvE literal 0 HcmV?d00001