Advertisement
ZoriaRPG

ZScript: Z3 Chest Game FFC v0.4.3 (Final)

Nov 25th, 2016
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.47 KB | None | 0 0
  1. ///////////////////////////////
  2. /// Z3 Style Chest Minigame ///
  3. /// v0.4.3 - 25-Nov-2016    ///
  4. /// By: ZoriaRPG            ///
  5. ///////////////////////////////
  6. /// Final Release           ///
  7. ///////////////////////////////
  8.  
  9.  
  10.  
  11. //! The initial combo used for this ffc (on the screen) should be a rupee icon with a numeric cost.
  12. //! The next combo in the list, should be blank.
  13.  
  14.  
  15. //Combos
  16. const int CMB_CHEST_GAME_CLOSED = 896; //The 'closed' chest combo.
  17.             //! This should be combo type 'none', and solid.
  18. const int CMB_CHEST_GAME_OPEN = 897; //The closed chest combo.
  19.             //! This should be the combo immediately after CMB_CHEST_GAME_CLOSED', with a type of 'none'.
  20.  
  21.  
  22. //Strings
  23. const int MSG_CHEST_GAME_RULES = 3; //Screen->Message string that explains the game rules to the player.
  24. const int MSG_CHEST_GAME_OVER = 2; //Screen->Message string for the end of a game round.
  25.  
  26. //Sounds
  27. const int SFX_OPEN_CHEST = 20; //The sound that will play when Link opens a chest, and an item is awarded.
  28. const int SFX_CHEST_GAME_SPECIAL_PRIZE_FANFARE = 27; //The sound to play when the player finds the special item in a chest.
  29. const int SFX_CHEST_GAME_START = 35; //The sound to play when the player starts the game.
  30.  
  31. //Other Settings and Options
  32. const int CHEST_GAME_SCREEN_D_REGISTER = 5; //The Screen->D[index] used to store if the main prize has been awarded.
  33. const int CHEST_GAME_HOLDUP_TYPE = 4; // The type of item hold-up tp use.  4 = LA_HOLD1LAND(one hand); 5 = LA_HOLD2LAND(two hands)
  34. const int CHEST_GAME_ALLOW_REPLAY = 0; //Set to '1' to allow the player to play again without leaving the screen.
  35. const int TIME_INPUT_UP_OPEN_CHEST = 50; //The number of frames of inputting up will open a closed chest.
  36. const int OPEN_CHESTS_FROM_SIDES_OR_ABOVE = 1; //Set to '0' to only permit opening them from the bottom.
  37.  
  38.  
  39.  
  40. // Chest Game FFC
  41.  
  42. //~ //D0: Number of chests to allow the player to open, per play.
  43. //~ //D1: ID of special prize to award.
  44. //~ //D2: Percentage chance of awarding special prize.
  45. //~ //D3: Backup prize, if special prize already awarded (e.g. 100 rupees, instead of a heart piece). Set to '0' to not offer a backup prize.
  46. //~ //D4: Cost per play.
  47. //~ //D5: String for game rules.
  48. //~ //D6: String to play at end of game.
  49. //~ //D7: Set to '1' to allow replaying without leaving the screen.
  50.  
  51.  
  52. ffc script ChestMiniGame{  
  53.     void run(int max_chests_Link_can_open, int specialPrize, int percentMainPrize, int backupPrize, int costPerPlay, int msgRules, int msgEnd, int allowReplay){
  54.  
  55.        
  56.         //Populate with the IDs of prizes to award. Each index is a 1% chance.
  57.         int chestPrizes[]= {    72, 030, 039, 039, 0229,
  58.                     0023, 72, 072, 72, 79, 80, 30,
  59.                     0239, 38, 71, 60, 040, 087,
  60.                     87, 086, 80, 00229, 60, 29,
  61.                     071, 73, 087, 73, 079, 38, 0,
  62.                     17, 80, 40, 23, 0038, 000,
  63.                     038, 24, 060, 71, 2173, 81,
  64.                     170, 029, 00080, 086,
  65.                     79, 070, 070, 00023, 0,
  66.                     02010, 038, 270, 70, 86  };
  67.  
  68.         int initialData = this->Data; //Store the initial combo, to revert, if replay is enabled.
  69.         int chestComboSpots[176];
  70.         int check;
  71.         int cmb;
  72.         int mainprize;
  73.         int timer = TIME_INPUT_UP_OPEN_CHEST;
  74.         bool openchest;
  75.         int has_opened_number_of_chests;
  76.         bool award_main_prize;
  77.         bool gameRunning;
  78.         bool gameOver;
  79.         item i;
  80.         bool giveprize;
  81.         bool awardnormalprize;
  82.        
  83.         if ( msgRules ) Screen->Message(msgRules);
  84.         else Screen->Message(MSG_CHEST_GAME_RULES); //Show the string for the chest game rules.
  85.        
  86.         while(true) {
  87.             if ( max_chests_Link_can_open == has_opened_number_of_chests ) gameOver = true;
  88.             if ( gameOver && ( !CHEST_GAME_ALLOW_REPLAY && !allowReplay ) || allowReplay < 0 ) break;
  89.            
  90.             if ( gameOver && ( CHEST_GAME_ALLOW_REPLAY || allowReplay > 0 ) ) {
  91.                 gameOver = false;
  92.                 gameRunning = false;
  93.                 this->Data = initialData;
  94.                 for ( int q = 0; q < 176; q++ ) {
  95.                     if ( Screen->ComboD[q] == CMB_CHEST_GAME_OPEN ) Screen->ComboD[q] = CMB_CHEST_GAME_CLOSED;
  96.                 }
  97.                 has_opened_number_of_chests = 0;
  98.             }
  99.            
  100.             if ( LinkCollision(this) && Game->Counter[CR_RUPEES] > costPerPlay && Xor(Link->PressA,Link->PressB) && !gameRunning ) {   
  101.                     //If Link collides with the ffc, which should show the cost, and presses a button, start the game.
  102.                 if ( SFX_CHEST_GAME_START ) Game->PlaySound(SFX_CHEST_GAME_START);
  103.                 gameRunning = true;
  104.                 Game->DCounter[CR_RUPEES] -= costPerPlay;
  105.                 this->Data++; //increase to the next combo, removing the cost icon.
  106.             }
  107.                
  108.            
  109.            
  110.             if ( gameRunning ) {
  111.            
  112.                 //Check to see if the combo above Link is a chest.
  113.                
  114.                
  115.                 if ( Link->Dir == DIR_UP ){
  116.                     cmb = Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),Link->Dir) ];
  117.                    
  118.                     if ( cmb == CMB_CHEST_GAME_CLOSED ) {
  119.                         if ( timer && Link->InputUp ) timer--;
  120.                         if ( timer <= 0 ||  Xor(Link->PressA,Link->PressB)) {
  121.                             has_opened_number_of_chests++;
  122.                             if ( SFX_OPEN_CHEST ) Game->PlaySound(SFX_OPEN_CHEST);
  123.                             Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),Link->Dir) ]++;
  124.                            
  125.                             timer = TIME_INPUT_UP_OPEN_CHEST;
  126.                             giveprize = true;
  127.                             Link->InputUp = false;
  128.                         }
  129.                     }
  130.                     else timer = TIME_INPUT_UP_OPEN_CHEST;
  131.                 }
  132.                 else if ( Link->Dir == DIR_DOWN && OPEN_CHESTS_FROM_SIDES_OR_ABOVE ){
  133.                     cmb = Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),Link->Dir) ];
  134.                    
  135.                     if ( cmb == CMB_CHEST_GAME_CLOSED ) {
  136.                         if ( timer > 0 && Link->InputDown ) timer--;
  137.                         if ( timer <= 0 ||  Xor(Link->PressA,Link->PressB) ) {
  138.                             has_opened_number_of_chests++;
  139.                             if ( SFX_OPEN_CHEST ) Game->PlaySound(SFX_OPEN_CHEST);
  140.                             Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),Link->Dir) ]++;
  141.                             timer = TIME_INPUT_UP_OPEN_CHEST;
  142.                             giveprize = true;
  143.                             Link->InputUp = false;
  144.                         }
  145.                     }
  146.                     else timer = TIME_INPUT_UP_OPEN_CHEST;
  147.                 }
  148.                 else if ( Link->Dir == DIR_LEFT && OPEN_CHESTS_FROM_SIDES_OR_ABOVE ) {
  149.                     cmb = Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),Link->Dir) ];
  150.                     if ( cmb == CMB_CHEST_GAME_CLOSED ) {
  151.                         if ( timer > 0 && Link->InputLeft ) timer--;
  152.                         if ( timer <= 0 ||  Xor(Link->PressA,Link->PressB) ) {
  153.                             has_opened_number_of_chests++;
  154.                             if ( SFX_OPEN_CHEST ) Game->PlaySound(SFX_OPEN_CHEST);
  155.                             Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),Link->Dir) ]++;
  156.                             timer = TIME_INPUT_UP_OPEN_CHEST;
  157.                             giveprize = true;
  158.                             Link->InputUp = false;
  159.                         }
  160.                     }
  161.                     else timer = TIME_INPUT_UP_OPEN_CHEST;
  162.                 }
  163.                 else if ( Link->Dir == DIR_RIGHT && OPEN_CHESTS_FROM_SIDES_OR_ABOVE ) {
  164.                     cmb = Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),Link->Dir)];
  165.                     if ( cmb == CMB_CHEST_GAME_CLOSED ) {
  166.                         if ( timer > 0 && Link->InputRight ) timer--;
  167.                         if ( timer <= 0 ||  Xor(Link->PressA,Link->PressB) ) {
  168.                             has_opened_number_of_chests++;
  169.                             if ( SFX_OPEN_CHEST ) Game->PlaySound(SFX_OPEN_CHEST);
  170.                             Screen->ComboD[ ___AdjacentCombo(ComboAt(Link->X+8, Link->Y+8),Link->Dir) ]++;
  171.                             timer = TIME_INPUT_UP_OPEN_CHEST;
  172.                             giveprize = true;
  173.                             Link->InputUp = false;
  174.                         }
  175.                     }
  176.                     else timer = TIME_INPUT_UP_OPEN_CHEST;
  177.                    
  178.                 }
  179.                
  180.            
  181.            
  182.                 if ( giveprize ) {
  183.                    
  184.                     check = Rand(1,100);  //Make a check, to use for determining if the main prize should e awarded.
  185.                    
  186.                     if ( check <= percentMainPrize ) award_main_prize = true; //If that check passes, then we will award the main prize.
  187.                    
  188.                     if ( check > percentMainPrize ) { awardnormalprize = true; check = Rand(0,SizeOfArray(chestPrizes)); }//Otherwise, reuse that var, and make a new check to determine
  189.                                                         //the prize to award from the table.
  190.                     int itm;
  191.        
  192.                     if ( !awardnormalprize && award_main_prize && !Screen->D[CHEST_GAME_SCREEN_D_REGISTER] ) { //The main prize has not been awarded, and has been randomly chosen.
  193.                         Game->PlaySound(SFX_CHEST_GAME_SPECIAL_PRIZE_FANFARE); //Play the fanfare...
  194.                         i = Screen->CreateItem(specialPrize);   //Assign the pointer, and make the item.
  195.                         itm = specialPrize; //Set the value of the item ID to a var so that we can use it for holding it up.
  196.                     }
  197.                     if ( !awardnormalprize && award_main_prize && Screen->D[CHEST_GAME_SCREEN_D_REGISTER] && backupPrize ) {    //The main prize has already been awarded, so recheck.
  198.                         Game->PlaySound(SFX_CHEST_GAME_SPECIAL_PRIZE_FANFARE);  //Play the special award fanfare...
  199.                         i = Screen->CreateItem(backupPrize);    //Assign the pointer, and make the item.
  200.                         itm = backupPrize;  //Set the value of the item ID to a var so that we can use it for holding it up.
  201.                     }
  202.                     if ( awardnormalprize && check ) {  //Otherwise, if the check to award a special prize did not pass..
  203.                         Game->PlaySound(SFX_OPEN_CHEST); //otherwise, play the default.
  204.                         i = Screen->CreateItem(chestPrizes[check]); //Award a normal prize, from the list.
  205.                         itm = chestPrizes[check]; //Set the value of the item ID to a var so that we can use it for holding it up.
  206.                    
  207.                     }
  208.                     if ( check ) {  //if we're awarding a prize...
  209.                         i -> X = Link->X;
  210.                         i -> Y = Link->Y;
  211.                         if ( CHEST_GAME_HOLDUP_TYPE ) {  //If the setting to hold the item overhead is enabled...
  212.                             Link->Action = CHEST_GAME_HOLDUP_TYPE; //Hold the item overhead, using the value of that setting.
  213.                             Link->HeldItem =  itm;
  214.                         }
  215.                        
  216.                         if ( award_main_prize ) { Screen->D[CHEST_GAME_SCREEN_D_REGISTER] = 1; award_main_prize = false; }  //Set the register so that Link cannot collect the special prize again.
  217.                        
  218.                         giveprize = false;
  219.                         while( Link->Action == LA_HOLD1LAND ) Waitframe();
  220.                     }
  221.                     else Remove(i); //if check is zero, remove the item pointer.
  222.                             //This allows chances of getting nothing at all.
  223.                 }
  224.                
  225.                 if ( has_opened_number_of_chests >= max_chests_Link_can_open ) {
  226.                     gameOver = true;
  227.                     gameRunning = false;
  228.                     if ( msgEnd ) Screen->Message(msgEnd);
  229.                     else Screen->Message(MSG_CHEST_GAME_OVER);
  230.                    
  231.                 }
  232.  
  233.             }
  234.        
  235.             Waitframe();
  236.         }
  237.         //If we reach here, then the chest game is over.
  238.         this->Data = 0;
  239.         this->Script = 0;
  240.         Quit();
  241.     }
  242.    
  243.     //Constants for AdjacentCombo()
  244.     //This now uses DIR_* constants, so you can do AdjacentCombo(cmb,Link->Dir)
  245.     //Returns the Nth combo index of a combo based on a central point, and a direction.
  246.     //For example, combo 22 + COMBO_UPRIGHT returns '7',
  247.     //as combo 7 is to the upper-right of combo 22.
  248.     int ___AdjacentCombo(int cmb, int dir){
  249.         int combooffsets[13]={-0x10, 0x10, -1, 1, -0x11, -0x0F, 0x0F, 0x11};
  250.         if ( cmb % 16 == 0 ) combooffsets[9] = 1;
  251.         if ( (cmb & 15) == 1 ) combooffsets[10] = 1;
  252.         if ( cmb < 0x10 ) combooffsets[11] = 1; //if it's the top row
  253.         if ( cmb > 0x9F ) combooffsets[12] = 1; //if it's on the bottom row
  254.         if ( combooffsets[9] && ( dir == CMB_LEFT || dir == CMB_UPLEFT || dir == CMB_DOWNLEFT || dir == CMB_LEFTUP ) ) return 0; //if the left columb
  255.         if ( combooffsets[10] && ( dir == CMB_RIGHT || dir == CMB_UPRIGHT || dir == CMB_DOWNRIGHT ) ) return 0; //if the right column
  256.         if ( combooffsets[11] && ( dir == CMB_UP || dir == CMB_UPRIGHT || dir == CMB_UPLEFT || dir == CMB_LEFTUP ) ) return 0; //if the top row
  257.         if ( combooffsets[12] && ( dir == CMB_DOWN || dir == CMB_DOWNRIGHT || dir == CMB_DOWNLEFT ) ) return 0; //if the bottom row
  258.         else if ( cmb >= 0 && cmb <= 176 ) return cmb + combooffsets[dir];
  259.         else return -1;
  260.     }  
  261.  
  262. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement