• 🏆 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!

Player-specific music

Status
Not open for further replies.
Level 7
Joined
May 13, 2011
Messages
310
Is it possible to have different music play for different players, using JASS? Basically, what I want to do is play different imported music for each player, depending on which race they are.

I already know that I can play music using PlayMusicBJ, SetMapMusicBJ, and so forth, but is there a function that makes it play for only one player? If there isn't, is there a sort of workaround?

I know that in my specific case it would be possible to simply replace the default music for each race, but since I'm using MIDI music it must be played through JASS. I really hope this is possible, otherwise I'll have a massive problem on my hands... :ogre_frown:
 
Level 7
Joined
May 13, 2011
Messages
310
JASS:
if GetLocalPlayer()==SomePlayer then
    PlayMusic(somemusic)
endif

Yes, I understand that, but wouldn't that play somemusic for all players? What I want is for each player to have different music, something like:
JASS:
if GetPlayerRace(Player(0)) == RACE_HUMAN then
    SetMapMusicBJ("HumanMusic.mp3", Player(0))
endif

However, I'm not very familiar with GetLocalPlayer, so it's possible that you have solved my problem. If that's so, could you explain?
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
It will only play somemusic for SomePlayer, because GetLocalPlayer works like this:
It browses through all warcraft engines and if someplayer is playing on that engine, then it will play the sound (on that ENGINE, so the others will never notice and their engine will never even notice anything happened).

Use with care, as creating anything inside "GetLocalPlayer" (also showing/hiding units or... basically a lot of stuff) desyncs the game.
To be a bit more specific: everything that creates an ID will desync when you create it locally (creating locally means within the GetLocalPlayer()).
This is because warcraft has some kind of ID pool, where it grabs ID's from every time a new object (such as a unit, or a timer) is created. If the ID pool is different for other engines, then it will desync.
But also when you hide/show a unit locally (because on one engine it can be targetted, while on the other it cannot).
Try to limit the use of GetLocalPlayer() until you've learned more about it, but using it like Magtheridon said causes no problems.

Further reading:
By DSG
By myself
 
Level 7
Joined
May 13, 2011
Messages
310
Oh OK, I get it now, thanks for that. I'll just use that then. It's just that since the actual function of PlayMusic is simply within an if statement, it didn't really appear separate from other players. I think I'm thinking too OOP-like...

By the way, just checking my understanding: I should only use GetLocalPlayer() for function which only that player should notice, right? Like playing music, sending a message, giving a dialog box, etc. Not stuff like adding resources, units, or anything that other players should know about.

Once again, thanks both you guys, it really helped me out.
 
JASS:
function PlayMusicForPlayers takes nothing returns nothing
    local integer i = 0
    local player p

    loop
        exitwhen i > 11
        set p = Player(i)
        if GetPlayerRace(p) == RACE_HUMAN then
            if GetLocalPlayer()==p then
                call PlayMusic(yourhumanmusic)
            endif
        elseif GetPlayerRace(p) == RACE_UNDEAD then
            if GetLocalPlayer()==p then
                call PlayMusic(yourundeadmusic)
            endif
        elseif GetPlayerRace(p) == RACE_NIGHTELF then
            if GetLocalPlayer()==p then
                call PlayMusic(yournightelfmusic)
            endif
        else
            if GetLocalPlayer()==p then
                call PlayMusic(yourorcmusic)
            endif
        endif
        set i = i + 1
    endloop
    set p = null
endfunction

This function loops through all the players to check their races. If their race is Human,
it would play the human themed music ONLY for that player.

That's how GetLocalPlayer() works :)


EDIT: I made it more efficient ^^
 
Level 7
Joined
May 13, 2011
Messages
310
Sweet, thanks for that. Especially the loop, I haven't done loops in JASS yet so that helps a lot.

Just one question though... I have multiple music tracks for my races, and I want to play one of them randomly, still using this race-specific method. Would I be able to use SetMapMusicRandomBJ() instead of PlayMusic(), or wouldn't that work?
 
Just create 4 arrays:
JASS:
string array HumanMusic
string array UndeadMusic
string array NightElfMusic
string array OrcMusic

Then you should set them to all the music files you imported.

Inside the system I gave you, you would call PlayMusic like this:
call PlayMusic(HumanMusic[GetRandomInt(1,NumberOfMusicFilesForHumanRace)])
call PlayMusic(UndeadMusic[GetRandomInt(1,NumberOfMusicFilesForUndeadRace)])
call PlayMusic(OrcMusic[GetRandomInt(1,NumberOfMusicFilesForOrcRace)])
call PlayMusic(NightElfMusic[GetRandomInt(1,NumberOfMusicFilesForNightElfRace)])
 
Level 7
Joined
May 13, 2011
Messages
310
Ooh, arrays. Thanks mate, I'll definitely use that.

By the way, you needn't waste time writing stuff for Undead and Night Elves, I'm only gonna have good ol' Orcs and Humans.
 
Level 7
Joined
May 13, 2011
Messages
310
Well, your suggestion works, but there's one thing. The music starts as soon as the map has loaded, before you start playing. Then, when you start playing (i.e. press any key) it starts all over again. This isn't exactly what I want, and I suspect that if I use SetMapMusicRandomBJ instead of PlayMusic, it won't happen.

I could, of course, modify my trigger to run only once the game has started, but I'm not willing to try that unless it's absolutely necessary. So once again, I ask: can I use SetMapMusicRandomBJ along with GetLocalPlayer()?
 
Level 7
Joined
May 13, 2011
Messages
310
Yep, I know that, but what I'm wondering is if it'll work together with GetLocalPlayer(), like PlayMusic(). For example, I want to know if I can substitute this code:
JASS:
local integer i = 0
local player p

loop
    exitwhen i > 11
    set p = Player(i)
    if GetPlayerRace(p) == RACE_HUMAN then
        if GetLocalPlayer()==p then
            call PlayMusic("hMusic.mp3")
    elseif GetPlayerRace(p) == RACE_ORC then
        if GetLocalPlayer()==p then
            call PlayMusic("oMusic.mp3")
        endif
    endif
    set i = i + 1
endloop
set p = null

With this code:
JASS:
local integer i = 0
local player p

loop
    exitwhen i > 11
    set p = Player(i)
    if GetPlayerRace(p) == RACE_HUMAN then
        if GetLocalPlayer()==p then
            call SetMapMusicRandomBJ("hMusic.mp3")
    elseif GetPlayerRace(p) == RACE_ORC then
        if GetLocalPlayer()==p then
            call SetMapMusicRandomBJ("oMusic.mp3")
        endif
    endif
    set i = i + 1
endloop
set p = null

I want to know if SetMapMusicRandomBJ() can still work for only one player using GetLocalPlayer(). The reason for this is in my previous post.
 
Sorry I am kinda sick at the moment and arn't thinking to focused..... and also don't use jass. So I'll just explain it to you... just start playing the music at map initialization and then stop all the music playing instantly whiles using GetLocalPlayer . After that use the event(however you use it in jass) elapsed time of 0.00 then use the code
call
SetMapMusicRandomBJ( "music" )
as that will play a random song that is set at map initialization but I think you will still need to use GetLocalPlayer for that(don't know if it'll desinc without it).

 
Level 7
Joined
May 13, 2011
Messages
310
You can do anything you want in a GetLocalPlayer() if/endif block as long as it involves:
-Music
-Weather
-Messages
-Cameras
-Sounds
-Floating Texts
-Quests (in some cases)
-Trackables (maybe)
-Special Effects
-Images
-Multiboards
-Leaderboards

Thanks for that Magtheridon, that's all I wanted to know. I was gonna test it out anyway but I just thought to ask. +rep (Sorry I can't yet, says I need to spread around)

Deathchef, I still don't exactly get your explanation though. Maybe it's because you don't use JASS, but anyway Magtheridon sorted it out for me. +rep for trying to help though, appreciate it.
 
Last edited:
Status
Not open for further replies.
Top