mirror of
https://gitlab.com/4w/mtimer.git
synced 2024-11-24 16:23:44 +01:00
switch to player based configuration
Before all variables and “constants” (configuration variables) were stored in one single global table. Now the players get custom attributes set. This allows player-based displaying of the timer information. This will be done in subsequent commits. Tracking issue: https://github.com/dsohler/mtimer/issues/1
This commit is contained in:
parent
9e4d98d896
commit
d65c1f11ba
145
init.lua
145
init.lua
@ -1,95 +1,64 @@
|
||||
-- Convert a given x,y string into a table {x=given_x, y=given_y} and return
|
||||
-- it to be used of the screen location parameters in the HUD definition
|
||||
local mtimer_location_value = function (o)
|
||||
local given_x = o:gsub(',[^,]+$', '')
|
||||
local given_y = o:gsub('^[^,]+,', '')
|
||||
-- Load default configuration andf functions
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())..DIR_DELIM
|
||||
local config = dofile(modpath..'system'..DIR_DELIM..'get_options.lua')
|
||||
dofile(modpath..'system'..DIR_DELIM..'timer_function.lua')
|
||||
|
||||
|
||||
-- Set custom player attribute if not set
|
||||
--
|
||||
-- Sets a custom player attribute if the attribute is not set already.
|
||||
--
|
||||
-- @param player The player opbject of the player to set the attribute for
|
||||
-- @param attribute The attribute to set if not present
|
||||
-- @param value The value to be set if the attribute does not exist
|
||||
local set_if_unset = function(player, attribute, value)
|
||||
local current_value = player:get_attribute(attribute)
|
||||
if current_value == nil then player:set_attribute(attribute, value) end
|
||||
end
|
||||
|
||||
|
||||
-- Get a position table from a comma-separated position string
|
||||
--
|
||||
-- @param position_string The desired position in `x,y` format
|
||||
--
|
||||
-- @return table The position table
|
||||
mtimer_position = function (position_string)
|
||||
local given_x = position_string:gsub(',[^,]+$', '')
|
||||
local given_y = position_string:gsub('^[^,]+,', '')
|
||||
return {x=given_x, y=given_y}
|
||||
end
|
||||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())..DIR_DELIM
|
||||
local options = dofile(modpath..'system'..DIR_DELIM..'get_options.lua')
|
||||
|
||||
local interval = options['mtimer_update_interval']
|
||||
local placeholder = options['mtimer_placeholder']
|
||||
local font_color = options['mtimer_font_color']
|
||||
|
||||
local format = {
|
||||
locale = options['mtimer_locale'],
|
||||
start = options['mtimer_session_start'],
|
||||
runtime = options['mtimer_session_runtime'],
|
||||
current = options['mtimer_current_time'],
|
||||
ingame = options['mtimer_ingame_time'],
|
||||
output = options['mtimer_output_format']
|
||||
}
|
||||
|
||||
local location = {
|
||||
position = mtimer_location_value(options['mtimer_position']),
|
||||
alignment = mtimer_location_value(options['mtimer_alignment']),
|
||||
offset = mtimer_location_value(options['mtimer_offset'])
|
||||
}
|
||||
|
||||
local player_data = {}
|
||||
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
minetest.after(1, function(player)
|
||||
local player_name = player:get_player_name()
|
||||
local _hud_id = player:hud_add({
|
||||
hud_elem_type = 'text',
|
||||
position = location.position,
|
||||
alignment = location.alignment,
|
||||
offset = location.offset,
|
||||
text = placeholder,
|
||||
number = '0x'..font_color
|
||||
})
|
||||
player_data[player_name] = {
|
||||
start_time = os.time(),
|
||||
hud_id = _hud_id
|
||||
}
|
||||
minetest.after(5, change_text, player)
|
||||
end, player)
|
||||
-- Set default values if not present
|
||||
set_if_unset(player, 'mtimer:runtime', config['mtimer_runtime'])
|
||||
set_if_unset(player, 'mtimer:offset', config['mtimer_offset'])
|
||||
set_if_unset(player, 'mtimer:ingame_time', config['mtimer_ingame_time'])
|
||||
set_if_unset(player, 'mtimer:current_time', config['mtimer_current_time'])
|
||||
set_if_unset(player, 'mtimer:font_color', config['mtimer_font_color'])
|
||||
set_if_unset(player, 'mtimer:start', config['mtimer_start'])
|
||||
set_if_unset(player, 'mtimer:show', config['mtimer_show'])
|
||||
set_if_unset(player, 'mtimer:locale', config['mtimer_locale'])
|
||||
set_if_unset(player, 'mtimer:position', config['mtimer_position'])
|
||||
set_if_unset(player, 'mtimer:format', config['mtimer_format'])
|
||||
set_if_unset(player, 'mtimer:alignment', config['mtimer_alignment'])
|
||||
|
||||
-- Set join timestamp for later calculations
|
||||
player:set_attribute('mtimer:joined_timestamp', os.time())
|
||||
|
||||
-- Set the hud element ID for later usage and set text to the placeholder
|
||||
player:set_attribute('mtimer:hud_id', player:hud_add({
|
||||
hud_elem_type = 'text',
|
||||
position = mtimer_position(player:get_attribute('mtimer:position')),
|
||||
alignment = mtimer_position(player:get_attribute('mtimer:alignment')),
|
||||
offset = mtimer_position(player:get_attribute('mtimer:offset')),
|
||||
text = config['mtimer_placeholder'],
|
||||
number = '0x'..player:get_attribute('mtimer:font_color')
|
||||
}))
|
||||
|
||||
-- Run inital update for the player
|
||||
minetest.after(1, mtimer_update, player)
|
||||
end)
|
||||
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local player_name = player:get_player_name()
|
||||
player_data[player_name] = nil
|
||||
end)
|
||||
|
||||
|
||||
function change_text(player)
|
||||
local player_name = player:get_player_name()
|
||||
if player_name == '' then return end
|
||||
|
||||
-- Save the game-detected locale. Fun fact: changing the locale on runtime
|
||||
-- from within a mod causes the UI to glitch out completely.
|
||||
local current_locale = os.setlocale(nil)
|
||||
os.setlocale(format.locale)
|
||||
|
||||
local start_time = player_data[player_name].start_time
|
||||
local hud_id = player_data[player_name].hud_id
|
||||
|
||||
local time = 24*60*minetest.get_timeofday()
|
||||
local h = tostring((math.floor(time/60) % 60))
|
||||
local m = tostring((math.floor(time) % 60))
|
||||
|
||||
local res = format.output:gsub('(+.)', {
|
||||
['+s'] = os.date(format.start, start_time),
|
||||
['+c'] = os.date(format.current),
|
||||
['+r'] = os.date('!'..format.runtime:gsub('(+.)', {
|
||||
['+h'] = '%H',
|
||||
['+m'] = '%M',
|
||||
['+s'] = '%S'
|
||||
}), os.time() - start_time),
|
||||
['+i'] = format.ingame:gsub('(+.)', {
|
||||
['+h'] = string.rep('0', 2-#h)..h,
|
||||
['+m'] = string.rep('0', 2-#m)..m
|
||||
}),
|
||||
['+n'] = "\n"
|
||||
})
|
||||
|
||||
os.setlocale(current_locale) -- Restore game-detected locale
|
||||
|
||||
player:hud_change(hud_id, 'text', res)
|
||||
minetest.after(interval, change_text, player)
|
||||
end
|
||||
-- Start iteration after 5 seconds
|
||||
minetest.after(5, mtimer_iterate, tonumber(config['mtimer_update_interval']))
|
||||
|
@ -12,11 +12,11 @@ mtimer_update_interval (Seconds between updates) int 30
|
||||
# +r = Runtime of the current session
|
||||
# +i = Current ingame time in 24h format
|
||||
# +n = Following output will be in a new line
|
||||
mtimer_output_format (Output string formatting) string Session from +s+nCurrent time: +c+nPlaytime: +r, Ingame time: +i
|
||||
mtimer_format (Output string formatting) string Session from +s+nCurrent time: +c+nPlaytime: +r, Ingame time: +i
|
||||
|
||||
# A placeholder text that is shown before the timer
|
||||
# function gets executed the first time
|
||||
mtimer_placeholder (Placeholder for the timer) string [MTimer ...]
|
||||
mtimer_placeholder (Placeholder for the timer) string [Initializing MTimer]
|
||||
|
||||
# The font color for the timer text
|
||||
#
|
||||
@ -34,7 +34,7 @@ mtimer_font_color (Font color for the timer text) string babdb6
|
||||
# Time when the current session was started. The session
|
||||
# is based on when the user connected to the world. The
|
||||
# format is this: https://www.lua.org/pil/22.1.html
|
||||
mtimer_session_start ([+s] Session start time) string %c
|
||||
mtimer_start ([+s] Session start time) string %c
|
||||
|
||||
# A hours:minutes timer that allows tracking of the
|
||||
# current play time. The timer breaks if game time
|
||||
@ -43,7 +43,7 @@ mtimer_session_start ([+s] Session start time) string %c
|
||||
# +h = Hours
|
||||
# +m = Minutes
|
||||
# +s = Seconds
|
||||
mtimer_session_runtime ([+r] Session runtime) string +h:+m
|
||||
mtimer_runtime ([+r] Session runtime) string +h:+m
|
||||
|
||||
# The current real-world time according to what the OS
|
||||
# provides. Formatting this string is quite easy by using
|
||||
@ -66,6 +66,10 @@ mtimer_locale (Format output locale) string C
|
||||
|
||||
[Positioning]
|
||||
|
||||
# Regardless of all other configuration: Show the timer
|
||||
# in the GUI of the players - or do noit show it.
|
||||
mtimer_show (Show at all) bool true
|
||||
|
||||
# "To account for differing resolutions, the position
|
||||
# coordinates are the percentage of the screen, ranging
|
||||
# in value from 0 to 1. 0 means left/top, 1 means
|
||||
|
76
system/timer_function.lua
Normal file
76
system/timer_function.lua
Normal file
@ -0,0 +1,76 @@
|
||||
-- Update an idividual player’s timer display
|
||||
--
|
||||
-- When running the function the player data will be read from the player’s
|
||||
-- `player` object and the output will be generated
|
||||
--
|
||||
-- @param player the player object to update
|
||||
mtimer_update = function (player)
|
||||
-- Formatting options
|
||||
local runtime = player:get_attribute('mtimer:runtime')
|
||||
local offset = mtimer_position(player:get_attribute('mtimer:offset'))
|
||||
local ingame_time = player:get_attribute('mtimer:ingame_time')
|
||||
local current_time = player:get_attribute('mtimer:current_time')
|
||||
local font_color = player:get_attribute('mtimer:font_color')
|
||||
local start = player:get_attribute('mtimer:start')
|
||||
local show = player:get_attribute('mtimer:show')
|
||||
local locale = player:get_attribute('mtimer:locale')
|
||||
local position = mtimer_position(player:get_attribute('mtimer:position'))
|
||||
local format = player:get_attribute('mtimer:format')
|
||||
local alignment = mtimer_position(player:get_attribute('mtimer:alignment'))
|
||||
|
||||
-- Settings
|
||||
local joined_timestamp = player:get_attribute('mtimer:joined_timestamp')
|
||||
local hud_id = tonumber(player:get_attribute('mtimer:hud_id'))
|
||||
|
||||
-- Calculate ingame time
|
||||
local ingame_timestamp = 24*60*minetest.get_timeofday()
|
||||
local ingame_h = tostring((math.floor(ingame_timestamp/60) % 60))
|
||||
local ingame_m = tostring((math.floor(ingame_timestamp) % 60))
|
||||
|
||||
-- Replace variables in output format if wanted by the user
|
||||
local rendered_output_format = ''
|
||||
if show == 'true' then
|
||||
rendered_output_format = format:gsub('+.', {
|
||||
['+s'] = os.date(start, joined_timestamp),
|
||||
['+c'] = os.date(current_time),
|
||||
['+r'] = os.date('!'..runtime:gsub('(+.)', {
|
||||
['+h'] = '%H',
|
||||
['+m'] = '%M',
|
||||
['+s'] = '%S'
|
||||
}), os.time() - joined_timestamp),
|
||||
['+i'] = ingame_time:gsub('(+.)', {
|
||||
['+h'] = string.rep('0', 2-#ingame_h)..ingame_h,
|
||||
['+m'] = string.rep('0', 2-#ingame_m)..ingame_m
|
||||
}),
|
||||
['+n'] = "\n"
|
||||
})
|
||||
end
|
||||
|
||||
-- Render the output format as HUD element
|
||||
player:hud_change(hud_id, 'text', rendered_output_format)
|
||||
player:hud_change(hud_id, 'number', '0x'..font_color)
|
||||
player:hud_change(hud_id, 'position', position)
|
||||
player:hud_change(hud_id, 'alignment', alignment)
|
||||
player:hud_change(hud_id, 'offset', offset)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Self-calling iteration function
|
||||
--
|
||||
-- The function iterates of all currentlz logged on players, checks if they
|
||||
-- have the custom attribute `mtimer:hud_id` set (this is the last value that
|
||||
-- will be set when a player joins so the player is set up completely if
|
||||
-- `mtimer:hud_id` is present in the custom player attributes) and then runs
|
||||
-- the function to update the timer display. After that the function calls
|
||||
-- itself again, using the set interval.
|
||||
--
|
||||
-- @param interval The intervall used to self-calling again after execution
|
||||
mtimer_iterate = function(interval)
|
||||
for _,player in pairs(minetest.get_connected_players()) do
|
||||
if player:get_attribute('mtimer:hud_id') ~= nil then
|
||||
mtimer_update(player)
|
||||
end
|
||||
end
|
||||
minetest.after(interval, mtimer_iterate, interval)
|
||||
end
|
Loading…
Reference in New Issue
Block a user