]> git.lizzy.rs Git - schematicas.git/blob - init.lua
Update Description
[schematicas.git] / init.lua
1 local storage = minetest.get_mod_storage()
2 local pos1, pos2
3 local min, max = math.min, math.max
4 local building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks, last_good_block
5
6 minetest.register_chatcommand("pos1", {
7         description = "Set schematicas position 1 at your current location",
8         func = function()
9                 pos1 = vector.round(minetest.localplayer:get_pos())
10                 return true, "Position 1 set to " .. minetest.pos_to_string(pos1)
11         end
12 })
13
14 minetest.register_chatcommand("pos2", {
15         description = "Set schematicas position 2 at your current location",
16         func = function()
17                 pos2 = vector.round(minetest.localplayer:get_pos())
18                 return true, "Position 2 set to " .. minetest.pos_to_string(pos2)
19         end
20 })
21
22
23 minetest.register_chatcommand("schemesave", {
24         description = "Save a schematica",
25         param = "<name>",
26         func = function(name)
27                 if not pos1 or not pos2 then
28                         return false, "Position 1 or 2 not set."
29                 end
30                 
31                 local data = {}
32                 
33                 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)
34
35                 for x = lx, hx do
36                         local rx = x - lx
37                         for y = ly, hy do
38                                 local ry = y - ly
39                                 for z = lz, hz do
40                                         local rz = z - lz
41                                         local node = minetest.get_node_or_nil({x = x, y = y, z = z})
42                                         if node and node.name ~= "air" then
43                                                 table.insert(data, {pos = {x = rx, y = ry, z = rz}, node = node.name})
44                                         end
45                                 end
46                         end
47                 end
48                 
49                 storage:set_string(name, minetest.serialize(data))
50                 return true, "Scheme saved successfully as '" .. name .. "'."
51         end
52 })
53
54 minetest.register_chatcommand("schemebuild", {
55         description = "Build a schematica",
56         param = "<name>",
57         func = function(name)
58                 if not pos1 then
59                         return false, "Position 1 not set."
60                 end
61                 if building then
62                         return false, "Still building a scheme. Use .schemeabort to stop it."
63                 end
64                 local rawdata = storage:get(name)
65                 if not rawdata then
66                         return false, "Schematica '" .. name .. "' not found."
67                 end
68                 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
69         end
70 })
71
72 minetest.register_chatcommand("schemerecipe", {
73         description = "Print the recipe for a schematica",
74         param = "<name>",
75         func = function(name)
76                 local rawdata = storage:get(name)
77                 if not rawdata then
78                         return false, "Schematica '" .. name .. "' not found."
79                 end
80                 local data = minetest.deserialize(rawdata)
81                 local sorted = {}
82                 for _, d in ipairs(data) do
83                 end
84         end
85 })
86
87 minetest.register_chatcommand("schemeresume", {
88         description = "Resume constructing a schematica",
89         func = function()
90                 if not build_data then
91                         return false, "Currently not building a scheme."
92                 end
93                 building, out_of_blocks = true, false
94                 return true, "Resumed."
95         end
96 })
97
98 minetest.register_chatcommand("schemepause", {
99         description = "Pause constructing a schematica",
100         func = function()
101                 if not build_data then
102                         return false, "Currently not building a scheme."
103                 end
104                 building = false
105                 return true, "Paused."
106         end
107 })
108
109 minetest.register_chatcommand("schemeabort", {
110         description = "Abort constructing a schematica",
111         param = "<name>",
112         func = function()
113                 if not build_data then
114                         return false, "Currently not building a scheme."
115                 end
116                 building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nilw
117                 return true, "Aborted."
118         end
119 })
120
121 minetest.register_chatcommand("schemeskip", {
122         description = "Skip a step in constructing a schematica",
123         param = "<name>",
124         func = function()
125                 if not build_data then
126                         return false, "Currently not building a scheme."
127                 end
128                 building, build_index = true, build_index + 1
129                 return true, "Skipped."
130         end
131 })
132
133 minetest.register_chatcommand("schemegetindex", {
134         description = "Output the build index of the schematica",
135         func = function()
136                 return build_index and true or false, build_index
137         end
138 })
139
140 minetest.register_chatcommand("schemesetindex", {
141         description = "Set the build index of the schematica",
142         param = "<index>",
143         func = function(param)
144                 local index = tonumber(param)
145                 if not index then return false, "Invalid usage." end
146                 build_index = index
147                 last_good_block = index
148                 return true, "Index Changed"
149         end
150 })
151
152 local function step()
153         if building then
154                 local data = build_data[build_index]
155                 if not data then
156                         building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nil
157                         minetest.display_chat_message("Completed Schematica.")
158                         return
159                 end
160                 local pos, node = vector.add(build_pos, data.pos), data.node
161                 if just_placed_node then
162                         just_placed_node = false
163                         local map_node = minetest.get_node_or_nil(pos)
164                         if map_node and map_node.name == node or build_index % 50 == 0 then
165                                 local lgb = last_good_block or 0
166                                 if lgb < build_index - 1 then
167                                         build_index = lgb + 1
168                                 else
169                                         if map_node and map_node.name == node then
170                                                 last_good_block = build_index
171                                                 build_index = build_index + 1
172                                                 just_placed_node = true
173                                                 step()
174                                         end
175                                 end
176                                 return                  
177                         else
178                                 failed_count = failed_count + 1
179                         end
180                         if reliable and failed_count < 10 then
181                                 return 
182                         end
183                         if not reliable and not map_node then
184                                 return
185                         end
186                         build_index = build_index + 1
187                 end
188                 failed_count = 0
189                 local new_index
190                 local inventory = minetest.get_inventory("current_player").main
191                 for index, stack in ipairs(inventory) do
192                         if minetest.get_item_def(stack:get_name()).node_placement_prediction == node then
193                                 new_index = index
194                                 break
195                         end
196                 end
197                 if not new_index then
198                         if not out_of_blocks then
199                                 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.")
200                                 minetest.send_chat_message("[Schematicas] Missing ressource: " .. node)
201                         end
202                         out_of_blocks = true
203                         return
204                 end
205                 if out_of_blocks then
206                         minetest.send_chat_message("[Schematicas] Resuming.")
207                 end
208                 out_of_blocks = false
209                 minetest.localplayer:set_wield_index(new_index)
210                 minetest.localplayer:set_pos(minetest.find_node_near(pos, 5, {"air", "ignore", "mcl_core:water_source", "mcl_core:water_flowing"}, false) or pos)
211                 minetest.place_node(pos)
212                 just_placed_node = true
213                 if build_index % 500 == 0 then
214                         minetest.send_chat_message("[Schematicas] " .. build_index .. " of " .. #build_data .. " blocks placed!")
215                 end
216         end
217 end
218
219 minetest.register_globalstep(step)
220