#################### 戦闘開始時に先制攻撃を設定可能にする #################### # # # 戦闘時に「先制攻撃」の設定が行えるようになります。 # # 先制攻撃に成功した側は最初のターンに一方的に攻撃が可能になります。 # # ステートによる補正にも対応しており、計算式を各自設定可能にしてあります。 # # そのため、詳しい計算の解説はできませんが、以下の設定を行うことで # # 戦闘時の先制攻撃の強制などは意図的に設定可能です。 # # # # 変数IDがFORCE_FA_VARIABLE(デフォルトでは1)の値を参照することで、 # # イベント戦などの場合の先制攻撃の設定が可能です。 # # 戦闘を行う前に、「変数ID 1」の値を「1」にすれば、通常通り戦闘が、 # # 「2」にすればアクター側の先制から、「3」にすればエネミー側の先制から # # といったように、任意に設定が可能です。 # # # ############################################################################## # ココから設定 module Annex # 先制攻撃計算に影響するステート名一覧 # 「名前 => 先制補正値」のハッシュ形式 FA_STATE_NAMES = { "電光石火" => 10, "鈍足化" => -10 } # 先制攻撃を強制する際に使うフラグの変数 # このIDの変数の値によって強制力が変化する # 0 : 通常通り計算 # 1 : 先制攻撃計算を行わない # 2 : 必ずアクター側の先制攻撃 # 3 : 必ずエネミー側の先制攻撃 FORCE_FA_VARIABLE = 1 # アクター先制時のテキスト FIRST_ATTACK_ACTOR = "先制攻撃に成功した!" # エネミー先制時のテキスト FIRST_ATTACK_ENEMY = "魔物がいきなり襲い掛かってきた!" end # 一応ココまで設定、ただし計算式を調節したい人はもう少し。 # 以下に先制攻撃の成功率などの計算式だけを上に持ってきました。 # 調節したい人はサンプルなどを参考に作成してください。 class Scene_Battle #-------------------------------------------------------------------------- # ◎ 追加:先制攻撃の計算式 # return 1 : アクター先制 # return 0 : 通常通り # return -1 : エネミー先制 #-------------------------------------------------------------------------- def first_attack_calculate # とりあえずサンプルとしての計算式 # 両方とも素早さ合計を出す。 # 計算開始 # 全員のステートと計算を確認する # アクター側 actor_size = 0 actors_agi = 0 actor_correct = 0 for actor in $game_party.actors next if not actor.exist? # 生存していない場合はスルー actor_size += 1 # 人数の増加 if actor.movable? # 行動可能ならばAGIを増加させる actors_agi += actor.agi end # ステート補正チェック actor_correct += actor.first_attack_state_check end # 敵側 enemy_size = 0 enemies_agi = 0 enemy_correct = 0 for enemy in $game_troop.enemies next if not enemy.exist? # 不可視の場合などはスルー enemy_size += 1 # 人数の増加 if enemy.movable? # 行動可能ならばAGIを増加させる enemies_agi += enemy.agi end # ステート補正チェック enemy_correct += actor.first_attack_state_check end actors = actors_agi * (100 + actor_correct) / 100 enemies = enemies_agi * (100 + enemy_correct) / 100 # 全員の素早さの平均値を算出 avg = (actors_agi + enemies_agi) / (actor_size + enemy_size) # この「平均値」以上の差がある場合 if actors > enemies + avg actor_rate = 15 # 先制攻撃 15% enemy_rate = 3 # 不意打ち 3% # アクターのAGIのが高いけど平均値ほどの差が無い場合 elsif actors >= enemies actor_rate = 10 # 先制攻撃 10% enemy_rate = 5 # 不意打ち 5% # エネミーのAGIが平均値以上大きい場合 elsif actors + avg <= enemies actor_rate = 3 # 先制攻撃 3% enemy_rate = 15 # 不意打ち 15% # その他 (エネミーのAGIが大きいけど差が平均値以下) else actor_rate = 5 # 先制攻撃 5% enemy_rate = 10 # 不意打ち 10% end # 先にアクター側の先制攻撃計算を実行 if rand(100) < actor_rate return 1 end # エネミー側の先制攻撃計算を実行 if rand(100) < enemy_rate return -1 end # 通常通り return 0 end end # ココまでが計算式設定 #============================================================================== # ■ Game_Battler #============================================================================== class Game_Battler #-------------------------------------------------------------------------- # ◎ 追加:先制攻撃に関係したステートにかかっているかの確認 # battler : バトラー #-------------------------------------------------------------------------- def first_attack_state_check correct = 0 # 先制攻撃に関係したステート名を順にまわしていく for name in Annex::FA_STATE_NAMES.keys if state_name?(name) # ステートにかかっていた場合その値を足す correct += Annex::FA_STATE_NAMES[name] end end return correct end #-------------------------------------------------------------------------- # ◎ 追加 指定された名前のステートのIDを取得 # state_name : ステート名 #-------------------------------------------------------------------------- def get_state_id(state_name) for i in $data_states next if i == nil if i.name == state_name return (i.id) end end return 0 end #-------------------------------------------------------------------------- # ◎ 追加 指定された名前のステートになっているかの確認 # state_name : ステート名 #-------------------------------------------------------------------------- def state_name?(state_name) id = get_state_id(state_name) return state?(id) end end #============================================================================== # ■ Scene_Battle #============================================================================== class Scene_Battle #-------------------------------------------------------------------------- # ○ プレバトルフェーズ開始 #-------------------------------------------------------------------------- alias first_attack_start_phase1 start_phase1 def start_phase1 # 呼び戻し first_attack_start_phase1 # フラグ設定 @first_attack = false # 先制攻撃計算を行う first_attack_flag = check_first_attack case first_attack_flag when -1 # 15 フレーム待つ @wait_count = 15 @help_window.set_text(Annex::FIRST_ATTACK_ENEMY, 1) # 敵先制ならばいきなり メインフェーズ へ以降 start_phase4 when 1 # 15 フレーム待つ @wait_count = 15 @help_window.set_text(Annex::FIRST_ATTACK_ACTOR, 1) # 味方先制ならば @enemy_attack_flag を false に設定 @first_attack = true end end #-------------------------------------------------------------------------- # ◎ 追加:先制攻撃判定 #-------------------------------------------------------------------------- def check_first_attack # 変数を確認して先制が強制されているかの確認 case $game_variables[Annex::FORCE_FA_VARIABLE] when 1 # 先制攻撃の計算を行わない return 0 when 2 # アクターの強制先制攻撃 return 1 when 3 # エネミーの強制先制攻撃 return -1 end # 先制攻撃の計算式を呼び出し first_attacker = first_attack_calculate return first_attacker end #-------------------------------------------------------------------------- # ○ パーティコマンドフェーズ開始 #-------------------------------------------------------------------------- alias first_attack_start_phase2 start_phase2 def start_phase2 # ヘルプウィンドウを不可視に @help_window.visible = false first_attack_start_phase2 end #-------------------------------------------------------------------------- # ○ フレーム更新 (パーティコマンドフェーズ : 逃げる) #-------------------------------------------------------------------------- alias first_attack_update_phase2_escape update_phase2_escape def update_phase2_escape # 先制攻撃の場合、逃走は 100% 成功する if @first_attack # 逃走 SE を演奏 $game_system.se_play($data_system.escape_se) # バトル開始前の BGM に戻す $game_system.bgm_play($game_temp.map_bgm) # バトル終了 battle_end(1) return end # 呼び戻し first_attack_update_phase2_escape end #-------------------------------------------------------------------------- # ○ 行動順序作成 #-------------------------------------------------------------------------- alias first_attack_make_action_orders make_action_orders def make_action_orders # 呼び戻し first_attack_make_action_orders # 先制攻撃した場合 if @first_attack # @action_battlers(行動する人を順に並べた配列) からエネミーを削除 @action_battlers.reject!{|a| a.is_a?(Game_Enemy)} @first_attack = false end end end