diff --git a/mods/char-select-extra-chars/toadette.lua b/mods/char-select-extra-chars/toadette.lua index ece3e95c..a7f6bdea 100644 --- a/mods/char-select-extra-chars/toadette.lua +++ b/mods/char-select-extra-chars/toadette.lua @@ -33,10 +33,10 @@ VOICETABLE_TOADETTE = { [CHAR_SOUND_MAMA_MIA] = "toadette_ooh.ogg", [CHAR_SOUND_DOH] = "toadette_oof.ogg", [CHAR_SOUND_HRMM] = "toadette_pickup.ogg", - [CHAR_SOUND_PANTING] = "toadette_pant", - [CHAR_SOUND_UH] = "toadette_oof_3.ogg", - [CHAR_SOUND_UH2] = "toadette_oof_4.ogg", - [CHAR_SOUND_UH2_2] = "toadette_oof_5.ogg" + [CHAR_SOUND_PANTING] = "toadette_pant.ogg", + [CHAR_SOUND_UH] = "toadette_oof2.ogg", + [CHAR_SOUND_UH2] = "toadette_oof2.ogg", + [CHAR_SOUND_UH2_2] = "toadette_oof2.ogg" } --MAKING VOICE CLIPS FOR ATM. USE PLACEHOLDER VOICE CLIPS! diff --git a/mods/char-select-extra-chars/yoshi.lua b/mods/char-select-extra-chars/yoshi.lua index 915afba1..7ef1768d 100644 --- a/mods/char-select-extra-chars/yoshi.lua +++ b/mods/char-select-extra-chars/yoshi.lua @@ -52,7 +52,7 @@ VOICETABLE_YOSHI = { [CHAR_SOUND_OOOF] = "yoshi_oof.ogg", [CHAR_SOUND_OOOF2] = "yoshi_oof2.ogg", [CHAR_SOUND_PANTING] = "yoshi_pant.ogg", - [CHAR_SOUND_PANTING_COLD] = "yoshi_pant_cold.ogg", + [CHAR_SOUND_PANTING_COLD] = "yoshi_pant.ogg", [CHAR_SOUND_SNORING1] = "yoshi_snore1.ogg", [CHAR_SOUND_SNORING2] = "yoshi_snore2.ogg", [CHAR_SOUND_SNORING3] = {"yoshi_snore1.ogg", "yoshi_snore2.ogg", "yoshi_snore3.ogg"}, diff --git a/mods/character-select-coop/main.lua b/mods/character-select-coop/main.lua index 221583b2..0c33568f 100644 --- a/mods/character-select-coop/main.lua +++ b/mods/character-select-coop/main.lua @@ -48,6 +48,8 @@ characterTable = { }, } +gPlayerSyncTable[0].offset = 0 + characterCaps = {} characterCelebrationStar = {} characterColorPresets = {} @@ -387,6 +389,14 @@ local menuActBlacklist = { } local faceAngle = 0 +local altOffsetActs = { + [ACT_CROUCH_SLIDE] = true, + [ACT_READING_AUTOMATIC_DIALOG] = true, + [ACT_DEATH_EXIT_LAND] = true, + [ACT_SLIDE_KICK] = false, + [ACT_SLIDE_KICK_SLIDE] = false, + [ACT_GROUND_POUND] = true, +} --- @param m MarioState local function mario_update(m) @@ -429,6 +439,13 @@ local function mario_update(m) currChar = 1 end + gPlayerSyncTable[0].offset = characterTable[currChar].offset + --[[ + for i = 0, MAX_PLAYERS-1 do + local m = gMarioStates[i] + end + ]] + if menuAndTransition then camera_freeze() hud_hide() @@ -476,29 +493,11 @@ local function mario_update(m) optionTable[i].optionBeingSet = false end end -end - -local altOffsetActs = { - [ACT_CROUCH_SLIDE] = true, - [ACT_READING_AUTOMATIC_DIALOG] = true, - [ACT_DEATH_EXIT_LAND] = true, - [ACT_SLIDE_KICK] = false, - [ACT_SLIDE_KICK_SLIDE] = false, - [ACT_GROUND_POUND] = true, -} - --- Vertical Offsets -local function on_object_render(obj) - if get_id_from_behavior(obj.behavior) ~= id_bhvMario then - return - end - for i=0, MAX_PLAYERS-1 do - local m = gMarioStates[i] - if characterTable[currChar].offset ~= 0 then - if altOffsetActs[m.action] ~= false then - m.marioObj.header.gfx.pos.y = (altOffsetActs[m.action] and m.pos.y or m.marioObj.header.gfx.pos.y) + characterTable[currChar].offset - end + local offset = gPlayerSyncTable[m.playerIndex].offset + if offset ~= 0 and offset ~= nil then + if altOffsetActs[m.action] ~= false then + m.marioObj.header.gfx.pos.y = (altOffsetActs[m.action] and m.pos.y or m.marioObj.header.gfx.pos.y) + offset end end end @@ -560,7 +559,6 @@ end hook_event(HOOK_MARIO_UPDATE, mario_update) hook_event(HOOK_OBJECT_SET_MODEL, set_model) -hook_event(HOOK_ON_OBJECT_RENDER, on_object_render) ------------------ -- Menu Handler -- @@ -1312,4 +1310,14 @@ local function chat_command(msg) return true end -hook_chat_command("char-select", "- Opens the Character Select Menu", chat_command) \ No newline at end of file +hook_chat_command("char-select", "- Opens the Character Select Menu", chat_command) + +-------------- +-- Mod Menu -- +-------------- + +local function open_cs_menu() + menu = true +end + +hook_mod_menu_button("Open Menu", open_cs_menu) \ No newline at end of file diff --git a/mods/character-select-coop/o-api.lua b/mods/character-select-coop/o-api.lua index dfbd499c..f1af4b63 100644 --- a/mods/character-select-coop/o-api.lua +++ b/mods/character-select-coop/o-api.lua @@ -214,7 +214,7 @@ local function character_get_number_from_string(name) end ---@param m MarioState -local function character_get_voice(m) +function character_get_voice(m) return characterVoices[gPlayerSyncTable[m.playerIndex].modelId] end diff --git a/mods/character-select-coop/z-voice.lua b/mods/character-select-coop/z-voice.lua index b47c233d..c8e3faf3 100644 --- a/mods/character-select-coop/z-voice.lua +++ b/mods/character-select-coop/z-voice.lua @@ -1,132 +1,144 @@ +if incompatibleClient then return end -if incompatibleClient then return 0 end +-- rewritten custom voice system for Character Select +-- by Agent X -local voiceTimeout = false +-- will need some revising in the future, but this will do for now. local SLEEP_TALK_SNORES = 8 - -gCustomVoiceSamples = {} -gCustomVoiceStream = nil - --- localize functions to improve performance -local audio_sample_stop,audio_sample_destroy,type,math_random,audio_stream_stop,audio_stream_destroy,audio_stream_load,audio_stream_play,audio_sample_load,audio_sample_play,is_game_paused,play_character_sound = audio_sample_stop,audio_sample_destroy,type,math.random,audio_stream_stop,audio_stream_destroy,audio_stream_load,audio_stream_play,audio_sample_load,audio_sample_play,is_game_paused,play_character_sound - ---- @param m MarioState -function stop_custom_character_sound(m, sound) - local voice_sample = gCustomVoiceSamples[m.playerIndex] - if voice_sample == nil or not voice_sample.loaded or voice_sample.isStream then - return nil - end - - audio_sample_stop(voice_sample) - if voice_sample.file.relativePath:match('^.+/(.+)$') == sound then - return voice_sample - end - audio_sample_destroy(voice_sample) - gCustomVoiceSamples[m.playerIndex] = nil -- prevent this from pointing to another sample or possibly garbage data - - return nil -end - ---- @param m MarioState -function play_custom_character_sound(m, voice) - if voiceTimeout then return 0 end - local sound - if type(voice) == "table" then - sound = voice[math_random(#voice)] - else - sound = voice - end - if sound == nil then return 0 end - - --Get current sample and stop it - local voice_sample = stop_custom_character_sound(m, sound) - - if type(sound) ~= "string" then - return sound - end - - if (m.area == nil or m.area.camera == nil) and m.playerIndex == 0 then - if gCustomVoiceStream ~= nil then - audio_stream_stop(gCustomVoiceStream) - audio_stream_destroy(gCustomVoiceStream) - end - gCustomVoiceStream = audio_stream_load(sound) - audio_stream_play(gCustomVoiceStream, true, 1) - else - if voice_sample == nil then - voice_sample = audio_sample_load(sound) - local lagTimer = 0 - repeat - lagTimer = lagTimer + 1 - if lagTimer > 500 then - voiceTimeout = true - if optionTable[optionTableRef.notification].toggle == 1 then - djui_chat_message_create("\\#FFAAAA\\Note: Custom Character Voices are unavalible due to\ninability to load audio, This is most likely because\nyour client does not support custom audio functionality.") - elseif optionTable[optionTableRef.notification].toggle == 2 then - djui_popup_create('Character Select:\nCustom Character Voices\nare unavalible due to\ninability to load audio!', 4) - end - break - end - until voice_sample.loaded - end - audio_sample_play(voice_sample, m.pos, 1) - gCustomVoiceSamples[m.playerIndex] = voice_sample - end - return 0 -end - ---- @param m MarioState -local function custom_character_sound(m, characterSound) - if is_game_paused() or voiceTimeout or optionTable[optionTableRef.localVoices].toggle == 0 then return 0 end - if characterSound == CHAR_SOUND_SNORING3 then return 0 end - if characterSound == CHAR_SOUND_HAHA and m.hurtCounter > 0 then return 0 end - - local voice = _G.charSelect.character_get_voice(m)[characterSound] - if voice ~= nil then - return play_custom_character_sound(m, voice) - end - return 0 -end - local STARTING_SNORE = 46 local SLEEP_TALK_START = STARTING_SNORE + 49 local SLEEP_TALK_END = SLEEP_TALK_START + SLEEP_TALK_SNORES +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]] + +--- @param m MarioState +--- @param sound CharacterSound +local function custom_character_sound(m, sound) + if optionTable[optionTableRef.localVoices].toggle == 0 then return NO_SOUND end + + -- get the voice table + local voiceTable = character_get_voice(m) + -- load samples that haven't been loaded + for voice, name in pairs(voiceTable) do + if type(voiceTable[voice]) == "string" then + voiceTable[voice] = audio_sample_load(name) + end + end + + -- get the sample to play + local voice = voiceTable[sound] + if voice == nil then return NO_SOUND end + local sample = voice + -- if there's no pointer then it must be a sound clip table + if voice._pointer == nil then + -- run through each sample and load in any samples that haven't been loaded + for i, name in pairs(voice) do + if type(voice[i]) == "string" then + voice[i] = audio_sample_load(name) + end + end + -- choose a random sample + sample = voice[math.random(#voice)] + end + + -- play the sample + -- audio_sample_stop(sample) -- doesn't seem to do anything? + if sound == CHAR_SOUND_SNORING1 or sound == CHAR_SOUND_SNORING2 or sound == CHAR_SOUND_SNORING3 then + audio_sample_play(sample, m.pos, 0.5) + else + audio_sample_play(sample, m.pos, 1.0) + end + return NO_SOUND +end + --- @param m MarioState local function custom_character_snore(m) - if is_game_paused() or voiceTimeout or optionTable[optionTableRef.localVoices].toggle == 0 then return end - - local SNORE3_TABLE = _G.charSelect.character_get_voice(m)[CHAR_SOUND_SNORING3] + if is_game_paused() or optionTable[optionTableRef.localVoices].toggle == 0 then return end if m.action ~= ACT_SLEEPING then - if m.isSnoring > 0 then - stop_custom_character_sound(m) - end + -- if m.isSnoring ~= 0 then + -- stop_custom_character_sound(m, CHAR_SOUND_SNORING1) + -- stop_custom_character_sound(m, CHAR_SOUND_SNORING2) + -- stop_custom_character_sound(m, CHAR_SOUND_SNORING3) + -- end return - - elseif not (m.actionState == 2 and (m.flags & MARIO_MARIO_SOUND_PLAYED) ~= 0) then + elseif m.actionState ~= 2 or (m.flags & MARIO_MARIO_SOUND_PLAYED) == 0 then return end - local animFrame = m.marioObj.header.gfx.animInfo.animFrame + local voice = character_get_voice(m) + local snoreTable = voice[CHAR_SOUND_SNORING3] + -- for some reason CS seemed to originally expect snoring to all be under SNORING3 for some reason??? + -- if there's a pointer then it can't be a sound clip table + 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 - if SNORE3_TABLE ~= nil and #SNORE3_TABLE >= 2 then + 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 - play_custom_character_sound(m, SNORE3_TABLE[2]) + play_custom_character_sound(m, snoreTable[2]) elseif animFrame == 25 then - if #SNORE3_TABLE >= 3 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_custom_character_sound(m, SNORE3_TABLE[3]) + play_character_sound(m, CHAR_SOUND_SNORING3) elseif m.actionTimer < SLEEP_TALK_START then - play_custom_character_sound(m, SNORE3_TABLE[1]) + play_character_sound(m, CHAR_SOUND_SNORING1) end else - play_custom_character_sound(m, SNORE3_TABLE[1]) + play_character_sound(m, CHAR_SOUND_SNORING1) end end elseif animFrame == 2 then @@ -137,24 +149,16 @@ local function custom_character_snore(m) end end -function stop_all_character_sounds() - if gCustomVoiceStream then - audio_stream_stop(gCustomVoiceStream) - audio_stream_destroy(gCustomVoiceStream) - gCustomVoiceStream = nil - end - for i = 0, MAX_PLAYERS-1 do - stop_custom_character_sound(gMarioStates[i]) +local function update() + if is_game_paused() then + stop_all_custom_character_sounds() end end -hook_event(HOOK_ON_WARP, stop_all_character_sounds) -hook_event(HOOK_UPDATE, function () - if is_game_paused() then - stop_all_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, -} +} \ No newline at end of file