205 lines
5.9 KiB
Lua
Raw Normal View History

2020-10-04 10:50:07 +02:00
local autoeat = rawget(_G, "autoeat") or {}
2020-08-24 19:49:42 +02:00
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
2020-10-04 10:50:07 +02:00
building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nilw
2020-08-24 19:49:42 +02:00
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()
2020-10-04 10:50:07 +02:00
if building and not autoeat.eating then
2020-08-24 19:49:42 +02:00
local data = build_data[build_index]
if not data then
2020-10-04 10:50:07 +02:00
building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nil
2020-08-24 19:49:42 +02:00
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 - 1
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.")
2020-10-04 10:50:07 +02:00
minetest.send_chat_message("[Schematicas] Missing ressource: " .. node)
2020-08-24 19:49:42 +02:00
end
out_of_blocks = true
return
end
2020-10-04 10:50:07 +02:00
if out_of_blocks then
minetest.send_chat_message("[Schematicas] Resuming.")
end
2020-08-24 19:49:42 +02:00
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
2020-10-04 10:50:07 +02:00
if build_index % 250 == 0 then
minetest.send_chat_message("[Schematicas] " .. build_index .. " of " .. #build_data .. " blocks placed!")
end
2020-08-24 19:49:42 +02:00
end
end)