#============================================================================== # Zenith RGSS10 交換屋 ver1.00 #   by 水夜 #  http://zenith.ifdef.jp/ #------------------------------------------------------------------------------ # 商品と所持品を交換するお店。 #============================================================================== #============================================================================== # □ カスタマイズポイント #============================================================================== module ZENITH10 # 商品の価格を表示するかどうか PRICE_INDICATE = false # 交換レート n (商品の価格の n 倍以上の価格のアイテムを提示しなければならない) EXCHANGE_RATE = 2 # # ※交換レートが 2 の場合の例 #  ・50G の商品A が欲しい場合 #   200G の所持品Aなら交換に応じてくれるが、 #   80G の所持品Bでは交換に応じてくれない。 #  ・この場合、所持品A 1個で 商品A 2個と交換できる。 # end #============================================================================== # □ カスタマイズポイント終了 #============================================================================== class Game_Temp #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :exchange_calling # 交換屋呼び出しフラグ #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- alias zenith10_initialize initialize def initialize @exchange_calling = false zenith10_initialize end end #============================================================================== # ■ Window_ExchangeCommand #------------------------------------------------------------------------------ #  交換屋画面で、用件を選択するウィンドウです。 #============================================================================== class Window_ExchangeCommand < Window_Selectable #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 64, 640, 64) self.contents = Bitmap.new(width - 32, height - 32) @item_max = 2 @column_max = 2 @commands = ["交換する", "やめる"] refresh self.index = 0 end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh self.contents.clear for i in 0...@item_max draw_item(i) end end #-------------------------------------------------------------------------- # ● 項目の描画 # index : 項目番号 #-------------------------------------------------------------------------- def draw_item(index) x = 4 + index * 320 self.contents.draw_text(x, 0, 288, 32, @commands[index], 1) end end #============================================================================== # ■ Window_ExchangeList #------------------------------------------------------------------------------ #  交換屋画面で、相手側の商品の一覧を表示するウィンドウです。 #============================================================================== class Window_ExchangeList < Window_Selectable #-------------------------------------------------------------------------- # ● オブジェクト初期化 # shop_goods : 商品 #-------------------------------------------------------------------------- def initialize(shop_goods) super(0, 128, 368, 352) @shop_goods = shop_goods refresh self.index = 0 end #-------------------------------------------------------------------------- # ● アイテムの取得 #-------------------------------------------------------------------------- def item return @data[self.index] end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh if self.contents != nil self.contents.dispose self.contents = nil end @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 @data.push(item) end end # 項目数が 0 でなければビットマップを作成し、全項目を描画 @item_max = @data.size if @item_max > 0 self.contents = Bitmap.new(width - 32, row_max * 32) for i in 0...@item_max draw_item(i) end end end #-------------------------------------------------------------------------- # ● 項目の描画 # index : 項目番号 #-------------------------------------------------------------------------- def draw_item(index) item = @data[index] # アイテムの所持数を取得 case item when RPG::Item number = $game_party.item_number(item.id) when RPG::Weapon number = $game_party.weapon_number(item.id) when RPG::Armor number = $game_party.armor_number(item.id) end # 所持数が 99 でなければ通常文字色に、 # そうでなければ無効文字色に設定 if number < 99 self.contents.font.color = normal_color else self.contents.font.color = disabled_color end 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) opacity = self.contents.font.color == normal_color ? 255 : 128 self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.draw_text(x + 28, y, 212, 32, item.name, 0) if ZENITH10::PRICE_INDICATE self.contents.draw_text(x + 240, y, 88, 32, item.price.to_s, 2) end end #-------------------------------------------------------------------------- # ● ヘルプテキスト更新 #-------------------------------------------------------------------------- def update_help @help_window.set_text(self.item == nil ? "" : self.item.description) end end #============================================================================== # ■ Window_ExchangeItem #------------------------------------------------------------------------------ #  交換屋画面で、所持アイテムの一覧を表示するウィンドウです。 #============================================================================== class Window_ExchangeItem < Window_Selectable #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 128, 640, 352) @column_max = 2 refresh self.index = 0 end #-------------------------------------------------------------------------- # ● アイテムの取得 #-------------------------------------------------------------------------- def item return @data[self.index] end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh(price=0) @price = price if self.contents != nil self.contents.dispose self.contents = nil end @data = [] for i in 1...$data_items.size if $game_party.item_number(i) > 0 @data.push($data_items[i]) end end for i in 1...$data_weapons.size if $game_party.weapon_number(i) > 0 @data.push($data_weapons[i]) end end for i in 1...$data_armors.size if $game_party.armor_number(i) > 0 @data.push($data_armors[i]) end end # 項目数が 0 でなければビットマップを作成し、全項目を描画 @item_max = @data.size if @item_max > 0 self.contents = Bitmap.new(width - 32, row_max * 32) for i in 0...@item_max draw_item(i) end end end #-------------------------------------------------------------------------- # ● 項目の描画 # index : 項目番号 #-------------------------------------------------------------------------- def draw_item(index) item = @data[index] case item when RPG::Item number = $game_party.item_number(item.id) when RPG::Weapon number = $game_party.weapon_number(item.id) when RPG::Armor number = $game_party.armor_number(item.id) end # 交換可能なら通常文字色に、そうでないなら無効文字色に設定 if item.price >= @price * ZENITH10::EXCHANGE_RATE self.contents.font.color = normal_color else self.contents.font.color = disabled_color end x = 4 + index % 2 * (288 + 32) y = index / 2 * 32 rect = Rect.new(x, y, self.width / @column_max - 32, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) bitmap = RPG::Cache.icon(item.icon_name) opacity = self.contents.font.color == normal_color ? 255 : 128 self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.draw_text(x + 28, y, 212, 32, item.name, 0) self.contents.draw_text(x + 240, y, 16, 32, ":", 1) self.contents.draw_text(x + 256, y, 24, 32, number.to_s, 2) end end #============================================================================== # ■ Window_ExchangeNumber #------------------------------------------------------------------------------ #  交換屋画面で、交換するアイテムの個数を入力するウィンドウです。 #============================================================================== class Window_ExchangeNumber < Window_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 128, 368, 352) self.contents = Bitmap.new(width - 32, height - 32) @item1 = nil @item2 = nil @max = 1 @number = 1 end #-------------------------------------------------------------------------- # ● アイテム、最大個数、価格の設定 #-------------------------------------------------------------------------- def set(item1, item2, max) @item1 = item1 @item2 = item2 @max = max @number = 0 refresh end #-------------------------------------------------------------------------- # ● 入力された個数の設定 #-------------------------------------------------------------------------- def number return @number end #-------------------------------------------------------------------------- # ● 何個と交換できるか計算 #-------------------------------------------------------------------------- def result_number(number) return (@item2.price * number/ (@item1.price * ZENITH10::EXCHANGE_RATE)).floor end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh self.contents.clear # 何個と交換できるか計算 @item1_number = result_number(@number) case @item1 when RPG::Item number = $game_party.item_number(@item1.id) when RPG::Weapon number = $game_party.weapon_number(@item1.id) when RPG::Armor number = $game_party.armor_number(@item1.id) end # 最大数を超えないように調整 if @item1_number >= 99 - number @item1_number = 99 - number loop do number2 = result_number(@number - 1) if number2 >= 99 - number @number -= 1 else break end end @max = @number end draw_item_name(@item1, 4, 72) self.contents.font.color = normal_color self.contents.draw_text(272, 72, 32, 32, "×") self.contents.draw_text(308, 72, 24, 32, @item1_number.to_s, 2) draw_item_name(@item2, 4, 120) self.contents.font.color = normal_color self.contents.draw_text(272, 120, 32, 32, "×") self.contents.draw_text(308, 120, 24, 32, @number.to_s, 2) self.cursor_rect.set(304, 120, 32, 32) end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update super if self.active # カーソル右 (+1) if Input.repeat?(Input::RIGHT) and @number < @max $game_system.se_play($data_system.cursor_se) @number += 1 refresh end # カーソル左 (-1) if Input.repeat?(Input::LEFT) and @number > 0 $game_system.se_play($data_system.cursor_se) @number -= 1 refresh end # カーソル上 (+10) if Input.repeat?(Input::UP) and @number < @max $game_system.se_play($data_system.cursor_se) @number = [@number + 10, @max].min refresh end # カーソル下 (-10) if Input.repeat?(Input::DOWN) and @number > 1 $game_system.se_play($data_system.cursor_se) @number = [@number - 10, 0].max refresh end end end end #============================================================================== # ■ Scene_Exchange #------------------------------------------------------------------------------ #  交換屋画面の処理を行うクラスです。 #============================================================================== class Scene_Exchange #-------------------------------------------------------------------------- # ● メイン処理 #-------------------------------------------------------------------------- def main # ヘルプウィンドウを作成 @help_window = Window_Help.new # コマンドウィンドウを作成 @command_window = Window_ExchangeCommand.new # ダミーウィンドウを作成 @dummy_window = Window_Base.new(0, 128, 640, 352) # 商品リストウィンドウを作成 @list_window = Window_ExchangeList.new($game_temp.shop_goods) @list_window.active = false @list_window.visible = false @list_window.help_window = @help_window # 所持品ウィンドウを作成 @item_window = Window_ExchangeItem.new @item_window.active = false @item_window.visible = false # 個数入力ウィンドウを作成 @number_window = Window_ExchangeNumber.new @number_window.active = false @number_window.visible = false # ステータスウィンドウを作成 @status_window = Window_ShopStatus.new @status_window.visible = false # トランジション実行 Graphics.transition # メインループ loop do # ゲーム画面を更新 Graphics.update # 入力情報を更新 Input.update # フレーム更新 update # 画面が切り替わったらループを中断 if $scene != self break end end # トランジション準備 Graphics.freeze # ウィンドウを解放 @help_window.dispose @command_window.dispose @dummy_window.dispose @list_window.dispose @item_window.dispose @number_window.dispose @status_window.dispose end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update # ウィンドウを更新 @help_window.update @command_window.update @dummy_window.update @list_window.update @item_window.update @number_window.update @status_window.update # コマンドウィンドウがアクティブの場合: update_command を呼ぶ if @command_window.active update_command return end # 商品リストウィンドウがアクティブの場合: update_list を呼ぶ if @list_window.active update_list return end # 所持品ウィンドウがアクティブの場合: update_item を呼ぶ if @item_window.active update_item return end # 個数入力ウィンドウがアクティブの場合: update_number を呼ぶ if @number_window.active update_number return end end #-------------------------------------------------------------------------- # ● フレーム更新 (コマンドウィンドウがアクティブの場合) #-------------------------------------------------------------------------- def update_command # B ボタンが押された場合 if Input.trigger?(Input::B) # キャンセル SE を演奏 $game_system.se_play($data_system.cancel_se) # マップ画面に切り替え $scene = Scene_Map.new return end # C ボタンが押された場合 if Input.trigger?(Input::C) # コマンドウィンドウのカーソル位置で分岐 case @command_window.index when 0 # 購入する # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) # ウィンドウの状態を商品リストモードへ @command_window.active = false @dummy_window.visible = false @list_window.active = true @list_window.visible = true @list_window.refresh @status_window.visible = true when 1 # やめる # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) # マップ画面に切り替え $scene = Scene_Map.new end return end end #-------------------------------------------------------------------------- # ● フレーム更新 (商品リストウィンドウがアクティブの場合) #-------------------------------------------------------------------------- def update_list # ステータスウィンドウのアイテムを設定 @status_window.item = @list_window.item # B ボタンが押された場合 if Input.trigger?(Input::B) # キャンセル SE を演奏 $game_system.se_play($data_system.cancel_se) # ウィンドウの状態を初期モードへ @command_window.active = true @dummy_window.visible = true @list_window.active = false @list_window.visible = false @status_window.visible = false @status_window.item = nil # ヘルプテキストを消去 @help_window.set_text("") return end # C ボタンが押された場合 if Input.trigger?(Input::C) # アイテムを取得 @item = @list_window.item # アイテムが無効の場合 if @item == nil # ブザー SE を演奏 $game_system.se_play($data_system.buzzer_se) return end # アイテムの所持数を取得 case @item when RPG::Item number = $game_party.item_number(@item.id) when RPG::Weapon number = $game_party.weapon_number(@item.id) when RPG::Armor number = $game_party.armor_number(@item.id) end # すでに 99 個所持している場合 if number == 99 # ブザー SE を演奏 $game_system.se_play($data_system.buzzer_se) return end # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) # ウィンドウの状態を所持品モードへ @list_window.active = false @list_window.visible = false @item_window.active = true @item_window.visible = true @item_window.refresh(@item.price) @item_window.index = 0 @status_window.item = nil @status_window.visible = false @item1 = @item # アイテムの所持数を取得 case @item when RPG::Item @item1_number = $game_party.item_number(@item.id) when RPG::Weapon @item1_number = $game_party.weapon_number(@item.id) when RPG::Armor @item1_number = $game_party.armor_number(@item.id) end # ヘルプテキスト @help_window.set_text("交換するアイテムを所持品から選択してください。") end end #-------------------------------------------------------------------------- # ● フレーム更新 (所持品ウィンドウがアクティブの場合) #-------------------------------------------------------------------------- def update_item # B ボタンが押された場合 if Input.trigger?(Input::B) # キャンセル SE を演奏 $game_system.se_play($data_system.cancel_se) # ウィンドウの状態を商品リストモードへ @list_window.active = true @list_window.visible = true @list_window.refresh @item_window.active = false @item_window.visible = false @status_window.visible = true return end # C ボタンが押された場合 if Input.trigger?(Input::C) # アイテムを取得 @item = @item_window.item # アイテムが無効の場合、または交換品の価格に足りない場合 if @item == nil or @item1.price * ZENITH10::EXCHANGE_RATE > @item.price # ブザー SE を演奏 $game_system.se_play($data_system.buzzer_se) return end # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) # アイテムの所持数を取得 case @item when RPG::Item number = $game_party.item_number(@item.id) when RPG::Weapon number = $game_party.weapon_number(@item.id) when RPG::Armor number = $game_party.armor_number(@item.id) end # 最大交換可能数を計算 max = number # ウィンドウの状態を個数入力モードへ @item_window.active = false @item_window.visible = false @number_window.set(@item1, @item, max) @number_window.active = true @number_window.visible = true @status_window.visible = true # ヘルプテキスト @help_window.set_text("交換する数を決定してください。") end end #-------------------------------------------------------------------------- # ● フレーム更新 (個数入力ウィンドウがアクティブの場合) #-------------------------------------------------------------------------- def update_number # ステータスウィンドウのアイテムを設定 @status_window.item = @list_window.item # B ボタンが押された場合 if Input.trigger?(Input::B) # キャンセル SE を演奏 $game_system.se_play($data_system.cancel_se) # 個数入力ウィンドウを非アクティブ・不可視に設定 @number_window.active = false @number_window.visible = false # ウィンドウの状態を所持品モードへ @item_window.active = true @item_window.visible = true @status_window.visible = false # ヘルプテキスト @help_window.set_text("交換するアイテムを所持品から選択してください。") return end # C ボタンが押された場合 if Input.trigger?(Input::C) # ショップ SE を演奏 $game_system.se_play($data_system.shop_se) # 個数入力ウィンドウを非アクティブ・不可視に設定 @number_window.active = false @number_window.visible = false # 交換処理 @item1_number = (@item.price * @number_window.number/ (@item1.price * ZENITH10::EXCHANGE_RATE)).floor case @item1 when RPG::Item $game_party.gain_item(@item1.id, @item1_number) when RPG::Weapon $game_party.gain_weapon(@item1.id, @item1_number) when RPG::Armor $game_party.gain_armor(@item1.id, @item1_number) end case @item when RPG::Item $game_party.lose_item(@item.id, @number_window.number) when RPG::Weapon $game_party.lose_weapon(@item.id, @number_window.number) when RPG::Armor $game_party.lose_armor(@item.id, @number_window.number) end # 各ウィンドウをリフレッシュ @list_window.refresh @status_window.refresh # ウィンドウの状態を商品リストモードへ @list_window.active = true @list_window.visible = true @status_window.visible = true return end end end class Scene_Map #-------------------------------------------------------------------------- # ● ショップの呼び出し #-------------------------------------------------------------------------- alias zenith10_call_shop call_shop def call_shop if $game_temp.exchange_calling # ショップ呼び出しフラグをクリア $game_temp.shop_calling = false # 交換屋呼び出しフラグをクリア $game_temp.exchange_calling = false # プレイヤーの姿勢を矯正 $game_player.straighten # 交換屋画面に切り替え $scene = Scene_Exchange.new else zenith10_call_shop end end end class Interpreter #-------------------------------------------------------------------------- # ● ラベル #-------------------------------------------------------------------------- alias zenith10_command_118 command_118 def command_118 # 「交換屋」ラベルの直後が「ショップの処理」の場合 if @list[@index + 1] != nil and @parameters[0] == "交換屋" and @list[@index + 1].code == 302 # 交換屋呼び出しフラグ $game_temp.exchange_calling = true end zenith10_command_118 end end