diff --git a/mods/day-night-cycle/a-utils.lua b/mods/day-night-cycle/a-utils.lua index 4e4f703fe..ed2450143 100755 --- a/mods/day-night-cycle/a-utils.lua +++ b/mods/day-night-cycle/a-utils.lua @@ -1,5 +1,37 @@ -- 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 --- Human readable ternary operator @@ -8,21 +40,18 @@ function if_then_else(cond, ifTrue, ifFalse) return ifFalse end ---- @param s string ---- Splits a string into a table by spaces -function split(s) - local result = {} - for match in (s):gmatch(string_format("[^%s]+", " ")) do - table_insert(result, match) - end - return result +--- @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 x number --- @return integer --- Rounds up or down depending on the decimal position of `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 --- @param a number @@ -63,17 +92,11 @@ end --- @param priority integer --- @param seqId SeqId +--- Generates a sequence ID integer with priority function SEQUENCE_ARGS(priority, seqId) return ((priority << 8) | seqId) 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 --- Returns whether or not the local player is in a vanilla level function in_vanilla_level(levelNum) @@ -84,33 +107,18 @@ end --- @param x number --- @param y number --- @param scale number ---- @param outlineBrightness number --- Prints outlined DJUI HUD text -function djui_hud_print_outlined_text(message, x, y, scale, outlineBrightness) - local color = djui_hud_get_color() - djui_hud_set_color(color.r * outlineBrightness, color.g * outlineBrightness, color.b * outlineBrightness, color.a) +function djui_hud_print_outlined_text(message, x, y, scale) + local hudColor = djui_hud_get_color() + 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, 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) 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 function check_common_hud_render_cancels() local action = gMarioStates[0].action @@ -119,26 +127,4 @@ function check_common_hud_render_cancels() gNetworkPlayers[0].currLevelNum == LEVEL_BOWSER_3 or gNetworkPlayers[0].currLevelNum == LEVEL_ENDING or action == ACT_END_PEACH_CUTSCENE or action == ACT_END_WAVING_CUTSCENE or action == ACT_CREDITS_CUTSCENE -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 \ No newline at end of file diff --git a/mods/day-night-cycle/actors/dnc_skybox_geo.bin b/mods/day-night-cycle/actors/dnc_skybox_geo.bin index 590978836..e066b4773 100644 Binary files a/mods/day-night-cycle/actors/dnc_skybox_geo.bin and b/mods/day-night-cycle/actors/dnc_skybox_geo.bin differ diff --git a/mods/day-night-cycle/b-constants.lua b/mods/day-night-cycle/b-constants.lua index e039a1d1c..5dbdce9fe 100644 --- a/mods/day-night-cycle/b-constants.lua +++ b/mods/day-night-cycle/b-constants.lua @@ -1,6 +1,6 @@ -- version DNC_VERSION_MAJOR = 2 -DNC_VERSION_MINOR = 4 +DNC_VERSION_MINOR = 5 DNC_VERSION_PATCH = 0 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 -- background constants -BACKGROUND_NIGHT = 10 -BACKGROUND_SUNRISE = 11 -BACKGROUND_SUNSET = 12 -BACKGROUND_BELOW_CLOUDS_NIGHT = 13 -BACKGROUND_BELOW_CLOUDS_SUNRISE = 14 -BACKGROUND_BELOW_CLOUDS_SUNSET = 15 +BACKGROUND_OCEAN_SKY_NIGHT = 10 +BACKGROUND_OCEAN_SKY_SUNRISE = 11 +BACKGROUND_OCEAN_SKY_SUNSET = 12 +BACKGROUND_UNDERWATER_CITY_NIGHT = 13 +BACKGROUND_UNDERWATER_CITY_SUNRISE = 14 +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 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 -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 } -local month = get_date_and_time().month + 1 +local MONTH = get_date_and_time().month + 1 syncSun = mod_storage_load_bool_2("sync_sun") HOUR_SUNRISE_START_BASE = 4 HOUR_SUNSET_START_BASE = 19 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_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_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 -- lighting direction constants -DIR_DARK = 0.6 -DIR_BRIGHT = 1 +DIR_DARK = -0.4 +DIR_BRIGHT = 0 -- fog intensity constants FOG_INTENSITY_NORMAL = 1.0 FOG_INTENSITY_DENSE = 1.02 -- colors -COLOR_NIGHT = { r = 90, g = 110, b = 150 } -COLOR_AMBIENT_NIGHT = { r = 90, g = 100, b = 150 } -COLOR_SUNRISE = { r = 255, g = 250, b = 150 } +COLOR_NIGHT = { r = 90, g = 100, b = 150 } +COLOR_AMBIENT_NIGHT = { r = 70, g = 90, b = 150 } +COLOR_SUNRISE = { r = 255, g = 250, b = 100 } COLOR_AMBIENT_SUNRISE = { r = 200, g = 200, b = 255 } COLOR_DAY = { r = 255, g = 255, b = 255 } COLOR_AMBIENT_DAY = { r = 255, g = 255, b = 255 } @@ -82,4 +121,5 @@ DNC_HOOK_SET_DISPLAY_TIME_POS = 6 DNC_HOOK_DELETE_AT_DARK = 7 DNC_HOOK_SET_TIME = 8 DNC_HOOK_SET_SKYBOX_MODEL = 9 -DNC_HOOK_SUN_TIMES_CHANGED = 10 \ No newline at end of file +DNC_HOOK_SUN_TIMES_CHANGED = 10 +DNC_HOOK_ON_HUD_RENDER_BEHIND = 11 \ No newline at end of file diff --git a/mods/day-night-cycle/b-time.lua b/mods/day-night-cycle/b-time.lua index d01f83b7f..a77568d82 100755 --- a/mods/day-night-cycle/b-time.lua +++ b/mods/day-night-cycle/b-time.lua @@ -1,7 +1,7 @@ -local sNightSequences = {} - -- 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 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 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) - 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 fade_volume_scale(SEQ_PLAYER_LEVEL, threshold * 127, 1) end diff --git a/mods/day-night-cycle/main.lua b/mods/day-night-cycle/main.lua index 76c2557cb..d4079491e 100755 --- a/mods/day-night-cycle/main.lua +++ b/mods/day-night-cycle/main.lua @@ -1,24 +1,14 @@ -- name: Day Night Cycle DX -- 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 ---- @field public x number ---- @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 +-- localize functions to improve performance +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 local init = false local timeModifier = 0 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 = { [DNC_HOOK_SET_LIGHTING_COLOR] = {}, [DNC_HOOK_SET_AMBIENT_LIGHTING_COLOR] = {}, @@ -30,9 +20,16 @@ local sDncHooks = { [DNC_HOOK_DELETE_AT_DARK] = {}, [DNC_HOOK_SET_TIME] = {}, [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 func function --- Hooks a function to the Day Night Cycle hook system @@ -82,6 +79,7 @@ function show_day_night_cycle() end local function reset_lighting() + set_lighting_dir(0, 0) set_lighting_dir(1, 0) set_lighting_dir(2, 0) set_lighting_color(0, 255) @@ -107,6 +105,7 @@ local function update() if network_is_server() then time_tick() end if init then update_night_music() end + init = true -- spawn skyboxes local skybox = get_skybox() @@ -118,9 +117,9 @@ local function update() for i = SKYBOX_DAY, SKYBOX_NIGHT do local thisSkybox = skybox 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 - thisSkybox = if_then_else(skybox == BACKGROUND_BELOW_CLOUDS, BACKGROUND_BELOW_CLOUDS_NIGHT, BACKGROUND_NIGHT) + thisSkybox = gNightSkyboxes[skybox] end local model = E_MODEL_DNC_SKYBOX @@ -140,10 +139,14 @@ local function update() ) end 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_non_sync_object( bhvDNCSkybox, - E_MODEL_DNC_SKYBOX, + model, 0, 0, 0, --- @param o Object function(o) @@ -158,124 +161,102 @@ local function update() local minutes = if_then_else(is_static_skybox(skybox), 12, get_time_minutes()) local actSelector = obj_get_first_with_behavior_id(id_bhvActSelector) - if actSelector == nil and show_day_night_cycle() then - -- calculate lighting color - local color = COLOR_DAY - 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) - 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) - 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) - 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) - elseif minutes > HOUR_NIGHT_START or minutes < HOUR_SUNRISE_START then - color = COLOR_NIGHT - elseif minutes > HOUR_DAY_START and minutes < HOUR_SUNSET_START then - color = COLOR_DAY - end - local overrideColor = dnc_call_hook(DNC_HOOK_SET_LIGHTING_COLOR, table_clone(color)) - 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)) - 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)) - if overrideFogColor ~= nil and type(overrideFogColor) == "table" then fogColor = overrideFogColor end - - -- calculate lighting direction - local dir = DIR_BRIGHT - 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 intensity = FOG_INTENSITY_NORMAL - if minutes >= HOUR_SUNRISE_START and minutes <= HOUR_SUNRISE_END then - 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(2, -(1 - dir)) - -- make the castle still 25% ambient lit - if in_vanilla_level(LEVEL_CASTLE) then - color = color_lerp(COLOR_DAY, color, 0.75) - end - set_lighting_color(0, color.r) - set_lighting_color(1, color.g) - set_lighting_color(2, color.b) - set_lighting_color_ambient(0, ambientColor.r) - set_lighting_color_ambient(1, ambientColor.g) - set_lighting_color_ambient(2, ambientColor.b) - local mix = color_lerp(color, ambientColor, 0.5) - set_vertex_color(0, mix.r) - set_vertex_color(1, mix.g) - set_vertex_color(2, mix.b) - set_fog_color(0, fogColor.r) - set_fog_color(1, fogColor.g) - set_fog_color(2, fogColor.b) - set_fog_intensity(intensity) - - -- lighting engine compatibility - if obj_get_first_with_behavior_id(id_bhvAmbientLight) ~= nil then - mix = color_lerp(color, COLOR_WHITE, 0.5) -- make the color less intense - le_set_ambient_color(mix.r, mix.g, mix.b) - end - else + if actSelector ~= nil or not show_day_night_cycle() then reset_lighting() + return end - init = true + -- calculate lighting color + 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 + 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 + 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 + 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 + 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 + color = COLOR_NIGHT + ambientColor = COLOR_AMBIENT_NIGHT + dir = DIR_DARK + fogColor = FOG_COLOR_NIGHT + fogIntensity = FOG_INTENSITY_DENSE + end + fogColor = color_lerp(fogColor, ambientColor, 0.5) + + local overrideColor = dnc_call_hook(DNC_HOOK_SET_LIGHTING_COLOR, table_clone(color)) + if overrideColor ~= nil and type(overrideColor) == "table" then color = overrideColor end + + 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 + + local overrideFogColor = dnc_call_hook(DNC_HOOK_SET_FOG_COLOR, table_clone(fogColor)) + if overrideFogColor ~= nil and type(overrideFogColor) == "table" then fogColor = overrideFogColor end + + local overrideFogIntensity = dnc_call_hook(DNC_HOOK_SET_FOG_INTENSITY, fogIntensity) + if overrideFogIntensity ~= nil and type(overrideFogIntensity) == "number" then fogIntensity = overrideFogIntensity end + + local lightingDir = { x = 0, y = dir, z = dir } + local overrideLightingDir = dnc_call_hook(DNC_HOOK_SET_LIGHTING_DIR, lightingDir) + if overrideLightingDir ~= nil and type(overrideLightingDir) == "table" then lightingDir = overrideLightingDir end + + set_lighting_dir(0, lightingDir.x) + set_lighting_dir(1, lightingDir.y) + set_lighting_dir(2, lightingDir.z) + -- make the castle still 25% lit + if in_vanilla_level(LEVEL_CASTLE) then + color = color_lerp(COLOR_DAY, color, 0.75) + end + set_lighting_color(0, color.r) + set_lighting_color(1, color.g) + set_lighting_color(2, color.b) + set_lighting_color_ambient(0, ambientColor.r) + set_lighting_color_ambient(1, ambientColor.g) + set_lighting_color_ambient(2, ambientColor.b) + local mix = color_lerp(color, ambientColor, 0.5) + set_vertex_color(0, mix.r) + set_vertex_color(1, mix.g) + set_vertex_color(2, mix.b) + set_fog_color(0, fogColor.r) + set_fog_color(1, fogColor.g) + set_fog_color(2, fogColor.b) + set_fog_intensity(fogIntensity) + + -- lighting engine compatibility + if obj_get_first_with_behavior_id(id_bhvAmbientLight) ~= nil then + mix = color_lerp(color, COLOR_WHITE, 0.5) -- make the color less intense + le_set_ambient_color(mix.r, mix.g, mix.b) + end end 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 dayNightCycleApi.displayTime or not displayTime then return end -- API 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) 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 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 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 local function on_level_init() @@ -428,7 +409,7 @@ local function on_scale_command(msg) gGlobalSyncTable.timeScale = 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) @@ -521,7 +502,7 @@ end --- @param msg string local function on_time_command(msg) - local args = split(msg) + local args = string_split(msg) if args[1] == "set" 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_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) end @@ -739,8 +720,8 @@ _G.dayNightCycleApi = { -- * Return: `Color` DNC_HOOK_SET_AMBIENT_LIGHTING_COLOR = DNC_HOOK_SET_AMBIENT_LIGHTING_COLOR, -- * Called whenever the lighting direction is calculated - -- * Parameters: `number` dir - -- * Return: `number` + -- * Parameters: `Vec3f` lightingDir + -- * Return: `Vec3f` DNC_HOOK_SET_LIGHTING_DIR = DNC_HOOK_SET_LIGHTING_DIR, -- * Called whenever the fog color is calculated -- * Parameters: `Color` color @@ -770,7 +751,9 @@ _G.dayNightCycleApi = { -- * Return: `ModelExtendedId` DNC_HOOK_SET_SKYBOX_MODEL = DNC_HOOK_SET_SKYBOX_MODEL, -- * 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) diff --git a/mods/day-night-cycle/skybox.lua b/mods/day-night-cycle/skybox.lua index dab52a8e7..f9b203084 100755 --- a/mods/day-night-cycle/skybox.lua +++ b/mods/day-night-cycle/skybox.lua @@ -1,5 +1,5 @@ -- 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 function bhv_dnc_skybox_init(o) @@ -29,33 +29,33 @@ function bhv_dnc_skybox_loop(o) o.oOpacity = 255 elseif o.oBehParams2ndByte == SKYBOX_SUNSET 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)) - 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 = ((minutes - HOUR_SUNRISE_START) / HOUR_SUNRISE_DURATION) * 255 + elseif minutes > HOUR_SUNRISE_END and minutes <= HOUR_DAY_START then + o.oOpacity = 255 - ((minutes - HOUR_SUNRISE_END) / HOUR_SUNRISE_DURATION) * 255 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)) - elseif minutes >= HOUR_SUNSET_END and minutes <= HOUR_NIGHT_START then + o.oOpacity = ((minutes - HOUR_SUNSET_START) / HOUR_SUNSET_DURATION) * 255 + elseif minutes > HOUR_SUNSET_END and minutes <= HOUR_NIGHT_START then o.oOpacity = 255 else o.oOpacity = 0 end 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 - 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 o.oFaceAngleYaw = o.oFaceAngleYaw - if_then_else(minutes < 12, 0x3000, 0x6000) elseif o.oBehParams2ndByte == SKYBOX_NIGHT 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 - o.oOpacity = lerp_ceil(0, 255, clampf((minutes - HOUR_SUNSET_END) / HOUR_SUNSET_DURATION, 0, 1)) - elseif minutes > HOUR_SUNRISE_END and minutes < HOUR_SUNSET_END then - o.oOpacity = 0 + o.oOpacity = ((minutes - HOUR_SUNSET_END) / HOUR_SUNSET_DURATION) * 255 elseif minutes > HOUR_NIGHT_START or minutes < HOUR_SUNRISE_START then o.oOpacity = 255 + else + o.oOpacity = 0 end end end \ No newline at end of file