From: Elias Fleckenstein Date: Wed, 21 Oct 2020 16:58:55 +0000 (+0200) Subject: Initial Commit X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=aea3ecdd7dcb0649dd9e24a86c40ab51a098e192;p=schematicas.git Initial Commit --- aea3ecdd7dcb0649dd9e24a86c40ab51a098e192 diff --git a/init.lua b/init.lua new file mode 100644 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 = "", + 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 = "", + 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 = "", + 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 = "", + 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 = "", + 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 = "", + 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 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