288 lines
10 KiB
Lua
288 lines
10 KiB
Lua
|
|
minetest.register_entity(":display", {
|
|
initial_properties = {
|
|
visual = "sprite",
|
|
textures = {"blank.png"},
|
|
pointable = false,
|
|
static_save = false
|
|
},
|
|
on_activate = function(e)
|
|
e.object:set_armor_groups{immortal = 1}
|
|
end
|
|
})
|
|
|
|
artifact.register_craftitem("cancel", {
|
|
inventory_image = "artifact_cancel.png"
|
|
})
|
|
|
|
--- @param receivers: A list of node positions to notify.
|
|
--- @param event: The event to send.
|
|
function artifact.dispatch_event(receivers, event)
|
|
for _, x in ipairs(receivers) do
|
|
-- Ensure that nodes are available.
|
|
minetest.load_area(x.pos)
|
|
local node = minetest.get_node(x.pos)
|
|
local def = minetest.registered_nodes[node.name]
|
|
if def.on_signal then
|
|
def.on_signal(x.pos, event, x.channel or "gold")
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
include "basics.lua"
|
|
include "doors.lua"
|
|
include "large_doors.lua"
|
|
include "chest.lua"
|
|
|
|
|
|
function artifact.load_schematic(dst, path, rot)
|
|
minetest.place_schematic(dst, path..".mts", rot or "0")
|
|
local f = io.open(path..".json")
|
|
local meta = minetest.parse_json(f:read("a"))
|
|
f:close()
|
|
-- Load auxiliary metadata.
|
|
for p, m in pairs(meta or {}) do
|
|
local pos = dst +vector.from_string(p)
|
|
-- Transform all position fields back into global space.
|
|
if m.fields and m.fields.receivers then
|
|
local receivers = minetest.deserialize(m.fields.receivers)
|
|
for i, x in ipairs(receivers) do
|
|
x.pos = vector.add(x.pos, dst)
|
|
receivers[i] = x
|
|
end
|
|
m.fields.receivers = minetest.serialize(receivers)
|
|
end
|
|
minetest.get_meta(pos):from_table(m)
|
|
local def = minetest.registered_nodes[minetest.get_node(pos).name]
|
|
if def.on_construct then
|
|
def.on_construct(pos)
|
|
end
|
|
end
|
|
end
|
|
|
|
function artifact.get_schem_size(path)
|
|
local f = io.open(path..".mts", "rb")
|
|
|
|
local function read_u16(file)
|
|
local data = file:read(2)
|
|
if not data or #data < 2 then return nil end
|
|
local a, b = data:byte(1, 2)
|
|
return a + b
|
|
end
|
|
local magic = f:read(4)
|
|
if magic ~= "MTSM" then
|
|
f:close()
|
|
error("Not a valid .mts file (missing` MTSM` header).")
|
|
end
|
|
|
|
local version = read_u16(f)
|
|
if not version or version > 4 then
|
|
f:close()
|
|
error("Unsupported .mts version: "..tostring(version))
|
|
end
|
|
|
|
local size_x = read_u16(f)
|
|
local size_y = read_u16(f)
|
|
local size_z = read_u16(f)
|
|
|
|
f:close()
|
|
|
|
return vector.new(size_x, size_y, size_z)
|
|
end
|
|
|
|
if artifact.debug then
|
|
|
|
local link_colors = {
|
|
"gold",
|
|
"red",
|
|
"green",
|
|
"blue"
|
|
}
|
|
|
|
if minetest.get_modpath("rhotator") then
|
|
minetest.override_item("rhotator:screwdriver", {
|
|
pointabilities = {
|
|
nodes = {
|
|
-- This gets added to everything in debug mode.
|
|
["group:dig_immediate"] = true,
|
|
air = false,
|
|
},
|
|
objects = {
|
|
-- The display entities should all be immortal.
|
|
["group:immortal"] = false
|
|
}
|
|
},
|
|
})
|
|
minetest.override_item("testtools:remover", {
|
|
pointabilities = {
|
|
nodes = {
|
|
-- This gets added to everything in debug mode.
|
|
["group:dig_immediate"] = true,
|
|
air = false,
|
|
},
|
|
objects = {
|
|
-- The display entities should all be immortal.
|
|
["group:immortal"] = false
|
|
}
|
|
},
|
|
})
|
|
minetest.override_item("testtools:node_meta_editor", {
|
|
pointabilities = {
|
|
nodes = {
|
|
-- This gets added to everything in debug mode.
|
|
["group:dig_immediate"] = true,
|
|
air = false,
|
|
},
|
|
objects = {
|
|
-- The display entities should all be immortal.
|
|
["group:immortal"] = false
|
|
}
|
|
},
|
|
})
|
|
minetest.override_item("testtools:param2tool", {
|
|
pointabilities = {
|
|
nodes = {
|
|
-- This gets added to everything in debug mode.
|
|
["group:dig_immediate"] = true,
|
|
air = false,
|
|
},
|
|
objects = {
|
|
-- The display entities should all be immortal.
|
|
["group:immortal"] = false
|
|
}
|
|
},
|
|
})
|
|
end
|
|
|
|
artifact.register_craftitem("linker_tool", {
|
|
inventory_image = "artifact_linker_tool.png",
|
|
stack_max = 1,
|
|
pointabilities = {
|
|
nodes = {
|
|
-- This gets added to everything in debug mode.
|
|
["group:dig_immediate"] = true,
|
|
air = false,
|
|
},
|
|
objects = {
|
|
-- The display entities should all be immortal.
|
|
["group:immortal"] = false
|
|
}
|
|
},
|
|
on_secondary_use = function(s, p, pt)
|
|
local m = s:get_meta()
|
|
-- Just cycle through the colors list.
|
|
local color = link_colors[table.indexof(link_colors, m:get("color") or "gold") %#link_colors +1]
|
|
m:set_string("color", color)
|
|
m:set_string("inventory_image", "[fill:16x16:0,0:"..color.."#00^artifact_linker_tool.png")
|
|
return s
|
|
end,
|
|
on_place = function(s, p, pt)
|
|
local m = artifact.players[p:get_player_name()]
|
|
if pt.type == "node" and m._linker_target then
|
|
local color = s:get_meta():get("color") or "gold"
|
|
local meta = minetest.get_meta(m._linker_target)
|
|
local receivers = minetest.deserialize(meta:get("receivers") or "return {}")
|
|
if m.ctl.sneak then
|
|
local idx = 0
|
|
for i, x in ipairs(receivers) do
|
|
if vector.equals(x.pos, pt.under) then idx = i end
|
|
end
|
|
if idx > 0 then
|
|
table.remove(receivers, idx)
|
|
m.object:hud_remove(m._linker_receivers[idx])
|
|
table.remove(m._linker_receivers, idx)
|
|
end
|
|
else
|
|
local idx = 0
|
|
for i, x in ipairs(receivers) do
|
|
if vector.equals(x.pos, pt.under) then idx = i end
|
|
end
|
|
-- Ensure we haven't added this pos already.
|
|
if idx == 0 then
|
|
table.insert(receivers, {pos = pt.under, channel = color})
|
|
table.insert(m._linker_receivers, m.object:hud_add {
|
|
type = "image_waypoint",
|
|
scale = {x=3, y=3},
|
|
world_pos = pt.under,
|
|
text = "artifact_linker_tool.png^[colorize:"..color..":64"
|
|
})
|
|
end
|
|
end
|
|
meta:set_string("receivers", minetest.serialize(receivers))
|
|
end
|
|
end,
|
|
on_use = function(s, p, pt)
|
|
local m = artifact.players[p:get_player_name()]
|
|
if pt.type == "node" then
|
|
m._linker_target = pt.under
|
|
if m._linker_target_hud then
|
|
m.object:hud_remove(m._linker_target_hud)
|
|
end
|
|
m._linker_target_hud = m.object:hud_add {
|
|
type = "image_waypoint",
|
|
scale = {x=3, y=3},
|
|
world_pos = pt.under,
|
|
text = "artifact_linker_tool.png"
|
|
}
|
|
if m._linker_receivers then
|
|
for _, x in ipairs(m._linker_receivers) do
|
|
m.object:hud_remove(x)
|
|
end
|
|
end
|
|
m._linker_receivers = {}
|
|
local receivers = minetest.deserialize(minetest.get_meta(m._linker_target):get("receivers") or "return {}")
|
|
for _, x in ipairs(receivers) do
|
|
table.insert(m._linker_receivers, m.object:hud_add {
|
|
type = "image_waypoint",
|
|
scale = {x=3, y=3},
|
|
world_pos = x.pos,
|
|
text = "artifact_linker_tool.png^[colorize:"..x.channel..":64"
|
|
})
|
|
end
|
|
end
|
|
end
|
|
})
|
|
|
|
-- To make life easier, simply require worldedit in order to export an area.
|
|
if minetest.global_exists("worldedit") then
|
|
minetest.mkdir(minetest.get_worldpath().."/schems")
|
|
minetest.register_chatcommand("export", {
|
|
privs = {server = true},
|
|
params = "<name>",
|
|
description = "Export the selected region as a schematic, with all node metadata stored in an adjacent JSON file.",
|
|
func = function(name, args)
|
|
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
|
|
print(dump(minetest.create_schematic(pos1, pos2, nil, minetest.get_worldpath().."/schems/"..args..".mts")))
|
|
local minp = vector.sort(pos1, pos2)
|
|
local meta = {}
|
|
for _, pos in pairs(minetest.find_nodes_with_meta(pos1, pos2)) do
|
|
local mt = minetest.get_meta(pos):to_table()
|
|
mt.fields.initialized = nil
|
|
-- Transform all position fields into local coordinate space.
|
|
if mt.fields.receivers then
|
|
local receivers = minetest.deserialize(mt.fields.receivers)
|
|
for i, x in ipairs(receivers) do
|
|
x.pos = vector.subtract(x.pos, minp)
|
|
receivers[i] = x
|
|
end
|
|
mt.fields.receivers = minetest.serialize(receivers)
|
|
end
|
|
meta[(pos -minp):to_string()] = mt
|
|
end
|
|
local f = io.open(minetest.get_worldpath().."/schems/"..args..".json", "w")
|
|
f:write(minetest.write_json(meta))
|
|
f:flush()
|
|
f:close()
|
|
end
|
|
})
|
|
end
|
|
|
|
minetest.register_chatcommand("load", {
|
|
privs = {server = true},
|
|
func = function(name, args)
|
|
artifact.load_schematic(artifact.players[name].pos:round(), minetest.get_worldpath().."/schems/"..args)
|
|
end
|
|
})
|
|
end
|
|
|