mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-22 03:55:11 +00:00
Update Character Select related mods
This commit is contained in:
parent
8bc345d856
commit
7f40b39694
5 changed files with 159 additions and 147 deletions
|
@ -33,10 +33,10 @@ VOICETABLE_TOADETTE = {
|
||||||
[CHAR_SOUND_MAMA_MIA] = "toadette_ooh.ogg",
|
[CHAR_SOUND_MAMA_MIA] = "toadette_ooh.ogg",
|
||||||
[CHAR_SOUND_DOH] = "toadette_oof.ogg",
|
[CHAR_SOUND_DOH] = "toadette_oof.ogg",
|
||||||
[CHAR_SOUND_HRMM] = "toadette_pickup.ogg",
|
[CHAR_SOUND_HRMM] = "toadette_pickup.ogg",
|
||||||
[CHAR_SOUND_PANTING] = "toadette_pant",
|
[CHAR_SOUND_PANTING] = "toadette_pant.ogg",
|
||||||
[CHAR_SOUND_UH] = "toadette_oof_3.ogg",
|
[CHAR_SOUND_UH] = "toadette_oof2.ogg",
|
||||||
[CHAR_SOUND_UH2] = "toadette_oof_4.ogg",
|
[CHAR_SOUND_UH2] = "toadette_oof2.ogg",
|
||||||
[CHAR_SOUND_UH2_2] = "toadette_oof_5.ogg"
|
[CHAR_SOUND_UH2_2] = "toadette_oof2.ogg"
|
||||||
}
|
}
|
||||||
|
|
||||||
--MAKING VOICE CLIPS FOR ATM. USE PLACEHOLDER VOICE CLIPS!
|
--MAKING VOICE CLIPS FOR ATM. USE PLACEHOLDER VOICE CLIPS!
|
||||||
|
|
|
@ -52,7 +52,7 @@ VOICETABLE_YOSHI = {
|
||||||
[CHAR_SOUND_OOOF] = "yoshi_oof.ogg",
|
[CHAR_SOUND_OOOF] = "yoshi_oof.ogg",
|
||||||
[CHAR_SOUND_OOOF2] = "yoshi_oof2.ogg",
|
[CHAR_SOUND_OOOF2] = "yoshi_oof2.ogg",
|
||||||
[CHAR_SOUND_PANTING] = "yoshi_pant.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_SNORING1] = "yoshi_snore1.ogg",
|
||||||
[CHAR_SOUND_SNORING2] = "yoshi_snore2.ogg",
|
[CHAR_SOUND_SNORING2] = "yoshi_snore2.ogg",
|
||||||
[CHAR_SOUND_SNORING3] = {"yoshi_snore1.ogg", "yoshi_snore2.ogg", "yoshi_snore3.ogg"},
|
[CHAR_SOUND_SNORING3] = {"yoshi_snore1.ogg", "yoshi_snore2.ogg", "yoshi_snore3.ogg"},
|
||||||
|
|
|
@ -48,6 +48,8 @@ characterTable = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gPlayerSyncTable[0].offset = 0
|
||||||
|
|
||||||
characterCaps = {}
|
characterCaps = {}
|
||||||
characterCelebrationStar = {}
|
characterCelebrationStar = {}
|
||||||
characterColorPresets = {}
|
characterColorPresets = {}
|
||||||
|
@ -387,6 +389,14 @@ local menuActBlacklist = {
|
||||||
}
|
}
|
||||||
|
|
||||||
local faceAngle = 0
|
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
|
--- @param m MarioState
|
||||||
local function mario_update(m)
|
local function mario_update(m)
|
||||||
|
@ -429,6 +439,13 @@ local function mario_update(m)
|
||||||
currChar = 1
|
currChar = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
gPlayerSyncTable[0].offset = characterTable[currChar].offset
|
||||||
|
--[[
|
||||||
|
for i = 0, MAX_PLAYERS-1 do
|
||||||
|
local m = gMarioStates[i]
|
||||||
|
end
|
||||||
|
]]
|
||||||
|
|
||||||
if menuAndTransition then
|
if menuAndTransition then
|
||||||
camera_freeze()
|
camera_freeze()
|
||||||
hud_hide()
|
hud_hide()
|
||||||
|
@ -476,29 +493,11 @@ local function mario_update(m)
|
||||||
optionTable[i].optionBeingSet = false
|
optionTable[i].optionBeingSet = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
local altOffsetActs = {
|
local offset = gPlayerSyncTable[m.playerIndex].offset
|
||||||
[ACT_CROUCH_SLIDE] = true,
|
if offset ~= 0 and offset ~= nil then
|
||||||
[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
|
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
|
m.marioObj.header.gfx.pos.y = (altOffsetActs[m.action] and m.pos.y or m.marioObj.header.gfx.pos.y) + offset
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -560,7 +559,6 @@ end
|
||||||
|
|
||||||
hook_event(HOOK_MARIO_UPDATE, mario_update)
|
hook_event(HOOK_MARIO_UPDATE, mario_update)
|
||||||
hook_event(HOOK_OBJECT_SET_MODEL, set_model)
|
hook_event(HOOK_OBJECT_SET_MODEL, set_model)
|
||||||
hook_event(HOOK_ON_OBJECT_RENDER, on_object_render)
|
|
||||||
|
|
||||||
------------------
|
------------------
|
||||||
-- Menu Handler --
|
-- Menu Handler --
|
||||||
|
@ -1313,3 +1311,13 @@ local function chat_command(msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
hook_chat_command("char-select", "- Opens the Character Select Menu", chat_command)
|
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)
|
|
@ -214,7 +214,7 @@ local function character_get_number_from_string(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param m MarioState
|
---@param m MarioState
|
||||||
local function character_get_voice(m)
|
function character_get_voice(m)
|
||||||
return characterVoices[gPlayerSyncTable[m.playerIndex].modelId]
|
return characterVoices[gPlayerSyncTable[m.playerIndex].modelId]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -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
|
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 STARTING_SNORE = 46
|
||||||
local SLEEP_TALK_START = STARTING_SNORE + 49
|
local SLEEP_TALK_START = STARTING_SNORE + 49
|
||||||
local SLEEP_TALK_END = SLEEP_TALK_START + SLEEP_TALK_SNORES
|
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
|
--- @param m MarioState
|
||||||
local function custom_character_snore(m)
|
local function custom_character_snore(m)
|
||||||
if is_game_paused() or voiceTimeout or optionTable[optionTableRef.localVoices].toggle == 0 then return end
|
if is_game_paused() or optionTable[optionTableRef.localVoices].toggle == 0 then return end
|
||||||
|
|
||||||
local SNORE3_TABLE = _G.charSelect.character_get_voice(m)[CHAR_SOUND_SNORING3]
|
|
||||||
|
|
||||||
if m.action ~= ACT_SLEEPING then
|
if m.action ~= ACT_SLEEPING then
|
||||||
if m.isSnoring > 0 then
|
-- if m.isSnoring ~= 0 then
|
||||||
stop_custom_character_sound(m)
|
-- 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 m.actionState ~= 2 or (m.flags & MARIO_MARIO_SOUND_PLAYED) == 0 then
|
||||||
|
return
|
||||||
end
|
end
|
||||||
return
|
|
||||||
|
|
||||||
elseif not (m.actionState == 2 and (m.flags & MARIO_MARIO_SOUND_PLAYED) ~= 0) then
|
local voice = character_get_voice(m)
|
||||||
return
|
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
|
end
|
||||||
|
|
||||||
local animFrame = m.marioObj.header.gfx.animInfo.animFrame
|
local animFrame = m.marioObj.header.gfx.animInfo.animFrame
|
||||||
|
if snoreTable ~= nil and #snoreTable >= 2 then
|
||||||
if SNORE3_TABLE ~= nil and #SNORE3_TABLE >= 2 then
|
|
||||||
if animFrame == 2 and m.actionTimer < SLEEP_TALK_START 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
|
elseif animFrame == 25 then
|
||||||
if #SNORE3_TABLE >= 3 then
|
if #snoreTable >= 3 then
|
||||||
m.actionTimer = m.actionTimer + 1
|
m.actionTimer = m.actionTimer + 1
|
||||||
if m.actionTimer >= SLEEP_TALK_END then
|
if m.actionTimer >= SLEEP_TALK_END then
|
||||||
m.actionTimer = STARTING_SNORE
|
m.actionTimer = STARTING_SNORE
|
||||||
end
|
end
|
||||||
if m.actionTimer == SLEEP_TALK_START then
|
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
|
elseif m.actionTimer < SLEEP_TALK_START then
|
||||||
play_custom_character_sound(m, SNORE3_TABLE[1])
|
play_character_sound(m, CHAR_SOUND_SNORING1)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
play_custom_character_sound(m, SNORE3_TABLE[1])
|
play_character_sound(m, CHAR_SOUND_SNORING1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif animFrame == 2 then
|
elseif animFrame == 2 then
|
||||||
|
@ -137,22 +149,14 @@ local function custom_character_snore(m)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function stop_all_character_sounds()
|
local function update()
|
||||||
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])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
hook_event(HOOK_ON_WARP, stop_all_character_sounds)
|
|
||||||
hook_event(HOOK_UPDATE, function ()
|
|
||||||
if is_game_paused() then
|
if is_game_paused() then
|
||||||
stop_all_character_sounds()
|
stop_all_custom_character_sounds()
|
||||||
end
|
end
|
||||||
end)
|
end
|
||||||
|
|
||||||
|
hook_event(HOOK_UPDATE, update)
|
||||||
|
hook_event(HOOK_ON_LEVEL_INIT, stop_all_custom_character_sounds)
|
||||||
|
|
||||||
_G.charSelect.voice = {
|
_G.charSelect.voice = {
|
||||||
sound = custom_character_sound,
|
sound = custom_character_sound,
|
||||||
|
|
Loading…
Reference in a new issue