epic/common.lua
2019-12-04 11:30:44 +01:00

185 lines
4.3 KiB
Lua

-- starts the configured epic node at position
epic.start = function(playername, pos)
local player = minetest.get_player_by_name(playername)
if not player then
-- player not online
return false
end
local meta = minetest.get_meta(pos)
local main_pos = epic.to_absolute_pos(pos, minetest.string_to_pos(meta:get_string("main_pos")))
local exit_pos = epic.to_absolute_pos(pos, minetest.string_to_pos(meta:get_string("exit_pos")))
local epic_name = meta:get_string("name")
if not main_pos then
-- no main position
return false
end
-- start epic
epic.execute_epic(player, main_pos, exit_pos, epic_name)
return true
end
-- abort epic if running
epic.abort = function(playername)
if epic.state[playername] then
epic.abort_flag[playername] = "manual"
end
end
-- debug log
epic.debug = function(msg)
if epic.log_executor then
minetest.log("action", "[epic] " .. msg)
end
end
-- converts a pos to a relative one in respect to the node_pos
epic.to_relative_pos = function(node_pos, remote_abs_pos)
if not node_pos or not remote_abs_pos then
return
end
return vector.subtract(remote_abs_pos, node_pos)
end
-- converts the relative pos to an absolute one
epic.to_absolute_pos = function(node_pos, remote_rel_pos)
if not node_pos or not remote_rel_pos then
return
end
return vector.add(node_pos, remote_rel_pos)
end
-- shows a waypoint for given seconds
epic.show_waypoint = function(playername, pos, name, seconds)
local player = minetest.get_player_by_name(playername)
if not player then
return
end
local id = player:hud_add({
hud_elem_type = "waypoint",
name = name,
text = "m",
number = 0xFF0000,
world_pos = pos
})
minetest.after(seconds, function()
player = minetest.get_player_by_name(playername)
if not player then
return
end
player:hud_remove(id)
end)
end
local SECONDS_IN_DAY = 3600*24
local SECONDS_IN_HOUR = 3600
local SECONDS_IN_MINUTE = 60
epic.format_time = function(seconds)
local str = ""
if seconds >= SECONDS_IN_DAY then
local days = math.floor(seconds / SECONDS_IN_DAY)
str = str .. days .. " d "
seconds = seconds - (days * SECONDS_IN_DAY)
end
if seconds >= SECONDS_IN_HOUR then
local hours = math.floor(seconds / SECONDS_IN_HOUR)
str = str .. hours .. " h "
seconds = seconds - (hours * SECONDS_IN_HOUR)
end
if seconds >= SECONDS_IN_MINUTE then
local minutes = math.floor(seconds / SECONDS_IN_MINUTE)
str = str .. minutes .. " min "
seconds = seconds - (minutes * SECONDS_IN_MINUTE)
end
str = str .. math.floor(seconds) .. " s"
return str
end
-- converts the direction from a param2
epic.get_direction = function(param2)
local direction = minetest.facedir_to_dir(param2)
if direction.x == -1 and direction.z == 0 then
return { x=0, y=0, z=1 }
elseif direction.x == 0 and direction.z == 1 then
return { x=1, y=0, z=0 }
elseif direction.x == 1 and direction.z == 0 then
return { x=0, y=0, z=-1 }
elseif direction.x == 0 and direction.z == -1 then
return { x=-1, y=0, z=0 }
else
return nil
end
end
-- returns the position of the next epic block
epic.get_next_pos = function(pos)
local node = minetest.get_node(pos)
local direction = epic.get_direction(node.param2)
if direction == nil then
return
end
local next_pos = vector.add(pos, direction)
return next_pos
end
-- returns a node and loads the area if needed
epic.get_node = function(pos)
local node = minetest.get_node_or_nil(pos)
if node == nil then
minetest.get_voxel_manip(pos, pos)
node = minetest.get_node_or_nil(pos)
end
return node
end
-- returns true if the node has an "epic" definition
epic.is_epic = function(node)
local nodedef = minetest.registered_nodes[node.name]
return nodedef.epic ~= nil
end
-- executes an epic with main and optional exit function
epic.execute_epic = function(player, main_pos, exit_pos, name)
if epic.state[player:get_player_name()] then
-- already running a function
return
end
minetest.log("action", "[epic] player " .. player:get_player_name() ..
" executes function at " .. minetest.pos_to_string(main_pos))
local state = {
ip = main_pos,
name = name,
stack = {},
initialized = false,
exit_pos = exit_pos,
data = {},
step_data = {}
}
epic.state[player:get_player_name()] = state
epic.run_hook("on_execute_epic", { player, main_pos, exit_pos, state })
end