#============================================================================== # ■ XP-RGSS-55 二重隊列システム [Ver.1.1.0] by Claimh #------------------------------------------------------------------------------ #・要・パーティー拡張 #・戦闘中にパーティーメンバーの入れ替えができます。 #・待機メンバーは毎ターンHP/SP/BPが自動回復します。 #------------------------------------------------------------------------------ #【再定義】 # Scene_Battler : main, update_phase4_step2 #============================================================================== module Double_Team #============================================================================== #--- 戦闘中メンバーチェンジ設定 ---# # 戦闘メンバーの待機を許可する? # (注) 戦闘メンバーを待機させると戦闘中はメンバーが減ったままになる MAIN_REST = false #--- 待機メンバー回復設定 ---# # 待機メンバーのHPを回復させる? SUB_HP = true # 待機メンバーのHP回復率(%) SUB_HP_PER = 5 # 待機メンバーのSPを回復させる? SUB_SP = true # 待機メンバーのSP回復率(%) SUB_SP_PER = 5 # 待機メンバーのBPを表示させる?[要・スキルBP制] SHOW_BP = false # 待機メンバーのBPを回復させる?[要・スキルBP制] SUB_BP = false #============================================================================== # Double_Team.can_change? module_function def can_change? return false if !MAIN_REST and $game_party.sub_actors.size == 0 i = 0 for actor in $game_party.sub_actors i += 1 if !actor.already_change and !actor.ch_lock end i += 1 if MAIN_REST return (i > 0 ? true : false) end end #============================================================================== # ■ Game_BattleAction #============================================================================== class Game_BattleAction attr_accessor :change_member # 入れ替え対象 #-------------------------------------------------------------------------- # ● アクションクリア #-------------------------------------------------------------------------- alias clear_party clear def clear clear_party @change_member.already_change = false unless @change_member.nil? @change_member = nil end end #============================================================================== # ■ Window_BttlSubMember #------------------------------------------------------------------------------ # 戦闘中のメンバー交換で使用する画面です。 #============================================================================== class Window_BttlSubMember < Window_Selectable #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 0, 640, 256 + 32) data_refresh self.contents = Bitmap.new(width - 32, 64 * @item_max) @column_max = 1 @row_size = 64 self.index = 0 self.active = true self.opacity = 160 refresh end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def data_refresh @commands = [] for id in 0...$game_party.sub_actors.size actor = $game_party.sub_actors[id] next if actor.already_change # 選択済みなら対象に入れない next if actor.ch_lock # 入れ替え禁止は対象に入れない @commands.push(actor) end @commands.push(nil) if Double_Team::MAIN_REST @item_max = @commands.size end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh x = 64 self.contents.clear for i in 0...@commands.size act = @commands[i] y = i * 64 if act.nil? self.contents.draw_text(x, y, 200, 64, "待機する") else draw_actor_graphic(act, 32, y + 54) draw_actor_name(act, x, y) draw_actor_class(act, x + 150, y) draw_actor_level(act, x + 300, y) draw_actor_state(act, x + 400, y) draw_actor_hp(act, x, y + 32) draw_actor_sp(act, x + 200, y + 32) draw_actor_bp(act, x + 400, y + 32) if Double_Team::SHOW_BP end end end #-------------------------------------------------------------------------- # ● 選択中アクター取得 #-------------------------------------------------------------------------- def actor return @commands[@index] end #-------------------------------------------------------------------------- # ● カーソル矩形更新 #-------------------------------------------------------------------------- def update_cursor_rect # 現在の行を取得 row = @index # 現在の行が、表示されている先頭の行より前の場合 if row < self.top_row # 現在の行が先頭になるようにスクロール self.top_row = row end # 現在の行が、表示されている最後尾の行より後ろの場合 if row > self.top_row + (self.page_row_max - 1) # 現在の行が最後尾になるようにスクロール self.top_row = row - (self.page_row_max - 1) end # カーソルの幅を計算 cursor_width = self.width - 32 # カーソルの座標を計算 x = @index % @column_max * (cursor_width + 32) y = @index / @column_max * @row_size - self.oy # カーソルの矩形を更新 self.cursor_rect.set(x, y, self.width - 32, 64) end #-------------------------------------------------------------------------- # ● 先頭の行の設定 # row : 先頭に表示する行 #-------------------------------------------------------------------------- def top_row=(row) # row が 0 未満の場合は 0 に修正 if row < 0 row = 0 end # row が row_max - 1 超の場合は row_max - 1 に修正 if row > row_max - 1 row = row_max - 1 end # row に 1 行の高さを掛け、ウィンドウ内容の転送元 Y 座標とする self.oy = row * @row_size end #-------------------------------------------------------------------------- # ● 1 ページに表示できる行数の取得 #-------------------------------------------------------------------------- def page_row_max return 4 end end #============================================================================== # ■ Scene_Battle #============================================================================== class Scene_Battle #-------------------------------------------------------------------------- # ● メイン処理 #-------------------------------------------------------------------------- def main # 戦闘用の各種一時データを初期化 $game_temp.in_battle = true $game_temp.battle_turn = 0 $game_temp.battle_event_flags.clear $game_temp.battle_abort = false $game_temp.battle_main_phase = false $game_temp.battleback_name = $game_map.battleback_name $game_temp.forcing_battler = nil # バトルイベント用インタプリタを初期化 $game_system.battle_interpreter.setup(nil, 0) # トループを準備 @troop_id = $game_temp.battle_troop_id $game_troop.setup(@troop_id) # アクターコマンドウィンドウを作成 s1 = $data_system.words.attack s2 = $data_system.words.skill s3 = $data_system.words.guard s4 = $data_system.words.item #-- s5 = "入れ替え" @actor_command_window = Window_Command.new(160, [s1, s2, s3, s4, s5]) @actor_command_window.y = 128 #-- @actor_command_window.back_opacity = 160 @actor_command_window.active = false @actor_command_window.visible = false # その他のウィンドウを作成 @party_command_window = Window_PartyCommand.new @help_window = Window_Help.new @help_window.back_opacity = 160 @help_window.visible = false @status_window = Window_BattleStatus.new @message_window = Window_Message.new # スプライトセットを作成 @spriteset = Spriteset_Battle.new # ウェイトカウントを初期化 @wait_count = 0 # トランジション実行 if $data_system.battle_transition == "" Graphics.transition(20) else Graphics.transition(40, "Graphics/Transitions/" + $data_system.battle_transition) end # プレバトルフェーズ開始 start_phase1 # メインループ loop do # ゲーム画面を更新 Graphics.update # 入力情報を更新 Input.update # フレーム更新 update # 画面が切り替わったらループを中断 if $scene != self break end end # マップをリフレッシュ $game_map.refresh # トランジション準備 Graphics.freeze # ウィンドウを解放 @actor_command_window.dispose @party_command_window.dispose @help_window.dispose @status_window.dispose @message_window.dispose if @skill_window != nil @skill_window.dispose end if @item_window != nil @item_window.dispose end if @result_window != nil @result_window.dispose end # スプライトセットを解放 @spriteset.dispose # タイトル画面に切り替え中の場合 if $scene.is_a?(Scene_Title) # 画面をフェードアウト Graphics.transition Graphics.freeze end # 戦闘テストからゲームオーバー画面以外に切り替え中の場合 if $BTEST and not $scene.is_a?(Scene_Gameover) $scene = nil end end #-------------------------------------------------------------------------- # ● パーティコマンドフェーズ開始 #-------------------------------------------------------------------------- alias start_phase2_actor_change start_phase2 def start_phase2 # メンバーチェンジフラグの解除 for actor in $game_party.actors + $game_party.sub_actors actor.already_change = false end start_phase2_actor_change end #-------------------------------------------------------------------------- # ● フレーム更新 (アクターコマンドフェーズ) #-------------------------------------------------------------------------- alias update_phase3_double_team update_phase3 def update_phase3 if @sub_member_window != nil update_phase3_submember_select else update_phase3_double_team # 原物 end end #-------------------------------------------------------------------------- # ● 前のアクターのコマンド入力へ #-------------------------------------------------------------------------- alias phase3_prior_actor_change phase3_prior_actor def phase3_prior_actor phase3_prior_actor_change # 原物 # メンバー交換の予約解除 if @active_battler.current_action.kind == 3 unless @active_battler.current_action.change_member.nil? @active_battler.current_action.change_member.already_change = false end end end #-------------------------------------------------------------------------- # ● アクターコマンドウィンドウのセットアップ #-------------------------------------------------------------------------- alias phase3_setup_command_window_double_team phase3_setup_command_window def phase3_setup_command_window phase3_setup_command_window_double_team if !Double_Team.can_change? or @active_battler.ch_lock @actor_command_window.disable_item(4) else @actor_command_window.draw_item(4, @actor_command_window.normal_color) end end #-------------------------------------------------------------------------- # ● フレーム更新 (アクターコマンドフェーズ : 基本コマンド) #-------------------------------------------------------------------------- alias update_phase3_basic_command_double_team update_phase3_basic_command def update_phase3_basic_command update_phase3_basic_command_double_team # 原物 # C ボタンが押された場合 if Input.trigger?(Input::C) # アクターコマンドウィンドウのカーソル位置で分岐 case @actor_command_window.index when 4 # パーティー入れ替え if !Double_Team.can_change? or @active_battler.ch_lock # キャンセル SE を演奏 $game_system.se_play($data_system.cancel_se) return end # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) # アクションを設定 @active_battler.current_action.kind = 3 # 入れ替え対象の選択を開始 start_sub_actor_select end return end end #-------------------------------------------------------------------------- # ● フレーム更新 (アクターコマンドフェーズ : 待機メンバー選択) #-------------------------------------------------------------------------- def update_phase3_submember_select # ウィンドウを可視状態にする @sub_member_window.visible = true # ウィンドウを更新 @sub_member_window.update # B ボタンが押された場合 if Input.trigger?(Input::B) # キャンセル SE を演奏 $game_system.se_play($data_system.cancel_se) # 待機メンバーの選択を終了 end_sub_actor_select return end # C ボタンが押された場合 if Input.trigger?(Input::C) # ウィンドウで現在選択されているデータを取得 change_member = @sub_member_window.actor # 変更できない場合 if change_member != nil and (change_member.dead? or change_member.ch_lock) # ブザー SE を演奏 $game_system.se_play($data_system.buzzer_se) return end # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) # アクションを設定 @active_battler.current_action.change_member = change_member # 待機メンバーの予約 change_member.already_change = true unless change_member.nil? # 待機メンバーの選択を終了 end_sub_actor_select # 次のアクターのコマンド入力へ phase3_next_actor return end end #-------------------------------------------------------------------------- # ● 待機メンバー選択開始 #-------------------------------------------------------------------------- def start_sub_actor_select # ウィンドウを作成 @sub_member_window = Window_BttlSubMember.new # アクターコマンドウィンドウを無効化 @actor_command_window.active = false @actor_command_window.visible = false end #-------------------------------------------------------------------------- # ● 待機メンバー選択終了 #-------------------------------------------------------------------------- def end_sub_actor_select # ウィンドウを解放 @sub_member_window.dispose @sub_member_window = nil # アクターコマンドウィンドウを有効化 @actor_command_window.active = true @actor_command_window.visible = true end #-------------------------------------------------------------------------- # ● メインフェーズ開始 #-------------------------------------------------------------------------- alias start_phase4_double_team start_phase4 def start_phase4 start_phase4_double_team # 全員行動済み # 待機メンバーのHP/SP/BP回復 for sub_actor in $game_party.sub_actors next if sub_actor.already_change # 入れ替え対象者は回復させない if Double_Team::SUB_HP sub_actor.hp += (sub_actor.hp * Double_Team::SUB_HP_PER / 100).truncate end if Double_Team::SUB_SP sub_actor.hp += (sub_actor.sp * Double_Team::SUB_SP_PER / 100).truncate end if Double_Team::SUB_BP sub_actor.bp += sub_actor.rest_bp sub_actor.bp = sub_actor.max_bp if sub_actor.bp > sub_actor.max_bp end end end #-------------------------------------------------------------------------- # ● フレーム更新 (メインフェーズ ステップ 2 : アクション開始) #-------------------------------------------------------------------------- def update_phase4_step2 # 強制アクションでなければ unless @active_battler.current_action.forcing # 制約が [敵を通常攻撃する] か [味方を通常攻撃する] の場合 if @active_battler.restriction == 2 or @active_battler.restriction == 3 # アクションに攻撃を設定 @active_battler.current_action.kind = 0 @active_battler.current_action.basic = 0 end # 制約が [行動できない] の場合 if @active_battler.restriction == 4 # アクション強制対象のバトラーをクリア $game_temp.forcing_battler = nil # ステップ 1 に移行 @phase4_step = 1 return end end # 対象バトラーをクリア @target_battlers = [] # アクションの種別で分岐 case @active_battler.current_action.kind when 0 # 基本 make_basic_action_result when 1 # スキル make_skill_action_result when 2 # アイテム make_item_action_result #------------- when 3 # 入れ替え make_change_party_result return #------------- end # ステップ 3 に移行 if @phase4_step == 2 @phase4_step = 3 end end #-------------------------------------------------------------------------- # ● メンバーチェンジアクション 結果作成 #-------------------------------------------------------------------------- def make_change_party_result if @active_battler.is_a?(Game_Enemy) # エネミーは対象外 @phase4_step = 1 return end # 待機メンバー取得 ch_actor = @active_battler.current_action.change_member if ch_actor.nil? if $game_party.actors.size == 1 # 最終メンバーは待機できない @help_window.set_text("これ以上、待機させることはできない!!", 1) else # 待機メンバーへ退避 $game_party.remove_actor(@active_battler.id) $game_party.sub_actors.push(@active_battler) @help_window.set_text("待機", 1) end else # 入れ替え予約解除 ch_actor.already_change = false # 入れ替え実行 $game_party.change_actors(@active_battler.id, ch_actor.id) # ヘルプウィンドウに表示 @help_window.set_text("メンバーチェンジ", 1) end @wait_count = 20 # ステータスウィンドウをリフレッシュ @status_window.refresh # ステップ6に移行 @phase4_step = 6 end end