64 lines
3.5 KiB
Lua
Executable File
64 lines
3.5 KiB
Lua
Executable File
-- Loaded after content/interface; schema and the persistence instance come from init.
|
|
local C, M, P = core, hearth.model, hearth.persistence
|
|
local singleplayer = C.is_singleplayer()
|
|
local deployment = C.settings:get("hearth_environment")
|
|
if deployment == nil then deployment = singleplayer and "local" or "production" end
|
|
if deployment ~= "local" and deployment ~= "staging" and deployment ~= "production" then
|
|
error("Last Hearth: hearth_environment must be local, staging, or production.", 0)
|
|
end
|
|
if not singleplayer and deployment == "local" then
|
|
error("Last Hearth: dedicated servers cannot use the local environment.", 0)
|
|
end
|
|
|
|
local date_setting = C.settings:get("hearth_preview_date")
|
|
local weather_setting = C.settings:get("hearth_preview_weather") or "auto"
|
|
local function nonempty(value) return value ~= nil and value ~= "" end
|
|
if deployment == "production" and (nonempty(date_setting) or weather_setting ~= "auto"
|
|
or C.settings:get("hearth_launcher_mode") ~= nil or C.settings:get("hearth_smoke_token") ~= nil
|
|
or C.settings:get("hearth_m1_course") ~= nil or C.settings:get("hearth_m1_course_nonce") ~= nil
|
|
or C.settings:get("hearth_m1_course_snag") ~= nil or C.settings:get("hearth_course_token") ~= nil) then
|
|
error("Last Hearth: production rejects fixture and launcher test settings.", 0)
|
|
end
|
|
local preview_date
|
|
if nonempty(date_setting) then
|
|
preview_date = tonumber(date_setting)
|
|
if not preview_date or preview_date ~= preview_date or preview_date < 946684800
|
|
or preview_date > 4102444800 or preview_date % 1 ~= 0 then
|
|
error("Last Hearth: hearth_preview_date must be an integer UTC timestamp from 2000 through 2100.", 0)
|
|
end
|
|
end
|
|
if weather_setting ~= "auto" and weather_setting ~= "clear" and weather_setting ~= "rain" then
|
|
error("Last Hearth: hearth_preview_weather must be auto, clear, or rain.", 0)
|
|
end
|
|
|
|
local configured = M.location(C.settings:get("hearth_latitude"), C.settings:get("hearth_longitude"))
|
|
if (deployment == "production" or not singleplayer) and not configured then
|
|
error("Last Hearth: server/production requires explicit valid hearth_latitude and hearth_longitude settings.", 0)
|
|
end
|
|
-- Always validate stored data, even when settings take precedence. Corrupt saves
|
|
-- must fail startup, not disappear behind a configured location or neutral preview.
|
|
local stored = P.load_world("location")
|
|
local selected = configured or (singleplayer and stored)
|
|
hearth.has_location = selected ~= nil and selected ~= false
|
|
-- The existing location form and HUD disclose this unchosen neutral preview.
|
|
local location = selected or {latitude = 0, longitude = 0}
|
|
function hearth.climate_at(timestamp)
|
|
if type(timestamp) ~= "number" or timestamp ~= timestamp or timestamp < 0 then return nil end
|
|
return M.solar(math.floor(timestamp), location.latitude, location.longitude)
|
|
end
|
|
function hearth.set_location(lat, lon)
|
|
assert(singleplayer, "Only local worlds can select location in game")
|
|
local value = assert(M.location(lat, lon), "Invalid reference coordinates")
|
|
-- Publish only after a successful save; never silently replace a failed record.
|
|
P.save_world("location", value)
|
|
location, hearth.has_location = value, true
|
|
end
|
|
function hearth.clock_update()
|
|
local now = preview_date or os.time()
|
|
hearth.clock = M.solar(now, location.latitude, location.longitude)
|
|
hearth.weather = M.weather(now, location.latitude, location.longitude)
|
|
if weather_setting ~= "auto" then hearth.weather = weather_setting end
|
|
C.set_timeofday(hearth.clock.timeofday)
|
|
end
|
|
C.after(0, hearth.clock_update)
|