﻿#==============================================================================
# ★ ExCommand_BarterShop　～ 以物易物商店 ～
#------------------------------------------------------------------------------
# 　在[商店處理] 使用特定的物品作為貨幣來購買貨物。
#==============================================================================

# 使兌換功能有效的開關 ID。
# 當此號的開關為 ON 時，[商店處理] 實際打開的是物品兌換的商店介面、
# 也可以勾選「只能購買的商店」選項
# 此開關會在離開商店畫面時自動設為 OFF
EXCMD_BTRSHOP_SID = 6

# 商店兌換命令視窗的用語。
# 從左數起分別為原本的[購買] [販賣] [離開]。
EXCMD_BTRSHOP_VOCAB = ["兌換", "販買", "離開"]

# 兌換物設定。
# 除了交易時使用，兌換物依然當作普通物品處理。
# 依次設定：物品 ID、單位用語、兌換率。
# 商品價格 ÷ 兌換率 自動取整，捨棄小數。
# 範例：兌換率設為 100 時 => 
# 　1650 G 的商品可以用16個兌換物交換，、100 G 以下的商品可以用1個兌換物交換
EXCMD_BTRSHOP_ITEM = [22, "枚", 100]

# 指定商品兌換率的文字。
# 在沒有直接指定商品的兌換物價格時，會自動換算
# 但是優先使用[備註]中所指定的價格： 指定文字 + [兌換率]
# 範例：可以用 20 個兌換物兌換的物品 => *BARTER_RATE[20]
EXCMD_BTRSHOP_SIGNATURE = "*BARTER_RATE"

# 識別商店的變數 ID。
# 可以在調用「商店處理」指令前，使用商店識別變數來設定商店編號。
# 也就是說，同一個商店NPC可以因為商店識別變數的數值不同而使用不同的兌換率。
EXCMD_BTRSHOP_VID = 6

# 商店的設定
# 格式：指定文字 ( + [兌換率] ) + [商店識別號:兌換率] 
# 「:」對應每個商店的兌換率，使用「|」來分隔商店。
# 範例1： 1號商店使用 20 個、2號商店使用 15 個、3號商店使用 25 個兌換物
# 來兌換商店內的物品 => *BARTER_RATE[1:20|2:15|3:25]

# 範例2：2號商店使用 10 個、3號商店使用 15 個、其餘的使用 20 個兌換物
# 來兌換商店內的物品 => *BARTER_RATE[20][2:10|3:15]
# 
# 兌換率判斷優先度：個別商店的設定 ＞ 商品的設定 ＞ 兌換物的兌換率。

#------------------------------------------------------------------------------

class Game_Party
  #--------------------------------------------------------------------------
  # ☆ 獲取交換物
  #--------------------------------------------------------------------------
  def barter_item
    return $data_items[EXCMD_BTRSHOP_ITEM[0]]
  end
  #--------------------------------------------------------------------------
  # ☆ 獲取交換物的數量
  #--------------------------------------------------------------------------
  def barter_item_number
    return $game_party.item_number(barter_item)
  end
  #--------------------------------------------------------------------------
  # ☆ 獲取物品兌換率
  #--------------------------------------------------------------------------
  def barter_rate(item)
    rate = 0
    shop_id = $game_variables[EXCMD_BTRSHOP_VID]
    sig = EXCMD_BTRSHOP_SIGNATURE
    reg = /#{Regexp.quote sig}(?:\[\d+\])?\[((\d+:\d+\|?)+)\]/
    note = item.note.clone
    note.gsub!(/\r\n/, "")
    if shop_id > 0 and note.scan(reg).to_a[0]
      for s in $~[1].split(/\s*\|\s*/)
        r = s.split(/\s*:\s*/)
        rate = r[1].to_i if r[0].to_i == shop_id
        break if rate > 0
      end
    end
    if rate == 0
      if note[/#{Regexp.quote sig}\[(\d+)\]/].to_a[0]
        rate = $1.to_i
      else
        rate = (item.price / EXCMD_BTRSHOP_ITEM[2]).round
      end
    end
    return rate > 0 ? rate : 1
  end
end

class Window_Base
  alias _excbshop_initialize initialize
  #--------------------------------------------------------------------------
  # ● 初始化對像(追加定義)
  #     x      : 窗口 X 座標
  #     y      : 窗口 Y 座標
  #     width  : 窗口寬度
  #     height : 窗口高度
  #--------------------------------------------------------------------------
  def initialize(x, y, width, height)
    _excbshop_initialize(x, y, width, height)
    self.currency = Vocab::gold
  end
  #--------------------------------------------------------------------------
  # ☆ 通貨單位設定
  #--------------------------------------------------------------------------
  def currency=(currency)
    @currency = currency
  end
  #--------------------------------------------------------------------------
  # ☆ 判斷是否使用金錢
  #--------------------------------------------------------------------------
  def gold?
    return @currency == Vocab::gold
  end
  #--------------------------------------------------------------------------
  # ● 繪製金錢單位(重新定義)
  #     value : 數目
  #     x     : 描畫目標 X 座標
  #     y     : 描畫目標 Y 座標
  #     width : 描畫目標寬度
  #--------------------------------------------------------------------------
  def draw_currency_value(value, x, y, width)
    cx = contents.text_size(@currency).width
    self.contents.font.color = normal_color
    self.contents.draw_text(x, y, width - cx - 2, WLH, value, 2)
    self.contents.font.color = system_color
    self.contents.draw_text(x, y, width, WLH, @currency, 2)
  end
end

class Window_Gold
  alias _excbshop_refresh refresh
  #--------------------------------------------------------------------------
  # ○ 刷新(追加定義)
  #--------------------------------------------------------------------------
  def refresh
    _excbshop_refresh
    if $game_switches[EXCMD_BTRSHOP_SID]
      self.contents.clear
      value = gold? ? $game_party.gold : $game_party.barter_item_number
      draw_currency_value(value, 4, 0, 120)
    end
  end
end

class Window_ShopBuy
  alias _excbshop_refresh refresh
  alias _excbshop_draw_item draw_item
  #--------------------------------------------------------------------------
  # ○ 刷新 (追加定義)
  #--------------------------------------------------------------------------
  def refresh
    unless $game_switches[EXCMD_BTRSHOP_SID]
      _excbshop_refresh
    else
      @data = []
      for goods_item in @shop_goods
        case goods_item[0]
        when 0
          item = $data_items[goods_item[1]]
        when 1
          item = $data_weapons[goods_item[1]]
        when 2
          item = $data_armors[goods_item[1]]
        end
        if item != nil and item != $game_party.barter_item # 交換アイテムを除外
          @data.push(item)
        end
      end
      @item_max = @data.size
      create_contents
      for i in 0...@item_max
        draw_item(i)
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 繪製商品 (追加定義)
  #     index : 商品索引
  #--------------------------------------------------------------------------
  def draw_item(index)
    unless $game_switches[EXCMD_BTRSHOP_SID]
      _excbshop_draw_item(index)
    else
      item = @data[index]
      number = $game_party.item_number(item)
      barter_number = $game_party.barter_item_number
      barter_rate = $game_party.barter_rate(item)
      enabled = (barter_rate <= barter_number and number < 99)
      rect = item_rect(index)
      self.contents.clear_rect(rect)
      draw_item_name(item, rect.x, rect.y, enabled)
      rect.width -= 4
      self.contents.draw_text(rect, barter_rate, 2)
    end
  end
end

class Scene_Shop
  alias _excbshop_start start
  alias _excbshop_terminate terminate
  alias _excbshop_create_command_window create_command_window
  alias _excbshop_update_command_selection update_command_selection
  alias _excbshop_update_buy_selection update_buy_selection
  alias _excbshop_update_sell_selection update_sell_selection
  alias _excbshop_decide_number_input decide_number_input
  #--------------------------------------------------------------------------
  # ☆ 判斷商店是否是「以物易物商店」
  #--------------------------------------------------------------------------
  def barter?
    return $game_switches[EXCMD_BTRSHOP_SID]
  end
  #--------------------------------------------------------------------------
  # ○ 開始處理 (重新定義)
  #--------------------------------------------------------------------------
  def start
    _excbshop_start
    if barter?
      @gold_window.currency = EXCMD_BTRSHOP_ITEM[1]
      @number_window.currency = EXCMD_BTRSHOP_ITEM[1]
      @gold_window.refresh
    end
  end
  #--------------------------------------------------------------------------
  # ○ 結束處理 (追加定義)
  #--------------------------------------------------------------------------
  def terminate
    _excbshop_terminate
    $game_switches[EXCMD_BTRSHOP_SID] = false
  end
  #--------------------------------------------------------------------------
  # ● 生成命令窗口(追加定義)
  #--------------------------------------------------------------------------
  def create_command_window
    unless barter?
      _excbshop_create_command_window
    else
      s1 = EXCMD_BTRSHOP_VOCAB[0]
      s2 = EXCMD_BTRSHOP_VOCAB[1]
      s3 = EXCMD_BTRSHOP_VOCAB[2]
      @command_window = Window_Command.new(384, [s1, s2, s3], 3)
      @command_window.y = 56
      if $game_temp.shop_purchase_only
        @command_window.draw_item(1, false)
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 更新命令窗口 (追加定義)
  #--------------------------------------------------------------------------
  def update_command_selection
    _excbshop_update_command_selection
    if Input.trigger?(Input::C) and barter?
      unless $game_temp.shop_purchase_only
        if @command_window.index == 1 # 売卻する
          @gold_window.currency = Vocab::gold
          @number_window.currency = Vocab::gold
          @gold_window.refresh
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 更新買入選擇(追加定義)
  #--------------------------------------------------------------------------
  def update_buy_selection
    unless barter?
      _excbshop_update_buy_selection
    else
      @status_window.item = @buy_window.item
      if Input.trigger?(Input::B)
        Sound.play_cancel
        @command_window.active = true
        @dummy_window.visible = true
        @buy_window.active = false
        @buy_window.visible = false
        @status_window.visible = false
        @status_window.item = nil
        @help_window.set_text("")
        return
      end
      if Input.trigger?(Input::C)
        @item = @buy_window.item
        barter_number = $game_party.barter_item_number
        barter_rate = $game_party.barter_rate(@item)
        number = $game_party.item_number(@item)
        if @item == nil or barter_rate > barter_number or number == 99
          Sound.play_buzzer
        else
          Sound.play_decision
          max = barter_number / barter_rate
          max = [max, 99 - number].min
          @buy_window.active = false
          @buy_window.visible = false
          @number_window.set(@item, max, barter_rate)
          @number_window.active = true
          @number_window.visible = true
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 更新賣出選擇(追加定義)
  #--------------------------------------------------------------------------
  def update_sell_selection
    _excbshop_update_sell_selection
    if Input.trigger?(Input::B) and barter?
      @gold_window.currency = EXCMD_BTRSHOP_ITEM[1]
      @number_window.currency = EXCMD_BTRSHOP_ITEM[1]
      @gold_window.refresh
    end
  end
  #--------------------------------------------------------------------------
  # ● 確認數值輸入(追加定義)
  #--------------------------------------------------------------------------
  def decide_number_input
    unless barter?
      _excbshop_decide_number_input
    else
      Sound.play_shop
      @number_window.active = false
      @number_window.visible = false
      barter_rate = $game_party.barter_rate(@item)
      number = @number_window.number
      case @command_window.index
      when 0  # 購買（交換）
        $game_party.lose_item($game_party.barter_item, number * barter_rate)
        $game_party.gain_item(@item, number)
        @gold_window.refresh
        @buy_window.refresh
        @status_window.refresh
        @buy_window.active = true
        @buy_window.visible = true
      when 1  # 販賣
        $game_party.gain_gold(number * (@item.price / 2))
        $game_party.lose_item(@item, number)
        @gold_window.refresh
        @sell_window.refresh
        @status_window.refresh
        @sell_window.active = true
        @sell_window.visible = true
        @status_window.visible = false
      end
    end
  end
end

