496 lines
15 KiB
Lua
496 lines
15 KiB
Lua
--debug_status = 1
|
|
debug_mod_name = "TimeTools"
|
|
debug_file = debug_mod_name .. "-debug.txt"
|
|
require("utils")
|
|
--require("config")
|
|
|
|
local ticks_per_day = 25000
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function init_day()
|
|
global.day = 1 + math.floor((game.tick+(ticks_per_day/2)) / ticks_per_day)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function get_time()
|
|
-- daytime : 0.0 to 1.0, noon to noon (midnight at 0.5), max light to min light to max light...
|
|
-- game starts at daytime = 0, so noon of day 1.
|
|
|
|
local daytime
|
|
local always_day = global.surface.always_day or 0
|
|
|
|
if global.always_day ~= always_day then
|
|
global.refresh_always_day = true
|
|
end
|
|
|
|
if always_day then
|
|
daytime = game.tick / ticks_per_day
|
|
daytime = daytime - math.floor(daytime)
|
|
else
|
|
if global.always_day == true then
|
|
daytime = ((global.h + 12) + (global.m / 60)) / 24
|
|
global.surface.daytime = daytime - math.floor(daytime)
|
|
end
|
|
daytime = global.surface.daytime
|
|
end
|
|
|
|
daytime = (daytime*24+12) % 24
|
|
global.h = math.floor(daytime)
|
|
global.m = math.floor((daytime-global.h)*60)
|
|
-- day calculation independant of hour
|
|
global.day = math.floor((game.tick+(ticks_per_day/2)) / ticks_per_day) + 1
|
|
|
|
global.always_day = always_day
|
|
global.h_prev = global.h
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function init_globals()
|
|
-- initialize or update general globals of the mod
|
|
debug_print( "init_globals" )
|
|
|
|
global.ticks = global.ticks or 0
|
|
global.cycles = global.cycles or 0
|
|
global.surface = game.surfaces.nauvis
|
|
|
|
if global.offset == nil then global.offset = 0 end
|
|
if global.h == nil then global.h = 12 end
|
|
if global.m == nil then global.m = 0 end
|
|
global.h_prev = global.h_prev or 23
|
|
global.always_day = global.always_day or -1 -- -1 to force update of the icon at first install
|
|
global.refresh_always_day = true
|
|
|
|
if not settings.global["timetools-always-day"].value then global.surface.always_day = false end
|
|
|
|
if global.day == nil then
|
|
init_day()
|
|
get_time()
|
|
end
|
|
|
|
if global.frozen == nil then global.frozen = false end
|
|
if global.display == nil then global.display = true end
|
|
global.clocks = global.clocks or {}
|
|
|
|
global.speed_mem = global.speed_mem or settings.global["timetools-maximum-speed"].value
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function init_player(player)
|
|
if global.ticks == nil then return end
|
|
|
|
-- initialize or update per player globals of the mod, and reset the gui
|
|
debug_print( "init_player ", player.name, " connected=", player.connected )
|
|
|
|
if player.connected then
|
|
build_gui(player)
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function init_players()
|
|
for _, player in pairs(game.players) do
|
|
init_player(player)
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function init_forces()
|
|
for _,force in pairs(game.forces) do
|
|
force.recipes["clock-combinator"].enabled = force.technologies["circuit-network"].researched
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function on_init()
|
|
-- called once, the first time the mod is loaded on a game (new or existing game)
|
|
debug_print( "on_init" )
|
|
init_globals()
|
|
init_forces()
|
|
init_players()
|
|
end
|
|
|
|
script.on_init(on_init)
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function on_configuration_changed(data)
|
|
-- detect any mod or game version change
|
|
if data.mod_changes ~= nil then
|
|
local changes = data.mod_changes[debug_mod_name]
|
|
if changes ~= nil then
|
|
debug_print( "update mod: ", debug_mod_name, " ", tostring(changes.old_version), " to ", tostring(changes.new_version) )
|
|
|
|
init_globals()
|
|
|
|
global.always_day = -1 -- to force update of icon
|
|
|
|
init_forces()
|
|
|
|
-- migrations
|
|
for _, player in pairs(game.players) do
|
|
if player.gui.top.timebar_frame then player.gui.top.timebar_frame.destroy() end -- destroy old bar
|
|
end
|
|
if changes.old_version ~= nil and older_version(changes.old_version, "1.0.18") then
|
|
init_day()
|
|
end
|
|
if changes.old_version ~= nil and older_version(changes.old_version, "1.0.34") then
|
|
for _, player in pairs(game.players) do
|
|
if player.gui.top.timetools_flow then player.gui.top.timetools_flow.destroy() end -- rebuild bar
|
|
end
|
|
end
|
|
if changes.old_version ~= nil and older_version(changes.old_version, "2.0.41") then
|
|
for _, player in pairs(game.players) do
|
|
if player.gui.top.timetools_flow then player.gui.top.timetools_flow.destroy() end -- rebuild bar
|
|
end
|
|
end
|
|
init_players()
|
|
|
|
update_guis()
|
|
end
|
|
end
|
|
end
|
|
|
|
script.on_configuration_changed(on_configuration_changed)
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function on_player_created(event)
|
|
-- called at player creation
|
|
local player = game.players[event.player_index]
|
|
debug_print( "player created ", player.name )
|
|
|
|
init_player(player)
|
|
end
|
|
|
|
script.on_event(defines.events.on_player_created, on_player_created )
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function on_player_joined_game(event)
|
|
-- called in SP(once) and MP(every connect), eventually after on_player_created
|
|
local player = game.players[event.player_index]
|
|
debug_print( "player joined ", player.name )
|
|
|
|
init_player(player)
|
|
end
|
|
|
|
script.on_event(defines.events.on_player_joined_game, on_player_joined_game )
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function on_creation( event )
|
|
local ent = event.created_entity
|
|
|
|
if ent.name == "clock-combinator" then
|
|
debug_print( "clock-combinator created" )
|
|
|
|
table.insert( global.clocks,
|
|
{
|
|
entity = ent,
|
|
}
|
|
)
|
|
|
|
debug_print( "clocks=" .. #global.clocks )
|
|
end
|
|
end
|
|
|
|
script.on_event(defines.events.on_built_entity, on_creation )
|
|
script.on_event(defines.events.on_robot_built_entity, on_creation )
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function on_destruction( event )
|
|
local ent = event.entity
|
|
|
|
if ent.name == "clock-combinator" then
|
|
debug_print( "clock-combinator destroyed" )
|
|
|
|
for i, clock in ipairs(global.clocks) do
|
|
if clock.entity == ent then
|
|
table.remove( global.clocks, i )
|
|
break
|
|
end
|
|
end
|
|
|
|
debug_print( "clocks=" .. #global.clocks )
|
|
end
|
|
end
|
|
|
|
script.on_event(defines.events.on_entity_died, on_destruction )
|
|
script.on_event(defines.events.on_robot_pre_mined, on_destruction )
|
|
script.on_event(defines.events.on_pre_player_mined_item, on_destruction )
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function format_time()
|
|
local sTime = ""
|
|
sTime = string.format("%u-%02u:%02u", global.day, global.h, global.m )
|
|
return sTime
|
|
end
|
|
|
|
local function on_tick(event)
|
|
if global.speed_mem > settings.global["timetools-maximum-speed"].value then
|
|
-- User changed the speed mid acceleration or on the fly
|
|
global.speed_mem = settings.global["timetools-maximum-speed"].value
|
|
if game.speed > global.speed_mem then
|
|
game.speed = global.speed_mem
|
|
update_guis()
|
|
end
|
|
end
|
|
if (game.tick % settings.global["timetools-clock-update-interval"].value) == 0 then
|
|
get_time()
|
|
|
|
-- update time display on button
|
|
|
|
if global.display then
|
|
local s_time = format_time()
|
|
local flow
|
|
|
|
for _, player in pairs(game.players) do
|
|
if player.connected and player.gui.top.timetools_flow then
|
|
flow = player.gui.top.timetools_flow
|
|
if flow.timetools_but_time == nil or (debug_status and flow.timetools_but_tick == nil) then
|
|
flow.destroy()
|
|
init_player(player)
|
|
update_guis()
|
|
flow = player.gui.top.timetools_flow -- re-assign
|
|
end
|
|
flow.timetools_but_time.caption = s_time
|
|
|
|
if global.refresh_always_day then
|
|
if global.surface.always_day then
|
|
flow.timetools_but_always.sprite = "sprite_timetools_alwday"
|
|
else
|
|
flow.timetools_but_always.sprite = "sprite_timetools_night"
|
|
end
|
|
end
|
|
if debug_status then
|
|
flow.timetools_but_tick.caption = game.tick
|
|
end
|
|
end
|
|
end
|
|
|
|
global.refresh_always_day = false
|
|
end
|
|
end
|
|
if (game.tick % settings.global["timetools-combinator-interval"].value) == 0 then
|
|
for i, clock in pairs(global.clocks) do
|
|
if clock.entity.valid then
|
|
params = {
|
|
{index=1,signal={type="virtual",name="signal-clock-gametick"},count=math.floor(game.tick)},
|
|
{index=2,signal={type="virtual",name="signal-clock-day"},count=global.day},
|
|
{index=3,signal={type="virtual",name="signal-clock-hour"},count=global.h},
|
|
{index=4,signal={type="virtual",name="signal-clock-minute"},count=global.m},
|
|
{index=5,signal={type="virtual",name="signal-clock-alwaysday"},count=iif(global.surface.always_day,1,0)},
|
|
{index=6,signal={type="virtual",name="signal-clock-darkness"},count=math.floor(global.surface.darkness*100)},
|
|
{index=7,signal={type="virtual",name="signal-clock-lightness"},count=math.floor((1-global.surface.darkness)*100)},
|
|
}
|
|
clock.entity.get_control_behavior().parameters = params
|
|
else
|
|
table.remove(global.clocks,i)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
script.on_event(defines.events.on_tick, on_tick)
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local function on_gui_click(event)
|
|
local player = game.players[event.player_index]
|
|
if string.match(event.element.name, "timetools_") == nil then
|
|
-- not for us
|
|
return
|
|
end
|
|
if player.admin then
|
|
if event.element.name == "timetools_but_time" then
|
|
if not global.surface.always_day then
|
|
global.frozen = not global.frozen
|
|
global.surface.freeze_daytime = global.frozen
|
|
update_guis()
|
|
end
|
|
|
|
elseif event.element.name == "timetools_but_always" then
|
|
if settings.global["timetools-always-day"].value then
|
|
global.surface.always_day = not global.surface.always_day
|
|
|
|
if global.surface.always_day then
|
|
global.frozen = false
|
|
end
|
|
end
|
|
update_guis()
|
|
|
|
elseif event.element.name == "timetools_but_slower" then
|
|
if game.speed >= 0.2 then game.speed = game.speed / 2 end -- minimum 0.1
|
|
if game.speed ~= 1 then global.speed_mem = game.speed end
|
|
update_guis()
|
|
|
|
elseif event.element.name == "timetools_but_faster" then
|
|
if game.speed < settings.global["timetools-maximum-speed"].value then game.speed = game.speed * 2 end
|
|
if game.speed ~= 1 then global.speed_mem = game.speed end
|
|
update_guis()
|
|
|
|
elseif event.element.name == "timetools_but_speed" then
|
|
if game.speed == 1 then game.speed = global.speed_mem else game.speed = 1 end
|
|
update_guis()
|
|
end
|
|
else
|
|
player.print({"mod-messages.timetools-message-admins-only"})
|
|
end
|
|
end
|
|
|
|
script.on_event(defines.events.on_gui_click, on_gui_click )
|
|
|
|
--------------------------------------------------------------------------------------
|
|
function build_gui( player )
|
|
local gui1 = player.gui.top.timetools_flow
|
|
|
|
if gui1 == nil and global.display then
|
|
debug_print("create frame player" .. player.name)
|
|
gui1 = player.gui.top.add({type = "flow", name = "timetools_flow", direction = "horizontal", style = "timetools_flow_style"})
|
|
local gui2 = gui1.add({type = "button", name = "timetools_but_time", caption = "0-00:00", font_color = colors.white, style = "timetools_botton_time_style"})
|
|
if global.frozen then
|
|
gui2.style.font_color = colors.lightred
|
|
else
|
|
gui2.style.font_color = colors.green
|
|
end
|
|
gui2 = gui1.add({type = "sprite-button", name = "timetools_but_always", style = "timetools_sprite_style"})
|
|
if global.surface.always_day then
|
|
gui2.sprite = "sprite_timetools_alwday"
|
|
else
|
|
gui2.sprite = "sprite_timetools_night"
|
|
end
|
|
gui1.add({type = "button", name = "timetools_but_slower", caption = "<" , font_color = colors.white, style = "timetools_button_style"})
|
|
gui1.add({type = "button", name = "timetools_but_faster", caption = ">" , font_color = colors.white, style = "timetools_button_style"})
|
|
gui1.add({type = "button", name = "timetools_but_speed", caption = "x1" , font_color = colors.white, style = "timetools_button_style"})
|
|
if debug_status then
|
|
gui1.add({type = "button", name = "timetools_but_tick", caption = "0" , font_color = colors.white, style = "timetools_button_style"})
|
|
end
|
|
end
|
|
return( gui1 )
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------
|
|
function update_guis()
|
|
if global.display then
|
|
for _, player in pairs(game.players) do
|
|
if player.connected then
|
|
local flow = build_gui(player)
|
|
local s
|
|
|
|
if game.speed == 1 then
|
|
flow.timetools_but_speed.caption = "x1"
|
|
flow.timetools_but_speed.style.font_color = colors.white
|
|
elseif game.speed < 1 then
|
|
s = string.format("/%1.0f", 1/game.speed )
|
|
flow.timetools_but_speed.caption = s
|
|
flow.timetools_but_speed.style.font_color = colors.green
|
|
elseif game.speed > 1 then
|
|
s = string.format("x%1.0f", game.speed )
|
|
flow.timetools_but_speed.caption = s
|
|
flow.timetools_but_speed.style.font_color = colors.lightred
|
|
end
|
|
|
|
if global.surface.always_day then
|
|
flow.timetools_but_always.sprite = "sprite_timetools_alwday"
|
|
else
|
|
flow.timetools_but_always.sprite = "sprite_timetools_night"
|
|
end
|
|
|
|
if global.frozen then
|
|
flow.timetools_but_time.style.font_color = colors.lightred
|
|
else
|
|
flow.timetools_but_time.style.font_color = colors.green
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------
|
|
|
|
local interface = {}
|
|
|
|
function interface.reset()
|
|
debug_print( "reset" )
|
|
|
|
init_day()
|
|
|
|
for _,force in pairs(game.forces) do
|
|
force.reset_recipes()
|
|
force.reset_technologies()
|
|
end
|
|
|
|
for _, player in pairs(game.players) do
|
|
if player.gui.top.timetools_flow then
|
|
player.gui.top.timetools_flow.destroy()
|
|
end
|
|
end
|
|
|
|
update_guis()
|
|
end
|
|
|
|
function interface.setclock( hhmm )
|
|
debug_print( "setclock" )
|
|
|
|
if hhmm == nil then hhmm = 0 end
|
|
if hhmm < 0 then hhmm = 0 end
|
|
if hhmm >= 24 then hhmm = 23.59 end
|
|
|
|
local mm = (hhmm - math.floor(hhmm)) * 100
|
|
local hh = math.floor(hhmm)
|
|
|
|
if mm >= 60 then mm = 59 end
|
|
|
|
global.surface.always_day = false
|
|
global.surface.daytime = math.min((((hh+12)%24) * 60 + mm) / 24 / 60,1)
|
|
global.frozen = false
|
|
global.h = hh
|
|
global.m = mm
|
|
|
|
update_guis()
|
|
end
|
|
|
|
function interface.setspeed(speed)
|
|
debug_print( "set time" )
|
|
if speed == nil then speed = 1 end
|
|
speed = math.floor(speed) -- ensure integer
|
|
if speed < 1 then speed = 1 end
|
|
if speed > settings.global["timetools-maximum-speed"].value then
|
|
speed = settings.global["timetools-maximum-speed"].value
|
|
end
|
|
global.speed = speed
|
|
update_guis()
|
|
end
|
|
|
|
function interface.setfrozen( frozen )
|
|
debug_print( "frozen" )
|
|
|
|
global.frozen = frozen
|
|
|
|
update_guis()
|
|
end
|
|
|
|
function interface.off( )
|
|
debug_print( "off" )
|
|
|
|
global.display = false
|
|
|
|
for _, player in pairs(game.players) do
|
|
if player.connected and player.gui.top.timetools_flow then player.gui.top.timetools_flow.destroy() end
|
|
end
|
|
end
|
|
|
|
function interface.on( )
|
|
debug_print( "on" )
|
|
|
|
global.display = true
|
|
|
|
update_guis()
|
|
end
|
|
|
|
|
|
remote.add_interface( "timetools", interface )
|
|
|
|
-- /c remote.call( "timetools", "setclock", 20.15 )
|
|
-- /c remote.call( "timetools", "reset" )
|
|
-- /c remote.call( "timetools", "on" )
|
|
-- /c remote.call( "timetools", "off" )
|
|
-- /c remote.call( "timetools", "setfrozen", true )
|
|
-- /c remote.call( "timetools", "setspeed", 2 )
|
|
|