- Joined
- Jul 18, 2010
- Messages
- 2,354
Using Custom Assets is a great thing since the filesize limit increase, and music is no exception, but the question is: how do you play that music?
How to do it?
Open Sound Editor:
Let's close the "Sounds", if they are open. We only want "Music".
A short explanation: the music played by default is Race1.mp3,Race2.mp3,Race3.mp3,RaceX1.mp3.
A player playing Humans will hear rotational Human1, Human2, Human3 and HumanX1.
A player playing Orcs will listen to Orc1, Orc2, Orc3 and OrcX1.
And so on.
Now let's replace Human1.mp3. Right-click it with your mouse and choose "Replace Internal Sound" then a file dialog will open and you can can choose your music. Best is to pick an mp3 file. I do not know if other formats work, but mp3 works (after-all the default music is mp3).
After you have replaced Human1.mp3, Human2.mp3, Human3.mp3 and HumanX1.mp3; players playing as Human will have a full custom music list.
Replacing is easy but has its limits.
Most skilled coders will try to mimic playlists with waits or timers (both have some problems). I have tried this too, until I recently stepped across an old post from Vexorian on wc3c.net (Own music list - Wc3C.net).
Mimicking a playlist is actually unneeded; Warcraft 3 already has the ability to set music playlists or loop multiple music files.
Before I continue, the Warcraft 3 playlist has timeouts of ca. 20 to 40 seconds between songs.
And there are some problems with some specific MP3 files. I did not discover the specifics of this yet.
The important information from the post from Vexorian is:
Conclusion: playing a music list is as simple as using a string which separates songs with ";".
Example:
The following playlist would contain these 4 Songs: War2IntroMusic.mp3 , Doom.mp3, TragicConfrontation.mp3, LichKingTheme.mp3
Let's take a closer look at SetMapMusic:
its a native having 3 arguments: String musicName, boolean random, and integer index.
When should we use SetMapMusic?
This Trigger sets the Playlist to War2IntroMusic.mp3, Doom.mp3, TragicConfrontation.mp3, and LichKingTheme.mp3 for all players.
Again between 2 song files is a ";".
This time we'll use the 4 Race Songs added with Frozen Throne: HumanX1.mp3, OrcX1.mp3, UndeadX1.mp3, NightElfX1.mp3.
We replace the music of players who chose "Random" as their race.
PlayMusic is an easy, powerful native which can, similar to SetMapMusic, take a string with all the music as an argument and can play it .
If you clear the current Music List and use PlayMusic with multiple music files it will play all of them and loop them.
The following lines will start the playlist PlayListBloodMage for any player who's hero is a Bloodmage
To reset to the default playlist:
Well Warcraft 3 does not accept any MP3 Files for being part of the playlist or as multiple Music Argument.
But it can play any Mp3 once, if used as single argument.
If you put together playlist of songs that can be put in a playlist and ones that cannot be put in a playlist, only one song is played.
Looks to me like these MP3's contain something that warcraft 3 can't work with and it skips setting the playlist, because of invalid argument.
We use the Win7 default MP3 Musics.
Sorry, but this does not work with the default win7 Music-Mp3s, but the concept is right.
It's not so much different from the stuff before. But you can now define the path of the music file which results to easier strings in general.
After some testing with current WEX: I still do not know why Warcraft 3 does not like these 3 Songs.
3 Songs from another game, the ProtectorsMod, are working. All of those 6 Files are Mp3.
Warcraft 3 can play each of the win7 music files as single argument, but not as pack. .
I even reduced Win7 Music Names to One Word-Files without Spaces and not beeing in SubFolders.
The Music from Protectors Mod can be play as pack, loops and can be set to be the playlist. Each is in an subfolder. :O
I realized now that warcraft 3 does not even loop this Win7-music files even if set as MapMusic being an Single Argument.
Current conclusion it has to do something with the files itself, but the problem is not the filesize.
Credits:
The uploaded map contains the examples in Way 2 and Way 3.
1. A Way To Replace Default Music
The simplest way if you don't need the default one is by replacing the default music files with custom ones.How to do it?
Open Sound Editor:
Let's close the "Sounds", if they are open. We only want "Music".
A short explanation: the music played by default is Race1.mp3,Race2.mp3,Race3.mp3,RaceX1.mp3.
A player playing Humans will hear rotational Human1, Human2, Human3 and HumanX1.
A player playing Orcs will listen to Orc1, Orc2, Orc3 and OrcX1.
And so on.
Now let's replace Human1.mp3. Right-click it with your mouse and choose "Replace Internal Sound" then a file dialog will open and you can can choose your music. Best is to pick an mp3 file. I do not know if other formats work, but mp3 works (after-all the default music is mp3).
After you have replaced Human1.mp3, Human2.mp3, Human3.mp3 and HumanX1.mp3; players playing as Human will have a full custom music list.
Replacing is easy but has its limits.
- You can only make 4 playlists (Human,Orc,Undead,NightElf) and each is linked to one race.
- Each play list must have 4 Songs.
- The original music can't be played in the map.
- Replaced sounds keep until warcraft 3 is closed, (Last checked before 1.28, but wasn't mentioned in patch notes so it's probably still the same.)
Triggers
Most skilled coders will try to mimic playlists with waits or timers (both have some problems). I have tried this too, until I recently stepped across an old post from Vexorian on wc3c.net (Own music list - Wc3C.net).
Mimicking a playlist is actually unneeded; Warcraft 3 already has the ability to set music playlists or loop multiple music files.
Before I continue, the Warcraft 3 playlist has timeouts of ca. 20 to 40 seconds between songs.
And there are some problems with some specific MP3 files. I did not discover the specifics of this yet.
The important information from the post from Vexorian is:
This -> ("path1;path2;path3")Vexorian said:Well the thing is that string musicName contains the path of the music file or "music" for default or plenty of paths separated by ; ("path1;path2;path3")
Conclusion: playing a music list is as simple as using a string which separates songs with ";".
Example:
The following playlist would contain these 4 Songs: War2IntroMusic.mp3 , Doom.mp3, TragicConfrontation.mp3, LichKingTheme.mp3
- Set PlayList = Sound\Music\mp3Music\War2IntroMusic.mp3;Sound\Music\mp3Music\Doom.mp3;Sound\Music\mp3Music\TragicConfrontation.mp3;Sound\Music\mp3Music\LichKingTheme.mp3
2. Way: Native SetMapMusic
Let's take a closer look at SetMapMusic:
JASS:
native SetMapMusic string musicName, boolean random, integer index
its a native having 3 arguments: String musicName, boolean random, and integer index.
- musicName is: The file(s) which you want to play.
- random: is order randomly changed?
- index: not so sure what it does, but from the BJ-Action I would assume its the starting Index-song.
- The BJ-Version can not be used - you can try but the two only things to choose is last played music and default music. Not want we want now.
- The Action in Trigger Editor has the description: "Plays the music after the current one ends".
When should we use SetMapMusic?
- "Map Init" is a good place as it will instantly set the playlist to the wanted one and play it.
- In other situations, the playlist will always be delayed after the current song.
- Stoping Music will stop this playList anyway and playing a music before results in some weird problems.
- For instant music change there is an easier option, but we'll go into that later.
This Trigger sets the Playlist to War2IntroMusic.mp3, Doom.mp3, TragicConfrontation.mp3, and LichKingTheme.mp3 for all players.
Again between 2 song files is a ";".
-
SetPlayList On Map Init
-
Events
- Map initialization
- Conditions
-
Actions
- Set PlayList = Sound\Music\mp3Music\War2IntroMusic.mp3;Sound\Music\mp3Music\Doom.mp3;Sound\Music\mp3Music\TragicConfrontation.mp3;Sound\Music\mp3Music\LichKingTheme.mp3
- Custom script: call SetMapMusic(udg_PlayList, true, 0)
-
Events
GetLocalPlayer()
.This time we'll use the 4 Race Songs added with Frozen Throne: HumanX1.mp3, OrcX1.mp3, UndeadX1.mp3, NightElfX1.mp3.
We replace the music of players who chose "Random" as their race.
-
SetPlayList On Map Init
-
Events
- Map initialization
- Conditions
-
Actions
- Set PlayLists = Sound\Music\mp3Music\HumanX1.mp3;Sound\Music\mp3Music\OrcX1.mp3;Sound\Music\mp3Music\UndeadX1.mp3;Sound\Music\mp3Music\NightElfX1.mp3
- Custom script: set udg_Boolean = IsPlayerRacePrefSet(GetLocalPlayer(), RACE_PREF_RANDOM)
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- Boolean Equal True
-
Then - Actions
- Custom script: call SetMapMusic(udg_PlayList, true, 0)
- Else - Actions
-
If - Conditions
-
Events
3. Way: PlayMusic
PlayMusic is an easy, powerful native which can, similar to SetMapMusic, take a string with all the music as an argument and can play it .
JASS:
native PlayMusic string musicName
If you clear the current Music List and use PlayMusic with multiple music files it will play all of them and loop them.
- Sound - Clear the music list
- Sound - Stop music Instantly
- Custom script: call PlayMusic( udg_PlayList)
The following lines will start the playlist PlayListBloodMage for any player who's hero is a Bloodmage
-
Blutmage Pick
-
Events
- Unit - A unit is Trained
-
Conditions
- (Unit-type of (Trained unit)) Equal Bloodmage
-
Actions
- Set PlayList = Sound\Music\mp3Music\BloodElfTheme.mp3;Sound\Music\mp3Music\NagaTheme.mp3;Sound\Music\mp3Music\IllidansTheme.mp3
- Custom script: set udg_LocalPlayer = GetLocalPlayer()
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
'IF'-Bedingungen
- (Owner of (Triggering unit)) Equal LocalPlayer
-
Then - Actins
- Sound - Clear the music list
- Sound - Stop music Sofort
- Custom script: call PlayMusic( udg_PlayList )
- Else - Actins
-
'IF'-Bedingungen
-
Events
To reset to the default playlist:
- -------- Music is a preset --------
- Sound - Stop music Sofort
- Sound - Play Music
- Sound - Set the music list to Music, starting with a random song
-
start
-
Events
- Map initialization
- Conditions
-
Actions
- Set PlayLists[0] = Sound\Music\mp3Music\Human1.mp3;Sound\Music\mp3Music\Human2.mp3;Sound\Music\mp3Music\Human3.mp3;Sound\Music\mp3Music\HumanX1.mp3
- Set PlayLists[1] = Sound\Music\mp3Music\Orc1.mp3;Sound\Music\mp3Music\Orc2.mp3;Sound\Music\mp3Music\Orc3.mp3;Sound\Music\mp3Music\OrcX1.mp3
- Set PlayLists[2] = Sound\Music\mp3Music\NightElf1.mp3;Sound\Music\mp3Music\NightElf2.mp3;Sound\Music\mp3Music\NightElf3.mp3;Sound\Music\mp3Music\NightElfX1.mp3
- Set PlayLists[3] = Sound\Music\mp3Music\Undead1.mp3;Sound\Music\mp3Music\Undead2.mp3;Sound\Music\mp3Music\Undead3.mp3;Sound\Music\mp3Music\UndeadX1.mp3
- Set PlayLists[4] = Sound\Music\mp3Music\HumanX1.mp3;Sound\Music\mp3Music\OrcX1.mp3;Sound\Music\mp3Music\UndeadX1.mp3;Sound\Music\mp3Music\NightElfX1.mp3
- Set PlayLists[5] = Sound\Music\mp3Music\War2IntroMusic.mp3;Sound\Music\mp3Music\Doom.mp3;Sound\Music\mp3Music\TragicConfrontation.mp3;Sound\Music\mp3Music\LichKingTheme.mp3
- Set PlayListsSize = 5
-
For each (Integer A) from 0 to PlayListsSize, do (Actions)
-
Loop - Actions
- Trigger - Add to Change Music <gen> the event (Player - Player 1 (Rot) types a chat message containing (String((Integer A))) as Exact Match)
-
Loop - Actions
- Select - Select Paladin 0000 <gen>
- Trigger - Run Random PlayList <gen> (ignoring conditions)
-
Events
-
Change Music
- Events
- Conditions
-
Actions
- Set PlayListsSelected = (Integer((Entered chat string)))
- Trigger - Run SetPlayList <gen> (checking conditions)
-
SetPlayList
- Events
-
Conditions
- PlayListsSelected greater than or equal to 0
- PlayListsSelected less than or equal to PlayListsSize
-
Actions
- -------- Find the Songs --------
- Set Counter = 0
- Set Songs[0] = <Leerer String>
- -------- Check Each Single Letter, if it is a ";" start new Song, else add it to the current Song --------
-
For each (Integer A) from 1 to (Length of PlayLists[PlayListsSelected]), do (Actions)
-
Loop - Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Substring(PlayLists[PlayListsSelected], (Integer A), (Integer A))) Unequal ;
-
Then - Actions
- Set Songs[Counter] = (Songs[Counter] + (Substring(PlayLists[PlayListsSelected], (Integer A), (Integer A))))
-
Else - Actions
- Set Counter = (Counter + 1)
- Set Songs[Counter] = <Leerer String>
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
Loop - Actions
- -------- Print them --------
-
For each (Integer A) from 0 to Counter, do (Actions)
-
Loop - Actions
- Game - Display to (All players) for 30.00 seconds the text: Songs[(Integer A)]
-
Loop - Actions
- Custom script: set udg_LocalPlayer = GetLocalPlayer()
- -------- Play them for Local Player --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Triggering player) Equal LocalPlayer
-
Then - Actions
- Sound - Clear the music list
- Sound - Stop music Sofort
- Custom script: call PlayMusic( udg_PlayLists[udg_PlayListsSelected] )
- Else - Actions
-
If - Conditions
How to Use Imported Music
Well Warcraft 3 does not accept any MP3 Files for being part of the playlist or as multiple Music Argument.
But it can play any Mp3 once, if used as single argument.
If you put together playlist of songs that can be put in a playlist and ones that cannot be put in a playlist, only one song is played.
Looks to me like these MP3's contain something that warcraft 3 can't work with and it skips setting the playlist, because of invalid argument.
We use the Win7 default MP3 Musics.
Sorry, but this does not work with the default win7 Music-Mp3s, but the concept is right.
It's not so much different from the stuff before. But you can now define the path of the music file which results to easier strings in general.
First let's import 3 music files with Import Manager.
Switch into Import Manager:
In the now opened window, start importing.
I import the Win7 basic included music.
Currently the paths in my opinion are bad. Everything is war3mapImported, and "Maid with the Flaxen Hair" to long.
Lets change it to Music\
We do that with all of them.
Now it looks like that:
As you can see at the bottom: music is quite heavy. These 3 Songs take ~17 MB.
Now we switch to Trigger Editor and create an String Variable name PlayList.
And create this trigger:
Make sure that every song is separated by ";".
The default GUI shown Action - "PlayMusic" can not take strings. That's why we have to use custom script.
Switch into Import Manager:
In the now opened window, start importing.
I import the Win7 basic included music.
Currently the paths in my opinion are bad. Everything is war3mapImported, and "Maid with the Flaxen Hair" to long.
Lets change it to Music\
We do that with all of them.
Now it looks like that:
As you can see at the bottom: music is quite heavy. These 3 Songs take ~17 MB.
Now we switch to Trigger Editor and create an String Variable name PlayList.
And create this trigger:
-
PlayMusic Starting at 5 seconds
-
Events
- Time - Elapsed game time is 5.00 seconds
- Conditions
-
Actions
- Sound - Clear the music list
- Sound - Stop music Instantly
- Set PlayList = Music\Kalimba.mp3;Music\Maid Flaxen Hair.mp3;Music\Sleep Away.mp3
- Custom script: call PlayMusic(udg_PlayList)
-
Events
Make sure that every song is separated by ";".
The default GUI shown Action - "PlayMusic" can not take strings. That's why we have to use custom script.
After some testing with current WEX: I still do not know why Warcraft 3 does not like these 3 Songs.
3 Songs from another game, the ProtectorsMod, are working. All of those 6 Files are Mp3.
Warcraft 3 can play each of the win7 music files as single argument, but not as pack. .
I even reduced Win7 Music Names to One Word-Files without Spaces and not beeing in SubFolders.
The Music from Protectors Mod can be play as pack, loops and can be set to be the playlist. Each is in an subfolder. :O
I realized now that warcraft 3 does not even loop this Win7-music files even if set as MapMusic being an Single Argument.
Current conclusion it has to do something with the files itself, but the problem is not the filesize.
Credits:
- Vexorian - multiple Musicfiles as 1 String
- RG00 - The Member why I discovered this stuff
- Chaosy - GetLocalPlayer
The uploaded map contains the examples in Way 2 and Way 3.
Attachments
Last edited by a moderator: