1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. The raddest synthwave tracks were chosen - Check out our Music Contest #12 - Results and congratulate the winners!
    Dismiss Notice
  5. The poll for Hive's 12th Concept Art Contest is up! Go cast your vote for your favourite genie!
    Dismiss Notice
  6. Travel to distant realms and encounter scenes unknown to the common folk. The Greatest of Adventures is upon us with the 8th Cinematic Contest. Join in on a fun ride.
    Dismiss Notice
  7. The 18th Icon Contest is ON! Choose any ingame unit and give him/her Hero abilities. Good luck to all.
    Dismiss Notice
  8. Contestants are to create a scene set in the Stone Age. Come and see what you can come up with. We wish you the best of luck!
    Dismiss Notice
  9. Colour outside the lines! Techtree Contest #13 is a go. The contest is optionally paired.
    Dismiss Notice
  10. Greetings cerebrates, our Swarm needs new spawners that will have numerous children. Join the HIVE's 31st Modeling Contest - Spawners and Spawned! The contest is optionally paired.
    Dismiss Notice
  11. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

External Music System V.1.5

Submitted by Arad MNK
This bundle is marked as approved. It works and satisfies the submission rules.
This is an unbelievably simple system I've made with basic vJASS (First vJASS spell!!) as I currently don't know advanced vJASS (structs and stuff) but it wasn't needed, as the system is waaaaay too simple, but I think useful. Might not be approved, as it is too simple, but for some Map-Makers that don't want to waste filesize on Music files they can attach the soundtrack to the map and let the player install it.

The is the External Music System. A system where you give it the .mp3 files in your Warcraft III folder (you give the system the path) and it plays the music for you one by one, I tried to make it as Configurable as possible, like you can choose all .mp3 prefixes, the choice whether the 0 before 1 should be there or not (like "Track-01" and "Track-1"), playing the music random, etc. The user can fully configure the system, and of course the .mp3 files!

Fully MUI and GUI friendly. Demo map includes whatever you need to know, and a way to use the system is under the Category "Demo related".

Requirements:
JNGP
Local Files Enabled


Why JNGP?
Because this is coded in vJASS and also you need to have local files enabled. Tick it from the Grimoire extension of JNGP (thanks Emm-A-!).

Disclaimer:
Changing the .mp3 files in the middle of when system is ran is NOT supported.
Only works with .mp3 files. .wav file formats and others are basically avoided.

Remember, if anyone uses this and finds a problem with it, he has the Responsibility to report the problem here (using the debug messages).

Special thanks to Zwiebelchen for his helps.

Triggers and Scripts
MS Configuration
  • MS Configuration
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- ===== --------
      • -------- Configuration --------
      • -------- ===== --------
      • -------- The Timeout for the system. --------
      • -------- The real timeout will be calculated by how many times(MS_Timeout) checks will happen in a SINGLE SECOND. So the system now currently works every 0.5 seconds. --------
      • -------- The bigger the variable is, the more percise the system gets. But with bigger values than like 40 or 50 you'll have some minor problems on Battle.net. --------
      • Set MS_Timeout = 20.00
      • -------- When set to true, "Test-01" will be used as a sound and "Test-1" won't be. Vica Versa as well. --------
      • Set MS_Use0 = True
      • -------- The Variable would look for a known number of tracks, so it will loop until then for like 3 times. --------
      • -------- Set it to 0 so it would look for all available tracks. (recommended) --------
      • Set MS_ForLoop = 0
      • -------- When true, it may choose random tracks from the folder (the one played earlier might be played :p). --------
      • Set MS_PlayingIsRandom = False
      • -------- ===== --------
      • -------- End of Configuration --------
      • -------- ===== --------
      • Sound - Clear the music list
      • Sound - Stop music Immediately


MS How to use
  • MS How to use
    • Events
    • Conditions
    • Actions
      • -------- ---- --------
      • -------- Just note that for these functions to run you'll need to call StartSoundtrack at least once. --------
      • -------- ---- --------
      • -------- Use this code to start your soundtrack. Most important function. --------
      • -------- The first parameter is the folder path and the second parameter is the .mp3 file prefix. --------
      • -------- So it's like this: Warcraft3Folder\MyFolderPath\MyFilePrefix-01.mp3 --------
      • Custom script: call StartSoundtrack("MyFolderPath", "MyFilePrefix")
      • -------- How to mute a player: --------
      • Set TempPlayer = Player 1 (Red)
      • -------- 0 Volume is mutation. --------
      • Custom script: call EMSSetVolume(udg_TempPlayer, 0)
      • -------- ---- --------
      • -------- You can unmute someone as well, using the line below: --------
      • Set TempPlayer = Player 1 (Red)
      • -------- 127 Is the highest volume possible, I don't know what will happen if it's greater than 127, but I'm not sure it'll work out well. --------
      • Custom script: call EMSSetVolume(udg_TempPlayer, 127)
      • -------- ---- --------
      • -------- ---- --------
      • -------- Here's how to get the number of tracks a player has: --------
      • Set TempPlayer = Player 1 (Red)
      • Custom script: set udg_DemoTrackNumber = EMSGetTrackNum(udg_TempPlayer)
      • -------- Variable Demo_TrackNumber now has the value. --------
      • -------- ---- --------
      • -------- Listen carefully to this one. --------
      • -------- This will get the number of tracks the player has "locally". The integer won't cause desyncs (dont' worry) but the results may be different for each player. --------
      • Custom script: set udg_DemoTrackNumber = EMSGetTrackNumLocal()
      • -------- Variable Demo_TrackNumber now has the value. --------
      • -------- ---- --------
      • -------- Gets the current Track playing. It's local just like GetTrackNumLocal(). --------
      • Custom script: set udg_DemoTrackNumber = EMSGetCurrentTrack()
      • -------- Variable Demo_TrackNumber now has the value. --------

MS System
Code (vJASS):
library EMS /* v.1.5 */ initializer Init /*
******************************************************************************************
*
*     EMS by Arad MNK
*
******************************************************************************************
*
*     EMS
*
*        EMS is the External Music System which is a GUI-Friendly system. You Can
*        use this system both with JASS and GUI (other things are supported too!)
*        You can control the music playing from other external folders with this system.
*
*           Notes:
*            - Changing the .mp3 files in the middle of when system is on is NOT supported.
*            - Only works with .mp3 files. .wav file formats and others are basically avoided.
*
******************************************************************************************
*/

//! novjass

//*      API

        function StartSoundtrack takes string path, string filePrefix returns nothing
//*         - Most important Function. Initializes the system with any GUI event, with the according folder and file prefix.

        function EMSSetVolume takes player p, integer vol returns nothing
//*       - Set a player's music volume to an integer.

        function EMSPlayCustomTrack takes integer track returns boolean
//*         - Play a custom track while the system is running.

        function EMSGetTrackNum takes player p returns integer
//*         - The number of tracks player p has.

        function EMSGetTrackNumLocal takes nothing returns integer
//*         - The number of tracks the player has. It's a local integer.

        function EMSGetCurrentTrack takes nothing returns integer
//*         - Current track running. Local integer.

//! endnovjass

/*
*
*
******************************************************************************************
*
*      Credits
*          Zwiebelchen - He helped me at some critical points. Also the main idea drives from him.
*
******************************************************************************************
*/


    globals
        private integer array TrackNum // Global how many tracks you have.
        private integer TrackNumLocal // Local how many tracks you have.
        private sound array Track // The sound handles of tracks.
        private integer CurrTrackNum // Current track playing number, i.e MusicFolder\Test-CurrTrackNum.mp3
        private boolean Allowed = true // Should the system run or it's not allowed?
        private string SoundtrackFilePrefix = "NULL" // These two NULLs are used in
        private string SoundtrackPath = "NULL"       //   the function Message.
        private timer SystemTimer = CreateTimer()
        private boolean FirstCall = false
    endglobals

//********************************************//
//*************/Message Function/*************//
//********************************************//
    private function Message takes string s returns nothing //Debug messages
        debug call DisplayTextToPlayer(Player(0), 0, 0, "|c00FFFF00EMS:|r " + s + "\n|c00FF0000ID:|r " + SoundtrackPath +" " + SoundtrackFilePrefix)
    endfunction

//*******************************//
//*************/API/*************//
//*******************************//

    function EMSSetVolume takes player p, integer vol returns nothing
        local integer i = 1

        if FirstCall then
            loop
                exitwhen i == TrackNum[GetPlayerId(p)] + 1
                if GetLocalPlayer() == p then
                    call SetSoundVolume(Track[i], vol)
                endif
                set i = i + 1
            endloop
       
            call Message("New Volume: " + I2S(vol))
        else
            call Message("System is not initialized for the first time yet...")
        endif
    endfunction

    function EMSPlayCustomTrack takes integer track returns boolean //The boolean means that the track exists or not
        local boolean b = track <= TrackNumLocal and FirstCall

        if b then
            set Allowed = false //Does not allow the core to detect the stopped sound and restart
            call StopSound(Track[CurrTrackNum], false, false)
            call Message("Custom Track Playing: " + I2S(track))
            set CurrTrackNum = track - 1
            call StartSound(Track[CurrTrackNum])
            set Allowed = true
        else
            call Message("Invalid Track.")
        endif

        return b
    endfunction

    function EMSGetTrackNum takes player p returns integer
        if FirstCall then
            return TrackNum[GetPlayerId(p)]
        else
            call Message("System is not initialized for the first time yet...")
            return 0
        endif
    endfunction

    function EMSGetTrackNumLocal takes nothing returns integer
        if FirstCall then
            return TrackNumLocal
        else
            call Message("System is not initialized for the first time yet...")
            return 0
        endif
    endfunction

    function EMSGetCurrentTrack takes nothing returns integer
        if FirstCall then
            return CurrTrackNum
        else
            call Message("System is not initialized for the first time yet...")
            return 0
        endif
    endfunction

//*********************************************************//
//*************/Functions used by the system./*************//
//*********************************************************//

    private function CreateTrackLocation takes integer i returns string
        local string s
        local string smsg

        if udg_MS_Use0 and i < 10 then
            set s = "0"
        else
            set s = ""
        endif

        set smsg = SoundtrackPath + "\\" + SoundtrackFilePrefix + "-" + s + I2S(i) + ".mp3"
        call Message("Track path generated: " + smsg)
        set s = null

        return smsg
    endfunction
   
    private function NumOfTracksLocal takes nothing returns integer
        local integer i = 1
        local integer i2 = 1

        loop
            exitwhen i != i2
            if GetSoundFileDuration(CreateTrackLocation(i)) > 0 then
                set i2 = i2 + 1
            endif
            set i = i + 1
        endloop

        return i2 - 1
    endfunction

    private function NumOfTracksLimitLocal takes integer limit returns integer
        local integer i = 1
        local integer i2 = 1

        loop
            exitwhen i == udg_MS_ForLoop or i != i2
            if GetSoundFileDuration(CreateTrackLocation(i)) > 0 then
                set i2 = i2 + 1
            endif
            set i = i + 1
        endloop

        return i2 - 1
    endfunction

    private function NumOfTracks takes player p returns integer
        local integer i = 1
        local integer i2 = 1

        loop
            exitwhen i != i2
            if GetLocalPlayer() == p then
            if GetSoundFileDuration(CreateTrackLocation(i)) > 0 then
                set i2 = i2 + 1
            endif
            endif
            set i = i + 1
        endloop
            return i2 - 1
    endfunction
   
    private function NumOfTracksLimit takes player p, integer limit returns integer
        local integer i = 1
        local integer i2 = 1
        loop
            exitwhen i == udg_MS_ForLoop or i != i2
            if GetLocalPlayer() == p then
            if GetSoundFileDuration(CreateTrackLocation(i)) > 0 then
                set i2 = i2 + 1
            endif
            endif
            set i = i + 1
        endloop

        return i2 - 1
    endfunction

    private function Core takes nothing returns nothing
        if not(GetSoundIsLoading(Track[CurrTrackNum]) or GetSoundIsPlaying(Track[CurrTrackNum])) and Allowed then
            call StopSound(Track[CurrTrackNum], false, false)
            if udg_MS_PlayingIsRandom then
                set CurrTrackNum = GetRandomInt(1, TrackNumLocal)
                call Message("Random Track: " + I2S(CurrTrackNum))
            else
                if CurrTrackNum != TrackNumLocal + 1 then
                    set CurrTrackNum = CurrTrackNum + 1
                elseif CurrTrackNum == TrackNumLocal + 1 then
                    set CurrTrackNum = 1 //start from beginning
                endif
            call Message("Next Track: " + I2S(CurrTrackNum))
            endif
            call StartSound(Track[CurrTrackNum])
        endif
    endfunction

    private function Init takes nothing returns nothing
        call Message("Initialized.\nDebug mode is on.")
    endfunction

//****************************************************************************//
//*************/Most Important user function, starts the system./*************//
//****************************************************************************//

    function StartSoundtrack takes string path, string filePrefix returns nothing
        local integer i = 1

        set Allowed = false
        set SoundtrackPath = path
        set SoundtrackFilePrefix = filePrefix

        if FirstCall then
            call Message("Not first call, Stopping music.")
            call Message("Track stopped: " + I2S(CurrTrackNum))
            call StopSound(Track[CurrTrackNum], false, false) //Stopping the music playing if called when a soundtrack is on

            loop
                exitwhen i == TrackNumLocal
                call KillSoundWhenDone(Track[i])
                call Message("Track destroyed. Track Number:" + I2S(i))
                set i = i + 1
            endloop
        else
            set FirstCall = true
            call Message("First call.")
        endif

        set CurrTrackNum = 1
        set i = 1
        call Message("Starting soundtrack: " + path + "\\" + filePrefix)

        if udg_MS_ForLoop == 0 then
            set TrackNumLocal = NumOfTracksLocal()
        elseif udg_MS_ForLoop > 0 then
            set TrackNumLocal = NumOfTracksLimitLocal(udg_MS_ForLoop)
        endif

        loop
            exitwhen i == TrackNumLocal
            set Track[i] = CreateSound(CreateTrackLocation(i), false, false, false, 12700, 12700, "")
            call Message("Track created. Track Number:" + I2S(i))
            set i = i + 1
        endloop

        call StartSound(Track[1])
        call TimerStart(SystemTimer, 1 / udg_MS_Timeout, true, function Core)
        set Allowed = true
    endfunction
endlibrary


Keywords:
Music, music, arad mnk, arad, mnk, m, n, k, external, system, external music, external music system, bleh, filesize, orpg, sound, mp3
Contents

EMS (Map)

Reviews
Moderator
16:57, 8th Feb 2016 Tank-Commander: A small system with a lot of use - great for saving map memory space and a good edition to the section. Code looks good from where I'm sat and the API fully explains the system. Well done. Notes (for users):...
  1. Arad MNK

    Arad MNK

    Joined:
    Dec 11, 2014
    Messages:
    1,889
    Resources:
    3
    Maps:
    2
    Spells:
    1
    Resources:
    3
    This is what you need.

    I'm still trying to figure out
    keyword
    s for the API... Else I woulda upload it today :p

    The demo will include what you want.


    Soundtrack update will be released either tomorrow or the day after (EMS v1.5).



    When released, with different events you can use:
    Code (vJASS):

    //register the event you want, GUI friendly as well
    call StartSoundtrack("myFolder", "myFilePrefix") //stops the music, changes the folder with the .mp3 files, and starts playing
     


    The demo event will be a peseant that with moving it you'd change track folders (specific songs you need).

    EDIT: I had some problems with thread crashes. It'll be released tomorrow, if my time allows that.

    EDIT 2: BRUH. Thread crash problem fixed, now when starting another soundtrack the other soundtrack plays the next track, making 2 tracks play at once. (You'll feel like a DJ)

    EDIT 3: FINALLY! Managed to find the issue. Preparing to upload.
     
    Last edited: Mar 8, 2016
  2. Arad MNK

    Arad MNK

    Joined:
    Dec 11, 2014
    Messages:
    1,889
    Resources:
    3
    Maps:
    2
    Spells:
    1
    Resources:
    3
    EMS updated! Hopefully it's last update!


    • Soundtrack system added!
    • Hotter debug messages!
    • Removed some variables
    • Added some variables.
    • Demo now has a unit to control the soundtracks.
     
  3. Emm-A-

    Emm-A-

    Joined:
    Jul 1, 2008
    Messages:
    1,313
    Resources:
    0
    Resources:
    0
    Unfortunately the system causes havy lag every time I enter one of these regions with the worker in your demo map ... Other than that it is really cool, thanks for creating this system. If I find some time, I will think about this more :)
     
  4. Arad MNK

    Arad MNK

    Joined:
    Dec 11, 2014
    Messages:
    1,889
    Resources:
    3
    Maps:
    2
    Spells:
    1
    Resources:
    3
    I've never faced lag in my demo.

    Just tell me: did you face a thread crash as well?
     
  5. Emm-A-

    Emm-A-

    Joined:
    Jul 1, 2008
    Messages:
    1,313
    Resources:
    0
    Resources:
    0
    nope just lags. maybe its just my computer, otherwise there would have been other posts I guess
     
  6. Arad MNK

    Arad MNK

    Joined:
    Dec 11, 2014
    Messages:
    1,889
    Resources:
    3
    Maps:
    2
    Spells:
    1
    Resources:
    3
    Note that the sounds can't be preloaded as they are created at call. This might be the reason for your lag. Maybe I'll add a new function to be able to preload sounds.
     
  7. Emm-A-

    Emm-A-

    Joined:
    Jul 1, 2008
    Messages:
    1,313
    Resources:
    0
    Resources:
    0
    I think this would be important .. I dont really get why my computer has problems with that as it runs wither 3 on max details but lags with that create native here. Might be some stupid special problem and not generally related to your function ..
     
  8. Arad MNK

    Arad MNK

    Joined:
    Dec 11, 2014
    Messages:
    1,889
    Resources:
    3
    Maps:
    2
    Spells:
    1
    Resources:
    3
    It is for sure handle preloading, if you lag only once.

    But if you have a looooooong lag, it may be a hidden leak or that you have over-engineered the system timeout (like setting it to 100).
     
  9. Emm-A-

    Emm-A-

    Joined:
    Jul 1, 2008
    Messages:
    1,313
    Resources:
    0
    Resources:
    0
    Hey by testing the CreateSound native like in your system, I just figured out, that you have to enable Warcraft to be able to use Local Files. I didnt read this here or I didnt see it, and as I have 2 computers with 2 editors I have been searching for almost 2 days now ... :ogre_rage:

    So I suggest you add this important tip to your description :) instruction using regedit.exe (or simply tick the "enable local files" in grimoire extensions of JNGP.


    @Lag: this laggy problem dissappeared when I changed some thing in my system, so besides a little first lag, there is no problem anymore :thumbs_up:
     
  10. Arad MNK

    Arad MNK

    Joined:
    Dec 11, 2014
    Messages:
    1,889
    Resources:
    3
    Maps:
    2
    Spells:
    1
    Resources:
    3
    Added. Thanks a bunch!
     
  11. Narasha

    Narasha

    Joined:
    Feb 25, 2016
    Messages:
    13
    Resources:
    0
    Resources:
    0
    " You don't have any selected music in your folder", I do change the path in "MS Init 1". I already created my Folder in warcraft folder and put a music in it. still it cannot detect it. Help?
     
  12. Arad MNK

    Arad MNK

    Joined:
    Dec 11, 2014
    Messages:
    1,889
    Resources:
    3
    Maps:
    2
    Spells:
    1
    Resources:
    3
    Um...
    I have deleted wc3 and I no longer code. I have left hive but just smth made me look up here.

    I remember the system had a bug, in which, the system couldn't play the last music (or was it the first?). Anyways, I can no longer test it (no Warcraft) but you can have a null mp3 file track in the end of it and use that as a music file, but the system won't play it. Basically you have avoided the bug.

    If anyone wants to recreate/fix this system your totally open.