#============================================================================== # ■ MixShop #------------------------------------------------------------------------------ # 製作:春日屋/春日 # URL :http://www.katch.ne.jp/~littelplanet/kasugaya/ # Ver :1.00 # 更新:2007/08/13 # #  アイテム合成ショップを実装します。 # 指定したスイッチが ON のとき合成ショップを、 # OFF のとき通常のショップを起動します。 # アイテム合成ショップ用のデータは、 # 専用のエディター(Mix Item Editer)を使用して作成してください。 # エディターは春日屋で配布しています。 # #============================================================================== class Game_Temp alias init initialize def initialize init # 設定項目 --------------------------------------------- # 通常のショップとアイテム合成ショップの切り替えをする # スイッチの番号を指定します。 # ここで指定した番号のスイッチが ON のとき、 # ショップコマンドでアイテム合成ショップが起動します。 @change_shop_switch = 1 # 設定項目終わり --------------------------------------- end attr_accessor :change_shop_switch end module RPG class Mixitem def initialize @kind = 0 @id = 0 @necessary_items = [] @price = false end attr_accessor :kind attr_accessor :id attr_accessor :necessary_items attr_accessor :price end end class Window_MixShopItems < Window_Base #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :mix_ok #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 128, 368, 352) @items = [] @mix_ok = false end #-------------------------------------------------------------------------- # ● 材料設定 # items : 必要アイテム # メモ:[[アイテム, 必要数, 所持数], ...] #-------------------------------------------------------------------------- def set_items(items, gold) @items = items # 0 番目の要素が nil なので削除して詰める #@items.delete_at(0) @gold = gold @number = 1 end #-------------------------------------------------------------------------- # ● 材料の一覧取得 #-------------------------------------------------------------------------- def get_items return @items end #-------------------------------------------------------------------------- # ● リフレッシュ # number:購入個数 #-------------------------------------------------------------------------- def refresh(number) @number = number @mix_ok = true if self.contents != nil self.contents.dispose self.contents = nil end # 全項目を描画 self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.color = system_color self.contents.draw_text(4, 0, 304, 32, "材料") for i in 0...@items.size draw_item(i) end # 合計価格と通貨単位を描画 domination = $data_system.words.gold cx = contents.text_size(domination).width total_price = @gold * @number self.contents.font.color = normal_color self.contents.draw_text(4, 256, 328-cx-2, 32, total_price.to_s, 2) self.contents.font.color = system_color self.contents.draw_text(332-cx, 256, cx, 32, domination, 2) end #-------------------------------------------------------------------------- # ● 項目の描画 # index : 項目番号 #-------------------------------------------------------------------------- def draw_item(index) item = @items[index][0] n_num = @items[index][1] * @number p_num = @items[index][2] # アイテムを必要数以上所持していれば通常文字色に、 # そうでなければ無効文字色に設定 if n_num <= p_num self.contents.font.color = normal_color else self.contents.font.color = disabled_color @mix_ok = false end x = 4 y = index * 32 + 64 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) self.contents.draw_text(x + 240, y, 88, 32, n_num.to_s, 2) end end class Window_MixShopHave < Window_Base #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :mix_ok #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(368, 128, 272, 352) @items = [] end #-------------------------------------------------------------------------- # ● 材料設定 # items : 必要アイテム # メモ:[[アイテム, 必要数, 所持数], ...] #-------------------------------------------------------------------------- def set_items(items) @items = items # 0 番目の要素が nil なので削除して詰める #@items.delete_at(0) @number = 1 end #-------------------------------------------------------------------------- # ● 材料の一覧取得 #-------------------------------------------------------------------------- def get_items return @items end #-------------------------------------------------------------------------- # ● リフレッシュ # number:購入個数 #-------------------------------------------------------------------------- def refresh(number) @number = number if self.contents != nil self.contents.dispose self.contents = nil end # 全項目を描画 self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.color = system_color self.contents.draw_text(4, 0, 304, 32, "材料所持数") for i in 0...@items.size draw_item(i) end end #-------------------------------------------------------------------------- # ● 項目の描画 # index : 項目番号 #-------------------------------------------------------------------------- def draw_item(index) n_num = @items[index][1] * @number p_num = @items[index][2] # アイテムを必要数以上所持していれば通常文字色に、 # そうでなければ無効文字色に設定 if n_num <= p_num self.contents.font.color = normal_color else self.contents.font.color = crisis_color end x = 4 y = index * 32 + 64 rect = Rect.new(x, y, self.width - 32, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) self.contents.draw_text(x + 144, y, 88, 32, p_num.to_s, 2) end end class Window_MixShopNumber < Window_ShopNumber #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh self.contents.clear draw_item_name(@item, 4, 0) self.contents.font.color = normal_color self.contents.draw_text(272, 0, 32, 32, "×") self.contents.draw_text(308, 0, 24, 32, @number.to_s, 2) self.cursor_rect.set(304, 0, 32, 32) end end class Window_MixGold < Window_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(368, 64, 272, 64) self.contents = Bitmap.new(width - 32, height - 32) refresh end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh self.contents.clear cx = contents.text_size($data_system.words.gold).width self.contents.font.color = normal_color self.contents.draw_text(4, 0, 232-cx-2, 32, $game_party.gold.to_s, 2) self.contents.font.color = system_color self.contents.draw_text(236-cx, 0, cx, 32, $data_system.words.gold, 2) end end class Scene_Map #-------------------------------------------------------------------------- # ● ショップの呼び出し #-------------------------------------------------------------------------- def call_shop # ショップ呼び出しフラグをクリア $game_temp.shop_calling = false # プレイヤーの姿勢を矯正 $game_player.straighten # ショップ画面に切り替え if $game_switches[$game_temp.change_shop_switch] $scene = Scene_MixShop.new else $scene = Scene_Shop.new end end end class Scene_MixShop #-------------------------------------------------------------------------- # ● メイン処理 #-------------------------------------------------------------------------- def main # 合成データをロード $data_mixitems = load_data("Data/MixItems.rxdata") # ヘルプウィンドウを作成 @help_window = Window_Help.new # 合成ウィンドウを作成 @mixitem_window = Window_MixShopItems.new @mixitem_window.active = false @mixitem_window.visible = false # 所持数ウィンドウを作成 @have_window = Window_MixShopHave.new @have_window.active = false @have_window.visible = false # ゴールドウィンドウを作成 @gold_window = Window_MixGold.new # 購入ウィンドウを作成 @buy_window = Window_ShopBuy.new($game_temp.shop_goods) @buy_window.y = 64 @buy_window.height = 416 @buy_window.active = true @buy_window.visible = true @buy_window.help_window = @help_window # 個数入力ウィンドウを作成 @number_window = Window_MixShopNumber.new @number_window.contents.dispose @number_window.contents = nil @number_window.contents = Bitmap.new(336, 32) @number_window.y = 64 @number_window.height = 64 @number_window.active = false @number_window.visible = false @number = 1 # ステータスウィンドウを作成 @status_window = Window_ShopStatus.new # トランジション実行 Graphics.transition # メインループ loop do # ゲーム画面を更新 Graphics.update # 入力情報を更新 Input.update # フレーム更新 update # 画面が切り替わったらループを中断 if $scene != self break end end # トランジション準備 Graphics.freeze # ウィンドウを解放 @help_window.dispose @gold_window.dispose @have_window.dispose @buy_window.dispose @number_window.dispose @status_window.dispose @mixitem_window.dispose end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update # ウィンドウを更新 @help_window.update @gold_window.update @buy_window.update @number_window.update @status_window.update # 購入ウィンドウがアクティブの場合: update_buy を呼ぶ if @buy_window.active update_buy return end # 個数入力ウィンドウがアクティブの場合: update_number を呼ぶ if @number_window.active update_number return end end #-------------------------------------------------------------------------- # ● フレーム更新 (コマンドウィンドウ2がアクティブの場合) #-------------------------------------------------------------------------- def update_command end #-------------------------------------------------------------------------- # ● フレーム更新 (購入ウィンドウがアクティブの場合) #-------------------------------------------------------------------------- def update_buy # ステータスウィンドウのアイテムを設定 @status_window.item = @buy_window.item # 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) # アイテムを取得 @item = @buy_window.item # アイテムが無効の場合、または価格が所持金より上の場合 if @item == nil or @item.price > $game_party.gold # ブザー SE を演奏 $game_system.se_play($data_system.buzzer_se) return end # アイテムの所持数と種類を取得 case @item when RPG::Item number = $game_party.item_number(@item.id) kind = 0 when RPG::Weapon number = $game_party.weapon_number(@item.id) kind = 1 when RPG::Armor number = $game_party.armor_number(@item.id) kind = 2 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) # 最大購入可能個数を計算 max = @item.price == 0 ? 99 : $game_party.gold / @item.price max = [max, 99 - number].min # ウィンドウの状態を個数入力モードへ @buy_window.active = false @buy_window.visible = false @number_window.set(@item, max, @item.price) @number_window.active = true @number_window.visible = true # 合成ウィンドウのリフレッシュ item = [] # データが存在するときのみ if $data_mixitems[kind] != nil if $data_mixitems[kind][@item.id] != nil for data in $data_mixitems[kind][@item.id].necessary_items next if data == nil next if data[1] == 0 || data[1] == nil # 必要アイテムデータを収集 id = data[1] # 必要数 e_num = data[2] # 分類によってデータと所持数を取得 case data[0] when 0 ia = $data_items[id] p_num = $game_party.item_number(id) when 1 ia = $data_weapons[id] p_num = $game_party.weapon_number(id) when 2 ia = $data_armors[id] p_num = $game_party.armor_number(id) end item << [ia, e_num, p_num] end end end # 費用取得 gold = @item.price # 合成ウィンドウをアクティブ・可視に設定 @mixitem_window.set_items(item, gold) @mixitem_window.refresh(1) @mixitem_window.active = true @mixitem_window.visible = true @have_window.set_items(item) @have_window.refresh(1) @have_window.active = true @have_window.visible = true # ステータスウィンドウを非アクティブ・不可視に設定 @status_window.active = false @status_window.visible = false end end #-------------------------------------------------------------------------- # ● フレーム更新 (個数入力ウィンドウがアクティブの場合) #-------------------------------------------------------------------------- def update_number # 合成ウィンドウリフレッシュ if @number != @number_window.number @number = @number_window.number @mixitem_window.refresh(@number) @have_window.refresh(@number) end # B ボタンが押された場合 if Input.trigger?(Input::B) # キャンセル SE を演奏 $game_system.se_play($data_system.cancel_se) # 個数入力ウィンドウを非アクティブ・不可視に設定 @number_window.active = false @number_window.visible = false # 合成ウィンドウを非アクティブ・不可視に設定 @mixitem_window.active = false @mixitem_window.visible = false @have_window.active = false @have_window.visible = false # ステータスウィンドウをアクティブ・可視に設定 @status_window.active = true @status_window.visible = true # ウィンドウの状態を購入モードへ @buy_window.active = true @buy_window.visible = true return end # C ボタンが押された場合 if Input.trigger?(Input::C) # 購入可能か判定 if @mixitem_window.mix_ok # ショップ SE を演奏 $game_system.se_play($data_system.shop_se) # 個数入力ウィンドウを非アクティブ・不可視に設定 @number_window.active = false @number_window.visible = false # 合成ウィンドウを非アクティブ・不可視に設定 @mixitem_window.active = false @mixitem_window.visible = false @have_window.active = false @have_window.visible = false # ステータスウィンドウをアクティブ・可視に設定 @status_window.active = true @status_window.visible = true # 購入処理 number = @number_window.number $game_party.lose_gold(@number_window.number * @item.price) case @item when RPG::Item $game_party.gain_item(@item.id, number) when RPG::Weapon $game_party.gain_weapon(@item.id, number) when RPG::Armor $game_party.gain_armor(@item.id, number) end # 材料の消滅 for item in @mixitem_window.get_items case item[0] when RPG::Item $game_party.lose_item(item[0].id, item[1] * number) when RPG::Weapon $game_party.lose_weapon(item[0].id, item[1] * number) when RPG::Armor $game_party.lose_armor(item[0].id, item[1] * number) end end # 各ウィンドウをリフレッシュ @gold_window.refresh @buy_window.refresh @status_window.refresh # ウィンドウの状態を購入モードへ @buy_window.active = true @buy_window.visible = true else # ブザー SE を演奏 $game_system.se_play($data_system.buzzer_se) end return end end end