incrementaltp: respect physics overrides
[waspsaliva.git] / clientmods / dragonfire / schematicas / init.lua
blob29e5d45396ec4dee263ef128caa86edb229fbba5
1 local autoeat = rawget(_G, "autoeat") or {}
2 local storage = minetest.get_mod_storage()
3 local pos1, pos2
4 local min, max = math.min, math.max
5 local building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks
7 minetest.register_chatcommand("pos1", {
8 description = "Set schematicas position 1 at your current location",
9 func = function()
10 pos1 = vector.round(minetest.localplayer:get_pos())
11 return true, "Position 1 set to " .. minetest.pos_to_string(pos1)
12 end
15 minetest.register_chatcommand("pos2", {
16 description = "Set schematicas position 2 at your current location",
17 func = function()
18 pos2 = vector.round(minetest.localplayer:get_pos())
19 return true, "Position 2 set to " .. minetest.pos_to_string(pos2)
20 end
24 minetest.register_chatcommand("schemesave", {
25 description = "Save a schematica",
26 param = "<name>",
27 func = function(name)
28 if not pos1 or not pos2 then
29 return false, "Position 1 or 2 not set."
30 end
32 local data = {}
34 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)
36 for x = lx, hx do
37 local rx = x - lx
38 for y = ly, hy do
39 local ry = y - ly
40 for z = lz, hz do
41 local rz = z - lz
42 local node = minetest.get_node_or_nil({x = x, y = y, z = z})
43 if node and node.name ~= "air" then
44 table.insert(data, {pos = {x = rx, y = ry, z = rz}, node = node.name})
45 end
46 end
47 end
48 end
50 storage:set_string(name, minetest.serialize(data))
51 return true, "Scheme saved successfully as '" .. name .. "'."
52 end
55 minetest.register_chatcommand("schemebuild", {
56 description = "Build a schematica",
57 param = "<name>",
58 func = function(name)
59 if not pos1 then
60 return false, "Position 1 not set."
61 end
62 if building then
63 return false, "Still building a scheme. Use .schemeabort to stop it."
64 end
65 local rawdata = storage:get(name)
66 if not rawdata then
67 return false, "Schematica '" .. name .. "' not found."
68 end
69 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
70 end
73 minetest.register_chatcommand("schemerecipe", {
74 description = "Print the recipe for a schematica",
75 param = "<name>",
76 func = function(name)
77 local rawdata = storage:get(name)
78 if not rawdata then
79 return false, "Schematica '" .. name .. "' not found."
80 end
81 local data = minetest.deserialize(rawdata)
82 local sorted = {}
83 for _, d in ipairs(data) do
85 end
86 end
89 minetest.register_chatcommand("schemeresume", {
90 description = "Resume constructing a schematica",
91 func = function()
92 if not build_data then
93 return false, "Currently not building a scheme."
94 end
95 building, out_of_blocks = true, false
96 return true, "Resumed."
97 end
100 minetest.register_chatcommand("schemepause", {
101 description = "Pause constructing a schematica",
102 func = function()
103 if not build_data then
104 return false, "Currently not building a scheme."
106 building = false
107 return true, "Paused."
111 minetest.register_chatcommand("schemeabort", {
112 description = "Abort constructing a schematica",
113 param = "<name>",
114 func = function()
115 if not build_data then
116 return false, "Currently not building a scheme."
118 building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nilw
119 return true, "Aborted."
123 minetest.register_chatcommand("schemeskip", {
124 description = "Skip a step in constructing a schematica",
125 param = "<name>",
126 func = function()
127 if not build_data then
128 return false, "Currently not building a scheme."
130 building, build_index = true, build_index + 1
131 return true, "Skipped."
135 minetest.register_chatcommand("schemegetindex", {
136 description = "Output the build index of the schematica",
137 func = function()
138 return build_index and true or false, build_index
142 minetest.register_chatcommand("schemesetindex", {
143 description = "Set the build index of the schematica",
144 param = "<index>",
145 func = function(param)
146 local index = tonumber(param)
147 if not index then return false, "Invalid usage." end
148 build_index = index
149 return true, "Index Changed"
153 minetest.register_globalstep(function()
154 if building and not autoeat.eating then
155 local data = build_data[build_index]
156 if not data then
157 building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nil
158 minetest.display_chat_message("Completed Schematica.")
159 return
161 local pos, node = vector.add(build_pos, data.pos), data.node
162 if just_placed_node then
163 local map_node = minetest.get_node_or_nil(pos)
164 if map_node and map_node.name == node then
165 build_index = build_index + 1
166 just_placed_node = false
167 else
168 failed_count = failed_count + 1
170 if failed_count < 10 then
171 return
174 failed_count = 0
175 local new_index
176 local inventory = minetest.get_inventory("current_player").main
177 for index, stack in ipairs(inventory) do
178 if minetest.get_item_def(stack:get_name()).node_placement_prediction == node then
179 new_index = index - 1
180 break
183 if not new_index then
184 if not out_of_blocks then
185 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.")
186 minetest.send_chat_message("[Schematicas] Missing ressource: " .. node)
188 out_of_blocks = true
189 return
191 if out_of_blocks then
192 minetest.send_chat_message("[Schematicas] Resuming.")
194 out_of_blocks = false
195 minetest.localplayer:set_wield_index(new_index)
196 minetest.localplayer:set_pos(minetest.find_node_near(pos, 5, {"air", "ignore", "mcl_core:water_source", "mcl_core:water_flowing"}, false) or pos)
197 minetest.place_node(pos)
198 just_placed_node = true
199 if build_index % 250 == 0 then
200 minetest.send_chat_message("[Schematicas] " .. build_index .. " of " .. #build_data .. " blocks placed!")
203 end)