#============================================================================== # ■ エネミー行動なかなか賢く Ver0.43  By むー #------------------------------------------------------------------------------ # 敵の行動を賢くします。リアルタイムに対応しました。 #------------------------------------------------------------------------------ # # ★簡単な仕様★ # #  本来、データベースでエネミーの行動を指定する際の条件は、 #  そのエネミーがどのような状態か、です。 #  HP20%〜60%などのように指定すると、そのエネミーのHPを参考にします。 #  このスクリプトでは、それを敵の味方(Troop)全体で判断します。 #  HP20%〜60%などのように指定すると、敵グループの中で該当者がいないかを探し、 #  いればその行動を、その該当者に対しておこなうようになります。 #  行動はリアルタイムです。 # # ★条件★ # #  HP、MP、ステートのみ有効です。 #  ターン、パーティレベル、スイッチは、賢い行動の元になりません。 # # ★設定方法★ # #  本スクリプト内で設定する場所はありません。 #  データベースの敵キャラの行動パターンに設定します。 #  賢い行動をさせたい行動の優先度(Rate)を10にしてください。 #  行動の優先順位は、行動一覧の上からになります。 # #  以前に公開した「エネミー行動ちょっと賢く」をお使いの場合、 #  スクリプトだけ入れ替えれば、データベースの敵キャラ設定はそのままで構いません。 #  ただ、今回は優先順位がありますので、必要な場合は順番だけ変えてください。 # # ★注意点★ # #  マナドレインなどのような吸収技には注意してください。 #  使用者に掛かる回復技を、例えばMP0%〜50%、優先度10などのように指定した場合、 #  MPが減っている味方がいる限り使い続けてしまいます。 #  減っているのは味方の誰かでも、回復するのは自分なので...。 # #============================================================================== $moo_enemy_clever = true module MOO_ENEMY_CLEVER #-------------------------------------------------------------------------- # 設定箇所はありません。以下は通常、変更しないで下さい。 #-------------------------------------------------------------------------- # 本スクリプトを使う場合(何かあって止めたい時) USE = true # 強制する行動のレート(変更しないでください) ACT_RATE = 10 end #============================================================================== # ■ Game_Enemy #------------------------------------------------------------------------------ #  敵キャラを扱うクラスです。このクラスは Game_Troop クラス($game_troop)の # 内部で使用されます。 #============================================================================== class Game_Enemy < Game_Battler #-------------------------------------------------------------------------- # ◎ 現在の状況で戦闘行動が有効か否かを判定 # action : RPG::Enemy::Action #-------------------------------------------------------------------------- alias moo_enemy_clever_action_valid? action_valid? def action_valid?(action) # 優先度10(指定値)は通常行動から除く return false if action.rating == MOO_ENEMY_CLEVER::ACT_RATE moo_enemy_clever_action_valid?(action) end end #============================================================================== # ■ Scene_Battle #------------------------------------------------------------------------------ #  バトル画面の処理を行うクラスです。 #============================================================================== class Scene_Battle < Scene_Base #-------------------------------------------------------------------------- # ○ 定数 (特徴) #-------------------------------------------------------------------------- FEATURE_STYPE_SEAL = 42 # スキルタイプ封印 FEATURE_SKILL_SEAL = 44 # スキル封印 #-------------------------------------------------------------------------- # ○ 強制行動のレートを取得 #-------------------------------------------------------------------------- def moo_enemy_clever_rate MOO_ENEMY_CLEVER::ACT_RATE end #-------------------------------------------------------------------------- # ○ 賢い行動システム #-------------------------------------------------------------------------- def moo_enemy_clever_change # 配列変数初期化 act_list = [] return_array = [0, -1] # 行動の数だけループ if $data_enemies[@subject.enemy_id].actions.size > 0 for act in $data_enemies[@subject.enemy_id].actions # レート10の中で使用可能な行動だけを拾って配列に追加 skill = $data_skills[act.skill_id] act_list << act if act.rating == moo_enemy_clever_rate and moo_enemy_clever_valid?(skill) end end # レート10の行動がない場合は終了 return return_array if act_list.size == 0 # 使用可能なレート10の行動の数だけループ for item in act_list # スキルに対してのターゲット取得 en_list = moo_enemy_clever_troop_check(item) # ターゲットがいた場合 if en_list.size != 0 # ターゲットをランダムにする en_list = en_list.sort_by{rand} # スキルとターゲットを格納 return_array[0] = item.skill_id return_array[1] = en_list[0] break end end # 返す return return_array end #-------------------------------------------------------------------------- # ○ エネミーがスキルを使用可能かチェック #-------------------------------------------------------------------------- def moo_enemy_clever_valid?(skill) moo_enemy_clever_movable? and # 動けるか? moo_enemy_clever_cost?(skill) and # MP/TPが足りているか? !moo_enemy_clever_skill_sealed?(skill.id) and # スキル封印は? !moo_enemy_clever_skill_type_sealed?(skill.stype_id) # スキルタイプ封印は? end #-------------------------------------------------------------------------- # ○ 行動可能かチェック #-------------------------------------------------------------------------- def moo_enemy_clever_movable? @subject.movable? end #-------------------------------------------------------------------------- # ○ スキルのコストが足りているかチェック(MPとTP) #-------------------------------------------------------------------------- def moo_enemy_clever_cost?(skill) s_mcr = @subject.mcr s_mpc = (skill.mp_cost * s_mcr).to_i s_tpc = skill.tp_cost @subject.tp >= s_tpc && @subject.mp >= s_mpc end #-------------------------------------------------------------------------- # ○ 現在のステートをオブジェクトの配列で取得 #-------------------------------------------------------------------------- def moo_enemy_clever_states # ファイ列変数初期化 st = [] # 掛かっているステートを列挙 for i in @subject.states st << i.id end st.collect {|id| $data_states[id] } end #-------------------------------------------------------------------------- # ○ 特徴を保持する全オブジェクトの配列取得 #-------------------------------------------------------------------------- def moo_enemy_clever_feature_objects moo_enemy_clever_states end #-------------------------------------------------------------------------- # ○ 全ての特徴オブジェクトの配列取得 #-------------------------------------------------------------------------- def moo_enemy_clever_all_features moo_enemy_clever_feature_objects.inject([]) {|r, obj| r + obj.features } end #-------------------------------------------------------------------------- # ○ 特徴オブジェクトの配列取得(特徴コードを限定) #-------------------------------------------------------------------------- def moo_enemy_clever_features(code) moo_enemy_clever_all_features.select {|ft| ft.code == code } end #-------------------------------------------------------------------------- # ○ 特徴の集合和計算 #-------------------------------------------------------------------------- def moo_enemy_clever_features_set(code) moo_enemy_clever_features(code).inject([]) {|r, ft| r |= [ft.data_id] } end #-------------------------------------------------------------------------- # ○ スキルタイプ封印の判定 #-------------------------------------------------------------------------- def moo_enemy_clever_skill_type_sealed?(stype_id) moo_enemy_clever_features_set(FEATURE_STYPE_SEAL).include?(stype_id) end #-------------------------------------------------------------------------- # ○ スキル封印の判定 #-------------------------------------------------------------------------- def moo_enemy_clever_skill_sealed?(skill_id) moo_enemy_clever_features_set(FEATURE_SKILL_SEAL).include?(skill_id) end #-------------------------------------------------------------------------- # ○ スキルを使う条件に当てはまるかの判定 #-------------------------------------------------------------------------- def moo_enemy_clever_troop_check(item) # 変数初期化 target_en = [] # パラメータ格納 p1 = item.condition_param1 p2 = item.condition_param2 # 敵グループのエネミー分ループ for en in $game_troop.members # アクションの条件によって分岐 case item.condition_type when 2 # HPが条件 target_en << en.index if moo_enemy_clever_conditions_met_hp?(en, p1, p2) when 3 # MPが条件 target_en << en.index if moo_enemy_clever_conditions_met_mp?(en, p1, p2) when 4 # ステートが条件 target_en << en.index if moo_enemy_clever_conditions_met_state?(en, p1, p2) end end # 返す return target_en end #-------------------------------------------------------------------------- # ○ 行動条件合致判定 [HP] #-------------------------------------------------------------------------- def moo_enemy_clever_conditions_met_hp?(enemy, param1, param2) val = enemy.hp.to_f / enemy.mhp val >= param1 && val <= param2 end #-------------------------------------------------------------------------- # ○ 行動条件合致判定 [MP] #-------------------------------------------------------------------------- def moo_enemy_clever_conditions_met_mp?(enemy, param1, param2) val = enemy.mp.to_f / enemy.mmp val >= param1 && val <= param2 end #-------------------------------------------------------------------------- # ○ 行動条件合致判定 [ステート] #-------------------------------------------------------------------------- def moo_enemy_clever_conditions_met_state?(enemy, param1, param2) # ステートに掛かっていない場合はfalseを返す return false if enemy.states.size == 0 # 配列変数初期化 st = [] # 掛かっているステートを列挙 for state in enemy.states st << state.id end # スキル発動条件のステートに掛かっているか st.include?(param1) end #-------------------------------------------------------------------------- # ◎ 戦闘行動の実行 #-------------------------------------------------------------------------- alias moo_enemy_clever_execute_action execute_action def execute_action if MOO_ENEMY_CLEVER::USE and @subject.class == Game_Enemy @subject.sprite_effect_type = :whiten moo_enemy_clever_use_item @log_window.wait_and_clear else moo_enemy_clever_execute_action end end #-------------------------------------------------------------------------- # ○ パーティメンバーへのターゲットをランダムに決定 #-------------------------------------------------------------------------- def moo_enemy_clever_random_actors(count) actor = [] for i in 1..count actor << $game_party.members[rand($game_party.members.length)] end return actor end #-------------------------------------------------------------------------- # ○ スキル/アイテムの使用(元をコピーして作り替え) #-------------------------------------------------------------------------- def moo_enemy_clever_use_item # 変数初期化 skill_target = [0, -1] # エネミーの行動の場合 if @subject.class == Game_Enemy skill_target = moo_enemy_clever_change end # エネミーの行動を指定 item = @subject.current_action.item if skill_target[0] == 0 item = $data_skills[skill_target[0]] if skill_target[0] != 0 # 以下3行は通常処理 @log_window.display_use_item(@subject, item) @subject.use_item(item) refresh_status # まずはデフォルトのターゲット設定 targets = @subject.current_action.make_targets.compact # 賢い行動対象の場合 if skill_target[0] != 0 and skill_target[1] != -1 # ターゲット設定(強制行動のみ) case $data_skills[skill_target[0]].scope when 0 # なし targets = [] when 1 # 敵単体の場合は敵(アクター)ランダム1体 targets = moo_enemy_clever_random_actors(1) when 2 # 敵全体の場合は敵(アクター)全体 targets = $game_party.members when 3 # 敵ランダム1体の場合は敵(アクター)ランダム1体 targets = moo_enemy_clever_random_actors(1) when 4 # 敵ランダム2体の場合は敵(アクター)ランダム2体 targets = moo_enemy_clever_random_actors(2) when 5 # 敵ランダム3体の場合は敵(アクター)ランダム3体 targets = moo_enemy_clever_random_actors(3) when 6 # 敵ランダム4体の場合は敵(アクター)ランダム4体 targets = moo_enemy_clever_random_actors(4) when 7, 9 # 味方1体の場合は味方(エネミー)単体 targets = [$game_troop.members[skill_target[1]]] when 8, 10 # 味方全体の場合は味方(エネミー)全体 targets = $game_troop.members when 11 # 使用者の場合は使用者 targets = [@subject] end end # 以下通常処理 show_animation(targets, item.animation_id) targets.each {|target| item.repeats.times { invoke_item(target, item) } } end end