2018-12-09 17:50:16 +02:00
|
|
|
-- For more info on the day/night cycle and examples of cycles see: https://github.com/Refactorio/RedMew/wiki/Day-Night-cycle
|
2019-02-02 03:09:12 +02:00
|
|
|
-- Dependencies
|
|
|
|
local Event = require 'utils.event'
|
2019-01-15 15:27:48 +02:00
|
|
|
local math = require 'utils.math'
|
2019-02-02 03:09:12 +02:00
|
|
|
local RS = require 'map_gen.shared.redmew_surface'
|
|
|
|
|
|
|
|
-- Localized global table
|
|
|
|
local config = global.config.day_night
|
|
|
|
|
|
|
|
-- Localized functions
|
|
|
|
local round = math.round
|
|
|
|
local format = string.format
|
2018-12-09 17:50:16 +02:00
|
|
|
|
2019-02-02 03:09:12 +02:00
|
|
|
-- Constants
|
2018-12-09 17:50:16 +02:00
|
|
|
local day_night_cycle_keys = {
|
|
|
|
'ticks_per_day',
|
|
|
|
'dusk',
|
|
|
|
'evening',
|
|
|
|
'morning',
|
2019-02-02 03:09:12 +02:00
|
|
|
'dawn'
|
2018-12-09 17:50:16 +02:00
|
|
|
}
|
|
|
|
|
2019-02-02 03:09:12 +02:00
|
|
|
-- Local vars
|
|
|
|
local Public = {}
|
|
|
|
|
|
|
|
--- Checks that a table is a valid day night cycle.
|
2018-12-09 17:50:16 +02:00
|
|
|
local function check_cycle_validity(day_night_cycle)
|
|
|
|
for _, required_key in pairs(day_night_cycle_keys) do
|
|
|
|
if not day_night_cycle[required_key] then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-02-02 03:09:12 +02:00
|
|
|
if (day_night_cycle['dusk'] > day_night_cycle['evening']) or (day_night_cycle['evening'] > day_night_cycle['morning']) or (day_night_cycle['morning'] > day_night_cycle['dawn']) then
|
2018-12-09 17:50:16 +02:00
|
|
|
return false
|
|
|
|
else
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-02-02 03:09:12 +02:00
|
|
|
--- On init, check the config settings
|
|
|
|
local function init()
|
|
|
|
if config.use_day_night_cycle and config.use_fixed_brightness then
|
|
|
|
error('Cannot use both a day/night cycle and a fixed brightness')
|
|
|
|
return
|
|
|
|
elseif config.use_day_night_cycle then
|
|
|
|
Public.set_cycle(config.day_night_cycle, RS.get_surface())
|
|
|
|
elseif config.use_fixed_brightness then
|
|
|
|
Public.set_fixed_brightness(config.fixed_brightness, RS.get_surface())
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
Event.on_init(init)
|
|
|
|
|
|
|
|
-- Public functions
|
|
|
|
|
2018-12-09 17:50:16 +02:00
|
|
|
--- Sets the day/night cycle according to the table it is given.
|
2019-02-04 23:17:00 +02:00
|
|
|
-- Can only be called during or after init.
|
2019-02-02 03:09:12 +02:00
|
|
|
-- @param day_night_cycle <table> containing specific, required keys: ticks_per_day, dusk, evening, morning, dawn
|
|
|
|
-- @param surface <LuaSurface> to set the day/night cycle of
|
|
|
|
-- @returns <boolean> true if set properly, nil if not
|
2018-12-09 17:50:16 +02:00
|
|
|
-- @see Venus::world_settings
|
2019-02-02 03:09:12 +02:00
|
|
|
function Public.set_cycle(day_night_cycle, surface)
|
2018-12-09 17:50:16 +02:00
|
|
|
if not check_cycle_validity(day_night_cycle) then
|
2019-02-02 03:38:35 +02:00
|
|
|
error('Provided day/night cycle is invalid')
|
2018-12-09 17:50:16 +02:00
|
|
|
return
|
|
|
|
end
|
2019-02-02 03:09:12 +02:00
|
|
|
if not surface or not surface.valid then
|
2019-02-02 03:38:35 +02:00
|
|
|
error('Provided surface is invalid')
|
2019-02-02 03:09:12 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
if not Public.unfreeze_daytime then
|
2019-02-02 03:38:35 +02:00
|
|
|
error('Time is stuck in a frozen state')
|
2018-12-09 17:50:16 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
surface.ticks_per_day = day_night_cycle.ticks_per_day
|
|
|
|
surface.dusk = 0
|
|
|
|
surface.evening = 0.001
|
|
|
|
surface.morning = 0.002
|
|
|
|
surface.dawn = day_night_cycle.dawn
|
|
|
|
surface.morning = day_night_cycle.morning
|
|
|
|
surface.evening = day_night_cycle.evening
|
|
|
|
surface.dusk = day_night_cycle.dusk
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Sets the brightness to a fixed level
|
2019-02-04 23:17:00 +02:00
|
|
|
-- Can only be called during or after init.
|
2019-02-02 03:09:12 +02:00
|
|
|
-- @param daylight <number> between 0.15 and 1 representing the percentage of daylight (0.15 brightness is the darkest available)
|
|
|
|
-- @param surface <LuaSurface> to set the day/night cycle of
|
|
|
|
-- @return <boolean> true if time is set properly, nil if not
|
|
|
|
function Public.set_fixed_brightness(daylight, surface)
|
|
|
|
if not surface or not surface.valid then
|
2019-02-02 03:38:35 +02:00
|
|
|
error('Provided surface is invalid')
|
2018-12-09 17:50:16 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
if daylight < 0.15 then
|
2019-02-02 03:38:35 +02:00
|
|
|
error('Daylight set too low. 0.15 is the darkest available.')
|
2018-12-09 17:50:16 +02:00
|
|
|
return
|
|
|
|
elseif daylight > 1 then
|
2019-02-02 03:38:35 +02:00
|
|
|
error('Daylight set too high. 1.00 is the lightest available.')
|
2018-12-09 17:50:16 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Do some algebra to find the correct point in the daytime to freeze
|
|
|
|
local brightness_slope = math.calculate_slope(surface.morning, 0.0, surface.dawn, 1)
|
|
|
|
local y_intercept = math.calculate_y_intercept(surface.morning, 0.0, brightness_slope)
|
|
|
|
local breakpoint = (daylight - y_intercept) / brightness_slope
|
|
|
|
-- Set the daytime to the point we just calculated
|
|
|
|
surface.daytime = breakpoint
|
|
|
|
-- Freeze the day/night cycle
|
|
|
|
surface.freeze_daytime = true
|
|
|
|
|
2019-02-02 03:09:12 +02:00
|
|
|
Debug.print(format('breakpoint/surface_daytime: %s/%s', breakpoint, surface.daytime))
|
|
|
|
Debug.print(format('brightness/surface_brightness: %s/%s', round(daylight, 2), round((1 - surface.darkness), 2)))
|
2018-12-09 17:50:16 +02:00
|
|
|
|
2019-02-02 03:09:12 +02:00
|
|
|
if round(daylight, 2) == round((1 - surface.darkness), 2) then
|
2018-12-09 17:50:16 +02:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-02-02 03:09:12 +02:00
|
|
|
--- Unfreezes daytime (usually frozen by set_fixed_brightness)
|
2019-02-04 23:17:00 +02:00
|
|
|
-- Can only be called during or after init.
|
2019-02-02 03:09:12 +02:00
|
|
|
-- @param surface <LuaSurface> to unfreeze the day/night cycle of
|
|
|
|
-- @return <boolean> true if daytime unfrozen, nil if not
|
|
|
|
function Public.unfreeze_daytime(surface)
|
|
|
|
if not surface or not surface.valid then
|
|
|
|
log('Provided surface is invalid')
|
|
|
|
return
|
|
|
|
end
|
|
|
|
surface.freeze_daytime = false
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2018-12-09 17:50:16 +02:00
|
|
|
return Public
|