8 local modpath
= minetest
.get_modpath("gestor")
10 -- Variavel global de estruturador
11 gestor
.estruturador
= {}
15 local arredondar
= function(pos
)
17 if pos
.x
> (math
.floor(pos
.x
)+0.5) then
18 r
.x
= math
.ceil(pos
.x
)
20 r
.x
= math
.floor(pos
.x
)
22 if pos
.y
> (math
.floor(pos
.y
)+0.5) then
23 r
.y
= math
.ceil(pos
.y
)
25 r
.y
= math
.floor(pos
.y
)
27 if pos
.z
> (math
.floor(pos
.z
)+0.5) then
28 r
.z
= math
.ceil(pos
.z
)
30 r
.z
= math
.floor(pos
.z
)
35 -- Restaurar as refenrencias em relacao a uma pos
36 local restaurar_pos
= function(pos
, ref
)
38 r
.x
, r
.y
, r
.z
= (pos
.x
+ref
.x
), (pos
.y
+ref
.y
), (pos
.z
+ref
.z
)
42 -- calcular o deslocamento de ref em relacao a pos
43 local ref_pos
= function(pos
, ref
)
45 r
.x
, r
.y
, r
.z
= (ref
.x
-pos
.x
), (ref
.y
-pos
.y
), (ref
.z
-pos
.z
)
49 -- metodo melhorado para pegar nodes (pega nodes ainda nao carregados)
50 local function pegar_node(pos
)
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
)
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
64 local meta
= minetest
.get_meta(pos
)
65 if node
.name
== "placa_terreno:livre" then -- placas de terreno
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"))
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"))))
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
}}
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
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
102 if silencio
== nil or silencio
== false then minetest
.chat_send_all("Serializando estrutura. Aguarde...") end
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)
111 estrutura
[ix
.." "..iy
.." "..iz
] = pegar_node({x
= x
, y
= y
, z
= z
})
128 local output
= io
.open(modp
.. "/estruturas/"..nome
, "w")
129 output
:write(minetest
.serialize(estrutura
))
132 -- Estrutura serializada com sucesso
133 if silencio
== nil or silencio
== false then minetest
.chat_send_all("Serializacao concluida.") end
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
144 dados
= gestor
.diretrizes
.estruturas
[nome
] or {}
145 largura
= dados
[1] or largura
146 altura
= dados
[2] or altura
149 if largura
== nil or altura
== nil or nome
== nil then return false end
150 local input
= io
.open(modp
.. "/estruturas/"..nome
, "r")
152 dados
.estrutura
= minetest
.deserialize(input
:read("*l"))
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)
165 local PosNode
= dados
.estrutura
[ix
.." "..iy
.." "..iz
] or {node
={name
="air"}}
166 minetest
.set_node({x
= x
, y
= y
, z
= z
}, PosNode
.node
)
168 if PosNode
.node
.name
== "placa_terreno:livre" then
169 local meta
= minetest
.get_meta({x
= x
, y
= y
, z
= z
})
171 Tenta restaurar pos1 e pos2 mas devido a um erro
172 desconhecido as vezes desloca 1 node de distancia
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
}))
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
)
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
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)
227 z
= pos
.z
-(largura
/2)
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
})
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
)
251 minetest
.register_node("gestor:escadaria", {
252 description
= "Restaurador de escadaria",
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"})