Advertisement
ZoriaRPG

Music.zh v1.3.4

Mar 19th, 2019
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 32.61 KB | None | 0 0
  1. ////////////////////////////////
  2. /// Music.zh                 ///
  3. /// v1.3.4 - 19th Mar, 2019  ///
  4. /// By: ZoriaRPG             ///
  5. ////////////////////////////////////////////////////////////////////////////////////////////////////
  6. /// A series of FFCs, and utility functions for playing MIDIs, Enhanced Music, and Sound Effects ///
  7. /// 1.3.3: Optimisation for inclusion with ZC 2.53 Gamma 4                                       ///
  8. /// 1.3.4: Fixes to NPC_MIDI and NPC_Music                                                       ///
  9. ////////////////////////////////////////////////////////////////////////////////////////////////////
  10.  
  11. import "std.zh"
  12. //import "string.zh"
  13.  
  14. const int MIDI_DEFEATBOSS = 0; //Set to default midi to play for Victory Music.
  15.                 //ZC will use this if enhanced Victory music is not available.
  16.                
  17. const int DEFAULT_BOSS_MUSIC = 0; //Sets a default boss music file to play.
  18.                
  19. ///////////////
  20. /// SCRIPTS ///
  21. ///////////////
  22.  
  23.  
  24. /////////////////////
  25. /// Sound Effects ///
  26. /////////////////////
  27.  
  28. // Ties SFX to an item, that is otherwise normally hardcoded. used for the Sonic Wand in LoE.
  29.  
  30. item script playSound
  31. {
  32.     void run(int sfx)
  33.     {
  34.         Game->PlaySound(sfx);
  35.     }
  36. }
  37.  
  38. /////////////////
  39. /// MIDI Only ///
  40. /////////////////
  41.  
  42. //Plays MIDI specified at D0. Place on a screen, to change the MIDI for that screen, only.
  43. //Plays at all times on that screen, and uses no conditions.
  44.  
  45. ffc script playMIDI
  46. {
  47.     void run(int midiNumber)
  48.     {
  49.         Game->PlayMIDI(midiNumber);
  50.     }
  51. }
  52.  
  53. /////////////////////////
  54. /// Conditional MIDIs ///
  55. /////////////////////////
  56.  
  57.  
  58.  
  59. //play a MIDI while an enemy with a specific ID is on-screen
  60.  
  61. ffc script NPC_MIDI
  62. {
  63.     void run(int npc_ID, int midi)
  64.     {
  65.         //int originalMIDi = //share these two
  66.         //int originalMusic[3] = //midi, enh music, track
  67.         //store the normal midi or music
  68.         //check for the npc and while it is on-screen
  69.         //change the midi
  70.         Waitframes(6);
  71.         //if it dies, change back
  72.         int q[4]; npc n; bool found;
  73.         int enh_music[256] = {0};
  74.         Game->GetDMapMusicFilename(Game->GetCurDMap(), enh_music);
  75.        
  76.         int enh_trk = Game->GetDMapMusicTrack(Game->GetCurDMap());
  77.         for ( q[0] = 0; q[0] < 256; ++q[0] ) { if ( enh_music[q] == ' ' ) enh_music[q] = 0; } //kill the space.
  78.         bool enhanced =  ( enh_music[0] != 0 ); //is the dmap music enhanced?
  79.        
  80.         int originalmusic = Game->DMapMIDI[Game->GetCurDMap()];
  81.         while(!Screen->NumNPCs()) Waitframe();
  82.         while(true){
  83.             for ( q[0] = Screen->NumNPCs(); q[0] > 0; --q[0] ) {
  84.                 n = Screen->LoadNPC(q);
  85.                 if ( n->ID == npc_ID )
  86.                 {
  87.                     q[1] = 1; break;
  88.                 }
  89.                 q[1] = 0;
  90.             }
  91.             if ( q[1] )
  92.             {
  93.                 if ( !q[2] )
  94.                 {
  95.                     Game->PlayMIDI( midi );
  96.                     q[2] = 1;
  97.                 }
  98.             }
  99.             if ( !NumNPCsOf(npc_ID) )
  100.             {
  101.                 Waitframes(10);
  102.                 Game->PlayEnhancedMusic(enh_music, enh_trk);
  103.                
  104.                 if ( !enhanced ) Game->PlayMIDI(originalmusic);
  105.             }
  106.             Waitframe();
  107.         }
  108.            
  109.     }
  110. }
  111.  
  112. //play enhanced music while an enemy with a specific ID is on-screen
  113.  
  114. ffc script NPC_Music
  115. {
  116.     void run(int npc_ID, int music_string, int track)
  117.     {
  118.         //int originalMIDi = //share these two
  119.         //int originalMusic[3] = //midi, enh music, track
  120.         //store the normal midi or music
  121.         //check for the npc and while it is on-screen
  122.         //change the midi
  123.         Waitframes(6);
  124.         //if it dies, change back
  125.         int q[4]; npc n; bool found;
  126.         int enh_music[256] = {0};
  127.         Game->GetDMapMusicFilename(Game->GetCurDMap(), enh_music);
  128.        
  129.         int enh_trk = Game->GetDMapMusicTrack(Game->GetCurDMap());
  130.         for ( q[0] = 0; q[0] < 256; ++q[0] ) { if ( enh_music[q] == ' ' ) enh_music[q] = 0; } //kill the space.
  131.         bool enhanced =  ( enh_music[0] != 0 ); //is the dmap music enhanced?
  132.         bool playing;
  133.        
  134.         int originalmusic = Game->DMapMIDI[Game->GetCurDMap()];
  135.         while(!Screen->NumNPCs()) Waitframe();
  136.        
  137.         while(true){
  138.             for ( q[0] = Screen->NumNPCs(); q[0] > 0; --q[0] )
  139.             {
  140.                 n = Screen->LoadNPC(q);
  141.                 if ( n->ID == npc_ID )
  142.                 {
  143.                     q[1] = 1; break;
  144.                 }
  145.                 q[1] = 0;
  146.             }
  147.             if ( q[1] )
  148.             {
  149.                 if ( !q[2] )
  150.                 {
  151.                     playing = PlayEnhMusicFile(music_string, track);
  152.                     q[2] = 1;
  153.                 }
  154.             }
  155.             if ( !NumNPCsOf(npc_ID) )
  156.             {
  157.                 Waitframes(10);
  158.                 if ( enhanced ) Game->PlayEnhancedMusic(enh_music, enh_trk);
  159.                
  160.                 if ( !enhanced ) Game->PlayMIDI(originalmusic);
  161.             }
  162.             Waitframe();
  163.         }
  164.            
  165.     }
  166. }
  167.  
  168. // These scripts will play MIDI files based on conditions set in the script args.
  169.  
  170. // D0: MIDI file to play while boss is on the screen.
  171. // D1: The Screen Register (Screen->D[reg]) to use.
  172. // D2: Victory MIDI to play when boss is defeated. If set to 0, the MIDI set by constant MIDI_DEFEATBOSS plays.
  173. // D3: The duration of the victory music.
  174. //
  175. //  If set to 0, the track will not play.
  176. //  If set to greater than 0, the track will play for a specific duration, as follows:
  177. //  To set using minutes, and seconds, set up minutes as the integer portion of the arg, and seconds as the decimal portion:
  178. //      e.g. 00005.0260 is 5 mins, 26 seconds.
  179. //      This works to a fineness of 1/10 second, so 00010.0136 is 10 minutes, 13.6 seconds.
  180. //  If you wish to specify the duration in frames, set the ten-thousands place to '1', and the rest of the value to the number of frames.
  181. //  e.g. 10526.1023 = 5,261,023 frames.
  182. //  e.g. 10001.3591 = 13,591 frames.
  183. //
  184. // D4: The enemy ID of the 'boss':
  185. //
  186. //  A value of zero here, instructs the FFC not to change the Screen->D[reg] value. Leave this at zero, if the enemy does this.
  187. //  Otherwise, set this to -1 (negative one) if you want the Victory music to play when all screen NPCs are dead...or...
  188. //  a positive value matching an enemy ID that is on the screen, if you want to play the Victory music when all enemies with that ID are dead.
  189.  
  190.  
  191. ffc script BossMusic
  192. {
  193.     void run(int bossMIDI, int reg, int victoryMIDI, int vict_dur, int enem)
  194.     {
  195.         Waitframes(6);
  196.         int curScreen = Game->GetCurScreen();
  197.         int dat = Game->GetScreenD(curScreen,reg);
  198.         if ( dat == 0 ) {
  199.             if ( bossMIDI > 0 )
  200.             {
  201.                 Game->PlayMIDI(bossMIDI);
  202.             }
  203.             else
  204.             {
  205.                 Game->PlayMIDI(DEFAULT_BOSS_MUSIC);
  206.             }
  207.         }
  208.         int curDMap = Game->GetCurDMap();
  209.         int stdMIDI = Game->DMapMIDI[curDMap];
  210.        
  211.  
  212.         int VictoryClockMethod = _Music_zh__GetDigit(vict_dur, 4);
  213.         int dur;
  214.        
  215.         if ( VictoryClockMethod == 0 )
  216.         {
  217.             dur = MusicFrames(vict_dur); //Convert victory music into frames.
  218.         }
  219.        
  220.         if ( VictoryClockMethod > 0 )
  221.         {
  222.             dur = _Music_zh__GetPartialArg(vict_dur,3,8); //Use the full value of loopBossMusic as frame in int.
  223.         }
  224.        
  225.         while(true)
  226.         {
  227.             dat = Game->GetScreenD(curScreen,reg);
  228.            
  229.             if ( enem == -1 && !Screen->NumNPCs() )
  230.             {
  231.                 Game->SetScreenD(curScreen,reg,1);
  232.             }
  233.             if ( enem == 0 )
  234.             {
  235.                 //Should we do anything special?
  236.                 //A zero value is intended to be used if we don;t want the FFC to set Screen->D to 1.
  237.                 //-1 if we do it based on all enemies being dead.
  238.                 //A positive value trips it if there are no enemies of that ID on the screen.
  239.             }
  240.        
  241.             if ( enem > 0 && !NumNPCsOf(enem) )
  242.             {
  243.                 Game->SetScreenD(curScreen,reg,1);
  244.             }
  245.            
  246.             dat = Game->GetScreenD(curScreen,reg);
  247.            
  248.            
  249.             if ( dat > 0 )
  250.             {
  251.                 if ( dur > 0 )
  252.                 {
  253.                     if ( victoryMIDI > 0 )
  254.                     {
  255.                         Game->PlayMIDI(MIDI_DEFEATBOSS);
  256.                     }
  257.                     else
  258.                     {
  259.                         Game->PlayMIDI(MIDI_DEFEATBOSS);
  260.                     }
  261.                     for ( int q = 0; q <= dur; ++q )
  262.                     {
  263.                         Waitframe();
  264.                     }
  265.                 }
  266.                 Game->PlayMIDI(stdMIDI);
  267.             }
  268.             Waitframe();
  269.         }
  270.     }
  271. }
  272.            
  273. //////////////////////         
  274. /// Enhanced Music ///
  275. //////////////////////
  276.  
  277. /// These scripts will play 'enhanced music', using values set in script args.
  278. /// If an enhanced music file is not available (e.g. the player does not have it, or elects
  279. /// not to use it, then they will play a back-up MIDI file, also set by script args.
  280.  
  281. // D0: MIDI number to default to for this boss, if no enhanced music is available.
  282. //  Split argument, high and low at decimal point:
  283. //  #####.xxxx -> Backup MIDI file to play if enhanced BOSS music is not available.
  284. //  xxxxx.#### -> Backup MIDI file to play if enhanced VICTORY music is not available.
  285. // D1: Screen->D reg to set/check.
  286. // D2: The duration of the victory music.
  287. //  If set to 0, the track will not play.
  288. //  If set to greater than 0, the track will play for a specific duration, as follows:
  289. //  To set using minutes, and seconds, set up minutes as the integer portion of the arg, and seconds as the decimal portion:
  290. //      e.g. 00005.0260 is 5 mins, 26 seconds.
  291. //      This works to a fineness of 1/10 second, so 00010.0136 is 10 minutes, 13.6 seconds.
  292. //  If you wish to specify the duration in frames, set the ten-thousands place to '1', and the rest of the value to the number of frames.
  293. //  e.g. 10526.1023 = 5,261,023 frames.
  294. //  e.g. 10001.3591 = 13,591 frames.
  295. //
  296. // D3: The STRING number, and track number, for Boss Music. Split arg, high and low at decimal point:
  297. //  #####.xxxx -> The file number.
  298. //  xxxxx.#### -> The track number to play.
  299. //  Uses string ID from internal strings table.
  300. // D4: The STRING number, and track number, for Victory Music. Split arg, high and low at decimal point:
  301. //  #####.xxxx -> The file number.
  302. //  xxxxx.#### -> The track number to play.
  303. //  Uses string ID from internal strings table.
  304. // D5: The point in the track to pause, then loop
  305. //
  306. //  If set to 0, the track with loop only when it ends.
  307. //  If set to greater than 0, the track will loop befor eit ends, as follows:
  308. //  To loop by setting minutes, and seconds, set up minutes as the integer portion of the arg, and seconds as the decimal portion:
  309. //      e.g. 00005.0260 is 5 mins, 26 seconds.
  310. //      This works to a fineness of 1/10 second, so 00010.0136 is 10 minutes, 13.6 seconds.
  311. //  If you wish to specify the loop in frames, set the ten-thousands place to '1', and the rest of the value to the number of frames.
  312. //  e.g. 10526.1023 = 5,261,023 frames.
  313. //  e.g. 10001.3591 = 13,591 frames.
  314. //
  315. // D6: This value instructs the FFC to set Screen->D[reg] = 1 when enemies are dead.
  316. //  A value of zero here, instructs the FFC not to change the Screen->D[reg] value. Leave this at zero, if the enemy does this.
  317. //  Otherwise, set this to -1 (negative one) if you want the Victory music to play when all screen NPCs are dead...or...
  318. //  a positive value matching an enemy ID that is on the screen, if you want to play the Victory music when all enemies with that ID are dead.
  319. //
  320. // D7: If set to '1' or above, this will trace informationt o allegro.log for you as debug datum.
  321.  
  322.  
  323. //Version 0.44 - Strings set by String Table (ZQuest String Editor, not hardcoded)
  324.  
  325. ffc script BossMusicEnhanced_InternalStrings
  326. {
  327.     //Credit Moosh for reminding me that reading internal strings in the string table is a thing.
  328.     void run(int midiNumber_victoryMidiNumber, int reg, int vict_dur, float musicBoss_trkBoss, float musicVictory_trkVictory, float loopBossMusic, int enem, int debug)
  329.     {
  330.         int curScreen = Game->GetCurScreen();
  331.         int curDMAP = Game->GetCurDMap();
  332.         int curDmap = Game->GetCurDMap();
  333.         int dat = Game->GetScreenD(curScreen,reg);
  334.         int stdMIDI = Game->DMapMIDI[curDMAP];
  335.        
  336.         int dmapMusicBuffer[512]=" ";
  337.         Game->GetDMapMusicFilename(curDMAP, dmapMusicBuffer);
  338.        
  339.         int midiNumber = _Music_zh__GetHighArgument(midiNumber_victoryMidiNumber); //#####.xxxx
  340.         int victoryMIDI = _Music_zh__GetLowArgument(midiNumber_victoryMidiNumber); //xxxxx.####
  341.        
  342.         int musicBoss = _Music_zh__GetHighArgument(musicBoss_trkBoss); //#####.xxxx
  343.         int trkBoss = _Music_zh__GetLowArgument(musicBoss_trkBoss); //xxxxx.####
  344.        
  345.         int musicVictory = _Music_zh__GetHighArgument(musicVictory_trkVictory);
  346.         int trkVictory = _Music_zh__GetLowArgument(musicVictory_trkVictory); //xxxxx.####
  347.        
  348.         int dmapTrack = Game->GetDMapMusicTrack(curDMAP);
  349.         int q;
  350.        
  351.         int boss_buffer[256]=" "; //two-digit number, plus four-digit extension, plus NULL.
  352.         int victory_buffer[256]=" "; //Buffer for Victory Music Filename.
  353.        
  354.         Game->GetMessage(musicVictory, victory_buffer);
  355.         Game->GetMessage(musicBoss, boss_buffer);
  356.        
  357.        
  358.         //Print filenames to allegro.log.
  359.         if ( debug )
  360.         {
  361.             int loading[]="Attempting to load file: ";
  362.             TraceNL();
  363.             TraceS(loading);
  364.             TraceNL();
  365.             TraceS(boss_buffer);
  366.             TraceNL();
  367.             TraceS(loading);
  368.             TraceNL();
  369.             TraceS(victory_buffer);
  370.             TraceNL();
  371.         }
  372.        
  373.         int playingBoss[]="Playing Boss Music";
  374.         int playingVictory[]="Playing Victory Music";
  375.         int errLoading[]="Error loading track.";
  376.        
  377.         int LoopClockMethod = _Music_zh__GetDigit(loopBossMusic, 4);
  378.         //Convert mins and seconds.
  379.        
  380.         int BossMusicDuration;
  381.         if ( LoopClockMethod == 0 )
  382.         {
  383.             BossMusicDuration = MusicFrames(loopBossMusic); //Convert loopBossMusic into time.
  384.         }
  385.         if ( LoopClockMethod > 0 )
  386.         {
  387.             BossMusicDuration = _Music_zh__GetPartialArg(loopBossMusic,3,8); //Use the full value of loopBossMusic as frame in int.
  388.         }
  389.        
  390.         int VictoryClockMethod = _Music_zh__GetDigit(vict_dur, 4);
  391.         int dur;
  392.        
  393.         if ( VictoryClockMethod == 0 )
  394.         {
  395.             dur = MusicFrames(vict_dur); //Convert victory music into frames.
  396.         }
  397.        
  398.         if ( VictoryClockMethod > 0 )
  399.         {
  400.             dur = _Music_zh__GetPartialArg(vict_dur,3,8); //Use the full value of loopBossMusic as frame in int.
  401.         }
  402.         for ( q  = 0; q < 256; q++ ) { if ( boss_buffer[q] == ' ' ) boss_buffer[q] = 0; } //kill the space.
  403.         for ( q  = 0; q < 256; q++ ) { if ( victory_buffer[q] == ' ' ) victory_buffer[q] = 0; } //kill the space.
  404.         bool playing = false;
  405.         Waitframes(6); //Wait for enemies to spawn. //Moved up here in 1.3.4
  406.         while(true)
  407.         {
  408.             //Waitframes(5); 1.3.4
  409.             dat = Game->GetScreenD(curScreen,reg);
  410.             //Waitframes(6); //Wait for enemies to spawn. 1.3.4
  411.             //Set Screen->D[reg] = 1 if the enemy is dead.
  412.             if ( enem == -1 && !Screen->NumNPCs() )
  413.             {
  414.                 Game->SetScreenD(curScreen,reg,1);
  415.             }
  416.             if ( enem == 0 )
  417.             {
  418.                 //Should we do anything special?
  419.                 //A zero value is intended to be used if we don't want the FFC to set Screen->D to 1.
  420.                 //-1 if we do it based on all enemies being dead.
  421.                 //A positive value trips it if there are no enemies of that ID on the screen.
  422.             }
  423.        
  424.             if ( enem > 0 && !NumNPCsOf(enem) )
  425.             {
  426.                 Game->SetScreenD(curScreen,reg,1);
  427.             }
  428.            
  429.             dat = Game->GetScreenD(curScreen,reg);
  430.                    
  431.             if ( dat == 0 && loopBossMusic == 0 && !playing )
  432.             {
  433.                 Game->PlayEnhancedMusic(boss_buffer, trkBoss);
  434.            
  435.                 if ( ! Game->PlayEnhancedMusic(boss_buffer, trkBoss) )
  436.                 {
  437.                     if ( midiNumber > 0 )
  438.                     {
  439.                         Game->PlayMIDI(midiNumber); //Play MIDI if enhanced music is not available.
  440.                     }
  441.                     else
  442.                     {
  443.                         Game->PlayMIDI(DEFAULT_BOSS_MUSIC); //Play default music if midiNumber is set to '0'.
  444.                     }
  445.                        
  446.                 }
  447.                 playing = true;
  448.             }
  449.            
  450.             if ( dat == 0 && loopBossMusic > 0 )
  451.             {
  452.  
  453.                 //set up music loop
  454.                 for ( int q = BossMusicDuration; q >=0; --q )
  455.                 {
  456.                     if ( q == BossMusicDuration && dat == 0 )
  457.                     {
  458.                         Game->PlayEnhancedMusic(boss_buffer, trkBoss);
  459.                         if ( ! Game->PlayEnhancedMusic(boss_buffer, trkBoss) )
  460.                         {
  461.                             Game->PlayMIDI(midiNumber); //Play MIDI if enhanced music is not available.
  462.                         }
  463.                     }
  464.                     if ( enem == -1 && !Screen->NumNPCs() )
  465.                     {
  466.                         Game->SetScreenD(curScreen,reg,1);
  467.                     }
  468.                     if ( enem == 0 )
  469.                     {
  470.                         //Should we do anything special?
  471.                         //A zero value is intended to be used if we don;t want the FFC to set Screen->D to 1.
  472.                         //-1 if we do it based on all enemies being dead.
  473.                         //A positive value trips it if there are no enemies of that ID on the screen.
  474.                     }
  475.                     if ( enem > 0 && !NumNPCsOf(enem) )
  476.                     {
  477.                         Game->SetScreenD(curScreen,reg,1);
  478.                     }
  479.                     dat = Game->GetScreenD(curScreen,reg);
  480.                     if ( dat > 0 )
  481.                     {
  482.                         break;
  483.                     }
  484.                     Waitframe();
  485.                
  486.                 }
  487.             }
  488.            
  489.             if ( dat == 0 && loopBossMusic == 0 && !playing )
  490.             {
  491.                 Game->PlayEnhancedMusic(boss_buffer, trkBoss);
  492.                 if ( ! Game->PlayEnhancedMusic(boss_buffer, trkBoss) )
  493.                 {
  494.                     if ( midiNumber > 0 )
  495.                     {
  496.                         Game->PlayMIDI(midiNumber); //Play MIDI if enhanced music is not available.
  497.                     }
  498.                     else
  499.                     {
  500.                         Game->PlayMIDI(DEFAULT_BOSS_MUSIC); //Plays default if not specified.
  501.                     }
  502.                 }
  503.                 playing = true;
  504.                
  505.             }
  506.            
  507.             dat = Game->GetScreenD(curScreen,reg);
  508.             if ( dat > 0 )
  509.             {
  510.                 if ( dur > 0 )
  511.                 {
  512.                     Game->PlayEnhancedMusic(victory_buffer, trkVictory);
  513.                     if ( ! Game->PlayEnhancedMusic(victory_buffer, trkVictory) )
  514.                     {
  515.                         if ( victoryMIDI > 0 )
  516.                         {
  517.                             Game->PlayMIDI(victoryMIDI);
  518.                         }
  519.                         else
  520.                         {
  521.                             Game->PlayMIDI(MIDI_DEFEATBOSS); //Plays default if Victory MIDI not specified.
  522.                         }
  523.                        
  524.                     }
  525.                     for ( int q = 0; q <= dur; ++q )
  526.                     {
  527.                         Waitframe(); //Pause for duration of victory music.
  528.                     }
  529.                 }
  530.                 Game->PlayEnhancedMusic(dmapMusicBuffer, dmapTrack);
  531.                 if ( ! Game->PlayEnhancedMusic(dmapMusicBuffer, dmapTrack) )
  532.                 {
  533.                     Game->PlayMIDI(stdMIDI);
  534.                 }
  535.                 Quit();
  536.             }
  537.             Waitframe();
  538.         }
  539.        
  540.     }
  541. }
  542.  
  543. // D0: MIDI number to default to for this boss, if no enhanced music is available.
  544. //  Split argument, high and low at decimal point:
  545. //  #####.xxxx -> Backup MIDI file to play if enhanced BOSS music is not available.
  546. //  xxxxx.#### -> Backup MIDI file to play if enhanced VICTORY music is not available.
  547. // D1: Screen->D reg to set/check.
  548. // D2: Set to a value of '1' or higher, to use durations.
  549. // D3: Sets file type for both enhanced music tracks. Split argument, high and low at decimal point:
  550. //  xxx##.xxxx -> Type for Boss Music file
  551. //  xxxxx.xx## -> Type for Victory Music file
  552. // D4: The file number, and track number, for Boss Music. Split arg, high and low at decimal point:
  553. //  #####.xxxx -> The file number.
  554. //  xxxxx.#### -> The track number to play.
  555. // D5: The file number, and track number, for Victory Music. Split arg, high and low at decimal point:
  556. //  #####.xxxx -> The file number.
  557. //  xxxxx.#### -> The track number to play.
  558. // D6: The point in the track to pause, then loop.
  559. //
  560. //  If set to 0, the track with loop only when it ends.
  561. //  If set to greater than 0, the track will loop befor eit ends, as follows:
  562. //  To loop by setting minutes, and seconds, set up minutes as the integer portion of the arg, and seconds as the decimal portion:
  563. //      e.g. 00005.0260 is 5 mins, 26 seconds.
  564. //      This works to a fineness of 1/10 second, so 00010.0136 is 10 minutes, 13.6 seconds.
  565. //  If you wish to specify the loop in frames, set the ten-thousands place to '1', and the rest of the value to the number of frames.
  566. //  e.g. 10526.1023 = 5,261,023 frames.
  567. //  e.g. 10001.3591 = 13,591 frames.
  568. //
  569. // D7: This value instructs the FFC to set Screen->D[reg] = 1 when enemies are dead.
  570. //  #####.xxxx -> A value of zero here, instructs the FFC not to change the Screen->D[reg] value. Leave this at zero, if the enemy does this.
  571. //  Otherwise, set this to -1 (negative one) if you want the Victory music to play when all screen NPCs are dead...or...
  572. //  a positive value matching an enemy ID that is on the screen, if you want to play the Victory music when all enemies with that ID are dead.
  573. //  xxxxx.#### -> Set to '1' or higher to enable debugging reports to allegro.log.
  574. // 
  575.  
  576. //Version 0.44 (Numbered Files)
  577.  
  578. ffc script BossMusicEnhanced_old
  579. {
  580.     void run(int midiNumber_victoryMidiNumber, int reg, int victoryDur, float musicType_musicTypeVictory, float musicBoss_trkBoss, float musicVictory_trkVictory, float loopBossMusic, int enem_debug)
  581.     {
  582.         int curScreen = Game->GetCurScreen();
  583.         int curDMAP = Game->GetCurDMap();
  584.         int curDmap = Game->GetCurDMap();
  585.         int dat = Game->GetScreenD(curScreen,reg);
  586.         int stdMIDI = Game->DMapMIDI[curDMAP]; 
  587.         int enem = _Music_zh__GetHighArgument(enem_debug);
  588.         int debug= _Music_zh__GetLowArgument(enem_debug);
  589.        
  590.         int dmapMusicBuffer[512]=" ";
  591.         Game->GetDMapMusicFilename(curDMAP, dmapMusicBuffer);
  592.        
  593.         int midiNumber = _Music_zh__GetHighArgument(midiNumber_victoryMidiNumber); //#####.xxxx
  594.         int victoryMIDI = _Music_zh__GetLowArgument(midiNumber_victoryMidiNumber); //xxxxx.####
  595.        
  596.         int musicType = _Music_zh__GetHighArgument(musicType_musicTypeVictory); //xxx##.xxxx
  597.         int musicType_Victory = _Music_zh__GetLowArgument(musicType_musicTypeVictory); //xxxxx.xx##
  598.        
  599.         int musicBoss = _Music_zh__GetHighArgument(musicBoss_trkBoss); //#####.xxxx
  600.         int trkBoss = _Music_zh__GetLowArgument(musicBoss_trkBoss); //xxxxx.####
  601.        
  602.         int musicVictory = _Music_zh__GetHighArgument(musicVictory_trkVictory); //#####.xxxx
  603.         int trkVictory = _Music_zh__GetLowArgument(musicVictory_trkVictory); //xxxxx.####
  604.        
  605.         int dmapTrack = Game->GetDMapMusicTrack(curDMAP);
  606.         int mp3[]=".mp3";
  607.         int vgm[]=".vgm";
  608.         int nsf[]=".nsf";
  609.         int ogg[]=".ogg";
  610.         int s3m[]=".s3m";
  611.         int mod[]=".mod";
  612.         int spc[]=".spc";
  613.         int gym[]=".gym";
  614.         int gbs[]=".gbs";
  615.         int it_format[]=".it";
  616.         int xm[]=".xm";
  617.        
  618.         int boss_buffer[7]=" "; //two-digit number, plus four-digit extension, plus NULL.
  619.         int victory_buffer[7]=" "; //Buffer for Victory Music Filename.
  620.         int strBoss[2]=" "; //The two digit value of musicBoss arg.
  621.         int strVictory[2]=" "; //The two digit value of musicVictory is stored here.
  622.         //int bossMusic[]=" "; //Must read value from enhBoss, append .mp3 to it, and
  623.        
  624.        
  625.         ///Set up Boss Music Filename String
  626.         itoa(strBoss, musicBoss); //Copy the value of arg musicBoss into string strBoss.   
  627.         strncpy(boss_buffer, strBoss, 2); //Copy filename (two-digit number) to buffer.
  628.         if ( musicType == 0 ) strcat(boss_buffer, mp3); //Append datatype to buffer (MP3)
  629.         else if ( musicType == 1 ) strcat(boss_buffer, vgm); //Append datatype to buffer ( Video Game Music format)
  630.         else if ( musicType == 2 ) strcat(boss_buffer, nsf); //Append datatype to buffer ( NES Sound File )
  631.         else if ( musicType == 3 ) strcat(boss_buffer, ogg); //Append datatype to buffer ( The Xiph.org open music format )
  632.         else if ( musicType == 4 ) strcat(boss_buffer, s3m); //Append datatype to buffer ( ScreamTracker 3 module file )
  633.         else if ( musicType == 5 ) strcat(boss_buffer, mod); //Append datatype to buffer ( Tracker Module file )
  634.         else if ( musicType == 6 ) strcat(boss_buffer, spc); //Append datatype to buffer ( Super NES / SuFami soound file )
  635.         else if ( musicType == 7 ) strcat(boss_buffer, gym); //Append datatype to buffer ( Genesis / Megadrive sound file )
  636.         else if ( musicType == 8 ) strcat(boss_buffer, gbs); //Append datatype to buffer ( Gameboy sound file )
  637.         else if ( musicType == 9 ) strcat(boss_buffer, it_format); //Append datatype to buffer ( Impulse Tracker audio file )
  638.         else if ( musicType == 10 ) strcat(boss_buffer, xm); //Append datatype to buffer ( Triton FastTracker 2 'Extended Module' format }
  639.         ///Other formats.
  640.        
  641.         //Set up Victory Music Filename String
  642.         itoa(strVictory, musicVictory); //Copy the value of arg musicVictory into string strVictory.
  643.         strncpy(victory_buffer, strVictory, 2); //Copy filename (two-digit number) to buffer.
  644.         if ( musicType_Victory == 0 ) strcat(victory_buffer, mp3); //Append datatype to buffer (MP3)
  645.         else if ( musicType_Victory == 1 ) strcat(victory_buffer, vgm); //Append datatype to buffer ( Video Game Music format)
  646.         else if ( musicType_Victory == 2 ) strcat(victory_buffer, nsf); //Append datatype to buffer ( NES Sound File )
  647.         else if ( musicType_Victory == 3 ) strcat(victory_buffer, ogg); //Append datatype to buffer ( The Xiph.org open music format )
  648.         else if ( musicType_Victory == 4 ) strcat(victory_buffer, s3m); //Append datatype to buffer ( ScreamTracker 3 module file )
  649.         else if ( musicType_Victory == 5 ) strcat(victory_buffer, mod); //Append datatype to buffer ( Tracker Module file )
  650.         else if ( musicType_Victory == 6 ) strcat(victory_buffer, spc); //Append datatype to buffer ( Super NES / SuFami soound file )
  651.         else if ( musicType_Victory == 7 ) strcat(victory_buffer, gym); //Append datatype to buffer ( Genesis / Megadrive sound file )
  652.         else if ( musicType_Victory == 8 ) strcat(victory_buffer, gbs); //Append datatype to buffer ( Gameboy sound file )
  653.         else if ( musicType_Victory == 9 ) strcat(victory_buffer, it_format); //Append datatype to buffer ( Impulse Tracker audio file )
  654.         else if ( musicType_Victory == 10 ) strcat(victory_buffer, xm); //Append datatype to buffer ( Triton FastTracker 2 'Extended Module' format }
  655.         ///Other formats.
  656.        
  657.        
  658.         //Print filenames to allegro.log.
  659.         if ( debug )
  660.         {
  661.             int loading[]="Attempting to load file: ";
  662.             TraceNL();
  663.             TraceS(loading);
  664.             TraceNL();
  665.             TraceS(boss_buffer);
  666.             TraceNL();
  667.             TraceS(loading);
  668.             TraceNL();
  669.             TraceS(victory_buffer);
  670.             TraceNL();
  671.         }
  672.        
  673.         int playingBoss[]="Playing Boss Music";
  674.         int playingVictory[]="Playing Victory Music";
  675.         int errLoading[]="Error loading track.";
  676.        
  677.         int LoopClockMethod = _Music_zh__GetDigit(loopBossMusic, 4);
  678.         //Convert mins and seconds.
  679.        
  680.        
  681.         int BossMusicDuration;
  682.         if ( LoopClockMethod == 0 )
  683.         {
  684.             BossMusicDuration = MusicFrames(loopBossMusic); //Convert loopBossMusic into time.
  685.         }
  686.         if ( LoopClockMethod > 0 )
  687.         {
  688.             BossMusicDuration = _Music_zh__GetPartialArg(loopBossMusic,3,8); //Use the full value of loopBossMusic as frame in int.
  689.         }
  690.        
  691.         int VictoryDuration;
  692.         int VictoryDurMethod = _Music_zh__GetDigit(victoryDur, 4);
  693.         if ( VictoryDurMethod == 0 )
  694.         {
  695.             VictoryDuration = MusicFrames(victoryDur); //Convert loopBossMusic into time.
  696.         }
  697.         if ( VictoryDurMethod > 0 )
  698.         {
  699.             VictoryDuration = _Music_zh__GetPartialArg(victoryDur,3,8); //Use the full value of loopBossMusic as frame in int.
  700.         }
  701.        
  702.        
  703.         bool playing = false;
  704.         Waitframes(6); //Wait for enemies to spawn. //Moved up here in 1.3.4
  705.         while(true)
  706.         {
  707.             dat = Game->GetScreenD(curScreen,reg);
  708.             //Waitframes(6); //Wait for enemies to spawn. 1.3.4
  709.             //Set Screen->D[reg] = 1 if the enemy is dead.
  710.             if ( enem == -1 && !Screen->NumNPCs() )
  711.             {
  712.                 Game->SetScreenD(curScreen,reg,1);
  713.             }
  714.             if ( enem == 0 )
  715.             {
  716.                 //Should we do anything special?
  717.                 //A zero value is intended to be used if we don;t want the FFC to set Screen->D to 1.
  718.                 //-1 if we do it based on all enemies being dead.
  719.                 //A positive value trips it if there are no enemies of that ID on the screen.
  720.             }
  721.        
  722.             if ( enem > 0 && !NumNPCsOf(enem) )
  723.             {
  724.                 Game->SetScreenD(curScreen,reg,1);
  725.             }
  726.            
  727.             dat = Game->GetScreenD(curScreen,reg);
  728.                    
  729.             if ( dat == 0 && loopBossMusic == 0 && !playing )
  730.             {
  731.                 Game->PlayEnhancedMusic(boss_buffer, trkBoss);
  732.            
  733.                 if ( ! Game->PlayEnhancedMusic(boss_buffer, trkBoss) )
  734.                 {
  735.                     if ( midiNumber > 0 )
  736.                     {
  737.                         Game->PlayMIDI(midiNumber); //Play MIDI if enhanced music is not available.
  738.                     }
  739.                     else
  740.                     {
  741.                         Game->PlayMIDI(DEFAULT_BOSS_MUSIC);  //Play default if not assigned.
  742.                     }
  743.                        
  744.                 }
  745.  
  746.                 playing = true;
  747.             }
  748.            
  749.             if ( dat == 0 && loopBossMusic > 0 )
  750.             {
  751.                 //set up music loop
  752.                 for ( int q = BossMusicDuration; q >=0; q-- ){
  753.                     if ( q == BossMusicDuration && dat == 0 )
  754.                     {
  755.                        
  756.                         Game->PlayEnhancedMusic(boss_buffer, trkBoss);
  757.                         if ( ! Game->PlayEnhancedMusic(boss_buffer, trkBoss) )
  758.                         {
  759.                             if ( midiNumber > 0 )
  760.                             {
  761.                                 Game->PlayMIDI(midiNumber); //Play MIDI if enhanced music is not available.
  762.                             }
  763.                             else
  764.                             {
  765.                                 Game->PlayMIDI(DEFAULT_BOSS_MUSIC); //Play default if not assigned.
  766.                             }
  767.                         }
  768.                     }
  769.                     if ( enem == -1 && !Screen->NumNPCs() )
  770.                     {
  771.                         Game->SetScreenD(curScreen,reg,1);
  772.                     }
  773.                     if ( enem == 0 )
  774.                     {
  775.                         //Should we do anything special?
  776.                         //A zero value is intended to be used if we don;t want the FFC to set Screen->D to 1.
  777.                         //-1 if we do it based on all enemies being dead.
  778.                         //A positive value trips it if there are no enemies of that ID on the screen.
  779.                     }
  780.                     if ( enem > 0 && !NumNPCsOf(enem) )
  781.                     {
  782.                         Game->SetScreenD(curScreen,reg,1);
  783.                     }
  784.                     dat = Game->GetScreenD(curScreen,reg);
  785.                     if ( dat > 0 )
  786.                     {
  787.                         break;
  788.                     }
  789.                     Waitframe();
  790.                
  791.                 }
  792.             }
  793.            
  794.             if ( dat == 0 && loopBossMusic == 0 && !playing )
  795.             {
  796.  
  797.                 Game->PlayEnhancedMusic(boss_buffer, trkBoss);
  798.                 if ( ! Game->PlayEnhancedMusic(boss_buffer, trkBoss) )
  799.                 {
  800.                     if ( midiNumber > 0 )
  801.                     {
  802.                         Game->PlayMIDI(midiNumber); //Play MIDI if enhanced music is not available.
  803.                     }
  804.                     else
  805.                     {
  806.                         Game->PlayMIDI(DEFAULT_BOSS_MUSIC); //Play default if not assigned.
  807.                     }
  808.                 }
  809.                 playing = true;
  810.                
  811.             }
  812.            
  813.             dat = Game->GetScreenD(curScreen,reg);
  814.             if ( dat > 0 )
  815.             {
  816.                 if ( VictoryDuration > 0 )
  817.                 {
  818.                     Game->PlayEnhancedMusic(victory_buffer, trkVictory);
  819.                     if ( ! Game->PlayEnhancedMusic(victory_buffer, trkVictory) )
  820.                     {
  821.                         if ( victoryMIDI > 0 )
  822.                         {
  823.                             Game->PlayMIDI(victoryMIDI);
  824.                         }
  825.                         else
  826.                         {
  827.                             Game->PlayMIDI(MIDI_DEFEATBOSS);
  828.                         }
  829.                        
  830.                     }
  831.                     for ( int q = 0; q <= VictoryDuration; q++ )
  832.                     {
  833.                         Waitframe(); //Pause for duration of victory music.
  834.                     }
  835.                 }
  836.                 Game->PlayEnhancedMusic(dmapMusicBuffer, dmapTrack);
  837.                 if ( ! Game->PlayEnhancedMusic(dmapMusicBuffer, dmapTrack) )
  838.                 {
  839.                     Game->PlayMIDI(stdMIDI);
  840.                 }
  841.                 Quit();
  842.             }
  843.             Waitframe();
  844.         }
  845.        
  846.     }
  847. }
  848.  
  849. /////////////////
  850. /// FUNCTIONS ///
  851. /////////////////
  852.  
  853. //Pass a float to either of these, to convert raw float into mins and seconds as:
  854. // #####.xxxx = # mins x seconds. Example:
  855. // 00003.0050 = 3 mins, 5 seconds.
  856. // 00001.0012 = 1 minute, 5.2 seconds.
  857.  
  858. //Timers are functional to a total clock of 3579 seconds (59 mins, 39 seconds).
  859.  
  860. int MusicSeconds(float seconds)
  861. {
  862.         int music_seconds = _Music_zh__GetLowArgument(seconds);
  863.         return music_seconds * 6;
  864. }
  865.    
  866. int MusicMinutes(float mins)
  867. {
  868.         int music_minutes = _Music_zh__GetHighArgument(mins);
  869.         return music_minutes * 360;
  870. }
  871.        
  872. //Returns total time in frames, so that ZC understands it.
  873.  
  874. int MusicFrames(float val)
  875. {
  876.     int mins = MusicMinutes(val);
  877.     int seconds = MusicSeconds(val);
  878.     return mins+seconds;
  879. }
  880.  
  881.  
  882. int _Music_zh__GetRemainderAsInt(int v)
  883. {
  884.         int r = (v - (v << 0)) * 10000;
  885.         return r;
  886.     }
  887.  
  888. // This function breaks up the value of an argument into individual digits. It is combined with the function GetDigit below.
  889.  
  890.  
  891. int _Music_zh__GetDigit(int n, int place)
  892. {
  893.     //GetDigit and related functions by Gleeok
  894.     place = Clamp(place, -4, 4);
  895.     if(place < 0){
  896.         n = _Music_zh__GetRemainderAsInt(n);
  897.         place += 4;
  898.     }
  899.  
  900.     int r = ((n / Pow(10, place)) % 10) << 0;
  901.     return r;
  902. }
  903.  
  904. int _Music_zh__GetHighArgument(int arg)
  905. {
  906.     return arg >> 0;
  907. }
  908.  
  909. int _Music_zh__GetLowArgument(int arg)
  910. {
  911.     return (arg - (arg >> 0)) * 10000;
  912. }
  913.  
  914. int _Music_zh__GetPartialArg(int arg, int place, int num)
  915. {
  916.     place = Clamp(place, -4, 4);
  917.     int r;
  918.     int adj = 1;
  919.     for(int i = num-1; i > -1; i--)
  920.     {
  921.         if(place - i < -4) continue;
  922.         r += _Music_zh__GetDigit(arg, place - i) * adj;
  923.         adj *= 10;
  924.     }
  925.     return r;
  926. }
  927.  
  928.  
  929. // Plays enhanced music file by reading the string 'str_id' from Quest->Strings, at a specified track 'track_id'.
  930. // If track_id is positive, it uses this track.
  931. // If track_id is negative, it uses the message string equal to the inverse value (so -20 is string ID 20)
  932. //  to set the track ID.
  933. // Returns true if playing, false otherwise.
  934. bool PlayEnhMusicFile(int str_id, int track_id)
  935. {
  936.     int musicBuffer[256]=" ";
  937.     int track_buffer[256]=" ";
  938.     int q; int trk;
  939.     Game->GetMessage(str_id, musicBuffer);
  940.     for ( q = 0; q < 256; ++q ) { if ( musicBuffer[q] == ' ' ) musicBuffer[q] = 0; } //Kill GetMessage trailing spaces.
  941.     if ( track_id < 0 )
  942.     {
  943.         Game->GetMessage((track_id * -1), track_buffer);
  944.         for ( q = 0; q < 256; ++q )
  945.         {
  946.             if ( track_buffer[q] == ' ' ) track_buffer[q] = 0;
  947.         }   //Kill GetMessage trailing spaces.
  948.         trk = atoi(track_buffer);
  949.     }
  950.     else trk = track_id;
  951.     //Kill GetMessage trailing spaces.
  952.     bool play = Game->PlayEnhancedMusic(musicBuffer, trk);
  953.     return ( play );
  954. }
  955.  
  956. int Legacy_PlayEnhMusicFile(int str_id, int track_id) { if ( PlayEnhMusicFile(str_id, track_id) ) return 1; return 0; }
  957.  
  958. ffc script music_zh_spawnnpc
  959. {
  960.     void run(int nid)
  961.     {
  962.         int pos;
  963.         for ( int q = 0; q < 176; q++ )
  964.         {
  965.             if ( Screen->ComboF[q] == 37 ) pos = q;
  966.         }
  967.         while(1){
  968.             if ( Collision(this) )
  969.             {
  970.                 npc n = Screen->CreateNPC(nid);
  971.                
  972.                 n->X = ComboX(pos); n->Y = ComboY(pos);
  973.                 Quit();
  974.             }
  975.             Waitframe();
  976.            
  977.         }
  978.     }
  979. }
  980.  
  981. void WandSound(int sound)
  982. {
  983.     int itmA = GetEquipmentA();
  984.     int itmB = GetEquipmentB();
  985.     itemdata ida = Game->LoadItemData(itmA);
  986.     itemdata idb = Game->LoadItemData(itmB);
  987.     if ( ( ida->Family == IC_WAND && Link->PressA ) || ( idb->Family == IC_WAND  && Link->PressB ) )
  988.     {
  989.         if ( !NumLWeaponsOf(LW_WAND) ) { Game->PlaySound(sound); }
  990.     }
  991. }
  992.  
  993. global script Music_ZH_Global_Active
  994. {
  995.     void run(){
  996.         while(true){
  997.             WandSound(30);
  998.             Waitdraw();
  999.             Waitframe();
  1000.         }
  1001.     }
  1002. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement