Nova licença
[gestor/gestor2.git] / estruturador.lua
blob799c36a0704f3fac5f6ee2748c8cc3c4981f962b
1 --
2 -- Mod gestor
3 --
4 -- Estruturador
5 --
7 -- Diretorio do Mod
8 local modpath = minetest.get_modpath("gestor")
10 -- Variavel global de estruturador
11 gestor.estruturador = {}
14 -- Arredondar posicao
15 local arredondar = function(pos)
16 local r = {}
17 if pos.x > (math.floor(pos.x)+0.5) then
18 r.x = math.ceil(pos.x)
19 else
20 r.x = math.floor(pos.x)
21 end
22 if pos.y > (math.floor(pos.y)+0.5) then
23 r.y = math.ceil(pos.y)
24 else
25 r.y = math.floor(pos.y)
26 end
27 if pos.z > (math.floor(pos.z)+0.5) then
28 r.z = math.ceil(pos.z)
29 else
30 r.z = math.floor(pos.z)
31 end
32 return r
33 end
35 -- Restaurar as refenrencias em relacao a uma pos
36 local restaurar_pos = function(pos, ref)
37 local r = {}
38 r.x, r.y, r.z = (pos.x+ref.x), (pos.y+ref.y), (pos.z+ref.z)
39 return r
40 end
42 -- calcular o deslocamento de ref em relacao a pos
43 local ref_pos = function(pos, ref)
44 local r = {}
45 r.x, r.y, r.z = (ref.x-pos.x), (ref.y-pos.y), (ref.z-pos.z)
46 return r
47 end
49 -- metodo melhorado para pegar nodes (pega nodes ainda nao carregados)
50 local function pegar_node(pos)
51 local resp = {}
52 local node = minetest.get_node(pos)
53 if node.name == "ignore" then
54 minetest.get_voxel_manip():read_from_map(pos, pos)
55 node = minetest.get_node(pos)
56 end
57 resp = {node=node}
58 --[[
59 Para salvar os metadados é criada um valor meta (node.meta)
60 para que alguns dados possam ser mantidos de forma serializada
61 no node e posteriormente serem restaurados quando a estrutura
62 for restaurada
64 local meta = minetest.get_meta(pos)
65 if node.name == "placa_terreno:livre" then -- placas de terreno
66 local ref1 = ""
67 local ref2 = ""
68 if meta:get_string("ref1") ~= "" then
69 -- Mantem os antigos ref's caso existam no metadado
70 ref1 = minetest.deserialize(meta:get_string("ref1"))
71 ref2 = minetest.deserialize(meta:get_string("ref2"))
72 else
73 -- Calcula os ref's
74 ref1 = minetest.serialize(ref_pos(pos, minetest.deserialize(meta:get_string("pos1"))))
75 ref2 = minetest.serialize(ref_pos(pos, minetest.deserialize(meta:get_string("pos2"))))
76 end
77 local custo = meta:get_string("custo")
78 local altura = meta:get_string("altura")
79 resp = {node=node,meta={ref1=ref1,ref2=ref2,custo=custo,altura=altura}}
80 elseif node.name == "default:sign_wall" then -- placas normais de parede
81 local text = meta:get_string("text")
82 local infotext = meta:get_string("infotext")
83 resp = {node=node,meta={text=text,infotext=infotext}}
84 end
85 return resp
86 end
89 -- Serializar estrutura
90 gestor.estruturador.salvar = function(pos, nome, largura, altura, modp, silencio)
91 if not pos or not nome then return false end
92 -- arredondar posicao
93 pos = arredondar(pos)
95 if modp == nil then
96 modp = modpath
97 end
98 largura = largura or gestor.diretrizes.estruturas[nome][1]
99 altura = altura or gestor.diretrizes.estruturas[nome][1]
100 if not largura or not altura then return false end
101 -- Criar estrutura
102 if silencio == nil or silencio == false then minetest.chat_send_all("Serializando estrutura. Aguarde...") end
103 local estrutura = {}
104 local ix, iy, iz = 1, 1, 1
105 local x, y, z = pos.x, pos.y, pos.z
106 local limx, limy, limz = (pos.x+largura-1), (pos.y+altura-1), (pos.z+largura-1)
107 local i = 0
108 while (x <= limx) do
109 while (y <= limy) do
110 while (z <= limz) do
111 estrutura[ix.." "..iy.." "..iz] = pegar_node({x = x, y = y, z = z})
112 i = i + 1
113 z = z + 1
114 iz = iz + 1
116 z = pos.z
117 iz = 1
118 y = y + 1
119 iy = iy + 1
121 y = pos.y
122 iy = 1
123 x = x + 1
124 ix = ix + 1
127 -- Criar arquivo
128 local output = io.open(modp .. "/estruturas/"..nome, "w")
129 output:write(minetest.serialize(estrutura))
130 io.close(output)
132 -- Estrutura serializada com sucesso
133 if silencio == nil or silencio == false then minetest.chat_send_all("Serializacao concluida.") end
134 return true
137 -- Deserializar uma estrutura
138 gestor.estruturador.carregar = function(pos, nome, largura, altura, modp, silencio)
139 if pos == nil or nome == nil then return false end
140 if silencio == nil or silencio == false then minetest.chat_send_all("Criando estrutura. Aguarde...") end
141 -- Coleta de dados
142 local dados = {}
143 if modp == nil then
144 dados = gestor.diretrizes.estruturas[nome] or {}
145 largura = dados[1] or largura
146 altura = dados[2] or altura
147 modp = modpath
149 if largura == nil or altura == nil or nome == nil then return false end
150 local input = io.open(modp .. "/estruturas/"..nome, "r")
151 if input then
152 dados.estrutura = minetest.deserialize(input:read("*l"))
153 else
154 return false
156 io.close(input)
157 -- Criar estrutura
158 local ix, iy, iz = 1, 1, 1
159 local x, y, z = pos.x, pos.y, pos.z
160 local limx, limy, limz = (pos.x+largura-1), (pos.y+altura-1), (pos.z+largura-1)
161 local i = 0
162 while (x <= limx) do
163 while (y <= limy) do
164 while (z <= limz) do
165 local PosNode = dados.estrutura[ix.." "..iy.." "..iz] or {node={name="air"}}
166 minetest.set_node({x = x, y = y, z = z}, PosNode.node)
167 if PosNode.meta then
168 if PosNode.node.name == "placa_terreno:livre" then
169 local meta = minetest.get_meta({x = x, y = y, z = z})
170 --[[
171 Tenta restaurar pos1 e pos2 mas devido a um erro
172 desconhecido as vezes desloca 1 node de distancia
173 para alguma direção
175 meta:set_string("pos1",
176 minetest.serialize(restaurar_pos(minetest.deserialize(PosNode.meta.ref1),
177 {x = x, y = y, z = z}))
179 meta:set_string("pos2",
180 minetest.serialize(restaurar_pos(minetest.deserialize(PosNode.meta.ref2),
181 {x = x, y = y, z = z}))
183 --[[
184 Mantes ref1 e ref2 no meto do bloco para evitar distorções maiores
185 usando sempre esses ref's a distorção pode ser no maximo 1 node
187 meta:set_string("ref1", minetest.serialize(PosNode.meta.ref1))
188 meta:set_string("ref2", minetest.serialize(PosNode.meta.ref2))
189 meta:set_string("custo", PosNode.meta.custo)
190 meta:set_string("altura", PosNode.meta.altura)
191 meta:set_string("status", "livre")
192 meta:set_string("infotext", "Terreno a Venda")
193 elseif PosNode.node.name == "default:sign_wall" then
194 local meta = minetest.get_meta({x = x, y = y, z = z})
195 meta:set_string("text", PosNode.meta.text)
196 meta:set_string("infotext", PosNode.meta.infotext)
199 i = i + 1
200 z = z + 1
201 iz = iz + 1
203 z = pos.z
204 iz = 1
205 y = y + 1
206 iy = iy + 1
208 y = pos.y
209 iy = 1
210 x = x + 1
211 ix = ix + 1
214 -- Estrutura construida com sucesso
215 if silencio == nil or silencio == false then minetest.chat_send_all("Estrutura construida. Aguarde o mapa ser renderizado.") end
216 return true
220 -----
221 --------
222 -- Nodes restaurador de escadarias
223 local criar_nivel_escadaria = function(pos, largura, name)
224 local limx, limz = pos.x+(largura/2), pos.z+(largura/2)
225 local x, z = pos.x-(largura/2), pos.z-(largura/2)
226 while (x<=limx) do
227 z = pos.z-(largura/2)
228 while (z<=limz) do
229 local npos = {x=x,y=pos.y,z=z}
230 local node = minetest.get_node(npos)
231 if node.name == "ignore" then
232 minetest.get_voxel_manip():read_from_map(npos, npos)
233 node = minetest.get_node(npos)
235 if node.name == "air" then
236 minetest.set_node(npos, {name=name})
238 z=z+1
240 x=x+1
243 local criar_escadaria = function(pos, node)
244 local npos = {x=pos.x,y=pos.y-10,z=pos.z}
245 local altura = pos.y - 8
246 while altura <= pos.y do
247 criar_nivel_escadaria({x=pos.x,y=altura,z=pos.z}, (math.abs(pos.y-altura)*4)+7, node)
248 altura = altura + 1
251 minetest.register_node("gestor:escadaria", {
252 description = "Restaurador de escadaria",
253 tiles = {
254 "default_pine_wood.png",
255 "default_pine_wood.png",
256 "default_pine_wood.png",
257 "default_pine_wood.png",
258 "default_pine_wood.png",
259 "default_pine_wood.png"
261 groups = {choppy=2,oddly_breakable_by_hand=2,wood=1},
262 sounds = default.node_sound_wood_defaults(),
263 on_rightclick = function(pos)
264 local node = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z})
265 criar_escadaria({x=pos.x,y=pos.y-1,z=pos.z}, node.name)
266 minetest.set_node(pos, {name="air"})
267 minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z}, {name="air"})
268 end,
270 -- Fim
271 --------
272 -----