• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] Sound for Local Player

Status
Not open for further replies.
Level 6
Joined
Jul 2, 2008
Messages
156
I did some searching around for how to play a sound for a single player, but I'm going to need to clarity on how to do that.

My situation: I'm converting GUI triggers into JASS, and I used to have a QuestMessageBJ to inform the player of stuff. I quickly changed that into a DisplayTimedTextToPlayer, but I need to know how to make and play the sound for the local player.

How should I go about creating the sound?
I'm not really sure what to put in the last parameter for the sound, or if I should be making the sound inside the function.

I searched around on the forum, and people were saying something about using GetLocalPlayer() is a bad idea.

My code:

JASS:
function Trig_Corrupt_Conversion_Towers_Actions takes nothing returns nothing
    local unit u= GetDyingUnit()
    local unit t
    local player p= GetOwningPlayer(GetKillingUnit())
    local sound s= CreateSound(gg_snd_ItemReceived, false, false, false, 10, 10, null)
    
    if ( Trig_Corrupt_Conversion_Towers_Func002C() ) then
        set t= CreateUnit(p, 'hatw', GetUnitX(u), GetUnitY(u), GetUnitFacing(u))
        call SetUnitRallyPoint( t, GetRectCenter(GetTowerRally(t)) )
        call DisplayTimedTextToPlayer(p, 0, 0, 4, "Tower Corrupted!")
        call StartSound(s)
    else
    endif
    if ( Trig_Corrupt_Conversion_Towers_Func003C() ) then
        set t= CreateUnit(p, 'hatw', GetUnitX(u), GetUnitY(u), GetUnitFacing(u))
        call SetUnitRallyPoint( t, GetRectCenter(GetTowerRally(t)) )
        call DisplayTimedTextToPlayer(p, 0, 0, 4, "Tower Cleansed!")
        call StartSound(s)
    else
    endif
endfunction

Thanks in advance!
 
Level 17
Joined
Sep 8, 2007
Messages
994
GetLocalPlayer will not be dangerous in this case, sounds won't cause desyncs.

First of all, you have to know what GetLocalPlayer actually does.
If you e.g. have a multiboard and want to change a thing, the command will proceed for all players, so basically all computers run this action. If you use GetLocalPlayer(), it will return the current player. So, if you now use that command inside a condition, you will be able to change things only for one player.
Example:
JASS:
function Example takes nothing returns nothing
   local multiboard mb = CreateMultiboard()
   if GetLocalPlayer() == Player(0) then
       call MultiboardShow(mb) //In this case, the multiboard will only be shown for player 0 (= red)
   endif
endfunction

Now, a desync is this ...

JASS:
globals
     integer Example = 1
endglobals

function Desync takes nothing returns nothing
    if GetLocalPlayer() == Player(0) then
       set Example = 5 //Desync!!!
    endif
endfunction

here you only change the global variable for player 0 (= red), thus you cause the other players to have another value for this. That is a desync and causes a crash.
 
Level 6
Joined
Jul 2, 2008
Messages
156
One more thing:
I keep getting an error with line
JASS:
local sound s= CreateSound(gg_snd_ItemReceived, false, false, false, 10, 10, null)
Cannot convert from string.
I know its gg_snd_ItemReceived, but I don't know what else to put there.

EDIT: Nevermind, did some searching and found I needed quotes and sound path.
 
Level 12
Joined
Jul 27, 2008
Messages
1,181
Do this:
JASS:
    local string soundPath = ""
    local sound soundToPlay
    
    if GetLocalPlayer() == YOUR_PLAYER then
        set soundPath = "war3mapImported\\sound.mp3"
    endif
    
    set soundToPlay = CreateSound(gg_snd_ItemReceived, false, false, false, 10, 10, null)
With your params though.
 
Level 8
Joined
Oct 3, 2008
Messages
367
On a slightly related note, this does not desync. It does not crash. Nothing wrong with it, really.
JASS:
globals
     integer Example = 1
endglobals

function NoDesync takes nothing returns nothing
    if GetLocalPlayer() == Player(0) then
       set Example = 5
    endif
endfunction

This does not desync. It does not crash. Nothing wrong with it, really.
JASS:
if GetLocalPlayer() == myPlayer then
    call StartSound(gg_snd_MySound)
endif
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
Reaper's method is the method that causes NO DESYNC... any other methods would cause desyncs...

but he has a little mistake, here's the good version:
JASS:
    local string soundPath = ""
    local sound soundToPlay

    if GetLocalPlayer() == YOUR_PLAYER then
        set soundPath = "war3mapImported\\sound.mp3"
    endif

    set soundToPlay = CreateSound(soundPath, false, false, false, 10, 10, null)
 
Level 8
Joined
Oct 3, 2008
Messages
367
JASS:
if GetLocalPlayer() == YOUR_PLAYER then
    set soundPath = "war3mapImported\\sound.mp3"
endif
This has a chance of locally modifying the string table, and thus possibly causing a desync.

StartSound causes no issues when called locally.
 
Level 13
Joined
Mar 16, 2008
Messages
941
JASS:
if GetLocalPlayer() == YOUR_PLAYER then
    set soundPath = "war3mapImported\\sound.mp3"
endif
This has a chance of locally modifying the string table, and thus possibly causing a desync.

StartSound causes no issues when called locally.

Prove it please, because many people mentioned that the string table problems happen the other way round :O
 
Level 11
Joined
Feb 22, 2006
Messages
752
JASS:
function StartSoundForPlayerBJ takes player whichPlayer, sound soundHandle returns nothing
    if (whichPlayer == GetLocalPlayer()) then
        call StartSound(soundHandle)
    endif
endfunction

This BJ solves your problem very nicely. So just use it.

JASS:
local string soundPath = ""
    local sound soundToPlay
    if GetLocalPlayer() == YOUR_PLAYER then
        set soundPath = "war3mapImported\\sound.mp3"
    endif
    set soundToPlay = CreateSound(soundPath, false, false, false, 10, 10, null)

This leaks a bunch of sound handles if done every time (and if you clean up the leaks it's still creating/destroying a lot of handles unecessarily).
 
Level 8
Joined
Oct 3, 2008
Messages
367
>Why do people create special effects locally with that method then?

They shouldn't. The proper method is to set the model to blank locally. Otherwise, you risk desyncs.

>This BJ solves your problem very nicely. So just use it.

Indeed it does.

>Prove it please, because many people mentioned that the string table problems happen the other way round :O

...? Other way around?
 
Level 8
Joined
Oct 3, 2008
Messages
367
Setting a string to "" locally has no chance of string table change, because "" is in the string table be default.

However, setting a string to a model path locally has a chance of locally reserving a spot in the string table for that string. Desyncs or other weird stuff ensue.
 
Status
Not open for further replies.
Top