236 lines
5.9 KiB
Lua
236 lines
5.9 KiB
Lua
-- Enable Minetest forever.
|
|
minetest = core
|
|
|
|
firefly = {
|
|
-- Set to `true` to enable testing admin things without having to open a server.
|
|
singleplayer_admin = true
|
|
}
|
|
local ns = firefly
|
|
|
|
function include(file)
|
|
return dofile(minetest.get_modpath(minetest.get_current_modname()).."/"..file)
|
|
end
|
|
|
|
function enum(cases)
|
|
local out = {}
|
|
local i = 0
|
|
for _, x in ipairs(cases) do
|
|
out[x] = i
|
|
i = i +1
|
|
end
|
|
return out
|
|
end
|
|
|
|
say = minetest.chat_send_all
|
|
|
|
function extend(dst, src)
|
|
for k, v in pairs(src) do
|
|
dst[k] = v
|
|
end
|
|
return dst
|
|
end
|
|
|
|
Promise = {
|
|
resolve = function(e, ...)
|
|
if e.resolved then return end
|
|
e.resolved = true
|
|
if e._after then e._after(...) end
|
|
end,
|
|
after = function(e, fn)
|
|
e._after = fn
|
|
end
|
|
}
|
|
Promise.__index = Promise
|
|
setmetatable(Promise, {
|
|
__call = function(_, fn)
|
|
local e = {resolved = false}
|
|
setmetatable(e, Promise)
|
|
fn(function(...) e:resolve(...) end)
|
|
return e
|
|
end
|
|
})
|
|
|
|
EventTarget = {
|
|
init = function()
|
|
local e = {
|
|
listeners = {}
|
|
}
|
|
return setmetatable(e, EventTarget)
|
|
end,
|
|
listen = function(e, channel, fn)
|
|
if not e.listeners[channel] then e.listeners[channel] = {} end
|
|
local l = e.listeners[channel]
|
|
l[#l +1] = fn
|
|
end,
|
|
unlisten = function(e, channel, fn)
|
|
if not e.listeners[channel] then return end
|
|
local l = e.listeners[channel]
|
|
local idx = table.indexof(l, fn)
|
|
if idx < 0 then return end
|
|
table.remove(l, idx)
|
|
end,
|
|
dispatch = function(e, channel, ...)
|
|
local l = e.listeners[channel]
|
|
if not l then return end
|
|
for i = 1, #l do
|
|
l[i](...)
|
|
end
|
|
end
|
|
}
|
|
EventTarget.__index = EventTarget
|
|
setmetatable(EventTarget, {
|
|
__call = function(_, ...) return EventTarget.init(...) end
|
|
})
|
|
|
|
-- HACK: Lookup table for getting a rotation from a
|
|
-- facedir (because Minetest doesn't have any way
|
|
-- to get this information normally).
|
|
local facedir_rotations = {
|
|
-- +Y
|
|
[0] = vector.new(0, 0, 0),
|
|
[1] = vector.new(0, math.pi * 1.5, 0),
|
|
[2] = vector.new(0, math.pi * 1.0, 0),
|
|
[3] = vector.new(0, math.pi * 0.5, 0),
|
|
-- +Z
|
|
[4] = vector.new(math.pi * 1.5, 0, 0),
|
|
[5] = vector.new(0, math.pi * 1.5, math.pi * 1.5),
|
|
[6] = vector.new(math.pi * 0.5, math.pi * 1.0, 0),
|
|
[7] = vector.new(0, math.pi * 0.5, math.pi * 0.5),
|
|
-- -Z
|
|
[8] = vector.new(math.pi * 0.5, 0, 0),
|
|
[9] = vector.new(0, math.pi * 1.5, math.pi * 0.5),
|
|
[10] = vector.new(math.pi * 1.5, math.pi * 1.0, 0),
|
|
[11] = vector.new(0, math.pi * 0.5, math.pi * 1.5),
|
|
-- +X
|
|
[12] = vector.new(0, 0, math.pi * 0.5),
|
|
[13] = vector.new(math.pi * 1.5, math.pi * 1.5, 0),
|
|
[14] = vector.new(0, math.pi * 1.0, math.pi * 1.5),
|
|
[15] = vector.new(math.pi * 0.5, math.pi * 0.5, 0),
|
|
-- -X
|
|
[16] = vector.new(0, 0, math.pi * 1.5),
|
|
[17] = vector.new(math.pi * 0.5, math.pi * 1.5, 0),
|
|
[18] = vector.new(0, math.pi * 1.0, math.pi * 0.5),
|
|
[19] = vector.new(math.pi * 1.5, math.pi * 0.5, 0),
|
|
-- -Y
|
|
[20] = vector.new(0, 0, math.pi * 1.0),
|
|
[21] = vector.new(0, math.pi * 0.5, math.pi * 1.0),
|
|
[22] = vector.new(0, math.pi * 1.0, math.pi * 1.0),
|
|
[23] = vector.new(0, math.pi * 1.5, math.pi * 1.0),
|
|
}
|
|
function ns.facedir_to_rotation(facedir)
|
|
return facedir_rotations[facedir] or minetest.facedir_to_dir(facedir):dir_to_rotation()
|
|
end
|
|
|
|
function ns.rotate_selectionbox(box, rot)
|
|
local a = vector.new(box[1], box[2], box[3]):rotate(rot)
|
|
local b = vector.new(box[4], box[5], box[6]):rotate(rot)
|
|
return {
|
|
a.x, a.y, a.z,
|
|
b.x, b.y, b.z
|
|
}
|
|
end
|
|
|
|
function ns.register_item(name, def)
|
|
local needs_alias
|
|
if not name:find ":" then
|
|
def._name = name
|
|
name = "firefly:"..name
|
|
needs_alias = true
|
|
end
|
|
|
|
minetest.register_craftitem(":"..name, def)
|
|
|
|
if needs_alias then
|
|
minetest.register_alias(def._name, name)
|
|
end
|
|
end
|
|
|
|
function ns.solid_color_frames(frames)
|
|
local out = "[fill:1x"..#frames..":0,0:#000"
|
|
for i, x in ipairs(frames) do
|
|
out = out.."^[fill:1x3:0,"..(i -1)..":"..x
|
|
end
|
|
return out
|
|
end
|
|
|
|
local digit_widths = {
|
|
[0] = 7,
|
|
6,
|
|
7,
|
|
7,
|
|
7,
|
|
7,
|
|
7,
|
|
7,
|
|
7,
|
|
7,
|
|
}
|
|
function ns.texture_from_number(num)
|
|
local w = 0
|
|
local digits = {}
|
|
repeat
|
|
w = w +1
|
|
digits[w] = num %10
|
|
num = math.floor(num /10)
|
|
until num <= 0
|
|
local width = 0
|
|
local out = ""
|
|
for i = w, 1, -1 do
|
|
out = out..":"..width..",1=firefly_number_"..digits[i]..".png"
|
|
width = width +digit_widths[digits[i]] +(i > 1 and 2 or 0)
|
|
end
|
|
return "[combine:"..width.."x16"..out, width
|
|
end
|
|
|
|
function ns.read_file(path)
|
|
local f = io.open(path)
|
|
if not f then return false end
|
|
local out = f:read("a")
|
|
f:close()
|
|
return out
|
|
end
|
|
|
|
function ns.manhattan_distance(a, b)
|
|
return math.abs(b.x -a.x) +math.abs(b.y -a.y) +math.abs(b.z -a.z)
|
|
end
|
|
|
|
minetest.register_lbm {
|
|
name = ":firefly:on_load",
|
|
nodenames = {"group:call_on_load"},
|
|
action = function(pos, node)
|
|
minetest.registered_nodes[node.name].on_load(pos)
|
|
end
|
|
}
|
|
|
|
ns.timer = EventTarget()
|
|
|
|
local last_time = minetest.get_us_time()
|
|
minetest.register_globalstep(function()
|
|
local time = minetest.get_us_time()
|
|
if time -last_time > 1000000 then
|
|
ns.timer:dispatch("every_second")
|
|
last_time = time
|
|
end
|
|
end)
|
|
|
|
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
|
|
})
|
|
|
|
|
|
if minetest.get_modpath("testtools") then
|
|
minetest.override_item("testtools:param2tool", {
|
|
pointabilities = {
|
|
nodes = {["group:everything"] = true},
|
|
objects = {["group:immortal"] = false}
|
|
}
|
|
})
|
|
end
|