diff options
author | FaceDeer <derksenmobile@gmail.com> | 2017-01-15 16:12:07 -0700 |
---|---|---|
committer | FaceDeer <derksenmobile@gmail.com> | 2017-01-15 16:12:07 -0700 |
commit | 2078572811a1c80ebd1228b24b35392ba02f4908 (patch) | |
tree | 827fbd12195c44530bca91a11ccba1e7a5760735 | |
parent | 51c5e9b6417b807ea3b7890240bd2ea43e8a297a (diff) |
Add crates for packing up, transporting, and unpacking digtron arrays
-rw-r--r-- | class_layout.lua | 37 | ||||
-rw-r--r-- | crate.lua | 149 | ||||
-rw-r--r-- | init.lua | 1 | ||||
-rw-r--r-- | textures/digtron_crate.png | bin | 0 -> 951 bytes |
4 files changed, 185 insertions, 2 deletions
diff --git a/class_layout.lua b/class_layout.lua index 3b3b739..135cfff 100644 --- a/class_layout.lua +++ b/class_layout.lua @@ -25,7 +25,7 @@ end function DigtronLayout.create(pos, player) local self = {} - setmetatable(self,DigtronLayout) + setmetatable(self, DigtronLayout) --initialize. We're assuming that the start position is a controller digtron, should be a safe assumption since only the controller node should call this self.traction = 0 @@ -314,7 +314,7 @@ function DigtronLayout.write_layout_image(self, player) -- create the new one for k, node_image in pairs(self.all) do - minetest.add_node(node_image.pos, node_image.node) + minetest.set_node(node_image.pos, node_image.node) minetest.get_meta(node_image.pos):from_table(node_image.meta) minetest.log("action", string.format("%s adds Digtron component %s at (%d, %d, %d)", player:get_player_name(), node_image.node.name, node_image.pos.x, node_image.pos.y, node_image.pos.z)) @@ -324,3 +324,36 @@ function DigtronLayout.write_layout_image(self, player) end end end + + +--------------------------------------------------------------------------------------------- +-- Serialization. Currently only serializes the data that is needed by the crate, upgrade this function if more is needed + +function DigtronLayout.serialize(self) + -- serialize can't handle ItemStack objects, convert them to strings. + for _, node_image in pairs(self.all) do + for k, inv in pairs(node_image.meta.inventory) do + for index, item in pairs(inv) do + inv[index] = item:to_string() + end + end + end + + return minetest.serialize({controller=self.controller, all=self.all}) +end + +function DigtronLayout.deserialize(layout_string) + local self = {} + setmetatable(self, DigtronLayout) + + if not layout_string or layout_string == "" then + return nil + end + deserialized_layout = minetest.deserialize(layout_string) + + self.all = deserialized_layout.all + self.controller = deserialized_layout.controller + self.old_pos_pointset = Pointset.create() -- needed by the write_layout method, leave empty + + return self +end
\ No newline at end of file diff --git a/crate.lua b/crate.lua new file mode 100644 index 0000000..5606971 --- /dev/null +++ b/crate.lua @@ -0,0 +1,149 @@ +minetest.register_craft({ + output = "digtron:empty_crate", + recipe = { + {"","default:chest",""}, + {"","digtron:digtron_core",""}, + {"","default:mese",""} + } +}) + +minetest.register_node("digtron:empty_crate", { + description = "Empty Digtron Crate", + 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", + 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", "Digtron can't be packaged, it contains protected nodes") + -- no stealing other peoples' digtrons + return + end + + 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 + minetest.remove_node(node_image.pos) + end + + -- Create the loaded crate node + minetest.set_node(pos, {name="digtron:loaded_crate", param1=node.param1, param2=node.param2}) + + local meta = minetest.get_meta(pos) + meta:set_string("crated_layout", layout_string) + meta:set_string("title", "Crated Digtron") + meta:set_string("infotext", "Crated Digtron") + end, +}) + +local loaded_formspec = "size[4,1.5]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "field[0.3,0.5;4,0.5;title;Digtron Name;${title}]" .. + "button_exit[0.5,1.2;1,0.1;save;Save Title]" .. + "tooltip[save;Saves the title of this Digtron]" .. + "button_exit[2.5,1.2;1,0.1;unpack;Unpack]" .. + "tooltip[unpack;Attempts to unpack the Digtron on this location]" + +minetest.register_node("digtron:loaded_crate", { + description = "Loaded Digtron Crate", + groups = {cracky = 3, oddly_breakable_by_hand=3, not_in_creative_inventory=1, digtron=1}, + stack_max = 1, + sounds = default.node_sound_wood_defaults(), + tiles = {"digtron_plate.png^digtron_crate.png"}, + is_ground_content = false, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", loaded_formspec) + end, + + on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + + if fields.unpack or fields.save then + meta:set_string("title", fields.title) + meta:set_string("infotext", fields.title) + end + + if not fields.unpack 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") .. "\nUnable 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 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 minetest.is_protected(node_image.pos, sender:get_player_name()) and not minetest.check_player_privs(sender, "protection_bypass") then + meta:set_string("infotext", meta:get_string("title") .. "\nUnable to deploy Digtron due to protected nodes in target area") + minetest.sound_play("buzzer", {gain=0.5, pos=pos}) + return + end + + if not minetest.registered_nodes[minetest.get_node(node_image.pos).name].buildable_to + and not vector.equals(layout.controller, node_image.pos) then + meta:set_string("infotext", meta:get_string("title") .. "\nUnable to deploy Digtron due to obstruction in target area") + minetest.sound_play("buzzer", {gain=0.5, pos=pos}) + return + end + end + + -- build digtron. Since the empty crate was included in the layout, that will overwrite this loaded crate and destroy it. + if layout then + layout:write_layout_image(sender) + end + end, + + on_dig = function(pos, node, player) + + 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) + 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) + + itemstack:take_item(1) + return itemstack + end + -- after-place callbacks + end, +})
\ No newline at end of file @@ -8,6 +8,7 @@ dofile( minetest.get_modpath( "digtron" ) .. "/node_diggers.lua" ) -- contains a dofile( minetest.get_modpath( "digtron" ) .. "/node_builders.lua" ) -- contains all builders (there's just one currently) dofile( minetest.get_modpath( "digtron" ) .. "/node_controllers.lua" ) -- controllers dofile( minetest.get_modpath( "digtron" ) .. "/node_axle.lua" ) -- Rotation controller +dofile( minetest.get_modpath( "digtron" ) .. "/crate.lua" ) -- Digtron portability support dofile( minetest.get_modpath( "digtron" ) .. "/recipes.lua" ) digtron.creative_mode = false -- this causes digtrons to operate without consuming fuel or building materials. diff --git a/textures/digtron_crate.png b/textures/digtron_crate.png Binary files differnew file mode 100644 index 0000000..bc5f315 --- /dev/null +++ b/textures/digtron_crate.png |