battle-maiden-mizuki/Scripts/BattleManager.rb
2025-06-17 11:57:06 -05:00

396 lines
16 KiB
Ruby
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#==============================================================================
# ■ 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
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_troop.enemy_names.each do |name|
$game_message.add(sprintf(Vocab::Emerge, name))
end
if @preemptive
$game_message.add(sprintf(Vocab::Preemptive, $game_party.name))
elsif @surprise
$game_message.add(sprintf(Vocab::Surprise, $game_party.name))
end
wait_for_message
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
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)
revive_battle_members
replay_bgm_and_bgs
SceneManager.return
$game_switches[296]=true
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
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
end
#--------------------------------------------------------------------------
# ● ターン終了
#--------------------------------------------------------------------------
def self.turn_end
@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