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  | 
