-- I was to lazy to store actual version (like 1.2) in table local dub_version = 4 -- In case addon loaded multiple times (when bundled with character addons, for -- instance) -- -- On second thought, maybe bundling such addons with characters is a bad idea, -- if you don't want dependency hell... -- -- On third thought, loading this lua before all addons that may contain older -- dub version will surely solve these problems :D if dub_loaded then -- Previous 2 versions used boolean to indicate that dub is loaded, so -- i'll replace it with number so lua don't complain about "attempt to -- compare boolean with number" -- -- ... And yes, i know that 'if bool == true' is stupid, but in this -- specific case that can be a number, so thats same as checking -- 'if type(dub_loaded) == "boolean"' if dub_loaded == true then rawset(_G, "dub_loaded", 1) end -- Not sure if i/someone else will update this addon that much that version -- missmatch would actually lead to problems, but its better to warn about -- that than just silently ignore if dub_loaded < dub_version then error("Older version of KL_CharDub loaded, this may lead to problems") end return end rawset(_G, "dub_loaded", dub_version) local dub = {} local skinsounds = { SKSKWIN, SKSKLOSE, SKSKPAN1, SKSKPAN2, SKSKATK1, SKSKATK2, SKSKBST1, SKSKBST2, SKSKSLOW, SKSKHITM, SKSKPOWR, } local config = "dub.cfg" local config_loaded = false local config_tosave = false local dub_enabled = CV_RegisterVar({ name = "dub_enabled", defaultvalue = "On", possiblevalue = CV_OnOff, }) local dub_soundoffhack = CV_RegisterVar({ name = "dub_soundoffhack", defaultvalue = "On", possiblevalue = CV_OnOff, }) local function loadConfig() if config_loaded or not consoleplayer then return end local file = io.open(config, "r") -- No config :( if not file then config_loaded = true return end for line in file:lines() do COM_BufInsertText(consoleplayer, line) end config_loaded = true file:close() end local function saveConfig() if not consoleplayer then return end config_tosave = false local file = io.open(config, "w") if not file then return end file:write("dub_enabled "..dub_enabled.string..'\n') file:write("dub_soundoffhack "..dub_soundoffhack.string..'\n') if consoleplayer.dub_choice ~= nil then for skin, choice in pairs(consoleplayer.dub_choice) do file:write("dub "..skin.." "..choice..'\n') end end file:close() end COM_AddCommand("dub", function(player, skin, choice) if player.dub_choice == nil then player.dub_choice = {} end if skin == nil then CONS_Printf(player, "Usage: \129dub\128 <\130skin\128> [\131dub\128]") CONS_Printf(player, "Check \129dub_list\128 for all avaible dubs") elseif choice == nil then if dub[skin] == nil then CONS_Printf(player, "\134This skin does not have any custom dub") return end local skin_dubs = {"default"} for dubname, _ in pairs(dub[skin]) do table.insert(skin_dubs, dubname) end CONS_Printf(player, "Avaible dubs for skin \130"..skin.."\128: \131"..table.concat(skin_dubs, ", ")) else if dub[skin] == nil then CONS_Printf(player, "\134This skin does not have any custom dub") return end if choice == "default" then player.dub_choice[skin] = nil CONS_Printf(player, "Custom dub for skin \130"..skin.." \133disabled") config_tosave = config_loaded -- To not cause config to be saved immideately after loading return end if dub[skin][choice] == nil then CONS_Printf(player, "Dub \131"..choice.." \133does not exist\128 for skin \130"..skin) return end player.dub_choice[skin] = choice CONS_Printf(player, "Set dub \131"..choice.."\128 for skin \130"..skin) config_tosave = config_loaded end end) COM_AddCommand("dub_list", function(player) local dubs = {"Skins with custom dubs:"} for skin, _ in pairs(dub) do local skin_dubs = {} for dubname, _ in pairs(dub[skin]) do table.insert(skin_dubs, dubname) end table.insert(dubs, "\130"..skin.."\128: \131"..table.concat(skin_dubs, ", ")) end if #dubs == 1 then CONS_Printf(player, "\134There are no dubs yet...") else CONS_Printf(player, table.concat(dubs, "\n")) end end) local function DUB_GetSkinSound(player, skinsound) if player.mo == nil then return end local psounds = skins[player.mo.skin].soundsid if not dub_enabled.value or player.dub_choice == nil or player.dub_choice[player.mo.skin] == nil then return psounds[skinsound] end local pdub = dub[player.mo.skin][player.dub_choice[player.mo.skin]] if pdub == nil then return psounds[skinsound] end return pdub[skinsound] or psounds[skinsound] end local function DUB_GetWinSound(player) return DUB_GetSkinSound(player, SKSKWIN) end local function DUB_GetLoseSound(player) return DUB_GetSkinSound(player, SKSKLOSE) end local function DUB_GetBoostSound(player) local skinsound = SKSKBST1 + P_RandomKey(2) return DUB_GetSkinSound(player, skinsound) end local function DUB_GetHurtSound(player) local skinsound = SKSKPAN1 + P_RandomKey(2) return DUB_GetSkinSound(player, skinsound) end local function DUB_GetAttackSound(player) local skinsound = SKSKATK1 + P_RandomKey(2) return DUB_GetSkinSound(player, skinsound) end local function DUB_GetHitEmSound(player) return DUB_GetSkinSound(player, SKSKHITM) end local function DUB_GetGloatSound(player) return DUB_GetSkinSound(player, SKSKPOWR) end local function DUB_RegisterDub(skin, dubname, dubvoices) if dubname == "default" then error("dub name 'default' is reserved") end if dub[skin] == nil then dub[skin] = {} end dub[skin][dubname] = {} for soundid, soundname in pairs(dubvoices) do -- Do not freeslot sounds if they already are dub[skin][dubname][soundid] = _G[soundname] or freeslot(soundname) end end rawset(_G, "DUB_GetSkinSound", DUB_GetSkinSound) rawset(_G, "DUB_GetWinSound", DUB_GetWinSound) rawset(_G, "DUB_GetLoseSound", DUB_GetLoseSound) rawset(_G, "DUB_GetBoostSound", DUB_GetBoostSound) rawset(_G, "DUB_GetHurtSound", DUB_GetHurtSound) rawset(_G, "DUB_GetAttackSound", DUB_GetAttackSound) rawset(_G, "DUB_GetGloatSound", DUB_GetGloatSound) rawset(_G, "DUB_GetHitEmSound", DUB_GetHitEmSound) rawset(_G, "DUB_RegisterDub", DUB_RegisterDub) -- Fuck you CV_CALL local saved_dub_enabled = dub_enabled.value local saved_dub_soundoffhack = dub_soundoffhack.value addHook("ThinkFrame", function() if not config_loaded then loadConfig() end if saved_dub_enabled ~= dub_enabled.value then config_tosave = true end if saved_dub_soundoffhack ~= dub_soundoffhack.value then config_tosave = true end saved_dub_enabled = dub_enabled.value saved_dub_soundoffhack = dub_soundoffhack.value if config_tosave then saveConfig() end end) addHook("ThinkFrame", function() if not dub_enabled.value then return end for player in players.iterate do if player.mo ~= nil and player.mo.valid and player.dub_choice ~= nil and player.dub_choice[player.mo.skin] ~= nil then local pdub = dub[player.mo.skin][player.dub_choice[player.mo.skin]] local psounds = skins[player.mo.skin].soundsid for _, sound in ipairs(skinsounds) do if pdub[sound] ~= nil then if S_SoundPlaying(player.mo, psounds[sound]) then S_StopSoundByID(player.mo, psounds[sound]) if sound ~= SKSKPOWR or not S_SoundPlaying(player.mo, pdub[sound]) then S_StartSound(player.mo, pdub[sound]) end end end end if dub_soundoffhack.value then if pdub[SKSKWIN] ~= nil and S_IdPlaying(psounds[SKSKWIN]) then -- This is disgusting. I hate srb2[kart] lua api. -- (this is what i have to do to stop winning sound from playing) -- Why couldn't they just add S_StopSoundByNum? WHYYYYYYY COM_BufInsertText(consoleplayer, "sounds Off; sounds On") S_StartSound(nil, pdub[SKSKWIN], consoleplayer) end if pdub[SKSKLOSE] ~= nil and S_IdPlaying(psounds[SKSKLOSE]) then COM_BufInsertText(consoleplayer, "sounds Off; sounds On") S_StartSound(nil, pdub[SKSKLOSE], consoleplayer) end end end end end)