mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-29 07:23:01 +00:00
183 lines
No EOL
6.1 KiB
Lua
183 lines
No EOL
6.1 KiB
Lua
local sNightSequences = {}
|
|
|
|
-- localize functions to improve performance
|
|
local mod_storage_remove,mod_storage_load_bool,math_floor,mod_storage_save_number,mod_storage_load_number,type,error,network_is_moderator,network_is_server,string_format,djui_hud_is_pause_menu_created,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,network_is_moderator,network_is_server,string.format,djui_hud_is_pause_menu_created,smlua_audio_utils_replace_sequence,fade_volume_scale,set_background_music,obj_mark_for_deletion
|
|
|
|
-- purge legacy fields
|
|
mod_storage_remove("ampm")
|
|
mod_storage_remove("night-music")
|
|
|
|
use24h = mod_storage_load_bool("24h")
|
|
|
|
local savedInMenu = false
|
|
local autoSaveTimer = 0
|
|
--- @type boolean
|
|
playNightMusic = if_then_else(mod_storage_load("night_music") == nil, true, mod_storage_load_bool("night_music"))
|
|
playingNightMusic = false
|
|
|
|
--- Returns the amount of days that have passed
|
|
function get_day_count()
|
|
return math_floor(gGlobalSyncTable.time / (MINUTE * 24))
|
|
end
|
|
|
|
function save_time()
|
|
if gNetworkPlayers[0].currActNum == 99 then return end
|
|
mod_storage_save_number("time", gGlobalSyncTable.time)
|
|
print("Saving time to 'day-night-cycle.sav'")
|
|
end
|
|
|
|
function load_time()
|
|
local time = mod_storage_load_number("time")
|
|
if time == nil then
|
|
time = MINUTE * 4 -- starts at the beginning of sunrise
|
|
mod_storage_save_number("time", time)
|
|
end
|
|
return time
|
|
end
|
|
|
|
--- Returns the time in frames
|
|
function get_raw_time()
|
|
return gGlobalSyncTable.time
|
|
end
|
|
|
|
--- @param time integer
|
|
--- Sets the time in frames
|
|
function set_raw_time(time)
|
|
if type(time) ~= "number" then
|
|
error("set_raw_time: Parameter 'time' must be a number")
|
|
return
|
|
end
|
|
if not network_is_server() and not network_is_moderator() then return end
|
|
|
|
gGlobalSyncTable.time = time
|
|
end
|
|
|
|
--- Returns the amount of time that has passed in the day in minutes
|
|
function get_time_minutes()
|
|
return (gGlobalSyncTable.time / MINUTE) % 24
|
|
end
|
|
|
|
--- Returns the time scale
|
|
function get_time_scale()
|
|
return gGlobalSyncTable.timeScale
|
|
end
|
|
|
|
--- @param scale number
|
|
--- Sets the time scale
|
|
function set_time_scale(scale)
|
|
if type(scale) ~= "number" then
|
|
error("set_time_scale: Parameter 'scale' must be a number")
|
|
return
|
|
end
|
|
if not network_is_server() and not network_is_moderator() then return end
|
|
|
|
gGlobalSyncTable.timeScale = scale
|
|
end
|
|
|
|
--- @param time number
|
|
--- @return string
|
|
--- Returns the properly formatted time string
|
|
function get_time_string(time)
|
|
if type(time) ~= "number" then
|
|
error("get_time_string: Parameter 'time' must be a number")
|
|
if use24h then
|
|
return "12:00 AM"
|
|
else
|
|
return "0:00"
|
|
end
|
|
end
|
|
|
|
local minutes = (time / MINUTE) % 24
|
|
local formattedMinutes = math_floor(minutes)
|
|
local seconds = math_floor(time / SECOND) % 60
|
|
|
|
if not use24h then
|
|
if formattedMinutes == 0 then
|
|
formattedMinutes = 12
|
|
elseif formattedMinutes > 12 then
|
|
formattedMinutes = formattedMinutes - 12
|
|
end
|
|
end
|
|
|
|
return string_format("%d:%02d%s", formattedMinutes, seconds, if_then_else(not use24h, if_then_else(minutes < 12, " AM", " PM"), ""))
|
|
end
|
|
|
|
function time_tick()
|
|
gGlobalSyncTable.time = gGlobalSyncTable.time + gGlobalSyncTable.timeScale
|
|
|
|
-- auto save every 30s
|
|
autoSaveTimer = (autoSaveTimer + 1) % (SECOND * 30)
|
|
if autoSaveTimer == 0 then
|
|
save_time()
|
|
end
|
|
|
|
-- save when paused
|
|
if djui_hud_is_pause_menu_created() then
|
|
if not savedInMenu then
|
|
save_time()
|
|
savedInMenu = true
|
|
end
|
|
else
|
|
savedInMenu = false
|
|
end
|
|
end
|
|
|
|
function night_music_register(sequenceId, m64Name)
|
|
local id = SEQ_COUNT + sequenceId
|
|
smlua_audio_utils_replace_sequence(id, 20, 127, m64Name)
|
|
sNightSequences[sequenceId] = id
|
|
end
|
|
|
|
function handle_night_music()
|
|
if gNetworkPlayers[0].currActNum == 99 or gMarioStates[0].area == nil then return end
|
|
local musicParam = gMarioStates[0].area.musicParam2
|
|
|
|
if not playNightMusic or not dayNightCycleApi.playNightMusic then
|
|
if playingNightMusic then
|
|
playingNightMusic = false
|
|
fade_volume_scale(SEQ_PLAYER_LEVEL, 127, 1)
|
|
set_background_music(SEQ_PLAYER_LEVEL, SEQUENCE_ARGS(4, musicParam), 0)
|
|
end
|
|
return
|
|
end
|
|
|
|
local seq = sNightSequences[musicParam]
|
|
if seq == nil then return end
|
|
|
|
fade_volume_scale(0, 127, 1)
|
|
|
|
local minutes = get_time_minutes()
|
|
|
|
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
|
|
local threshold = 1 - (minutes - (HOUR_SUNRISE_START + 0.75)) * 4
|
|
fade_volume_scale(SEQ_PLAYER_LEVEL, threshold * 127, 1)
|
|
end
|
|
|
|
if (minutes >= HOUR_NIGHT_START or minutes < HOUR_SUNRISE_END) and not playingNightMusic then
|
|
playingNightMusic = true
|
|
fade_volume_scale(SEQ_PLAYER_LEVEL, 127, 1)
|
|
set_background_music(SEQ_PLAYER_LEVEL, SEQUENCE_ARGS(4, seq), 450)
|
|
elseif minutes >= HOUR_SUNRISE_END and minutes < HOUR_NIGHT_START and playingNightMusic then
|
|
playingNightMusic = false
|
|
fade_volume_scale(SEQ_PLAYER_LEVEL, 127, 1)
|
|
set_background_music(SEQ_PLAYER_LEVEL, SEQUENCE_ARGS(4, musicParam), 0)
|
|
end
|
|
end
|
|
|
|
--- @param obj Object
|
|
function delete_at_dark(obj)
|
|
if obj == nil then
|
|
error("delete_at_dark: Parameter 'obj' must be an Object")
|
|
return
|
|
end
|
|
local minutes = gGlobalSyncTable.time / MINUTE % 24
|
|
|
|
local delete = minutes < HOUR_SUNRISE_START or minutes > HOUR_SUNSET_END
|
|
overrideDelete = dnc_call_hook(DNC_HOOK_DELETE_AT_DARK, obj, delete)
|
|
if overrideDelete ~= nil and type(overrideDelete) == "boolean" then delete = overrideDelete end
|
|
|
|
if delete then obj_mark_for_deletion(obj) end
|
|
end |