• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece!🔗 Click here to enter!

[JASS] Sounds won't preload

Status
Not open for further replies.
Level 8
Joined
Jan 28, 2016
Messages
486
As the title says, I can't get sound files to preload properly in a spell request I created (A unique portal spell). The idea is to preload the sounds so that when the ability is first cast, the sounds run as they should. However this isn't the case; the sounds don't play the first time the spell is cast but thereafter, the sounds work as they should.

Initially I had the code set up as per the snippet found in the Small Code Snippets thread but that didn't work, and so I did some searching but all I found was this: How do I create sound?. The debug messages do print out the correct info though.

If anyone could help me out in anyway possible, I would greatly appreciate it.

JASS:
function Preload_Jass_Sounds takes nothing returns nothing
    local integer i = 1
    local sound audio
    local string array filename
    set filename[1] = "Sound\\Ambient\\DoodadEffects\\ShimmeringPortalBirth.wav"
    set filename[2] = "Sound\\Ambient\\DoodadEffects\\ShimmeringPortalDeath.wav"
    set filename[3] = "Abilities\\Spells\\Undead\\DarkSummoning\\DarkSummoningTarget1.wav"
    loop
        exitwhen i == 4
        set audio = CreateSound( filename[i], false, true, true, 10, 10, "DefaultEAXON" )
        call SetSoundChannel( audio, 0 )
        call SetSoundDistances( audio, 10.00, 100.00 )
        call SetSoundDistanceCutoff( audio, 100.00)
        call SetSoundDuration( audio, GetSoundFileDuration(filename[i]) )

        call BJDebugMsg(I2S(GetSoundFileDuration(filename[i])))

        call SetSoundVolume( audio, 1 )
        call SetSoundConeAngles( audio, 0.0, 0.0, 1 )
        call SetSoundConeOrientation( audio, 0.0, 0.0, 0.0 )
        call SetSoundPitch( audio, 1.0 )
        call StartSound(audio)
        call KillSoundWhenDone(audio)

        call BJDebugMsg(filename[i])

        set audio = null
        set i = i + 1
    endloop
endfunction

//===========================================================================
function InitTrig_Demonic_Portal_Sounds takes nothing returns nothing
    local trigger trig = CreateTrigger()
    call TriggerRegisterTimerEvent( trig, 1.00, false )
    call TriggerAddAction( trig, function Preload_Jass_Sounds )
    set trig = null
endfunction

The ability:
DEMONIC PORTAL
"Create a link from the Twisting Nether, allowing a random solider of the Burning Legion to travel through it once every 10 minutes. Lasts 30 minutes."

  • Demonic Portal Setup
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Spell Configurables --------
      • Set DPBoolDelayPortal = True
      • Set DPPortalDelayTime = 7.50
      • Set DPSummonsInterval = 10.00
      • -------- Summon Unit Types --------
      • Set DPSummons[1] = Bloodfiend
      • Set DPSummons[2] = Fel Stalker
      • Set DPSummons[3] = Overlord
      • Set DPSummons[4] = Eredar Diabolist
      • Set DPSummons[5] = Fel Ravager
      • Set DPSummons[6] = Infernal
      • Set DPSummons[7] = Doom Guard
      • Set DPSummons[8] = Eredar Warlock
      • Set DPSummons[9] = Archimonde
      • Set DPSummonsMax = 9
      • -------- Summon Chance --------
      • Set DPChance[1] = 100
      • Set DPChance[2] = 75
      • Set DPChance[3] = 55
      • Set DPChance[4] = 40
      • Set DPChance[5] = 25
      • Set DPChance[6] = 15
      • Set DPChance[7] = 10
      • Set DPChance[8] = 5
      • Set DPChance[9] = 1

JASS:
//===========================================================================
//==========Jass Configurables===============================================
//===========================================================================

//Add the raw code of your Portal ability here.
constant function PortalAbilityId takes nothing returns integer
    return 'A000'
endfunction

//Add the Portal unit's raw code here.
constant function PortalUnitType takes nothing returns integer
    return 'hprt'
endfunction

//Special effect model you want to be played when a unit is summoned.
constant function PortalSummonSFX takes nothing returns string
    return "Abilities\\Spells\\Other\\HowlOfTerror\\HowlCaster.mdl"
endfunction



//===========================================================================
//==========Summoning System=================================================
//===========================================================================

function Demonic_Portal_Jass_End takes timer watch returns nothing
    call PauseTimer(watch)
    call DestroyTimer(watch)
    call FlushChildHashtable( udg_DPHash, GetHandleId(watch) )
endfunction

function Demonic_Portal_Jass_Sound takes string filename, unit portal returns nothing
    local sound audio = CreateSound( filename, false, true, true, 10, 10, "DefaultEAXON")
    call SetSoundChannel( audio, 0 )
    call SetSoundDistances( audio, 500.00, 5000.00 )
    call SetSoundDistanceCutoff( audio, 2500.00)
    call SetSoundDuration( audio, GetSoundFileDuration(filename) )
    call SetSoundVolume( audio, 127 )
    call SetSoundConeAngles( audio, 0.0, 0.0, 127 )
    call SetSoundConeOrientation( audio, 0.0, 0.0, 0.0 )
    call SetSoundPitch( audio, 1.0 )
    call AttachSoundToUnit( audio, portal )
    call StartSound( audio )
    call KillSoundWhenDone( audio )
    set audio = null
endfunction

function Demonic_Portal_Jass_Timer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer tick = LoadInteger( udg_DPHash, GetHandleId(t), 0 ) + 1
    local unit portal = LoadUnitHandle( udg_DPHash, GetHandleId(t), 1 )
    local real angle = LoadReal( udg_DPHash, GetHandleId(portal), 1 ) - 3.14159
    local real x = GetUnitX(portal)
    local real y = GetUnitY(portal)
    local integer rand
    local integer temp = udg_DPSummonsMax
    local boolean bool = false
    local boolean rare = LoadBoolean( udg_DPHash, GetHandleId(portal), 3 )
    local unit summon
    if rare then
        set rand = GetRandomInt(2, 100)
    else
        set rand = GetRandomInt(1, 100)
    endif
    loop
        exitwhen temp < 1
        if rand <= udg_DPChance[temp] and bool == false then
            if rand == 1 then
                call SaveBoolean( udg_DPHash, GetHandleId(portal), 3, true )
            endif
            set summon = CreateUnit( GetOwningPlayer(portal), udg_DPSummons[temp], x+64*Cos(angle), y+64*Sin(angle), (angle*180/3.14159) )
            call DestroyEffect( AddSpecialEffect( PortalSummonSFX(), x, y ) )
            call IssuePointOrder( summon, "move", x+300*Cos(angle), y+300*Sin(angle) )
            call Demonic_Portal_Jass_Sound("Abilities\\Spells\\Undead\\DarkSummoning\\DarkSummoningTarget1.wav",portal)
            set bool = true
            set summon = null
        endif
        set temp = temp - 1
    endloop
    if tick == 3 then
        call KillUnit(portal)
    else
        call SaveInteger( udg_DPHash, GetHandleId(t), 0, tick )
    endif
    set t = null
    set portal = null
endfunction

function Demonic_Portal_Jass_Delay takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local timer clock = LoadTimerHandle( udg_DPHash, GetHandleId(t), 2 )
    local unit portal = LoadUnitHandle( udg_DPHash, GetHandleId(t), 1 )
    call SetUnitInvulnerable( portal, false )
    call TimerStart( clock, udg_DPSummonsInterval, true, function Demonic_Portal_Jass_Timer )
    call SaveInteger( udg_DPHash, GetHandleId(clock), 0, 0 )                             //Saved to clock
    call SaveUnitHandle( udg_DPHash, GetHandleId(clock), 1, portal )                     //Saved to clock
    call SaveTimerHandle( udg_DPHash, GetHandleId(portal), 0, clock )                    //Saved to portal
    call Demonic_Portal_Jass_End(t)
    set t = null
    set clock = null
    set portal = null
endfunction

function Demonic_Portal_Jass_Actions takes nothing returns nothing
    local real x = GetSpellTargetX()
    local real y = GetSpellTargetY()
    local real angle = Atan2( y - GetUnitY(GetTriggerUnit()), x - GetUnitX(GetTriggerUnit()) )
    local unit portal = CreateUnit( GetOwningPlayer(GetTriggerUnit()), PortalUnitType(), x, y, angle * (180/3.14159) - 180 )
    local timer watch = CreateTimer()
    local timer clock = CreateTimer()
    call SaveReal( udg_DPHash, GetHandleId(portal), 1, angle )                           //Saved to portal
    call SaveBoolean( udg_DPHash, GetHandleId(portal), 3, false )
    if udg_DPBoolDelayPortal then
        call SetUnitInvulnerable( portal, true )
        call SetUnitAnimation( portal, "birth" )

        //Sound function: Change birth sound filename here.
        call Demonic_Portal_Jass_Sound("Sound\\Ambient\\DoodadEffects\\ShimmeringPortalBirth.wav",portal)

        call TimerStart( watch, udg_DPPortalDelayTime, false, function Demonic_Portal_Jass_Delay )
        call SaveUnitHandle( udg_DPHash, GetHandleId(watch), 1, portal )                 //Saved to watch
        call SaveTimerHandle( udg_DPHash, GetHandleId(watch), 2, clock )                 //Saved to watch
    else
        call TimerStart( clock, udg_DPSummonsInterval, true, function Demonic_Portal_Jass_Timer )
        call SaveInteger( udg_DPHash, GetHandleId(clock), 0, 0 )                         //Saved to clock
        call SaveUnitHandle( udg_DPHash, GetHandleId(clock), 1, portal )                 //Saved to clock
        call SaveTimerHandle( udg_DPHash, GetHandleId(portal), 0, clock )                //Saved to portal
    endif
    set portal = null
    set watch = null
    set clock = null
endfunction

function Demonic_Portal_Jass_Conditions takes nothing returns boolean
    local unit portal = GetTriggerUnit()
    local timer t
    if GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_EFFECT and GetSpellAbilityId() == PortalAbilityId() then
        call Demonic_Portal_Jass_Actions()
    elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_DEATH and GetUnitTypeId(portal) == PortalUnitType() then
        set t = LoadTimerHandle( udg_DPHash, GetHandleId(GetTriggerUnit()), 0 )

        //Sound function: Change death sound filename here.
        call Demonic_Portal_Jass_Sound("Sound\\Ambient\\DoodadEffects\\ShimmeringPortalDeath.wav",portal)

        call Demonic_Portal_Jass_End(t)
        call FlushChildHashtable( udg_DPHash, GetHandleId(portal) )
        set t = null
    endif
    set portal = null
    return false
endfunction

//===========================================================================
//==========Init Function====================================================
//===========================================================================
function InitTrig_Demonic_Portal_Jass takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( t, Condition( function Demonic_Portal_Jass_Conditions ) )
    set t = null
endfunction
 
Last edited:
Level 8
Joined
Jan 28, 2016
Messages
486

Didn't even know this existed. Cheers!

I don't think the most operations are needed for the sounds inside the loop. Can you show the example code? (it is easy to test if it's done in a scope or library)

Next to the one jondrean linked to, you also can use [vJASS] - [Snippet] RapidSound, if you just want to play normal sounds quickly.

Initially I had it as per the snippet below, though slightly modified. Unfortunately it didn't work. I thought it may have been down to those missing operations but apparently not. Thanks for the link!
JASS:
//By Silvenon
function PreloadSoundPath takes string path returns nothing
    local sound snd = CreateSound(path, false, false, false, 10, 10, "")
    call SetSoundVolume(snd, 0)
    call StartSound(snd)
    call KillSoundWhenDone(snd)
    set snd = null
endfunction

You could also just create a dummy on map in it and order it to cast the spell once before instantly removing the spell instance and unit.

I probably should've posted the spell as well; I've posted it in the OP as well. This was one of my last resorts if I couldn't manage to find a way to fix this issue. Thanks for the reminder though. :)


P.S.: Does preloading sounds in Jass work for anyone else? May be this is a me problem.
 
Last edited:
Level 8
Joined
Jan 28, 2016
Messages
486
I think I'm out of my league when it comes to sounds... :/


Again, show us test code, too. We need to see all. Yes iirc it worked for me.

I don't quite understand what you mean by test code. I've posted everything related to my problem in the OP; I've got nothing else to show. There's also the map in the first link I provided which has a map-specific init trigger but it has no relation to the ability code.

Where do you actually instruct the game to preload the sound? Surely it should require some use of the preload natives?

I don't think this is the answer you're looking for but the trigger is run one second into the game. I'm not familiar with these preload natives you speak of. Are they necessary for sounds to be loaded?
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
I don't think this is the answer you're looking for but the trigger is run one second into the game.
Just because you tell the game to play the sound 1 second into the game does not necessarily mean that it will or that it will even bother to load the sound.

Are they necessary for sounds to be loaded?
No idea. However it might be more reliable and efficient that trying to play sounds shortly after map initialization.
 
Level 8
Joined
Jan 28, 2016
Messages
486
Alright.

I managed to get this to work by adding the preload snippet in the map header (with a couple of alterations) and running the sounds after one second had elapsed. The snippet from the header is then called whenever a sounds need to be played. Here's the Jass code and the map.

JASS:
function Demonic_Portal_Jass_Sound takes string path, unit tester, integer volume returns nothing
    local sound audio = CreateSound( path, false, false, false, 10, 10, "" )
    call AttachSoundToUnit( audio, tester )
    call SetSoundVolume( audio, volume )
    call StartSound( audio )
    call KillSoundWhenDone( audio )
    call BJDebugMsg( path )
    set audio = null
endfunction
JASS:
function Preload_Jass_Sounds takes nothing returns nothing
    local integer i = 1
    local string array filename
    set filename[1] = "Sound\\Ambient\\DoodadEffects\\ShimmeringPortalBirth.wav"
    set filename[2] = "Sound\\Ambient\\DoodadEffects\\ShimmeringPortalDeath.wav"
    set filename[3] = "Abilities\\Spells\\Undead\\DarkSummoning\\DarkSummoningTarget1.wav"
    loop
        exitwhen i == 4
        call Demonic_Portal_Jass_Sound( filename[i], null, 0 )
        set i = i + 1
    endloop
endfunction

//===========================================================================
function InitTrig_Demonic_Portal_Sounds takes nothing returns nothing
    local trigger trig = CreateTrigger()
    call TriggerRegisterTimerEvent( trig, 1.00, false )
    call TriggerAddAction( trig, function Preload_Jass_Sounds )
    set trig = null
endfunction
 

Attachments

  • [Spell] Summoning Portal.w3x
    15.2 KB · Views: 46
Status
Not open for further replies.
Top