| 
 RE: KyoDiscounts XP VX, ACE MV - kyonides -  01-14-2019
 
 Well, I decided to post the latest version of KyoDiscounts XP 1.5.0, even if it is some sort of beta release.
 
 Edit: I had to include some method calls to get rid of the appraisal options window and the appraisal result window contents.
 Another Edit: I had to reduce some windows sizes to fit the screen... =_=
 
 
 Code: # * KyoDiscounts XP#   Scripter : Kyonides-Arkanthes
 #   v1.5.0 - 2019-01-13
 
 #   Whenever you obtain a discount card, such discount will be applied to all
 #   of your purchases if you have picked a card till it expires after a certain
 #   number of steps. Additional steps will be quickly added to your current card
 #   whenever you purchase any additional card of the same kind.
 
 #   One coupon will be spent every single time you purchase any specific item,
 #   you will need another one to purchase a different item later on.
 #   The discount card or coupon price is used to calculate the corresponding
 #   discount on every single purchase the player makes with it.
 
 #   Place this script below KItemRefill XP or KyoScriptPack Item XP if you
 #   included any of those scripts in your current game project.
 
 #   Now you can also setup exclusive store discount cards as well. Just keep in
 #   mind that you will need to setup the in game variable you picked so it will
 #   be able to store the Exclusive Store Code (an Integer) before you can add
 #   the shop event command. Common stores don't need any Store Code at all.
 
 #   Besides the player can also place orders to get an item that is supposed to
 #   be found at another store only. The player will be charged an extra fee, but
 #   he or she won't need to go back to another store. The player would only need
 #   to keep walking for a while before the goods are available at the store.
 #   Now the required steps for each placed order will be automatically increased
 #   between 0% and 50%, making it look a bit random but also kind of realistic.
 
 # * Unknown Item or Weapon or Armor Appraisals *
 
 #   Use the Game Variable defined in the STORECODEVARID Constant to store the
 #   Shop ID that will include the appraisal service.
 #   Use the MYSTERIOUS series of Arrays to include as many IDs of unknown items
 #   or weapons or armors that will serve as fillers till they get replaced by
 #   the actual goods they represent.
 #   Follow the Instructions included in the APPRAISALS Hash to define all
 #   conditions that will affect an appraiser's task of identifying the item.
 
 #   Script Calls   #
 
 #   $game_party.discount_cards_expire
 #      Makes all Discount Cards expire as part of the game's plot.
 
 #   $game_party.disc_card_expire(Card_ID)
 #      Makes an specific Discount Card expire as part of the game's plot.
 
 #   KyoShopOrders << [Percent1, Percent2, etc.]
 #      Defines a Commission percent for every Item in the Place Order List.
 
 #   KyoShopOrders.steps = [Steps1, Steps2, etc.]
 #   KyoShopOrders.steps += [Steps5, Steps6, etc.]
 #      Defines Steps required by every Order in the Place Order List.
 #      The 2nd call will be required only if you couldn't include all steps.
 
 #   KyoShop.scarcity_lvl = 0 or higher
 #     Define all prices and maximum number of units per shop item.
 #     0 means no scarcity, 1 or higher reflects how severe it is.
 #     You also have to configure the @scarce_limits hash in order to predefine
 #     :price and :max per scarcity level. The maximum scarcity level depends on
 #     how many values you entered in both :price and :max arrays.
 #     In few words, you define the maximum scarcity level ever possible!
 
 module KyoShop
 # Maximum number of units for each shop item
 NUMBERMAX = 99
 # Button that will open the Discount window while on the shop menu
 DISCOUNTBUTTON = Input::A
 # Add Discount Card Object IDs
 DISCOUNT_IDS = [33, 34]
 # Add Discount Coupon Object IDs
 COUPON_IDS = [36, 37]
 # Maximum Steps before Discount Card expires : ID => Steps
 STEPS = { 33 => 500, 34 => 300, 35 => 150 }
 # Exclusive Stores In Game Variable ID
 STORECODEVARID = 1
 # Exclusive Stores List : Object ID => Exclusive Store Code
 EXCLUSIVESTORES = { 35 => 102 }
 # Switch ID : deactivates Store to add Goods found elsewhere
 GOODSSWITCHID = 1
 # Store IDs for stores where you have invested some gold
 INVESTSTOREIDS = [101]
 # Maximum Number of Shares & Share Price
 SHARESMAXMIN = [10000, 100]
 INVESTMENTS = {} # Store Investments - Do Not Edit This Line
 INVESTMENTS.default = {} # Do Not Edit This Line
 # Available Improvements #
 # :discount : [:discount, 25]
 # :goods    : [:goods, 'i10', 'w4', 'a6']
 # :orders   : [:orders, 'i11', 'w5', 'a7']
 # [Store ID] = { Shares => Prize, Shares => Another Prize, etc. }
 INVESTMENTS[101] = { 50 => [:goods,'i10','w5','a6'], 100 => [:discount,10] }
 APPRAISALS = {} # Do Not Edit This Line!
 # [Store ID] = { appraisal cost => $, estimate cost => $, success rate => %,
 #            bad result => "item1", goods => [item4, weapon2, armor3, etc.] }
 APPRAISALS[101] = { :cost => 150, :test_cost => 75, :rate => 10,
 :default => 'i1', :goods => ['i2','i3','i9','i10'] }
 # Add Item IDs for unknown shop goods that need to be appraised by experts
 MYSTERIOUSITEMS = []
 # Add Weapon IDs for unknown shop goods that need to be appraised by experts
 MYSTERIOUSWEAPONS = []
 # Add Armor IDs for unknown shop goods that need to be appraised by experts
 MYSTERIOUSARMORS = []
 @scarce_limits = {
 :price  => [0, 25, 50, 100, 250, 350, 500, 650, 800],
 :max => [NUMBERMAX, NUMBERMAX - 10, NUMBERMAX - 25, NUMBERMAX - 35,
 NUMBERMAX - 50, NUMBERMAX - 65, NUMBERMAX - 80, NUMBERMAX - 90, 1]
 #:item => [1, 2, 3, 4, 5, 6],
 #:weapon => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
 #:armor => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
 }
 @scarce_lvl = 0 # Initial Level
 def self.current_item_max() @scarce_limits[:max][@scarce_lvl] end
 def self.current_price_max() @scarce_limits[:price][@scarce_lvl] end
 def self.scarcity_limits() @scarce_limits end
 def self.scarcity_lvl() @scarce_lvl end
 def self.scarcity_lvl=(lvl) @scarce_lvl = lvl end
 end
 
 module KyoShopLabels
 # Basic Shop Command Labels
 BASIC = ["Buy", "Sell", "Exit"]
 MOREOPTIONS = "Options"
 # Buy Stuff & Place Order & Pick Up Items Label
 BUYPLACEPICKUP = ['Buy Items', 'Place Order', 'Pick Up Items',
 'Appraise', 'Invest']
 # Subtotal, Commission Percent and Total Amount
 PRICELABELS = ['Subtotal', 'Commission %', 'Total']
 # Place an Order Label
 PLACEORDER = 'Do you wish to place an order?'
 # Pick Up Order Label
 PICKUPORDER = 'Do you want to pick up an order?'
 # No Order Found Label
 NOORDERFOUND = 'There is nothing left, boss!'
 # Available Discounts Label
 SOMEDISCOUNTS = 'Press A to get a discount'
 # No Discount Available Label
 NODISCOUNTS = 'No Discount Available'
 # Select a Discount Card or Coupon Label
 SELECTDISCOUNT = 'Choose a Card or Coupon'
 # Apply Discount Label
 APPLYDISCOUNT = "Discount Applied %s%"
 # Warning about Extra Fees for Placing Orders
 FEESAPPLY = 'Extra Fees Apply'
 # Discount Card's Steps Left Label
 STEPSLEFT = " %s steps left."
 # Investment Label...
 INVESTMENT = 'Want to invest in this store?'
 # Share Number Label
 SHARES = 'Share Number'
 # Adquired or Purchased Shares Label
 TOTALSHARES = 'Total Shares'
 # Pick Item to be Appraised Label
 APPRAISALMENULABEL = "Appraisal Menu"
 # Appraisal Window Labels
 APPRAISALLABELS = ["Quick Test Cost", "Normal Cost"]
 # Appraisal Options Labels
 APPRAISALOPTIONS = ["Quick Test", "Detailed Test", "Cancel"]
 # Appraisal End Result Labels
 APPRAISALRESULTLABELS = [
 "The item at hand is nothing else but... %s",
 "I think it might be worth some... %s"
 ]
 end
 # DO NOT EDIT ANYTHING ELSE #
 module KyoShopOrders
 @commissions = []
 @steps = []
 class << self
 attr_accessor :store_event_id, :goods_id
 attr_reader :steps, :commissions
 def steps=(val) @steps = val.map {|n| n + rand((n / 2) + 2) } end
 def <<(val)
 @commissions += val
 @commissions = @commissions.flatten
 end
 end
 end
 
 module WindowModule
 def appear
 self.active = true
 self.visible = true
 end
 
 def disappear
 self.active = false
 self.visible = false
 end
 end
 
 class Game_System
 attr_accessor :shop_goods
 attr_reader :placed_orders, :shop_shares
 alias kyon_discounts_gm_sys_init initialize
 def initialize
 @shop_goods = []
 @placed_orders = {}
 @placed_orders.default = []
 @shop_shares = {}
 @shop_shares.default = 0
 kyon_discounts_gm_sys_init
 end
 
 def disc_store?(disc_id) !KyoShop::EXCLUSIVESTORES[disc_id] end
 
 def excl_disc_store?(disc_id)
 exclusive = KyoShop::EXCLUSIVESTORES[disc_id]
 $game_variables[KyoShop::STORECODEVARID] == exclusive
 end
 
 def check_shares(shop_id)
 results = []
 shares = @shop_shares[shop_id]
 investments = KyoShop::INVESTMENTS[shop_id]
 limits = KyoShop::INVESTMENTS[shop_id].keys.sort
 results = investments.select{|limit| shares >= limit[0] }.map {|r| r[1] }
 end
 end
 
 class Game_Party
 attr_reader :discounts
 alias kyon_discounts_gm_party_init initialize
 alias kyon_discounts_gm_party_gain_item gain_item
 def initialize
 @discounts = {}
 kyon_discounts_gm_party_init
 end
 
 def gain_item(item_id, n)
 kyon_discounts_gm_party_gain_item(item_id, n)
 return if item_id == 0 or n == 0
 return unless KyoShop::DISCOUNT_IDS.include?(item_id)
 if @discounts[item_id]
 @discounts[item_id] += KyoShop::STEPS[item_id]
 @items[item_id] = 1
 else
 @discounts[item_id] = KyoShop::STEPS[item_id]
 end
 end
 
 def check_discounts
 unless @discounts.empty?
 for did in KyoShop::DISCOUNT_IDS
 next unless @discounts[did] and @discounts[did] > 0
 return true if $game_system.disc_store?(did)
 return true if $game_system.excl_disc_store?(did)
 end
 end
 for cid in KyoShop::COUPON_IDS
 next unless item_number(cid) > 0
 return true if $game_system.disc_store?(cid)
 return true if $game_system.excl_disc_store?(cid)
 end
 return false
 end
 
 def decrease_discounts
 KyoShop::DISCOUNT_IDS.each {|n| next unless @discounts[n]
 @discounts[n] -= 1 if @discounts[n] > 0 }
 end
 
 def discount_cards_expire
 KyoShop::DISCOUNT_IDS.each {|n| @discounts[n] = 0 if @discounts[n] }
 end
 
 def disc_card_expire(dc_id) @discounts[dc_id] = 0 end
 end
 
 class Game_Player
 alias kyon_discounts_coupons_gm_player_increase_steps increase_steps
 def increase_steps
 kyon_discounts_coupons_gm_player_increase_steps
 $game_party.decrease_discounts
 end
 end
 
 class Window_Selectable
 include WindowModule
 end
 
 class Window_Help
 def set_text(item_id, text=nil, align=0)
 if item_id.is_a?(String)
 if KyoShop::DISCOUNT_IDS.include?(KyoShopOrders.goods_id)
 steps = $game_party.discounts[KyoShopOrders.goods_id].to_s
 text = item_id + sprintf(KyoShopLabels::STEPSLEFT, steps)
 KyoShopOrders.goods_id = item_id = nil
 end
 end
 if text.is_a?(String)
 text = text.gsub(/\\[Uu]/){$game_system.refill_items[item_id].sips.to_s}
 elsif text.is_a?(Integer)
 align = text
 text = item_id
 else
 text = item_id
 end
 if text != @text or align != @align
 self.contents.clear
 self.contents.font.color = normal_color
 self.contents.draw_text(4, 0, self.width - 40, 32, text, align)
 @text = text
 @align = align
 @actor = nil
 end
 self.visible = true
 end
 end
 
 class Window_Item
 alias kyon_discounts_win_item_up_help update_help
 def update_help
 KyoShopOrders.goods_id = self.item.id
 kyon_discounts_win_item_up_help
 end
 end
 
 class AppraiseItemWindow < Window_Selectable
 include WindowModule
 def initialize
 super(0, 64, 480, 320)
 @column_max = 1
 refresh
 self.index = 0
 end
 
 def refresh
 if self.contents != nil
 self.contents.dispose
 self.contents = nil
 end
 @data = []
 for n in KyoShop::MYSTERIOUSITEMS
 next if $game_party.item_number(n) == 0
 @data << $data_items[n]
 end
 for i in KyoShop::MYSTERIOUSWEAPONS
 next if $game_party.weapon_number(i) == 0
 @data << $data_weapons[i]
 end
 for i in KyoShop::MYSTERIOUSARMORS
 next if $game_party.armor_number(i) == 0
 @data << $data_armors[i]
 end
 @item_max = @data.size
 return if @item_max == 0
 self.contents = Bitmap.new(width - 32, row_max * 32)
 @item_max.times{|i| draw_item(i) }
 end
 
 def draw_item(index)
 item = @data[index]
 number = case item
 when RPG::Item then $game_party.item_number(item.id)
 when RPG::Weapon then $game_party.weapon_number(item.id)
 when RPG::Armor then $game_party.armor_number(item.id)
 end
 c = self.contents
 x = 4 + index % 2 * (288 + 32)
 y = index / 2 * 32
 rect = Rect.new(x, y, self.width / @column_max - 32, 32)
 c.fill_rect(rect, Color.new(0, 0, 0, 0))
 bit = RPG::Cache.icon(item.icon_name)
 c.blt(x, y + 4, bit, Rect.new(0, 0, 24, 24), 255)
 c.draw_text(x + 28, y, 212, 32, item.name, 0)
 c.draw_text(x + 240, y, 16, 32, ":", 1)
 c.draw_text(x + 256, y, 24, 32, number.to_s, 2)
 end
 def item() @data[@index] end
 def empty?() @data.empty? end
 end
 
 class AppraiseInfoWindow < Window_Base
 def initialize(store_id)
 super(480, 128, 160, 256)
 @data = KyoShop::APPRAISALS[store_id]
 @labels = KyoShopLabels::APPRAISALLABELS.dup
 @currency = $data_system.words.gold
 self.contents = Bitmap.new(width - 32, height - 32)
 refresh
 end
 
 def refresh
 aw = width - 32
 contents.clear
 contents.font.color = system_color
 contents.draw_text(0, 0, aw, 24, @labels[0])
 contents.draw_text(0, 48, aw, 24, @labels[1])
 contents.draw_text(0, 24, aw, 24, @currency, 2)
 contents.draw_text(0, 72, aw, 24, @currency, 2)
 contents.font.color = normal_color
 contents.draw_text(0, 24, width - 48, 24, @data[:test_cost].to_s, 2)
 contents.draw_text(0, 72, width - 48, 24, @data[:cost].to_s, 2)
 end
 end
 
 class AppraiseResultWindow < Window_Base
 def initialize
 super(0, 384, 640, 96)
 @labels = KyoShopLabels::APPRAISALRESULTLABELS.dup
 @currency = $data_system.words.gold
 self.contents = Bitmap.new(width - 32, height - 32)
 end
 
 def refresh(item)
 contents.clear
 result = sprintf(@labels[0], item.name)
 cost = sprintf(@labels[1], item.price) + " " + @currency
 contents.draw_text(0, 0, width - 32, 24, result)
 contents.draw_text(0, 24, width - 32, 24, cost)
 end
 end
 
 class Window_ShopCommand
 def initialize
 super(0, 64, 480, 64)
 self.contents = Bitmap.new(width - 32, height - 32)
 @item_max = 3
 @column_max = 3
 @commands = KyoShopLabels::BASIC.dup
 if KyoShop::APPRAISALS[$game_variables[KyoShop::STORECODEVARID]]
 @commands[0] = KyoShopLabels::MOREOPTIONS.dup
 end
 refresh
 self.index = 0
 end
 end
 
 class Window_ShopBuy
 attr_accessor :discount
 def initialize(shop_goods)
 super(0, 128, 368, 288)
 @shop_goods = shop_goods
 @discount = 0
 refresh
 self.index = 0
 end
 
 def deliver(goods)
 @shop_goods = goods
 if goods.size - 1 < @index
 @index = goods.size > 0 ? (@index + goods.size - 1) % goods.size : 0
 update_cursor_rect
 end
 refresh
 self.index = 0
 end
 
 def draw_item(index)
 item = @data[index]
 number = case item
 when RPG::Item then $game_party.item_number(item.id)
 when RPG::Weapon then $game_party.weapon_number(item.id)
 when RPG::Armor then $game_party.armor_number(item.id)
 end
 enough = (item.price <= $game_party.gold and number < 99)
 self.contents.font.color = enough ? normal_color : disabled_color
 y = index * 32
 rect = Rect.new(4, y, self.width - 32, 32)
 self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
 bitmap = RPG::Cache.icon(item.icon_name)
 opacity = enough ? 255 : 128
 self.contents.blt(4, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
 self.contents.draw_text(32, y, 212, 32, item.name, 0)
 price = item.price - item.price * @discount / 100
 self.contents.draw_text(244, y, 88, 32, price.to_s, 2)
 end
 end
 
 class Window_ShopPickUp < Window_ShopBuy
 def refresh
 if self.contents != nil
 self.contents.dispose
 self.contents = nil
 end
 @data = []
 for good in @shop_goods
 new_item = case good[0]
 when 0 then $data_items[good[1]]
 when 1 then $data_weapons[good[1]]
 when 2 then $data_armors[good[1]]
 end
 @data << new_item if new_item
 end
 @item_max = @data.size
 return if @item_max == 0
 self.contents = Bitmap.new(width - 32, row_max * 32)
 (0...@item_max).each {|i| draw_item(i) }
 end
 
 def draw_item(index)
 item = @data[index]
 qty, steps = @shop_goods[index][2..3]
 number = case item
 when RPG::Item then $game_party.item_number(item.id)
 when RPG::Weapon then $game_party.weapon_number(item.id)
 when RPG::Armor then $game_party.armor_number(item.id)
 end
 enough = (number + qty < 100 and steps <= $game_party.steps)
 self.contents.font.color = enough ? normal_color : disabled_color
 y = index * 32
 rect = Rect.new(4, y, self.width - 32, 32)
 self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
 bitmap = RPG::Cache.icon(item.icon_name)
 opacity = enough ? 255 : 128
 self.contents.blt(4, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
 self.contents.draw_text(32, y, 212, 32, item.name, 0)
 self.contents.draw_text(244, y, 88, 32, qty.to_s, 2)
 end
 undef discount, discount=
 end
 
 class Window_ShopNumber
 include WindowModule
 def initialize
 super(0, 128, 368, 288)
 self.contents = Bitmap.new(width - 32, height - 32)
 @item = nil
 @max = 1
 @price = 0
 @number = 1
 @multiplier = 1
 end
 
 def reset_multiplier
 @multiplier = 1
 @number = 1
 refresh
 end
 
 def set(item, max, price, percent=nil, multiplier=1)
 @item = item
 @max = max
 @price = price
 @number = 1
 @multiplier = multiplier
 @percent = percent
 refresh
 end
 
 def update
 super
 return unless self.active
 if Input.repeat?(Input::RIGHT) and @number < @max
 $game_system.se_play($data_system.cursor_se)
 @number += @multiplier
 refresh
 end
 if Input.repeat?(Input::LEFT) and @number > @multiplier
 $game_system.se_play($data_system.cursor_se)
 @number -= @multiplier
 refresh
 end
 if Input.repeat?(Input::UP) and @number < @max
 $game_system.se_play($data_system.cursor_se)
 @number = [@number + 10 * @multiplier, @max].min
 refresh
 end
 if Input.repeat?(Input::DOWN) and @number > @multiplier
 $game_system.se_play($data_system.cursor_se)
 @number = [@number - 10 * @multiplier, 1].max
 refresh
 end
 end
 
 def refresh
 self.contents.clear
 draw_item_name(@item, 4, 96)
 self.contents.font.color = normal_color
 if @multiplier == 1
 cx1, cx2, cx3, cw1, cw2 = [272, 308, 304, 24, 32]
 else
 cx1, cx2, cx3, cw1, cw2 = [260, 264, 272, 68, 64]
 end
 self.contents.draw_text(cx1, 96, 32, 32, "")
 self.contents.draw_text(cx2, 96, cw1, 32, @number.to_s, 2)
 self.cursor_rect.set(cx3, 96, cw2, 32)
 gold = $data_system.words.gold
 cx = contents.text_size(gold).width
 subtotal_price = @item.price * @number
 total_price = @price * @number
 labels = KyoShopLabels::PRICELABELS
 if total_price > subtotal_price and @multiplier < 2
 self.contents.font.color = system_color
 self.contents.draw_text(120, 128, 100, 32, labels[0], 2)
 self.contents.draw_text(332-cx, 128, cx, 32, gold, 2)
 self.contents.draw_text(80, 160, 140, 32, labels[1], 2)
 self.contents.draw_text(328-cx, 160, cx + 4, 32, '%', 2)
 self.contents.font.color = normal_color
 self.contents.draw_text(4, 128, 328-cx-2, 32, subtotal_price.to_s, 2)
 self.contents.draw_text(4, 160, 328-cx-2, 32, @percent.to_s, 2)
 end
 self.contents.draw_text(4, 192, 328-cx-2, 32, total_price.to_s, 2)
 self.contents.font.color = system_color
 self.contents.draw_text(120, 192, 100, 32, labels[2], 2)
 self.contents.draw_text(332-cx, 192, cx, 32, gold, 2)
 end
 end
 
 class Window_ShopBuyOptions < Window_Selectable
 def initialize
 commands = KyoShopLabels::BUYPLACEPICKUP.dup
 varid = $game_variables[KyoShop::STORECODEVARID]
 commands.pop unless KyoShop::INVESTSTOREIDS.include?(varid)
 super(214, 148, 212, commands.size * 32 + 32)
 @commands = commands
 @item_max = @commands.size
 self.contents = Bitmap.new(width - 32, @item_max * 32)
 refresh
 self.index = 0
 end
 
 def refresh
 self.contents.clear
 @item_max.times {|i| @commands[i]
 contents.draw_text(4, i * 32, 172, 32, @commands[i]) }
 end
 end
 
 class Window_ShopDiscountAlert < Window_Base
 def initialize
 super(0, 416, 368, 64)
 self.contents = Bitmap.new(width - 32, height - 32)
 end
 
 def set_text(text)
 self.contents.clear
 self.contents.draw_text(0, 0, width - 32, height - 32, text)
 end
 end
 
 class Window_ShopDiscountCoupon < Window_Selectable
 def initialize
 super(0, 128, 368, 288)
 self.index = 0
 refresh
 end
 
 def item() @data[@index] end
 
 def refresh
 if self.contents != nil
 self.contents.dispose
 self.contents = nil
 end
 @data = []
 dc_ids = $game_party.discounts.keys.sort
 dc_ids.each {|i| next if $game_party.discounts[i] == 0
 next if !$game_system.disc_store?(i) and !$game_system.excl_disc_store?(i)
 @data << $data_items[i] }
 KyoShop::COUPON_IDS.each {|i| next unless $game_party.item_number(i) > 0
 @data << $data_items[i] }
 @item_max = @data.size
 return if @item_max == 0
 self.index -= 1 if @index > @item_max - 1
 self.contents = Bitmap.new(width - 32, row_max * 32)
 (0...@item_max).each {|i| draw_item(i) }
 end
 
 def draw_item(index)
 item = @data[index]
 number = $game_party.item_number(item.id)
 x = 4
 y = index * 32
 rect = Rect.new(x, y, self.width - 32, 32)
 self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
 bitmap = RPG::Cache.icon(item.icon_name)
 self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), 255)
 self.contents.draw_text(x + 28, y, 212, 32, item.name)
 self.contents.draw_text(x + 28, y, 244, 32, ': ' + number.to_s, 2)
 end
 
 def update_help
 KyoShopOrders.goods_id = self.item.id
 @help_window.set_text(self.item.description)
 end
 end
 
 class Window_ShopStatus
 alias kyon_discounts_win_shop_status_refresh refresh
 def refresh
 if @investment
 refresh_investment
 return
 end
 kyon_discounts_win_shop_status_refresh
 end
 
 def investment=(bool)
 @investment = bool
 refresh
 end
 
 def refresh_investment
 shares = $game_system.shop_shares[$game_variables[KyoShop::STORECODEVARID]]
 contents.font.color = system_color
 contents.draw_text(0, 0, 240, 32, KyoShopLabels::TOTALSHARES)
 contents.font.color = normal_color
 contents.draw_text(0, 0, 240, 32, shares.to_s, 2)
 end
 end
 
 class Interpreter
 alias kyon_discounts_inter_comm_302 command_302
 def command_302
 if $game_switches[KyoShop::GOODSSWITCHID]
 KyoShopOrders.store_event_id = @event_id
 $game_switches[KyoShop::GOODSSWITCHID] = false
 $game_system.shop_goods = [@parameters]
 loop do
 @index += 1
 if @list[@index].code == 605
 $game_system.shop_goods << @list[@index].parameters
 else
 return false
 end
 end
 end
 kyon_discounts_inter_comm_302
 end
 end
 
 class Scene_Shop
 alias kyon_discounts_scn_shop_up update
 def main
 start
 Graphics.transition
 while @keep_loop
 Graphics.update
 Input.update
 update
 end
 Graphics.freeze
 terminate
 end
 
 def start
 @keep_loop = true
 @stage = :main
 @shop_id = $game_variables[KyoShop::STORECODEVARID]
 @goods = $game_temp.shop_goods.dup
 @orders = $game_system.shop_goods.dup
 update_goods_orders_after_investment
 make_basic_windows
 @discount_window = Window_ShopDiscountCoupon.new
 @discount_window.disappear
 @discount_window.help_window = @help_window
 unless $game_system.shop_goods.empty?
 @order_window = Window_ShopBuy.new($game_system.shop_goods)
 @order_window.disappear
 @order_window.help_window = @help_window
 @option_window = Window_ShopBuyOptions.new
 @option_window.z += 200
 @option_window.disappear
 end
 if (@need_appraisal = KyoShop::APPRAISALS.keys.include?(@shop_id))
 @appraise_item_window = AppraiseItemWindow.new
 @appraise_item_window.visible = false
 @appraise_info_window = AppraiseInfoWindow.new(@shop_id)
 @appraise_info_window.visible = false
 options = KyoShopLabels::APPRAISALOPTIONS.dup
 @appraise_options = Window_Command.new(160, options)
 @appraise_options.disappear
 @appraise_options.x = 240
 @appraise_options.y = 200
 @result_info_window = AppraiseResultWindow.new
 else
 @option_window.disable_item(3)
 end
 @purchase_window = Window_ShopBuy.new($game_temp.shop_goods)
 @purchase_window.disappear
 @purchase_window.help_window = @help_window
 @pack_id = [$game_map.map_id, KyoShopOrders.store_event_id]
 goods = $game_system.placed_orders[@pack_id]
 goods ||= []
 @pickup_window = Window_ShopPickUp.new(goods)
 @pickup_window.disappear
 @pickup_window.help_window = @help_window
 @sell_window = Window_ShopSell.new
 @sell_window.disappear
 @sell_window.help_window = @help_window
 @number_window = Window_ShopNumber.new
 @number_window.disappear
 @status_window = Window_ShopStatus.new
 @status_window.visible = false
 end
 
 def update_goods_orders_after_investment
 gds = []
 orders = []
 stuff = $game_system.check_shares(@shop_id)
 return if stuff.empty?
 stuff.each {|b| gds += strings_goods_conversion(b[1..-1]) if b[0] == :goods
 orders += string_good_conversion(b[1..-1]) if b[0] == :orders }
 $game_system.shop_goods = (@orders + orders).sort.uniq
 $game_temp.shop_goods = (@goods + gds).sort.uniq
 end
 
 def strings_goods_conversion(strings)
 data = []
 strings.each {|string| data << retrieve_item(string) }
 data
 end
 
 def retrieve_item(string)
 case string[0,1]
 when 'i' then [0, string[1..-1].to_i]
 when 'w' then [1, string[1..-1].to_i]
 when 'a' then [2, string[1..-1].to_i]
 end
 end
 
 def make_basic_windows
 @help_window = Window_Help.new
 @command_window = Window_ShopCommand.new
 @gold_window = Window_Gold.new
 @gold_window.x = 480
 @gold_window.y = 64
 @dummy_window = Window_Base.new(0, 128, 640, 352)
 @question_window = Window_ShopDiscountAlert.new
 @question_window.visible = false
 end
 
 def terminate
 @help_window.dispose
 @command_window.dispose
 @gold_window.dispose
 @dummy_window.dispose
 @purchase_window.dispose
 @pickup_window.dispose
 @sell_window.dispose
 @number_window.dispose
 @status_window.dispose
 @question_window.dispose
 @discount_window.dispose
 $game_variables[KyoShop::STORECODEVARID] = 0
 if @need_appraisal
 @appraise_item_window.dispose
 @appraise_info_window.dispose
 @appraise_options.dispose
 @result_info_window.dispose
 end
 return if $game_system.shop_goods.empty?
 @order_window.dispose
 @option_window.dispose
 $game_system.shop_goods.clear
 KyoShopOrders.commissions.clear
 KyoShopOrders.steps.clear
 KyoShopOrders.store_event_id = nil
 @stage = nil
 end
 
 def update_discount_message
 cd = $game_party.check_discounts
 text = cd ? KyoShopLabels::SOMEDISCOUNTS : KyoShopLabels::NODISCOUNTS
 @question_window.set_text(text)
 end
 
 def update
 @help_window.update
 @gold_window.update
 @dummy_window.update
 @sell_window.update
 @status_window.update
 case @stage
 when :main then update_command
 when :option then update_option
 when :purchase then update_purchase
 when :place then update_place_order
 when :pickup then update_pickup_order
 when :discount then update_discount
 when :appraise then update_appraisal
 when :appraise_option then update_appraisal_option
 when :sell then update_sell
 when :number then update_number
 end
 end
 
 def update_command
 @command_window.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 $scene = Scene_Map.new
 return @keep_loop = nil
 elsif Input.trigger?(Input::C)
 case @command_window.index
 when 0 # buy
 $game_system.se_play($data_system.decision_se)
 @command_window.active = false
 if $game_system.shop_goods.empty?
 @discount = 0
 @dummy_window.visible = false
 @question_window.visible = true
 @status_window.visible = true
 @purchase_window.appear
 @purchase_window.refresh
 update_discount_message
 return @stage = :purchase
 else
 @option_window.appear
 return @stage = :option
 end
 when 1 # sell
 $game_system.se_play($data_system.decision_se)
 @command_window.active = false
 @dummy_window.visible = false
 @sell_window.appear
 @sell_window.refresh
 return
 when 2 # quit
 $game_system.se_play($data_system.decision_se)
 $scene = Scene_Map.new
 @keep_loop = nil
 end
 end
 end
 
 def update_option
 @option_window.update
 @order_window.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @option_window.disappear
 @status_window.visible = false
 @command_window.active = true
 @dummy_window.visible = true
 return @stage = :main
 elsif Input.trigger?(Input::C)
 shares = $game_system.shop_shares[@shop_id]
 inv_max, inv_price = KyoShop::SHARESMAXMIN
 pos = @option_window.index
 if pos == 3 and !@need_appraisal
 return $game_system.se_play($data_system.buzzer_se)
 end
 if pos == 4 and inv_max == shares
 return $game_system.se_play($data_system.buzzer_se)
 end
 $game_system.se_play($data_system.decision_se)
 @dummy_window.visible = false
 @option_window.disappear
 @question_window.visible = true
 @status_window.visible = true
 case pos
 when 0 # buy
 @discount = 0
 @purchase_window.discount = 0
 disc = $game_system.check_shares(@shop_id)
 disc.each {|b| @purchase_window.discount += b[1] if b[0] == :discount }
 @status_window.item = @purchase_window.item
 @purchase_window.refresh
 @purchase_window.appear
 update_discount_message
 return @stage = :purchase
 when 1 # place order
 @status_window.item = @order_window.item
 @order_window.appear
 @order_window.refresh
 @question_window.set_text(KyoShopLabels::PLACEORDER)
 return @stage = :place
 when 2 # pick up stuff
 @status_window.item = @pickup_window.item
 @pickup_window.appear
 @pickup_window.refresh
 @question_window.set_text(KyoShopLabels::PICKUPORDER)
 return @stage = :pickup
 when 3 # appraisal
 @appraise_item_window.appear
 @appraise_info_window.visible = true
 @result_info_window.visible = true
 @dummy_window.visible = false
 @command_window.visible = false
 @number_window.visible = false
 @status_window.visible = false
 @help_window.set_text(KyoShopLabels::APPRAISALMENULABEL)
 return @stage = :appraise
 when 4 # investments
 @status_window.investment = @investment = true
 inv_max = [inv_max - shares, $game_party.gold / inv_price].min
 fake_item = RPG::Item.new
 fake_item.name = KyoShopLabels::SHARES
 @price = inv_price
 @number_window.set(fake_item, inv_max, inv_price, nil, 10)
 @number_window.appear
 @question_window.set_text(KyoShopLabels::INVESTMENT)
 @stage = :number
 end
 end
 end
 
 def update_purchase
 @purchase_window.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 if $game_system.shop_goods.empty?
 @command_window.active = true
 @stage = :main
 else
 @option_window.appear
 @stage = :option
 end
 @discount = 0
 @purchase_window.discount = 0
 @dummy_window.visible = true
 @purchase_window.disappear
 @question_window.visible = false
 @status_window.visible = false
 @status_window.item = nil
 @help_window.set_text("")
 return
 end
 if Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @status_window.item = @purchase_window.item
 return
 end
 if Input.trigger?(KyoShop::DISCOUNTBUTTON)
 unless $game_party.check_discounts
 return $game_system.se_play($data_system.buzzer_se)
 end
 $game_system.se_play($data_system.decision_se)
 @purchase_window.disappear
 @discount_window.refresh
 @discount_window.appear
 @question_window.set_text(KyoShopLabels::SELECTDISCOUNT)
 return @stage = :discount
 elsif Input.trigger?(Input::C)
 discount = @purchase_window.discount
 percent = KyoShop.current_price_max
 @item = @purchase_window.item
 @price = @item.price + @item.price * percent / 100
 @price -= @item.price * discount / 100 if discount > 0
 if @item == nil or @price > $game_party.gold
 return $game_system.se_play($data_system.buzzer_se)
 end
 shop_max = KyoShop.current_item_max
 if (number = check_number) == shop_max
 return $game_system.se_play($data_system.buzzer_se)
 end
 $game_system.se_play($data_system.decision_se)
 max = @price == 0 ? shop_max : $game_party.gold / @price
 max = [max, shop_max - number].min
 @purchase_window.disappear
 @number_window.set(@item, max, @price)
 @number_window.appear
 @last_stage = @stage
 @stage = :number
 end
 end
 
 def update_place_order
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @option_window.appear
 @dummy_window.visible = true
 @order_window.disappear
 @question_window.visible = false
 @status_window.visible = false
 @status_window.item = nil
 @help_window.set_text("")
 return @stage = :option
 end
 if Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @status_window.item = @order_window.item
 return
 end
 if Input.trigger?(Input::C)
 $game_system.se_play($data_system.decision_se)
 @item = @order_window.item
 @price = @item.price
 percent = KyoShopOrders.commissions[@order_window.index]
 percent += KyoShop.current_price_max
 @price += percent * @item.price / 100 if percent > 0
 if @item == nil or @price > $game_party.gold
 return $game_system.se_play($data_system.buzzer_se)
 end
 number = check_number
 shop_max = KyoShop.current_item_max
 if number == shop_max
 return $game_system.se_play($data_system.buzzer_se)
 end
 $game_system.se_play($data_system.decision_se)
 max = @price == 0 ? shop_max : $game_party.gold / @price
 max = [max, shop_max - number].min
 @order_window.disappear
 @place_order = true
 @number_window.set(@item, max, @price, percent)
 @number_window.appear
 @question_window.set_text(KyoShopLabels::FEESAPPLY)
 @last_stage = @stage
 @stage = :number
 end
 end
 
 def update_pickup_order
 @pickup_window.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @dummy_window.visible = true
 @question_window.visible = false
 @status_window.visible = false
 @pickup_window.disappear
 @option_window.appear
 return @stage = :option
 end
 if Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @status_window.item = @pickup_window.item
 return
 end
 if Input.trigger?(Input::C)
 current_item = @pickup_window.item
 goods = $game_system.placed_orders[@pack_id]
 unless goods
 return $game_system.se_play($data_system.buzzer_se)
 end
 goods = goods[@pickup_window.index]
 unless current_item and goods[3] <= $game_party.steps
 return $game_system.se_play($data_system.buzzer_se)
 end
 $game_system.se_play($data_system.decision_se)
 number = goods[2]
 case current_item
 when RPG::Item then $game_party.gain_item(current_item.id, number)
 when RPG::Weapon then $game_party.gain_weapon(current_item.id, number)
 when RPG::Armor then $game_party.gain_armor(current_item.id, number)
 end
 $game_system.placed_orders[@pack_id].delete_at(@pickup_window.index)
 @pickup_window.deliver($game_system.placed_orders[@pack_id])
 end
 end
 
 def update_discount
 @discount_window.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @discount_window.disappear
 @purchase_window.appear
 return @stage = :purchase
 elsif Input.trigger?(Input::C)
 $game_system.se_play($data_system.decision_se)
 @coupons_allowed = KyoShop::COUPON_IDS.include?(@discount_window.item.id)
 @purchase_window.discount -= @discount
 @discount = @discount_window.item.price
 @discount_window.disappear
 @purchase_window.appear
 discount = @purchase_window.discount += @discount
 @purchase_window.refresh
 text = sprintf(KyoShopLabels::APPLYDISCOUNT, discount)
 @question_window.set_text(text)
 @stage = :purchase
 end
 end
 
 def update_appraisal
 @appraise_item_window.update
 if Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @appraise_info_window.refresh
 return
 end
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @appraise_item_window.disappear
 @appraise_info_window.visible = false
 @result_info_window.visible = false
 @result_info_window.contents.clear
 @appraise_options.disappear
 @dummy_window.visible = true
 @command_window.visible = true
 @number_window.visible = true
 @status_window.visible = true
 @option_window.appear
 @help_window.set_text("")
 return @stage = :option
 elsif Input.trigger?(Input::C)
 if @appraise_item_window.empty?
 return $game_system.se_play($data_system.buzzer_se)
 end
 $game_system.se_play($data_system.decision_se)
 @appraise_options.appear
 @stage = :appraise_option
 end
 end
 
 def update_appraisal_option
 @appraise_options.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @appraise_options.disappear
 return @stage = :appraise
 elsif Input.trigger?(Input::C)
 data = KyoShop::APPRAISALS[@shop_id]
 price = case @appraise_options.index
 when 0 then data[:test_cost]
 when 1 then data[:cost]
 when 2 then -10
 end
 if price == -10 or $game_party.gold < price
 $game_system.se_play($data_system.buzzer_se)
 @appraise_options.disappear
 return @stage = :appraise
 end
 $game_system.se_play($data_system.decision_se)
 item = @appraise_item_window.item
 $game_party.lose_item(item.id, 1)
 $game_party.lose_gold(price)
 if rand(100) < data[:rate]
 goods = data[:goods]
 kind, id = retrieve_item(goods[rand(goods.size)])
 else
 kind, id = retrieve_item(data[:default])
 end
 item = case kind
 when 0 then $data_items[id]
 when 1 then $data_weapons[id]
 when 2 then $data_armors[id]
 end
 @result_info_window.refresh(item)
 @appraise_item_window.refresh
 @gold_window.refresh
 @appraise_options.disappear
 @stage = :appraise
 end
 end
 
 def check_number
 return number = case @item
 when RPG::Item then $game_party.item_number(@item.id)
 when RPG::Weapon then $game_party.weapon_number(@item.id)
 when RPG::Armor then $game_party.armor_number(@item.id)
 end
 end
 
 def update_number
 @number_window.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @number_window.disappear
 @number_window.reset_multiplier
 case @command_window.index
 when 0 # buy or place order
 if @place_order
 @place_order = nil
 @order_window.appear
 @question_window.set_text(KyoShopLabels::PLACEORDER)
 elsif @investment
 @investment = nil
 @status_window.investment = nil
 @option_window.appear
 @question_window.visible = false
 @status_window.visible = false
 @dummy_window.visible = true
 else
 @purchase_window.appear
 discount = @purchase_window.discount
 if discount == 0
 update_discount_message
 else
 text = sprintf(KyoShopLabels::APPLYDISCOUNT, discount) + "%"
 @question_window.set_text(text)
 end
 end
 when 1 # sell
 update_discount_message
 @sell_window.appear
 @status_window.visible = false
 end
 @stage = @last_stage
 return @last_stage = nil
 elsif Input.trigger?(Input::C)
 $game_system.se_play($data_system.shop_se)
 @number_window.disappear
 case @command_window.index
 when 0  # buy
 $game_party.lose_gold(@number_window.number * @price)
 number = @number_window.number
 if @place_order
 update_number_place_order(number)
 elsif @investment
 update_number_investment(number)
 else
 update_number_purchase(number)
 end
 return
 when 1  # sell
 number = @number_window.number
 $game_party.gain_gold(number * (@item.price / 2))
 case @item
 when RPG::Item then   $game_party.lose_item(@item.id, number)
 when RPG::Weapon then $game_party.lose_weapon(@item.id, number)
 when RPG::Armor then  $game_party.lose_armor(@item.id, number)
 end
 @gold_window.refresh
 @sell_window.refresh
 @status_window.refresh
 @sell_window.appear
 @status_window.visible = false
 @stage = @last_stage
 return @last_stage = nil
 end
 end
 end
 
 def update_number_place_order(number)
 steps = $game_party.steps + KyoShopOrders.steps[@order_window.index]
 order = [nil, @item.id, number, steps]
 order[0] = case @item
 when RPG::Item then 0
 when RPG::Weapon then 1
 when RPG::Armor then 2
 end
 $game_system.placed_orders[@pack_id] ||= []
 $game_system.placed_orders[@pack_id] << order
 @pickup_window.deliver($game_system.placed_orders[@pack_id])
 @gold_window.refresh
 @status_window.refresh
 @place_order = nil
 @order_window.refresh
 @order_window.appear
 @question_window.set_text(KyoShopLabels::PLACEORDER)
 @stage = :place
 end
 
 def update_number_investment(number)
 @investment = nil
 @status_window.investment = nil
 $game_system.shop_shares[@shop_id] += number
 update_goods_orders_after_investment
 @order_window.deliver($game_system.shop_goods)
 @purchase_window.deliver($game_temp.shop_goods)
 @gold_window.refresh
 @question_window.visible = false
 @status_window.visible = false
 @dummy_window.visible = true
 @number_window.reset_multiplier
 @number_window.disappear
 @option_window.appear
 @stage = :option
 end
 
 def update_number_purchase(number)
 case @item
 when RPG::Item then $game_party.gain_item(@item.id, number)
 when RPG::Weapon then $game_party.gain_weapon(@item.id, number)
 when RPG::Armor then $game_party.gain_armor(@item.id, number)
 end
 if @coupons_allowed
 @coupons_allowed = nil
 $game_party.lose_item(@discount_window.item.id, 1)
 update_discount_message
 @discount_window.refresh
 @purchase_window.discount = 0
 @discount = 0
 end
 @gold_window.refresh
 @status_window.refresh
 @purchase_window.refresh
 @purchase_window.appear
 @stage = :purchase
 end
 end
 
 RE: KyoDiscounts XP VX, ACE MV - kyonides -  01-14-2019
 
 Here I come again! Nope, I ain't singing here!
  
 A while ago I finished a new release of KyoDiscounts XP where game developers will now feel free to include extra features like haggling! The benefits would be that it would count as a favor so the storekeeper alias appraiser might be able to offer extra goods after finishing his or her appraisal. Nope, don't worry, pals!
  They won't get more than a single good at a time. The difference would be that the player would be able to get a chance to get a good that wasn't available before doing him or her a favor...or series of favors. If the appraisal results in a great finding that captivates the appraiser, he or she will make you an offer and even a second and final offer if you allow that! 
 Happy Game Testing!?
  
 Edit: I have finished implementing favors so now the shopkeeper alias appraiser should recall how many times you have brought and sold interesting items to him or her.
 
 
 Code: # * KyoDiscounts XP#   Scripter : Kyonides-Arkanthes
 #   v1.5.0 - 2019-01-14
 
 #   Whenever you obtain a discount card, such discount will be applied to all
 #   of your purchases if you have picked a card till it expires after a certain
 #   number of steps. Additional steps will be quickly added to your current card
 #   whenever you purchase any additional card of the same kind.
 
 #   One coupon will be spent every single time you purchase any specific item,
 #   you will need another one to purchase a different item later on.
 #   The discount card or coupon price is used to calculate the corresponding
 #   discount on every single purchase the player makes with it.
 
 #   Place this script below KItemRefill XP or KyoScriptPack Item XP if you
 #   included any of those scripts in your current game project.
 
 #   Now you can also setup exclusive store discount cards as well. Just keep in
 #   mind that you will need to setup the in game variable you picked so it will
 #   be able to store the Exclusive Store Code (an Integer) before you can add
 #   the shop event command. Common stores don't need any Store Code at all.
 
 #   Besides the player can also place orders to get an item that is supposed to
 #   be found at another store only. The player will be charged an extra fee, but
 #   he or she won't need to go back to another store. The player would only need
 #   to keep walking for a while before the goods are available at the store.
 #   Now the required steps for each placed order will be automatically increased
 #   between 0% and 50%, making it look a bit random but also kind of realistic.
 
 # * Unknown Item or Weapon or Armor Appraisals *
 
 #   Use the Game Variable defined in the STORECODEVARID Constant to store the
 #   Shop ID that will include the appraisal service.
 #   Use the MYSTERIOUS series of Arrays to include as many IDs of unknown items
 #   or weapons or armors that will serve as fillers till they get replaced by
 #   the actual goods they represent.
 #   Follow the Instructions included in the APPRAISALS Hash to define all
 #   conditions that will affect an appraiser's task of identifying the item.
 
 #   Script Calls   #
 
 #   $game_party.discount_cards_expire
 #      Makes all Discount Cards expire as part of the game's plot.
 
 #   $game_party.disc_card_expire(Card_ID)
 #      Makes an specific Discount Card expire as part of the game's plot.
 
 #   KyoShopOrders << [Percent1, Percent2, etc.]
 #      Defines a Commission percent for every Item in the Place Order List.
 
 #   KyoShopOrders.steps = [Steps1, Steps2, etc.]
 #   KyoShopOrders.steps += [Steps5, Steps6, etc.]
 #      Defines Steps required by every Order in the Place Order List.
 #      The 2nd call will be required only if you couldn't include all steps.
 
 #   KyoShop.scarcity_lvl = 0 or higher
 #     Define all prices and maximum number of units per shop item.
 #     0 means no scarcity, 1 or higher reflects how severe it is.
 #     You also have to configure the @scarce_limits hash in order to predefine
 #     :price and :max per scarcity level. The maximum scarcity level depends on
 #     how many values you entered in both :price and :max arrays.
 #     In few words, you define the maximum scarcity level ever possible!
 
 module KyoShop
 # Maximum number of units for each shop item
 NUMBERMAX = 99
 # Button that will open the Discount window while on the shop menu
 DISCOUNTBUTTON = Input::A
 # Add Discount Card Object IDs
 DISCOUNT_IDS = [33, 34]
 # Add Discount Coupon Object IDs
 COUPON_IDS = [36, 37]
 # Maximum Steps before Discount Card expires : ID => Steps
 STEPS = { 33 => 500, 34 => 300, 35 => 150 }
 # Exclusive Stores In Game Variable ID
 STORECODEVARID = 1
 # Exclusive Stores List : Object ID => Exclusive Store Code
 EXCLUSIVESTORES = { 35 => 102 }
 # Switch ID : deactivates Store to add Goods found elsewhere
 GOODSSWITCHID = 1
 # Store IDs for stores where you have invested some gold
 INVESTSTOREIDS = [101]
 # Maximum Number of Shares & Share Price
 SHARESMAXMIN = [10000, 100]
 INVESTMENTS = {} # Store Investments - Do Not Edit This Line
 INVESTMENTS.default = {} # Do Not Edit This Line
 # Available Improvements #
 # :discount : [:discount, 25]
 # :goods    : [:goods, 'i10', 'w4', 'a6']
 # :orders   : [:orders, 'i11', 'w5', 'a7']
 # [Store ID] = { Shares => Prize, Shares => Another Prize, etc. }
 INVESTMENTS[101] = { 50 => [:goods,'i10','w5','a6'], 100 => [:discount,10] }
 APPRAISALS = {} # Do Not Edit This Line!
 # [Store ID] = { appraisal cost => $, estimate cost => $, success rate => %,
 # times you can help the a. => 0, bad result => "i1", goods => [item4, etc.] }
 APPRAISALS[101] = { :cost => 150, :test_cost => 75, :rate => 10,
 :default => 'i1', :help_limit => 5, :haggle => true,
 :target => { 'i9' => 1, 'i10' => 2 },
 :goods => ['i2','i3','i9','i10'], :extras => ['i11'] }
 # Add Item IDs for unknown shop goods that need to be appraised by experts
 MYSTERIOUSITEMS = []
 # Add Weapon IDs for unknown shop goods that need to be appraised by experts
 MYSTERIOUSWEAPONS = []
 # Add Armor IDs for unknown shop goods that need to be appraised by experts
 MYSTERIOUSARMORS = []
 @scarce_limits = {
 :price  => [0, 25, 50, 100, 250, 350, 500, 650, 800],
 :max => [NUMBERMAX, NUMBERMAX - 10, NUMBERMAX - 25, NUMBERMAX - 35,
 NUMBERMAX - 50, NUMBERMAX - 65, NUMBERMAX - 80, NUMBERMAX - 90, 1]
 #:item => [1, 2, 3, 4, 5, 6],
 #:weapon => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
 #:armor => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
 }
 @scarce_lvl = 0 # Initial Level
 def self.current_item_max() @scarce_limits[:max][@scarce_lvl] end
 def self.current_price_max() @scarce_limits[:price][@scarce_lvl] end
 def self.scarcity_limits() @scarce_limits end
 def self.scarcity_lvl() @scarce_lvl end
 def self.scarcity_lvl=(lvl) @scarce_lvl = lvl end
 end
 
 module KyoShopLabels
 # Basic Shop Command Labels
 BASIC = ["Buy", "Sell", "Exit"]
 MOREOPTIONS = "Options"
 # Buy Stuff & Place Order & Pick Up Items Label
 BUYPLACEPICKUP = ['Buy Items', 'Place Order', 'Pick Up Items',
 'Appraise', 'Invest']
 # Subtotal, Commission Percent and Total Amount
 PRICELABELS = ['Subtotal', 'Commission %', 'Total']
 # Place an Order Label
 PLACEORDER = 'Do you wish to place an order?'
 # Pick Up Order Label
 PICKUPORDER = 'Do you want to pick up an order?'
 # No Order Found Label
 NOORDERFOUND = 'There is nothing left, boss!'
 # Available Discounts Label
 SOMEDISCOUNTS = 'Press A to get a discount'
 # No Discount Available Label
 NODISCOUNTS = 'No Discount Available'
 # Select a Discount Card or Coupon Label
 SELECTDISCOUNT = 'Choose a Card or Coupon'
 # Apply Discount Label
 APPLYDISCOUNT = "Discount Applied %s%"
 # Warning about Extra Fees for Placing Orders
 FEESAPPLY = 'Extra Fees Apply'
 # Discount Card's Steps Left Label
 STEPSLEFT = " %s steps left."
 # Investment Label...
 INVESTMENT = 'Want to invest in this store?'
 # Share Number Label
 SHARES = 'Share Number'
 # Adquired or Purchased Shares Label
 TOTALSHARES = 'Total Shares'
 # Pick Item to be Appraised Label
 APPRAISALMENULABEL = "Appraisal Menu"
 # Appraisal Window Labels
 APPRAISALLABELS = ["Quick Test Cost", "Normal Cost"]
 # Appraisal Options Labels
 APPRAISALOPTIONS = ["Quick Test", "Detailed Test", "Cancel"]
 # Purchase Offer and Haggle Labels
 APPRAISALHAGGLEOPTIONS = ["Accept", "Haggle", "Decline"]
 # Appraisal End Result Labels
 APPRAISALRESULTLABELS = [
 "The item at hand is nothing else but... %s",
 "I think it might be worth some... %s",
 "I've been searching for some %s!",
 "Now I want to make a deal.",
 "What if I make a better offer?",
 "Would you accept some %s?"
 ]
 end
 # DO NOT EDIT ANYTHING ELSE #
 module KyoShopOrders
 @commissions = []
 @steps = []
 class << self
 attr_accessor :store_event_id, :goods_id
 attr_reader :steps, :commissions
 def steps=(val) @steps = val.map {|n| n + rand((n / 2) + 2) } end
 def <<(val)
 @commissions += val
 @commissions = @commissions.flatten
 end
 end
 end
 
 module WindowModule
 def appear
 self.active = true
 self.visible = true
 end
 
 def disappear
 self.active = false
 self.visible = false
 end
 end
 
 class Game_System
 attr_accessor :shop_goods
 attr_reader :placed_orders, :shop_shares, :shop_favors
 alias kyon_discounts_gm_sys_init initialize
 def initialize
 @shop_goods = []
 @placed_orders = {}
 @shop_shares = {}
 @shop_favors = {}
 @placed_orders.default = []
 @shop_shares.default = 0
 @shop_favors.default = 0
 kyon_discounts_gm_sys_init
 end
 
 def disc_store?(disc_id) !KyoShop::EXCLUSIVESTORES[disc_id] end
 
 def excl_disc_store?(disc_id)
 exclusive = KyoShop::EXCLUSIVESTORES[disc_id]
 $game_variables[KyoShop::STORECODEVARID] == exclusive
 end
 
 def check_shares(shop_id)
 results = []
 shares = @shop_shares[shop_id]
 investments = KyoShop::INVESTMENTS[shop_id]
 limits = KyoShop::INVESTMENTS[shop_id].keys.sort
 results = investments.select{|limit| shares >= limit[0] }.map {|r| r[1] }
 end
 end
 
 class Game_Party
 attr_reader :discounts
 alias kyon_discounts_gm_party_init initialize
 alias kyon_discounts_gm_party_gain_item gain_item
 def initialize
 @discounts = {}
 kyon_discounts_gm_party_init
 end
 
 def gain_item(item_id, n)
 kyon_discounts_gm_party_gain_item(item_id, n)
 return if item_id == 0 or n == 0
 return unless KyoShop::DISCOUNT_IDS.include?(item_id)
 if @discounts[item_id]
 @discounts[item_id] += KyoShop::STEPS[item_id]
 @items[item_id] = 1
 else
 @discounts[item_id] = KyoShop::STEPS[item_id]
 end
 end
 
 def check_discounts
 unless @discounts.empty?
 for did in KyoShop::DISCOUNT_IDS
 next unless @discounts[did] and @discounts[did] > 0
 return true if $game_system.disc_store?(did)
 return true if $game_system.excl_disc_store?(did)
 end
 end
 for cid in KyoShop::COUPON_IDS
 next unless item_number(cid) > 0
 return true if $game_system.disc_store?(cid)
 return true if $game_system.excl_disc_store?(cid)
 end
 return false
 end
 
 def decrease_discounts
 KyoShop::DISCOUNT_IDS.each {|n| next unless @discounts[n]
 @discounts[n] -= 1 if @discounts[n] > 0 }
 end
 
 def discount_cards_expire
 KyoShop::DISCOUNT_IDS.each {|n| @discounts[n] = 0 if @discounts[n] }
 end
 
 def disc_card_expire(dc_id) @discounts[dc_id] = 0 end
 end
 
 class Game_Player
 alias kyon_discounts_coupons_gm_player_increase_steps increase_steps
 def increase_steps
 kyon_discounts_coupons_gm_player_increase_steps
 $game_party.decrease_discounts
 end
 end
 
 class Window_Selectable
 include WindowModule
 end
 
 class Window_Help
 def set_text(item_id, text=nil, align=0)
 if item_id.is_a?(String)
 if KyoShop::DISCOUNT_IDS.include?(KyoShopOrders.goods_id)
 steps = $game_party.discounts[KyoShopOrders.goods_id].to_s
 text = item_id + sprintf(KyoShopLabels::STEPSLEFT, steps)
 KyoShopOrders.goods_id = item_id = nil
 end
 end
 if text.is_a?(String)
 text = text.gsub(/\\[Uu]/){$game_system.refill_items[item_id].sips.to_s}
 elsif text.is_a?(Integer)
 align = text
 text = item_id
 else
 text = item_id
 end
 if text != @text or align != @align
 self.contents.clear
 self.contents.font.color = normal_color
 self.contents.draw_text(4, 0, self.width - 40, 32, text, align)
 @text = text
 @align = align
 @actor = nil
 end
 self.visible = true
 end
 end
 
 class Window_Item
 alias kyon_discounts_win_item_up_help update_help
 def update_help
 KyoShopOrders.goods_id = self.item.id
 kyon_discounts_win_item_up_help
 end
 end
 
 class AppraiseItemWindow < Window_Selectable
 def initialize
 super(0, 64, 480, 320)
 @column_max = 1
 refresh
 self.index = 0
 end
 
 def refresh
 if self.contents != nil
 self.contents.dispose
 self.contents = nil
 end
 @data = []
 for n in KyoShop::MYSTERIOUSITEMS
 next if $game_party.item_number(n) == 0
 @data << $data_items[n]
 end
 for i in KyoShop::MYSTERIOUSWEAPONS
 next if $game_party.weapon_number(i) == 0
 @data << $data_weapons[i]
 end
 for i in KyoShop::MYSTERIOUSARMORS
 next if $game_party.armor_number(i) == 0
 @data << $data_armors[i]
 end
 @item_max = @data.size
 return if @item_max == 0
 self.contents = Bitmap.new(width - 32, row_max * 32)
 @item_max.times{|i| draw_item(i) }
 end
 
 def draw_item(index)
 item = @data[index]
 number = case item
 when RPG::Item then $game_party.item_number(item.id)
 when RPG::Weapon then $game_party.weapon_number(item.id)
 when RPG::Armor then $game_party.armor_number(item.id)
 end
 c = self.contents
 x = 4 + index % 2 * (288 + 32)
 y = index / 2 * 32
 rect = Rect.new(x, y, self.width / @column_max - 32, 32)
 c.fill_rect(rect, Color.new(0, 0, 0, 0))
 bit = RPG::Cache.icon(item.icon_name)
 c.blt(x, y + 4, bit, Rect.new(0, 0, 24, 24), 255)
 c.draw_text(x + 28, y, 212, 32, item.name, 0)
 c.draw_text(x + 240, y, 16, 32, ":", 1)
 c.draw_text(x + 256, y, 24, 32, number.to_s, 2)
 end
 def item() @data[@index] end
 def empty?() @data.empty? end
 end
 
 class AppraiseInfoWindow < Window_Base
 def initialize(store_id)
 super(480, 128, 160, 256)
 @data = KyoShop::APPRAISALS[store_id]
 @labels = KyoShopLabels::APPRAISALLABELS.dup
 @currency = $data_system.words.gold
 self.contents = Bitmap.new(width - 32, height - 32)
 refresh
 end
 
 def refresh
 aw = width - 32
 contents.clear
 contents.font.color = system_color
 contents.draw_text(0, 0, aw, 24, @labels[0])
 contents.draw_text(0, 48, aw, 24, @labels[1])
 contents.draw_text(0, 24, aw, 24, @currency, 2)
 contents.draw_text(0, 72, aw, 24, @currency, 2)
 contents.font.color = normal_color
 contents.draw_text(0, 24, width - 48, 24, @data[:test_cost].to_s, 2)
 contents.draw_text(0, 72, width - 48, 24, @data[:cost].to_s, 2)
 end
 end
 
 class AppraiseResultWindow < Window_Base
 def initialize
 super(0, 384, 640, 96)
 @labels = KyoShopLabels::APPRAISALRESULTLABELS.dup
 @currency = $data_system.words.gold
 self.contents = Bitmap.new(width - 32, height - 32)
 end
 
 def refresh(item)
 contents.clear
 result = sprintf(@labels[0], item.name)
 cost = sprintf(@labels[1], item.price) + " " + @currency
 contents.draw_text(0, 0, width - 32, 24, result)
 contents.draw_text(0, 24, width - 32, 24, cost)
 end
 
 def ask_favor(item)
 contents.clear
 result = sprintf(@labels[2], item.name)
 contents.draw_text(0, 0, width - 32, 24, result)
 contents.draw_text(0, 24, width - 32, 24, @labels[3])
 end
 
 def make_offer(overprice)
 contents.clear
 result = sprintf(@labels[5], overprice) + " " + @currency
 contents.draw_text(0, 0, width - 32, 24, @labels[4])
 contents.draw_text(0, 24, width - 32, 24, result)
 end
 end
 
 class Window_ShopCommand
 def initialize
 super(0, 64, 480, 64)
 self.contents = Bitmap.new(width - 32, height - 32)
 @item_max = 3
 @column_max = 3
 @commands = KyoShopLabels::BASIC.dup
 if KyoShop::APPRAISALS[$game_variables[KyoShop::STORECODEVARID]]
 @commands[0] = KyoShopLabels::MOREOPTIONS.dup
 end
 refresh
 self.index = 0
 end
 end
 
 class Window_ShopBuy
 attr_accessor :discount
 def initialize(shop_goods)
 super(0, 128, 368, 288)
 @shop_goods = shop_goods
 @discount = 0
 refresh
 self.index = 0
 end
 
 def deliver(goods)
 @shop_goods = goods
 if goods.size - 1 < @index
 @index = goods.size > 0 ? (@index + goods.size - 1) % goods.size : 0
 update_cursor_rect
 end
 refresh
 self.index = 0
 end
 
 def draw_item(index)
 item = @data[index]
 number = case item
 when RPG::Item then $game_party.item_number(item.id)
 when RPG::Weapon then $game_party.weapon_number(item.id)
 when RPG::Armor then $game_party.armor_number(item.id)
 end
 enough = (item.price <= $game_party.gold and number < 99)
 self.contents.font.color = enough ? normal_color : disabled_color
 y = index * 32
 rect = Rect.new(4, y, self.width - 32, 32)
 self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
 bitmap = RPG::Cache.icon(item.icon_name)
 opacity = enough ? 255 : 128
 self.contents.blt(4, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
 self.contents.draw_text(32, y, 212, 32, item.name, 0)
 price = item.price - item.price * @discount / 100
 self.contents.draw_text(244, y, 88, 32, price.to_s, 2)
 end
 end
 
 class Window_ShopPickUp < Window_ShopBuy
 def refresh
 if self.contents != nil
 self.contents.dispose
 self.contents = nil
 end
 @data = []
 for good in @shop_goods
 new_item = case good[0]
 when 0 then $data_items[good[1]]
 when 1 then $data_weapons[good[1]]
 when 2 then $data_armors[good[1]]
 end
 @data << new_item if new_item
 end
 @item_max = @data.size
 return if @item_max == 0
 self.contents = Bitmap.new(width - 32, row_max * 32)
 (0...@item_max).each {|i| draw_item(i) }
 end
 
 def draw_item(index)
 item = @data[index]
 qty, steps = @shop_goods[index][2..3]
 number = case item
 when RPG::Item then $game_party.item_number(item.id)
 when RPG::Weapon then $game_party.weapon_number(item.id)
 when RPG::Armor then $game_party.armor_number(item.id)
 end
 enough = (number + qty < 100 and steps <= $game_party.steps)
 self.contents.font.color = enough ? normal_color : disabled_color
 y = index * 32
 rect = Rect.new(4, y, self.width - 32, 32)
 self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
 bitmap = RPG::Cache.icon(item.icon_name)
 opacity = enough ? 255 : 128
 self.contents.blt(4, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
 self.contents.draw_text(32, y, 212, 32, item.name, 0)
 self.contents.draw_text(244, y, 88, 32, qty.to_s, 2)
 end
 undef discount, discount=
 end
 
 class Window_ShopNumber
 include WindowModule
 def initialize
 super(0, 128, 368, 288)
 self.contents = Bitmap.new(width - 32, height - 32)
 @item = nil
 @max = 1
 @price = 0
 @number = 1
 @multiplier = 1
 end
 
 def reset_multiplier
 @multiplier = 1
 @number = 1
 refresh
 end
 
 def set(item, max, price, percent=nil, multiplier=1)
 @item = item
 @max = max
 @price = price
 @number = 1
 @multiplier = multiplier
 @percent = percent
 refresh
 end
 
 def update
 super
 return unless self.active
 if Input.repeat?(Input::RIGHT) and @number < @max
 $game_system.se_play($data_system.cursor_se)
 @number += @multiplier
 refresh
 end
 if Input.repeat?(Input::LEFT) and @number > @multiplier
 $game_system.se_play($data_system.cursor_se)
 @number -= @multiplier
 refresh
 end
 if Input.repeat?(Input::UP) and @number < @max
 $game_system.se_play($data_system.cursor_se)
 @number = [@number + 10 * @multiplier, @max].min
 refresh
 end
 if Input.repeat?(Input::DOWN) and @number > @multiplier
 $game_system.se_play($data_system.cursor_se)
 @number = [@number - 10 * @multiplier, 1].max
 refresh
 end
 end
 
 def refresh
 self.contents.clear
 draw_item_name(@item, 4, 96)
 self.contents.font.color = normal_color
 if @multiplier == 1
 cx1, cx2, cx3, cw1, cw2 = [272, 308, 304, 24, 32]
 else
 cx1, cx2, cx3, cw1, cw2 = [260, 264, 272, 68, 64]
 end
 self.contents.draw_text(cx1, 96, 32, 32, "")
 self.contents.draw_text(cx2, 96, cw1, 32, @number.to_s, 2)
 self.cursor_rect.set(cx3, 96, cw2, 32)
 gold = $data_system.words.gold
 cx = contents.text_size(gold).width
 subtotal_price = @item.price * @number
 total_price = @price * @number
 labels = KyoShopLabels::PRICELABELS
 if total_price > subtotal_price and @multiplier < 2
 self.contents.font.color = system_color
 self.contents.draw_text(120, 128, 100, 32, labels[0], 2)
 self.contents.draw_text(332-cx, 128, cx, 32, gold, 2)
 self.contents.draw_text(80, 160, 140, 32, labels[1], 2)
 self.contents.draw_text(328-cx, 160, cx + 4, 32, '%', 2)
 self.contents.font.color = normal_color
 self.contents.draw_text(4, 128, 328-cx-2, 32, subtotal_price.to_s, 2)
 self.contents.draw_text(4, 160, 328-cx-2, 32, @percent.to_s, 2)
 end
 self.contents.draw_text(4, 192, 328-cx-2, 32, total_price.to_s, 2)
 self.contents.font.color = system_color
 self.contents.draw_text(120, 192, 100, 32, labels[2], 2)
 self.contents.draw_text(332-cx, 192, cx, 32, gold, 2)
 end
 end
 
 class Window_ShopBuyOptions < Window_Selectable
 def initialize
 commands = KyoShopLabels::BUYPLACEPICKUP.dup
 varid = $game_variables[KyoShop::STORECODEVARID]
 commands.pop unless KyoShop::INVESTSTOREIDS.include?(varid)
 super(214, 148, 212, commands.size * 32 + 32)
 @commands = commands
 @item_max = @commands.size
 self.contents = Bitmap.new(width - 32, @item_max * 32)
 refresh
 self.index = 0
 end
 
 def refresh
 self.contents.clear
 @item_max.times {|i| @commands[i]
 contents.draw_text(4, i * 32, 172, 32, @commands[i]) }
 end
 end
 
 class Window_ShopDiscountAlert < Window_Base
 def initialize
 super(0, 416, 368, 64)
 self.contents = Bitmap.new(width - 32, height - 32)
 end
 
 def set_text(text)
 self.contents.clear
 self.contents.draw_text(0, 0, width - 32, height - 32, text)
 end
 end
 
 class Window_ShopDiscountCoupon < Window_Selectable
 def initialize
 super(0, 128, 368, 288)
 self.index = 0
 refresh
 end
 
 def item() @data[@index] end
 
 def refresh
 if self.contents != nil
 self.contents.dispose
 self.contents = nil
 end
 @data = []
 dc_ids = $game_party.discounts.keys.sort
 dc_ids.each {|i| next if $game_party.discounts[i] == 0
 next if !$game_system.disc_store?(i) and !$game_system.excl_disc_store?(i)
 @data << $data_items[i] }
 KyoShop::COUPON_IDS.each {|i| next unless $game_party.item_number(i) > 0
 @data << $data_items[i] }
 @item_max = @data.size
 return if @item_max == 0
 self.index -= 1 if @index > @item_max - 1
 self.contents = Bitmap.new(width - 32, row_max * 32)
 (0...@item_max).each {|i| draw_item(i) }
 end
 
 def draw_item(index)
 item = @data[index]
 number = $game_party.item_number(item.id)
 x = 4
 y = index * 32
 rect = Rect.new(x, y, self.width - 32, 32)
 self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
 bitmap = RPG::Cache.icon(item.icon_name)
 self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), 255)
 self.contents.draw_text(x + 28, y, 212, 32, item.name)
 self.contents.draw_text(x + 28, y, 244, 32, ': ' + number.to_s, 2)
 end
 
 def update_help
 KyoShopOrders.goods_id = self.item.id
 @help_window.set_text(self.item.description)
 end
 end
 
 class Window_ShopStatus
 alias kyon_discounts_win_shop_status_refresh refresh
 def refresh
 if @investment
 refresh_investment
 return
 end
 kyon_discounts_win_shop_status_refresh
 end
 
 def investment=(bool)
 @investment = bool
 refresh
 end
 
 def refresh_investment
 shares = $game_system.shop_shares[$game_variables[KyoShop::STORECODEVARID]]
 contents.font.color = system_color
 contents.draw_text(0, 0, 240, 32, KyoShopLabels::TOTALSHARES)
 contents.font.color = normal_color
 contents.draw_text(0, 0, 240, 32, shares.to_s, 2)
 end
 end
 
 class Interpreter
 alias kyon_discounts_inter_comm_302 command_302
 def command_302
 if $game_switches[KyoShop::GOODSSWITCHID]
 KyoShopOrders.store_event_id = @event_id
 $game_switches[KyoShop::GOODSSWITCHID] = false
 $game_system.shop_goods = [@parameters]
 loop do
 @index += 1
 if @list[@index].code == 605
 $game_system.shop_goods << @list[@index].parameters
 else
 return false
 end
 end
 end
 kyon_discounts_inter_comm_302
 end
 end
 
 class Scene_Shop
 alias kyon_discounts_scn_shop_up update
 def main
 start
 Graphics.transition
 while @keep_loop
 Graphics.update
 Input.update
 update
 end
 Graphics.freeze
 terminate
 end
 
 def start
 @keep_loop = true
 @stage = :main
 @shop_id = $game_variables[KyoShop::STORECODEVARID]
 @goods = $game_temp.shop_goods.dup
 @orders = $game_system.shop_goods.dup
 update_goods_orders_after_investment
 make_basic_windows
 @discount_window = Window_ShopDiscountCoupon.new
 @discount_window.disappear
 @discount_window.help_window = @help_window
 unless $game_system.shop_goods.empty?
 @order_window = Window_ShopBuy.new($game_system.shop_goods)
 @order_window.disappear
 @order_window.help_window = @help_window
 @option_window = Window_ShopBuyOptions.new
 @option_window.z += 200
 @option_window.disappear
 end
 if (@need_appraisal = KyoShop::APPRAISALS.keys.include?(@shop_id))
 @appraise_item_window = AppraiseItemWindow.new
 @appraise_item_window.visible = false
 @appraise_info_window = AppraiseInfoWindow.new(@shop_id)
 @appraise_info_window.visible = false
 options = KyoShopLabels::APPRAISALOPTIONS.dup
 @appraise_options = Window_Command.new(160, options)
 @appraise_options.disappear
 @appraise_options.x = 240
 @appraise_options.y = 200
 @result_info_window = AppraiseResultWindow.new
 options = KyoShopLabels::APPRAISALHAGGLEOPTIONS.dup
 @favor_options = Window_Command.new(160, options)
 @favor_options.disappear
 @favor_options.x = 240
 @favor_options.y = 200
 else
 @option_window.disable_item(3)
 end
 @purchase_window = Window_ShopBuy.new($game_temp.shop_goods)
 @purchase_window.disappear
 @purchase_window.help_window = @help_window
 @pack_id = [$game_map.map_id, KyoShopOrders.store_event_id]
 goods = $game_system.placed_orders[@pack_id]
 goods ||= []
 @pickup_window = Window_ShopPickUp.new(goods)
 @pickup_window.disappear
 @pickup_window.help_window = @help_window
 @sell_window = Window_ShopSell.new
 @sell_window.disappear
 @sell_window.help_window = @help_window
 @number_window = Window_ShopNumber.new
 @number_window.disappear
 @status_window = Window_ShopStatus.new
 @status_window.visible = false
 end
 
 def update_goods_orders_after_investment
 gds = []
 orders = []
 stuff = $game_system.check_shares(@shop_id)
 return if stuff.empty?
 stuff.each {|b| gds += strings_goods_conversion(b[1..-1]) if b[0] == :goods
 orders += string_good_conversion(b[1..-1]) if b[0] == :orders }
 $game_system.shop_goods = (@orders + orders).sort.uniq
 $game_temp.shop_goods = (@goods + gds).sort.uniq
 end
 
 def strings_goods_conversion(strings)
 data = []
 strings.each {|string| data << retrieve_item(string) }
 data
 end
 
 def retrieve_item(string)
 case string[0,1]
 when 'i' then [0, string[1..-1].to_i]
 when 'w' then [1, string[1..-1].to_i]
 when 'a' then [2, string[1..-1].to_i]
 end
 end
 
 def make_basic_windows
 @help_window = Window_Help.new
 @command_window = Window_ShopCommand.new
 @gold_window = Window_Gold.new
 @gold_window.x = 480
 @gold_window.y = 64
 @dummy_window = Window_Base.new(0, 128, 640, 352)
 @question_window = Window_ShopDiscountAlert.new
 @question_window.visible = false
 end
 
 def terminate
 @help_window.dispose
 @command_window.dispose
 @gold_window.dispose
 @dummy_window.dispose
 @purchase_window.dispose
 @pickup_window.dispose
 @sell_window.dispose
 @number_window.dispose
 @status_window.dispose
 @question_window.dispose
 @discount_window.dispose
 $game_variables[KyoShop::STORECODEVARID] = 0
 if @need_appraisal
 @appraise_item_window.dispose
 @appraise_info_window.dispose
 @appraise_options.dispose
 @result_info_window.dispose
 @favor_options.dispose
 end
 return if $game_system.shop_goods.empty?
 @order_window.dispose
 @option_window.dispose
 $game_system.shop_goods.clear
 KyoShopOrders.commissions.clear
 KyoShopOrders.steps.clear
 KyoShopOrders.store_event_id = nil
 @stage = nil
 end
 
 def update_discount_message
 cd = $game_party.check_discounts
 text = cd ? KyoShopLabels::SOMEDISCOUNTS : KyoShopLabels::NODISCOUNTS
 @question_window.set_text(text)
 end
 
 def update
 @help_window.update
 @gold_window.update
 @dummy_window.update
 @sell_window.update
 @status_window.update
 case @stage
 when :main then update_command
 when :option then update_option
 when :purchase then update_purchase
 when :place then update_place_order
 when :pickup then update_pickup_order
 when :discount then update_discount
 when :appraise then update_appraisal
 when :appraise_option then update_appraisal_option
 when :appraise_favor then update_appraisal_favor
 when :sell then update_sell
 when :number then update_number
 end
 end
 
 def update_command
 @command_window.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 $scene = Scene_Map.new
 return @keep_loop = nil
 elsif Input.trigger?(Input::C)
 case @command_window.index
 when 0 # buy
 $game_system.se_play($data_system.decision_se)
 @command_window.active = false
 if $game_system.shop_goods.empty?
 @discount = 0
 @dummy_window.visible = false
 @question_window.visible = true
 @status_window.visible = true
 @purchase_window.appear
 @purchase_window.refresh
 update_discount_message
 return @stage = :purchase
 else
 @option_window.appear
 return @stage = :option
 end
 when 1 # sell
 $game_system.se_play($data_system.decision_se)
 @command_window.active = false
 @dummy_window.visible = false
 @sell_window.appear
 @sell_window.refresh
 return
 when 2 # quit
 $game_system.se_play($data_system.decision_se)
 $scene = Scene_Map.new
 @keep_loop = nil
 end
 end
 end
 
 def update_option
 @option_window.update
 @order_window.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @option_window.disappear
 @status_window.visible = false
 @command_window.active = true
 @dummy_window.visible = true
 return @stage = :main
 elsif Input.trigger?(Input::C)
 shares = $game_system.shop_shares[@shop_id]
 inv_max, inv_price = KyoShop::SHARESMAXMIN
 pos = @option_window.index
 if pos == 3 and !@need_appraisal
 return $game_system.se_play($data_system.buzzer_se)
 end
 if pos == 4 and inv_max == shares
 return $game_system.se_play($data_system.buzzer_se)
 end
 $game_system.se_play($data_system.decision_se)
 @dummy_window.visible = false
 @option_window.disappear
 @question_window.visible = true
 @status_window.visible = true
 case pos
 when 0 # buy
 @discount = 0
 @purchase_window.discount = 0
 disc = $game_system.check_shares(@shop_id)
 disc.each {|b| @purchase_window.discount += b[1] if b[0] == :discount }
 @status_window.item = @purchase_window.item
 @purchase_window.refresh
 @purchase_window.appear
 update_discount_message
 return @stage = :purchase
 when 1 # place order
 @status_window.item = @order_window.item
 @order_window.appear
 @order_window.refresh
 @question_window.set_text(KyoShopLabels::PLACEORDER)
 return @stage = :place
 when 2 # pick up stuff
 @status_window.item = @pickup_window.item
 @pickup_window.appear
 @pickup_window.refresh
 @question_window.set_text(KyoShopLabels::PICKUPORDER)
 return @stage = :pickup
 when 3 # appraisal
 @appraise_item_window.appear
 @appraise_info_window.visible = true
 @result_info_window.visible = true
 @dummy_window.visible = false
 @command_window.visible = false
 @number_window.visible = false
 @status_window.visible = false
 @help_window.set_text(KyoShopLabels::APPRAISALMENULABEL)
 return @stage = :appraise
 when 4 # investments
 @status_window.investment = @investment = true
 inv_max = [inv_max - shares, $game_party.gold / inv_price].min
 fake_item = RPG::Item.new
 fake_item.name = KyoShopLabels::SHARES
 @price = inv_price
 @number_window.set(fake_item, inv_max, inv_price, nil, 10)
 @number_window.appear
 @question_window.set_text(KyoShopLabels::INVESTMENT)
 @stage = :number
 end
 end
 end
 
 def update_purchase
 @purchase_window.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 if $game_system.shop_goods.empty?
 @command_window.active = true
 @stage = :main
 else
 @option_window.appear
 @stage = :option
 end
 @discount = 0
 @purchase_window.discount = 0
 @dummy_window.visible = true
 @purchase_window.disappear
 @question_window.visible = false
 @status_window.visible = false
 @status_window.item = nil
 @help_window.set_text("")
 return
 end
 if Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @status_window.item = @purchase_window.item
 return
 end
 if Input.trigger?(KyoShop::DISCOUNTBUTTON)
 unless $game_party.check_discounts
 return $game_system.se_play($data_system.buzzer_se)
 end
 $game_system.se_play($data_system.decision_se)
 @purchase_window.disappear
 @discount_window.refresh
 @discount_window.appear
 @question_window.set_text(KyoShopLabels::SELECTDISCOUNT)
 return @stage = :discount
 elsif Input.trigger?(Input::C)
 discount = @purchase_window.discount
 percent = KyoShop.current_price_max
 @item = @purchase_window.item
 @price = @item.price + @item.price * percent / 100
 @price -= @item.price * discount / 100 if discount > 0
 if @item == nil or @price > $game_party.gold
 return $game_system.se_play($data_system.buzzer_se)
 end
 shop_max = KyoShop.current_item_max
 if (number = check_number) == shop_max
 return $game_system.se_play($data_system.buzzer_se)
 end
 $game_system.se_play($data_system.decision_se)
 max = @price == 0 ? shop_max : $game_party.gold / @price
 max = [max, shop_max - number].min
 @purchase_window.disappear
 @number_window.set(@item, max, @price)
 @number_window.appear
 @last_stage = @stage
 @stage = :number
 end
 end
 
 def update_place_order
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @option_window.appear
 @dummy_window.visible = true
 @order_window.disappear
 @question_window.visible = false
 @status_window.visible = false
 @status_window.item = nil
 @help_window.set_text("")
 return @stage = :option
 end
 if Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @status_window.item = @order_window.item
 return
 end
 if Input.trigger?(Input::C)
 $game_system.se_play($data_system.decision_se)
 @item = @order_window.item
 @price = @item.price
 percent = KyoShopOrders.commissions[@order_window.index]
 percent += KyoShop.current_price_max
 @price += percent * @item.price / 100 if percent > 0
 if @item == nil or @price > $game_party.gold
 return $game_system.se_play($data_system.buzzer_se)
 end
 number = check_number
 shop_max = KyoShop.current_item_max
 if number == shop_max
 return $game_system.se_play($data_system.buzzer_se)
 end
 $game_system.se_play($data_system.decision_se)
 max = @price == 0 ? shop_max : $game_party.gold / @price
 max = [max, shop_max - number].min
 @order_window.disappear
 @place_order = true
 @number_window.set(@item, max, @price, percent)
 @number_window.appear
 @question_window.set_text(KyoShopLabels::FEESAPPLY)
 @last_stage = @stage
 @stage = :number
 end
 end
 
 def update_pickup_order
 @pickup_window.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @dummy_window.visible = true
 @question_window.visible = false
 @status_window.visible = false
 @pickup_window.disappear
 @option_window.appear
 return @stage = :option
 end
 if Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @status_window.item = @pickup_window.item
 return
 end
 if Input.trigger?(Input::C)
 current_item = @pickup_window.item
 goods = $game_system.placed_orders[@pack_id]
 unless goods
 return $game_system.se_play($data_system.buzzer_se)
 end
 goods = goods[@pickup_window.index]
 unless current_item and goods[3] <= $game_party.steps
 return $game_system.se_play($data_system.buzzer_se)
 end
 $game_system.se_play($data_system.decision_se)
 number = goods[2]
 case current_item
 when RPG::Item then $game_party.gain_item(current_item.id, number)
 when RPG::Weapon then $game_party.gain_weapon(current_item.id, number)
 when RPG::Armor then $game_party.gain_armor(current_item.id, number)
 end
 $game_system.placed_orders[@pack_id].delete_at(@pickup_window.index)
 @pickup_window.deliver($game_system.placed_orders[@pack_id])
 end
 end
 
 def update_discount
 @discount_window.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @discount_window.disappear
 @purchase_window.appear
 return @stage = :purchase
 elsif Input.trigger?(Input::C)
 $game_system.se_play($data_system.decision_se)
 @coupons_allowed = KyoShop::COUPON_IDS.include?(@discount_window.item.id)
 @purchase_window.discount -= @discount
 @discount = @discount_window.item.price
 @discount_window.disappear
 @purchase_window.appear
 discount = @purchase_window.discount += @discount
 @purchase_window.refresh
 text = sprintf(KyoShopLabels::APPLYDISCOUNT, discount)
 @question_window.set_text(text)
 @stage = :purchase
 end
 end
 
 def update_appraisal
 @appraise_item_window.update
 if Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @appraise_info_window.refresh
 return
 end
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @appraise_item_window.disappear
 @appraise_info_window.visible = false
 @result_info_window.visible = false
 @result_info_window.contents.clear
 @appraise_options.disappear
 @dummy_window.visible = true
 @command_window.visible = true
 @number_window.visible = true
 @status_window.visible = true
 @option_window.appear
 @help_window.set_text("")
 return @stage = :option
 elsif Input.trigger?(Input::C)
 if @appraise_item_window.empty?
 return $game_system.se_play($data_system.buzzer_se)
 end
 $game_system.se_play($data_system.decision_se)
 @appraise_options.appear
 @stage = :appraise_option
 end
 end
 
 def update_appraisal_option
 @appraise_options.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @appraise_options.disappear
 return @stage = :appraise
 elsif Input.trigger?(Input::C)
 data = KyoShop::APPRAISALS[@shop_id]
 price = case @appraise_options.index
 when 0 then data[:test_cost]
 when 1 then data[:cost]
 when 2 then -10
 end
 if price == -10 or $game_party.gold < price
 $game_system.se_play($data_system.buzzer_se)
 @appraise_options.disappear
 return @stage = :appraise
 end
 $game_system.se_play($data_system.decision_se)
 item = @appraise_item_window.item
 $game_party.lose_gold(price)
 if rand(100) < data[:rate]
 goods = data[:goods]
 favors = $game_system.shop_favors[@shop_id]
 goods += data[:extras] if data[:help_limit] <= favors
 key = goods[rand(goods.size)]
 else
 key = data[:default]
 end
 kind, id = retrieve_item(key)
 case item.class
 when RPG::Item then $game_party.lose_item(item.id, 1)
 when RPG::Weapon then $game_party.lose_weapon(item.id, 1)
 when RPG::Armor then $game_party.lose_armor(item.id, 1)
 end
 if data[:target].has_key?(key)
 @appraise_options.disappear
 @favor_options.appear
 @result_info_window.ask_favor(new_item)
 @target_item = new_item
 @target_key = key
 @target_points = data[:target][key]
 @haggle_enabled = data[:haggle]
 @haggle_max = data[:overprice]
 return @stage = :appraise_favor
 end
 case kind
 when 0
 new_item = $data_items[id]
 $game_party.gain_item(id, 1)
 when 1
 new_item = $data_weapons[id]
 $game_party.gain_weapon(id, 1)
 when 2
 new_item = $data_armors[id]
 $game_party.gain_armor(id, 1)
 end
 @result_info_window.refresh(new_item)
 @appraise_item_window.refresh
 @gold_window.refresh
 @appraise_options.disappear
 @stage = :appraise
 end
 end
 
 def update_appraisal_favor
 @favor_options.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @favor_options.disappear
 return @stage = :appraise
 elsif Input.trigger?(Input::C)
 case @favor_options.index
 when 0
 if @overprice
 $game_system.se_play($data_system.shop_se)
 $game_system.shop_favors[@shop_id] += @target_points
 price = @overprice
 @target_points = nil
 else
 $game_system.se_play($data_system.decision_se)
 price = @target_item.price
 end
 $game_party.gain_gold(price)
 @overprice = @target_item = nil
 when 1
 unless @haggle_enabled
 return $game_system.se_play($data_system.buzzer_se)
 end
 $game_system.se_play($data_system.decision_se)
 @haggle_enabled = nil
 @overprice = rand(@haggle_max) + 1
 @overprice = 25 if @overprice < 25
 @overprice += @target_item.price
 @result_info_window.make_offer(@overprice)
 return
 when 2
 $game_system.se_play($data_system.decision_se)
 case @target_item.class
 when RPG::Item then $game_party.gain_item(@target_item.id, 1)
 when RPG::Weapon then $game_party.gain_weapon(@target_item.id, 1)
 when RPG::Armor then $game_party.gain_armor(@target_item.id, 1)
 end
 @target_item = nil
 @favor_options.disappear
 end
 return @stage = :appraise
 end
 end
 
 def check_number
 return number = case @item
 when RPG::Item then $game_party.item_number(@item.id)
 when RPG::Weapon then $game_party.weapon_number(@item.id)
 when RPG::Armor then $game_party.armor_number(@item.id)
 end
 end
 
 def update_number
 @number_window.update
 if Input.trigger?(Input::B)
 $game_system.se_play($data_system.cancel_se)
 @number_window.disappear
 @number_window.reset_multiplier
 case @command_window.index
 when 0 # buy or place order
 if @place_order
 @place_order = nil
 @order_window.appear
 @question_window.set_text(KyoShopLabels::PLACEORDER)
 elsif @investment
 @investment = nil
 @status_window.investment = nil
 @option_window.appear
 @question_window.visible = false
 @status_window.visible = false
 @dummy_window.visible = true
 else
 @purchase_window.appear
 discount = @purchase_window.discount
 if discount == 0
 update_discount_message
 else
 text = sprintf(KyoShopLabels::APPLYDISCOUNT, discount) + "%"
 @question_window.set_text(text)
 end
 end
 when 1 # sell
 update_discount_message
 @sell_window.appear
 @status_window.visible = false
 end
 @stage = @last_stage
 return @last_stage = nil
 elsif Input.trigger?(Input::C)
 $game_system.se_play($data_system.shop_se)
 @number_window.disappear
 case @command_window.index
 when 0  # buy
 $game_party.lose_gold(@number_window.number * @price)
 number = @number_window.number
 if @place_order
 update_number_place_order(number)
 elsif @investment
 update_number_investment(number)
 else
 update_number_purchase(number)
 end
 return
 when 1  # sell
 number = @number_window.number
 $game_party.gain_gold(number * (@item.price / 2))
 case @item
 when RPG::Item then   $game_party.lose_item(@item.id, number)
 when RPG::Weapon then $game_party.lose_weapon(@item.id, number)
 when RPG::Armor then  $game_party.lose_armor(@item.id, number)
 end
 @gold_window.refresh
 @sell_window.refresh
 @status_window.refresh
 @sell_window.appear
 @status_window.visible = false
 @stage = @last_stage
 return @last_stage = nil
 end
 end
 end
 
 def update_number_place_order(number)
 steps = $game_party.steps + KyoShopOrders.steps[@order_window.index]
 order = [nil, @item.id, number, steps]
 order[0] = case @item
 when RPG::Item then 0
 when RPG::Weapon then 1
 when RPG::Armor then 2
 end
 $game_system.placed_orders[@pack_id] ||= []
 $game_system.placed_orders[@pack_id] << order
 @pickup_window.deliver($game_system.placed_orders[@pack_id])
 @gold_window.refresh
 @status_window.refresh
 @place_order = nil
 @order_window.refresh
 @order_window.appear
 @question_window.set_text(KyoShopLabels::PLACEORDER)
 @stage = :place
 end
 
 def update_number_investment(number)
 @investment = nil
 @status_window.investment = nil
 $game_system.shop_shares[@shop_id] += number
 update_goods_orders_after_investment
 @order_window.deliver($game_system.shop_goods)
 @purchase_window.deliver($game_temp.shop_goods)
 @gold_window.refresh
 @question_window.visible = false
 @status_window.visible = false
 @dummy_window.visible = true
 @number_window.reset_multiplier
 @number_window.disappear
 @option_window.appear
 @stage = :option
 end
 
 def update_number_purchase(number)
 case @item
 when RPG::Item then $game_party.gain_item(@item.id, number)
 when RPG::Weapon then $game_party.gain_weapon(@item.id, number)
 when RPG::Armor then $game_party.gain_armor(@item.id, number)
 end
 if @coupons_allowed
 @coupons_allowed = nil
 $game_party.lose_item(@discount_window.item.id, 1)
 update_discount_message
 @discount_window.refresh
 @purchase_window.discount = 0
 @discount = 0
 end
 @gold_window.refresh
 @status_window.refresh
 @purchase_window.refresh
 @purchase_window.appear
 @stage = :purchase
 end
 end
I don't know why I let wulfo convince me of adding such a weird feature, namely the haggling part... =_=
 
 
 RE: KyoDiscounts XP VX, ACE MV - kyonides -  01-15-2019
 
 Well, don't even think I've forgotten about plain old VX, guys!
  
 I came back with the VX release of KyoDiscounts this time! It's still a beta release, but it's quite functional already. I just need some feedback to make sure it works just as intended.
  
 
 Code: # * KyoDiscounts VX#   Scripter : Kyonides-Arkanthos
 #   v1.5.0 - 2019-01-15
 
 #   Besides the player can also place orders to get an item that is supposed to
 #   be found at another store only. The player will be charged an extra fee, but
 #   he or she won't need to go back to another store. The player would only need
 #   to keep walking for a while before the goods are available at the store.
 #   Now the required steps for each placed order will be automatically increased
 #   between 0% and 50%, making it look a bit random but also kind of realistic.
 
 # * Unknown Item or Weapon or Armor Appraisals *
 
 #   Use the Game Variable defined in the STORECODEVARID Constant to store the
 #   Shop ID that will include the appraisal service.
 #   Use the MYSTERIOUS series of Arrays to include as many IDs of unknown items
 #   or weapons or armors that will serve as fillers till they get replaced by
 #   the actual goods they represent.
 #   Follow the Instructions included in the APPRAISALS Hash to define all
 #   conditions that will affect an appraiser's task of identifying the item.
 
 #   Script Calls   #
 
 #   $game_party.discount_cards_expire
 #      Makes all Discount Cards expire as part of the game's plot.
 
 #   $game_party.disc_card_expire(Card_ID)
 #      Makes an specific Discount Card expire as part of the game's plot.
 
 #   KyoShopOrders << [Percent1, Percent2, etc.]
 #      Defines a Commission percent for every Item in the Place Order List.
 
 #   KyoShopOrders.steps = [Steps1, Steps2, etc.]
 #   KyoShopOrders.steps += [Steps5, Steps6, etc.]
 #      Defines Steps required by every Order in the Place Order List.
 #      The 2nd call will be required only if you couldn't include all steps.
 
 #   KyoShop.scarcity_lvl = 0 or higher
 #     Define all prices and maximum number of units per shop item.
 #     0 means no scarcity, 1 or higher reflects how severe it is.
 #     You also have to configure the @scarce_limits hash in order to predefine
 #     :price and :max per scarcity level. The maximum scarcity level depends on
 #     how many values you entered in both :price and :max arrays.
 #     In few words, you define the maximum scarcity level ever possible!
 
 module KyoShop
 # Maximum number of units for each shop item
 NUMBERMAX = 99
 # Button that will open the Discount window while on the shop menu
 DISCOUNTBUTTON = Input::A
 # Add Discount Card Object IDs
 DISCOUNT_IDS = [21, 22, 23]
 # Add Discount Coupon Object IDs
 COUPON_IDS = [24, 25, 26]
 # Maximum Steps before Discount Card expires : ID => Steps
 STEPS = { 21 => 500, 22 => 300, 23 => 150 }
 # Exclusive Stores In Game Variable ID
 STORECODEVARID = 1
 # Exclusive Stores List : Object ID => Exclusive Store Code
 EXCLUSIVESTORES = { 35 => 102 }
 # Switch ID : deactivates Store to add Goods found elsewhere
 GOODSSWITCHID = 1
 # Store IDs for stores where you have invested some gold
 INVESTSTOREIDS = [101]
 # Maximum Number of Shares & Share Price
 SHARESMAXMIN = [10000, 100]
 INVESTMENTS = {} # Store Investments - Do Not Edit This Line
 INVESTMENTS.default = {} # Do Not Edit This Line
 # Available Improvements #
 # :discount : [:discount, 25]
 # :goods    : [:goods, 'i10', 'w4', 'a6']
 # :orders   : [:orders, 'i11', 'w5', 'a7']
 # [Store ID] = { Shares => Prize, Shares => Another Prize, etc. }
 INVESTMENTS[101] = { 50 => [:goods,'i10','w5','a6'], 100 => [:discount,10] }
 APPRAISALS = {} # Do Not Edit This Line!
 # [Store ID] = { appraisal cost => $, estimate cost => $, success rate => %,
 # times you can help the a. => 0, bad result => "i1", goods => [item4, etc.] }
 APPRAISALS[101] = { :cost => 150, :test_cost => 75, :rate => 10,
 :default => 'i1', :help_limit => 5, :haggle => true,
 :target => { 'i9' => 1, 'i10' => 2 },
 :goods => ['i2','i3','i9','i10'], :extras => ['i11'] }
 # Add Item IDs for unknown shop goods that need to be appraised by experts
 MYSTERIOUSITEMS = []
 # Add Weapon IDs for unknown shop goods that need to be appraised by experts
 MYSTERIOUSWEAPONS = []
 # Add Armor IDs for unknown shop goods that need to be appraised by experts
 MYSTERIOUSARMORS = []
 @scarce_limits = {
 :price  => [0, 25, 50, 100, 250, 350, 500, 650, 800],
 :max => [NUMBERMAX, NUMBERMAX - 10, NUMBERMAX - 25, NUMBERMAX - 35,
 NUMBERMAX - 50, NUMBERMAX - 65, NUMBERMAX - 80, NUMBERMAX - 90, 1]
 #:item => [1, 2, 3, 4, 5, 6],
 #:weapon => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
 #:armor => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
 }
 @scarce_lvl = 0 # Initial Level
 def self.current_item_max() @scarce_limits[:max][@scarce_lvl] end
 def self.current_price_max() @scarce_limits[:price][@scarce_lvl] end
 def self.scarcity_limits() @scarce_limits end
 def self.scarcity_lvl() @scarce_lvl end
 def self.scarcity_lvl=(lvl) @scarce_lvl = lvl end
 end
 
 
 module KyoShopLabels
 # Buy Stuff & Place Order & Pick Up Items Label
 BUYPLACEPICKUP = ['Buy Items', 'Place Order', 'Pick Up Items', 'Invest']
 # Item Price Data Labels
 PRICEDATA = ['Basic Price', 'Commission', 'Discount', 'Total Price']
 # Place an Order Label
 PLACEORDER = 'Do you wish to place an order?'
 # Pick Up Order Label
 PICKUPORDER = 'Do you want to pick up an order?'
 # No Order Found Label
 NOORDERFOUND = 'There is nothing left, boss!'
 # Available Discounts Label
 SOMEDISCOUNTS = 'Press A to get a discount'
 # No Discount Available Label
 NODISCOUNTS = 'No Discount Available'
 # Select a Discount Card or Coupon Label
 SELECTDISCOUNT = 'Choose a Card or Coupon'
 # Apply Discount Label
 APPLYDISCOUNT = 'Discount Applied'
 # Commission Fees Apply Label
 FEESAPPLY = 'Special Fees Apply'
 # Discount Card's Steps Left Label
 STEPSLEFT = " %s steps left."
 # Investment Label...
 INVESTMENT = 'Want to invest in this store?'
 # Share Number Label
 SHARES = 'Share Number'
 # Adquired or Purchased Shares Label
 TOTALSHARES = 'Total Shares'
 # Need a Discount Label
 NEEDADISCOUNT = 'Need a Discount?'
 # Pick Item to be Appraised Label
 APPRAISALMENULABEL = "Appraisal Menu"
 # Appraisal Window Labels
 APPRAISALLABELS = ["Quick Test Cost", "Normal Cost"]
 # Appraisal Options Labels
 APPRAISALOPTIONS = ["Quick Test", "Detailed Test", "Cancel"]
 # Purchase Offer and Haggle Labels
 APPRAISALHAGGLEOPTIONS = ["Accept", "Haggle", "Decline"]
 # Appraisal End Result Labels
 APPRAISALRESULTLABELS = [
 "The item at hand is nothing else but... %s",
 "I think it might be worth some... %s",
 "I've been searching for some %s!",
 "Now I want to make a deal.",
 "What if I make a better offer?",
 "Would you accept some %s?"
 ]
 end
 # DO NOT EDIT ANYTHING ELSE #
 module KyoShopOrders
 @goods = []
 @commissions = []
 @steps = []
 class << self
 attr_accessor :store_id, :goods_id, :goods
 attr_reader :steps, :commissions
 def steps=(val) @steps = val.map {|n| n + rand((n / 2) + 2) } end
 def <<(val)
 @commissions += val
 @commissions = @commissions.flatten
 end
 end
 end
 
 class Game_System
 attr_reader :placed_orders, :shop_shares, :shop_favors
 alias kyon_discounts_gm_sys_init initialize
 def initialize
 @placed_orders = {}
 @shop_shares = {}
 @shop_favors = {}
 @placed_orders.default = []
 @shop_shares.default = 0
 @shop_favors.default = 0
 kyon_discounts_gm_sys_init
 end
 
 def disc_store?(disc_id) !KyoShop::EXCLUSIVESTORES[disc_id] end
 
 def excl_disc_store?(disc_id)
 exclusive = KyoShop::EXCLUSIVESTORES[disc_id]
 exclusive == $game_variables[KyoShop::STORECODEVARID]
 end
 
 def check_shares(shop_id)
 results = []
 shares = @shop_shares[shop_id]
 investments = KyoShop::INVESTMENTS[shop_id]
 limits = KyoShop::INVESTMENTS[shop_id].keys.sort
 results = investments.select{|limit| shares >= limit[0] }.map {|r| r[1] }
 end
 end
 
 class Game_Party
 attr_reader :discounts
 alias kyon_discounts_gm_party_init initialize
 alias kyon_discounts_gm_party_gain_item gain_item
 def initialize
 @discounts = {}
 kyon_discounts_gm_party_init
 end
 
 def gain_item(item, n, equip=false)
 kyon_discounts_gm_party_gain_item(item, n, equip)
 return if item == nil or n == 0
 return unless KyoShop::DISCOUNT_IDS.include?(item.id)
 item_id = item.id
 if @discounts[item_id]
 @discounts[item_id] += KyoShop::STEPS[item_id]
 @items[item_id] = 1
 else
 @discounts[item_id] = KyoShop::STEPS[item_id]
 end
 end
 
 def check_discounts
 unless @discounts.empty?
 for did in KyoShop::DISCOUNT_IDS
 next unless @discounts[did] and @discounts[did] > 0
 return true if $game_system.disc_store?(did)
 return true if $game_system.excl_disc_store?(did)
 end
 end
 for cid in KyoShop::COUPON_IDS
 next unless @items[cid] and @items[cid] > 0
 return true if $game_system.disc_store?(cid)
 return true if $game_system.excl_disc_store?(cid)
 end
 return false
 end
 
 def decrease_discounts
 KyoShop::DISCOUNT_IDS.each {|n| next unless @discounts[n]
 @discounts[n] -= 1 if @discounts[n] > 0 }
 end
 
 def discount_cards_expire
 KyoShop::DISCOUNT_IDS.each {|n| @discounts[n] = 0 if @discounts[n] }
 end
 
 def disc_card_expire(dc_id) @discounts[dc_id] = 0 end
 def item_include?(item_id) @items[item_id] and @items[item_id] > 0 end
 end
 
 class Game_Player
 alias kyon_discounts_coupons_gm_player_increase_steps increase_steps
 def increase_steps
 kyon_discounts_coupons_gm_player_increase_steps
 $game_party.decrease_discounts
 end
 end
 
 class Game_Interpreter
 alias kyon_discounts_game_inter_comm_302 command_302
 def command_302
 if $game_switches[KyoShop::GOODSSWITCHID]
 KyoShopOrders.store_id = @event_id
 $game_switches[KyoShop::GOODSSWITCHID] = false
 KyoShopOrders.goods = [@params[0,2]]
 loop do
 @index += 1
 if @list[@index].code == 605
 KyoShopOrders.goods << @list[@index].parameters
 else
 return false
 end
 end
 end
 kyon_discounts_game_inter_comm_302
 end
 end
 
 class Window_Base
 def appear
 self.active = true
 self.visible = true
 end
 
 def disappear
 self.active = false
 self.visible = false
 end
 
 def draw_currency_value(value, x, y, width)
 c = self.contents
 cx = c.text_size(Vocab::gold).width
 c.font.color = normal_color
 c.draw_text(x - 8, y, width-cx-2, WLH, value, 2)
 c.font.color = system_color
 c.draw_text(x, y, width, WLH, Vocab::gold, 2)
 end
 end
 
 class Window_KyoShopHelp < Window_Help
 def set_text(text, align=0)
 if KyoShop::DISCOUNT_IDS.include?(KyoShopOrders.goods_id)
 steps = $game_party.discounts[KyoShopOrders.goods_id].to_s
 text = sprintf(KyoShopLabels::STEPSLEFT, steps)
 KyoShopOrders.goods_id = nil
 end
 super(text, align)
 end
 end
 
 class Window_Item
 alias kyon_discounts_win_item_up_help update_help
 def update_help
 KyoShopOrders.goods_id = self.item.id
 kyon_discounts_win_item_up_help
 end
 end
 
 class AppraiseItemWindow < Window_Selectable
 def initialize
 super(0, 56, 544-160, 280)
 @column_max = 1
 refresh
 self.index = 0
 end
 
 def refresh
 self.contents.clear
 @data = []
 for n in KyoShop::MYSTERIOUSITEMS
 next if $game_party.item_number(n) == 0
 @data << $data_items[n]
 end
 for i in KyoShop::MYSTERIOUSWEAPONS
 next if $game_party.weapon_number(i) == 0
 @data << $data_weapons[i]
 end
 for i in KyoShop::MYSTERIOUSARMORS
 next if $game_party.armor_number(i) == 0
 @data << $data_armors[i]
 end
 @item_max = @data.size
 return if @item_max == 0
 self.contents = Bitmap.new(width - 32, row_max * 32)
 @item_max.times{|i| draw_item(i) }
 end
 
 def draw_item(index)
 item = @data[index]
 number = case item
 when RPG::Item then $game_party.item_number(item.id)
 when RPG::Weapon then $game_party.weapon_number(item.id)
 when RPG::Armor then $game_party.armor_number(item.id)
 end
 c = self.contents
 x = 4 + index % 2 * (288 + 32)
 y = index / 2 * 32
 rect = Rect.new(x, y, self.width / @column_max - 32, 32)
 c.fill_rect(rect, Color.new(0, 0, 0, 0))
 bit = RPG::Cache.icon(item.icon_name)
 c.blt(x, y + 4, bit, Rect.new(0, 0, 24, 24), 255)
 c.draw_text(x + 28, y, 212, 32, item.name, 0)
 c.draw_text(x + 240, y, 16, 32, ":", 1)
 c.draw_text(x + 256, y, 24, 32, number.to_s, 2)
 end
 def item() @data[@index] end
 def empty?() @data.empty? end
 end
 
 class AppraiseInfoWindow < Window_Base
 def initialize(store_id)
 super(384, 112, 160, 224)
 @data = KyoShop::APPRAISALS[store_id]
 @labels = KyoShopLabels::APPRAISALLABELS.dup
 @currency = Vocab.gold
 self.contents = Bitmap.new(width - 32, height - 32)
 refresh
 end
 
 def refresh
 aw = width - 32
 contents.clear
 contents.font.color = system_color
 contents.draw_text(0, 0, aw, 24, @labels[0])
 contents.draw_text(0, 48, aw, 24, @labels[1])
 contents.draw_text(0, 24, aw, 24, @currency, 2)
 contents.draw_text(0, 72, aw, 24, @currency, 2)
 contents.font.color = normal_color
 contents.draw_text(0, 24, width - 48, 24, @data[:test_cost].to_s, 2)
 contents.draw_text(0, 72, width - 48, 24, @data[:cost].to_s, 2)
 end
 end
 
 class AppraiseResultWindow < Window_Base
 def initialize
 super(0, 334, 544, 84)
 @labels = KyoShopLabels::APPRAISALRESULTLABELS.dup
 @currency = Vocab.gold #draw_currency_value(value, x, y, width)
 self.contents = Bitmap.new(width - 32, height - 32)
 end
 
 def refresh(item)
 contents.clear
 result = sprintf(@labels[0], item.name)
 cost = sprintf(@labels[1], item.price) + " " + @currency
 contents.draw_text(0, 0, width - 32, 24, result)
 contents.draw_text(0, 24, width - 32, 24, cost)
 end
 
 def ask_favor(item)
 contents.clear
 result = sprintf(@labels[2], item.name)
 contents.draw_text(0, 0, width - 32, 24, result)
 contents.draw_text(0, 24, width - 32, 24, @labels[3])
 end
 
 def make_offer(overprice)
 contents.clear
 result = sprintf(@labels[5], overprice) + " " + @currency
 contents.draw_text(0, 0, width - 32, 24, @labels[4])
 contents.draw_text(0, 24, width - 32, 24, result)
 end
 end
 
 class Window_ShopBuyPlace < Window_Selectable
 attr_accessor :discount
 attr_reader :discounts
 def initialize(shop_goods, discounts=[])
 super(0, 112, 304, 248)
 @shop_goods = shop_goods
 @discount = 0
 @discounts = discounts
 refresh
 self.index = 0
 end
 
 def deliver(goods)
 @shop_goods = goods
 if goods.size - 1 < @index
 @index = goods.size > 0 ? (@index + goods.size - 1) % goods.size : 0
 update_cursor_rect
 end
 refresh
 self.index = 0
 end
 
 def item() @data[self.index] end
 
 def refresh
 @data = []
 for goods_item in @shop_goods
 item = case goods_item[0]
 when 0 then $data_items[goods_item[1]]
 when 1 then $data_weapons[goods_item[1]]
 when 2 then $data_armors[goods_item[1]]
 end
 @data << item if item
 end
 @item_max = @data.size
 create_contents
 @item_max.times {|i| draw_item(i) }
 end
 
 def draw_item(index)
 item = @data[index]
 number = $game_party.item_number(item)
 enabled = (item.price <= $game_party.gold and number < 99)
 rect = item_rect(index)
 self.contents.clear_rect(rect)
 draw_item_name(item, rect.x, rect.y, enabled)
 rect.width -= 4
 fee = @discounts.empty? ? @discount : @discounts[index]
 fee = item.price * fee / 100
 self.contents.draw_text(rect, item.price + fee, 2)
 end
 
 def update_help
 @help_window.set_text(item == nil ? "" : item.description)
 end
 end
 
 class Window_ShopNumber
 def initialize(x, y)
 super(x, y, 304, 248)
 @item = nil
 @max = 1
 @price = 0
 @number = 1
 @percent = 0
 @multiplier = 1
 end
 
 def reset_multiplier
 @multiplier = 1
 @number = 1
 refresh
 end
 
 def set(item, max, price, percent=0, multiplier=1)
 @item = item
 @max = max
 @price = price
 @number = 1
 @multiplier = multiplier
 @percent = percent
 refresh
 end
 
 def refresh
 self.contents.clear
 draw_item_name(@item, 0, 96)
 self.contents.font.color = normal_color
 if @multiplier == 1
 cx1, cx2, cx3, cw1, cw2 = [212, 240, 244, 28, 28]
 else
 cx1, cx2, cx3, cw1, cw2 = [196, 202, 212, 68, 64]
 end
 self.contents.draw_text(cx1, 96, 20, WLH, "")
 self.contents.draw_text(cx2, 96, cw1, WLH, @number, 2)
 self.cursor_rect.set(cx3, 96, cw2, WLH)
 if @percent == 0 or @multiplier > 1
 draw_currency_value(@price * @number, 4, 96 + WLH * 2, 264)
 return
 end
 draw_currency_value(@item.price * @number, 4, 72 + WLH * 2, 264)
 draw_percent_value(@percent, 4, 96 + WLH * 2, 264)
 end_price = @item.price + @item.price * @percent / 100
 draw_currency_value(end_price * @number, 4, 120 + WLH * 2, 264)
 draw_price_labels(x - 20, 120, 160)
 end
 
 def draw_percent_value(value, x, y, width)
 cx = contents.text_size(Vocab::gold).width
 self.contents.font.color = normal_color
 self.contents.draw_text(x - 8, y, width-cx-2, WLH, value, 2)
 text = KyoShopLabels::PRICEDATA[@percent < 0 ? 2 : 1]
 self.contents.draw_text(x + 40, y, width, WLH, text)
 self.contents.font.color = system_color
 self.contents.draw_text(x, y, width, WLH, '%', 2)
 end
 
 def draw_price_labels(x, y, w)
 self.contents.font.color = normal_color
 self.contents.draw_text(x, y, w, WLH, KyoShopLabels::PRICEDATA[0], 2)
 self.contents.draw_text(x, y + 48, w, WLH, KyoShopLabels::PRICEDATA[3], 2)
 end
 end
 
 class Window_ShopPickUp < Window_ShopBuyPlace
 def draw_item(index)
 item = @data[index]
 qty, steps = @shop_goods[index][2..3]
 number = $game_party.item_number(item)
 enough = (number + qty < 100 and steps <= $game_party.steps)
 self.contents.font.color.alpha = enough ? 255 : 128
 y = index * 24
 draw_icon(item.icon_index, 0, y, enough)
 self.contents.draw_text(32, y - 4, 212, 32, item.name, 0)
 self.contents.draw_text(180, y - 4, 88, 32, qty.to_s, 2)
 end
 end
 
 class Window_ShopDiscountAlert < Window_Base
 def initialize
 super(0, 360, 304, 56)
 self.contents = Bitmap.new(width - 32, height - 32)
 end
 
 def set_text(text)
 self.contents.clear
 self.contents.draw_text(0, 0, 272, 24, text)
 end
 end
 
 class Window_ShopDiscountCoupon < Window_Selectable
 def initialize
 super(0, 112, 304, 248)
 self.index = 0
 refresh
 end
 
 def item() @data[self.index] end
 
 def refresh
 @data = []
 gs = $game_system
 dc_ids = $game_party.discounts.keys.sort
 dc_ids.each {|i| next if $game_party.discounts[i] == 0
 next unless gs.disc_store?(i) or gs.excl_disc_store?(i)
 @data << $data_items[i] }
 KyoShop::COUPON_IDS.each {|i| next unless $game_party.item_include?(i)
 @data << $data_items[i] }
 @item_max = @data.size
 self.index -= 1 if @index > @item_max - 1
 create_contents
 @item_max.times {|i| draw_item(i) }
 end
 
 def draw_item(index)
 item = @data[index]
 number = $game_party.item_number(item)
 y = index * 24
 rect = Rect.new(4, y, self.width - 32, 32)
 self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
 enabled = $game_party.item_can_use?(item)
 draw_item_name(item, rect.x, rect.y, enabled)
 self.contents.draw_text(32, y, 236, 24, ': ' + number.to_s, 2)
 end
 
 def update_help
 KyoShopOrders.goods_id = self.item.id
 @help_window.set_text(self.item.description)
 end
 end
 
 class Window_ShopStatus
 alias kyon_discounts_win_shop_status_refresh refresh
 def investment=(bool)
 @investment = bool
 refresh
 end
 
 def refresh
 if @investment
 refresh_investment
 return
 end
 kyon_discounts_win_shop_status_refresh
 end
 
 def refresh_investment
 self.contents.clear
 shares = $game_system.shop_shares[$game_variables[KyoShop::STORECODEVARID]]
 contents.font.color = system_color
 contents.draw_text(0, 0, 200, 32, KyoShopLabels::TOTALSHARES)
 contents.font.color = normal_color
 contents.draw_text(0, 0, 208, 32, shares.to_s, 2)
 end
 end
 
 class Scene_Shop
 def start
 @stage = :main
 @shop_id = $game_variables[KyoShop::STORECODEVARID]
 @goods = $game_temp.shop_goods.dup
 @orders = KyoShopOrders.goods.dup
 update_goods_orders_after_investment
 create_menu_background
 create_command_window
 make_basic_data_windows
 make_shop_windows
 make_discount_order_pickup_windows
 make_appraisal_windows
 end
 
 def make_basic_data_windows
 @help_window = Window_Help.new
 @gold_window = Window_Gold.new(384, 56)
 @dummy_window = Window_Base.new(0, 112, 544, 304)
 @status_window = Window_ShopStatus.new(304, 112)
 @status_window.visible = false
 end
 
 def make_shop_windows
 @buy_window = Window_ShopBuyPlace.new($game_temp.shop_goods)
 @buy_window.disappear
 @buy_window.help_window = @help_window
 @sell_window = Window_ShopSell.new(0, 112, 544, 304)
 @sell_window.disappear
 @sell_window.help_window = @help_window
 @number_window = Window_ShopNumber.new(0, 112)
 @number_window.disappear
 end
 
 def make_discount_order_pickup_windows
 @question_window = Window_ShopDiscountAlert.new
 @question_window.visible = false
 @discount_window = Window_ShopDiscountCoupon.new
 @discount_window.disappear
 @discount_window.help_window = @help_window
 commands = KyoShopLabels::BUYPLACEPICKUP.dup
 commands.pop unless KyoShop::INVESTSTOREIDS.include?(@shop_id)
 @extras_window = Window_Command.new(200, commands)
 @extras_window.x = (544 - 200) / 2
 @extras_window.y = 112
 @extras_window.disappear
 unless KyoShopOrders.goods.empty?
 goods = KyoShopOrders.goods
 @order_window = Window_ShopBuyPlace.new(goods, KyoShopOrders.commissions)
 @order_window.disappear
 @order_window.help_window = @help_window
 end
 @pack_id = [$game_map.map_id, KyoShopOrders.store_id]
 goods = $game_system.placed_orders[@pack_id]
 unless goods
 goods = []
 @no_orders = true
 @extras_window.draw_item(2, nil)
 end
 @pickup_window = Window_ShopPickUp.new(goods)
 @pickup_window.disappear
 @pickup_window.help_window = @help_window
 end
 
 def make_appraisal_windows
 if (@need_appraisal = KyoShop::APPRAISALS.keys.include?(@shop_id))
 @appraise_item_window = AppraiseItemWindow.new
 @appraise_item_window.visible = false
 @appraise_info_window = AppraiseInfoWindow.new(@shop_id)
 @appraise_info_window.visible = false
 options = KyoShopLabels::APPRAISALOPTIONS.dup
 @appraise_options = Window_Command.new(160, options)
 @appraise_options.disappear
 @appraise_options.x = 240
 @appraise_options.y = 200
 @result_info_window = AppraiseResultWindow.new
 @result_info_window.visible = false
 options = KyoShopLabels::APPRAISALHAGGLEOPTIONS.dup
 @favor_options = Window_Command.new(160, options)
 @favor_options.disappear
 @favor_options.x = 240
 @favor_options.y = 200
 else
 @extras_window.draw_item(3, nil)
 end
 end
 
 def update_goods_orders_after_investment
 gds = []
 orders = []
 stuff = $game_system.check_shares(@shop_id)
 return if stuff.empty?
 stuff.each {|b| gds += strings_goods_conversion(b[1..-1]) if b[0] == :goods
 orders += string_good_conversion(b[1..-1]) if b[0] == :orders }
 KyoShopOrders.goods = (@orders + orders).sort.uniq
 $game_temp.shop_goods = (@goods + gds).sort.uniq
 end
 
 def strings_goods_conversion(strings)
 data = []
 strings.each {|string| data << retrieve_item(string) }
 data
 end
 
 def retrieve_item(string)
 case string[0,1]
 when 'i' then [0, string[1..-1].to_i]
 when 'w' then [1, string[1..-1].to_i]
 when 'a' then [2, string[1..-1].to_i]
 end
 end
 
 def update_discount_message
 if @buy_window.discount < 0
 text = sprintf(KyoShopLabels::APPLYDISCOUNT, @discount_window.item.price)
 else
 cd = $game_party.check_discounts
 text = cd ? KyoShopLabels::SOMEDISCOUNTS : KyoShopLabels::NODISCOUNTS
 end
 @question_window.set_text(text)
 end
 
 def terminate
 dispose_menu_background
 dispose_command_window
 @discount_window.dispose
 @extras_window.dispose
 @order_window.dispose
 @pickup_window.dispose
 @question_window.dispose
 @help_window.dispose
 @gold_window.dispose
 @dummy_window.dispose
 @buy_window.dispose
 @sell_window.dispose
 @number_window.dispose
 @status_window.dispose
 if @need_appraisal
 @appraise_item_window.dispose
 @appraise_info_window.dispose
 @appraise_options.dispose
 @result_info_window.dispose
 @favor_options.dispose
 end
 KyoShopOrders.goods.clear
 KyoShopOrders.steps.clear
 KyoShopOrders.commissions.clear
 KyoShopOrders.store_id = 0
 @stage = @shop_id = nil
 end
 
 def update
 super
 update_menu_background
 @help_window.update
 @gold_window.update
 @number_window.update
 @status_window.update
 case @stage
 when :main then update_command
 when :option then update_extras
 when :purchase then update_purchase
 when :place then update_place_order
 when :pickup then update_pickup_order
 when :discount then update_discount
 when :appraise then update_appraisal
 when :appraise_option then update_appraisal_option
 when :appraise_favor then update_appraisal_favor
 when :sell then update_sell
 when :number then update_number
 end
 end
 
 def update_command
 @command_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 $scene = Scene_Map.new
 return
 elsif Input.trigger?(Input::C)
 case @command_window.index
 when 0  # buy
 Sound.play_decision
 @command_window.active = false
 @extras_window.appear
 @question_window.visible = true
 update_discount_message
 return @stage = :option
 when 1  # sell
 return Sound.play_buzzer if $game_temp.shop_purchase_only
 Sound.play_decision
 @command_window.active = false
 @dummy_window.visible = false
 @sell_window.appear
 @sell_window.refresh
 return @stage = :sell
 when 2  # Quit
 Sound.play_decision
 $scene = Scene_Map.new
 end
 end
 end
 
 def update_extras
 @extras_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @extras_window.disappear
 @question_window.visible = false
 @command_window.active = true
 return @stage = :main
 elsif Input.trigger?(Input::C)
 if @no_orders and @extras_window.index == 2
 return Sound.play_buzzer
 end
 shares = $game_system.shop_shares[@shop_id]
 inv_max, inv_price = KyoShop::SHARESMAXMIN
 if @extras_window.index == 3 and inv_max == shares
 return Sound.play_buzzer
 end
 Sound.play_decision
 @extras_window.disappear
 @dummy_window.visible = false
 @status_window.visible = true
 @question_window.visible = @extras_window.index != 3
 update_discount_message
 case @extras_window.index
 when 0 # purchase
 @status_window.item = @buy_window.item
 @buy_window.appear
 @buy_window.refresh
 @last_stage = :option
 return @stage = :purchase
 when 1 # place order
 @status_window.item = @order_window.item
 @order_window.appear
 @question_window.set_text(KyoShopLabels::FEESAPPLY)
 return @stage = :place
 when 2 # pick up order
 @status_window.item = @pickup_window.item
 @pickup_window.appear
 return @stage = :pickup
 when 3 # appraisals
 @appraise_item_window.appear
 @appraise_info_window.visible = true
 @result_info_window.visible = true
 @dummy_window.visible = false
 @command_window.visible = false
 @number_window.visible = false
 @status_window.visible = false
 @help_window.set_text(KyoShopLabels::APPRAISALMENULABEL)
 return @stage = :appraise
 when 4 # investments
 @status_window.investment = @investment = true
 inv_max = [inv_max - shares, $game_party.gold / inv_price].min
 fake_item = RPG::Item.new
 fake_item.name = KyoShopLabels::SHARES
 @price = inv_price
 @number_window.set(fake_item, inv_max, inv_price, 0, 10)
 @number_window.appear
 @question_window.set_text(KyoShopLabels::INVESTMENT)
 @stage = :number
 end
 end
 end
 
 def update_purchase
 @buy_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @buy_window.disappear
 @status_window.visible = false
 @question_window.visible = false
 @dummy_window.visible = true
 @extras_window.appear
 @status_window.item = nil
 @help_window.set_text("")
 return @stage = :option
 elsif Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @status_window.item = @buy_window.item
 return
 elsif Input.trigger?(KyoShop::DISCOUNTBUTTON)
 unless $game_party.check_discounts
 return Sound.play_buzzer
 end
 Sound.play_decision
 @buy_window.disappear
 @discount_window.refresh
 @discount_window.appear
 @question_window.set_text(KyoShopLabels::SELECTDISCOUNT)
 return @stage = :discount
 elsif Input.trigger?(Input::C)
 @item = @buy_window.item
 number = $game_party.item_number(@item)
 shop_max = KyoShop.current_item_max
 if @item == nil or @item.price > $game_party.gold or number == shop_max
 return Sound.play_buzzer
 end
 Sound.play_decision
 max = @item.price == 0 ? shop_max : $game_party.gold / @item.price
 max = [max, shop_max - number].min
 @buy_window.disappear
 discount = @buy_window.discount < 0 ? @buy_window.discount : 0
 @number_window.set(@item, max, @item.price, discount)
 @number_window.appear
 @last_stage = :purchase
 @stage = :number
 end
 end
 
 def update_place_order
 @order_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @status_window.disappear
 @order_window.disappear
 @extras_window.appear
 @dummy_window.visible = true
 @question_window.visible = false
 return @stage = :option
 elsif Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @status_window.item = @order_window.item
 return
 elsif Input.trigger?(Input::C)
 @item = @order_window.item
 @price = @item.price
 percent = KyoShopOrders.commissions[@order_window.index]
 @price += percent * @item.price / 100 if percent > 0
 number = $game_party.item_number(@item)
 shop_max = KyoShop.current_item_max
 if @item == nil or @price > $game_party.gold or number == shop_max
 Sound.play_buzzer
 return
 end
 Sound.play_decision
 max = @price == 0 ? shop_max : $game_party.gold / @price
 max = [max, shop_max - number].min
 @order_window.disappear
 @number_window.set(@item, max, @price, percent)
 @number_window.appear
 @last_stage = :place
 @stage = :number
 end
 end
 
 def update_pickup_order
 @pickup_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @status_window.disappear
 @pickup_window.disappear
 @extras_window.appear
 @dummy_window.visible = true
 @question_window.visible = false
 return @stage = :option
 elsif Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @status_window.item = @pickup_window.item
 return
 elsif Input.trigger?(Input::C)
 unless (goods = $game_system.placed_orders[@pack_id])
 return Sound.play_buzzer
 end
 current_item = @pickup_window.item
 goods = goods[@pickup_window.index]
 unless current_item and goods[3] <= $game_party.steps
 return Sound.play_buzzer
 end
 Sound.play_decision
 number = goods[2]
 $game_party.gain_item(current_item, number)
 $game_system.placed_orders[@pack_id].delete_at(@pickup_window.index)
 @pickup_window.reload_goods($game_system.placed_orders[@pack_id])
 @last_stage = :pickup
 @stage = :number
 end
 end
 
 def update_discount
 @discount_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @discount_window.disappear
 @buy_window.appear
 return @stage = :purchase
 elsif Input.trigger?(Input::C)
 Sound.play_decision
 @coupons_allowed = KyoShop::COUPON_IDS.include?(@discount_window.item.id)
 @buy_window.discount = -@discount_window.item.price
 @buy_window.refresh
 @discount_window.disappear
 @buy_window.appear
 update_discount_message
 @stage = :purchase
 end
 end
 
 def update_appraisal
 @appraise_item_window.update
 if Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @appraise_info_window.refresh
 return
 end
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @appraise_item_window.disappear
 @appraise_info_window.visible = false
 @question_window.visible = false
 @result_info_window.visible = false
 @result_info_window.contents.clear
 @appraise_options.disappear
 @dummy_window.visible = true
 @command_window.visible = true
 @extras_window.appear
 @help_window.set_text("")
 return @stage = :option
 elsif Input.trigger?(Input::C)
 return Sound.play_buzzer if @appraise_item_window.empty?
 Sound.play_decision
 @appraise_options.appear
 @stage = :appraise_option
 end
 end
 
 def update_appraisal_option
 @appraise_options.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @appraise_options.disappear
 return @stage = :appraise
 elsif Input.trigger?(Input::C)
 data = KyoShop::APPRAISALS[@shop_id]
 price = case @appraise_options.index
 when 0 then data[:test_cost]
 when 1 then data[:cost]
 when 2 then -10
 end
 if price == -10 or $game_party.gold < price
 Sound.play_buzzer
 @appraise_options.disappear
 return @stage = :appraise
 end
 Sound.play_decision
 item = @appraise_item_window.item
 $game_party.lose_gold(price)
 if rand(100) < data[:rate]
 goods = data[:goods]
 favors = $game_system.shop_favors[@shop_id]
 goods += data[:extras] if data[:help_limit] <= favors
 key = goods[rand(goods.size)]
 else
 key = data[:default]
 end
 kind, id = retrieve_item(key)
 case item.class
 when RPG::Item then $game_party.lose_item(item.id, 1)
 when RPG::Weapon then $game_party.lose_weapon(item.id, 1)
 when RPG::Armor then $game_party.lose_armor(item.id, 1)
 end
 if data[:target].has_key?(key)
 @appraise_options.disappear
 @favor_options.appear
 @result_info_window.ask_favor(new_item)
 @target_item = new_item
 @target_key = key
 @target_points = data[:target][key]
 @haggle_enabled = data[:haggle]
 @haggle_max = data[:overprice]
 return @stage = :appraise_favor
 end
 case kind
 when 0
 new_item = $data_items[id]
 $game_party.gain_item(id, 1)
 when 1
 new_item = $data_weapons[id]
 $game_party.gain_weapon(id, 1)
 when 2
 new_item = $data_armors[id]
 $game_party.gain_armor(id, 1)
 end
 @result_info_window.refresh(new_item)
 @appraise_item_window.refresh
 @gold_window.refresh
 @appraise_options.disappear
 @stage = :appraise
 end
 end
 
 def update_appraisal_favor
 @favor_options.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @favor_options.disappear
 return @stage = :appraise
 elsif Input.trigger?(Input::C)
 case @favor_options.index
 when 0
 if @overprice
 Sound.play_shop
 $game_system.shop_favors[@shop_id] += @target_points
 price = @overprice
 @target_points = nil
 else
 Sound.play_decision
 price = @target_item.price
 end
 $game_party.gain_gold(price)
 @overprice = @target_item = nil
 when 1
 return Sound.se_play($data_system.buzzer_se) unless @haggle_enabled
 Sound.play_decision
 @haggle_enabled = nil
 @overprice = rand(@haggle_max) + 1
 @overprice = 25 if @overprice < 25
 @overprice += @target_item.price
 @result_info_window.make_offer(@overprice)
 return
 when 2
 Sound.play_decision
 case @target_item.class
 when RPG::Item then $game_party.gain_item(@target_item.id, 1)
 when RPG::Weapon then $game_party.gain_weapon(@target_item.id, 1)
 when RPG::Armor then $game_party.gain_armor(@target_item.id, 1)
 end
 @target_item = nil
 @favor_options.disappear
 end
 return @stage = :appraise
 end
 end
 
 def update_sell
 @sell_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @command_window.active = true
 @dummy_window.visible = true
 @sell_window.disappear
 @status_window.item = nil
 @help_window.set_text("")
 return @stage = :main
 elsif Input.trigger?(Input::C)
 @item = @sell_window.item
 @status_window.item = @item
 if @item == nil or @item.price == 0
 return Sound.play_buzzer
 end
 Sound.play_decision
 max = $game_party.item_number(@item)
 @sell_window.disappear
 @number_window.set(@item, max, @item.price / 2)
 @number_window.appear
 @status_window.visible = true
 @stage = :number
 end
 end
 
 def update_number
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @number_window.disappear
 if @extras_window.index == 1
 @order_window.appear
 return @stage = :place
 elsif @extras_window.index == 4
 return update_cancel_investment
 end
 case @command_window.index
 when 0
 @buy_window.appear
 return @stage = :purchase
 when 1  # Sell
 @sell_window.appear
 @status_window.visible = false
 return @stage = :sell
 end
 elsif Input.trigger?(Input::C)
 decide_number_input
 end
 end
 
 def decide_number_input
 Sound.play_shop
 @number_window.disappear
 case @extras_window.index
 when 1
 decide_number_order
 return
 when 4
 decide_number_investment
 return
 end
 case @command_window.index
 when 0  # Buy
 percent = KyoShop.current_price_max
 price = @item.price + @item.price * percent / 100
 price += price * @buy_window.discount / 100
 $game_party.lose_gold(@number_window.number * price)
 $game_party.gain_item(@item, @number_window.number)
 if @coupons_allowed
 @coupons_allowed = nil
 $game_party.lose_item(@discount_window.item, 1)
 @buy_window.discount = 0
 update_discount_message
 @discount_window.refresh
 end
 @gold_window.refresh
 @buy_window.refresh
 @status_window.refresh
 @buy_window.appear
 return @stage = :purchase
 when 1  # sell
 $game_party.gain_gold(@number_window.number * (@item.price / 2))
 $game_party.lose_item(@item, @number_window.number)
 @gold_window.refresh
 @sell_window.refresh
 @status_window.refresh
 @sell_window.appear
 @status_window.visible = false
 @stage = :sell
 end
 end
 
 def decide_number_order
 percent = KyoShopOrders.commissions[@order_window.index]
 percent += KyoShop.current_price_max
 price = @item.price + @item.price * percent / 100
 $game_party.lose_gold(@number_window.number * price)
 steps = $game_party.steps + KyoShopOrders.steps[@order_window.index]
 order = [nil, @item.id, @number_window.number, steps]
 order[0] = case @item
 when RPG::Item then 0
 when RPG::Weapon then 1
 when RPG::Armor then 2
 end
 unless $game_system.placed_orders[@pack_id]
 @no_orders = nil
 @extras_window.draw_item(2, true)
 end
 $game_system.placed_orders[@pack_id] << order
 @pickup_window.reload_goods($game_system.placed_orders[@pack_id])
 @status_window.refresh
 @gold_window.refresh
 @order_window.refresh
 @order_window.appear
 @stage = :place
 end
 
 def decide_number_investment
 $game_system.shop_shares[@shop_id] += @number_window.number
 update_goods_orders_after_investment
 @order_window.deliver(KyoShopOrders.goods)
 @buy_window.deliver($game_temp.shop_goods)
 @gold_window.refresh
 update_cancel_investment
 end
 
 def update_cancel_investment
 @investment = nil
 @status_window.investment = nil
 @status_window.visible = false
 @question_window.visible = false
 @dummy_window.visible = true
 @number_window.reset_multiplier
 @number_window.disappear
 @extras_window.appear
 @stage = :option
 end
 end
 
 RE: KyoDiscounts XP VX, ACE MV - kyonides -  01-17-2019
 
 Here is an updated version of KyoDiscounts VX! I have the need to fix some issues regarding gaining items, weapons and armors, plus simplify a few things here and there...
  
 
 Code: # * KyoDiscounts VX#   Scripter : Kyonides-Arkanthos
 #   v1.5.0 - 2019-01-17
 
 #   Besides the player can also place orders to get an item that is supposed to
 #   be found at another store only. The player will be charged an extra fee, but
 #   he or she won't need to go back to another store. The player would only need
 #   to keep walking for a while before the goods are available at the store.
 #   Now the required steps for each placed order will be automatically increased
 #   between 0% and 50%, making it look a bit random but also kind of realistic.
 
 # * Unknown Item or Weapon or Armor Appraisals *
 
 #   Use the Game Variable defined in the STORECODEVARID Constant to store the
 #   Shop ID that will include the appraisal service.
 #   Use the MYSTERIOUS series of Arrays to include as many IDs of unknown items
 #   or weapons or armors that will serve as fillers till they get replaced by
 #   the actual goods they represent.
 #   Follow the Instructions included in the APPRAISALS Hash to define all
 #   conditions that will affect an appraiser's task of identifying the item.
 
 #   Script Calls   #
 
 #   $game_party.discount_cards_expire
 #      Makes all Discount Cards expire as part of the game's plot.
 
 #   $game_party.disc_card_expire(Card_ID)
 #      Makes an specific Discount Card expire as part of the game's plot.
 
 #   KyoShopOrders << [Percent1, Percent2, etc.]
 #      Defines a Commission percent for every Item in the Place Order List.
 
 #   KyoShopOrders.steps = [Steps1, Steps2, etc.]
 #   KyoShopOrders.steps += [Steps5, Steps6, etc.]
 #      Defines Steps required by every Order in the Place Order List.
 #      The 2nd call will be required only if you couldn't include all steps.
 
 #   KyoShop.scarcity_lvl = 0 or higher
 #     Define all prices and maximum number of units per shop item.
 #     0 means no scarcity, 1 or higher reflects how severe it is.
 #     You also have to configure the @scarce_limits hash in order to predefine
 #     :price and :max per scarcity level. The maximum scarcity level depends on
 #     how many values you entered in both :price and :max arrays.
 #     In few words, you define the maximum scarcity level ever possible!
 
 module KyoShop
 # Maximum number of units for each shop item
 NUMBERMAX = 99
 # Button that will open the Discount window while on the shop menu
 DISCOUNTBUTTON = Input::A
 # Add Discount Card Object IDs
 DISCOUNT_IDS = [21, 22, 23]
 # Add Discount Coupon Object IDs
 COUPON_IDS = [24, 25, 26]
 # Maximum Steps before Discount Card expires : ID => Steps
 STEPS = { 21 => 500, 22 => 300, 23 => 150 }
 # Exclusive Stores In Game Variable ID
 STORECODEVARID = 1
 # Exclusive Stores List : Object ID => Exclusive Store Code
 EXCLUSIVESTORES = { 35 => 102 }
 # Switch ID : deactivates Store to add Goods found elsewhere
 GOODSSWITCHID = 1
 # Store IDs for stores where you have invested some gold
 INVESTSTOREIDS = [101]
 # Maximum Number of Shares & Share Price
 SHARESMAXMIN = [10000, 100]
 INVESTMENTS = {} # Store Investments - Do Not Edit This Line
 INVESTMENTS.default = {} # Do Not Edit This Line
 # Available Improvements #
 # :discount : [:discount, 25]
 # :goods    : [:goods, 'i10', 'w4', 'a6']
 # :orders   : [:orders, 'i11', 'w5', 'a7']
 # [Store ID] = { Shares => Prize, Shares => Another Prize, etc. }
 INVESTMENTS[101] = { 50 => [:goods,'i10','w5','a6'], 100 => [:discount,10] }
 APPRAISALS = {} # Do Not Edit This Line!
 # [Store ID] = { appraisal cost => $, estimate cost => $, success rate => %,
 # times you can help the a. => 0, bad result => "i1", goods => [item4, etc.] }
 APPRAISALS[101] = { :cost => 150, :test_cost => 75, :rate => 10,
 :default => 'i1', :help_limit => 5, :haggle => true,
 :target => { 'i9' => 1, 'i10' => 2 },
 :goods => ['i2','i3','i9','i10'], :extras => ['i11'] }
 # Add Item IDs for unknown shop goods that need to be appraised by experts
 MYSTERIOUSITEMS = []
 # Add Weapon IDs for unknown shop goods that need to be appraised by experts
 MYSTERIOUSWEAPONS = []
 # Add Armor IDs for unknown shop goods that need to be appraised by experts
 MYSTERIOUSARMORS = []
 @scarce_limits = {
 :price  => [0, 25, 50, 100, 250, 350, 500, 650, 800],
 :max => [NUMBERMAX, NUMBERMAX - 10, NUMBERMAX - 25, NUMBERMAX - 35,
 NUMBERMAX - 50, NUMBERMAX - 65, NUMBERMAX - 80, NUMBERMAX - 90, 1]
 #:item => [1, 2, 3, 4, 5, 6],
 #:weapon => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
 #:armor => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
 }
 @scarce_lvl = 0 # Initial Level
 def self.current_item_max() @scarce_limits[:max][@scarce_lvl] end
 def self.current_price_max() @scarce_limits[:price][@scarce_lvl] end
 def self.scarcity_limits() @scarce_limits end
 def self.scarcity_lvl() @scarce_lvl end
 def self.scarcity_lvl=(lvl) @scarce_lvl = lvl end
 end
 
 
 module KyoShopLabels
 # Buy Stuff & Place Order & Pick Up Items Label
 BUYPLACEPICKUP = ['Buy Items', 'Place Order', 'Pick Up Items', 'Invest']
 # Item Price Data Labels
 PRICEDATA = ['Basic Price', 'Commission', 'Discount', 'Total Price']
 # Place an Order Label
 PLACEORDER = 'Do you wish to place an order?'
 # Pick Up Order Label
 PICKUPORDER = 'Do you want to pick up an order?'
 # No Order Found Label
 NOORDERFOUND = 'There is nothing left, boss!'
 # Available Discounts Label
 SOMEDISCOUNTS = 'Press A to get a discount'
 # No Discount Available Label
 NODISCOUNTS = 'No Discount Available'
 # Select a Discount Card or Coupon Label
 SELECTDISCOUNT = 'Choose a Card or Coupon'
 # Apply Discount Label
 APPLYDISCOUNT = 'Discount Applied'
 # Commission Fees Apply Label
 FEESAPPLY = 'Special Fees Apply'
 # Discount Card's Steps Left Label
 STEPSLEFT = " %s steps left."
 # Investment Label...
 INVESTMENT = 'Want to invest in this store?'
 # Share Number Label
 SHARES = 'Share Number'
 # Adquired or Purchased Shares Label
 TOTALSHARES = 'Total Shares'
 # Need a Discount Label
 NEEDADISCOUNT = 'Need a Discount?'
 # Pick Item to be Appraised Label
 APPRAISALMENULABEL = "Appraisal Menu"
 # Appraisal Window Labels
 APPRAISALLABELS = ["Quick Test Cost", "Normal Cost"]
 # Appraisal Options Labels
 APPRAISALOPTIONS = ["Quick Test", "Detailed Test", "Cancel"]
 # Purchase Offer and Haggle Labels
 APPRAISALHAGGLEOPTIONS = ["Accept", "Haggle", "Decline"]
 # Appraisal End Result Labels
 APPRAISALRESULTLABELS = [
 "The item at hand is nothing else but... %s",
 "I think it might be worth some... %s",
 "I've been searching for some %s!",
 "Now I want to make a deal.",
 "What if I make a better offer?",
 "Would you accept some %s?"
 ]
 end
 # DO NOT EDIT ANYTHING ELSE #
 module KyoShopOrders
 @goods = []
 @commissions = []
 @steps = []
 class << self
 attr_accessor :store_id, :goods_id, :goods
 attr_reader :steps, :commissions
 def steps=(val) @steps = val.map {|n| n + rand((n / 2) + 2) } end
 def <<(val)
 @commissions += val
 @commissions = @commissions.flatten
 end
 end
 end
 
 class Game_System
 attr_reader :placed_orders, :shop_shares, :shop_favors
 alias kyon_discounts_gm_sys_init initialize
 def initialize
 @placed_orders = {}
 @shop_shares = {}
 @shop_favors = {}
 @placed_orders.default = []
 @shop_shares.default = 0
 @shop_favors.default = 0
 kyon_discounts_gm_sys_init
 end
 
 def disc_store?(disc_id) !KyoShop::EXCLUSIVESTORES[disc_id] end
 
 def excl_disc_store?(disc_id)
 exclusive = KyoShop::EXCLUSIVESTORES[disc_id]
 exclusive == $game_variables[KyoShop::STORECODEVARID]
 end
 
 def check_shares(shop_id)
 results = []
 shares = @shop_shares[shop_id]
 investments = KyoShop::INVESTMENTS[shop_id]
 limits = KyoShop::INVESTMENTS[shop_id].keys.sort
 results = investments.select{|limit| shares >= limit[0] }.map {|r| r[1] }
 end
 end
 
 class Game_Party
 attr_reader :discounts
 alias kyon_discounts_gm_party_init initialize
 alias kyon_discounts_gm_party_gain_item gain_item
 def initialize
 @discounts = {}
 kyon_discounts_gm_party_init
 end
 
 def gain_item(item, n, equip=false)
 kyon_discounts_gm_party_gain_item(item, n, equip)
 return if item == nil or n == 0
 return unless KyoShop::DISCOUNT_IDS.include?(item.id)
 item_id = item.id
 if @discounts[item_id]
 @discounts[item_id] += KyoShop::STEPS[item_id]
 @items[item_id] = 1
 else
 @discounts[item_id] = KyoShop::STEPS[item_id]
 end
 end
 
 def check_discounts
 unless @discounts.empty?
 for did in KyoShop::DISCOUNT_IDS
 next unless @discounts[did] and @discounts[did] > 0
 return true if $game_system.disc_store?(did)
 return true if $game_system.excl_disc_store?(did)
 end
 end
 for cid in KyoShop::COUPON_IDS
 next unless @items[cid] and @items[cid] > 0
 return true if $game_system.disc_store?(cid)
 return true if $game_system.excl_disc_store?(cid)
 end
 return false
 end
 
 def decrease_discounts
 KyoShop::DISCOUNT_IDS.each {|n| next unless @discounts[n]
 @discounts[n] -= 1 if @discounts[n] > 0 }
 end
 
 def discount_cards_expire
 KyoShop::DISCOUNT_IDS.each {|n| @discounts[n] = 0 if @discounts[n] }
 end
 
 def disc_card_expire(dc_id) @discounts[dc_id] = 0 end
 def item_include?(item_id) @items[item_id] and @items[item_id] > 0 end
 end
 
 class Game_Player
 alias kyon_discounts_coupons_gm_player_increase_steps increase_steps
 def increase_steps
 kyon_discounts_coupons_gm_player_increase_steps
 $game_party.decrease_discounts
 end
 end
 
 class Game_Interpreter
 alias kyon_discounts_game_inter_comm_302 command_302
 def command_302
 if $game_switches[KyoShop::GOODSSWITCHID]
 KyoShopOrders.store_id = @event_id
 $game_switches[KyoShop::GOODSSWITCHID] = false
 KyoShopOrders.goods = [@params[0,2]]
 loop do
 @index += 1
 if @list[@index].code == 605
 KyoShopOrders.goods << @list[@index].parameters
 else
 return false
 end
 end
 end
 kyon_discounts_game_inter_comm_302
 end
 end
 
 class Window_Base
 def appear
 self.active = true
 self.visible = true
 end
 
 def disappear
 self.active = false
 self.visible = false
 end
 
 def draw_currency_value(value, x, y, width)
 c = self.contents
 cx = c.text_size(Vocab::gold).width
 c.font.color = normal_color
 c.draw_text(x - 8, y, width-cx-2, WLH, value, 2)
 c.font.color = system_color
 c.draw_text(x, y, width, WLH, Vocab::gold, 2)
 end
 end
 
 class Window_KyoShopHelp < Window_Help
 def set_text(text, align=0)
 if KyoShop::DISCOUNT_IDS.include?(KyoShopOrders.goods_id)
 steps = $game_party.discounts[KyoShopOrders.goods_id].to_s
 text = sprintf(KyoShopLabels::STEPSLEFT, steps)
 KyoShopOrders.goods_id = nil
 end
 super(text, align)
 end
 end
 
 class Window_Item
 alias kyon_discounts_win_item_up_help update_help
 def update_help
 KyoShopOrders.goods_id = self.item.id
 kyon_discounts_win_item_up_help
 end
 end
 
 class AppraiseItemWindow < Window_Selectable
 def initialize
 super(0, 56, 544-160, 280)
 @column_max = 1
 refresh
 self.index = 0
 end
 
 def refresh
 self.contents.clear
 @data = []
 for n in KyoShop::MYSTERIOUSITEMS
 next if $game_party.item_number(n) == 0
 @data << $data_items[n]
 end
 for i in KyoShop::MYSTERIOUSWEAPONS
 next if $game_party.weapon_number(i) == 0
 @data << $data_weapons[i]
 end
 for i in KyoShop::MYSTERIOUSARMORS
 next if $game_party.armor_number(i) == 0
 @data << $data_armors[i]
 end
 @item_max = @data.size
 return if @item_max == 0
 self.contents = Bitmap.new(width - 32, row_max * 32)
 @item_max.times{|i| draw_item(i) }
 end
 
 def draw_item(index)
 item = @data[index]
 number = case item
 when RPG::Item then $game_party.item_number(item.id)
 when RPG::Weapon then $game_party.weapon_number(item.id)
 when RPG::Armor then $game_party.armor_number(item.id)
 end
 c = self.contents
 x = 4 + index % 2 * (288 + 32)
 y = index / 2 * 32
 rect = Rect.new(x, y, self.width / @column_max - 32, 32)
 c.fill_rect(rect, Color.new(0, 0, 0, 0))
 bit = RPG::Cache.icon(item.icon_name)
 c.blt(x, y + 4, bit, Rect.new(0, 0, 24, 24), 255)
 c.draw_text(x + 28, y, 212, 32, item.name, 0)
 c.draw_text(x + 240, y, 16, 32, ":", 1)
 c.draw_text(x + 256, y, 24, 32, number.to_s, 2)
 end
 def item() @data[@index] end
 def empty?() @data.empty? end
 end
 
 class AppraiseInfoWindow < Window_Base
 def initialize(store_id)
 super(384, 112, 160, 224)
 @data = KyoShop::APPRAISALS[store_id]
 @labels = KyoShopLabels::APPRAISALLABELS.dup
 @currency = Vocab.gold
 self.contents = Bitmap.new(width - 32, height - 32)
 refresh
 end
 
 def refresh
 aw = width - 32
 contents.clear
 contents.font.color = system_color
 contents.draw_text(0, 0, aw, 24, @labels[0])
 contents.draw_text(0, 48, aw, 24, @labels[1])
 contents.draw_text(0, 24, aw, 24, @currency, 2)
 contents.draw_text(0, 72, aw, 24, @currency, 2)
 contents.font.color = normal_color
 contents.draw_text(0, 24, width - 48, 24, @data[:test_cost].to_s, 2)
 contents.draw_text(0, 72, width - 48, 24, @data[:cost].to_s, 2)
 end
 end
 
 class AppraiseResultWindow < Window_Base
 def initialize
 super(0, 334, 544, 84)
 @labels = KyoShopLabels::APPRAISALRESULTLABELS.dup
 @currency = Vocab.gold #draw_currency_value(value, x, y, width)
 self.contents = Bitmap.new(width - 32, height - 32)
 end
 
 def refresh(item)
 contents.clear
 result = sprintf(@labels[0], item.name)
 cost = sprintf(@labels[1], item.price) + " " + @currency
 contents.draw_text(0, 0, width - 32, 24, result)
 contents.draw_text(0, 24, width - 32, 24, cost)
 end
 
 def ask_favor(item)
 contents.clear
 result = sprintf(@labels[2], item.name)
 contents.draw_text(0, 0, width - 32, 24, result)
 contents.draw_text(0, 24, width - 32, 24, @labels[3])
 end
 
 def make_offer(overprice)
 contents.clear
 result = sprintf(@labels[5], overprice) + " " + @currency
 contents.draw_text(0, 0, width - 32, 24, @labels[4])
 contents.draw_text(0, 24, width - 32, 24, result)
 end
 end
 
 class Window_ShopBuyPlace < Window_Selectable
 attr_accessor :discount
 attr_reader :discounts
 def initialize(shop_goods, discounts=[])
 super(0, 112, 304, 248)
 @shop_goods = shop_goods
 @discount = 0
 @discounts = discounts
 refresh
 self.index = 0
 end
 
 def deliver(goods)
 @shop_goods = goods
 if goods.size - 1 < @index
 @index = goods.size > 0 ? (@index + goods.size - 1) % goods.size : 0
 update_cursor_rect
 end
 refresh
 self.index = 0
 end
 
 def item() @data[self.index] end
 
 def refresh
 @data = []
 for goods_item in @shop_goods
 item = case goods_item[0]
 when 0 then $data_items[goods_item[1]]
 when 1 then $data_weapons[goods_item[1]]
 when 2 then $data_armors[goods_item[1]]
 end
 @data << item if item
 end
 @item_max = @data.size
 create_contents
 @item_max.times {|i| draw_item(i) }
 end
 
 def draw_item(index)
 item = @data[index]
 number = $game_party.item_number(item)
 enabled = (item.price <= $game_party.gold and number < 99)
 rect = item_rect(index)
 self.contents.clear_rect(rect)
 draw_item_name(item, rect.x, rect.y, enabled)
 rect.width -= 4
 fee = @discounts.empty? ? @discount : @discounts[index]
 fee = item.price * fee / 100
 self.contents.draw_text(rect, item.price + fee, 2)
 end
 
 def update_help
 @help_window.set_text(item == nil ? "" : item.description)
 end
 end
 
 class Window_ShopNumber
 def initialize(x, y)
 super(x, y, 304, 248)
 @item = nil
 @max = 1
 @price = 0
 @number = 1
 @percent = 0
 @multiplier = 1
 end
 
 def reset_multiplier
 @multiplier = 1
 @number = 1
 refresh
 end
 
 def set(item, max, price, percent=0, multiplier=1)
 @item = item
 @max = max
 @price = price
 @number = 1
 @multiplier = multiplier
 @percent = percent
 refresh
 end
 
 def refresh
 self.contents.clear
 draw_item_name(@item, 0, 96)
 self.contents.font.color = normal_color
 if @multiplier == 1
 cx1, cx2, cx3, cw1, cw2 = [212, 240, 244, 28, 28]
 else
 cx1, cx2, cx3, cw1, cw2 = [196, 202, 212, 68, 64]
 end
 self.contents.draw_text(cx1, 96, 20, WLH, "")
 self.contents.draw_text(cx2, 96, cw1, WLH, @number, 2)
 self.cursor_rect.set(cx3, 96, cw2, WLH)
 if @percent == 0 or @multiplier > 1
 draw_currency_value(@price * @number, 4, 96 + WLH * 2, 264)
 return
 end
 draw_currency_value(@item.price * @number, 4, 72 + WLH * 2, 264)
 draw_percent_value(@percent, 4, 96 + WLH * 2, 264)
 end_price = @item.price + @item.price * @percent / 100
 draw_currency_value(end_price * @number, 4, 120 + WLH * 2, 264)
 draw_price_labels(x - 20, 120, 160)
 end
 
 def draw_percent_value(value, x, y, width)
 cx = contents.text_size(Vocab::gold).width
 self.contents.font.color = normal_color
 self.contents.draw_text(x - 8, y, width-cx-2, WLH, value, 2)
 text = KyoShopLabels::PRICEDATA[@percent < 0 ? 2 : 1]
 self.contents.draw_text(x + 40, y, width, WLH, text)
 self.contents.font.color = system_color
 self.contents.draw_text(x, y, width, WLH, '%', 2)
 end
 
 def draw_price_labels(x, y, w)
 self.contents.font.color = normal_color
 self.contents.draw_text(x, y, w, WLH, KyoShopLabels::PRICEDATA[0], 2)
 self.contents.draw_text(x, y + 48, w, WLH, KyoShopLabels::PRICEDATA[3], 2)
 end
 end
 
 class Window_ShopPickUp < Window_ShopBuyPlace
 def draw_item(index)
 item = @data[index]
 qty, steps = @shop_goods[index][2..3]
 number = $game_party.item_number(item)
 enough = (number + qty < 100 and steps <= $game_party.steps)
 self.contents.font.color.alpha = enough ? 255 : 128
 y = index * 24
 draw_icon(item.icon_index, 0, y, enough)
 self.contents.draw_text(32, y - 4, 212, 32, item.name, 0)
 self.contents.draw_text(180, y - 4, 88, 32, qty.to_s, 2)
 end
 end
 
 class Window_ShopDiscountAlert < Window_Base
 def initialize
 super(0, 360, 304, 56)
 self.contents = Bitmap.new(width - 32, height - 32)
 end
 
 def set_text(text)
 self.contents.clear
 self.contents.draw_text(0, 0, 272, 24, text)
 end
 end
 
 class Window_ShopDiscountCoupon < Window_Selectable
 def initialize
 super(0, 112, 304, 248)
 self.index = 0
 refresh
 end
 
 def item() @data[self.index] end
 
 def refresh
 @data = []
 gs = $game_system
 dc_ids = $game_party.discounts.keys.sort
 dc_ids.each {|i| next if $game_party.discounts[i] == 0
 next unless gs.disc_store?(i) or gs.excl_disc_store?(i)
 @data << $data_items[i] }
 KyoShop::COUPON_IDS.each {|i| next unless $game_party.item_include?(i)
 @data << $data_items[i] }
 @item_max = @data.size
 self.index -= 1 if @index > @item_max - 1
 create_contents
 @item_max.times {|i| draw_item(i) }
 end
 
 def draw_item(index)
 item = @data[index]
 number = $game_party.item_number(item)
 y = index * 24
 rect = Rect.new(4, y, self.width - 32, 32)
 self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
 enabled = $game_party.item_can_use?(item)
 draw_item_name(item, rect.x, rect.y, enabled)
 self.contents.draw_text(32, y, 236, 24, ': ' + number.to_s, 2)
 end
 
 def update_help
 KyoShopOrders.goods_id = self.item.id
 @help_window.set_text(self.item.description)
 end
 end
 
 class Window_ShopStatus
 alias kyon_discounts_win_shop_status_refresh refresh
 def investment=(bool)
 @investment = bool
 refresh
 end
 
 def refresh
 if @investment
 refresh_investment
 return
 end
 kyon_discounts_win_shop_status_refresh
 end
 
 def refresh_investment
 self.contents.clear
 shares = $game_system.shop_shares[$game_variables[KyoShop::STORECODEVARID]]
 contents.font.color = system_color
 contents.draw_text(0, 0, 200, 32, KyoShopLabels::TOTALSHARES)
 contents.font.color = normal_color
 contents.draw_text(0, 0, 208, 32, shares.to_s, 2)
 end
 end
 
 class Scene_Shop
 def start
 @stage = :main
 @shop_id = $game_variables[KyoShop::STORECODEVARID]
 @goods = $game_temp.shop_goods.dup
 @orders = KyoShopOrders.goods.dup
 update_goods_orders_after_investment
 create_menu_background
 create_command_window
 make_basic_data_windows
 make_shop_windows
 make_discount_order_pickup_windows
 make_appraisal_windows
 end
 
 def make_basic_data_windows
 @help_window = Window_Help.new
 @gold_window = Window_Gold.new(384, 56)
 @dummy_window = Window_Base.new(0, 112, 544, 304)
 @status_window = Window_ShopStatus.new(304, 112)
 @status_window.visible = false
 end
 
 def make_shop_windows
 @buy_window = Window_ShopBuyPlace.new($game_temp.shop_goods)
 @buy_window.disappear
 @buy_window.help_window = @help_window
 @sell_window = Window_ShopSell.new(0, 112, 544, 304)
 @sell_window.disappear
 @sell_window.help_window = @help_window
 @number_window = Window_ShopNumber.new(0, 112)
 @number_window.disappear
 end
 
 def make_discount_order_pickup_windows
 @question_window = Window_ShopDiscountAlert.new
 @question_window.visible = false
 @discount_window = Window_ShopDiscountCoupon.new
 @discount_window.disappear
 @discount_window.help_window = @help_window
 commands = KyoShopLabels::BUYPLACEPICKUP.dup
 commands.pop unless KyoShop::INVESTSTOREIDS.include?(@shop_id)
 @extras_window = Window_Command.new(200, commands)
 @extras_window.x = (544 - 200) / 2
 @extras_window.y = 112
 @extras_window.disappear
 unless KyoShopOrders.goods.empty?
 goods = KyoShopOrders.goods
 @order_window = Window_ShopBuyPlace.new(goods, KyoShopOrders.commissions)
 @order_window.disappear
 @order_window.help_window = @help_window
 end
 @pack_id = [$game_map.map_id, KyoShopOrders.store_id]
 goods = $game_system.placed_orders[@pack_id]
 unless goods
 goods = []
 @no_orders = true
 @extras_window.draw_item(2, nil)
 end
 @pickup_window = Window_ShopPickUp.new(goods)
 @pickup_window.disappear
 @pickup_window.help_window = @help_window
 end
 
 def make_appraisal_windows
 if (@need_appraisal = KyoShop::APPRAISALS.keys.include?(@shop_id))
 @appraise_item_window = AppraiseItemWindow.new
 @appraise_item_window.visible = false
 @appraise_info_window = AppraiseInfoWindow.new(@shop_id)
 @appraise_info_window.visible = false
 options = KyoShopLabels::APPRAISALOPTIONS.dup
 @appraise_options = Window_Command.new(160, options)
 @appraise_options.disappear
 @appraise_options.x = 240
 @appraise_options.y = 200
 @result_info_window = AppraiseResultWindow.new
 @result_info_window.visible = false
 options = KyoShopLabels::APPRAISALHAGGLEOPTIONS.dup
 @favor_options = Window_Command.new(160, options)
 @favor_options.disappear
 @favor_options.x = 240
 @favor_options.y = 200
 else
 @extras_window.draw_item(3, nil)
 end
 end
 
 def update_goods_orders_after_investment
 gds = []
 orders = []
 stuff = $game_system.check_shares(@shop_id)
 return if stuff.empty?
 stuff.each {|b| gds += strings_goods_conversion(b[1..-1]) if b[0] == :goods
 orders += string_good_conversion(b[1..-1]) if b[0] == :orders }
 KyoShopOrders.goods = (@orders + orders).sort.uniq
 $game_temp.shop_goods = (@goods + gds).sort.uniq
 end
 
 def strings_goods_conversion(strings)
 data = []
 strings.each {|string| data << retrieve_item(string) }
 data
 end
 
 def retrieve_item(string)
 case string[0,1]
 when 'i' then [0, string[1..-1].to_i]
 when 'w' then [1, string[1..-1].to_i]
 when 'a' then [2, string[1..-1].to_i]
 end
 end
 
 def update_discount_message
 if @buy_window.discount < 0
 text = sprintf(KyoShopLabels::APPLYDISCOUNT, @discount_window.item.price)
 else
 cd = $game_party.check_discounts
 text = cd ? KyoShopLabels::SOMEDISCOUNTS : KyoShopLabels::NODISCOUNTS
 end
 @question_window.set_text(text)
 end
 
 def terminate
 dispose_menu_background
 dispose_command_window
 @discount_window.dispose
 @extras_window.dispose
 @order_window.dispose
 @pickup_window.dispose
 @question_window.dispose
 @help_window.dispose
 @gold_window.dispose
 @dummy_window.dispose
 @buy_window.dispose
 @sell_window.dispose
 @number_window.dispose
 @status_window.dispose
 if @need_appraisal
 @appraise_item_window.dispose
 @appraise_info_window.dispose
 @appraise_options.dispose
 @result_info_window.dispose
 @favor_options.dispose
 end
 KyoShopOrders.goods.clear
 KyoShopOrders.steps.clear
 KyoShopOrders.commissions.clear
 KyoShopOrders.store_id = 0
 @stage = @shop_id = nil
 end
 
 def update
 super
 update_menu_background
 @help_window.update
 @gold_window.update
 @number_window.update
 @status_window.update
 case @stage
 when :main then update_command
 when :option then update_extras
 when :purchase then update_purchase
 when :place then update_place_order
 when :pickup then update_pickup_order
 when :discount then update_discount
 when :appraise then update_appraisal
 when :appraise_option then update_appraisal_option
 when :appraise_favor then update_appraisal_favor
 when :sell then update_sell
 when :number then update_number
 end
 end
 
 def update_command
 @command_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 $scene = Scene_Map.new
 return
 elsif Input.trigger?(Input::C)
 case @command_window.index
 when 0  # buy
 Sound.play_decision
 @command_window.active = false
 @extras_window.appear
 @question_window.visible = true
 update_discount_message
 return @stage = :option
 when 1  # sell
 return Sound.play_buzzer if $game_temp.shop_purchase_only
 Sound.play_decision
 @command_window.active = false
 @dummy_window.visible = false
 @sell_window.appear
 @sell_window.refresh
 return @stage = :sell
 when 2  # Quit
 Sound.play_decision
 $scene = Scene_Map.new
 end
 end
 end
 
 def update_extras
 @extras_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @extras_window.disappear
 @question_window.visible = false
 @command_window.active = true
 return @stage = :main
 elsif Input.trigger?(Input::C)
 if @no_orders and @extras_window.index == 2
 return Sound.play_buzzer
 end
 shares = $game_system.shop_shares[@shop_id]
 inv_max, inv_price = KyoShop::SHARESMAXMIN
 if @extras_window.index == 4 and inv_max == shares
 return Sound.play_buzzer
 end
 Sound.play_decision
 @extras_window.disappear
 @dummy_window.visible = false
 @status_window.visible = true
 @question_window.visible = @extras_window.index != 3
 update_discount_message
 case @extras_window.index
 when 0 # purchase
 @status_window.item = @buy_window.item
 @buy_window.appear
 @buy_window.refresh
 @last_stage = :option
 return @stage = :purchase
 when 1 # place order
 @status_window.item = @order_window.item
 @order_window.appear
 @question_window.set_text(KyoShopLabels::FEESAPPLY)
 return @stage = :place
 when 2 # pick up order
 @status_window.item = @pickup_window.item
 @pickup_window.appear
 return @stage = :pickup
 when 3 # appraisals
 @appraise_item_window.appear
 @appraise_info_window.visible = true
 @result_info_window.visible = true
 @dummy_window.visible = false
 @command_window.visible = false
 @number_window.visible = false
 @status_window.visible = false
 @help_window.set_text(KyoShopLabels::APPRAISALMENULABEL)
 return @stage = :appraise
 when 4 # investments
 @status_window.investment = @investment = true
 inv_max = [inv_max - shares, $game_party.gold / inv_price].min
 fake_item = RPG::Item.new
 fake_item.name = KyoShopLabels::SHARES
 @price = inv_price
 @number_window.set(fake_item, inv_max, inv_price, 0, 10)
 @number_window.appear
 @question_window.set_text(KyoShopLabels::INVESTMENT)
 @stage = :number
 end
 end
 end
 
 def update_purchase
 @buy_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @buy_window.disappear
 @status_window.visible = false
 @question_window.visible = false
 @dummy_window.visible = true
 @extras_window.appear
 @status_window.item = nil
 @help_window.set_text("")
 return @stage = :option
 elsif Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @status_window.item = @buy_window.item
 return
 elsif Input.trigger?(KyoShop::DISCOUNTBUTTON)
 unless $game_party.check_discounts
 return Sound.play_buzzer
 end
 Sound.play_decision
 @buy_window.disappear
 @discount_window.refresh
 @discount_window.appear
 @question_window.set_text(KyoShopLabels::SELECTDISCOUNT)
 return @stage = :discount
 elsif Input.trigger?(Input::C)
 @item = @buy_window.item
 number = $game_party.item_number(@item)
 shop_max = KyoShop.current_item_max
 if @item == nil or @item.price > $game_party.gold or number == shop_max
 return Sound.play_buzzer
 end
 Sound.play_decision
 max = @item.price == 0 ? shop_max : $game_party.gold / @item.price
 max = [max, shop_max - number].min
 @buy_window.disappear
 discount = @buy_window.discount < 0 ? @buy_window.discount : 0
 @number_window.set(@item, max, @item.price, discount)
 @number_window.appear
 @last_stage = :purchase
 @stage = :number
 end
 end
 
 def update_place_order
 @order_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @status_window.disappear
 @order_window.disappear
 @extras_window.appear
 @dummy_window.visible = true
 @question_window.visible = false
 return @stage = :option
 elsif Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @status_window.item = @order_window.item
 return
 elsif Input.trigger?(Input::C)
 @item = @order_window.item
 @price = @item.price
 percent = KyoShopOrders.commissions[@order_window.index]
 @price += percent * @item.price / 100 if percent > 0
 number = $game_party.item_number(@item)
 shop_max = KyoShop.current_item_max
 if @item == nil or @price > $game_party.gold or number == shop_max
 Sound.play_buzzer
 return
 end
 Sound.play_decision
 max = @price == 0 ? shop_max : $game_party.gold / @price
 max = [max, shop_max - number].min
 @order_window.disappear
 @number_window.set(@item, max, @price, percent)
 @number_window.appear
 @last_stage = :place
 @stage = :number
 end
 end
 
 def update_pickup_order
 @pickup_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @status_window.disappear
 @pickup_window.disappear
 @extras_window.appear
 @dummy_window.visible = true
 @question_window.visible = false
 return @stage = :option
 elsif Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @status_window.item = @pickup_window.item
 return
 elsif Input.trigger?(Input::C)
 unless (goods = $game_system.placed_orders[@pack_id])
 return Sound.play_buzzer
 end
 current_item = @pickup_window.item
 goods = goods[@pickup_window.index]
 unless current_item and goods[3] <= $game_party.steps
 return Sound.play_buzzer
 end
 Sound.play_decision
 number = goods[2]
 $game_party.gain_item(current_item, number)
 $game_system.placed_orders[@pack_id].delete_at(@pickup_window.index)
 @pickup_window.reload_goods($game_system.placed_orders[@pack_id])
 @last_stage = :pickup
 @stage = :number
 end
 end
 
 def update_discount
 @discount_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @discount_window.disappear
 @buy_window.appear
 return @stage = :purchase
 elsif Input.trigger?(Input::C)
 Sound.play_decision
 @coupons_allowed = KyoShop::COUPON_IDS.include?(@discount_window.item.id)
 @buy_window.discount = -@discount_window.item.price
 @buy_window.refresh
 @discount_window.disappear
 @buy_window.appear
 update_discount_message
 @stage = :purchase
 end
 end
 
 def update_appraisal
 @appraise_item_window.update
 if Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)
 @appraise_info_window.refresh
 return
 end
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @appraise_item_window.disappear
 @appraise_info_window.visible = false
 @question_window.visible = false
 @result_info_window.visible = false
 @result_info_window.contents.clear
 @appraise_options.disappear
 @dummy_window.visible = true
 @command_window.visible = true
 @extras_window.appear
 @help_window.set_text("")
 return @stage = :option
 elsif Input.trigger?(Input::C)
 return Sound.play_buzzer if @appraise_item_window.empty?
 Sound.play_decision
 @appraise_options.appear
 @stage = :appraise_option
 end
 end
 
 def update_appraisal_option
 @appraise_options.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @appraise_options.disappear
 return @stage = :appraise
 elsif Input.trigger?(Input::C)
 data = KyoShop::APPRAISALS[@shop_id]
 price = case @appraise_options.index
 when 0 then data[:test_cost]
 when 1 then data[:cost]
 when 2 then -10
 end
 if price == -10 or $game_party.gold < price
 Sound.play_buzzer
 @appraise_options.disappear
 return @stage = :appraise
 end
 Sound.play_decision
 $game_party.lose_gold(price)
 $game_party.lose_item(@appraise_item_window.item, 1)
 if rand(100) < data[:rate]
 goods = data[:goods]
 favors = $game_system.shop_favors[@shop_id]
 goods += data[:extras] if data[:help_limit] <= favors
 key = goods[rand(goods.size)]
 else
 key = data[:default]
 end
 kind, id = retrieve_item(key)
 new_item = case kind
 when 0 then $data_items[id]
 when 1 then $data_weapons[id]
 when 2 then $data_armors[id]
 end
 if data[:target].has_key?(key)
 @appraise_options.disappear
 @favor_options.appear
 @result_info_window.ask_favor(new_item)
 @target_item = new_item
 @target_key = key
 @target_points = data[:target][key]
 @haggle_enabled = data[:haggle]
 @haggle_max = data[:overprice]
 return @stage = :appraise_favor
 end
 $game_party.gain_item(new_item, 1)
 @result_info_window.refresh(new_item)
 @appraise_item_window.refresh
 @gold_window.refresh
 @appraise_options.disappear
 @stage = :appraise
 end
 end
 
 def update_appraisal_favor
 @favor_options.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @favor_options.disappear
 return @stage = :appraise
 elsif Input.trigger?(Input::C)
 case @favor_options.index
 when 0
 if @overprice
 Sound.play_shop
 $game_system.shop_favors[@shop_id] += @target_points
 price = @overprice
 @target_points = nil
 else
 Sound.play_decision
 price = @target_item.price
 end
 $game_party.gain_gold(price)
 @overprice = @target_item = nil
 when 1
 return Sound.play_buzzer unless @haggle_enabled
 Sound.play_decision
 @haggle_enabled = nil
 @overprice = rand(@haggle_max) + 1
 @overprice = 25 if @overprice < 25
 @overprice += @target_item.price
 @result_info_window.make_offer(@overprice)
 return
 when 2
 Sound.play_decision
 case @target_item.class
 when RPG::Item then $game_party.gain_item(@target_item.id, 1)
 when RPG::Weapon then $game_party.gain_weapon(@target_item.id, 1)
 when RPG::Armor then $game_party.gain_armor(@target_item.id, 1)
 end
 @target_item = nil
 @favor_options.disappear
 end
 return @stage = :appraise
 end
 end
 
 def update_sell
 @sell_window.update
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @command_window.active = true
 @dummy_window.visible = true
 @sell_window.disappear
 @status_window.item = nil
 @help_window.set_text("")
 return @stage = :main
 elsif Input.trigger?(Input::C)
 @item = @sell_window.item
 @status_window.item = @item
 if @item == nil or @item.price == 0
 return Sound.play_buzzer
 end
 Sound.play_decision
 max = $game_party.item_number(@item)
 @sell_window.disappear
 @number_window.set(@item, max, @item.price / 2)
 @number_window.appear
 @status_window.visible = true
 @stage = :number
 end
 end
 
 def update_number
 if Input.trigger?(Input::B)
 Sound.play_cancel
 @number_window.disappear
 if @extras_window.index == 1
 @order_window.appear
 return @stage = :place
 elsif @extras_window.index == 4
 return update_cancel_investment
 end
 case @command_window.index
 when 0
 @buy_window.appear
 return @stage = :purchase
 when 1  # Sell
 @sell_window.appear
 @status_window.visible = false
 return @stage = :sell
 end
 elsif Input.trigger?(Input::C)
 decide_number_input
 end
 end
 
 def decide_number_input
 Sound.play_shop
 @number_window.disappear
 case @extras_window.index
 when 1
 decide_number_order
 return
 when 4
 decide_number_investment
 return
 end
 case @command_window.index
 when 0  # Buy
 percent = KyoShop.current_price_max
 price = @item.price + @item.price * percent / 100
 price += price * @buy_window.discount / 100
 $game_party.lose_gold(@number_window.number * price)
 $game_party.gain_item(@item, @number_window.number)
 if @coupons_allowed
 @coupons_allowed = nil
 $game_party.lose_item(@discount_window.item, 1)
 @buy_window.discount = 0
 update_discount_message
 @discount_window.refresh
 end
 @gold_window.refresh
 @buy_window.refresh
 @status_window.refresh
 @buy_window.appear
 return @stage = :purchase
 when 1  # sell
 $game_party.gain_gold(@number_window.number * (@item.price / 2))
 $game_party.lose_item(@item, @number_window.number)
 @gold_window.refresh
 @sell_window.refresh
 @status_window.refresh
 @sell_window.appear
 @status_window.visible = false
 @stage = :sell
 end
 end
 
 def decide_number_order
 percent = KyoShopOrders.commissions[@order_window.index]
 percent += KyoShop.current_price_max
 price = @item.price + @item.price * percent / 100
 $game_party.lose_gold(@number_window.number * price)
 steps = $game_party.steps + KyoShopOrders.steps[@order_window.index]
 order = [nil, @item.id, @number_window.number, steps]
 order[0] = case @item
 when RPG::Item then 0
 when RPG::Weapon then 1
 when RPG::Armor then 2
 end
 unless $game_system.placed_orders[@pack_id]
 @no_orders = nil
 @extras_window.draw_item(2, true)
 end
 $game_system.placed_orders[@pack_id] << order
 @pickup_window.reload_goods($game_system.placed_orders[@pack_id])
 @status_window.refresh
 @gold_window.refresh
 @order_window.refresh
 @order_window.appear
 @stage = :place
 end
 
 def decide_number_investment
 $game_system.shop_shares[@shop_id] += @number_window.number
 update_goods_orders_after_investment
 @order_window.deliver(KyoShopOrders.goods)
 @buy_window.deliver($game_temp.shop_goods)
 @gold_window.refresh
 update_cancel_investment
 end
 
 def update_cancel_investment
 @investment = nil
 @status_window.investment = nil
 @status_window.visible = false
 @question_window.visible = false
 @dummy_window.visible = true
 @number_window.reset_multiplier
 @number_window.disappear
 @extras_window.appear
 @stage = :option
 end
 end
Happy Script Testing!?
   
 
 RE: KyoDiscounts XP VX, ACE MV - kyonides -  01-18-2019
 
 Yeah, bump...
 
 Even if I really hate the fact that I didn't get much feedback lately concerning bugs or missing features, I have uploaded the latest versions of the KyoDiscounts XP, VX and ACE scripts. All of them have reached the 1.5.0 milestone officially!
 
 Of course, there is always some room for bugs...
  but I HOPE I will get some reports if that were the case here.   
 
 RE: KyoDiscounts XP VX, ACE MV - kyonides -  01-27-2019
 
 
 Another bump... hurrah...   I have gladly
  published the latest version of KyoDiscounts XP, even if I have not received any full or partial bug report of the previous one...   
 Since version 1.6.0 you need to place the contents of kyodiscountsxptool.rb in a separate section in the script editor, right above KyoDiscounts XP. It is a temporary script that might be called a parser since it reads the template TXT files, following the shop item list any-number.txt naming convention, used in the creation of the custom price increases and decreases. That tool is not supposed to be distributed with your closed demo or finished game project!
 
 My script would be lucky if anybody tests it any time soon...
   
 
 RE: KyoDiscounts XP VX, ACE MV - kyonides -  01-28-2019
 
 
 A Traveling BUMP! Guess what people? I have traveled in time!
  And I have foreseen the XP version of my script did include a bug, a missing method alias feature to be honest with you.  Once I returned to our timeline, I have managed to fix it, hopefully... You know, I don't have any sonic screwdriver to make anything work as I just expected.   
 
 RE: KyoDiscounts XP VX, ACE MV - kyonides -  01-29-2019
 
 
 A Revamped BUMP But the Appraiser Does Not Know What is a Flux Capacitor! After discussing with Maracuyá, actually getting tired of his suggestions that almost sound like actual demands
  , I have redesigned the Appraisal section of KyoDiscounts XP. It has now reached the 1.6.8 milestone!  
 One of the benefits is that you can now specify which item or weapon or armor will trigger a specific result during the appraisal stage, like revealing the unknown stone was some ultra powerful weapon or just a fur ball.
  By the way, after n attempts you might get surprised. You see, after the player has reached an amount of points by bringing in some interesting artifacts, the appraiser might be able to appraise extra goods. I guess it simulates the appraiser's ability to increase his own experience.   
 
 RE: KyoDiscounts XP VX, ACE MV - kyonides -  01-30-2019
 
 
 A Quickly Parsed BuMp! Well, I have uploaded a new version of KyoDiscounts XP, guys!
  It has reached the 1.6.10 milestone already! I have updated the main script as well as the kyodiscountsxptool.rb parser, yeah, the one you open in a text editor just like any TXT file you have found before. 
 So far you could configure the STORECODEVARID constant to define the in-game variable that would hold the Store ID you need for Exclusive Stores or shops where investors are welcome or those stores that offer their appraisal services. Now you could use a script call instead. (I think I have reinstalled this call after its long absence. Blame Maracuyá for it!)
 
 The script call would be...
 KyoShop.id = 100
 
 Oh and I have created two new directories, namely Appraisals and PriceChanges. They will hold all of the TXT configuration files needed by KyoDiscounts. During development you will need to run the parser alias kyodiscountsxptool.rb to make new rxdata files located in the Data directory. Before your game is ready for distribution, remove the parser and the temporary Appraisals and PriceChanges folders or move them to another location. (You do not want your players to cheat via modifying the TXT files!
  ) 
 By the way, now you can prevent the player from selling either discount cards or coupons at stores at any time.
 
 KyoShop.no_card_sale = true
 KyoShop.no_coupon_sale = true
 
 Or use false to allow their sales once again.
 
 
 RE: KyoDiscounts XP VX, ACE MV - kyonides -  01-31-2019
 
 
 Some Bump alias Maintenance Update Guess, what? I have found a couple of minor bugs and have thought I had to fix them. A few moments ago I finished uploading the new version, namely the brand new 1.6.11. It also includes a new window that will show common weapon or armor stats in the purchase stage if you press some specific button you can configure in the KyoShop module as usual.
 
 I will not wish you some happy testing because I know for sure most of you never test scripts. =_=
 
 
 
 |