#============================================================================== # ■ BattleManager #------------------------------------------------------------------------------ #  戦闘の進行を管理するモジュールです。 #============================================================================== module BattleManager #-------------------------------------------------------------------------- # ● セットアップ #-------------------------------------------------------------------------- def self.setup(troop_id, can_escape = true, can_lose = false) init_members $game_troop.setup(troop_id) @can_escape = can_escape @can_lose = can_lose make_escape_ratio end #-------------------------------------------------------------------------- # ● メンバ変数の初期化 #-------------------------------------------------------------------------- def self.init_members @phase = :init # 戦闘進行フェーズ @can_escape = false # 逃走可能フラグ @can_lose = false # 敗北可能フラグ @event_proc = nil # イベント用コールバック @preemptive = false # 先制攻撃フラグ @surprise = false # 不意打ちフラグ @actor_index = -1 # コマンド入力中のアクター @action_forced = nil # 戦闘行動の強制 @map_bgm = nil # 戦闘前の BGM 記憶用 @map_bgs = nil # 戦闘前の BGS 記憶用 @action_battlers = [] # 行動順序リスト end #-------------------------------------------------------------------------- # ● エンカウント時の処理 #-------------------------------------------------------------------------- def self.on_encounter @preemptive = (rand < rate_preemptive) @surprise = (rand < rate_surprise && !@preemptive) end #-------------------------------------------------------------------------- # ● 先制攻撃の確率取得 #-------------------------------------------------------------------------- def self.rate_preemptive $game_party.rate_preemptive($game_troop.agi) end #-------------------------------------------------------------------------- # ● 不意打ちの確率取得 #-------------------------------------------------------------------------- def self.rate_surprise $game_party.rate_surprise($game_troop.agi) end #-------------------------------------------------------------------------- # ● BGM と BGS の保存 #-------------------------------------------------------------------------- def self.save_bgm_and_bgs @map_bgm = RPG::BGM.last @map_bgs = RPG::BGS.last end #-------------------------------------------------------------------------- # ● 戦闘 BGM の演奏 #-------------------------------------------------------------------------- def self.play_battle_bgm $game_system.battle_bgm.play RPG::BGS.stop end #-------------------------------------------------------------------------- # ● 戦闘終了 ME の演奏 #-------------------------------------------------------------------------- def self.play_battle_end_me $game_system.battle_end_me.play end #-------------------------------------------------------------------------- # ● BGM と BGS の再開 #-------------------------------------------------------------------------- def self.replay_bgm_and_bgs @map_bgm.replay unless $BTEST @map_bgs.replay unless $BTEST end #-------------------------------------------------------------------------- # ● 逃走成功率の作成 #-------------------------------------------------------------------------- def self.make_escape_ratio # @escape_ratio = 1.5 - 1.0 * $game_troop.agi / $game_party.agi @escape_ratio = 1 end #-------------------------------------------------------------------------- # ● ターン実行中判定 #-------------------------------------------------------------------------- def self.in_turn? @phase == :turn end #-------------------------------------------------------------------------- # ● ターン終了中判定 #-------------------------------------------------------------------------- def self.turn_end? @phase == :turn_end end #-------------------------------------------------------------------------- # ● 戦闘中断判定 #-------------------------------------------------------------------------- def self.aborting? @phase == :aborting end #-------------------------------------------------------------------------- # ● 逃走許可の取得 #-------------------------------------------------------------------------- def self.can_escape? @can_escape end #-------------------------------------------------------------------------- # ● コマンド入力中のアクターを取得 #-------------------------------------------------------------------------- def self.actor @actor_index >= 0 ? $game_party.members[@actor_index] : nil end #-------------------------------------------------------------------------- # ● コマンド入力中のアクターをクリア #-------------------------------------------------------------------------- def self.clear_actor @actor_index = -1 end #-------------------------------------------------------------------------- # ● 次のコマンド入力へ #-------------------------------------------------------------------------- def self.next_command begin if !actor || !actor.next_command @actor_index += 1 return false if @actor_index >= $game_party.members.size end end until actor.inputable? return true end #-------------------------------------------------------------------------- # ● 前のコマンド入力へ #-------------------------------------------------------------------------- def self.prior_command begin if !actor || !actor.prior_command @actor_index -= 1 return false if @actor_index < 0 end end until actor.inputable? return true end #-------------------------------------------------------------------------- # ● イベントへのコールバック用 Proc の設定 #-------------------------------------------------------------------------- def self.event_proc=(proc) @event_proc = proc end #-------------------------------------------------------------------------- # ● ウェイト用メソッドの設定 #-------------------------------------------------------------------------- def self.method_wait_for_message=(method) @method_wait_for_message = method end #-------------------------------------------------------------------------- # ● メッセージ表示が終わるまでウェイト #-------------------------------------------------------------------------- def self.wait_for_message @method_wait_for_message.call if @method_wait_for_message end #-------------------------------------------------------------------------- # ● 戦闘開始 #-------------------------------------------------------------------------- def self.battle_start $game_system.battle_count += 1 $game_party.on_battle_start $game_troop.on_battle_start $game_switches[200] = true $game_switches[969] = true $game_switches[501] = true $game_troop.enemy_names.each do |name| $game_message.add(sprintf(Vocab::Emerge, name)) end end #-------------------------------------------------------------------------- # ● 戦闘中断 #-------------------------------------------------------------------------- def self.abort @phase = :aborting end #-------------------------------------------------------------------------- # ● 勝敗判定 #-------------------------------------------------------------------------- def self.judge_win_loss if @phase return process_abort if $game_party.members.empty? return process_defeat if $game_party.all_dead? return process_victory if $game_troop.all_dead? return process_abort if aborting? end return false end #-------------------------------------------------------------------------- # ● 勝利の処理 #-------------------------------------------------------------------------- def self.process_victory $game_temp.reserve_common_event(399) play_battle_end_me replay_bgm_and_bgs $game_message.add(sprintf(Vocab::Victory, $game_party.name)) display_exp gain_gold gain_drop_items gain_exp SceneManager.return battle_end(0) return true end #-------------------------------------------------------------------------- # ● 逃走の処理 #-------------------------------------------------------------------------- def self.process_escape $game_message.add(sprintf(Vocab::EscapeStart, $game_party.name)) success = @preemptive ? true : (rand < @escape_ratio) Sound.play_escape if success process_abort else # @escape_ratio += 0.1 $game_message.add('\.' + Vocab::EscapeFailure) $game_party.clear_actions end wait_for_message return success end #-------------------------------------------------------------------------- # ● 中断の処理 #-------------------------------------------------------------------------- def self.process_abort replay_bgm_and_bgs SceneManager.return battle_end(1) return true end #-------------------------------------------------------------------------- # ● 敗北の処理 #-------------------------------------------------------------------------- def self.process_defeat $game_message.add(sprintf(Vocab::Defeat, $game_party.name)) wait_for_message if @can_lose revive_battle_members replay_bgm_and_bgs SceneManager.return else SceneManager.goto(Scene_Gameover) end battle_end(2) return true end #-------------------------------------------------------------------------- # ● 戦闘メンバーの復活(敗北時) #-------------------------------------------------------------------------- def self.revive_battle_members $game_party.battle_members.each do |actor| actor.hp = 1 if actor.dead? end end #-------------------------------------------------------------------------- # ● 戦闘終了 # result : 結果(0:勝利 1:逃走 2:敗北) #-------------------------------------------------------------------------- def self.battle_end(result) @phase = nil @event_proc.call(result) if @event_proc $game_party.on_battle_end $game_troop.on_battle_end SceneManager.exit if $BTEST $game_timer.stop $game_switches[200] = false $game_switches[900] = false $game_switches[501] = false end #-------------------------------------------------------------------------- # ● コマンド入力開始 #-------------------------------------------------------------------------- def self.input_start if @phase != :input @phase = :input $game_party.make_actions $game_troop.make_actions clear_actor end return !@surprise && $game_party.inputable? end #-------------------------------------------------------------------------- # ● ターン開始 #-------------------------------------------------------------------------- def self.turn_start @phase = :turn clear_actor $game_troop.increase_turn make_action_orders # $game_temp.reserve_common_event(103) end #-------------------------------------------------------------------------- # ● ターン終了 #-------------------------------------------------------------------------- def self.turn_end # $game_temp.reserve_common_event(104) @phase = :turn_end @preemptive = false @surprise = false end #-------------------------------------------------------------------------- # ● 獲得した経験値の表示 #-------------------------------------------------------------------------- def self.display_exp if $game_troop.exp_total > 0 text = sprintf(Vocab::ObtainExp, $game_troop.exp_total) $game_message.add('\.' + text) end end #-------------------------------------------------------------------------- # ● お金の獲得と表示 #-------------------------------------------------------------------------- def self.gain_gold if $game_troop.gold_total > 0 text = sprintf(Vocab::ObtainGold, $game_troop.gold_total) $game_message.add('\.' + text) $game_party.gain_gold($game_troop.gold_total) end wait_for_message end #-------------------------------------------------------------------------- # ● ドロップアイテムの獲得と表示 #-------------------------------------------------------------------------- def self.gain_drop_items $game_troop.make_drop_items.each do |item| $game_party.gain_item(item, 1) $game_message.add(sprintf(Vocab::ObtainItem, item.name)) end wait_for_message end #-------------------------------------------------------------------------- # ● 経験値の獲得とレベルアップの表示 #-------------------------------------------------------------------------- def self.gain_exp $game_party.all_members.each do |actor| actor.gain_exp($game_troop.exp_total) end wait_for_message end #-------------------------------------------------------------------------- # ● 行動順序の作成 #-------------------------------------------------------------------------- def self.make_action_orders @action_battlers = [] @action_battlers += $game_party.members unless @surprise @action_battlers += $game_troop.members unless @preemptive @action_battlers.each {|battler| battler.make_speed } @action_battlers.sort! {|a,b| b.speed - a.speed } end #-------------------------------------------------------------------------- # ● 戦闘行動の強制 #-------------------------------------------------------------------------- def self.force_action(battler) @action_forced = battler @action_battlers.delete(battler) end #-------------------------------------------------------------------------- # ● 戦闘行動の強制状態を取得 #-------------------------------------------------------------------------- def self.action_forced? @action_forced != nil end #-------------------------------------------------------------------------- # ● 戦闘行動が強制されたバトラーを取得 #-------------------------------------------------------------------------- def self.action_forced_battler @action_forced end #-------------------------------------------------------------------------- # ● 戦闘行動の強制をクリア #-------------------------------------------------------------------------- def self.clear_action_force @action_forced = nil end #-------------------------------------------------------------------------- # ● 次の行動主体の取得 # 行動順序リストの先頭からバトラーを取得する。 # 現在パーティにいないアクターを取得した場合(index が nil, バトルイベ # ントでの離脱直後などに発生)は、それをスキップする。 #-------------------------------------------------------------------------- def self.next_subject loop do battler = @action_battlers.shift return nil unless battler next unless battler.index && battler.alive? return battler end end end