ZoriaRPG

Menu Shop v0.7.3

May 2nd, 2017
46
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //////////////////////////////////////
  2. /// Shop FFC Item with Yes/No Menu ///
  3. /// By: ZoriaRPG                   ///
  4. /// 26-July-2016                   ///
  5. /// v0.7.3                         ///
  6. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  7. ///                                                                                                                                         ///
  8. /// !! Set FFC FLag 'Run on Screen Init !!!                                                                                             ///
  9. ///                                                                                                                                         ///
  10. /// D0 : The item ID (number) to give Link.                                                                                                 ///
  11. /// D1 : The price of the item.                                                                                                             ///
  12. /// D2 : The item info message (high) and the OPTIONAL alternate message string for replacement items (low).                                ///
  13. /// --> Integer Portion (#####.xxxx) THe message to display for Item Info menu option.                                                  ///
  14. /// --> Decimal Portion (xxxxx.####) An alternate info string, for a replacement item, if desired.                                      ///
  15. /// D3 : Alternate combo to use, if you want a generic combo for shop items (high) and alternate counter (low).                             ///
  16. /// --> Integer Portion (#####.xxxx) The combo ID.                                                                                      ///
  17. /// --> Decimal Portion (xxxxx.####) An alternate counter, instead of the default (CR_RUPEES), if desired.                              ///
  18. /// D4 : Sound to play if purchase is a success.                                                                                            ///
  19. /// D5 : If set to '1', Link holds the item up with one hand. If set to '2', he holds it up with two hands.                                 ///
  20. ///      Set to '0' for no item hold-up animation.                                                                                          ///
  21. /// D6 : This value is split between the integer portion,a nd the decimal. the decimal portion is only used for optional shop capabilities. ///
  22. ///     --> Integer Portion ( #####.xxxx ) Set to '1' to sell only one time.                                                                ///
  23. ///                                         If set to '1', a 'sold out' sign will take the place of this item when it sells.                ///
  24. ///                                    If set ABOVE 1, a REPLACEMENT item with this ID will take the place of the item when it sells.   ///
  25. /// --> Decimal Portion ( xxxxx.#### ) If you wish to set a different price for a REPLACEMENT ITEM, enter it here.                      ///
  26. /// D7 : The Nth item in this shop. Set each in sequence, starting at '1', and ending at '9' (max) or whatever the number of items is that  ///
  27. ///  you have in this shop.                                                                                                             ///        
  28. /// --> Example: If a shop with three items, number one of them '1', another '2', and the last '3'.                                     ///
  29. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  30. /// Requested By: JudasRising, with additional features requested  by Dimentio, and Grayswandir.                                            ///
  31. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  32. /// Crediting:            ///
  33. ///                       ///
  34. /// JudasRising: Testing. ///
  35. /////////////////////////////
  36.  
  37. //! CHANGES
  38. // 0.7.3 -  * Added an flag to check if shops should stay open.
  39. //      * Fixed bug with 'only_once' not being truncated in some calls.
  40. //      * This fixes the bug with replacement items causing shops to close. The lights do go out briedly, until the new item spawns.
  41. //      * Modified IsShopAllSoldOut(int dmap, int screen) to check for this extra flag.
  42. //      * Still no support for replacement items being FREE. Should I just make it use this arg by default?
  43. // 0.7.2 -  * Fixed issue with sold out sign not appearing.
  44. //      * New bug:  Replacement items don't prevent shop closure (total sell-out). This may be very tedious to correct, and
  45. //              it would be simpler to warn not to have a shop that can be totally sold out, and have replacement goods.
  46. // 0.7.1 -  * Somewhere between 0.6.6 and here, a bug emerged. Sold Out no logner works, and some free dummy object is being created.
  47. // 0.7.1 -  * Add ability to set CR_LIFE s a cost, using 100 as its counter value.
  48. // 0.7.0 -  * Fix price being incorrectly displayed if it is a decimal place lower for replacement items (10 is displayed as 100).
  49. // 0.6.9 -  * Added support for drawing item graphcs without needing to make a combo.
  50. // 0.6.8 -  * Added alternate info string for replacement items.
  51. // 0.6.7 -  * Fixed alternate item price display, and display of replacement item graphics.
  52. // 0.6.6 -  * Imitial tests of replacment item. Fixed ability to change item, and draw it.
  53. // 0.6.5 -  * Fixed drawing of rupee icon, price, and 'x' when item is sold out.
  54. //      * Fixed SHOP_TILE_RUPEE_ICON_OPACITY not being used.
  55. //      * Added SHOP_BUY_BUTTON_OFFSETS_ARE_FROM_FFC. Buy button can now be set based on the ffc, or based on Link!
  56. // 0.6.4 -  * Fixed IsShopAllSoldOut() in both incarnations.
  57. // 0.6.3 -  * Added more debug functions and features.
  58. // 0.6.2 -  * Bugfixes: Removed calls to CenterX/Y in door ffc. Fixed Game-> pointers for GetDMapScreenD. Fixed typos.
  59. // 0.6.1 -  * Fxed error in FFC_NumShopItems() where ffc 32 would be ignored.
  60. // 0.6.0 -  * Stopepd calling Quit(). This hosed the calls to FFC_NumShopItems() as the number of running shops would change!
  61. // 0.5.9 -  * Changed darkness to a global function. Added 'Closed door' ffc.
  62. // 0.5.8 -  * Bugfixes. Changed IsShopAllSoldOut() method. Added SHOP_DEBUG.
  63. // 0.5.7 -  * Bugfixes: Fixed bug where 'Free' wouldn't draw - changed itoa() to strcat()
  64. // 0.5.6 -  * Bugfixes. Fixed rupee tile.
  65. // 0.5.5 -  * Now supports nine items. Added many new features.
  66. // 0.5.6 -  * Fixed bug in storing flags.
  67. //      * Fixed bugs in drawing rupee icon.
  68. //      * Fixed bug in displayig 'Free'
  69. // 0.5.7 -  * Changed how we check if a shop is closed.
  70. //      * Added debug feature to ensure that the number of shops, and sold-out us are being set.
  71. // 0.5.8 -  * Changed shop darknesss to a global component.
  72. //      * Added functions to read shop darkness from other DMap/Screen locations
  73. // 0.5.9 -  * Added ffc to control closing shop doors. Uses remore reading functions.
  74. //      * Deprecated old darkness routines.
  75.  
  76. //General Settings
  77. const int SHOP_REGISTER = 6; //Screen->D used for shop items.
  78. const int SHOP_DEBUG_ON = 0; //Set to '0' to disable debug reports in allegro.log.
  79.                 //! TURN THIS OFF BEFORE RELEASING A QUEST !
  80.  
  81. //Combos and Tiles
  82. const int TILE_SOLD_SIGN = 22913; //The sold ign, if using the sell-out feature.
  83.  
  84. const int SHOP_SIGNS_CHANGE_WHEN_ALL_ITEMS_SOLD = 0;
  85.     //If this is set to '1', then signs will chane again if none of the itms are available to buy any longer.
  86. const int TILE_SHOP_CLOSED_FOREVER = 0; //Set to a combo of your choice if all the items are sold out, forever.
  87.  
  88. //The small button icon that appears next to an item, to allow link to know he can interact with it.
  89. //THe tile should have a graphic that occupies the upper-rightmost 8x8pixels, as a 'minitile'.
  90. const int SHOP_BUY_BUTTON_TILE = 44190; //Tile of the 'open menu' button, or whatever button you use to activate the 'buy' menu.
  91.  
  92. const int SHOP_BUY_BUTTON_TILE_CSET = 2;
  93. const int SHOP_BUY_BUTTON_TILE_OPACITY = 128; //128 is opaque, 64 translucent.
  94. const int SHOP_BUY_BUTTON_TILE_LAYER = 2; //Layer for the button. Default '2'.
  95. const int SHOP_BUY_BUTTON_TILE_X_OFFSET = 17; //Offsets for drawing, from the ffc's x/y position.
  96. const int SHOP_BUY_BUTTON_TILE_Y_OFFSET = -6;
  97. const int SHOP_BUY_BUTTON_TILE_BLOCKW = 1; //The number of tiles (wide) to draw. Default '1'.
  98. const int SHOP_BUY_BUTTON_TILE_BLOCKH = 1; //The number of tiles (high) to draw. Default '1'.
  99. const int SHOP_BUY_BUTTON_OFFSETS_ARE_FROM_FFC = 1; //Set to '1' to use the ffc coordinates, otherwise it uses Link->X/Y as a base.
  100.  
  101. //Replacement Item
  102. const int SHOP_TILE_REPLACEMENT_ITEM_LAYER = 2;
  103.  
  104. //Rupee Icon Tile (next to price)
  105. const int SHOP_TILE_RUPEE_ICON = 44180; //Tile of the rupee icon to put by the price.
  106.     //! The script will only draw this if it is npt set to '0'.
  107. const int SHOP_TILE_RUPEE_ICON_LAYER = 2; //Layer for the icon. Default '1'.
  108. const int SHOP_TILE_RUPEE_ICON_BLOCKW = 1; //The number of tiles wide) to draw. Default '1'.
  109. const int SHOP_TILE_RUPEE_ICON_BLOCKH = 1; //The number of tiles (high) to draw. Default '1'.
  110. const int SHOP_TILE_RUPEE_ICON_CSET = 2;
  111. const int SHOP_TILE_RUPEE_ICON_X_OFFSET = 0; //Position of the rupee icon offsets (from the ffc x/y).
  112. const int SHOP_TILE_RUPEE_ICON_Y_OFFSET = 11;
  113. const int SHOP_TILE_RUPEE_ICON_XSCALE = 15; //Scaling factor of the tile in percent.//50
  114. const int SHOP_TILE_RUPEE_ICON_YSCALE = 15; //Scaling factor of the tile in percent.//50
  115. const int SHOP_TILE_RUPEE_ICON_OPACITY = 128; //128 is opaque, 64 translucent.
  116.  
  117. //Text Settings for shop prices
  118. const int SHOP_PRICE_FONT = 2; //See std_constants.zh for font values.
  119. const int SHOP_PRICE_COLOUR_FOREGROUND = 0x0F; //Black
  120. const int SHOP_PRICE_COLOUR_BACKGROUND = 0x01; //WHite
  121. const int SHOP_PRICE_TEXT_LAYER = 2; //Layer to draw the text. Default '2'.
  122. const int SHOP_PRICE_TEXT_X_OFFSET_FOREGROUND = 12; //The x/y offsets for the text, based on the ffc coordinates.
  123. const int SHOP_PRICE_TEXT_X_OFFSET_BACKGROUND = 13;
  124. const int SHOP_PRICE_TEXT_Y_OFFSET_FOREGROUND = 13;
  125. const int SHOP_PRICE_TEXT_Y_OFFSET_BACKGROUND = 14;
  126. const int SHOP_PRICE_SIZE = 0; //Size-scale factor.
  127.  
  128. //The 'x' between the rupee icon and the price.
  129. const int SHOP_PRICE_DRAW_X_SIGN = 1; //Set to 1 to draw the 'x' between the rupee icon, and the text; 0 to disqable.
  130. const int SHOP_PRICE_DRAW_X_SIGN_LAYER = 2; //Layer to draw the 'x'. Default '2'.
  131. const int SHOP_PRICE_DRAW_X_SIGN_COLOUR_FOREGROUND = 0x01; //Black
  132. const int SHOP_PRICE_DRAW_X_SIGN_COLOUR_BACKGROUND = 0x0F; //White
  133. const int SHOP_PRICE_DRAW_X_SIGN_SIZE = 0; //Size-scale factor.
  134. const int SHOP_PRICE_DRAW_X_SIGN_X_OFFSET_FOREGROUND = 8; //The x/y offsets for the text, based on the ffc coordinates.
  135. const int SHOP_PRICE_DRAW_X_SIGN_Y_OFFSET_FOREGROUND = 13;
  136. const int SHOP_PRICE_DRAW_X_SIGN_X_OFFSET_BACKGROUND = 9;
  137. const int SHOP_PRICE_DRAW_X_SIGN_Y_OFFSET_BACKGROUND = 14;
  138. const int SHOP_PRICE_DRAW_X_SIGN_FONT = 2; //See std_constants.zh for font values.
  139.  
  140. //Button Settings: THe shop will activate the menu / Link will take the item based on a button press.
  141. //Set any button that you wish to permit the player to take the 'buy' action by enabling it here.
  142. //Any button enabled will work, and you may enable any combination, one, some, or all, of them.
  143. //Set to '1' to enable, '0' to disable.
  144. const int SHOP_USE_BUTTON_R = 1;
  145. const int SHOP_USE_BUTTON_L = 0;
  146. const int SHOP_USE_BUTTON_A = 1;
  147. const int SHOP_USE_BUTTON_B = 0;
  148. const int SHOP_USE_BUTTON_EX1 = 0;
  149. const int SHOP_USE_BUTTON_EX2 = 0;
  150. const int SHOP_USE_BUTTON_EX3 = 0;
  151. const int SHOP_USE_BUTTON_EX4 = 0;
  152.  
  153. //Replacement Item Tile Settings
  154. const int SHOP_REPL_ITEM_TILE_LAYER = 1; //Replacement item tiles (via Screen->Drawtile) will appear on this layer.
  155.  
  156. //Sound and String
  157. const int SFX_SHOP_ERROR = 9; //Sound to play when buying an item.
  158. const int MSG_SHOP_ERROR = 10; //Message to display if Link is out of funds.
  159.  
  160. //Shop Darkness Settings
  161. const int SHOP_DARK_WHEN_CLOSED = 1; //Set to '1' to close the shop by turning out the lights.
  162. const int SHOP_DARKNESS_COLOUR = 0x0F;// Black; used by shop darkness overlay.//0x0F
  163. const int SHOP_DARKNESS_LAYER = 6; //Darkness effect will be drawn to this layer.
  164. const int SHOP_DARKNESS_SCALE = 100;
  165. const int SHOP_DARKNESS_OPACITY = 64; //64 is transparent, 128 is opaque.
  166. const int SHOP_DARKNESSS_NUM_LAYERS = 2; //How many draws to perform.
  167.  
  168. //Closed shop door
  169. const int SHOP_DEFAULTCLOSED_DOOR_COMBO = 100; //Set to ID of default closed door combo.  
  170.  
  171. //Shop Functionality Setings
  172. const int SHOP_LINK_PROXIMITY_X_TO_ITEM = 25; //X-Distance in pixels for required proximity to activate menu.
  173. const int SHOP_LINK_PROXIMITY_Y_TO_ITEM = 25; //Y-Distance in pixels for required proximity to activate menu.
  174. const int SHOP_LINK_MUST_FACE_ITEM = 1; //Set to 0 to disable.
  175. const int SHOP_SHOW_ZERO = 0; //Show zero value prices. '1' to show, '0' to disable.
  176.                 //! This is mutually-exclusive with 'SHOP_ZERO_PRICE_STATES_FREE'
  177. const int SHOP_SHOW_NEGATIVE_PRICE = 0;  //Show negative value prices. '1' to show, '0' to disable.
  178. const int SHOP_FREE_ITEMS_NO_MENU = 0; //Set to '1' to bypass the menu for free items, giving the player the item instantly.
  179. const int SHOP_SHOW_RUPEE_X_FOR_FREE_ITEMS = 1; //Set to '0'; to disable showing rupee ICON and/or X for free items. Depends on main setting to display either.
  180. const int SHOP_ZERO_PRICE_STATES_FREE = 1; //Set to '1' to show the string 'Free' next to 0-price items, instead of '0'.
  181.                         //! This is mutually exclusive with 'SHOP_SHOW_ZERO'.
  182.  
  183. //Tango slot constants.
  184. const int WINDOW_SLOT_1 = 0;
  185. const int WINDOW_SLOT_2 = 1;
  186. const int WINDOW_SLOT_3 = 2;
  187. const int WINDOW_SLOT_4 = 3;
  188. const int WINDOW_SLOT_5 = 4;
  189.  
  190. //Values that you probably should not change.
  191. //! These are the binary flags for items, used in conjunction with one-time-only sales.
  192. const int SHOP_SOLD_ITEM_1 = 000000001b;
  193. const int SHOP_SOLD_ITEM_2 = 000000010b;
  194. const int SHOP_SOLD_ITEM_3 = 000000100b;
  195. const int SHOP_SOLD_ITEM_4 = 000001000b;
  196. const int SHOP_SOLD_ITEM_5 = 000010000b;
  197. const int SHOP_SOLD_ITEM_6 = 000100000b;
  198. const int SHOP_SOLD_ITEM_7 = 001000000b;
  199. const int SHOP_SOLD_ITEM_8 = 010000000b;
  200. const int SHOP_SOLD_ITEM_9 = 100000000b;
  201. const int SHOP_STAY_OPEN = 1000000000b;
  202.  
  203.  
  204. // There are certainly other ways to handle these...
  205. // Vars used by the Tango menu.
  206. int menuCommand;
  207. int menuArg;
  208.  
  209. //Tango Menu Init
  210. void SetUpWindow(int slot, int style, int x, int y, int size)
  211. {
  212.     SetStyleSize(style, size);
  213.     Tango_ClearSlot(slot);
  214.     Tango_SetSlotStyle(slot, style);
  215.     Tango_SetSlotPosition(slot, x, y);
  216. }
  217.  
  218. //Quick way to drop a string into a Tango dialogue box.
  219. void ShowString(int string, int slot, int style, int x, int y)
  220. {
  221.     SetUpWindow(slot, style, x, y, SIZE_LARGE);
  222.     Tango_LoadString(slot, string);
  223.     Tango_ActivateSlot(slot);
  224.     while(Tango_SlotIsActive(slot))  
  225.         Waitframe();
  226. }
  227.  
  228.  
  229.  
  230. //The main shop ffc.
  231. ffc script ShopItemMenu{
  232.     void run(int itm, int price, int msg, int itemcombo, int sound, int holdup_type, int only_once, int itemnumber_in_shop){
  233.         int msg_str = msg << 0; //Message string is integer of D2.
  234.         int counter = ( itemcombo - ( itemcombo << 0 )) *10000; //Alt counte ris decimal of D2.
  235.         if ( counter == 0 ) counter = CR_RUPEES; //Allow an alternate counter.
  236.         if ( counter == 100 ) counter = CR_LIFE; //Permit life, just don't let it be the DEFAULT.
  237.         item it = Screen->CreateItem(only_once << 0);
  238.         item main; int q;
  239.         if ( itm > 0 ) main = Screen->CreateItem(itm);
  240.         if ( itm < 0 ) main = Screen->CreateItem(itm*-1);
  241.         if ( !itm ) Quit();
  242.         int choice; bool pressed; bool replace; int drawitem;
  243.         bool dotile; //true if we use a tile, not a combo
  244.         int str_price[6];
  245.         int free[]="Free";
  246.  
  247.         it->X = 0; it->Y = 0;
  248.         it->DrawXOffset = -300;
  249.         it->HitXOffset = -300;
  250.         it->DrawYOffset = -300;
  251.         it->HitYOffset = -300;
  252.        
  253.         main->X = 0; main->Y = 0;
  254.         main->DrawXOffset = -300;
  255.         main->HitXOffset = -300;
  256.         main->DrawYOffset = -300;
  257.         main->HitYOffset = -300;
  258.        
  259.         if ( itm < 0 ) {
  260.             this->Data = FFCS_INVISIBLE_COMBO;
  261.             drawitem = itm * -1;
  262.             itm = itm * -1;
  263.         }
  264.        
  265.         if ( itemcombo << 0 ) this->Data = itemcombo << 0; //If we have a specific combo ID set, use it.
  266.        
  267.         if ( ( only_once << 0 ) > 1 ) {
  268.             //We have a replacement item when this one sells, so don't put up a sold out sign.
  269.             if ( FFC_ShopFlag(SHOP_SOLD_ITEM_1) && itemnumber_in_shop == 1 ) { replace = true; itm = ( only_once << 0 ); this->Data = FFCS_INVISIBLE_COMBO; }
  270.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_2) && itemnumber_in_shop == 2 ) { replace = true;  itm = ( only_once << 0 ); this->Data = FFCS_INVISIBLE_COMBO; } //We could offer drawtile for this.
  271.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_3) && itemnumber_in_shop == 3 ) { replace = true;  itm = ( only_once << 0 ); this->Data = FFCS_INVISIBLE_COMBO; }
  272.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_4) && itemnumber_in_shop == 4 ) { replace = true;  itm = ( only_once << 0 ); this->Data = FFCS_INVISIBLE_COMBO; }
  273.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_5) && itemnumber_in_shop == 5 ) { replace = true;  itm = ( only_once << 0 ); this->Data = FFCS_INVISIBLE_COMBO; }
  274.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_6) && itemnumber_in_shop == 6 ) { replace = true;  itm = ( only_once << 0 ); this->Data = FFCS_INVISIBLE_COMBO; }
  275.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_9) && itemnumber_in_shop == 7 ) { replace = true;  itm = ( only_once << 0 ); this->Data = FFCS_INVISIBLE_COMBO; }
  276.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_8) && itemnumber_in_shop == 8 ) { replace = true;  itm = ( only_once << 0 ); this->Data = FFCS_INVISIBLE_COMBO; }
  277.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_3) && itemnumber_in_shop == 9 ) { replace = true;  itm = ( only_once << 0 ); this->Data = FFCS_INVISIBLE_COMBO; }
  278.            
  279.             if ( !replace && drawitem ) {
  280.                 Screen->DrawTile(SHOP_TILE_REPLACEMENT_ITEM_LAYER,this->X,this->Y,main->Tile,main->TileWidth,main->TileHeight,main->CSet,-1,-1,0,0,0,0,true,128);
  281.  
  282.             }
  283.            
  284.             if ( replace ) {
  285.                 FFC_SetShopFlag(SHOP_STAY_OPEN,true);
  286.                 itm = ( only_once << 0 );
  287.                 //Screen->D[SHOP_REGISTER_REPL_ITEM] = ( only_once - ( only_once << 0 )) *10000;
  288.                 this->Data = FFCS_INVISIBLE_COMBO;
  289.                 //Make this ffc combo invisible, then...
  290.                 //it->DrawXOffset = this->X;
  291.                 //it->DrawYOffset = this->Y;
  292.                 //Screen->DrawTile(SHOP_REPL_ITEM_TILE_LAYER, this->X, this->Y, it->Tile, 1, 1, it->CSet, -1, -1, 0, 0, 0, 0, true, OP_OPAQUE);
  293.                 //Draw a tile so that it's easier to customise what the user sees.
  294.                 //Set an alternate price using the decimal portion of D6.
  295.                 if ( ( (only_once - ( only_once << 0 )) *10000)  > 0 ) price = ( only_once - ( only_once << 0 )) *10000;
  296.                 //TracePrice(price);
  297.                 if ( !SHOP_ZERO_PRICE_STATES_FREE || price != 0 ) {
  298.                         //Wipe the string, and replace it.
  299.                     for ( q = 0; q < SizeOfArray(str_price); q++ ) str_price[q] = 0;
  300.                     itoa(str_price,price); //Store the price in a string to display it.
  301.                 }
  302.                 else {
  303.                     //Wipe the string, and replace it.
  304.                     for ( q = 0; q < SizeOfArray(str_price); q++ ) str_price[q] = 0;
  305.                     strcat(str_price,free); //Show 'Free' instead of a numeral '0'.
  306.                 }
  307.                 Screen->DrawTile(SHOP_TILE_REPLACEMENT_ITEM_LAYER,this->X,this->Y,it->Tile,it->TileWidth,it->TileHeight,it->CSet,-1,-1,0,0,0,0,true,128);
  308.  
  309.                 //Set an alternate item info message, using the decimal portion of D3.
  310.                 msg_str = (msg - (msg << 0)) * 10000;
  311.             }
  312.         }
  313.        
  314.         if ( ( only_once << 0 ) == 1 || ( only_once << 0 ) < 0 ) {
  315.             if ( FFC_ShopFlag(SHOP_SOLD_ITEM_1) && itemnumber_in_shop == 1 ) { this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  316.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_2) && itemnumber_in_shop == 2 ) { this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  317.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_3) && itemnumber_in_shop == 3 ) { this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  318.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_4) && itemnumber_in_shop == 4 ) { this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  319.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_5) && itemnumber_in_shop == 5 ) { this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  320.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_6) && itemnumber_in_shop == 6 ) { this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  321.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_9) && itemnumber_in_shop == 7 ) { this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  322.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_8) && itemnumber_in_shop == 8 ) { this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  323.             else if ( FFC_ShopFlag(SHOP_SOLD_ITEM_3) && itemnumber_in_shop == 9 ) { this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  324.         }
  325.        
  326.        
  327.        
  328.        
  329.        
  330.            
  331.        
  332.        
  333.        
  334.        
  335.         if ( !SHOP_ZERO_PRICE_STATES_FREE || price != 0 ) itoa(str_price,price); //Store the price in a string to display it.
  336.         else strcat(str_price,free); //Show 'Free' instead of a numeral '0'.
  337.        
  338.                                    
  339.         //Replce the item if needed.
  340.        
  341.         if ( SHOP_DEBUG_ON ) ShopDebug();
  342.  
  343.         //if ( ( this->Data == TILE_SOLD_SIGN || this->Data == TILE_SHOP_CLOSED_FOREVER) ) {
  344.             //&& !SHOP_DARK_WHEN_CLOSED ) {
  345.         //      this->Script = 0;
  346.         //      Quit();
  347.         //} //Clear the ffc if the item is sold, to prevent count of running shops from reading it.
  348.        
  349.         //if ( ( this->Data == TILE_SOLD_SIGN || this->Data == TILE_SHOP_CLOSED_FOREVER) && SHOP_DARK_WHEN_CLOSED ) {
  350.         //      this->Script = FFC_GetShopDarkness();
  351.         //      Quit();
  352.         //} //If shops should be dark, change the script.
  353.        
  354.         FFC_SetNumberShopItems(); //Store how many shops are running.
  355.        
  356.         while(true){
  357.             //Waitframes(2); //Wait for all shops to load before setting the number of active shops running.
  358.             if (SHOP_DEBUG_ON && (Link->InputEx1 || Link->PressEx1) && ( Link->InputEx2 || Link->PressEx2 ) ) ShopDebug();
  359.             //if ( ( this->Data == TILE_SOLD_SIGN || this->Data == TILE_SHOP_CLOSED_FOREVER) && !SHOP_DARK_WHEN_CLOSED ){
  360.                 //this->Script = 0;
  361.                 //Quit();
  362.                 //If we clear the ffc or qit, it mucks up FFC_NumShopItems()
  363.             //}
  364.            
  365.             //if ( IsShopAllSoldOut() && SHOP_DARK_WHEN_CLOSED ) {
  366.             //  this->Script = FFC_GetShopDarkness();
  367.                 //Quit();
  368.             //} //If shops should be dark, change the script.
  369.            
  370.             if ( SHOP_SIGNS_CHANGE_WHEN_ALL_ITEMS_SOLD && IsShopAllSoldOut() ) this->Data = TILE_SHOP_CLOSED_FOREVER;
  371.            
  372.             if ( !replace && drawitem ) {
  373.                 Screen->DrawTile(SHOP_TILE_REPLACEMENT_ITEM_LAYER,this->X,this->Y,main->Tile,main->TileWidth,main->TileHeight,main->CSet,-1,-1,0,0,0,0,true,128);
  374.  
  375.             }
  376.            
  377.             //Draw the replacement items, as they need to have the highest drawing priority
  378.             if ( replace ) {
  379.                 FFC_SetShopFlag(SHOP_STAY_OPEN,true);
  380.                 //! Replace with the new item
  381.                 itm = ( only_once << 0 );
  382.                 price = ( only_once - ( only_once << 0 )) *10000;
  383.                 //TracePrice(price);
  384.                 //Screen->D[SHOP_REGISTER_REPL_ITEM] = ( only_once - ( only_once << 0 )) *10000;
  385.                 this->Data = FFCS_INVISIBLE_COMBO;
  386.                 //Make this ffc combo invisible, then...
  387.                 //it->DrawXOffset = -200;
  388.                 //it->DrawYOffset = -200;
  389.                 //Draws an item to a given layer
  390.                 Screen->DrawTile(SHOP_TILE_REPLACEMENT_ITEM_LAYER,this->X,this->Y,it->Tile,it->TileWidth,it->TileHeight,it->CSet,-1,-1,0,0,0,0,true,128);
  391.  
  392.                 //Screen->DrawTile(SHOP_REPL_ITEM_TILE_LAYER, this->X, this->Y, it->Tile, 1, 1, it->CSet, -1, -1, 0, 0, 0, 0, true, OP_OPAQUE);
  393.                 //Draw a tile so that it's easier to customise what the user sees.
  394.                 //Set an alternate price using the decimal portion of D6.
  395.                 if ( ( only_once - ( only_once << 0 )) *10000 > 0 ) price = ( only_once - ( only_once << 0 )) *10000;
  396.                 //TracePrice(price);
  397.                 //Update the price string.
  398.                 if ( !SHOP_ZERO_PRICE_STATES_FREE || price != 0 ) {
  399.                         //Wipe the string, and replace it.
  400.                     for ( q = 0; q < SizeOfArray(str_price); q++ ) str_price[q] = 0;
  401.                     itoa(str_price,price); //Store the price in a string to display it.
  402.                 }
  403.                 else {
  404.                     //Wipe the string, and replace it.
  405.                     for ( q = 0; q < SizeOfArray(str_price); q++ ) str_price[q] = 0;
  406.                     strcat(str_price,free); //Show 'Free' instead of a numeral '0'.
  407.                 }
  408.                 //Set an alternate item info message, using the decimal portion of D3.
  409.                 msg_str = (msg - (msg << 0)) * 10000;
  410.             }
  411.            
  412.             //Draw the shop prices and icons:
  413.            
  414.             //If a tile is set for a rupee icon...
  415.             if ( this->Data != TILE_SOLD_SIGN && this->Data !=TILE_SHOP_CLOSED_FOREVER ) {
  416.                 if ( ( SHOP_TILE_RUPEE_ICON && !SHOP_SHOW_RUPEE_X_FOR_FREE_ITEMS ) ||
  417.                     ( SHOP_TILE_RUPEE_ICON && SHOP_SHOW_RUPEE_X_FOR_FREE_ITEMS && price != 0 ) )
  418.                 {
  419.                         Screen->DrawTile(   SHOP_TILE_RUPEE_ICON_LAYER,
  420.                                     this->X + SHOP_TILE_RUPEE_ICON_X_OFFSET,
  421.                                     this->Y + SHOP_TILE_RUPEE_ICON_Y_OFFSET,
  422.                                     SHOP_TILE_RUPEE_ICON,
  423.                                     SHOP_TILE_RUPEE_ICON_BLOCKW,
  424.                                     SHOP_TILE_RUPEE_ICON_BLOCKH,
  425.                                     SHOP_TILE_RUPEE_ICON_CSET,
  426.                                     SHOP_TILE_RUPEE_ICON_XSCALE,
  427.                                     SHOP_TILE_RUPEE_ICON_YSCALE,
  428.                                     0, 0, 0, 0, true,
  429.                                     SHOP_TILE_RUPEE_ICON_OPACITY);
  430.                 }
  431.                 //If the setting to draw an 'x' between the rupee icon and the price is enabled...
  432.                 if (  ( SHOP_PRICE_DRAW_X_SIGN && !SHOP_SHOW_RUPEE_X_FOR_FREE_ITEMS ) ||
  433.                     ( SHOP_PRICE_DRAW_X_SIGN && SHOP_SHOW_RUPEE_X_FOR_FREE_ITEMS && price != 0 ) )
  434.                         FFC_DrawShopPrice_X_Sign(this); //Draw the 'x'
  435.                
  436.                 //Draw the actual price.
  437.                 if ( ( ( !SHOP_SHOW_ZERO && price !=0 ) || SHOP_SHOW_ZERO && price > -1 ) &&
  438.                     ( ( !SHOP_SHOW_NEGATIVE_PRICE && price > -1 ) || SHOP_SHOW_NEGATIVE_PRICE ) )
  439.                         //Draw the background.
  440.                         Screen->DrawString(
  441.                                     SHOP_PRICE_TEXT_LAYER,
  442.                                     this->X+SHOP_PRICE_TEXT_X_OFFSET_BACKGROUND,
  443.                                     this->Y+SHOP_PRICE_TEXT_Y_OFFSET_BACKGROUND,
  444.                                     SHOP_PRICE_FONT,
  445.                                     SHOP_PRICE_COLOUR_BACKGROUND,
  446.                                     SHOP_PRICE_SIZE,
  447.                                     TF_NORMAL, str_price, OP_OPAQUE); //Background
  448.                         //Draw the foreground.
  449.                         Screen->DrawString(
  450.                                     SHOP_PRICE_TEXT_LAYER,
  451.                                     this->X+SHOP_PRICE_TEXT_X_OFFSET_FOREGROUND,
  452.                                     this->Y+SHOP_PRICE_TEXT_Y_OFFSET_FOREGROUND,
  453.                                     SHOP_PRICE_FONT,
  454.                                     SHOP_PRICE_COLOUR_BACKGROUND,
  455.                                     SHOP_PRICE_SIZE,
  456.                                     TF_NORMAL, str_price, OP_OPAQUE); //Foreground
  457.                        
  458.                 if ( __DistX(this,SHOP_LINK_PROXIMITY_X_TO_ITEM,true) && __DistY(this,SHOP_LINK_PROXIMITY_Y_TO_ITEM,true) && ( __LinkFacing(this) || !SHOP_LINK_MUST_FACE_ITEM ) ) {
  459.                     //Draw the button tile overlay.
  460.                     if ( SHOP_BUY_BUTTON_TILE && !SHOP_BUY_BUTTON_OFFSETS_ARE_FROM_FFC  )   Screen->DrawTile(   SHOP_BUY_BUTTON_TILE_LAYER,
  461.                                                 Link->X + SHOP_BUY_BUTTON_TILE_X_OFFSET,
  462.                                                 Link->Y + SHOP_BUY_BUTTON_TILE_Y_OFFSET,
  463.                                                 SHOP_BUY_BUTTON_TILE,
  464.                                                 SHOP_BUY_BUTTON_TILE_BLOCKW,
  465.                                                 SHOP_BUY_BUTTON_TILE_BLOCKH,
  466.                                                 SHOP_BUY_BUTTON_TILE_CSET,
  467.                                                 -1, -1, 0, 0, 0, 0, true,
  468.                                                 SHOP_BUY_BUTTON_TILE_OPACITY);
  469.                    
  470.                     if ( SHOP_BUY_BUTTON_TILE && SHOP_BUY_BUTTON_OFFSETS_ARE_FROM_FFC  )    Screen->DrawTile(   SHOP_BUY_BUTTON_TILE_LAYER,
  471.                                                 this->X + SHOP_BUY_BUTTON_TILE_X_OFFSET,
  472.                                                 this->Y + SHOP_BUY_BUTTON_TILE_Y_OFFSET,
  473.                                                 SHOP_BUY_BUTTON_TILE,
  474.                                                 SHOP_BUY_BUTTON_TILE_BLOCKW,
  475.                                                 SHOP_BUY_BUTTON_TILE_BLOCKH,
  476.                                                 SHOP_BUY_BUTTON_TILE_CSET,
  477.                                                 -1, -1, 0, 0, 0, 0, true,
  478.                                                 SHOP_BUY_BUTTON_TILE_OPACITY);
  479.                    
  480.                    
  481.                    
  482.                     //Check for input based on the button settings...
  483.                     if  ( SHOP_USE_BUTTON_R && Link->PressR ) { pressed = true; Link->PressR = false; Link->InputR = false; }
  484.                     if  ( SHOP_USE_BUTTON_L && Link->PressL ) { pressed = true; Link->PressL = false; Link->InputL = false; }
  485.                     if  ( SHOP_USE_BUTTON_A && Link->PressA ) { pressed = true; Link->PressA = false; Link->InputA = false; }
  486.                     if  ( SHOP_USE_BUTTON_B && Link->PressB ) { pressed = true; Link->PressB = false; Link->InputB = false; }
  487.                     if  ( SHOP_USE_BUTTON_EX1 && Link->PressEx1 ) { pressed = true; Link->PressEx1 = false; Link->InputEx1 = false; }
  488.                     if  ( SHOP_USE_BUTTON_EX2 && Link->PressEx2 ) { pressed = true; Link->PressEx2 = false; Link->InputEx2 = false; }
  489.                     if  ( SHOP_USE_BUTTON_EX2 && Link->PressEx3 ) { pressed = true; Link->PressEx3 = false; Link->InputEx3 = false; }
  490.                     if  ( SHOP_USE_BUTTON_EX2 && Link->PressEx4 ) { pressed = true; Link->PressEx4 = false; Link->InputEx4 = false; }
  491.  
  492.                    
  493.                     //Show info on ittem, then...
  494.                     //yes/no menu
  495.                     //if ( price <= Game->Counter[CR_RUPEES] ) {
  496.                     //Yes/No
  497.                    
  498.                     if ( this->Data != TILE_SOLD_SIGN && this->Data !=TILE_SHOP_CLOSED_FOREVER && pressed ) { //If Link pressed a button that we want to use...
  499.                         pressed = false; //Clear pressed.
  500.                         if ( !SHOP_FREE_ITEMS_NO_MENU || ( SHOP_FREE_ITEMS_NO_MENU && price != 0) ) choice = BuyYesNo(msg_str,price);
  501.                         if ( choice == 2 || ( SHOP_FREE_ITEMS_NO_MENU && price == 0 ) ) { //Bought it.
  502.                             if ( Game->Counter[counter] >= price ) { //Bought and can buy it...
  503.                                 Game->DCounter[counter] -= price;
  504.                                 if ( sound ) Game->PlaySound(sound);
  505.                                 item it = Screen->CreateItem(itm);
  506.                                 it->X = Link->X;
  507.                                 it->Y = Link->Y;
  508.                                 it->Z = Link->Z;
  509.                                 if ( holdup_type ) {
  510.                                     Link->Action = holdup_type + 3;
  511.                                     Link->HeldItem = itm;
  512.                                 }
  513.                                 if ( (only_once << 0) ) {
  514.                                     //Set the flags.
  515.                                     if ( itemnumber_in_shop == 1 ) {
  516.                                         FFC_SetShopFlag(SHOP_SOLD_ITEM_1, true); if ( ( only_once << 0) > 0 ) replace = true;
  517.                                         if ( ( only_once << 0) < 0 || ( only_once << 0 ) == 1 ) { replace = false; this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  518.                                     }
  519.                                     if ( itemnumber_in_shop == 2 ) { FFC_SetShopFlag(SHOP_SOLD_ITEM_2, true); if ( ( only_once << 0) > 0 ) replace = true;
  520.                                         if ( ( only_once << 0) < 0 || ( only_once << 0 ) == 1 ) { replace = false; this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  521.                                     }
  522.                                     if ( itemnumber_in_shop == 3 ) { FFC_SetShopFlag(SHOP_SOLD_ITEM_3, true); if ( ( only_once << 0) > 0 ) replace = true;
  523.                                         if ( ( only_once << 0) < 0 || ( only_once << 0 ) == 1 ) { replace = false; this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  524.                                     }
  525.                                     if ( itemnumber_in_shop == 4 ) { FFC_SetShopFlag(SHOP_SOLD_ITEM_4, true); if ( ( only_once << 0) > 0 ) replace = true;
  526.                                         if ( ( only_once << 0) < 0 || ( only_once << 0 ) == 1 ) { replace = false; this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  527.                                     }
  528.                                     if ( itemnumber_in_shop == 5 ) { FFC_SetShopFlag(SHOP_SOLD_ITEM_5, true); if ( ( only_once << 0) > 0 ) replace = true;
  529.                                         if ( ( only_once << 0) < 0 || ( only_once << 0 ) == 1 ) { replace = false; this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  530.                                     }
  531.                                     if ( itemnumber_in_shop == 6 ) { FFC_SetShopFlag(SHOP_SOLD_ITEM_6, true); if ( ( only_once << 0) > 0 ) replace = true;
  532.                                         if ( ( only_once << 0) < 0 || ( only_once << 0 ) == 1 ) { replace = false; this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  533.                                     }
  534.                                     if ( itemnumber_in_shop == 7 ) { FFC_SetShopFlag(SHOP_SOLD_ITEM_7, true); if ( ( only_once << 0) > 0 ) replace = true;
  535.                                         if ( ( only_once << 0) < 0 || ( only_once << 0 ) == 1 ) { replace = false; this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  536.                                     }
  537.                                     if ( itemnumber_in_shop == 8 ) { FFC_SetShopFlag(SHOP_SOLD_ITEM_8, true); if ( ( only_once << 0) > 0 ) replace = true;
  538.                                         if ( ( only_once << 0) < 0 || ( only_once << 0 ) == 1 ) { replace = false; this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  539.                                     }
  540.                                     if ( itemnumber_in_shop == 9 ) { FFC_SetShopFlag(SHOP_SOLD_ITEM_9, true); if ( ( only_once << 0) > 0 ) replace = true;
  541.                                         if ( ( only_once << 0) < 0 || ( only_once << 0 ) == 1 ) { replace = false; this->Data = TILE_SOLD_SIGN; drawitem = 0; }
  542.                                     }
  543.                                    
  544.                                    
  545.                                     //{
  546.                                    
  547.                                    
  548.                                    
  549.                                 }
  550.                             }
  551.                             else {
  552.                                 //Errors
  553.                                 if ( SFX_SHOP_ERROR ) Game->PlaySound(SFX_SHOP_ERROR);
  554.                                 if ( MSG_SHOP_ERROR ) Screen->Message(MSG_SHOP_ERROR);
  555.                                
  556.                             }
  557.                         }
  558.                         else choice = 0; //Clear the choice selection.
  559.                     }
  560.                    
  561.                 }
  562.             }
  563.             Waitframe();
  564.         }
  565.     }
  566.    
  567.     //The following three functions are from my std.zh update, with leading underscores added in the event that you upgrade, to prevent conflicts.
  568.     bool __DistX(ffc a, int distance, bool fromcentre) {
  569.         int dist;
  570.         if ( a->X > Link->X ) dist = a->X - Link->X;
  571.         else dist = Link->X - a->X;
  572.         return ( dist <= distance );
  573.     } //Link to ffc distance
  574.     bool __DistY(ffc a, int distance, bool fromcentre) {
  575.         int dist;
  576.         if ( a->Y > Link->Y ) dist = a->Y - Link->Y;
  577.         else dist = Link->Y - a->Y;
  578.         return ( dist <= distance );
  579.     }
  580.     bool __LinkFacing(ffc f){
  581.         if ( Link->Dir == DIR_UP && Link->Y > f->Y ) return true;
  582.         if ( Link->Dir == DIR_DOWN && Link->Y < f->Y ) return true;
  583.         if ( Link->Dir == DIR_RIGHT && Link->X < f->X ) return true;
  584.         if ( Link->Dir == DIR_LEFT && Link->X > f->X ) return true;
  585.         return false;
  586.     }
  587. }
  588.  
  589. ///////////////////////////////
  590. /// FFC to Close Shop Doors ///
  591. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  592. /// Place on the screen with the tile warp that leads Link into the shop.                                ///
  593. /// Place over the tile warp combo (the door/entrance).                                                  ///
  594. /// D0: The *destination* DMap of the tilewarp.                                                          ///
  595. /// D1: The *destination* Screen of the tilewarp.                                                        ///
  596. /// D2: The combo to use as a closed door. Uses SHOP_DEFAULTCLOSED_DOOR_COMBO by default.                ///
  597. /// D3: THe CSet of the closed door.                                                                     ///
  598. /// D4: The solidity of the closed door. If set to '0', the script will default it to '4' (fully solid). ///
  599. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  600. ffc script ShopDoorClosed{
  601.     void run(int dmap, int screen, int combo, int cset, int solid){
  602.         if ( !solid ) solid = 4;
  603.         if ( !combo ) combo = SHOP_DEFAULTCLOSED_DOOR_COMBO;
  604.         bool waiting = true;
  605.         if ( SHOP_DEBUG_ON ) ShopDoorDebug(dmap, screen);
  606.         while(waiting){
  607.             if ( IsShopAllSoldOut(dmap,screen) ){
  608.                 Screen->ComboD[ComboAt(this->X+8, this->Y+8)] = combo;
  609.                 Screen->ComboT[ComboAt(this->X+8, this->Y+8)] = CT_NONE;
  610.                 Screen->ComboC[ComboAt(this->X+8, this->Y+8)] = cset;
  611.                 Screen->ComboS[ComboAt(this->X+8, this->Y+8)] = solid;
  612.                 Screen->ComboF[ComboAt(this->X+8, this->Y+8)] = CF_NONE;
  613.                 Screen->ComboI[ComboAt(this->X+8, this->Y+8)] = 0;
  614.                 waiting = false;
  615.             }
  616.            
  617.             Waitframe();
  618.         }
  619.         this->Data = 0; this->Script = 0; Quit();
  620.     }
  621. }
  622.  
  623. ////////////////////////
  624. /// Global Functions ///
  625. ////////////////////////
  626.  
  627. //Check a shop item sold-out flag.
  628. bool FFC_ShopFlag(int flag){
  629.  
  630.     return ( ( Screen->D[SHOP_REGISTER]<<0 )&flag ) != 0;
  631. }
  632.  
  633. //The same, for remote checks.
  634. bool FFC_ShopFlag(int dmap, int screen, int flag){
  635.     return ( ( Game->GetDMapScreenD(dmap,screen,SHOP_REGISTER) << 0 )&flag ) != 0;
  636. }
  637.  
  638. //Set a shop item sold-out flag.
  639. void FFC_SetShopFlag(int flag, bool state){
  640.     int val[3];
  641.     val[0]= Screen->D[SHOP_REGISTER];
  642.     val[1]= val[0] << 0; //Integer side
  643.     val[2] = val[0] - val[1]; //Decimal side.
  644.     if ( state ) val[1] |= flag;
  645.     else val[1] &= ~flag;
  646.     Screen->D[SHOP_REGISTER] = val[1]+val[2]; //Preserve the decimal, and replace the integer.
  647. }
  648.  
  649. //Returns how many shop item ffcs are running.
  650. int FFC_NumShopItems(){
  651.     ffc f;
  652.     int count;
  653.     int ff[]="ShopItemMenu";
  654.     int ffid = Game->GetFFCScript(ff);
  655.     for ( int q = 1; q <= 32; q++ ){
  656.         f = Screen->LoadFFC(q);
  657.         if ( f->Script == ffid ) count++;
  658.     }
  659.     return count;
  660. }
  661.  
  662. //Stores the number of items in the screen register.
  663. void FFC_SetNumberShopItems(){
  664.     int val[6];
  665.     val[0]= Screen->D[SHOP_REGISTER];
  666.     val[1]= val[0] << 0; //Integer side
  667.     val[2] = val[0] - val[1]; //Decimal side.
  668.     val[3] = val[2] * 10000; //Decimal to Int
  669.     val[4] = FFC_NumShopItems(); //Read how many shops are running.
  670.     val[5] = val[4] / 10000; //Turn it into a decimal.
  671.     Screen->D[SHOP_REGISTER] = val[1]+val[5]; //Preserve the integer, and replace the decimal.
  672. }
  673.  
  674. //Returns te stored value of the number of running shop items.
  675. int FFC_GetNumberShopItems(){
  676.     int val[3];
  677.     val[0]= Screen->D[SHOP_REGISTER];
  678.     val[1]= val[0] << 0; //Integer side
  679.     val[2] = val[0] - val[1]; //Decimal side.
  680.     return val[2] * 10000;
  681. }
  682.  
  683. //Check if all items are sold out. Works only if there ALL items sold out.
  684. bool IsShopAllSoldOut(){
  685.     int shopsold[]={0,1,2,4,8,16,32,64,128,256};
  686.     int count;
  687.     //int numshopitems = FFC_GetNumberShopItems();
  688.    
  689.     //int flag = Screen->D[SHOP_REG] << 0;
  690.     int q;
  691.     if ( SHOP_DEBUG_ON && Link->PressEx1) DebugIsSHopAllSoldOut(shopsold[FFC_GetNumberShopItems()]);
  692.     //int count;
  693.     for ( q = 0; q <= FFC_GetNumberShopItems(); q++ ) {
  694.         count += shopsold[q];
  695.     }
  696.     if ( SHOP_DEBUG_ON ) DebugIsSHopAllSoldOut(count);
  697.     //if ( SHOP_DEBUG_ON ) DebugIsSHopAllSoldOut(shopsold[q]);
  698.     return ( ( Screen->D[SHOP_REGISTER] << 0 ) >= count && shopsold[q] != 0 );
  699.     //return ( ( Screen->D[SHOP_REGISTER] << 0 ) >= shopsold[FFC_GetNumberShopItems()+1] );
  700. }
  701.  
  702. void DebugIsShopAllSoldOutCount(int val){
  703.     int t[]="The combined index value we're comparing against for IsShopAllSoldOut() is: ";
  704.     TraceNL(); TraceS(t); Trace(val);
  705. }
  706.  
  707.  
  708. void DebugIsSHopAllSoldOut(int val){
  709.     int str[]="Doing DebugIsSHopAllSoldOut()";
  710.     TraceNL(); TraceS(str);
  711.     int t[]="IsShopAllSoldOut() array value selected is: ";
  712.     TraceNL(); TraceS(t); Trace(val);
  713.     int tt[]="and the flag is: ";
  714.     TraceNL(); TraceS(tt); Trace(Screen->D[SHOP_REGISTER] << 0);
  715. }
  716.  
  717. //Draw the 'x' between the rupee icon and the price.
  718. void FFC_DrawShopPrice_X_Sign(ffc f){
  719.     int x[]="x";
  720.     Screen->DrawString(SHOP_PRICE_DRAW_X_SIGN_LAYER, f->X+SHOP_PRICE_DRAW_X_SIGN_X_OFFSET_BACKGROUND, f->Y+SHOP_PRICE_DRAW_X_SIGN_Y_OFFSET_BACKGROUND,
  721.             SHOP_PRICE_DRAW_X_SIGN_FONT, SHOP_PRICE_DRAW_X_SIGN_COLOUR_BACKGROUND, SHOP_PRICE_DRAW_X_SIGN_SIZE, TF_NORMAL, x, OP_OPAQUE); //Background
  722.     Screen->DrawString(SHOP_PRICE_DRAW_X_SIGN_LAYER, f->X+SHOP_PRICE_DRAW_X_SIGN_X_OFFSET_FOREGROUND, f->Y+SHOP_PRICE_DRAW_X_SIGN_Y_OFFSET_FOREGROUND,
  723.             SHOP_PRICE_DRAW_X_SIGN_FONT, SHOP_PRICE_DRAW_X_SIGN_COLOUR_FOREGROUND, SHOP_PRICE_DRAW_X_SIGN_SIZE, TF_NORMAL, x, OP_OPAQUE); //Background
  724. }
  725.  
  726. // A simple debug function that reports the present status of the shop flags.
  727. void ShopDebug(){
  728.     int t[]="Screen->D[SHOP_REGISTER] <<  0 is: ";
  729.     TraceNL(); TraceS(t); Trace( Screen->D[SHOP_REGISTER] << 0);
  730.    
  731.     int tttt[]="FFC_NumShopItems() returned: ";
  732.     int tttt1[]="This is the value read by checking how many ffcs are running the shop script.";
  733.     TraceNL(); TraceS(tttt); Trace(FFC_NumShopItems()); TraceNL(); TraceS(tttt1);
  734.    
  735.     int tt[]=" FFC_GetNumberShopItems()  returned: ";
  736.     int tt1[]="This is the number of shop items, based on the value in Screen->D.";
  737.     TraceNL(); TraceS(tt); Trace( FFC_GetNumberShopItems() ); TraceNL(); TraceS(tt1);
  738.    
  739.     int ttt[]=" IsShopAllSoldOut() returned:  ";
  740.     TraceNL(); TraceS(ttt); TraceB( IsShopAllSoldOut() );
  741.    
  742. }
  743.  
  744. void ShopDoorDebug(int dmap, int scr){
  745.     int t[]="FFC_GetNumberShopItems() returned: ";
  746.     TraceNL(); TraceS(t); Trace(FFC_GetNumberShopItems(dmap,scr));
  747.     int tt[]="IsShopAllSoldOut() returned: ";
  748.     TraceNL(); TraceS(tt); TraceB(IsShopAllSoldOut(dmap,scr));
  749. }
  750.  
  751. void DebugIsSHopAllSoldOutRemote(int val){
  752.     int t[]="IsShopAllSoldOut(dmap,screen) array value selected is: ";
  753.     TraceNL(); TraceS(t); Trace(val);
  754. }
  755.  
  756. //! Remote flag checking.
  757.  
  758. //Returns the stored value of the number of running shop items on the Screen 'screen' of DMap 'dmap'.
  759. int FFC_GetNumberShopItems(int dmap, int screen){
  760.     int val[3];
  761.     val[0]= Game->GetDMapScreenD(dmap,screen,SHOP_REGISTER);
  762.     val[1]= val[0] << 0; //Integer side
  763.     val[2] = val[0] - val[1]; //Decimal side.
  764.     return val[2] * 10000;
  765. }
  766.  
  767. //Check if all items are sold out. Works only if there ALL items sold out on the Screen 'screen' of DMap 'dmap'.
  768. bool IsShopAllSoldOut(int dmap, int screen){
  769.     int shopsold[]={0,1,2,4,8,16,32,64,128,256};
  770.     if ( SHOP_DEBUG_ON ) DebugIsSHopAllSoldOutRemote(shopsold[FFC_GetNumberShopItems(dmap,screen)]);
  771.     int count; int q;
  772.     for ( q = 0; q <= FFC_GetNumberShopItems(dmap,screen); q++ ) {
  773.         count += shopsold[q];
  774.     }
  775.     return ( ( Game->GetDMapScreenD(dmap,screen,SHOP_REGISTER) << 0 ) >= count && shopsold[q] != 0 && (Game->GetDMapScreenD(dmap,screen,SHOP_REGISTER) << 0) !=0 && !FFC_ShopFlag(dmap, screen, SHOP_STAY_OPEN));
  776.     //return ( ( Screen->D[SHOP_REGISTER] << 0 ) >= count );
  777.     //return ( ( Game->GetDMapScreenD(dmap,screen,SHOP_REGISTER) << 0 ) > shopsold[FFC_GetNumberShopItems(dmap,screen)] );
  778. }
  779.  
  780. /////////////////////
  781. /// Shop Darkness ///
  782. /////////////////////
  783.  
  784. //Call before Waitdraw in global active script.
  785. void FFC_ShopDarkness(){
  786.     if ( Screen->D[SHOP_REGISTER] ) {
  787.         if ( IsShopAllSoldOut( Game->GetCurDMap(), Game->GetCurScreen() ) ){
  788.             for ( int q = 0; q < SHOP_DARKNESSS_NUM_LAYERS; q++ )
  789.             Screen->Rectangle(SHOP_DARKNESS_LAYER, 0, 0, 255, 175, SHOP_DARKNESS_COLOUR, SHOP_DARKNESS_SCALE, 0, 0, 0, true, SHOP_DARKNESS_OPACITY);  
  790.         }
  791.     }
  792. }
  793.  
  794. //The 'yes/no' menu called by the ffc.
  795. int BuyYesNo(int msg, int price) {
  796.  
  797.     int lineBreak[]="@26";
  798.     int line1[]="@choice(1)Item Info@26";
  799.     int line2[]="@choice(2)Buy@26@choice(3)Cancel@domenu(1)@suspend()";
  800.     int free[]="@choice(2)Take@26@choice(3)Cancel@domenu(1)@suspend()";
  801.    
  802.     SetUpWindow(WINDOW_SLOT_1, WINDOW_STYLE_3, 32, 32, SIZE_LARGE);
  803.         Tango_LoadString(WINDOW_SLOT_1, line1);
  804.     if ( price == 0 ) Tango_AppendString(WINDOW_SLOT_1, free);
  805.         else Tango_AppendString(WINDOW_SLOT_1, line2);
  806.         Tango_ActivateSlot(WINDOW_SLOT_1);
  807.  
  808.    
  809.     while(!Tango_MenuIsActive()){
  810.        
  811.         Waitframe();
  812.     }
  813.    
  814.     // Save the state again...
  815.     int slotState[278];
  816.     int menuState[960];
  817.     int cursorPos;
  818.     Tango_SaveSlotState(WINDOW_SLOT_1, slotState);
  819.     Tango_SaveMenuState(menuState);
  820.    
  821.     int done = 0;
  822.     int choice;
  823.     while(true){
  824.    
  825.         while( Tango_MenuIsActive() ) {
  826.             cursorPos=Tango_GetMenuCursorPosition();
  827.             Waitframe();
  828.         }
  829.        
  830.         choice = Tango_GetLastMenuChoice();
  831.         if ( choice == 1 ) { // Item Info
  832.             int text[256];
  833.             Game->GetMessage(msg,text); //Load msg into the buffer.
  834.             ShowString(text, WINDOW_SLOT_2, WINDOW_STYLE_3, 48, 48);
  835.         }
  836.         else if ( choice == 2 ) { //Buy
  837.             done = choice;
  838.             menuArg = choice;
  839.         }
  840.        
  841.         else if ( choice == 3 ) { //Cancel
  842.             done = choice;
  843.         }
  844.        
  845.         else if ( Link->PressEx1 ) {
  846.             done = 1;
  847.         }
  848.         else done = 3;
  849.  
  850.         if ( done ) {
  851.             break;
  852.         //  return choice;
  853.         }
  854.         else {
  855.             Tango_RestoreSlotState(WINDOW_SLOT_1, slotState);
  856.             Tango_RestoreMenuState(menuState);
  857.             Tango_SetMenuCursorPosition(cursorPos);
  858.         }
  859.     }
  860.    
  861.     Tango_ClearSlot(WINDOW_SLOT_1);
  862.     return done;
  863. }
  864.  
  865. //Global Scripts
  866.  
  867. //Mandatory init script: If you already have an init script, merge them.
  868. global script Init {
  869.     void run(){
  870.  
  871.         SetCommonStyleData(WINDOW_STYLE_1);
  872.         SetCommonStyleData(WINDOW_STYLE_2);
  873.         SetCommonStyleData(WINDOW_STYLE_3);
  874.     }
  875. }
  876.  
  877.  
  878. //Example global active (slot 2) script.
  879. global script Tango{
  880.    
  881.     void run(){
  882.         if ( SHOP_DEBUG_ON ) ClearTrace();
  883.         Tango_Start();
  884.         StartGhostZH();
  885.        
  886.         while(true) {
  887.             UpdateGhostZH1();
  888.             Tango_Update1();
  889.            
  890.             if ( SHOP_DARK_WHEN_CLOSED ) FFC_ShopDarkness(); //Manages shop darkness.
  891.            
  892.             Waitdraw();
  893.            
  894.             UpdateGhostZH2();
  895.             Tango_Update2();
  896.             Waitframe();
  897.         }
  898.  
  899.     }
  900. }
  901.  
  902.  
  903.  
  904.  
  905. //////////////////
  906. /// DEPRECATED ///
  907. //////////////////
  908.  
  909. //Draws the darkness layer.
  910. void ShopSoldOut(){
  911.     for ( int q = 0; q < SHOP_DARKNESSS_NUM_LAYERS; q++ )
  912.         Screen->Rectangle(SHOP_DARKNESS_LAYER, 0, 0, 255, 175, SHOP_DARKNESS_COLOUR, SHOP_DARKNESS_SCALE, 0, 0, 0, true, SHOP_DARKNESS_OPACITY);  
  913. }
  914.  
  915.  
  916. //The ffc that makes the screen dark.
  917. ffc script ShopDarknessFFC{
  918.     void run(){
  919.         while(true){
  920.             if ( IsShopAllSoldOut() && SHOP_DARK_WHEN_CLOSED ) ShopSoldOut(); //Draw dark layer if setting enabled.
  921.             Waitframe();
  922.         }
  923.     }
  924. }
  925.  
  926. //Draws darkness effect if the shop is sold out, and the setting is enabled.
  927. int FFC_GetShopDarkness(){
  928.     int ff[]="ShopDarknessFFC";
  929.     return Game->GetFFCScript(ff);
  930. }
  931.  
  932. void TracePrice(int val){
  933.     int t[]="Tracing price: ";
  934.     TraceNL(); TraceS(t); Trace(val);
  935. }
RAW Paste Data