Update Day Night Cycle DX to new v2.5
Some checks are pending
Build coop / build-ubuntu (push) Waiting to run
Build coop / build-windows (push) Waiting to run
Build coop / build-macos-arm (push) Waiting to run
Build coop / build-macos-intel (push) Waiting to run

This commit is contained in:
Agent X 2025-05-04 11:55:08 -04:00
parent 8ef8712237
commit 3e1c04dbe7
6 changed files with 237 additions and 228 deletions

View file

@ -1,5 +1,37 @@
-- localize functions to improve performance -- localize functions to improve performance
local string_format,table_insert,math_floor,math_ceil,level_is_vanilla_level,djui_hud_get_color,djui_hud_set_color,djui_hud_print_text,obj_get_first_with_behavior_id = string.format,table.insert,math.floor,math.ceil,level_is_vanilla_level,djui_hud_get_color,djui_hud_set_color,djui_hud_print_text,obj_get_first_with_behavior_id local mod_storage_load,string_format,table_insert,type,math_floor,math_ceil,level_is_vanilla_level,djui_hud_get_color,djui_hud_set_color,djui_hud_print_text,obj_get_first_with_behavior_id = mod_storage_load,string.format,table.insert,type,math.floor,math.ceil,level_is_vanilla_level,djui_hud_get_color,djui_hud_set_color,djui_hud_print_text,obj_get_first_with_behavior_id
--- @param key string
--- `mod_storage_load_bool` except it returns true by default
function mod_storage_load_bool_2(key)
local value = mod_storage_load(key)
if value == nil then return true end
return value == "true"
end
--- @param s string
--- Splits a string into a table by spaces
function string_split(s)
local result = {}
for match in (s):gmatch(string_format("[^%s]+", " ")) do
table_insert(result, match)
end
return result
end
--- @param table table
--- Clones a table out of an existing one, useful for making referenceless tables
function table_clone(table)
local clone = {}
for key, value in pairs(table) do
if type(value) == "table" then
clone[key] = table_clone(value) -- recursive call for nested tables
else
clone[key] = value
end
end
return clone
end
--- @param cond boolean --- @param cond boolean
--- Human readable ternary operator --- Human readable ternary operator
@ -8,21 +40,18 @@ function if_then_else(cond, ifTrue, ifFalse)
return ifFalse return ifFalse
end end
--- @param s string --- @param value boolean
--- Splits a string into a table by spaces --- Returns an on or off string depending on value
function split(s) function on_or_off(value)
local result = {} if value then return "\\#00ff00\\ON" end
for match in (s):gmatch(string_format("[^%s]+", " ")) do return "\\#ff0000\\OFF"
table_insert(result, match)
end
return result
end end
--- @param x number --- @param x number
--- @return integer --- @return integer
--- Rounds up or down depending on the decimal position of `x` --- Rounds up or down depending on the decimal position of `x`
function math_round(x) function math_round(x)
return if_then_else(x - math_floor(x) >= 0.5, math_ceil(x), math_floor(x)) return math_floor(x + 0.5)
end end
--- @param a number --- @param a number
@ -63,17 +92,11 @@ end
--- @param priority integer --- @param priority integer
--- @param seqId SeqId --- @param seqId SeqId
--- Generates a sequence ID integer with priority
function SEQUENCE_ARGS(priority, seqId) function SEQUENCE_ARGS(priority, seqId)
return ((priority << 8) | seqId) return ((priority << 8) | seqId)
end end
--- @param value boolean
--- Returns an on or off string depending on value
function on_or_off(value)
if value then return "\\#00ff00\\ON" end
return "\\#ff0000\\OFF"
end
--- @param levelNum LevelNum --- @param levelNum LevelNum
--- Returns whether or not the local player is in a vanilla level --- Returns whether or not the local player is in a vanilla level
function in_vanilla_level(levelNum) function in_vanilla_level(levelNum)
@ -84,33 +107,18 @@ end
--- @param x number --- @param x number
--- @param y number --- @param y number
--- @param scale number --- @param scale number
--- @param outlineBrightness number
--- Prints outlined DJUI HUD text --- Prints outlined DJUI HUD text
function djui_hud_print_outlined_text(message, x, y, scale, outlineBrightness) function djui_hud_print_outlined_text(message, x, y, scale)
local color = djui_hud_get_color() local hudColor = djui_hud_get_color()
djui_hud_set_color(color.r * outlineBrightness, color.g * outlineBrightness, color.b * outlineBrightness, color.a) djui_hud_set_color(0, 0, 0, hudColor.a)
djui_hud_print_text(message, x - 1, y, scale) djui_hud_print_text(message, x - 1, y, scale)
djui_hud_print_text(message, x + 1, y, scale) djui_hud_print_text(message, x + 1, y, scale)
djui_hud_print_text(message, x, y - 1, scale) djui_hud_print_text(message, x, y - 1, scale)
djui_hud_print_text(message, x, y + 1, scale) djui_hud_print_text(message, x, y + 1, scale)
djui_hud_set_color(color.r, color.g, color.b, color.a) djui_hud_set_color(hudColor.r, hudColor.g, hudColor.b, hudColor.a)
djui_hud_print_text(message, x, y, scale) djui_hud_print_text(message, x, y, scale)
end end
--- @param table table
--- Clones a table out of an existing one, useful for making referenceless tables
function table_clone(table)
local clone = {}
for key, value in pairs(table) do
if type(value) == "table" then
clone[key] = table_clone(value) -- recursive call for nested tables
else
clone[key] = value
end
end
return clone
end
--- Checks common conditions that make HUD rendering out of place --- Checks common conditions that make HUD rendering out of place
function check_common_hud_render_cancels() function check_common_hud_render_cancels()
local action = gMarioStates[0].action local action = gMarioStates[0].action
@ -120,25 +128,3 @@ function check_common_hud_render_cancels()
gNetworkPlayers[0].currLevelNum == LEVEL_ENDING or gNetworkPlayers[0].currLevelNum == LEVEL_ENDING or
action == ACT_END_PEACH_CUTSCENE or action == ACT_END_WAVING_CUTSCENE or action == ACT_CREDITS_CUTSCENE action == ACT_END_PEACH_CUTSCENE or action == ACT_END_WAVING_CUTSCENE or action == ACT_CREDITS_CUTSCENE
end end
local function tobool(value)
local type = type(value)
if type == "boolean" then
return value
elseif type == "number" then
return value == 1
elseif type == "string" then
return value == "true"
elseif type == "table" or type == "function" or type == "thread" or type == "userdata" then
return true
end
return false
end
--- @param key string
--- `mod_storage_load_bool` except it returns true by default
function mod_storage_load_bool_2(key)
local value = mod_storage_load(key)
if value == nil then return true end
return tobool(value)
end

View file

@ -1,6 +1,6 @@
-- version -- version
DNC_VERSION_MAJOR = 2 DNC_VERSION_MAJOR = 2
DNC_VERSION_MINOR = 4 DNC_VERSION_MINOR = 5
DNC_VERSION_PATCH = 0 DNC_VERSION_PATCH = 0
DNC_VERSION = math.tointeger(string.format("%d%d%d", DNC_VERSION_MAJOR, DNC_VERSION_MINOR, DNC_VERSION_PATCH)) DNC_VERSION = math.tointeger(string.format("%d%d%d", DNC_VERSION_MAJOR, DNC_VERSION_MINOR, DNC_VERSION_PATCH))
@ -13,12 +13,51 @@ SKYBOX_SUNSET = 1
SKYBOX_NIGHT = 2 SKYBOX_NIGHT = 2
-- background constants -- background constants
BACKGROUND_NIGHT = 10 BACKGROUND_OCEAN_SKY_NIGHT = 10
BACKGROUND_SUNRISE = 11 BACKGROUND_OCEAN_SKY_SUNRISE = 11
BACKGROUND_SUNSET = 12 BACKGROUND_OCEAN_SKY_SUNSET = 12
BACKGROUND_BELOW_CLOUDS_NIGHT = 13 BACKGROUND_UNDERWATER_CITY_NIGHT = 13
BACKGROUND_BELOW_CLOUDS_SUNRISE = 14 BACKGROUND_UNDERWATER_CITY_SUNRISE = 14
BACKGROUND_BELOW_CLOUDS_SUNSET = 15 BACKGROUND_UNDERWATER_CITY_SUNSET = 15
BACKGROUND_BELOW_CLOUDS_NIGHT = 16
BACKGROUND_BELOW_CLOUDS_SUNRISE = 17
BACKGROUND_BELOW_CLOUDS_SUNSET = 18
BACKGROUND_SNOW_MOUNTAINS_NIGHT = 19
BACKGROUND_SNOW_MOUNTAINS_SUNRISE = 20
BACKGROUND_SNOW_MOUNTAINS_SUNSET = 21
BACKGROUND_DESERT_NIGHT = 22
BACKGROUND_DESERT_SUNRISE = 23
BACKGROUND_DESERT_SUNSET = 24
BACKGROUND_ABOVE_CLOUDS_NIGHT = 25
BACKGROUND_ABOVE_CLOUDS_SUNRISE = 26
BACKGROUND_ABOVE_CLOUDS_SUNSET = 27
gNightSkyboxes = {
[BACKGROUND_OCEAN_SKY] = BACKGROUND_OCEAN_SKY_NIGHT,
[BACKGROUND_UNDERWATER_CITY] = BACKGROUND_UNDERWATER_CITY_NIGHT,
[BACKGROUND_BELOW_CLOUDS] = BACKGROUND_BELOW_CLOUDS_NIGHT,
[BACKGROUND_SNOW_MOUNTAINS] = BACKGROUND_SNOW_MOUNTAINS_NIGHT,
[BACKGROUND_DESERT] = BACKGROUND_DESERT_NIGHT,
[BACKGROUND_ABOVE_CLOUDS] = BACKGROUND_ABOVE_CLOUDS_NIGHT
}
gSunriseSkyboxes = {
[BACKGROUND_OCEAN_SKY] = BACKGROUND_OCEAN_SKY_SUNRISE,
[BACKGROUND_UNDERWATER_CITY] = BACKGROUND_UNDERWATER_CITY_SUNRISE,
[BACKGROUND_BELOW_CLOUDS] = BACKGROUND_BELOW_CLOUDS_SUNRISE,
[BACKGROUND_SNOW_MOUNTAINS] = BACKGROUND_SNOW_MOUNTAINS_SUNRISE,
[BACKGROUND_DESERT] = BACKGROUND_DESERT_SUNRISE,
[BACKGROUND_ABOVE_CLOUDS] = BACKGROUND_ABOVE_CLOUDS_SUNRISE
}
gSunsetSkyboxes = {
[BACKGROUND_OCEAN_SKY] = BACKGROUND_OCEAN_SKY_SUNSET,
[BACKGROUND_UNDERWATER_CITY] = BACKGROUND_UNDERWATER_CITY_SUNSET,
[BACKGROUND_BELOW_CLOUDS] = BACKGROUND_BELOW_CLOUDS_SUNSET,
[BACKGROUND_SNOW_MOUNTAINS] = BACKGROUND_SNOW_MOUNTAINS_SUNSET,
[BACKGROUND_DESERT] = BACKGROUND_DESERT_SUNSET,
[BACKGROUND_ABOVE_CLOUDS] = BACKGROUND_ABOVE_CLOUDS_SUNSET
}
-- time constants -- time constants
SECOND = 30 -- how many frames are in 1 second SECOND = 30 -- how many frames are in 1 second
@ -26,21 +65,21 @@ MINUTE = SECOND * 60 -- how many frames are in 1 minute
-- Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec -- Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
gSunriseTimes = { 6, 5, 6, 6, 5, 4, 4, 4, 5, 6, 6, 6 } gSunriseTimes = { 6, 5, 6, 5, 5, 4, 4, 4, 5, 6, 6, 6 }
gSunsetTimes = { 15, 16, 17, 18, 18, 19, 19, 19, 18, 17, 15, 14 } gSunsetTimes = { 15, 16, 17, 18, 18, 19, 19, 19, 18, 17, 15, 14 }
local month = get_date_and_time().month + 1 local MONTH = get_date_and_time().month + 1
syncSun = mod_storage_load_bool_2("sync_sun") syncSun = mod_storage_load_bool_2("sync_sun")
HOUR_SUNRISE_START_BASE = 4 HOUR_SUNRISE_START_BASE = 4
HOUR_SUNSET_START_BASE = 19 HOUR_SUNSET_START_BASE = 19
HOUR_SUNRISE_DURATION = 1 HOUR_SUNRISE_DURATION = 1
HOUR_SUNRISE_START = if_then_else(syncSun, gSunriseTimes[month], HOUR_SUNRISE_START_BASE) HOUR_SUNRISE_START = if_then_else(syncSun, gSunriseTimes[MONTH], HOUR_SUNRISE_START_BASE)
HOUR_SUNRISE_END = HOUR_SUNRISE_START + HOUR_SUNRISE_DURATION HOUR_SUNRISE_END = HOUR_SUNRISE_START + HOUR_SUNRISE_DURATION
HOUR_SUNSET_DURATION = 1 HOUR_SUNSET_DURATION = 1
HOUR_SUNSET_START = if_then_else(syncSun, gSunsetTimes[month], HOUR_SUNSET_START_BASE) HOUR_SUNSET_START = if_then_else(syncSun, gSunsetTimes[MONTH], HOUR_SUNSET_START_BASE)
HOUR_SUNSET_END = HOUR_SUNSET_START + HOUR_SUNSET_DURATION HOUR_SUNSET_END = HOUR_SUNSET_START + HOUR_SUNSET_DURATION
HOUR_DAY_START = HOUR_SUNRISE_END + HOUR_SUNRISE_DURATION HOUR_DAY_START = HOUR_SUNRISE_END + HOUR_SUNRISE_DURATION
@ -49,17 +88,17 @@ HOUR_NIGHT_START = HOUR_SUNSET_END + HOUR_SUNSET_DURATION
REAL_MINUTE = 1 / 60 REAL_MINUTE = 1 / 60
-- lighting direction constants -- lighting direction constants
DIR_DARK = 0.6 DIR_DARK = -0.4
DIR_BRIGHT = 1 DIR_BRIGHT = 0
-- fog intensity constants -- fog intensity constants
FOG_INTENSITY_NORMAL = 1.0 FOG_INTENSITY_NORMAL = 1.0
FOG_INTENSITY_DENSE = 1.02 FOG_INTENSITY_DENSE = 1.02
-- colors -- colors
COLOR_NIGHT = { r = 90, g = 110, b = 150 } COLOR_NIGHT = { r = 90, g = 100, b = 150 }
COLOR_AMBIENT_NIGHT = { r = 90, g = 100, b = 150 } COLOR_AMBIENT_NIGHT = { r = 70, g = 90, b = 150 }
COLOR_SUNRISE = { r = 255, g = 250, b = 150 } COLOR_SUNRISE = { r = 255, g = 250, b = 100 }
COLOR_AMBIENT_SUNRISE = { r = 200, g = 200, b = 255 } COLOR_AMBIENT_SUNRISE = { r = 200, g = 200, b = 255 }
COLOR_DAY = { r = 255, g = 255, b = 255 } COLOR_DAY = { r = 255, g = 255, b = 255 }
COLOR_AMBIENT_DAY = { r = 255, g = 255, b = 255 } COLOR_AMBIENT_DAY = { r = 255, g = 255, b = 255 }
@ -83,3 +122,4 @@ DNC_HOOK_DELETE_AT_DARK = 7
DNC_HOOK_SET_TIME = 8 DNC_HOOK_SET_TIME = 8
DNC_HOOK_SET_SKYBOX_MODEL = 9 DNC_HOOK_SET_SKYBOX_MODEL = 9
DNC_HOOK_SUN_TIMES_CHANGED = 10 DNC_HOOK_SUN_TIMES_CHANGED = 10
DNC_HOOK_ON_HUD_RENDER_BEHIND = 11

View file

@ -1,7 +1,7 @@
local sNightSequences = {}
-- localize functions to improve performance -- localize functions to improve performance
local mod_storage_remove,mod_storage_load_bool,mod_storage_exists,math_floor,mod_storage_save_number,mod_storage_load_number,string_format,smlua_audio_utils_replace_sequence,fade_volume_scale,set_background_music,obj_mark_for_deletion = mod_storage_remove,mod_storage_load_bool,mod_storage_exists,math.floor,mod_storage_save_number,mod_storage_load_number,string.format,smlua_audio_utils_replace_sequence,fade_volume_scale,set_background_music,obj_mark_for_deletion local mod_storage_remove,mod_storage_load_bool,math_floor,mod_storage_save_number,mod_storage_load_number,type,error,string_format,smlua_audio_utils_replace_sequence,fade_volume_scale,set_background_music,obj_mark_for_deletion = mod_storage_remove,mod_storage_load_bool,math.floor,mod_storage_save_number,mod_storage_load_number,type,error,string.format,smlua_audio_utils_replace_sequence,fade_volume_scale,set_background_music,obj_mark_for_deletion
local sNightSequences = {}
-- purge legacy fields -- purge legacy fields
mod_storage_remove("ampm") mod_storage_remove("ampm")
@ -159,7 +159,7 @@ function update_night_music()
if minutes >= HOUR_SUNSET_END + 0.75 and minutes < HOUR_NIGHT_START then if minutes >= HOUR_SUNSET_END + 0.75 and minutes < HOUR_NIGHT_START then
local threshold = 1 - (minutes - (HOUR_SUNSET_END + 0.75)) * 4 -- multiply by 4 because four quarters make a whole local threshold = 1 - (minutes - (HOUR_SUNSET_END + 0.75)) * 4 -- multiply by 4 because four quarters make a whole
fade_volume_scale(SEQ_PLAYER_LEVEL, threshold * 127, 1) fade_volume_scale(SEQ_PLAYER_LEVEL, threshold * 127, 1)
elseif minutes >= HOUR_SUNRISE_START + 0.75 and minutes <= HOUR_SUNRISE_END then elseif minutes >= HOUR_SUNRISE_START + 0.75 and minutes < HOUR_SUNRISE_END then
local threshold = 1 - (minutes - (HOUR_SUNRISE_START + 0.75)) * 4 local threshold = 1 - (minutes - (HOUR_SUNRISE_START + 0.75)) * 4
fade_volume_scale(SEQ_PLAYER_LEVEL, threshold * 127, 1) fade_volume_scale(SEQ_PLAYER_LEVEL, threshold * 127, 1)
end end

View file

@ -1,24 +1,14 @@
-- name: Day Night Cycle DX -- name: Day Night Cycle DX
-- incompatible: light day-night-cycle -- incompatible: light day-night-cycle
-- description: Day Night Cycle DX v2.4\nBy \\#ec7731\\Agent X\n\n\\#dcdcdc\\This mod adds a fully featured day & night cycle system with night, sunrise, day and sunset to sm64coopdx. It includes an API and hook system for interfacing with several components of the mod externally. This mod was originally made for sm64ex-coop but has been practically rewritten for sm64coopdx.\n\nDays last 24 minutes and with the /time command, you can get/set the time or change your settings.\n\nThere is also now a new menu in the pause menu for Day Night Cycle DX!\n\nSpecial thanks to \\#e06de4\\MaiskX3\\#dcdcdc\\ for the night time music.\nSpecial thanks to \\#00ffff\\AngelicMiracles\\#dcdcdc\\ for the sunset, sunrise and night time skyboxes.\nSpecial thanks to \\#344ee1\\eros71\\#dcdcdc\\ for salvaging\nthe mod files. -- description: Day Night Cycle DX v2.5\nBy \\#ec7731\\Agent X\n\n\\#dcdcdc\\This mod adds a fully featured day & night cycle system with night, sunrise, day and sunset to sm64coopdx. It includes an API and hook system for interfacing with several components of the mod externally. This mod was originally made for sm64ex-coop but has been practically rewritten for sm64coopdx.\n\nDays last 24 minutes and with the /time command, you can get/set the time or change your settings.\n\nThere is also now a new menu in the pause menu for Day Night Cycle DX!\n\nSpecial thanks to \\#e06de4\\MaiskX3\\#dcdcdc\\ for the night time music.\nSpecial thanks to \\#00ffff\\AngelicMiracles\\#dcdcdc\\ for the sunset, sunrise and night time skyboxes.\nSpecial thanks to \\#344ee1\\eros71\\#dcdcdc\\ for salvaging\nthe mod files.
--- @class Vec2f -- localize functions to improve performance
--- @field public x number local network_is_server,mod_storage_load,tonumber,type,math_floor,error,table_insert,get_skybox,set_lighting_dir,set_lighting_color,set_vertex_color,set_fog_color,set_fog_intensity,network_check_singleplayer_pause,network_player_connected_count,obj_get_first_with_behavior_id,spawn_non_sync_object,obj_scale,clampf,set_lighting_color_ambient,le_set_ambient_color,djui_hud_set_resolution,djui_hud_set_font,hud_is_hidden,hud_get_value,djui_hud_get_screen_width,djui_hud_measure_text,djui_hud_get_screen_height,djui_hud_set_color,play_sound,djui_chat_message_create,string_format,mod_storage_save_number,mod_storage_save_bool,get_date_and_time = network_is_server,mod_storage_load,tonumber,type,math.floor,error,table.insert,get_skybox,set_lighting_dir,set_lighting_color,set_vertex_color,set_fog_color,set_fog_intensity,network_check_singleplayer_pause,network_player_connected_count,obj_get_first_with_behavior_id,spawn_non_sync_object,obj_scale,clampf,set_lighting_color_ambient,le_set_ambient_color,djui_hud_set_resolution,djui_hud_set_font,hud_is_hidden,hud_get_value,djui_hud_get_screen_width,djui_hud_measure_text,djui_hud_get_screen_height,djui_hud_set_color,play_sound,djui_chat_message_create,string.format,mod_storage_save_number,mod_storage_save_bool,get_date_and_time
--- @field public y number
gGlobalSyncTable.dncEnabled = true
gGlobalSyncTable.time = if_then_else(network_is_server(), load_time(), HOUR_DAY_START)
gGlobalSyncTable.timeScale = tonumber(mod_storage_load("scale")) or 1.0
gGlobalSyncTable.sunrise = HOUR_SUNRISE_START
gGlobalSyncTable.sunset = HOUR_SUNSET_START
local init = false local init = false
local timeModifier = 0 local timeModifier = 0
local displayTime = mod_storage_load_bool_2("display_time") local displayTime = mod_storage_load_bool_2("display_time")
-- localize functions to improve performance
local math_floor,table_insert,get_skybox,set_lighting_dir,set_lighting_color,set_vertex_color,set_fog_color,set_fog_intensity,network_check_singleplayer_pause,network_player_connected_count,obj_get_first_with_behavior_id,network_is_server,spawn_non_sync_object,obj_scale,clampf,set_lighting_color_ambient,djui_hud_set_resolution,djui_hud_set_font,hud_get_value,hud_is_hidden,djui_hud_get_screen_width,djui_hud_measure_text,djui_hud_get_screen_height,djui_hud_set_color,play_sound,djui_chat_message_create,string_format,mod_storage_save_number,mod_storage_save_bool,get_date_and_time = math.floor,table.insert,get_skybox,set_lighting_dir,set_lighting_color,set_vertex_color,set_fog_color,set_fog_intensity,network_check_singleplayer_pause,network_player_connected_count,obj_get_first_with_behavior_id,network_is_server,spawn_non_sync_object,obj_scale,clampf,set_lighting_color_ambient,djui_hud_set_resolution,djui_hud_set_font,hud_get_value,hud_is_hidden,djui_hud_get_screen_width,djui_hud_measure_text,djui_hud_get_screen_height,djui_hud_set_color,play_sound,djui_chat_message_create,string.format,mod_storage_save_number,mod_storage_save_bool,get_date_and_time
local sDncHooks = { local sDncHooks = {
[DNC_HOOK_SET_LIGHTING_COLOR] = {}, [DNC_HOOK_SET_LIGHTING_COLOR] = {},
[DNC_HOOK_SET_AMBIENT_LIGHTING_COLOR] = {}, [DNC_HOOK_SET_AMBIENT_LIGHTING_COLOR] = {},
@ -30,9 +20,16 @@ local sDncHooks = {
[DNC_HOOK_DELETE_AT_DARK] = {}, [DNC_HOOK_DELETE_AT_DARK] = {},
[DNC_HOOK_SET_TIME] = {}, [DNC_HOOK_SET_TIME] = {},
[DNC_HOOK_SET_SKYBOX_MODEL] = {}, [DNC_HOOK_SET_SKYBOX_MODEL] = {},
[DNC_HOOK_SUN_TIMES_CHANGED] = {} [DNC_HOOK_SUN_TIMES_CHANGED] = {},
[DNC_HOOK_ON_HUD_RENDER_BEHIND] = {}
} }
gGlobalSyncTable.dncEnabled = true
gGlobalSyncTable.time = if_then_else(network_is_server(), load_time(), HOUR_DAY_START)
gGlobalSyncTable.timeScale = tonumber(mod_storage_load("scale")) or 1.0
gGlobalSyncTable.sunrise = HOUR_SUNRISE_START
gGlobalSyncTable.sunset = HOUR_SUNSET_START
--- @param hookEventType integer --- @param hookEventType integer
--- @param func function --- @param func function
--- Hooks a function to the Day Night Cycle hook system --- Hooks a function to the Day Night Cycle hook system
@ -82,6 +79,7 @@ function show_day_night_cycle()
end end
local function reset_lighting() local function reset_lighting()
set_lighting_dir(0, 0)
set_lighting_dir(1, 0) set_lighting_dir(1, 0)
set_lighting_dir(2, 0) set_lighting_dir(2, 0)
set_lighting_color(0, 255) set_lighting_color(0, 255)
@ -107,6 +105,7 @@ local function update()
if network_is_server() then time_tick() end if network_is_server() then time_tick() end
if init then update_night_music() end if init then update_night_music() end
init = true
-- spawn skyboxes -- spawn skyboxes
local skybox = get_skybox() local skybox = get_skybox()
@ -118,9 +117,9 @@ local function update()
for i = SKYBOX_DAY, SKYBOX_NIGHT do for i = SKYBOX_DAY, SKYBOX_NIGHT do
local thisSkybox = skybox local thisSkybox = skybox
if i == SKYBOX_SUNSET then if i == SKYBOX_SUNSET then
thisSkybox = if_then_else(skybox == BACKGROUND_BELOW_CLOUDS, BACKGROUND_BELOW_CLOUDS_SUNSET, BACKGROUND_SUNSET) thisSkybox = gSunsetSkyboxes[skybox]
elseif i == SKYBOX_NIGHT then elseif i == SKYBOX_NIGHT then
thisSkybox = if_then_else(skybox == BACKGROUND_BELOW_CLOUDS, BACKGROUND_BELOW_CLOUDS_NIGHT, BACKGROUND_NIGHT) thisSkybox = gNightSkyboxes[skybox]
end end
local model = E_MODEL_DNC_SKYBOX local model = E_MODEL_DNC_SKYBOX
@ -140,10 +139,14 @@ local function update()
) )
end end
else else
local model = E_MODEL_DNC_SKYBOX
local overrideModel = dnc_call_hook(DNC_HOOK_SET_SKYBOX_MODEL, -1, skybox)
if overrideModel ~= nil and type(overrideModel) == "number" then model = overrideModel end
-- spawn static skybox -- spawn static skybox
spawn_non_sync_object( spawn_non_sync_object(
bhvDNCSkybox, bhvDNCSkybox,
E_MODEL_DNC_SKYBOX, model,
0, 0, 0, 0, 0, 0,
--- @param o Object --- @param o Object
function(o) function(o)
@ -158,93 +161,74 @@ local function update()
local minutes = if_then_else(is_static_skybox(skybox), 12, get_time_minutes()) local minutes = if_then_else(is_static_skybox(skybox), 12, get_time_minutes())
local actSelector = obj_get_first_with_behavior_id(id_bhvActSelector) local actSelector = obj_get_first_with_behavior_id(id_bhvActSelector)
if actSelector == nil and show_day_night_cycle() then if actSelector ~= nil or not show_day_night_cycle() then
reset_lighting()
return
end
-- calculate lighting color -- calculate lighting color
local color = COLOR_DAY local color = COLOR_DAY
local ambientColor = COLOR_AMBIENT_DAY
local dir = DIR_BRIGHT
local fogColor = COLOR_DAY
local fogIntensity = FOG_INTENSITY_NORMAL
if minutes >= HOUR_SUNRISE_START and minutes <= HOUR_SUNRISE_END then if minutes >= HOUR_SUNRISE_START and minutes <= HOUR_SUNRISE_END then
color = color_lerp(COLOR_NIGHT, COLOR_SUNRISE, (minutes - HOUR_SUNRISE_START) / HOUR_SUNRISE_DURATION) local t = (minutes - HOUR_SUNRISE_START) / HOUR_SUNRISE_DURATION
color = color_lerp(COLOR_NIGHT, COLOR_SUNRISE, t)
ambientColor = color_lerp(COLOR_AMBIENT_NIGHT, COLOR_AMBIENT_SUNRISE, t)
dir = lerp(DIR_DARK, DIR_BRIGHT, t)
fogColor = color_lerp(FOG_COLOR_NIGHT, COLOR_SUNRISE, t)
fogIntensity = lerp(FOG_INTENSITY_DENSE, FOG_INTENSITY_NORMAL, t)
elseif minutes >= HOUR_SUNRISE_END and minutes <= HOUR_DAY_START then elseif minutes >= HOUR_SUNRISE_END and minutes <= HOUR_DAY_START then
color = color_lerp(COLOR_SUNRISE, COLOR_DAY, (minutes - HOUR_SUNRISE_END) / HOUR_SUNRISE_DURATION) local t = (minutes - HOUR_SUNRISE_END) / HOUR_SUNRISE_DURATION
color = color_lerp(COLOR_SUNRISE, COLOR_DAY, t)
ambientColor = color_lerp(COLOR_AMBIENT_SUNRISE, COLOR_AMBIENT_DAY, t)
dir = DIR_BRIGHT
fogColor = color
fogIntensity = FOG_INTENSITY_NORMAL
elseif minutes >= HOUR_SUNSET_START and minutes <= HOUR_SUNSET_END then elseif minutes >= HOUR_SUNSET_START and minutes <= HOUR_SUNSET_END then
color = color_lerp(COLOR_DAY, COLOR_SUNSET, (minutes - HOUR_SUNSET_START) / HOUR_SUNSET_DURATION) local t = (minutes - HOUR_SUNSET_START) / HOUR_SUNSET_DURATION
color = color_lerp(COLOR_DAY, COLOR_SUNSET, t)
ambientColor = color_lerp(COLOR_AMBIENT_DAY, COLOR_AMBIENT_SUNSET, t)
dir = lerp(DIR_BRIGHT, DIR_DARK, t)
fogColor = color
fogIntensity = FOG_INTENSITY_NORMAL
elseif minutes >= HOUR_SUNSET_END and minutes <= HOUR_NIGHT_START then elseif minutes >= HOUR_SUNSET_END and minutes <= HOUR_NIGHT_START then
color = color_lerp(COLOR_SUNSET, COLOR_NIGHT, (minutes - HOUR_SUNSET_END) / HOUR_SUNSET_DURATION) local t = (minutes - HOUR_SUNSET_END) / HOUR_SUNSET_DURATION
color = color_lerp(COLOR_SUNSET, COLOR_NIGHT, t)
ambientColor = color_lerp(COLOR_AMBIENT_SUNSET, COLOR_AMBIENT_NIGHT, t)
dir = DIR_DARK
fogColor = color_lerp(COLOR_SUNSET, FOG_COLOR_NIGHT, t)
fogIntensity = lerp(FOG_INTENSITY_NORMAL, FOG_INTENSITY_DENSE, t)
elseif minutes > HOUR_NIGHT_START or minutes < HOUR_SUNRISE_START then elseif minutes > HOUR_NIGHT_START or minutes < HOUR_SUNRISE_START then
color = COLOR_NIGHT color = COLOR_NIGHT
elseif minutes > HOUR_DAY_START and minutes < HOUR_SUNSET_START then ambientColor = COLOR_AMBIENT_NIGHT
color = COLOR_DAY dir = DIR_DARK
fogColor = FOG_COLOR_NIGHT
fogIntensity = FOG_INTENSITY_DENSE
end end
fogColor = color_lerp(fogColor, ambientColor, 0.5)
local overrideColor = dnc_call_hook(DNC_HOOK_SET_LIGHTING_COLOR, table_clone(color)) local overrideColor = dnc_call_hook(DNC_HOOK_SET_LIGHTING_COLOR, table_clone(color))
if overrideColor ~= nil and type(overrideColor) == "table" then color = overrideColor end if overrideColor ~= nil and type(overrideColor) == "table" then color = overrideColor end
-- calculate ambient lighting color
local ambientColor = COLOR_AMBIENT_DAY
if minutes >= HOUR_SUNRISE_START and minutes <= HOUR_SUNRISE_END then
ambientColor = color_lerp(COLOR_AMBIENT_NIGHT, COLOR_AMBIENT_SUNRISE, (minutes - HOUR_SUNRISE_START) / HOUR_SUNRISE_DURATION)
elseif minutes >= HOUR_SUNRISE_END and minutes <= HOUR_DAY_START then
ambientColor = color_lerp(COLOR_AMBIENT_SUNRISE, COLOR_AMBIENT_DAY, (minutes - HOUR_SUNRISE_END) / HOUR_SUNRISE_DURATION)
elseif minutes >= HOUR_SUNSET_START and minutes <= HOUR_SUNSET_END then
ambientColor = color_lerp(COLOR_AMBIENT_DAY, COLOR_AMBIENT_SUNSET, (minutes - HOUR_SUNSET_START) / HOUR_SUNSET_DURATION)
elseif minutes >= HOUR_SUNSET_END and minutes <= HOUR_NIGHT_START then
ambientColor = color_lerp(COLOR_AMBIENT_SUNSET, COLOR_AMBIENT_NIGHT, (minutes - HOUR_SUNSET_END) / HOUR_SUNSET_DURATION)
elseif minutes > HOUR_NIGHT_START or minutes < HOUR_SUNRISE_START then
ambientColor = COLOR_AMBIENT_NIGHT
elseif minutes > HOUR_DAY_START and minutes < HOUR_SUNSET_START then
ambientColor = COLOR_AMBIENT_DAY
end
local overrideAmbientColor = dnc_call_hook(DNC_HOOK_SET_AMBIENT_LIGHTING_COLOR, table_clone(ambientColor)) local overrideAmbientColor = dnc_call_hook(DNC_HOOK_SET_AMBIENT_LIGHTING_COLOR, table_clone(ambientColor))
if overrideAmbientColor ~= nil and type(overrideColor) == "table" then ambientColor = overrideAmbientColor end if overrideAmbientColor ~= nil and type(overrideColor) == "table" then ambientColor = overrideAmbientColor end
-- calculate fog color
local fogColor = COLOR_DAY
if minutes >= HOUR_SUNRISE_START and minutes <= HOUR_SUNRISE_END then
fogColor = color_lerp(FOG_COLOR_NIGHT, COLOR_SUNRISE, (minutes - HOUR_SUNRISE_START) / HOUR_SUNRISE_DURATION)
elseif minutes >= HOUR_SUNRISE_END and minutes <= HOUR_DAY_START then
fogColor = color_lerp(COLOR_SUNRISE, COLOR_DAY, (minutes - HOUR_SUNRISE_END) / HOUR_SUNRISE_DURATION)
elseif minutes >= HOUR_SUNSET_START and minutes <= HOUR_SUNSET_END then
fogColor = color_lerp(COLOR_DAY, COLOR_SUNSET, (minutes - HOUR_SUNSET_START) / HOUR_SUNSET_DURATION)
elseif minutes >= HOUR_SUNSET_END and minutes <= HOUR_NIGHT_START then
fogColor = color_lerp(COLOR_SUNSET, FOG_COLOR_NIGHT, (minutes - HOUR_SUNSET_END) / HOUR_SUNSET_DURATION)
elseif minutes > HOUR_NIGHT_START or minutes < HOUR_SUNRISE_START then
fogColor = FOG_COLOR_NIGHT
elseif minutes > HOUR_DAY_START and minutes < HOUR_SUNSET_START then
fogColor = COLOR_DAY
end
fogColor = color_lerp(fogColor, ambientColor, 0.5)
local overrideFogColor = dnc_call_hook(DNC_HOOK_SET_FOG_COLOR, table_clone(fogColor)) local overrideFogColor = dnc_call_hook(DNC_HOOK_SET_FOG_COLOR, table_clone(fogColor))
if overrideFogColor ~= nil and type(overrideFogColor) == "table" then fogColor = overrideFogColor end if overrideFogColor ~= nil and type(overrideFogColor) == "table" then fogColor = overrideFogColor end
-- calculate lighting direction local overrideFogIntensity = dnc_call_hook(DNC_HOOK_SET_FOG_INTENSITY, fogIntensity)
local dir = DIR_BRIGHT if overrideFogIntensity ~= nil and type(overrideFogIntensity) == "number" then fogIntensity = overrideFogIntensity end
if minutes >= HOUR_SUNRISE_START and minutes <= HOUR_SUNRISE_END then
dir = lerp(DIR_DARK, DIR_BRIGHT, clampf((minutes - HOUR_SUNRISE_START) / (HOUR_SUNRISE_DURATION), 0, 1))
elseif minutes >= HOUR_SUNSET_START and minutes <= HOUR_NIGHT_START then
dir = lerp(DIR_BRIGHT, DIR_DARK, clampf((minutes - HOUR_SUNSET_START) / (HOUR_NIGHT_START - HOUR_SUNSET_START), 0, 1))
elseif minutes < HOUR_SUNRISE_START or minutes > HOUR_NIGHT_START then
dir = DIR_DARK
elseif minutes > HOUR_SUNRISE_END and minutes < HOUR_SUNSET_START then
dir = DIR_BRIGHT
end
local overrideDir = dnc_call_hook(DNC_HOOK_SET_LIGHTING_DIR, dir)
if overrideDir ~= nil and type(overrideDir) == "number" then dir = overrideDir end
-- calculate fog intensity local lightingDir = { x = 0, y = dir, z = dir }
local intensity = FOG_INTENSITY_NORMAL local overrideLightingDir = dnc_call_hook(DNC_HOOK_SET_LIGHTING_DIR, lightingDir)
if minutes >= HOUR_SUNRISE_START and minutes <= HOUR_SUNRISE_END then if overrideLightingDir ~= nil and type(overrideLightingDir) == "table" then lightingDir = overrideLightingDir end
intensity = lerp(FOG_INTENSITY_DENSE, FOG_INTENSITY_NORMAL, clampf((minutes - HOUR_SUNRISE_START) / (HOUR_SUNRISE_DURATION), 0, 1))
elseif minutes >= HOUR_SUNSET_START and minutes <= HOUR_NIGHT_START then
intensity = lerp(FOG_INTENSITY_NORMAL, FOG_INTENSITY_DENSE, clampf((minutes - HOUR_SUNSET_START) / (HOUR_NIGHT_START - HOUR_SUNSET_START), 0, 1))
elseif minutes < HOUR_SUNRISE_START or minutes > HOUR_NIGHT_START then
intensity = FOG_INTENSITY_DENSE
elseif minutes > HOUR_SUNRISE_END and minutes < HOUR_SUNSET_START then
intensity = FOG_INTENSITY_NORMAL
end
local overrideIntensity = dnc_call_hook(DNC_HOOK_SET_FOG_INTENSITY, intensity)
if overrideIntensity ~= nil and type(overrideIntensity) == "number" then intensity = overrideIntensity end
set_lighting_dir(1, -(1 - dir)) set_lighting_dir(0, lightingDir.x)
set_lighting_dir(2, -(1 - dir)) set_lighting_dir(1, lightingDir.y)
-- make the castle still 25% ambient lit set_lighting_dir(2, lightingDir.z)
-- make the castle still 25% lit
if in_vanilla_level(LEVEL_CASTLE) then if in_vanilla_level(LEVEL_CASTLE) then
color = color_lerp(COLOR_DAY, color, 0.75) color = color_lerp(COLOR_DAY, color, 0.75)
end end
@ -261,21 +245,18 @@ local function update()
set_fog_color(0, fogColor.r) set_fog_color(0, fogColor.r)
set_fog_color(1, fogColor.g) set_fog_color(1, fogColor.g)
set_fog_color(2, fogColor.b) set_fog_color(2, fogColor.b)
set_fog_intensity(intensity) set_fog_intensity(fogIntensity)
-- lighting engine compatibility -- lighting engine compatibility
if obj_get_first_with_behavior_id(id_bhvAmbientLight) ~= nil then if obj_get_first_with_behavior_id(id_bhvAmbientLight) ~= nil then
mix = color_lerp(color, COLOR_WHITE, 0.5) -- make the color less intense mix = color_lerp(color, COLOR_WHITE, 0.5) -- make the color less intense
le_set_ambient_color(mix.r, mix.g, mix.b) le_set_ambient_color(mix.r, mix.g, mix.b)
end end
else
reset_lighting()
end
init = true
end end
local function on_hud_render_behind() local function on_hud_render_behind()
dnc_call_hook(DNC_HOOK_ON_HUD_RENDER_BEHIND)
if not is_dnc_enabled() then return end -- option check if not is_dnc_enabled() then return end -- option check
if not dayNightCycleApi.displayTime or not displayTime then return end -- API checks if not dayNightCycleApi.displayTime or not displayTime then return end -- API checks
if check_common_hud_render_cancels() then return end -- game checks if check_common_hud_render_cancels() then return end -- game checks
@ -284,7 +265,7 @@ local function on_hud_render_behind()
djui_hud_set_font(FONT_NORMAL) djui_hud_set_font(FONT_NORMAL)
local scale = 0.5 local scale = 0.5
local text = get_time_string(gGlobalSyncTable.time) local text = get_time_string()
local hidden = hud_is_hidden() or (hud_get_value(HUD_DISPLAY_FLAGS) & HUD_DISPLAY_FLAG_LIVES) == 0 local hidden = hud_is_hidden() or (hud_get_value(HUD_DISPLAY_FLAGS) & HUD_DISPLAY_FLAG_LIVES) == 0
local x = if_then_else(hidden, (djui_hud_get_screen_width() * 0.5) - (djui_hud_measure_text(text) * (0.5 * scale)), 24) local x = if_then_else(hidden, (djui_hud_get_screen_width() * 0.5) - (djui_hud_measure_text(text) * (0.5 * scale)), 24)
@ -312,7 +293,7 @@ local function on_hud_render_behind()
if overrideColor ~= nil and type(overrideColor) == "table" then color = overrideColor end if overrideColor ~= nil and type(overrideColor) == "table" then color = overrideColor end
djui_hud_set_color(color.r, color.g, color.b, 255) djui_hud_set_color(color.r, color.g, color.b, 255)
djui_hud_print_outlined_text(text, x, y, scale, 0.0) djui_hud_print_outlined_text(text, x, y, scale)
end end
local function on_level_init() local function on_level_init()
@ -428,7 +409,7 @@ local function on_scale_command(msg)
gGlobalSyncTable.timeScale = scale gGlobalSyncTable.timeScale = scale
mod_storage_save_number("scale", scale) mod_storage_save_number("scale", scale)
update_mod_menu_element_slider(modMenuTimeScale, scale) -- I wonder update_mod_menu_element_slider(modMenuTimeScale, scale)
djui_chat_message_create("[Day Night Cycle] Time scale set to " .. scale) djui_chat_message_create("[Day Night Cycle] Time scale set to " .. scale)
@ -521,7 +502,7 @@ end
--- @param msg string --- @param msg string
local function on_time_command(msg) local function on_time_command(msg)
local args = split(msg) local args = string_split(msg)
if args[1] == "set" then if args[1] == "set" then
if not network_is_server() then if not network_is_server() then
@ -581,7 +562,7 @@ local function on_sunrise_changed(_, _, newVal)
_G.dayNightCycleApi.constants.HOUR_SUNRISE_START = HOUR_SUNRISE_START _G.dayNightCycleApi.constants.HOUR_SUNRISE_START = HOUR_SUNRISE_START
_G.dayNightCycleApi.constants.HOUR_SUNRISE_END = HOUR_SUNRISE_END _G.dayNightCycleApi.constants.HOUR_SUNRISE_END = HOUR_SUNRISE_END
_G.dayNightCycleApi.constants.HOUR_DAY_START = HOUR_NIGHT_START _G.dayNightCycleApi.constants.HOUR_DAY_START = HOUR_DAY_START
dnc_call_hook(DNC_HOOK_SUN_TIMES_CHANGED) dnc_call_hook(DNC_HOOK_SUN_TIMES_CHANGED)
end end
@ -739,8 +720,8 @@ _G.dayNightCycleApi = {
-- * Return: `Color` -- * Return: `Color`
DNC_HOOK_SET_AMBIENT_LIGHTING_COLOR = DNC_HOOK_SET_AMBIENT_LIGHTING_COLOR, DNC_HOOK_SET_AMBIENT_LIGHTING_COLOR = DNC_HOOK_SET_AMBIENT_LIGHTING_COLOR,
-- * Called whenever the lighting direction is calculated -- * Called whenever the lighting direction is calculated
-- * Parameters: `number` dir -- * Parameters: `Vec3f` lightingDir
-- * Return: `number` -- * Return: `Vec3f`
DNC_HOOK_SET_LIGHTING_DIR = DNC_HOOK_SET_LIGHTING_DIR, DNC_HOOK_SET_LIGHTING_DIR = DNC_HOOK_SET_LIGHTING_DIR,
-- * Called whenever the fog color is calculated -- * Called whenever the fog color is calculated
-- * Parameters: `Color` color -- * Parameters: `Color` color
@ -770,7 +751,9 @@ _G.dayNightCycleApi = {
-- * Return: `ModelExtendedId` -- * Return: `ModelExtendedId`
DNC_HOOK_SET_SKYBOX_MODEL = DNC_HOOK_SET_SKYBOX_MODEL, DNC_HOOK_SET_SKYBOX_MODEL = DNC_HOOK_SET_SKYBOX_MODEL,
-- * Called when sunrise and sunset times are changed -- * Called when sunrise and sunset times are changed
DNC_HOOK_SUN_TIMES_CHANGED = DNC_HOOK_SUN_TIMES_CHANGED DNC_HOOK_SUN_TIMES_CHANGED = DNC_HOOK_SUN_TIMES_CHANGED,
-- * Called during HOOK_ON_HUD_RENDER_BEHIND before anything is rendered
DNC_HOOK_ON_HUD_RENDER_BEHIND = DNC_HOOK_ON_HUD_RENDER_BEHIND
} }
} }
setmetatable(_G.dayNightCycleApi, sReadonlyMetatable) setmetatable(_G.dayNightCycleApi, sReadonlyMetatable)

View file

@ -1,5 +1,5 @@
-- localize functions to improve performance -- localize functions to improve performance
local set_override_far,obj_mark_for_deletion,vec3f_to_object_pos,get_skybox,clampf = set_override_far,obj_mark_for_deletion,vec3f_to_object_pos,get_skybox,clampf local set_override_far,obj_mark_for_deletion,vec3f_to_object_pos,get_skybox = set_override_far,obj_mark_for_deletion,vec3f_to_object_pos,get_skybox
--- @param o Object --- @param o Object
function bhv_dnc_skybox_init(o) function bhv_dnc_skybox_init(o)
@ -29,33 +29,33 @@ function bhv_dnc_skybox_loop(o)
o.oOpacity = 255 o.oOpacity = 255
elseif o.oBehParams2ndByte == SKYBOX_SUNSET then elseif o.oBehParams2ndByte == SKYBOX_SUNSET then
if minutes >= HOUR_SUNRISE_START and minutes <= HOUR_SUNRISE_END then if minutes >= HOUR_SUNRISE_START and minutes <= HOUR_SUNRISE_END then
o.oOpacity = lerp_ceil(0, 255, clampf((minutes - HOUR_SUNRISE_START) / HOUR_SUNRISE_DURATION, 0, 1)) o.oOpacity = ((minutes - HOUR_SUNRISE_START) / HOUR_SUNRISE_DURATION) * 255
elseif minutes >= HOUR_SUNRISE_END and minutes <= HOUR_DAY_START then elseif minutes > HOUR_SUNRISE_END and minutes <= HOUR_DAY_START then
o.oOpacity = lerp_ceil(255, 0, clampf((minutes - HOUR_SUNRISE_END) / HOUR_SUNRISE_DURATION, 0, 1)) o.oOpacity = 255 - ((minutes - HOUR_SUNRISE_END) / HOUR_SUNRISE_DURATION) * 255
elseif minutes >= HOUR_SUNSET_START and minutes <= HOUR_SUNSET_END then elseif minutes >= HOUR_SUNSET_START and minutes <= HOUR_SUNSET_END then
o.oOpacity = lerp_ceil(0, 255, clampf((minutes - HOUR_SUNSET_START) / HOUR_SUNSET_DURATION, 0, 1)) o.oOpacity = ((minutes - HOUR_SUNSET_START) / HOUR_SUNSET_DURATION) * 255
elseif minutes >= HOUR_SUNSET_END and minutes <= HOUR_NIGHT_START then elseif minutes > HOUR_SUNSET_END and minutes <= HOUR_NIGHT_START then
o.oOpacity = 255 o.oOpacity = 255
else else
o.oOpacity = 0 o.oOpacity = 0
end end
if minutes < 12 then if minutes < 12 then
o.oAnimState = if_then_else(skybox == BACKGROUND_BELOW_CLOUDS, BACKGROUND_BELOW_CLOUDS_SUNRISE, BACKGROUND_SUNRISE) o.oAnimState = gSunriseSkyboxes[skybox] or BACKGROUND_OCEAN_SKY_SUNRISE
else else
o.oAnimState = if_then_else(skybox == BACKGROUND_BELOW_CLOUDS, BACKGROUND_BELOW_CLOUDS_SUNSET, BACKGROUND_SUNSET) o.oAnimState = gSunsetSkyboxes[skybox] or BACKGROUND_OCEAN_SKY_SUNSET
end end
o.oFaceAngleYaw = o.oFaceAngleYaw - if_then_else(minutes < 12, 0x3000, 0x6000) o.oFaceAngleYaw = o.oFaceAngleYaw - if_then_else(minutes < 12, 0x3000, 0x6000)
elseif o.oBehParams2ndByte == SKYBOX_NIGHT then elseif o.oBehParams2ndByte == SKYBOX_NIGHT then
if minutes >= HOUR_SUNRISE_START and minutes <= HOUR_SUNRISE_END then if minutes >= HOUR_SUNRISE_START and minutes <= HOUR_SUNRISE_END then
o.oOpacity = lerp_ceil(255, 0, clampf((minutes - HOUR_SUNRISE_START) / HOUR_SUNRISE_DURATION, 0, 1)) o.oOpacity = 255 - ((minutes - HOUR_SUNRISE_START) / HOUR_SUNRISE_DURATION) * 255
elseif minutes >= HOUR_SUNSET_END and minutes <= HOUR_NIGHT_START then elseif minutes >= HOUR_SUNSET_END and minutes <= HOUR_NIGHT_START then
o.oOpacity = lerp_ceil(0, 255, clampf((minutes - HOUR_SUNSET_END) / HOUR_SUNSET_DURATION, 0, 1)) o.oOpacity = ((minutes - HOUR_SUNSET_END) / HOUR_SUNSET_DURATION) * 255
elseif minutes > HOUR_SUNRISE_END and minutes < HOUR_SUNSET_END then
o.oOpacity = 0
elseif minutes > HOUR_NIGHT_START or minutes < HOUR_SUNRISE_START then elseif minutes > HOUR_NIGHT_START or minutes < HOUR_SUNRISE_START then
o.oOpacity = 255 o.oOpacity = 255
else
o.oOpacity = 0
end end
end end
end end