# ======================================================
#  「マルチスキル」スクリプト
# ======================================================
# <概要>
# 「敵に攻撃しつつ味方への補助効果」など、
# 一つのスキルの追加効果に別のスキルの効果を発動できます。
# 効果毎にスキルのターゲットを指定できます。
# 単体攻撃と全体攻撃、自身対象と味方単体対象などの組み合わせも可能です。
# 
# <基本的な使い方>
# ・元となるスキルのメモ欄に<マルチスキル:ID>と書いて下さい。
# 　「ID」の部分には追加で発動させたいスキルのIDを指定して下さい。
# ・追加分のスキルはMPが足りなかったり覚えてなかったりなど、
# 　使用条件を満たしてなくても使用可能です。
# 　
# <応用的な使い方>
# ・スキル1のメモに<マルチスキル:2>、スキル2のメモに<マルチスキル:3>、
# 　とやって行けば複数のスキルの効果を同時に発動できます。
# 　ただしここでスキル3のメモに<マルチスキル:1>や2を指定すると、
# 　無限ループになってしまうので注意。(無限ループって怖くね？)
# ・初期設定では追加分のスキルはアニメーションだけ表示するようになっています。
# 　変えたい場合は少し下にある設定項目で変更して下さい。
# 
# 
# ■再定義している箇所
# class Scene_Battle内
# 　determine_skill（スキルの決定）
# 　update_target_enemy_selection（対象敵キャラ選択の更新）
# 　update_target_actor_selection（対象アクター選択の更新）
# ■エイリアスしている箇所
# class Game_BattleAction内
# 　clear（クリア）
# class Scene_Battle内
# 　execute_action_skill（戦闘行動の実行 : スキル）
# 
# 同じ箇所を再定義やエイリアスしているスクリプトとは
# 競合する可能性があります。
# 
# 
module NukumizuMultiSkill
  # 【マルチスキル用設定項目】
  # true = する　false =しない
  # 適用されるのは全て追加分のスキルに対してです。
  # 一段目のスキルは通常と同じです。
  TEXT1         = false # テキスト1(〜は〜を唱えた。など)の表示。
  TEXT2         = false # テキスト2の表示
  ANIMATION     = true  # アニメーションの表示
  MPCOST        = false # MPコストの消費。(足りなくても残り0になるだけ)
  COMMON_EVENT  = false # コモンイベントの実行。
  # 設定項目ここまで
end

class Game_BattleAction
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_accessor :target_index_multi         # マルチスキル用対象インデックス
  #--------------------------------------------------------------------------
  # ● クリア
  #--------------------------------------------------------------------------
  alias clear_sub clear
  def clear
    @target_index_multi = []
    clear_sub  # 元の処理
  end
end
class Scene_Battle < Scene_Base
  #--------------------------------------------------------------------------
  # ● マルチスキルである場合IDを返す　■新規
  #--------------------------------------------------------------------------
  def multi_skill_id(skill)
    #受け取った「skill」がnilの場合nilを返す
    return nil if skill == nil
    result = skill.note.scan(/<マルチスキル:(\d+)>/).flatten
    result = result[0].to_i
    #スキルのメモから次に発動するIDを返す(キーがない場合はnilを返す)
    return nil if result == 0
    return result
  end
  #--------------------------------------------------------------------------
  # ● 次に発動するスキルをセットする　■新規
  #--------------------------------------------------------------------------
  def multi_skill_set(skill_id)
    @skill = $data_skills[skill_id]
    @active_battler.action.set_skill(skill_id)
  end
  #--------------------------------------------------------------------------
  # ● スキルの決定
  #--------------------------------------------------------------------------
  def determine_skill
    @active_battler.action.set_skill(@skill.id)
    @skill_window.active = false
    if @skill.need_selection?
      if @skill.for_opponent?
        start_target_enemy_selection
      else
        start_target_actor_selection
      end
    else
      # マルチスキルかチェック
      mskill_id = multi_skill_id(@skill)
      if mskill_id != nil
        # 次のスキルがある場合
        @active_battler.action.target_index_multi.push(-1)
        multi_skill_set(mskill_id)# 次のスキルをセット
        determine_skill
      else
        # 次のスキルがない場合
        if @active_battler.action.target_index_multi != []
          @active_battler.action.target_index = @active_battler.action.target_index_multi[0]
          @active_battler.action.target_index_multi.shift
          @skill = @skill_window.skill
          @active_battler.action.set_skill(@skill.id)
        end
        end_skill_selection
        next_actor
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 対象敵キャラ選択の更新
  #--------------------------------------------------------------------------
  def update_target_enemy_selection
    @target_enemy_window.update
    if Input.trigger?(Input::B)
      Sound.play_cancel
      end_target_enemy_selection
    elsif Input.trigger?(Input::C)
      Sound.play_decision
      # 現在のスキルがマルチスキルかチェック
      mskill_id = multi_skill_id(@skill)
      if mskill_id != nil
        # 次のスキルがある場合
        @active_battler.action.target_index_multi.push(@target_enemy_window.enemy.index)
        end_target_enemy_selection
        multi_skill_set(mskill_id)# 次のスキルをセット
        determine_skill
      else
        if @active_battler.action.target_index_multi != []
          # マルチスキルの最後のスキルの処理
          @active_battler.action.target_index_multi.push(@target_enemy_window.enemy.index)
          @active_battler.action.target_index = @active_battler.action.target_index_multi[0]
          @active_battler.action.target_index_multi.shift
          @skill = @skill_window.skill
          @active_battler.action.set_skill(@skill.id)
        else
          # 完全にマルチスキルではない場合
          @active_battler.action.target_index = @target_enemy_window.enemy.index
        end
        end_target_enemy_selection
        end_skill_selection
        end_item_selection
        next_actor
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 対象アクター選択の更新
  #--------------------------------------------------------------------------
  def update_target_actor_selection
    @target_actor_window.update
    if Input.trigger?(Input::B)
      Sound.play_cancel
      end_target_actor_selection
    elsif Input.trigger?(Input::C)
      Sound.play_decision
      # 現在のスキルがマルチスキルかチェック
      mskill_id = multi_skill_id(@skill)
      if mskill_id != nil
        # 次のスキルがある場合
        @active_battler.action.target_index_multi.push(@target_actor_window.index)
        end_target_actor_selection
        multi_skill_set(mskill_id)# 次のスキルをセット
        determine_skill
      else
        if @active_battler.action.target_index_multi != []
          # マルチスキルの最後のスキルの処理
          @active_battler.action.target_index_multi.push(@target_actor_window.index)
          @active_battler.action.target_index = @active_battler.action.target_index_multi[0]
          @active_battler.action.target_index_multi.shift
          @skill = @skill_window.skill
          @active_battler.action.set_skill(@skill.id)
        else
          # 完全にマルチスキルではない場合
          @active_battler.action.target_index = @target_actor_window.index
        end
        end_target_actor_selection
        end_skill_selection
        end_item_selection
        next_actor
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 戦闘行動の実行 : スキル
  #--------------------------------------------------------------------------
  alias execute_action_skill_multi execute_action_skill
  def execute_action_skill
    execute_action_skill_multi  # 元の処理
    # マルチスキルかチェック
    mskill_id = multi_skill_id(@active_battler.action.skill)
    if mskill_id != nil
      loop do
        # マルチスキル発動準備
        @active_battler.action.set_skill(mskill_id)
        @active_battler.action.target_index = @active_battler.action.target_index_multi[0]
        @active_battler.action.target_index_multi.shift
        # マルチスキル発動実行処理
        skill = @active_battler.action.skill
        if NukumizuMultiSkill::TEXT1 == true
          @message_window.clear
          text = @active_battler.name + skill.message1 
          @message_window.add_instant_text(text)
        end
        if NukumizuMultiSkill::TEXT2 == true
          unless skill.message2.empty?
            wait(10)
            @message_window.back_to(1) if @message_window.line_number != 1
            @message_window.add_instant_text(skill.message2)
          end
        end
        targets = @active_battler.action.make_targets
        display_animation(targets, skill.animation_id) if NukumizuMultiSkill::ANIMATION == true
        @active_battler.mp -= @active_battler.calc_mp_cost(skill) if NukumizuMultiSkill::MPCOST == true
        $game_temp.common_event_id = skill.common_event_id if NukumizuMultiSkill::COMMON_EVENT == true
        for target in targets
          target.skill_effect(@active_battler, skill)
          display_action_effects(target, skill)
        end
        # 更にチェックし続きがなければループ終了
        mskill_id = multi_skill_id(@active_battler.action.skill)
        break if mskill_id == nil
      end
    end
  end
end