Advertisement
ZoriaRPG

Moosh's Bottle Script + Bugfixes and Improvements by Z.

May 25th, 2017
306
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 26.34 KB | None | 0 0
  1. //The blue potion is bugged. It continues to freeze the screen long after it finishes filling Links HP and MP.
  2. //Clearly a maths issue. -Z
  3.  
  4. //! Fixed the blue potion bug. -Z
  5. //! Fixed the water trigger bug. -Z
  6.  
  7. import "std.zh"
  8. import "ffcscript.zh"
  9.  
  10. //X---------------------------X
  11. //|  Screen Freeze Constants  |
  12. //X---------------------------X
  13.  
  14. const int FFC_SFA = 31; //FFC used for screen freeze A
  15. const int FFC_SFB = 32; //FFC used for screen freeze B
  16. const int CMB_SFA = 882; //Combo used for screen freeze A
  17. const int CMB_SFB = 883; //Combo used for screen freeze B
  18.  
  19.  
  20. //X--------------------------X
  21. //|  Empty Bottle Functions  |
  22. //X--------------------------X
  23.  
  24. const int BOTTLE_SETTING_NO_WATER = 0; //Set to 1 if water shouldn't be bottleable
  25.  
  26. //X--------------------------------------------------------X
  27. //|  These constants don't need to be changed.             |
  28. //|  They just define various states of the empty bottle.  |
  29. //|  BS_ constants are also used for  the potion filling   |
  30. //|  pickup item script. Look here to see what to set D2   |
  31. //|  to for that.                                          |
  32. //X--------------------------------------------------------X
  33. //                                                         |
  34. const int BS_EMPTY = 0; //                                 |
  35. const int BS_POTIONRED = 1; //                             |
  36. const int BS_POTIONGREEN = 2; //                           |
  37. const int BS_POTIONBLUE = 3; //                            |
  38. const int BS_WATER = 4; //                                 |
  39. const int BS_FAIRY = 5; //                                 |
  40. const int BS_BEE = 6; //                                   |
  41. //                                                         |
  42. const int BSI_BOTTLEUSED = 4; //                           |
  43. const int BSI_BOTTLETIMER = 5; //                          |
  44. const int BSI_OLDHP = 6; //                                |
  45. const int BSI_OLDMP = 7; //                                |
  46. const int BSI_FAIRYTIMER = 8; //                           |
  47. const int BSI_FAIRYREVIVE = 9; //                          |
  48. //                                                         |
  49. //---------------------------------------------------------
  50.  
  51. //! I believe we need to set these STATES to fill the bottles, as well, which is not in the instructions.
  52. // Moosh says:
  53. //D0 is the string to play and D1 is what type of potion it is (Red = 1, Green = 2, Blue = 3).
  54. // AND
  55. // 4 - water, 5 = faerie, 6 = bee. -Z
  56.  
  57. //D3 of the FFC must be set to 1 for __ANY__ refill item, not merely for potions.
  58.  
  59.  
  60.  
  61.  
  62.  
  63. const int REDPOTION_HEARTS = 8; //Hearts the red potion heals
  64. const int GREENPOTION_MP = 256; //MP the green potion restores
  65. const int BLUEPOTION_HEARTS = 16; //Hearts the blue potion heals
  66. const int BLUEPOTION_MP = 256; //MP the blue potion restores
  67.  
  68. const int LW_WATER = 31; //LWeapon type used for bottled water. Script 1 by default
  69. const int SPR_BOTTLEWATER = 88; //Sprite used for bottled water
  70. const int SFX_BOTTLEWATER = 55; //Sound when water is dumped out
  71.  
  72. const int FAIRY_HEARTS = 6; //Hearts healed by a fairy
  73. const int CMB_FAIRY = 889; //Fairy combo
  74. const int CS_FAIRY = 8; //Fairy cset
  75. const int SFX_FAIRY = 44; //Sound that plays when a fairy appears
  76.  
  77. const int IC_BOTTLE = 67; //Item class used for bottles. Custom 1 by default.
  78.  
  79.  
  80. const int TIL_BOTTLE = 15980; //First of the tiles used for the bottle items. Should come in four identical rows.
  81.                               //Tile order in each row should go as such:
  82.                               //Empty, Empty, Red Potion, Green Potion, Blue Potion, Water, Fairy, Bee
  83.  
  84. const int I_BOTTLE1 = 123; //Item ID for the first bottle (Level 1)
  85. const int I_BOTTLE2 = 124; //Item ID for the second bottle (Level 2)
  86. const int I_BOTTLE3 = 125; //Item ID for the second bottle (Level 3)
  87. const int I_BOTTLE4 = 126; //Item ID for the second bottle (Level 4)
  88. const int I_WATERBOTTLE = 130; //Item for bottle water pickup
  89. const int I_FAIRYBOTTLE = 131; //Item for bottle fairy pickup
  90. const int I_BEEBOTTLE = 132; //Item for bottle bee pickup
  91.  
  92. const int FREQ_HEARTREFILL = 8; //Frequency in frames at which potions/fairies restore hearts
  93. const int SFX_HEARTREFILL = 22; //Sound when potion/fairy restores a heart
  94. const int FREQ_MAGICSOUND = 8; //Frequency in frames where the magic refill sound plays
  95. const int SFX_MAGICREFILL = 49; //Magic refill sound
  96. const int SFX_ERROR = 36; //Error sound
  97.  
  98. const int TIL_BOTTLESWING = 16306; //Tile of a right facing open bottle used when trying to catch something
  99. const int CS_BOTTLESWING = 0; //CSet of the swinging bottle
  100. const int SFX_BOTTLESWING = 41; //Sound used for the bottle being swung
  101.  
  102. const int CMB_BEE = 888; //Combo used for the bee
  103. const int CS_BEE = 8; //CSet used for the bee
  104. const int SFX_BEE = 43; //SFX used for the bee
  105. const int LW_BEE = 32; //Lweapon used for the bee (Script 2 by default)
  106. const int EW_BEE = 32; //Eweapon used for the bee (Script 2 by default)
  107. const int DAMAGE_BEE = 4; //Damage the bee deals
  108. const int FFCM_BEE_SELFDESTRUCT = 0; //FFC misc used to tell the bee to disappear
  109.  
  110. const int STR_CANTAFFORD = 1; //Message for when you can't afford an item
  111. const int STR_NOBOTTLE = 2; //Message for when you don't have a bottle to store a potion in
  112.  
  113. const int C_WHITE = 0x01; //The color white
  114. const int C_BLACK = 0x0F; //The color black
  115.  
  116. //I suggest making the distance to the ffc a setting, and displaying some kind of icon when Link is close enough to buy any item. -Z
  117. //I further suggest making the ffc draw the price to a LAYER set by a CONSTANT. The price, drawn over Link, and the item, drawn UNDER
  118. //Link, is a bit, off.
  119.  
  120. const int FFC_BOTTLE_SHOP_PRICE_LAYER = 1; //Layer for drawing the price to the screen. -Z
  121. const int FFC_SHOP_DISTANCE = 14; //Distance from FFC. -Z
  122.  
  123.  
  124. const int ITEMSHOP_BLANK_FFCS_DRAW_ITEMS = 1; //Set to 1 to use the item tile instead of the ffc combo.
  125. const int ITEMSHOP_BLANK_COMBO = 896; //A blank combo.
  126. const int ITEMSHOP_VISIBLE_COMBO = 897; //A generic combo used to place ffcs visually.
  127.  
  128. //The icon that tells the player that they can buy an item by pressing a button.
  129. const int TILE_SHOP_BUTTON = 16140; //Indicator that you can press L or R.
  130. const int TILE_SHOP_BUTTON_Y_OFFSET = -4; //Y Offset Component for indicator that you can press L or R.
  131. const int TILE_SHOP_BUTTON_X_OFFSET = 14;  //Y Offset Component for indicator that you can press L or R.
  132. const int TILE_SHOP_BUTTON_CSET = 0;
  133. const int TILE_SHOP_BUTTON_LAYER = 6;
  134. const int TILE_SHOP_BUTTON_XSCALE = -1;
  135. const int TILE_SHOP_BUTTON_YSCALE = -1;
  136. const int TILE_SHOP_BUTTON_OPACITY = 128; //128 for opaque, 64 for translucent.
  137.  
  138. //Set one and ONLY ONE, of these to '1' to indicate which button is used to buy an item.
  139. const int SHOP_BUY_BUTTON_A = 0;
  140. const int SHOP_BUY_BUTTON_B = 0;
  141. const int SHOP_BUY_BUTTON_L = 0;
  142. const int SHOP_BUY_BUTTON_R = 1;
  143. const int SHOP_BUY_BUTTON_EX1 = 0;
  144. const int SHOP_BUY_BUTTON_EX2 = 0;
  145. const int SHOP_BUY_BUTTON_EX3 = 0;
  146. const int SHOP_BUY_BUTTON_EX4 = 0;
  147.  
  148. //Set one and ONLY ONE, of these to '1' to indicate which button is used to buy an item.
  149. const int SHOP_LOOK_BUTTON_A = 0;
  150. const int SHOP_LOOK_BUTTON_B = 0;
  151. const int SHOP_LOOK_BUTTON_L = 1;
  152. const int SHOP_LOOK_BUTTON_R = 0;
  153. const int SHOP_LOOK_BUTTON_EX1 = 0;
  154. const int SHOP_LOOK_BUTTON_EX2 = 0;
  155. const int SHOP_LOOK_BUTTON_EX3 = 0;
  156. const int SHOP_LOOK_BUTTON_EX4 = 0;
  157.  
  158. const int SFX_SHOP_BUYITEM = 20;
  159.  
  160. int BottleState[12]; //0-3: States of bottles, 4: Bottle used,
  161.                      //5: Potion timer, 6: OldHP, 7: OldMP
  162.  
  163.  
  164. //This function should be called at the beginning of your global and
  165. //refreshes the graphics for the bottles.
  166. void RefreshBottles(){
  167.     for(int i=0; i<4; i++){
  168.         CopyTile(TIL_BOTTLE+20*i+1+BottleState[i], TIL_BOTTLE+20*i);
  169.     }
  170. }
  171.  
  172.  
  173. int UsingEmptyBottle(){
  174.     if(Link->PressA){
  175.         int id = GetEquipmentA();
  176.         if(id>0){
  177.             itemdata A = Game->LoadItemData(id);
  178.             if(A->Family==IC_BOTTLE)
  179.                 return A->Level-1;
  180.         }
  181.     }
  182.     else if(Link->PressB){
  183.         int id = GetEquipmentB();
  184.         if(id>0){
  185.             itemdata B = Game->LoadItemData(id);
  186.             if(B->Family==IC_BOTTLE)
  187.                 return B->Level-1;
  188.         }
  189.     }
  190.     return -1;
  191. }
  192.  
  193.  
  194. bool CanFillBottle(){
  195.     int bottles[4] = {I_BOTTLE1, I_BOTTLE2, I_BOTTLE3, I_BOTTLE4};
  196.     for(int i=0; i<4; i++){
  197.         if(Link->Item[bottles[i]]&&BottleState[i]==BS_EMPTY)
  198.             return true;
  199.     }
  200.     return false;
  201. }
  202.  
  203. int FillBottle(int state){
  204.     int bottles[4] = {I_BOTTLE1, I_BOTTLE2, I_BOTTLE3, I_BOTTLE4};
  205.     for(int i=0; i<4; i++){
  206.         if(Link->Item[bottles[i]]&&BottleState[i]==BS_EMPTY){
  207.             BottleState[i] = state;
  208.             RefreshBottles();
  209.             return i;
  210.         }
  211.     }
  212. }
  213.  
  214. int HasFairy(){
  215.     int bottles[4] = {I_BOTTLE1, I_BOTTLE2, I_BOTTLE3, I_BOTTLE4};
  216.     for(int i=0; i<4; i++){
  217.         if(Link->Item[bottles[i]]&&BottleState[i]==BS_FAIRY)
  218.             return i;
  219.     }
  220.     return -1;
  221. }
  222.  
  223. //This function goes in the while loop of your global script before waitdraw
  224. void EmptyBottleGlobal(){
  225.     int bottle = BottleState[BSI_BOTTLEUSED];
  226.     if(BottleState[BSI_BOTTLETIMER]>0){
  227.         if(BottleState[bottle]==BS_POTIONRED){
  228.             if(BottleState[BSI_BOTTLETIMER]%FREQ_HEARTREFILL==0){
  229.                 Link->HP += 16;
  230.                 Game->PlaySound(SFX_HEARTREFILL);
  231.                 if(Link->HP>=Link->MaxHP){
  232.                     BottleState[BSI_BOTTLETIMER] = 0;
  233.                 }
  234.             }
  235.         }
  236.         else if(BottleState[bottle]==BS_POTIONGREEN){
  237.             Link->MP += 2;
  238.             if(BottleState[BSI_BOTTLETIMER]%FREQ_MAGICSOUND==0)
  239.                 Game->PlaySound(SFX_MAGICREFILL);
  240.             if(Link->MP>=Link->MaxMP){
  241.                 BottleState[BSI_BOTTLETIMER] = 0;
  242.             }
  243.         }
  244.         else if(BottleState[bottle]==BS_POTIONBLUE){
  245.             if(BottleState[BSI_BOTTLETIMER]%FREQ_HEARTREFILL==0&&Link->HP<BottleState[BSI_OLDHP]+BLUEPOTION_HEARTS*16&&Link->HP<Link->MaxHP){
  246.                 Link->HP += 16;
  247.                 Game->PlaySound(SFX_HEARTREFILL);
  248.             }
  249.             if(Link->MP<BottleState[BSI_OLDMP]+BLUEPOTION_MP&&Link->MP<Link->MaxMP){
  250.                 if(BottleState[BSI_BOTTLETIMER]%FREQ_MAGICSOUND==0)
  251.                     Game->PlaySound(SFX_MAGICREFILL);
  252.                 Link->MP += 2;
  253.             }
  254.             if(Link->HP>=Link->MaxHP&&Link->MP>=Link->MaxMP){
  255.                 BottleState[BSI_BOTTLETIMER] = 0;
  256.             }
  257.         }
  258.         else if(BottleState[bottle]==BS_FAIRY){
  259.             if(BottleState[BSI_BOTTLETIMER]<2&&BottleState[BSI_FAIRYTIMER]<120)
  260.                 BottleState[BSI_BOTTLETIMER] = 2;
  261.             BottleState[BSI_FAIRYTIMER]++;
  262.             int X = Link->X+VectorX(16*(BottleState[BSI_FAIRYTIMER]/120), BottleState[BSI_FAIRYTIMER]*8);
  263.             int Y = Link->Y+VectorY(8*(BottleState[BSI_FAIRYTIMER]/120), BottleState[BSI_FAIRYTIMER]*8)-BottleState[BSI_FAIRYTIMER]/8;
  264.             if(BottleState[BSI_FAIRYREVIVE]==1){
  265.                 if(BottleState[BSI_FAIRYTIMER]<10||BottleState[BSI_FAIRYTIMER]>110)
  266.                     Screen->Rectangle(6, 0, 0, 256, 176, C_BLACK, 1, 0, 0, 0, true, 64);
  267.                 else
  268.                     Screen->Rectangle(6, 0, 0, 256, 176, C_BLACK, 1, 0, 0, 0, true, 128);
  269.                 Screen->FastTile(6, Link->X+Link->DrawXOffset, Link->Y+Link->DrawYOffset, Link->Tile, 6, 128);
  270.             }
  271.             if(BottleState[BSI_FAIRYTIMER]<80||BottleState[BSI_FAIRYTIMER]%2==0)
  272.                 Screen->FastCombo(6, X, Y, CMB_FAIRY, CS_FAIRY, 128);
  273.             if(BottleState[BSI_BOTTLETIMER]%FREQ_HEARTREFILL==0&&Link->HP<Link->MaxHP){
  274.                 Link->HP += 16;
  275.                 Game->PlaySound(SFX_HEARTREFILL);
  276.             }
  277.         }
  278.         BottleState[BSI_BOTTLETIMER]--;
  279.         NoAction();
  280.         if(BottleState[BSI_BOTTLETIMER]<=0 || ( Link->HP >= Link->MaxHP && Link->MP >= Link->MaxMP ) ){
  281.             //This countdown is bugged. -Z
  282.             BottleState[bottle] = BS_EMPTY;
  283.             BottleState[BSI_BOTTLEUSED] = -1;
  284.             RefreshBottles();
  285.             Screen_Unfreeze();
  286.         }
  287.     }
  288.     else{
  289.         bottle = UsingEmptyBottle();
  290.         if(bottle>-1){
  291.             if(BottleState[bottle]==BS_EMPTY){
  292.                 int scriptname[] = "Bottle_Empty";
  293.                 int scriptid = Game->GetFFCScript(scriptname);
  294.                 int Args[8] = {bottle};
  295.                 RunFFCScript(scriptid, Args);
  296.             }
  297.             else if(BottleState[bottle]==BS_POTIONRED){
  298.                 if(Link->HP==Link->MaxHP){
  299.                     Game->PlaySound(SFX_ERROR);
  300.                 }
  301.                 else{
  302.                     BottleState[BSI_BOTTLEUSED] = bottle;
  303.                     BottleState[BSI_BOTTLETIMER] = FREQ_HEARTREFILL*REDPOTION_HEARTS;
  304.                     Screen_Freeze();
  305.                 }
  306.             }
  307.             else if(BottleState[bottle]==BS_POTIONGREEN){
  308.                 if(Link->MP==Link->MaxMP){
  309.                     Game->PlaySound(SFX_ERROR);
  310.                 }
  311.                 else{
  312.                     BottleState[BSI_BOTTLEUSED] = bottle;
  313.                     BottleState[BSI_BOTTLETIMER] = GREENPOTION_MP/2;
  314.                     Screen_Freeze();
  315.                 }
  316.             }
  317.             else if(BottleState[bottle]==BS_POTIONBLUE){
  318.                 if(Link->HP==Link->MaxHP&&Link->MP==Link->MaxMP){
  319.                     Game->PlaySound(SFX_ERROR);
  320.                 }
  321.                 else{
  322.                     BottleState[BSI_BOTTLEUSED] = bottle;
  323.                     //I used Max() here to fix a bug where the blue potion had super-long lag. -Z
  324.                     BottleState[BSI_BOTTLETIMER] = Max(FREQ_HEARTREFILL*REDPOTION_HEARTS, GREENPOTION_MP/2); //FREQ_HEARTREFILL*99; //WHat ? *99?!
  325.                     BottleState[BSI_OLDHP] = Link->HP;
  326.                     BottleState[BSI_OLDMP] = Link->MP;
  327.                     Screen_Freeze();
  328.                 }
  329.             }
  330.             else if(BottleState[bottle]==BS_WATER){
  331.                 Link->Action = LA_ATTACKING;
  332.                 lweapon l = CreateLWeaponAt(LW_WATER, Link->X+InFrontX(Link->Dir, 0), Link->Y+InFrontY(Link->Dir, 0));
  333.                 l->UseSprite(SPR_BOTTLEWATER);
  334.                 l->DeadState = l->ASpeed*l->NumFrames;
  335.                 l->CollDetection = false;
  336.                 Game->PlaySound(SFX_BOTTLEWATER);
  337.                 BottleState[bottle] = BS_EMPTY;
  338.                 RefreshBottles();
  339.             }
  340.             else if(BottleState[bottle]==BS_FAIRY){
  341.                 if(Link->HP==Link->MaxHP){
  342.                     Game->PlaySound(SFX_ERROR);
  343.                 }
  344.                 else{
  345.                     BottleState[BSI_BOTTLEUSED] = bottle;
  346.                     BottleState[BSI_BOTTLETIMER] = FREQ_HEARTREFILL*FAIRY_HEARTS;
  347.                     BottleState[BSI_FAIRYTIMER] = 0;
  348.                     BottleState[BSI_FAIRYREVIVE] = 0;
  349.                     Game->PlaySound(SFX_FAIRY);
  350.                     Screen_Freeze();
  351.                 }
  352.             }
  353.             else if(BottleState[bottle]==BS_BEE){
  354.                 int scriptname[] = "Bottle_Bee";
  355.                 int scriptid = Game->GetFFCScript(scriptname);
  356.                 int vars[8] = {1};
  357.                 RunFFCScript(scriptid, vars);
  358.                 BottleState[bottle] = BS_EMPTY;
  359.                 RefreshBottles();
  360.             }
  361.         }
  362.         int fairy = HasFairy();
  363.         if(Link->HP<=0&&fairy>-1){
  364.             Link->HP = 1;
  365.             BottleState[BSI_BOTTLEUSED] = fairy;
  366.             BottleState[BSI_BOTTLETIMER] = FREQ_HEARTREFILL*FAIRY_HEARTS;
  367.             BottleState[BSI_FAIRYTIMER] = 0;
  368.             BottleState[BSI_FAIRYREVIVE] = 1;
  369.             Game->PlaySound(SFX_FAIRY);
  370.             Screen_Freeze();
  371.         }
  372.     }
  373. }
  374.  
  375.  
  376. ///! NOTE to viewers, I am not adding sounds to this default uest, but you should surely do that.
  377.  
  378. //X-------------------------------X
  379. //|  Empty Bottle Action Scripts  |
  380. //X-------------------------------X
  381.  
  382.  
  383.  
  384. //I'm pretty sure that the script will change the bottle tile based on the ffc arg, so why do we waste three items here,
  385. //for reg, green, and blue potions? -Z
  386.  
  387. ffc script Bottle_Empty{
  388.     void run(int bottleid){
  389.         int Angle = 0;
  390.         if(Link->Dir==DIR_UP)
  391.             Angle = -90;
  392.         else if(Link->Dir==DIR_DOWN)
  393.             Angle = 90;
  394.         else if(Link->Dir==DIR_LEFT)
  395.             Angle = 180;
  396.         Game->PlaySound(SFX_BOTTLESWING);
  397.         Link->Action = LA_ATTACKING;
  398.         int Collected = 0;
  399.         for(int i=-45; i<45; i+=10){
  400.             int X = Link->X+VectorX(12, Angle+i);
  401.             int Y = Link->Y+VectorY(12, Angle+i);
  402.             Screen->DrawTile(2, X, Y, TIL_BOTTLESWING, 1, 1, CS_BOTTLESWING, -1, -1, X, Y, Angle+i+90, 0, true, 128);
  403.             if(Collected==0||Collected==BS_WATER){
  404.                 if(OnWater(X+8, Y+8)&&Collected==0&&BOTTLE_SETTING_NO_WATER==0){
  405.                     Collected = BS_WATER;
  406.                 }
  407.                 for(int j=1; j<=Screen->NumItems(); j++){
  408.                     item itm = Screen->LoadItem(j);
  409.                     if(itm->ID==I_FAIRY||itm->ID==I_FAIRYSTILL){
  410.                         if(RectCollision(itm->X+itm->HitXOffset, itm->Y+itm->HitYOffset, itm->X+itm->HitXOffset+itm->HitWidth, itm->Y+itm->HitYOffset+itm->HitHeight, X+4, Y+4, X+11, Y+11)){
  411.                             Collected = BS_FAIRY;
  412.                             Remove(itm);
  413.                             break;
  414.                         }
  415.                     }
  416.                 }
  417.                 for(int j=1; j<=32; j++){
  418.                     ffc f = Screen->LoadFFC(j);
  419.                     int scriptname[] = "Bottle_Bee";
  420.                     int scriptid = Game->GetFFCScript(scriptname);
  421.                     if(f->Script==scriptid){
  422.                         if(RectCollision(X+4, Y+4, X+11, Y+11, f->X+4, f->Y+4, f->X+11, f->Y+11)){
  423.                             Collected = BS_BEE;
  424.                             f->Misc[FFCM_BEE_SELFDESTRUCT] = 1;
  425.                         }
  426.                     }
  427.                 }
  428.             }
  429.             WaitNoAction();
  430.         }
  431.         if(Collected==BS_WATER){
  432.             BottleState[bottleid] = BS_WATER;
  433.             RefreshBottles();
  434.             item itm = CreateItemAt(I_WATERBOTTLE, Link->X, Link->Y);
  435.             itm->Pickup = IP_HOLDUP;
  436.         }
  437.         else if(Collected==BS_FAIRY){
  438.             BottleState[bottleid] = BS_FAIRY;
  439.             RefreshBottles();
  440.             item itm = CreateItemAt(I_FAIRYBOTTLE, Link->X, Link->Y);
  441.             itm->Pickup = IP_HOLDUP;
  442.         }
  443.         else if(Collected==BS_BEE){
  444.             BottleState[bottleid] = BS_BEE;
  445.             RefreshBottles();
  446.             item itm = CreateItemAt(I_BEEBOTTLE, Link->X, Link->Y);
  447.             itm->Pickup = IP_HOLDUP;
  448.         }
  449.         WaitNoAction(10);
  450.     }
  451.     bool OnWater(int x, int y){
  452.         int ct = Screen->ComboT[ComboAt(x, y)];
  453.         if(ct==CT_WATER||ct==CT_SHALLOWWATER)
  454.             return true;
  455.         return false;
  456.     }
  457. }
  458.  
  459.  
  460.  
  461.  
  462. //! Moosh, these constants would be better ALL at the TOP of the script file. -Z
  463.  
  464. ffc script Bottle_Bee{
  465.     void run(int friendly){
  466.         this->Data = CMB_BEE;
  467.         this->CSet = CS_BEE;
  468.         if(friendly==1){
  469.             this->X = Link->X;
  470.             this->Y = Link->Y;
  471.         }
  472.         int i; int j; int k;
  473.         int X = this->X;
  474.         int Y = this->Y;
  475.         lweapon lh;
  476.         eweapon eh;
  477.         int Lifespan = Rand(900, 1200);
  478.         for(i=0; i<40; i++){
  479.             Y -= 0.5;
  480.             this->X = X;
  481.             this->Y = Y;
  482.             Waitframe();
  483.         }
  484.         while(Lifespan>0){
  485.             int Angle;
  486.             if(friendly==1){
  487.                 int Tx = -1000;
  488.                 int Ty = -1000;
  489.                 int Dist = 1000;
  490.                 for(i=1; i<=Screen->NumNPCs(); i++){
  491.                     npc n = Screen->LoadNPC(i);
  492.                     if(Distance(X+8, Y+8, CenterX(n), CenterY(n))<Dist){
  493.                         Dist = Distance(X+8, Y+8, CenterX(n), CenterY(n));
  494.                         Tx = CenterX(n)-8;
  495.                         Ty = CenterY(n)-8;
  496.                     }
  497.                 }
  498.                 Angle = Angle(X, Y, Tx, Ty);
  499.                 if(Screen->NumNPCs()==0)
  500.                     Angle = Angle(X, Y, Link->X, Link->Y);
  501.             }
  502.             else{
  503.                 if(Distance(Link->X, Link->Y, X, Y)<80&&Rand(2)==0)
  504.                     Angle = Angle(X, Y, Link->X, Link->Y);
  505.                 else
  506.                     Angle = Rand(360);
  507.             }
  508.             k = Rand(32, 48);
  509.             for(i=0; i<k; i++){
  510.                 Lifespan--;
  511.                 j = (j+1)%360;
  512.                 if(j%30==0)
  513.                     Game->PlaySound(SFX_BEE);
  514.                 X = Clamp(X+VectorX(2, Angle), -16, 256);
  515.                 Y = Clamp(Y+VectorY(2, Angle), -16, 176);
  516.                 this->X = X;
  517.                 this->Y = Y;
  518.                 if(friendly==1){
  519.                     if(lh->isValid()){
  520.                         lh->X = X;
  521.                         lh->Y = Y;
  522.                     }
  523.                     else{
  524.                         lh = CreateLWeaponAt(LW_BEE, X, Y);
  525.                         lh->HitXOffset = 4;
  526.                         lh->HitYOffset = 4;
  527.                         lh->HitWidth = 8;
  528.                         lh->HitHeight = 8;
  529.                         lh->DrawYOffset = -1000;
  530.                         lh->Dir = 8;
  531.                         lh->Damage = DAMAGE_BEE;
  532.                     }
  533.                 }
  534.                 else{
  535.                     if(eh->isValid()){
  536.                         eh->X = X;
  537.                         eh->Y = Y;
  538.                     }
  539.                     else{
  540.                         eh = CreateEWeaponAt(EW_BEE, X, Y);
  541.                         eh->HitXOffset = 4;
  542.                         eh->HitYOffset = 4;
  543.                         eh->HitWidth = 8;
  544.                         eh->HitHeight = 8;
  545.                         eh->DrawYOffset = -1000;
  546.                         eh->Dir = 8;
  547.                         eh->Damage = DAMAGE_BEE;
  548.                     }
  549.                 }
  550.                 if(this->Misc[FFCM_BEE_SELFDESTRUCT]==1){
  551.                     if(lh->isValid())
  552.                         lh->DeadState = 0;
  553.                     if(eh->isValid())
  554.                         eh->DeadState = 0;
  555.                     this->Data = 0;
  556.                     this->CSet = 0;
  557.                     Quit();
  558.                 }
  559.                 Waitframe();
  560.             }
  561.         }
  562.         if(lh->isValid())
  563.             lh->DeadState = 0;
  564.         if(eh->isValid())
  565.             eh->DeadState = 0;
  566.         this->Data = 0;
  567.         this->CSet = 0;
  568.         for(i=0; i<40; i++){
  569.             if(i%2==0)
  570.                 Screen->FastCombo(2, X, Y, CMB_BEE, CS_BEE, 128);
  571.             Waitframe();
  572.         }
  573.     }
  574. }
  575.  
  576.  
  577. //X----------------------------X
  578. //|  Other Associated Scripts  |
  579. //X----------------------------X
  580.  
  581. item script PotionFill{
  582.     void run(int str, int state){
  583.         FillBottle(state);
  584.         Screen->Message(str);
  585.     }
  586. }
  587.  
  588. //! Now, let's see if Moosh automatically set the ffc Data using any tricks.
  589. //! I am betting AGAINST this, and that you will also need to set up six combos for the items, which
  590. //! is not explained in the set-up.
  591.  
  592. //! Of course. This is why I would draw the item use din the arg to the screen. -Z
  593.  
  594. // What I do instead of forcing anyone to set up one combo per item in a shoppe, is to CREATE the item on the screen
  595. // at the coordinates of the ffc, and either set its IP_PICKUP or move its Y hit component off-screen.
  596.  
  597. // Setting up an ffc per item with a combo per item is tedious; and wasteful.
  598.  
  599. // We also need to set up a subscreen for this.
  600.  
  601. //! The shop is not selling me bees, faeries or water. Hmm.
  602.  
  603. //Returns if Link is below a specified ffc.
  604. bool ___BelowFFC(ffc n){ return Link->Y > n->Y; }
  605.  
  606.  
  607. //Returns if Link is within a specified distance to an ffc.
  608. bool _______DistXY(ffc b, int distance) {
  609.     int distx; int disty;
  610.     distx = Abs(Link->X - b->X);
  611.     disty = Abs(Link->Y - b->Y);
  612.     return ( distx <= distance && disty <= distance );
  613. }
  614.  
  615.  
  616.  
  617. //Returns if the correct button was pressed to buy an item based on the desired button settings.
  618. bool ShopItem_MatchBuyPress(){
  619.     if ( SHOP_BUY_BUTTON_A ) { if ( Link->PressA ) return true; }
  620.     if ( SHOP_BUY_BUTTON_B ) { if ( Link->PressB ) return true; }
  621.     if ( SHOP_BUY_BUTTON_L ) { if ( Link->PressL ) return true; }
  622.     if ( SHOP_BUY_BUTTON_R ) { if ( Link->PressR ) return true; }
  623.     if ( SHOP_BUY_BUTTON_EX1 ) { if ( Link->PressEx1 ) return true; }
  624.     if ( SHOP_BUY_BUTTON_EX2 ) { if ( Link->PressEx2 ) return true; }
  625.     if ( SHOP_BUY_BUTTON_EX3 ) { if ( Link->PressEx3 ) return true; }
  626.     if ( SHOP_BUY_BUTTON_EX4 ) { if ( Link->PressEx4 ) return true; }
  627.     return false;
  628. }
  629.  
  630. //Returns if the correct button was pressed to read an item info string for an item based on the desired button settings.
  631. bool ShopItem_MatchLookPress(){
  632.     if ( SHOP_LOOK_BUTTON_A ) { if ( Link->PressA ) return true; }
  633.     if ( SHOP_LOOK_BUTTON_B ) { if ( Link->PressB ) return true; }
  634.     if ( SHOP_LOOK_BUTTON_L ) { if ( Link->PressL ) return true; }
  635.     if ( SHOP_LOOK_BUTTON_R ) { if ( Link->PressR ) return true; }
  636.     if ( SHOP_LOOK_BUTTON_EX1 ) { if ( Link->PressEx1 ) return true; }
  637.     if ( SHOP_LOOK_BUTTON_EX2 ) { if ( Link->PressEx2 ) return true; }
  638.     if ( SHOP_LOOK_BUTTON_EX3 ) { if ( Link->PressEx3 ) return true; }
  639.     if ( SHOP_LOOK_BUTTON_EX4 ) { if ( Link->PressEx4 ) return true; }
  640.     return false;
  641. }
  642.  
  643.  
  644. ffc script ItemShop{
  645.     void run(int id, int strdescription, int price, int potion){ //D3 must be the item ID for the three potion items.
  646.         itemdata ic = Game->LoadItemData(id); item shopitms[2];
  647.         price = price << 0;
  648.         if ( price < 0 ) price = 0; //Sanity check.
  649.         if ( ITEMSHOP_BLANK_FFCS_DRAW_ITEMS ) {
  650.             if ( this->Data == ITEMSHOP_VISIBLE_COMBO || this->Data == ITEMSHOP_BLANK_COMBO ) {
  651.                 this->Data = ITEMSHOP_BLANK_COMBO;
  652.                 shopitms[0] = Screen->CreateItem(id); //Create the item so that the user does not need to set the combo.
  653.                 shopitms[0]->X = this->X; shopitms[0]->Y = this->Y;
  654.                 shopitms[0]->HitYOffset = -999;
  655.                 //itm[0]->Pickup = IP_DUMMY; //Set its pickup flag.
  656.            
  657.             }
  658.         }
  659.         while(true){
  660.            
  661.            
  662.             if ( Link->Dir == DIR_UP ) {
  663.                 if ( ___BelowFFC(this) ) {
  664.                     if ( _______DistXY(this, FFC_SHOP_DISTANCE) ) {
  665.                         //Draw the button tile.
  666.                         Screen->DrawTile(TILE_SHOP_BUTTON_LAYER, this->X + TILE_SHOP_BUTTON_X_OFFSET, this->Y + TILE_SHOP_BUTTON_Y_OFFSET,
  667.                             TILE_SHOP_BUTTON, 1, 1, TILE_SHOP_BUTTON_CSET, TILE_SHOP_BUTTON_XSCALE, TILE_SHOP_BUTTON_YSCALE,
  668.                             0, 0, 0, 0, true, TILE_SHOP_BUTTON_OPACITY);
  669.                        
  670.                         if( ShopItem_MatchLookPress() ){
  671.                             Screen->Message(strdescription);
  672.                             NoAction();
  673.                         }
  674.                         if( ShopItem_MatchBuyPress() ){
  675.                             if(Game->Counter[CR_RUPEES]+Game->DCounter[CR_RUPEES]>=price){
  676.                                 if(potion>0&&!CanFillBottle()){
  677.                                     Screen->Message(STR_NOBOTTLE);
  678.                                     NoAction();
  679.                                 }
  680.                                 else{
  681.                                     shopitms[1] = CreateItemAt(id, Link->X, Link->Y);
  682.                                    
  683.                                     //shopitms[1]->Pickup = IP_HOLDUP;
  684.                                     Game->DCounter[CR_RUPEES] -= price;
  685.                                     Link->HeldItem = id;
  686.                                     //Don;t remove the items if that idiotic quest rule is enabled.
  687.                                     //Set the pick-up animation manually.
  688.                                     for(int q=0; q<2; q++){
  689.                                         Game->PlaySound(SFX_SHOP_BUYITEM);
  690.                                         Link->Action = LA_HOLD1LAND;
  691.                                         Waitframe();
  692.                                     }
  693.                                 }
  694.                             }
  695.                             else{
  696.                                 Screen->Message(STR_CANTAFFORD);
  697.                                 NoAction();
  698.                             }
  699.                         }
  700.                     }
  701.                 }
  702.             }
  703.             DrawPrice(this, price);
  704.            
  705.             Waitframe();
  706.         }
  707.     }
  708.     void DrawPrice(ffc this, int price){
  709.         int xoff = -2;
  710.         if ( price > 0 ) {
  711.             if(price>999)
  712.                 xoff = -8;
  713.             else if(price>99)
  714.                 xoff = -6;
  715.             else if(price>9)
  716.                 xoff = -4;
  717.             Screen->DrawInteger(FFC_BOTTLE_SHOP_PRICE_LAYER, this->X+8+xoff+1, this->Y+18+1, FONT_Z3SMALL, C_BLACK, -1, -1, -1, price, 0, 128);
  718.             Screen->DrawInteger(FFC_BOTTLE_SHOP_PRICE_LAYER, this->X+8+xoff, this->Y+18, FONT_Z3SMALL, C_WHITE, -1, -1, -1, price, 0, 128);
  719.         }
  720.         else { //Draw the string 'FREE' if it is free.
  721.             int free[]="FREE"; xoff = -8;
  722.             Screen->DrawString(FFC_BOTTLE_SHOP_PRICE_LAYER, this->X+8+xoff+1, this->Y+18+1, FONT_Z3SMALL, C_BLACK, 0, 0, free, 128);
  723.             Screen->DrawString(FFC_BOTTLE_SHOP_PRICE_LAYER, this->X+8+xoff, this->Y+18, FONT_Z3SMALL, C_WHITE, 0, 0, free, 128);
  724.         }
  725.     }
  726.            
  727. }
  728.  
  729. ffc script BeeGrass{
  730.     void run(int chances){
  731.         int Combo = Screen->ComboD[ComboAt(this->X+8, this->Y+8)];
  732.         while(Screen->ComboD[ComboAt(this->X+8, this->Y+8)]==Combo){
  733.             Waitframe();
  734.         }
  735.         if(Rand(chances)==0){
  736.             int scriptname[] = "Bottle_Bee";
  737.             int scriptid = Game->GetFFCScript(scriptname);
  738.             int i = RunFFCScript(scriptid, 0);
  739.             ffc f = Screen->LoadFFC(i);
  740.             f->X = this->X;
  741.             f->Y = this->Y;
  742.         }
  743.     }
  744. }
  745.  
  746. //Bug: The script does not stop allowing a player to trigger the secrets by repeatedly pouring water over the trigger spot.  -Z
  747. //This only occurs if the player tries to trigger it multiple times without leaving the screen. -Z
  748. ffc script WaterTrigger{
  749.     void run(){
  750.         if(Screen->State[ST_SECRET]){ this->Data - 0; this->Script = 0; Quit(); }
  751.         while(true){
  752.             if(!Screen->State[ST_SECRET]){ //This fixed the multiple trigger bug. -Z
  753.                 for(int i=1; i<=Screen->NumLWeapons(); i++){
  754.                     lweapon l = Screen->LoadLWeapon(i);
  755.                     if(l->ID==LW_WATER&&Collision(this, l)){
  756.                         Screen->TriggerSecrets();
  757.                         Game->PlaySound(SFX_SECRET);
  758.                         Screen->State[ST_SECRET] = true; //This was not sufficient? -Z
  759.                         this->Data = 0; this->Script = 0; Quit();
  760.                     }
  761.                 }
  762.             }
  763.             Waitframe();
  764.         }
  765.     }
  766. }
  767.  
  768. //X-------------------------X
  769. //|  Example Global Script  |
  770. //X-------------------------X
  771.  
  772.  
  773. global script Main2{
  774.     void run(){
  775.         RefreshBottles();
  776.         while(true){
  777.             EmptyBottleGlobal();
  778.             Waitdraw();
  779.             Waitframe();
  780.         }
  781.     }
  782. }
  783.  
  784. void Screen_Freeze(){
  785.     ffc f1 = Screen->LoadFFC(FFC_SFA);
  786.     ffc f2 = Screen->LoadFFC(FFC_SFB);
  787.     f1->Data = CMB_SFA;
  788.     f2->Data = CMB_SFB;
  789. }
  790.  
  791. void Screen_Unfreeze(){
  792.     ffc f1 = Screen->LoadFFC(FFC_SFA);
  793.     ffc f2 = Screen->LoadFFC(FFC_SFB);
  794.     f1->Data = 0;
  795.     f2->Data = 0;
  796. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement