5 local path
= minetest
.get_worldpath().."/advschem.mt"
9 -- [local function] Renumber table
10 local function renumber(t
)
12 for _
, i
in pairs(t
) do
27 -- [function] Add form
28 function advschem
.add_form(name
, def
)
33 tabs
[#tabs
+ 1] = name
37 -- [function] Generate tabs
38 function advschem
.generate_tabs(current
)
39 local retval
= "tabheader[0,0;tabs;"
40 for _
, t
in pairs(tabs
) do
42 if f
.tab
~= false and f
.caption
then
43 retval
= retval
..f
.caption
..","
45 if type(current
) ~= "number" and current
== f
.name
then
50 retval
= retval
:sub(1, -2) -- Strip last comma
51 retval
= retval
..";"..current
.."]" -- Close tabheader
55 -- [function] Handle tabs
56 function advschem
.handle_tabs(pos
, name
, fields
)
57 local tab
= tonumber(fields
.tabs
)
58 if tab
and tabs
[tab
] and forms
[tabs
[tab]]
then
59 advschem
.show_formspec(pos
, name
, forms
[tabs
[tab]]
.name
)
64 -- [function] Show formspec
65 function advschem
.show_formspec(pos
, player
, tab
, show
, ...)
67 if type(player
) == "string" then
68 player
= minetest
.get_player_by_name(player
)
70 local name
= player
:get_player_name()
73 if not form_data
[name
] then
77 local form
= forms
[tab
].get(form_data
[name
], pos
, name
, ...)
78 if forms
[tab
].tab
then
79 form
= form
..advschem
.generate_tabs(tab
)
82 minetest
.show_formspec(name
, "advschem:"..tab
, form
)
85 -- Update player attribute
86 if forms
[tab
].cache_name
~= false then
87 player
:set_attribute("advschem:tab", tab
)
90 minetest
.close_formspec(pname
, "advschem:"..tab
)
95 -- [event] On receive fields
96 minetest
.register_on_player_receive_fields(function(player
, formname
, fields
)
97 local formname
= formname
:split(":")
99 if formname
[1] == "advschem" and forms
[formname
[2]]
then
100 local handle
= forms
[formname
[2]]
.handle
101 local name
= player
:get_player_name()
102 if contexts
[name
] then
103 if not form_data
[name
] then
107 if not advschem
.handle_tabs(contexts
[name
], name
, fields
) and handle
then
108 handle(form_data
[name
], contexts
[name
], name
, fields
)
118 advschem
.add_form("main", {
121 get
= function(self
, pos
, name
)
122 local meta
= minetest
.get_meta(pos
):to_table().fields
123 local strpos
= minetest
.pos_to_string(pos
)
126 if meta
.schem_border
== "true" and advschem
.markers
[strpos
] then
127 border_button
= "button[3.5,7.5;3,1;border;Hide Border]"
129 border_button
= "button[3.5,7.5;3,1;border;Show Border]"
132 -- TODO: Show information regarding volume, pos1, pos2, etc... in formspec
135 label[0.5,-0.1;Position: ]]..strpos
..[[]
136 label[3,-0.1;Owner: ]]..name
..[[]
138 field[0.8,1;5,1;name;Schematic Name:;]]..(meta
.schem_name
or "")..[[]
139 button[5.3,0.69;1.2,1;save_name;Save]
140 tooltip[save_name;Save schematic name]
141 field_close_on_enter[name;false]
143 button[0.5,1.5;6,1;export;Export Schematic]
144 label[0.5,2.2;Schematic will be exported as a .mts file and stored in]
145 label[0.5,2.45;<minetest dir>/worlds/<worldname>/schems/<name>.mts]
147 field[0.8,7;2,1;x;X-Size:;]]..meta
.x_size
..[[]
148 field[2.8,7;2,1;y;Y-Size:;]]..meta
.y_size
..[[]
149 field[4.8,7;2,1;z;Z-Size:;]]..meta
.z_size
..[[]
150 field_close_on_enter[x;false]
151 field_close_on_enter[y;false]
152 field_close_on_enter[z;false]
154 button[0.5,7.5;3,1;save;Save Size]
158 handle
= function(self
, pos
, name
, fields
)
159 local realmeta
= minetest
.get_meta(pos
)
160 local meta
= realmeta
:to_table().fields
161 local strpos
= minetest
.pos_to_string(pos
)
164 if fields
.border
then
165 if meta
.schem_border
== "true" and advschem
.markers
[strpos
] then
167 meta
.schem_border
= "false"
170 meta
.schem_border
= "true"
174 local update_positions
= false
175 -- Save size vector values
176 if (fields
.save
or fields
.key_enter_field
== "x" or
177 fields
.key_enter_field
== "y" or fields
.key_enter_field
== "z")
178 and (fields
.x
and fields
.y
and fields
.z
and fields
.x
~= ""
179 and fields
.y
~= "" and fields
.z
~= "") then
180 local x
, y
, z
= tonumber(fields
.x
), tonumber(fields
.y
), tonumber(fields
.z
)
183 meta
.x_size
= math
.max(x
, 1)
186 meta
.y_size
= math
.max(y
, 1)
189 meta
.z_size
= math
.max(z
, 1)
192 -- Set positions to be updated
193 update_positions
= true
196 -- Save schematic name
197 if fields
.save_name
or fields
.key_enter_field
== "name" and fields
.name
and
198 fields
.name
~= "" then
199 meta
.schem_name
= fields
.name
203 if fields
.export
and meta
.schem_name
and meta
.schem_name
~= "" then
204 local pos1
, pos2
= advschem
.size(pos
)
205 local path
= minetest
.get_worldpath().."/schems/"
208 local plist
= minetest
.deserialize(meta
.prob_list
)
209 local probability_list
= {}
210 for _
, i
in pairs(plist
) do
212 if i
.force_place
== true then
216 probability_list
[#probability_list
+ 1] = {
217 pos
= minetest
.string_to_pos(_
),
222 local slist
= minetest
.deserialize(meta
.slices
)
223 local slice_list
= {}
224 for _
, i
in pairs(slist
) do
225 slice_list
[#slice_list
+ 1] = {
226 ypos
= pos
.y
+ i
.ypos
,
231 local filepath
= path
..meta
.schem_name
..".mts"
232 local res
= minetest
.create_schematic(pos1
, pos2
, probability_list
, filepath
, slice_list
)
235 minetest
.chat_send_player(name
, minetest
.colorize("#00ff00",
236 "Exported schematic to "..filepath
))
238 minetest
.chat_send_player(name
, minetest
.colorize("red",
239 "Failed to export schematic to "..filepath
))
243 -- Save meta before updating visuals
244 local inv
= realmeta
:get_inventory():get_lists()
245 realmeta
:from_table({fields
= meta
, inventory
= inv
})
248 if not fields
.border
and meta
.schem_border
== "true" then
253 if not fields
.quit
then
254 advschem
.show_formspec(pos
, minetest
.get_player_by_name(name
), "main")
257 -- Update pos1 and pos2 in marked table (for interaction checking)
258 if update_positions
then
259 local pos1
, pos2
= advschem
.size(pos
)
260 pos1
, pos2
= advschem
.sort_pos(pos1
, pos2
)
261 marked
[minetest
.pos_to_string(pos
)] = {
269 advschem
.add_form("prob", {
271 caption
= "Probability",
272 get
= function(self
, pos
, name
)
273 local meta
= minetest
.get_meta(pos
)
274 local inventory
= meta
:get_inventory()
275 local stack
= inventory
:get_stack("probability", 1)
276 local stringpos
= pos
.x
..","..pos
.y
..","..pos
.z
280 list[nodemeta:]]..stringpos
..[[;probability;0,0;1,1;]
281 label[0,1;Probability is a number between 0 and 127.]
282 list[current_player;main;0,1.5;8,4;]
283 listring[nodemeta:]]..stringpos
..[[;probability]
284 listring[current_player;main]
287 if stack
:get_name() ~= "" then
288 local smeta
= stack
:get_meta():to_table().fields
291 field[1.3,0.4;2,1;probability;Probability:;]]..
292 (smeta
.advschem_prob
or "127").."]" ..
294 field_close_on_enter[probability;false]
295 checkbox[3.1,0.1;force_place;Force Place;]]..(smeta
.advschem_force_place
or "false")..[[]
296 button[5,0.1;1.5,1;rst;Reset]
297 button[6.5,0.1;1.5,1;save;Save]
301 label[1,0.2;Insert node in slot.]
307 handle
= function(self
, pos
, name
, fields
)
308 local meta
= minetest
.get_meta(pos
)
309 local inventory
= meta
:get_inventory()
310 local stack
= inventory
:get_stack("probability", 1)
311 local smeta
= stack
:get_meta()
313 if stack
:get_name() ~= "" then
315 smeta
:set_string("advschem_prob", nil)
316 smeta
:set_string("advschem_force_place", nil)
319 local original_desc
= smeta
:get_string("original_desc")
320 if not original_desc
or original_desc
== "" then
321 original_desc
= minetest
.registered_items
[stack
:get_name()].description
324 smeta
:set_string("description", original_desc
)
325 elseif fields
.force_place
or fields
.save
or
326 fields
.key_enter_field
== "probability" then
328 local prob_desc
= "\nProbability: "..(fields
.probability
or
329 smeta
:get_string("advschem_prob") or "Not Set")
330 -- Update probability
331 if fields
.probability
~= "" then
332 local prob
= tonumber(fields
.probability
)
333 if prob
and prob
>= 0 and prob
< 127 then
334 smeta
:set_string("advschem_prob", fields
.probability
)
335 elseif prob
and prob
== 127 then
336 -- Clear prob metadata for default probability
338 smeta
:set_string("advschem_prob", nil)
340 prob_desc
= "\nProbability: "..(smeta
:get_string("advschem_prob") or
342 advschem
.show_formspec(pos
, minetest
.get_player_by_name(name
), "prob")
345 smeta
:set_string("advschem_prob", nil)
348 -- Update force place if fields value is not nil
349 if fields
.force_place
~= nil then
350 smeta
:set_string("advschem_force_place", fields
.force_place
)
353 -- Update description
354 local desc
= minetest
.registered_items
[stack
:get_name()].description
355 local meta_desc
= smeta
:get_string("description")
356 if meta_desc
and meta_desc
~= "" then
360 local original_desc
= smeta
:get_string("original_description")
361 if original_desc
and original_desc
~= "" then
364 smeta
:set_string("original_description", desc
)
367 local force_desc
= ""
368 if smeta
:get_string("advschem_force_place") == "true" then
369 force_desc
= "\n".."Force Place"
372 desc
= desc
..minetest
.colorize("grey", prob_desc
..force_desc
)
374 smeta
:set_string("description", desc
)
378 inventory
:set_stack("probability", 1, stack
)
380 -- Refresh formspec on reset or force placement change
381 if fields
.rst
or fields
.force_place
then
382 advschem
.show_formspec(pos
, minetest
.get_player_by_name(name
), "prob")
388 advschem
.add_form("slice", {
391 get
= function(self
, pos
, name
, visible_panel
)
392 local meta
= minetest
.get_meta(pos
):to_table().fields
394 self
.selected
= self
.selected
or 1
395 local selected
= tostring(self
.selected
)
396 local slice_list
= minetest
.deserialize(meta
.slices
)
398 for _
, i
in pairs(slice_list
) do
399 local insert
= "Y = "..tostring(i
.ypos
).."; Probability = "..tostring(i
.prob
)
400 slices
= slices
..minetest
.formspec_escape(insert
)..","
402 slices
= slices
:sub(1, -2) -- Remove final comma
406 table[0,0;6.8,4;slices;]]..slices
..[[;]]..selected
..[[]
409 if self
.panel_add
or self
.panel_edit
then
410 local ypos_default
, prob_default
= "", ""
411 local done_button
= "button[5,5.18;2,1;done_add;Done]"
412 if self
.panel_edit
then
413 done_button
= "button[5,5.18;2,1;done_edit;Done]"
414 ypos_default
= slice_list
[self
.selected
].ypos
415 prob_default
= slice_list
[self
.selected
].prob
419 field[0.3,5.5;2.5,1;ypos;Y-Position (max ]]..(meta
.y_size
- 1)..[[):;]]..ypos_default
..[[]
420 field[2.8,5.5;2.5,1;prob;Probability (0-127):;]]..prob_default
..[[]
421 field_close_on_enter[ypos;false]
422 field_close_on_enter[prob;false]
426 if not self
.panel_edit
then
427 form
= form
.."button[0,4;2,1;add;+ Add Slice]"
430 if slices
~= "" and self
.selected
and not self
.panel_add
then
431 if not self
.panel_edit
then
433 button[2,4;2,1;remove;- Remove Slice]
434 button[4,4;2,1;edit;+/- Edit Slice]
438 button[0,4;2,1;remove;- Remove Slice]
439 button[2,4;2,1;edit;+/- Edit Slice]
446 handle
= function(self
, pos
, name
, fields
)
447 local meta
= minetest
.get_meta(pos
)
448 local player
= minetest
.get_player_by_name(name
)
450 if fields
.slices
then
451 local slices
= fields
.slices
:split(":")
452 self
.selected
= tonumber(slices
[2])
456 if not self
.panel_add
then
457 self
.panel_add
= true
458 advschem
.show_formspec(pos
, player
, "slice")
461 advschem
.show_formspec(pos
, player
, "slice")
465 local ypos
, prob
= tonumber(fields
.ypos
), tonumber(fields
.prob
)
466 if (fields
.done_add
or fields
.done_edit
) and fields
.ypos
and fields
.prob
and
467 fields
.ypos
~= "" and fields
.prob
~= "" and ypos
and prob
and
468 ypos
<= (meta
:get_int("y_size") - 1) and prob
>= 0 and prob
<= 255 then
469 local slice_list
= minetest
.deserialize(meta
:get_string("slices"))
470 local index
= #slice_list
+ 1
471 if fields
.done_edit
then
472 index
= self
.selected
475 slice_list
[index
] = {ypos
= ypos
, prob
= prob
}
477 meta
:set_string("slices", minetest
.serialize(slice_list
))
479 -- Update and show formspec
481 advschem
.show_formspec(pos
, player
, "slice")
484 if fields
.remove and self
.selected
then
485 local slice_list
= minetest
.deserialize(meta
:get_string("slices"))
486 slice_list
[self
.selected
] = nil
487 meta
:set_string("slices", minetest
.serialize(renumber(slice_list
)))
491 self
.panel_edit
= nil
492 advschem
.show_formspec(pos
, player
, "slice")
496 if not self
.panel_edit
then
497 self
.panel_edit
= true
498 advschem
.show_formspec(pos
, player
, "slice")
500 self
.panel_edit
= nil
501 advschem
.show_formspec(pos
, player
, "slice")
512 function advschem
.load()
513 local res
= io
.open(path
, "r")
515 marked
= minetest
.deserialize(res
:read("*a"))
519 if type(marked
) ~= "table" then
525 function advschem
.save()
526 local res
= io
.open(path
, "w")
528 res
:write(minetest
.serialize(marked
))
533 --- Copies and modifies positions `pos1` and `pos2` so that each component of
534 -- `pos1` is less than or equal to the corresponding component of `pos2`.
535 -- Returns the new positions.
536 function advschem
.sort_pos(pos1
, pos2
)
537 if not pos1
or not pos2
then
541 pos1
, pos2
= table.copy(pos1
), table.copy(pos2
)
542 if pos1
.x
> pos2
.x
then
543 pos2
.x
, pos1
.x
= pos1
.x
, pos2
.x
545 if pos1
.y
> pos2
.y
then
546 pos2
.y
, pos1
.y
= pos1
.y
, pos2
.y
548 if pos1
.z
> pos2
.z
then
549 pos2
.z
, pos1
.z
= pos1
.z
, pos2
.z
554 -- [function] Prepare size
555 function advschem
.size(pos
)
556 local pos1
= vector
.new(pos
)
557 local meta
= minetest
.get_meta(pos
)
558 local node
= minetest
.get_node(pos
)
559 local param2
= node
.param2
561 x
= meta
:get_int("x_size"),
562 y
= math
.max(meta
:get_int("y_size") - 1, 0),
563 z
= meta
:get_int("z_size"),
567 local new_pos
= vector
.add({x
= size
.z
, y
= size
.y
, z
= -size
.x
}, pos
)
569 new_pos
.z
= new_pos
.z
+ 1
571 elseif param2
== 2 then
572 local new_pos
= vector
.add({x
= -size
.x
, y
= size
.y
, z
= -size
.z
}, pos
)
574 new_pos
.x
= new_pos
.x
+ 1
576 elseif param2
== 3 then
577 local new_pos
= vector
.add({x
= -size
.z
, y
= size
.y
, z
= size
.x
}, pos
)
579 new_pos
.z
= new_pos
.z
- 1
582 local new_pos
= vector
.add(size
, pos
)
584 new_pos
.x
= new_pos
.x
- 1
589 -- [function] Mark region
590 function advschem
.mark(pos
)
593 local id
= minetest
.pos_to_string(pos
)
594 local owner
= minetest
.get_meta(pos
):get_string("owner")
595 local pos1
, pos2
= advschem
.size(pos
)
596 pos1
, pos2
= advschem
.sort_pos(pos1
, pos2
)
598 local thickness
= 0.2
599 local sizex
, sizey
, sizez
= (1 + pos2
.x
- pos1
.x
) / 2, (1 + pos2
.y
- pos1
.y
) / 2, (1 + pos2
.z
- pos1
.z
) / 2
605 for _
, z
in ipairs({pos1
.z
- 0.5, pos2
.z
+ 0.5}) do
611 local marker
= minetest
.add_entity({x
= pos1
.x
+ sizex
- 0.5, y
= pos1
.y
+ sizey
- 0.5, z
= z
+ offset
}, "advschem:display")
612 if marker
~= nil then
613 marker
:set_properties({
614 visual_size
={x
=(sizex
+0.01) * 2, y
=sizey
* 2},
615 collisionbox
= {-sizex
, -sizey
, -thickness
, sizex
, sizey
, thickness
},
617 marker
:get_luaentity().id
= id
618 marker
:get_luaentity().owner
= owner
619 table.insert(m
, marker
)
626 for _
, x
in ipairs({pos1
.x
- 0.5, pos2
.x
+ 0.5}) do
633 local marker
= minetest
.add_entity({x
= x
+ offset
, y
= pos1
.y
+ sizey
- 0.5, z
= pos1
.z
+ sizez
- 0.5}, "advschem:display")
634 if marker
~= nil then
635 marker
:set_properties({
636 visual_size
={x
=(sizez
+0.01) * 2, y
=sizey
* 2},
637 collisionbox
= {-thickness
, -sizey
, -sizez
, thickness
, sizey
, sizez
},
639 marker
:set_yaw(math
.pi
/ 2)
640 marker
:get_luaentity().id
= id
641 marker
:get_luaentity().owner
= owner
642 table.insert(m
, marker
)
647 advschem
.markers
[id
] = m
651 -- [function] Unmark region
652 function advschem
.unmark(pos
)
653 local id
= minetest
.pos_to_string(pos
)
654 if advschem
.markers
[id
] then
656 for _
, entity
in ipairs(advschem
.markers
[id
]) do
668 -- [event] Save data on shut down
669 minetest
.register_on_shutdown(advschem
.save
)
671 -- [event] Transfer probabilities and force place on place node
672 minetest
.register_on_placenode(function(pos
, newnode
, player
, oldnode
, itemstack
)
673 local smeta
= itemstack
:get_meta():to_table().fields
676 if smeta
.advschem_prob
and tonumber(smeta
.advschem_prob
) then
677 prob
= tonumber(smeta
.advschem_prob
)
678 elseif newnode
.name
== "advschem:void" then
684 local px
, py
, pz
= pos
.x
, pos
.y
, pos
.z
685 for strpos
, r
in pairs(marked
) do
686 local ap1
, ap2
= r
.pos1
, r
.pos2
687 if (px
>= ap1
.x
and px
<= ap2
.x
) and
688 (py
>= ap1
.y
and py
<= ap2
.y
) and
689 (pz
>= ap1
.z
and pz
<= ap2
.z
) then
690 local realpos
= minetest
.string_to_pos(strpos
)
691 local node
= minetest
.get_node_or_nil(realpos
)
693 if node
and node
.name
== "advschem:creator" then
694 local meta
= minetest
.get_meta(realpos
)
695 local prob_list
= minetest
.deserialize(meta
:get_string("prob_list"))
697 local force_place
= false
698 if newnode
.name
~= "advschem:void" and smeta
.advschem_force_place
== "true" then
702 local ostrpos
= minetest
.pos_to_string(pos
)
703 prob_list
[ostrpos
] = {
706 force_place
= force_place
,
708 meta
:set_string("prob_list", minetest
.serialize(prob_list
))
714 -- [event] Remove probability on break node
715 minetest
.register_on_dignode(function(pos
, oldnode
, player
)
716 local original_strpos
= minetest
.pos_to_string(pos
)
717 local px
, py
, pz
= pos
.x
, pos
.y
, pos
.z
718 for strpos
, r
in pairs(marked
) do
719 local ap1
, ap2
= r
.pos1
, r
.pos2
720 if (px
>= ap1
.x
and px
<= ap2
.x
) and
721 (py
>= ap1
.y
and py
<= ap2
.y
) and
722 (pz
>= ap1
.z
and pz
<= ap2
.z
) then
723 local realpos
= minetest
.string_to_pos(strpos
)
724 local meta
= minetest
.get_meta(realpos
)
725 local prob_list
= minetest
.deserialize(meta
:get_string("prob_list"))
728 for _
, i
in pairs(prob_list
) do
729 if _
== original_strpos
then
735 meta
:set_string("prob_list", minetest
.serialize(prob_list
))
740 -- [priv] schematic_override
741 minetest
.register_privilege("schematic_override", {
742 description
= "Allows you to access advschem nodes not owned by you",
743 give_to_singleplayer
= false,
746 -- [node] Schematic creator
747 minetest
.register_node("advschem:creator", {
748 description
= "Schematic Creator",
749 tiles
= {"advschem_creator_top.png", "advschem_creator_bottom.png",
750 "advschem_creator_sides.png"},
751 groups
= { dig_immediate
= 3},
752 paramtype2
= "facedir",
753 is_ground_content
= false,
755 after_place_node
= function(pos
, player
)
756 local name
= player
:get_player_name()
757 local meta
= minetest
.get_meta(pos
)
759 meta
:set_string("owner", name
)
760 meta
:set_string("infotext", "Schematic Creator\n(owned by "..name
..")")
761 meta
:set_string("prob_list", minetest
.serialize({}))
762 meta
:set_string("slices", minetest
.serialize({}))
764 local node
= minetest
.get_node(pos
)
765 local dir
= minetest
.facedir_to_dir(node
.param2
)
767 meta
:set_int("x_size", 1)
768 meta
:set_int("y_size", 1)
769 meta
:set_int("z_size", 1)
771 local inv
= meta
:get_inventory()
772 inv
:set_size("probability", 1)
774 local pos1
, pos2
= advschem
.size(pos
)
775 marked
[minetest
.pos_to_string(pos
)] = {
780 -- Don't take item from itemstack
783 can_dig
= function(pos
, player
)
784 local name
= player
:get_player_name()
785 local meta
= minetest
.get_meta(pos
)
786 if meta
:get_string("owner") == name
or
787 minetest
.check_player_privs(player
, "schematic_override") == true then
793 on_rightclick
= function(pos
, node
, player
)
794 local meta
= minetest
.get_meta(pos
)
795 local name
= player
:get_player_name()
796 if meta
:get_string("owner") == name
or
797 minetest
.check_player_privs(player
, "schematic_override") == true then
798 -- Get player attribute
799 local tab
= player
:get_attribute("advschem:tab")
800 if not forms
[tab
] then
804 advschem
.show_formspec(pos
, player
, tab
, true)
807 after_destruct
= function(pos
)
811 -- Update formspec when items are added to or taken from the probability inventory
812 on_metadata_inventory_put
= function(pos
, listname
, index
, stack
, player
)
813 if listname
== "probability" then
814 advschem
.show_formspec(pos
, player
, "prob", true)
817 allow_metadata_inventory_put
= function(pos
, listname
, index
, stack
, player
)
818 if listname
== "probability" then
819 local itemstring
= stack
:get_name()
820 if itemstring
== "advschem:void" then
822 elseif minetest
.registered_items
[itemstring
].type ~= "node" then
826 return stack
:get_count()
828 on_metadata_inventory_take
= function(pos
, listname
, index
, stack
, player
)
829 if listname
== "probability" then
830 advschem
.show_formspec(pos
, player
, "prob", true)
835 minetest
.register_node("advschem:void", {
836 description
= "Schematic Void",
837 tiles
= { "advschem_void.png" },
838 drawtype
= "nodebox",
839 is_ground_content
= false,
842 sunlight_propagates
= true,
846 { -4/16, -4/16, -4/16, 4/16, 4/16, 4/16 },
849 groups
= { dig_immediate
= 3},
853 minetest
.register_entity("advschem:display", {
854 initial_properties
= {
855 visual
= "upright_sprite",
856 textures
= {"advschem_border.png"},
857 visual_size
= {x
=10, y
=10},
860 on_step
= function(self
, dtime
)
863 elseif not advschem
.markers
[self
.id
] then
867 on_punch
= function(self
, hitter
)
868 local pos
= minetest
.string_to_pos(self
.id
)
869 local meta
= minetest
.get_meta(pos
)
870 if meta
:get_string("owner") == hitter
:get_player_name() or
871 minetest
.check_player_privs(hitter
, "schematic_override") == true then
873 meta
:set_string("schem_border", "false")
876 on_activate
= function(self
)
877 self
.object
:set_armor_groups({immortal
= 1})
881 -- [chatcommand] Place schematic
882 minetest
.register_chatcommand("placeschem", {
883 description
= "Place schematic at the position specified or the current "..
884 "player position (loaded from "..minetest
.get_worldpath().."/schems/)",
885 privs
= {debug
= true},
886 params
= "[<schematic name>.mts] (<x> <y> <z>)",
887 func
= function(name
, param
)
888 local schem
, p
= string.match(param
, "^([^ ]+) *(.*)$")
889 local pos
= minetest
.string_to_pos(p
)
892 pos
= minetest
.get_player_by_name(name
):get_pos()
895 return true, "Success: "..dump(minetest
.place_schematic(pos
,
896 minetest
.get_worldpath().."/schems/"..schem
..".mts", "random", nil, false))