]> git.lizzy.rs Git - schematicas.git/commitdiff
Initial Commit
authorElias Fleckenstein <eliasfleckenstein@web.de>
Wed, 21 Oct 2020 16:58:55 +0000 (18:58 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Wed, 21 Oct 2020 16:58:55 +0000 (18:58 +0200)
init.lua [new file with mode: 0644]
mod.conf [new file with mode: 0644]

diff --git a/init.lua b/init.lua
new file mode 100644 (file)
index 0000000..fb249c1
--- /dev/null
+++ b/init.lua
@@ -0,0 +1,202 @@
+local storage = minetest.get_mod_storage()
+local pos1, pos2
+local min, max = math.min, math.max
+local building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks
+
+minetest.register_chatcommand("pos1", {
+       description = "Set schematicas position 1 at your current location",
+       func = function()
+               pos1 = vector.round(minetest.localplayer:get_pos())
+               return true, "Position 1 set to " .. minetest.pos_to_string(pos1)
+       end
+})
+
+minetest.register_chatcommand("pos2", {
+       description = "Set schematicas position 2 at your current location",
+       func = function()
+               pos2 = vector.round(minetest.localplayer:get_pos())
+               return true, "Position 2 set to " .. minetest.pos_to_string(pos2)
+       end
+})
+
+
+minetest.register_chatcommand("schemesave", {
+       description = "Save a schematica",
+       param = "<name>",
+       func = function(name)
+               if not pos1 or not pos2 then
+                       return false, "Position 1 or 2 not set."
+               end
+               
+               local data = {}
+               
+               local lx, ly, lz, hx, hy, hz = min(pos1.x, pos2.x), min(pos1.y, pos2.y), min(pos1.z, pos2.z), max(pos1.x, pos2.x), max(pos1.y, pos2.y), max(pos1.z, pos2.z)
+
+               for x = lx, hx do
+                       local rx = x - lx
+                       for y = ly, hy do
+                               local ry = y - ly
+                               for z = lz, hz do
+                                       local rz = z - lz
+                                       local node = minetest.get_node_or_nil({x = x, y = y, z = z})
+                                       if node and node.name ~= "air" then
+                                               table.insert(data, {pos = {x = rx, y = ry, z = rz}, node = node.name})
+                                       end
+                               end
+                       end
+               end
+               
+               storage:set_string(name, minetest.serialize(data))
+               return true, "Scheme saved successfully as '" .. name .. "'."
+       end
+})
+
+minetest.register_chatcommand("schemebuild", {
+       description = "Build a schematica",
+       param = "<name>",
+       func = function(name)
+               if not pos1 then
+                       return false, "Position 1 not set."
+               end
+               if building then
+                       return false, "Still building a scheme. Use .schemeabort to stop it."
+               end
+               local rawdata = storage:get(name)
+               if not rawdata then
+                       return false, "Schematica '" .. name .. "' not found."
+               end
+               building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks  = true, 1, minetest.deserialize(rawdata), vector.new(pos1), false, 0, false
+       end
+})
+
+minetest.register_chatcommand("schemerecipe", {
+       description = "Print the recipe for a schematica",
+       param = "<name>",
+       func = function(name)
+               local rawdata = storage:get(name)
+               if not rawdata then
+                       return false, "Schematica '" .. name .. "' not found."
+               end
+               local data = minetest.deserialize(rawdata)
+               local sorted = {}
+               for _, d in ipairs(data) do
+               end
+       end
+})
+
+minetest.register_chatcommand("schemeresume", {
+       description = "Resume constructing a schematica",
+       func = function()
+               if not build_data then
+                       return false, "Currently not building a scheme."
+               end
+               building, out_of_blocks = true, false
+               return true, "Resumed."
+       end
+})
+
+minetest.register_chatcommand("schemepause", {
+       description = "Pause constructing a schematica",
+       func = function()
+               if not build_data then
+                       return false, "Currently not building a scheme."
+               end
+               building = false
+               return true, "Paused."
+       end
+})
+
+minetest.register_chatcommand("schemeabort", {
+       description = "Abort constructing a schematica",
+       param = "<name>",
+       func = function()
+               if not build_data then
+                       return false, "Currently not building a scheme."
+               end
+               building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nilw
+               return true, "Aborted."
+       end
+})
+
+minetest.register_chatcommand("schemeskip", {
+       description = "Skip a step in constructing a schematica",
+       param = "<name>",
+       func = function()
+               if not build_data then
+                       return false, "Currently not building a scheme."
+               end
+               building, build_index = true, build_index + 1
+               return true, "Skipped."
+       end
+})
+
+minetest.register_chatcommand("schemegetindex", {
+       description = "Output the build index of the schematica",
+       func = function()
+               return build_index and true or false, build_index
+       end
+})
+
+minetest.register_chatcommand("schemesetindex", {
+       description = "Set the build index of the schematica",
+       param = "<index>",
+       func = function(param)
+               local index = tonumber(param)
+               if not index then return false, "Invalid usage." end
+               build_index = index
+               return true, "Index Changed"
+       end
+})
+
+minetest.register_globalstep(function()
+       if building then
+               local data = build_data[build_index]
+               if not data then
+                       building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nil
+                       minetest.display_chat_message("Completed Schematica.")
+                       return
+               end
+               local pos, node = vector.add(build_pos, data.pos), data.node
+               if just_placed_node then
+                       local map_node = minetest.get_node_or_nil(pos)
+                       if map_node and map_node.name == node then
+                               build_index = build_index + 1
+                               just_placed_node = false
+                       else
+                               failed_count = failed_count + 1
+                       end
+                       if failed_count < 10 then
+                               return
+                       end
+               end
+               failed_count = 0
+               local new_index
+               local inventory = minetest.get_inventory("current_player").main
+               for index, stack in ipairs(inventory) do
+                       if minetest.get_item_def(stack:get_name()).node_placement_prediction == node then
+                               new_index = index
+                               break
+                       end
+               end
+               if not new_index then
+                       if not out_of_blocks then
+                               minetest.display_chat_message("Out of blocks for schematica. Missing ressource: '" .. node .. "'. It will resume as soon as you got it or use .schemeskip to skip it.")
+                               minetest.send_chat_message("[Schematicas] Missing ressource: " .. node)
+                       end
+                       out_of_blocks = true
+                       return
+               end
+               if out_of_blocks then
+                       minetest.send_chat_message("[Schematicas] Resuming.")
+               end
+               out_of_blocks = false
+               minetest.localplayer:set_wield_index(new_index)
+               minetest.localplayer:set_pos(minetest.find_node_near(pos, 5, {"air", "ignore", "mcl_core:water_source", "mcl_core:water_flowing"}, false) or pos)
+               minetest.place_node(pos)
+               just_placed_node = true
+               if build_index % 250 == 0 then
+                       minetest.send_chat_message("[Schematicas] " .. build_index .. " of " .. #build_data .. " blocks placed!")
+               end
+       end
+end)
+
diff --git a/mod.conf b/mod.conf
new file mode 100644 (file)
index 0000000..92eda80
--- /dev/null
+++ b/mod.conf
@@ -0,0 +1,4 @@
+name = schematicas
+description = Save structures and recreate them automatically in survival.
+author = Fleckenstein
+optional_depends = autoeat