mirror of
				https://github.com/coop-deluxe/sm64coopdx.git
				synced 2025-10-30 08:01:01 +00:00 
			
		
		
		
	
		
			Some checks failed
		
		
	
	Build coop / build-linux (push) Has been cancelled
				
			Build coop / build-steamos (push) Has been cancelled
				
			Build coop / build-windows-opengl (push) Has been cancelled
				
			Build coop / build-windows-directx (push) Has been cancelled
				
			Build coop / build-macos-arm (push) Has been cancelled
				
			Build coop / build-macos-intel (push) Has been cancelled
				
			
		
			
				
	
	
		
			223 lines
		
	
	
		
			No EOL
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			223 lines
		
	
	
		
			No EOL
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
if incompatibleClient then return 0 end
 | 
						|
 | 
						|
-- localize functions to improve performance - z-voice.lua
 | 
						|
local type,audio_sample_stop,audio_sample_load,math_random,audio_sample_play,is_game_paused,table_insert,play_character_sound = type,audio_sample_stop,audio_sample_load,math.random,audio_sample_play,is_game_paused,table.insert,play_character_sound
 | 
						|
 | 
						|
-- rewritten custom voice system for Character Select
 | 
						|
-- by Agent X
 | 
						|
 | 
						|
-- will need some revising in the future, but this will do for now.
 | 
						|
 | 
						|
local SLEEP_TALK_SNORES = 8
 | 
						|
local STARTING_SNORE = 46
 | 
						|
local SLEEP_TALK_START = STARTING_SNORE + 49
 | 
						|
local SLEEP_TALK_END = SLEEP_TALK_START + SLEEP_TALK_SNORES
 | 
						|
local stallTimer = 0
 | 
						|
local stallSayLine = 5
 | 
						|
 | 
						|
local TYPE_TABLE = "table"
 | 
						|
local TYPE_USERDATA = "userdata"
 | 
						|
local TYPE_STRING = "string"
 | 
						|
local function check_sound_exists(sound)
 | 
						|
    if sound == nil then return false end
 | 
						|
    local soundType = type(sound)
 | 
						|
    if soundType == TYPE_USERDATA and sound._pointer ~= nil then
 | 
						|
        return true
 | 
						|
    elseif soundType == TYPE_STRING then
 | 
						|
        sound = "sound/"..sound
 | 
						|
        return (mod_file_exists(sound))
 | 
						|
    end
 | 
						|
    return false
 | 
						|
end
 | 
						|
 | 
						|
local function stop_all_custom_character_sounds()
 | 
						|
    -- run through each player
 | 
						|
    for i = 0, MAX_PLAYERS - 1 do
 | 
						|
        local m = gMarioStates[i]
 | 
						|
        -- get the voice table, if there is one
 | 
						|
        local voiceTable = character_get_voice(m)
 | 
						|
        if voiceTable ~= nil then
 | 
						|
            -- run through each sample
 | 
						|
            for sound in pairs(voiceTable) do
 | 
						|
                -- if the sample is found, try to stop it
 | 
						|
                if voiceTable[sound] ~= nil and type(voiceTable[sound]) ~= "string" then
 | 
						|
                    -- if there's no pointer then it must be a sound clip table
 | 
						|
                    if voiceTable[sound]._pointer == nil then
 | 
						|
                        for voice in pairs(voiceTable[sound]) do
 | 
						|
                            if type(voiceTable[sound][voice]) == "string" then
 | 
						|
                                break
 | 
						|
                            end
 | 
						|
                            audio_sample_stop(voiceTable[sound][voice])
 | 
						|
                        end
 | 
						|
                    else
 | 
						|
                        audio_sample_stop(voiceTable[sound])
 | 
						|
                    end
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
--[[local function stop_custom_character_sound(m, sound)
 | 
						|
    local voiceTable = character_get_voice(m)
 | 
						|
    -- if there's no pointer then it must be a sound clip table
 | 
						|
    if type(voiceTable[sound]) == "string" then return end
 | 
						|
    if voiceTable[sound]._pointer == nil then
 | 
						|
        for voice in pairs(voiceTable[sound]) do
 | 
						|
            if type(voiceTable[voice]) == "string" then
 | 
						|
                break
 | 
						|
            end
 | 
						|
            audio_sample_stop(voiceTable[sound][voice])
 | 
						|
        end
 | 
						|
    else
 | 
						|
        audio_sample_stop(voiceTable[sound])
 | 
						|
    end
 | 
						|
end]]
 | 
						|
 | 
						|
local playerSample = {}
 | 
						|
for i = 0, MAX_PLAYERS - 1 do
 | 
						|
    playerSample[i] = nil
 | 
						|
end
 | 
						|
 | 
						|
--- @param m MarioState
 | 
						|
--- @param sound CharacterSound
 | 
						|
local function custom_character_sound(m, sound)
 | 
						|
    if m.playerIndex == 0 then
 | 
						|
        if stallTimer < stallSayLine then
 | 
						|
            return NO_SOUND
 | 
						|
        end
 | 
						|
    end
 | 
						|
    local index = m.playerIndex
 | 
						|
    if check_sound_exists(playerSample[index]) and type(playerSample[index]) ~= TYPE_STRING then
 | 
						|
        audio_sample_stop(playerSample[index])
 | 
						|
    end
 | 
						|
    if optionTable[optionTableRef.localVoices].toggle == 0 then return NO_SOUND end
 | 
						|
 | 
						|
    -- get the voice table
 | 
						|
    local voiceTable = character_get_voice(m)
 | 
						|
    if voiceTable == nil then return end
 | 
						|
    -- load samples that haven't been loaded
 | 
						|
    for voice, name in pairs(voiceTable) do
 | 
						|
        if check_sound_exists(voiceTable[voice]) and type(voiceTable[voice]) == "string" then
 | 
						|
            local load = audio_sample_load(name)
 | 
						|
            if load ~= nil then
 | 
						|
                voiceTable[voice] = load
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    -- get the sample to play
 | 
						|
    local voice = voiceTable[sound]
 | 
						|
    if voice == nil then return NO_SOUND end
 | 
						|
    playerSample[index] = voice
 | 
						|
    -- if there's no pointer then it must be a sound clip table
 | 
						|
    if voice._pointer == nil and type(voice) ~= TYPE_STRING then
 | 
						|
        -- run through each sample and load in any samples that haven't been loaded
 | 
						|
        for i, name in pairs(voice) do
 | 
						|
            if check_sound_exists(voice[i]) and type(voice[i]) == "string" then
 | 
						|
                local load = audio_sample_load(name)
 | 
						|
                if load ~= nil then
 | 
						|
                    voice[i] = load
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
        if #voice ~= 0 then
 | 
						|
            -- choose a random sample
 | 
						|
            playerSample[index] = voice[math_random(#voice)]
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    -- Play the sample
 | 
						|
    if check_sound_exists(playerSample[index]) then
 | 
						|
        if sound == CHAR_SOUND_SNORING1 or sound == CHAR_SOUND_SNORING2 or sound == CHAR_SOUND_SNORING3 then
 | 
						|
            audio_sample_play(playerSample[index], m.pos, 0.5)
 | 
						|
        else
 | 
						|
            audio_sample_play(playerSample[index], m.pos, 1.0)
 | 
						|
        end
 | 
						|
        return NO_SOUND
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
--- @param m MarioState
 | 
						|
local function custom_character_snore(m)
 | 
						|
    if is_game_paused() or optionTable[optionTableRef.localVoices].toggle == 0 then return end
 | 
						|
 | 
						|
    if m.action ~= ACT_SLEEPING then
 | 
						|
        return
 | 
						|
    elseif m.actionState ~= 2 or (m.flags & MARIO_MARIO_SOUND_PLAYED) == 0 then
 | 
						|
        return
 | 
						|
    end
 | 
						|
 | 
						|
    local voice = character_get_voice(m)
 | 
						|
    if voice == nil then return end
 | 
						|
    local snoreTable = voice[CHAR_SOUND_SNORING3]
 | 
						|
    if snoreTable == nil or snoreTable._pointer ~= nil then
 | 
						|
        snoreTable = {}
 | 
						|
        for i = CHAR_SOUND_SNORING1, CHAR_SOUND_SNORING3 do
 | 
						|
            if voice[i] ~= nil then
 | 
						|
                table_insert(snoreTable, voice[i])
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    local animFrame = m.marioObj.header.gfx.animInfo.animFrame
 | 
						|
    if snoreTable ~= nil and #snoreTable >= 2 then
 | 
						|
        if animFrame == 2 and m.actionTimer < SLEEP_TALK_START then
 | 
						|
            custom_character_sound(m, snoreTable[2])
 | 
						|
        elseif animFrame == 25 then
 | 
						|
            if #snoreTable >= 3 then
 | 
						|
                m.actionTimer = m.actionTimer + 1
 | 
						|
                if m.actionTimer >= SLEEP_TALK_END then
 | 
						|
                    m.actionTimer = STARTING_SNORE
 | 
						|
                end
 | 
						|
                if m.actionTimer == SLEEP_TALK_START then
 | 
						|
                    play_character_sound(m, CHAR_SOUND_SNORING3)
 | 
						|
                elseif m.actionTimer < SLEEP_TALK_START then
 | 
						|
                    play_character_sound(m, CHAR_SOUND_SNORING1)
 | 
						|
                end
 | 
						|
            else
 | 
						|
                play_character_sound(m, CHAR_SOUND_SNORING1)
 | 
						|
            end
 | 
						|
        end
 | 
						|
    elseif animFrame == 2 then
 | 
						|
        play_character_sound(m, CHAR_SOUND_SNORING2)
 | 
						|
 | 
						|
    elseif animFrame == 25 then
 | 
						|
        play_character_sound(m, CHAR_SOUND_SNORING1)
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
local function update()
 | 
						|
    if is_game_paused() then
 | 
						|
        stop_all_custom_character_sounds()
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
hook_event(HOOK_UPDATE, update)
 | 
						|
hook_event(HOOK_ON_LEVEL_INIT, stop_all_custom_character_sounds)
 | 
						|
 | 
						|
_G.charSelect.voice = {
 | 
						|
    sound = custom_character_sound,
 | 
						|
    snore = custom_character_snore,
 | 
						|
}
 | 
						|
 | 
						|
-- Must be ran on startup
 | 
						|
local function config_character_sounds()
 | 
						|
    hook_event(HOOK_CHARACTER_SOUND, custom_character_sound)
 | 
						|
    --hook_event(HOOK_MARIO_UPDATE, custom_character_snore)
 | 
						|
    cs_hook_mario_update(custom_character_snore)
 | 
						|
end
 | 
						|
_G.charSelect.config_character_sounds = config_character_sounds
 | 
						|
 | 
						|
-- Join sound
 | 
						|
local function mario_update(m)
 | 
						|
    if m.playerIndex ~= 0 then return end
 | 
						|
    if stallTimer == stallSayLine then
 | 
						|
        play_character_sound(m, CHAR_SOUND_OKEY_DOKEY)
 | 
						|
        stallTimer = stallTimer + 1
 | 
						|
    elseif stallTimer < stallSayLine then
 | 
						|
        stallTimer = stallTimer + 1
 | 
						|
    end
 | 
						|
end
 | 
						|
--hook_event(HOOK_MARIO_UPDATE, mario_update)
 | 
						|
cs_hook_mario_update(mario_update) |