• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

OTClient Playing sounds at the same time - SoundChannels

Nekokan

New Member
Joined
Mar 13, 2022
Messages
8
Reaction score
1
GitHub
SirNekokan
Hey all,

I am currently struggling with this situation and I would appreciate some tips. Basically, I am using rc_sound module to play ambience music in a town, village, cave w/e. (no problem with that) but I want that now is that also specific zones like (fountains, wind zone, people talking) are separately defined and reproduced as well INSIDE the city.

lua script looks something ike this (example)

Lua:
SOUNDS_CONFIG = {
    soundChannel = SoundChannels.Music,
    checkInterval = 500,
    folder = 'music/',
    noSound = 'No sound file for this area.',
}

SOUNDS = {
        -- Define Areas:
        -- City
        {fromPos = {x=925, y=987, z=7}, toPos = {x=1091, y=1091, z=7}, priority = 1, sound="city.ogg"},
        -- City Fountain, this is defined isnide the city
        {fromPos = {x=1012, y=1036, z=7}, toPos = {x=1022, y=1047, z=7}, priority = 1, sound="fountain.ogg"},

The thing is no mountain sound is reproduced because
1. obviously I still didn't leave the city. so no new exceptions is triggered to stop the sound.
2. defined music channel is already being used.

Then, is it possible to do? I don't know if creating a new sound channel, defining the exceptions or play functions differently?
BTW: I'm using a bot alarm system to define spell, usage, walk sounds, but I think it is not applicable for that case...

Remaining code is:
Lua:
-- Sound
local rcSoundChannel
local showPosEvent
local playingSound

-- Design
soundWindow = nil
soundButton = nil

function toggle()
  if soundButton:isOn() then
    soundWindow:close()
    soundButton:setOn(false)
  else
    soundWindow:open()
    soundButton:setOn(true)
  end
end

function onMiniWindowClose()
  soundButton:setOn(false)
end

function init()
    for i = 1, #SOUNDS do
        SOUNDS[i].sound = SOUNDS_CONFIG.folder .. SOUNDS[i].sound
    end
    
    connect(g_game, { onGameStart = onGameStart,
                    onGameEnd = onGameEnd })
    
    rcSoundChannel = g_sounds.getChannel(SOUNDS_CONFIG.soundChannel)
    -- rcSoundChannel:setGain(value/COUNDS_CONFIG.volume)

    soundButton = modules.client_topmenu.addRightGameToggleButton('soundButton', tr('Sound Info') .. '', '/images/audio', toggle)
    soundButton:setOn(true)
    
    soundWindow = g_ui.loadUI('rcsound', modules.game_interface.getRightPanel())
    soundWindow:disableResize()
    soundWindow:setup()
    
    if(g_game.isOnline()) then
        onGameStart()
    end
end

function terminate()
    disconnect(g_game, { onGameStart = onGameStart,
                       onGameEnd = onGameEnd })
    onGameEnd()
    soundWindow:destroy()
    soundButton:destroy()
end

function onGameStart()
    stopSound()
    toggleSoundEvent = addEvent(toggleSound, SOUNDS_CONFIG.checkInterval)
end

function onGameEnd()
    stopSound()
    removeEvent(toggleSoundEvent)
end

function isInPos(pos, fromPos, toPos)
    return
        pos.x>=fromPos.x and
        pos.y>=fromPos.y and
        pos.z>=fromPos.z and
        pos.x<=toPos.x and
        pos.y<=toPos.y and
        pos.z<=toPos.z
end

function toggleSound()
    local player = g_game.getLocalPlayer()
    if not player then return end
    
    local pos = player:getPosition()
    local toPlay = nil

    for i = 1, #SOUNDS do
        if(isInPos(pos, SOUNDS[i].fromPos, SOUNDS[i].toPos)) then
            if(toPlay) then
                toPlay.priority = toPlay.priority or 0
                if((toPlay.sound~=SOUNDS[i].sound) and (SOUNDS[i].priority>toPlay.priority)) then
                    toPlay = SOUNDS[i]
                end
            else
                toPlay = SOUNDS[i]
            end
        end
    end

    playingSound = playingSound or {sound='', priority=0}
    
    if(toPlay~=nil and playingSound.sound~=toPlay.sound) then
        g_logger.info("RC Sounds: New sound area detected:")
        g_logger.info("  Position: {x=" .. pos.x .. ", y=" .. pos.y .. ", z=" .. pos.z .. "}")
        g_logger.info("  Music: " .. toPlay.sound)
        stopSound()
        playSound(toPlay.sound)
        playingSound = toPlay
    elseif(toPlay==nil) and (playingSound.sound~='') then
        g_logger.info("RC Sounds: New sound area detected:")
        g_logger.info("  Left music area.")
        stopSound()
    end

    toggleSoundEvent = scheduleEvent(toggleSound, SOUNDS_CONFIG.checkInterval)
end

function playSound(sound)
    rcSoundChannel:enqueue(sound, 0)
    setLabel(clearName(sound))
end

function clearName(soundName)
    local explode = string.explode(soundName, "/")
    soundName = explode[#explode]
    explode = string.explode(soundName, ".ogg")
    soundName = ''
    for i = 1, #explode-1 do
        soundName = soundName .. explode[i]
    end
    return soundName
end

function stopSound()
    setLabel(SOUNDS_CONFIG.noSound)
    rcSoundChannel:stop()
    playingSound = nil
end

function setLabel(str)
    soundWindow:recursiveGetChildById('currentSound'):getChildById('value'):setText(str)
end
 
well, I have been checking and discovered that there are more sound channels:
Lua:
SoundChannels = {
  Music = 1,
  Ambient = 2,
  Effect = 3,
  Bot = 4
}

I'm using ot v8.
prob. I should be applying the same logical function but creating and using a new variable like
ambientChannel = SoundChannels.Ambient,

Anyone has an idea about how to do it properly?
 
well, I have been checking and discovered that there are more sound channels:
Lua:
SoundChannels = {
  Music = 1,
  Ambient = 2,
  Effect = 3,
  Bot = 4
}

I'm using ot v8.
prob. I should be applying the same logical function but creating and using a new variable like


Anyone has an idea about how to do it properly?

Lua:
ambientChannel =  g_sounds.getChannel(SoundChannels.Ambient)
 
Back
Top