#============================================================================== # ■ XP-RGSS-47 オート行動キャラクタ [Ver.1.0.0] by Claimh #------------------------------------------------------------------------------ # 特定のキャラクタのみオート行動させることが出来ます。 #------------------------------------------------------------------------------ # ● オート行動者の変更(イベントコマンド) # $game_actors[アクターID].auto_play = true/false # true :オート行動者に設定 # false ;オート行動者を解除 #------------------------------------------------------------------------------ # ● オート行動者の変更 # 設定カスタマイズで設定しているPT_SW[アクターID]で指定した変数を変更する。 # 対応する行動パターンが設定されていないと「何もしない」 #============================================================================== module AutoPlayer AUTO_MODE = [] PT_SW = [] RATING_PLUS = 5 RETRY_TIME = 10 #------------------------------------------------------------------------------ # ★設定カスタマイズ #------------------------------------------------------------------------------ # 初期状態からオート行動キャラクタ # AUTO_PLAYER = [アクターID,・・・] AUTO_PLAYER = [1, 3] # オート行動パターン切り替え用変数 # PT_SW[アクターID] = 変数ID PT_SW[1] = 1 PT_SW[2] = 2 PT_SW[3] = 3 PT_SW[4] = 4 # 瀕死条件と判定するHP(%) CRISIS = 25 #----------------------------------------------------------- # ◆オート行動パターン設定 # 行動パターンの設定です。 # レーティングに応じて行動をランダムに行動します。 # 行動優先条件に適合する際は設定されたレーティング+5 #----------------------------------------------------------- # 定数名 = [ # レーティング(1〜10), # 行動優先条件(0:指定なし, 1:味方ピンチ, 2:敵が瀕死状態), # 行動種類(0:通常攻撃, 1:防御, 2:スキル, 3:アイテム), # 使用スキルID or 使用アイテムID(通常攻撃、防御の場合はnil), # ターゲット選択条件(0:ランダム, 1:残HPの低い者, 2:残HPの高い者) # ] #---------アクター1---------# # アクター1:パターン0 AT_PATTERN_1_0 = [ [5, 0, 0, nil, 0], # レーティング5:条件なし:通常攻撃:ランダム [2, 0, 2, 57, 2], # レーティング2:条件なし:スキル:クロスカット;残HP高 [1, 0, 1, nil, 0] # レーティング1:条件なし:防御 ] # アクター1:パターン1 AT_PATTERN_1_1 = [ [2, 0, 0, nil, 0], # レーティング2:条件なし:通常攻撃:ランダム [5, 0, 2, nil, 0] # レーティング5:条件なし:防御 ] #---------アクター2---------# # アクター2:パターン0 AT_PATTERN_2_0 = [ [5, 0, 0, nil, 0], # レーティング5:条件なし:通常攻撃:ランダム [1, 0, 0, nil, 1], # レーティング1:条件なし:防御 [2, 0, 2, 7, 2] # レーティング2:条件なし:スキル:ファイア;残HP高 ] # アクター2:パターン1 AT_PATTERN_2_1 = [ [2, 0, 0, nil, 0], # レーティング2:条件なし:通常攻撃:ランダム [5, 0, 2, nil, 0] # レーティング5:条件なし:防御 ] #---------アクター3---------# # アクター3:パターン0 AT_PATTERN_3_0 = [ [5, 0, 0, nil, 1], # レーティング5:条件なし:通常攻撃:残HP低 [2, 0, 1, nil, 0], # レーティング2:条件なし:防御 [3, 1, 2, 1, 1] # レーティング3:味方ピンチ:スキル:ヒール:残HP低 ] # アクター3:パターン1 AT_PATTERN_3_1 = [ [2, 0, 1, nil, 0], # レーティング2:条件なし:防御 [5, 1, 2, 1, 1] # レーティング5:味方ピンチ:スキル:ヒール:残HP低 ] #---------アクター4---------# # アクター4:パターン0 AT_PATTERN_4_0 = [ [5, 0, 0, nil, 1], # レーティング5:条件なし:通常攻撃:残HP低 [3, 2, 0, nil, 1], # レーティング2:敵瀕死:通常攻撃:残HP低 [1, 0, 1, nil, 0] # レーティング1:条件なし:防御 ] # アクター4:パターン1 AT_PATTERN_4_1 = [ [2, 0, 0, nil, 1], # レーティング2:条件なし:通常攻撃:残HP低 [5, 0, 2, nil, 0] # レーティング5:条件なし:防御 ] #----------------------------------------------------------- # ◆オート行動設定 # 各キャラクタの行動パターンの設定 #----------------------------------------------------------- # AUTO_MODE[アクターID] = { # PT_SW[アクターID]で指定した変数の値 => [オート行動パターン] # } # アクター1 AUTO_MODE[1] = { 0 => AT_PATTERN_1_0, # アクター1:パターン0 1 => AT_PATTERN_1_1 # アクター1:パターン1 } # アクター2 AUTO_MODE[2] = { 0 => AT_PATTERN_2_0, # アクター2:パターン0 1 => AT_PATTERN_2_1 # アクター2:パターン1 } # アクター3 AUTO_MODE[3] = { 0 => AT_PATTERN_3_0, # アクター3:パターン0 1 => AT_PATTERN_3_1 # アクター3:パターン1 } # アクター4 AUTO_MODE[4] = { 0 => AT_PATTERN_4_0, # アクター4:パターン0 1 => AT_PATTERN_4_1 # アクター4:パターン1 } #------------------------------------------------------------------------------ end #============================================================================== # ■ Scene_Battle #============================================================================== class Game_Actor < Game_Battler #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :auto_play # オート行動 #-------------------------------------------------------------------------- # ● オブジェクト初期化 # actor_id : アクター ID #-------------------------------------------------------------------------- alias init_auto_chara initialize def initialize(actor_id) init_auto_chara(actor_id) @auto_play = AutoPlayer::AUTO_PLAYER.include?(actor_id) end #-------------------------------------------------------------------------- # ● コマンド入力可能判定 #-------------------------------------------------------------------------- def inputable? ret = super ret = false if @auto_play return ret end end #============================================================================== # ■ Scene_Battle #============================================================================== class Scene_Battle #-------------------------------------------------------------------------- # ● フレーム更新 (メインフェーズ ステップ 2 : アクション開始) #-------------------------------------------------------------------------- alias update_phase4_step2_auto_player update_phase4_step2 def update_phase4_step2 # オート行動者か? if @active_battler.is_a?(Game_Actor) and @active_battler.auto_play make_auto_player_actions end update_phase4_step2_auto_player end #-------------------------------------------------------------------------- # ● オート行動者の行動選択 #-------------------------------------------------------------------------- def make_auto_player_actions # 行動パターン抽出 action_motion = at_judge_auto_pattern? return if action_motion.nil? # 抽出失敗 # 行動が決まるまでリトライ(RETRY_TIMEまで) for i in 0...AutoPlayer::RETRY_TIME # 行動判定処理 action = make_auto_play_pattern(action_motion) # 行動パターンが設定されていない if action.nil? # 何もしない @active_battler.current_action.kind = 0 @active_battler.current_action.basic = 3 return end # 行動設定処理 ret = make_auto_play_motion(action) return if ret # 正常終了 end # 行動選択に失敗 = 何もしない ## 味方全員生存している状態で、味方(HP0)対象のスキル、アイテムが ## 連続して発生しない限りここにはこない。 ## 安全策のために何もしないを入れておく。 @active_battler.current_action.kind = 0 @active_battler.current_action.basic = 3 end #-------------------------------------------------------------------------- # ● 行動パターン抽出 #-------------------------------------------------------------------------- def at_judge_auto_pattern? # 行動が設定されていない vari = $game_variables[AutoPlayer::PT_SW[@active_battler.id]] if AutoPlayer::AUTO_MODE[@active_battler.id].nil? or vari.nil? # 何もしない @active_battler.current_action.kind = 0 @active_battler.current_action.basic = 3 return nil end action_motion = AutoPlayer::AUTO_MODE[@active_battler.id][vari] # 行動パターンが設定されていない if action_motion.nil? # 何もしない @active_battler.current_action.kind = 0 @active_battler.current_action.basic = 3 return nil end return action_motion end #-------------------------------------------------------------------------- # ● 優先条件"味方ピンチ"の判定 #-------------------------------------------------------------------------- def at_judge_party_crisis? for actor in $game_party.actors # 瀕死状態? if actor.hp <= (actor.maxhp * AutoPlayer::CRISIS / 100) return true end end return false end #-------------------------------------------------------------------------- # ● 優先条件"味方ピンチ"の判定 #-------------------------------------------------------------------------- def at_judge_enemy_crisis? for enemy in $game_troop.enemies # 瀕死状態? if enemy.hp <= (enemy.maxhp * AutoPlayer::CRISIS / 100) return true end end return false end #-------------------------------------------------------------------------- # ● オート行動者の行動パターン判定 #-------------------------------------------------------------------------- def make_auto_play_pattern(action_pattern) # 優先条件の有無をチェックする pt_crisis = at_judge_party_crisis? tr_crisis = at_judge_enemy_crisis? # レーティング合計値 total_rating = 0 rating_box = [] for i in 0...action_pattern.size rating_plus = 0 case action_pattern[i][1] when 0 # 条件なし when 1 # 味方ピンチ rating_plus = AutoPlayer::RATING_PLUS if pt_crisis when 2 # 敵が瀕死状態 rating_plus = AutoPlayer::RATING_PLUS if tr_crisis else p "行動パターン::優先行動条件 設定ミス" exit end rating_box[i] = action_pattern[i][0] + rating_plus total_rating += rating_box[i] end # レーティングによる行動選択 rating_randam = rand(total_rating) before_rating = 0 for i in 0...action_pattern.size if rating_randam < (rating_box[i] + before_rating) return action_pattern[i] end before_rating += rating_box[i] end return nil # 行動選択失敗 end #-------------------------------------------------------------------------- # ● 行動選択 #-------------------------------------------------------------------------- def make_auto_play_motion(action) ret = true case action[2] when 0 # 通常攻撃 @active_battler.current_action.kind = 0 @active_battler.current_action.basic = 0 ret = make_auto_play_target(action[4], 1) when 1 # 防御 @active_battler.current_action.kind = 0 @active_battler.current_action.basic = 1 when 2 # スキル @active_battler.current_action.kind = 1 @active_battler.current_action.skill_id = skill_id = action[3] # 使えない場合は再選択 return nil unless @active_battler.skill_can_use?(skill_id) # ターゲット選択 ret = make_auto_play_target(action[4], $data_skills[skill_id].scope) when 3 # アイテム @active_battler.current_action.kind = 2 @active_battler.current_action.item_id = item_id = action[3] # 持ってない場合は再選択 return nil if $game_party.item_number(item_id) == 0 # ターゲット選択 ret = make_auto_play_target(action[4], $data_items[item_id].scope) else p "行動パターン::行動種類 設定ミス" exit end return ret end #-------------------------------------------------------------------------- # ● ターゲット選択 #-------------------------------------------------------------------------- def make_auto_play_target(mode, scope) case scope when 0, 2, 4, 6, 7 # 全体攻撃なので設定不要 @active_battler.current_action.target_index = 0 else # その他単体攻撃 # ターゲット選択 case mode when 0 # ランダム case scope when 1 # 敵 @active_battler.current_action.target_index = make_randum_target($game_troop.enemies) when 3, 5 # 味方 @active_battler.current_action.target_index = make_randum_target($game_party.actors) end when 1 # 残HPの低い者 case scope when 1 # 敵 @active_battler.current_action.target_index = make_crisis_target($game_troop.enemies) when 3 @active_battler.current_action.target_index = make_crisis_target($game_party.actors) when 5 # 味方(HP0) target = make_dead_target return nil if target.nil? # 選び直し @active_battler.current_action.target_index = target end when 2 # 残HPの高い者 case scope when 1 # 敵 @active_battler.current_action.target_index = make_vigour_target($game_troop.enemies) when 3 # 味方 @active_battler.current_action.target_index = make_vigour_target($game_party.actors) when 5 # 味方(HP0) target = make_dead_target return nil if target.nil? # 選び直し @active_battler.current_action.target_index = target end else p "行動パターン::ターゲット 設定ミス" exit end end return true end #-------------------------------------------------------------------------- # ● ランダムターゲット選択 #-------------------------------------------------------------------------- def make_randum_target(targets) while 0 index = rand(targets.size) if targets[index].exist? return index end end end #-------------------------------------------------------------------------- # ● 残HP低ターゲット選択 #-------------------------------------------------------------------------- def make_crisis_target(targets) target_hp = 1000000 target_index = make_randum_target(targets) for index in 0...targets.size if targets[index].hp < target_hp target_hp = targets[index].hp target_index = index end end return target_index end #-------------------------------------------------------------------------- # ● 残HP高ターゲット選択 #-------------------------------------------------------------------------- def make_vigour_target(targets) target_hp = 0 target_index = make_randum_target(targets) for index in 0...targets.size if targets[index].hp > target_hp target_hp = targets[index].hp target_index = index end end return target_index end #-------------------------------------------------------------------------- # ● 残HP0ターゲット選択 #-------------------------------------------------------------------------- def make_dead_target target_index = [] for index in 0...$game_party.actors.size if $game_party.actors[index].dead? target_index.push(index) end end return nil if target_index.empty return target_index[rand(target_index.size)] end end