Advertisement
ZoriaRPG

ZScript: Z3 Chest Game FFC v0.4.1 (Tested, Working)

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