mirror of
https://gitlab.com/4w/mtimer.git
synced 2024-11-24 08:13:48 +01:00
351 lines
14 KiB
Lua
351 lines
14 KiB
Lua
local m = mtimer
|
||
local d = mtimer.dialog
|
||
|
||
|
||
-- When formspec data is sent to the server check for the formname and run the
|
||
-- specific action for the given form. See Individual descriptions. The code
|
||
-- for this is very simple because most of the logic is handled in the
|
||
-- timer functions and not in the formspec code.
|
||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||
if not player:is_player() then return end
|
||
local meta = player:get_meta()
|
||
local name = player:get_player_name()
|
||
|
||
|
||
-- Select what formspec to show basing on main menu button
|
||
if formname == 'mtimer:main_menu' then
|
||
if fields.set_visibility then d.set_visibility(name) end
|
||
if fields.set_position then d.set_position(name) end
|
||
if fields.set_color then d.set_color(name) end
|
||
if fields.timezone_offset then d.timezone_offset(name) end
|
||
if fields.ingame_time_format then d.ingame_time_format(name) end
|
||
if fields.real_world_time_format then d.real_world_time_format(name) end
|
||
if fields.host_time_format then d.host_time_format(name) end
|
||
if fields.session_start_time_format then
|
||
d.session_start_time_format(name)
|
||
end
|
||
if fields.session_duration_format then
|
||
d.session_duration_format(name)
|
||
end
|
||
if fields.hud_element_scale then d.hud_element_scale(name) end
|
||
if fields.hud_element_offset then d.hud_element_offset(name) end
|
||
if fields.timer_format then d.timer_format(name) end
|
||
if fields.custom_timer then d.custom_timer(name) end
|
||
if fields.reset_everything then d.reset_everything(name) end
|
||
end
|
||
|
||
|
||
-- Set timer visibility
|
||
if formname == 'mtimer:set_visibility' then
|
||
local attr = m.meta.visible
|
||
if fields.set_visible then meta:set_string(attr.key, 'true') end
|
||
if fields.set_invisible then meta:set_string(attr.key, 'false') end
|
||
if fields.default then meta:set_string(attr.key, attr.default) end
|
||
if not fields.quit then d.set_visibility(name) end
|
||
end
|
||
|
||
|
||
-- Set timer position
|
||
if formname == 'mtimer:set_position' then
|
||
local attr = m.meta.position
|
||
for p,_ in pairs(fields) do
|
||
if p == 'default' then
|
||
meta:set_string(attr.key, attr.default)
|
||
elseif p:gsub('_.*', '') == 'pos' then
|
||
local new_pos = p:gsub('pos_', '')
|
||
if new_pos ~= 'xx' then meta:set_string(attr.key, new_pos) end
|
||
end
|
||
end
|
||
if not fields.quit then d.set_position(name) end
|
||
end
|
||
|
||
|
||
-- Set timer text color
|
||
if formname == 'mtimer:set_color' then
|
||
local attr = m.meta.color
|
||
local color = ''
|
||
|
||
-- Set fields.color to predefined color if a button was clicked
|
||
if fields.set_color ~= nil then
|
||
fields.color = '#'..fields.set_color
|
||
end
|
||
|
||
-- Validate the given color and set it
|
||
if fields.color then
|
||
local valid = fields.color:match('^#'..('[0-9a-fA-F]'):rep(6)..'$')
|
||
local color = valid and fields.color or attr.default
|
||
meta:set_string(attr.key, color)
|
||
end
|
||
|
||
if fields.default then meta:set_string(attr.key, attr.default) end
|
||
if not fields.quit then d.set_color(name) end
|
||
end
|
||
|
||
|
||
-- Configure timezone offset
|
||
if formname == 'mtimer:timezone_offset' then
|
||
local attr = m.meta.timezone_offset
|
||
local value = tonumber(fields.offset) or attr.default
|
||
|
||
-- Check if a timezone offset button was clicked
|
||
for p,_ in pairs(fields) do
|
||
if string.sub(p,1,11) == 'new_offset_' then
|
||
value = tonumber((p:gsub('new_offset_', '')))
|
||
end
|
||
end
|
||
|
||
-- Validate and set new timezone offset
|
||
if fields.offset then
|
||
if value > 12 then value = 12 end
|
||
if value < -12 then value = -12 end
|
||
meta:set_string(attr.key, value)
|
||
end
|
||
|
||
if fields.default then meta:set_string(attr.key, attr.default) end
|
||
if not fields.quit then d.timezone_offset(name) end
|
||
end
|
||
|
||
|
||
-- Set ingame time format
|
||
if formname == 'mtimer:ingame_time_format' then
|
||
local attr = m.meta.ingame_time_format
|
||
local value = fields.format or attr.default
|
||
meta:set_string(attr.key, value)
|
||
if fields.default then meta:set_string(attr.key, attr.default) end
|
||
if not fields.quit then d.ingame_time_format(name)end
|
||
end
|
||
|
||
|
||
-- Set real-time format
|
||
if formname == 'mtimer:real_world_time_format' then
|
||
local attr = m.meta.real_time_format
|
||
local value = fields.format or attr.default
|
||
meta:set_string(attr.key, value)
|
||
if fields.default then meta:set_string(attr.key, attr.default) end
|
||
if not fields.quit then d.real_world_time_format(name) end
|
||
end
|
||
|
||
|
||
-- Set host time format
|
||
if formname == 'mtimer:host_time_format' then
|
||
local attr = m.meta.host_time_format
|
||
local value = fields.format or attr.default
|
||
meta:set_string(attr.key, value)
|
||
if fields.default then meta:set_string(attr.key, attr.default) end
|
||
if not fields.quit then d.host_time_format(name) end
|
||
end
|
||
|
||
|
||
-- Set session start time format
|
||
if formname == 'mtimer:session_start_time_format' then
|
||
local attr = m.meta.session_start_time_format
|
||
local value = fields.format or attr.default
|
||
meta:set_string(attr.key, value)
|
||
if fields.default then meta:set_string(attr.key, attr.default) end
|
||
if not fields.quit then d.session_start_time_format(name) end
|
||
end
|
||
|
||
|
||
-- Set session duration format
|
||
if formname == 'mtimer:session_duration_format' then
|
||
local attr = m.meta.session_duration_format
|
||
local value = fields.format or attr.default
|
||
meta:set_string(attr.key, value)
|
||
if fields.default then meta:set_string(attr.key, attr.default) end
|
||
if not fields.quit then d.session_duration_format(name) end
|
||
end
|
||
|
||
|
||
-- Set scale of the timer HUD element
|
||
if formname == 'mtimer:hud_element_scale' then
|
||
local attr = m.meta.hud_element_scale
|
||
local value = tonumber(attr.default)
|
||
local nv_data = minetest.explode_scrollbar_event(fields.new_value)
|
||
|
||
-- Set new value if value was changed
|
||
if nv_data.type == 'CHG' then
|
||
value = nv_data.value
|
||
if value < 1 then value = 1 end
|
||
if value > 10 then value = 10 end
|
||
meta:set_string(attr.key, value)
|
||
end
|
||
|
||
-- DEVELOPERS: Ideally this formspec would fully reset (like when
|
||
-- closed and re-opened) to reflect the scale position when
|
||
-- clicking the “Default” button. But for whatever reason
|
||
-- this does not work. The scollbar position is simply
|
||
-- not set accordingly no matter what I tried.
|
||
--
|
||
-- A pesky pseudosolution is to accept what it is and just
|
||
-- inform the player about this fact.
|
||
--
|
||
-- Trust me, I tried for roughly 1-2 hours before giving
|
||
-- up, without having either the formspec not reset when
|
||
-- clicking the default button or not being able to drag
|
||
-- the scollbar because the formspec gets re-sent.
|
||
--
|
||
-- I even tried to manually closing the formspec and
|
||
-- re-opening it via `minetest.after` to prevent race
|
||
-- conditions. This worked with a delay of 0.1 seconds
|
||
-- every now and then and with smaller delays the whole
|
||
-- screen looked like it “flashed” because, well, the
|
||
-- formspec was closed and then re-opened after the delay.
|
||
--
|
||
-- But I absolutely hate the solution so I just accepted
|
||
-- how it works. If everyone ever reading this and knows
|
||
-- a proper solution to re-sent the formspec and have it
|
||
-- using the actual value instead of keeping the previous
|
||
-- value I’d be glad hearing from you :)
|
||
--
|
||
-- Have awonderful day!
|
||
--
|
||
-- Kind regards,
|
||
-- Dirk
|
||
if fields.default then
|
||
-- This works as expected
|
||
meta:set_string(attr.key, attr.default)
|
||
-- it should reset the scrollbar position here when clicking the
|
||
-- default button but it doesn’t …
|
||
d.hud_element_scale(name)
|
||
end
|
||
end
|
||
|
||
|
||
-- Set offset (used as border/padding) of the timer HUD element
|
||
if formname == 'mtimer:hud_element_offset' then
|
||
local attr = m.meta.hud_element_offset
|
||
local default = minetest.deserialize(attr.default)
|
||
local x_offset = tonumber(fields.x_offset) or default.x
|
||
local y_offset = tonumber(fields.y_offset) or default.y
|
||
|
||
if fields.x_add_1 then x_offset = x_offset + 1 end
|
||
if fields.y_add_1 then y_offset = y_offset + 1 end
|
||
if fields.x_substract_1 then x_offset = x_offset - 1 end
|
||
if fields.y_substract_1 then y_offset = y_offset - 1 end
|
||
|
||
meta:set_string(attr.key, minetest.serialize({
|
||
x = x_offset,
|
||
y = y_offset
|
||
}))
|
||
|
||
if fields.default then meta:set_string(attr.key, attr.default) end
|
||
if not fields.quit then d.hud_element_offset(name) end
|
||
end
|
||
|
||
|
||
-- Set timer text
|
||
if formname == 'mtimer:timer_format' then
|
||
local attr = m.meta.timer_format
|
||
local value = fields.format or attr.default
|
||
meta:set_string(attr.key, value)
|
||
if fields.default then meta:set_string(attr.key, attr.default) end
|
||
if not fields.quit then d.timer_format(name) end
|
||
end
|
||
|
||
|
||
-- Custom timer setting and configuration
|
||
if formname == 'mtimer:custom_timer' then
|
||
local attr = m.meta.custom_timer_settings
|
||
local ctv = minetest.deserialize(meta:get_string(attr.key))
|
||
local entered = fields.key_enter_field or ''
|
||
|
||
-- Set mode
|
||
if fields.mode_countdown ~= nil then ctv.timer_mode='countdown' end
|
||
if fields.mode_timer ~= nil then ctv.timer_mode='timer' end
|
||
if fields.mode_continuous ~= nil then ctv.timer_mode='continuous' end
|
||
|
||
-- Validate direct input
|
||
local days = tonumber(fields.v_days) or 0
|
||
local hours = tonumber(fields.v_hours) or 0
|
||
local minutes = tonumber(fields.v_minutes) or 0
|
||
local seconds = tonumber(fields.v_seconds) or 0
|
||
|
||
-- Set values from plus/minus input
|
||
if fields.c_days_p then days = days + 1 end
|
||
if fields.c_hours_p then hours = hours + 1 end
|
||
if fields.c_minutes_p then minutes = minutes + 1 end
|
||
if fields.c_seconds_p then seconds = seconds + 1 end
|
||
if fields.c_days_m then days = days - 1 end
|
||
if fields.c_hours_m then hours = hours - 1 end
|
||
if fields.c_minutes_m then minutes = minutes - 1 end
|
||
if fields.c_seconds_m then seconds = seconds - 1 end
|
||
|
||
-- Validate values
|
||
if seconds >= 60 then seconds = 0 minutes = minutes + 1 end
|
||
if minutes >= 60 then minutes = 0 hours = hours + 1 end
|
||
if hours >= 24 then hours = 0 days = days + 1 end
|
||
if seconds < 0 then seconds = 59 minutes = minutes - 1 end
|
||
if minutes < 0 then minutes = 59 hours = hours - 1 end
|
||
if hours < 0 then hours = 23 days = days - 1 end
|
||
if days < 0 then days = 0 end
|
||
|
||
-- set relevant values
|
||
ctv.format = {
|
||
running = fields.v_format_running,
|
||
stopped = fields.v_format_stopped,
|
||
finished = fields.v_format_finished
|
||
}
|
||
ctv.values = {
|
||
days = days,
|
||
hours = hours,
|
||
minutes = minutes,
|
||
seconds = seconds
|
||
}
|
||
|
||
-- Set default values if requested and instantly return to prevent the
|
||
-- rest of the configuration to be executed. At this point only
|
||
-- resetting all values is desired.
|
||
if fields.default then
|
||
meta:set_string(attr.key, attr.default)
|
||
d.custom_timer(name)
|
||
m.update_timer(name)
|
||
return
|
||
end
|
||
|
||
-- Set values if not quitting
|
||
if not fields.quit then
|
||
meta:set_string(attr.key, minetest.serialize(ctv))
|
||
end
|
||
|
||
-- Control timer if one of the control buttons was pressed. This is run
|
||
-- after the values safing in order to use the new values instead of
|
||
-- the values that were stored before.
|
||
local ct_update = false
|
||
if fields.ct_start then ct_update = { action = 'start' } end
|
||
if fields.ct_stop then ct_update = { action = 'stop' } end
|
||
if fields.ct_restart then ct_update = { action = 'restart' } end
|
||
if ct_update~=false then mtimer.update_custom_timer(name,ct_update) end
|
||
|
||
-- Show the timer formspec if not quitting
|
||
if not fields.quit then d.custom_timer(name) end
|
||
end
|
||
|
||
|
||
-- Reset everything
|
||
if formname == 'mtimer:reset_everything' then
|
||
local kick_message = m.translator('You requested a hard reset of the mTimer configuration. This request was stored. As described, you were kicked from the server in order to have the hard reset performed. Please rejoin the server. On rejoin all previously stored configuration regarding mTimer will be deleted.')
|
||
|
||
-- Perform a soft reset
|
||
if fields.reset_soft then
|
||
for _,def in pairs(m.meta) do
|
||
meta:set_string(def.key, def.default)
|
||
end
|
||
end
|
||
|
||
-- Request hard reset and kick the player with informational message
|
||
if fields.reset_hard then
|
||
meta:set_int(m.meta.hard_reset_everything.key, os.time())
|
||
minetest.kick_player(name, kick_message)
|
||
end
|
||
|
||
-- Show main menu formspec when cancelled or close on fields.quit
|
||
if fields.reset_cancel then d.main_menu(name) return end
|
||
if not fields.quit then d.reset_everything(name) end
|
||
end
|
||
|
||
|
||
-- Back to menu from all formspecs and conditionally update timer
|
||
if fields.main_menu then d.main_menu(name) end
|
||
if formname ~= 'mtimer:main_menu' then m.update_timer(name) end
|
||
end)
|