summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFaceDeer <derksenmobile@gmail.com>2017-01-15 16:12:07 -0700
committerFaceDeer <derksenmobile@gmail.com>2017-01-15 16:12:07 -0700
commit2078572811a1c80ebd1228b24b35392ba02f4908 (patch)
tree827fbd12195c44530bca91a11ccba1e7a5760735
parent51c5e9b6417b807ea3b7890240bd2ea43e8a297a (diff)
Add crates for packing up, transporting, and unpacking digtron arrays
-rw-r--r--class_layout.lua37
-rw-r--r--crate.lua149
-rw-r--r--init.lua1
-rw-r--r--textures/digtron_crate.pngbin0 -> 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
diff --git a/init.lua b/init.lua
index 94eb79e..e5193bd 100644
--- a/init.lua
+++ b/init.lua
@@ -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
new file mode 100644
index 0000000..bc5f315
--- /dev/null
+++ b/textures/digtron_crate.png
Binary files differ