#============================================================================== # ■ Game_Action #------------------------------------------------------------------------------ #  戦闘行動を扱うクラスです。このクラスは Game_Battler クラスの内部で使用され # ます。 #============================================================================== class Game_Action #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :subject # 行動主体 attr_reader :forcing # 戦闘行動の強制フラグ attr_reader :item # スキル / アイテム attr_accessor :target_index # 対象インデックス attr_reader :value # 自動戦闘用 評価値 #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(subject, forcing = false) @subject = subject @forcing = forcing clear end #-------------------------------------------------------------------------- # ● クリア #-------------------------------------------------------------------------- def clear @item = Game_BaseItem.new @target_index = -1 @value = 0 end #-------------------------------------------------------------------------- # ● 味方ユニットを取得 #-------------------------------------------------------------------------- def friends_unit subject.friends_unit end #-------------------------------------------------------------------------- # ● 敵ユニットを取得 #-------------------------------------------------------------------------- def opponents_unit subject.opponents_unit end #-------------------------------------------------------------------------- # ● 敵キャラの戦闘行動を設定 # action : RPG::Enemy::Action #-------------------------------------------------------------------------- def set_enemy_action(action) if action set_skill(action.skill_id) else clear end end #-------------------------------------------------------------------------- # ● 通常攻撃を設定 #-------------------------------------------------------------------------- def set_attack set_skill(subject.attack_skill_id) self end #-------------------------------------------------------------------------- # ● 防御を設定 #-------------------------------------------------------------------------- def set_guard set_skill(subject.guard_skill_id) self end #-------------------------------------------------------------------------- # ● スキルを設定 #-------------------------------------------------------------------------- def set_skill(skill_id) @item.object = $data_skills[skill_id] self end #-------------------------------------------------------------------------- # ● アイテムを設定 #-------------------------------------------------------------------------- def set_item(item_id) @item.object = $data_items[item_id] self end #-------------------------------------------------------------------------- # ● アイテムオブジェクト取得 #-------------------------------------------------------------------------- def item @item.object end #-------------------------------------------------------------------------- # ● 通常攻撃判定 #-------------------------------------------------------------------------- def attack? item == $data_skills[subject.attack_skill_id] end #-------------------------------------------------------------------------- # ● ランダムターゲット #-------------------------------------------------------------------------- def decide_random_target if item.for_dead_friend? target = friends_unit.random_dead_target elsif item.for_friend? target = friends_unit.random_target else target = opponents_unit.random_target end if target @target_index = target.index else clear end end #-------------------------------------------------------------------------- # ● 混乱行動を設定 #-------------------------------------------------------------------------- def set_confusion set_attack end #-------------------------------------------------------------------------- # ● 行動準備 #-------------------------------------------------------------------------- def prepare set_confusion if subject.confusion? && !forcing end #-------------------------------------------------------------------------- # ● 行動が有効か否かの判定 # イベントコマンドによる [戦闘行動の強制] ではないとき、ステートの制限 # やアイテム切れなどで予定の行動ができなければ false を返す。 #-------------------------------------------------------------------------- def valid? (forcing && item) || subject.usable?(item) end #-------------------------------------------------------------------------- # ● 行動速度の計算 #-------------------------------------------------------------------------- def speed speed = subject.agi + rand(5 + subject.agi / 4) speed += item.speed if item speed += subject.atk_speed if attack? speed end #-------------------------------------------------------------------------- # ● ターゲットの配列作成 #-------------------------------------------------------------------------- def make_targets if !forcing && subject.confusion? [confusion_target] elsif item.for_opponent? targets_for_opponents elsif item.for_friend? targets_for_friends else [] end end #-------------------------------------------------------------------------- # ● 混乱時のターゲット #-------------------------------------------------------------------------- def confusion_target case subject.confusion_level when 1 opponents_unit.random_target when 2 if rand(2) == 0 opponents_unit.random_target else friends_unit.random_target end else friends_unit.random_target end end #-------------------------------------------------------------------------- # ● 敵に対するターゲット #-------------------------------------------------------------------------- def targets_for_opponents if item.for_random? Array.new(item.number_of_targets) { opponents_unit.random_target } elsif item.for_one? num = 1 + (attack? ? subject.atk_times_add.to_i : 0) if @target_index < 0 [opponents_unit.random_target] * num else [opponents_unit.smooth_target(@target_index)] * num end else opponents_unit.alive_members end end #-------------------------------------------------------------------------- # ● 味方に対するターゲット #-------------------------------------------------------------------------- def targets_for_friends if item.for_user? [subject] elsif item.for_dead_friend? if item.for_one? [friends_unit.smooth_dead_target(@target_index)] else friends_unit.dead_members end elsif item.for_friend? if item.for_one? [friends_unit.smooth_target(@target_index)] else friends_unit.alive_members end end end #-------------------------------------------------------------------------- # ● 行動の価値評価(自動戦闘用) # @value および @target_index を自動的に設定する。 #-------------------------------------------------------------------------- def evaluate @value = 0 evaluate_item if valid? @value += rand if @value > 0 self end #-------------------------------------------------------------------------- # ● スキル/アイテムの評価 #-------------------------------------------------------------------------- def evaluate_item item_target_candidates.each do |target| value = evaluate_item_with_target(target) if item.for_all? @value += value elsif value > @value @value = value @target_index = target.index end end end #-------------------------------------------------------------------------- # ● スキル/アイテムの使用対象候補を取得 #-------------------------------------------------------------------------- def item_target_candidates if item.for_opponent? opponents_unit.alive_members elsif item.for_user? [subject] elsif item.for_dead_friend? friends_unit.dead_members else friends_unit.alive_members end end #-------------------------------------------------------------------------- # ● スキル/アイテムの評価(ターゲット指定) #-------------------------------------------------------------------------- def evaluate_item_with_target(target) target.result.clear target.make_damage_value(subject, item) if item.for_opponent? return target.result.hp_damage.to_f / [target.hp, 1].max else recovery = [-target.result.hp_damage, target.mhp - target.hp].min return recovery.to_f / target.mhp end end end