KyoDiscounts XP
#21
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
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Reply }


Messages In This Thread
KyoDiscounts XP - by kyonides - 11-07-2016, 03:32 AM
RE: KyoDiscounts XP - by kyonides - 11-07-2016, 06:41 AM
RE: KyoDiscounts XP - by kyonides - 11-07-2016, 07:38 PM
RE: KyoDiscounts XP - by Bounty Hunter Lani - 11-07-2016, 08:13 PM
RE: KyoDiscounts XP - by kyonides - 11-08-2016, 03:44 AM
RE: KyoDiscounts XP - by kyonides - 11-09-2016, 03:26 AM
RE: KyoDiscounts XP - by kyonides - 11-09-2016, 10:21 PM
RE: KyoDiscounts XP - by kyonides - 11-15-2016, 08:22 PM
RE: KyoDiscounts XP MV - by kyonides - 11-18-2016, 12:47 PM
RE: KyoDiscounts XP VX MV - by kyonides - 11-20-2016, 07:19 PM
RE: KyoDiscounts XP VX MV - by kyonides - 11-22-2016, 02:21 AM
RE: KyoDiscounts XP VX MV - by kyonides - 11-23-2016, 12:36 AM
RE: KyoDiscounts XP VX MV - by kyonides - 11-24-2016, 04:24 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 11-25-2016, 11:21 PM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 11-26-2016, 06:33 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 11-27-2016, 03:27 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 12-04-2018, 12:56 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 12-04-2018, 08:52 AM
RE: KyoDiscounts XP VX, ACE MV - by Nyakuya - 01-12-2019, 11:16 PM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 01-12-2019, 11:31 PM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 01-14-2019, 05:48 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 01-14-2019, 10:40 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 01-15-2019, 07:10 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 01-17-2019, 10:11 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 01-18-2019, 06:23 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 01-27-2019, 05:12 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 01-28-2019, 05:41 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 01-29-2019, 10:17 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 01-30-2019, 09:47 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 01-31-2019, 03:36 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 02-01-2019, 09:54 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 02-03-2019, 04:38 AM
RE: KyoDiscounts XP VX, ACE MV - by Mel - 02-03-2019, 11:06 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 07-28-2019, 05:04 AM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 10-02-2021, 10:21 PM
RE: KyoDiscounts XP VX, ACE MV - by kyonides - 11-10-2022, 09:57 AM



Users browsing this thread: 2 Guest(s)