# ======================================================
#  「FF11風幻影ステート」スクリプトver.1.2
# ======================================================
# ■更新履歴
# ver.1.2(2011/7/28)
# ・戦闘開始時に幻影ステートになっている場合、最大数からスタートするように。
# ・幻影ステートを上書きできるように伴い、幻影の優先度を設定。
# 　既に幻影ステートにかかっている場合、新しい幻影ステートの
# 　優先度が同じか高い場合のみ上書き可能です。
# 　設定項目のGENEI_PROに優先度の設定箇所があるので記述してください。
# ver.1.1(2011/3/31)
# ・全体攻撃でも単体攻撃と同様の幻影消費の<幻影単体消費>を実装。
# ======================================================
# 
# ■主な機能
# ・敵の攻撃を幻影で回避できるステートを作成できます。
# 　単体攻撃を空蝉の枚数分回避(多段の場合は攻撃回数分消費)、
# 　全体攻撃を受けた場合は幻影全消費でその攻撃の効果もくらいます。
# ・空蝉を消費せず単体および全体攻撃の効果だけ食らったり、
# 　単体攻撃なのに空蝉を全て消費させられたりするスキルも設定できます。
# ・空蝉の判定は敵の攻撃ミス判定、こちらの素避け判定の後になります。
# ・空蝉の上書き判定を優先度という形で設定。
# 　優先度が同じか高いステートが後からかけられた場合、
# 　以前の幻影ステートに上書きされます。
# 
# ■使い方
# １．データベースで幻影状態用のステートを用意する。
# ２．このスクリプト内の設定項目でそのステートのIDと性能設定をする。
# ３．そのステートにするスキルなどを作れば幻影スキルの完成。
#   ※このスクリプトは再定義している箇所が多いので、
#   　素材スクリプトの上の方に設置することをオススメします。
# 
# ■オプション
# それぞれスキルのメモ欄に記入する。
# ・<幻影無視>
# 　そのスキルを受けた場合、幻影はそのままの状態で本体にスキルの効果。
# ・<幻影貫通>
# 　そのスキルを受けた場合、幻影を全て消した上で本体にスキルの効果。
# ・<幻影単体消費>
# 　全体攻撃スキルの場合でも幻影全消費せず、単体と同じように動作する。
# 
# ■エイリアスしている箇所
# class Game_Battler内
# 　add_state              （ステートの付加）
# class Scene_Battle内
# 　process_battle_start   （戦闘開始の処理）
# ■再定義している箇所
# class Game_Battler内
#   apply_state_changes     （ステート変化の適用）
#   attack_effect           （通常攻撃の効果適用）
#   skill_effect            （スキルの効果適用）
# class Scene_Battle内
#   display_damage          （ダメージの表示）
# 
# 同じ箇所を再定義やエイリアスしているスクリプトとは
# 競合する可能性があります。
# 
module FF11GENEI
  # 【設定項目】
  # 
  # ■幻影状態用ステートのID
  # 性能設定と併せて好きな分だけ増減できます。
  GENEI_ID = [17,18,19]
  # ■幻影の性能設定
  # 順番は先に設定したIDの順番に対応。
  # [ 初期幻影の数 , 幻影発動確率(n/100) , 優先度 , 幻影発動時のメッセージ ]
  # サンプル設定は上から順に蝉壱、蝉弐、ブリンク。
  GENEI_PRO = [
  [3,100,2,"幻影1体が%sの身替わりとなって攻撃を受けて消えた。"],
  [4,100,3,"幻影1体が%sの身替わりとなって攻撃を受けて消えた。"],
  [2,70,1,"幻影1体が%sの身替わりとなって攻撃を受けて消えた。"]
  ]
end

class Game_Battler
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_reader   :genei                 # 行動結果: 幻影発動フラグ
  attr_reader   :genei_end             # 行動結果: 幻影枚数が尽きたフラグ
  attr_accessor :genei_var             # 幻影残り枚数
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  alias genei_initialize initialize
  def initialize
    genei_initialize          #従来の処理
    @genei     = false        #幻影発動フラグ 
    @genei_end = false        #幻影枚数が尽きたフラグ
    @genei_mes = 0            #幻影メッセージ
    @genei_var = 0            #幻影残り枚数
  end
  #--------------------------------------------------------------------------
  # ● 行動効果の保持用変数をクリア
  #--------------------------------------------------------------------------
  alias semi_clear_action_results clear_action_results
  def clear_action_results
    semi_clear_action_results #従来の処理
    @genei     = false        #幻影発動フラグ 
    @genei_end = false        #幻影枚数が尽きたフラグ
    @genei_mes = 0            #幻影メッセージ
  end
  #--------------------------------------------------------------------------
  # ○ スキルが敵全体かどうかチェック
  #--------------------------------------------------------------------------
  def check_for_opponent_all?(obj)
    if obj.for_opponent?
      if obj.for_all?
        return true
      end
    end
    return false
  end
  #--------------------------------------------------------------------------
  # ○ 幻影メッセージを返す
  #--------------------------------------------------------------------------
  def genei_mes
    return @genei_mes
  end
  #--------------------------------------------------------------------------
  # ○ 幻影ステートにかかってるかどうかチェック
  #--------------------------------------------------------------------------
  def genei_check
    # ステートをチェック
    for state in @states
      for i in 0..FF11GENEI::GENEI_ID.size
        return [state,i] if state == FF11GENEI::GENEI_ID[i]
      end
    end
    return false
  end
  #--------------------------------------------------------------------------
  # ○ 幻影枚数を1枚減らす
  #--------------------------------------------------------------------------
  def genei_down(genei_id)
    @genei_var -= 1  #幻影を減らす
    if @genei_var <= 0  #幻影が０以下の場合
      @genei_var = 0
      remove_state(genei_id)
      @genei_end = true
    end
  end
  #--------------------------------------------------------------------------
  # ○ 幻影ステートが発動するかチェック(通常攻撃版)
  #--------------------------------------------------------------------------
  def genei_value
    genei_id = genei_check #幻影ステート有効かチェック
    if genei_id != false #幻影ステート有効の場合
      @genei = true # とりあえず幻影判定ON
      if rand(100) <= FF11GENEI::GENEI_PRO[genei_id[1]][1]
        genei_down(genei_id[0])
      else
        @genei = false
      end
    end
  end
  #--------------------------------------------------------------------------
  # ○ 幻影ステートが発動するかチェック(スキル版)
  #--------------------------------------------------------------------------
  def genei_value_skill(skill)
    genei_id = genei_check #幻影ステート有効かチェック
    if genei_id != false and skill.for_opponent? #幻影ステート有効の場合
      @genei = true # とりあえず幻影判定ON
      # スキルの対幻影設定参照
      if skill.note.include?("<幻影無視>")
        @genei = false
        return
      end
      if skill.note.include?("<幻影貫通>")
        @genei = false
        @genei_var = 0
        @genei_end = true
        remove_state(genei_id[0])
        return
      end
      # 全体攻撃の場合
      if check_for_opponent_all?(skill)
        unless skill.note.include?("<幻影単体消費>")
          @genei = false
          @genei_var = 0
          @genei_end = true
          remove_state(genei_id[0])
          return
        end
      end
      # 単体攻撃の場合
      if rand(100) <= FF11GENEI::GENEI_PRO[genei_id[1]][1]
        genei_down(genei_id[0])
      else
        @genei = false
      end
    end
  end
  #--------------------------------------------------------------------------
  # ○ 幻影ステートを上書き可能かチェック
  #--------------------------------------------------------------------------
  def genei_update(state_id)
    for state in @states
      if FF11GENEI::GENEI_ID.include?(state)
        new = FF11GENEI::GENEI_PRO[FF11GENEI::GENEI_ID.index(state_id)][2]
        old = FF11GENEI::GENEI_PRO[FF11GENEI::GENEI_ID.index(state)][2]
        if new >= old
          remove_state(state)
        else
          @remained_states.push(state_id)
          return false
        end
      end
    end
    return true
  end
  #--------------------------------------------------------------------------
  # ● ステート変化の適用　　■再定義
  #     obj : スキル、アイテム、または攻撃者
  #--------------------------------------------------------------------------
  def apply_state_changes(obj)
    plus = obj.plus_state_set             # ステート変化(+) を取得
    minus = obj.minus_state_set           # ステート変化(-) を取得
    for i in plus                         # ステート変化 (+)
      next if state_resist?(i)            # 無効化されている？
      next if dead?                       # 戦闘不能？
      next if i == 1 and @immortal        # 不死身？
      if state?(i)                        # すでに付加されている？
        unless FF11GENEI::GENEI_ID.include?(i)  #■
          @remained_states.push(i)        # 変化しなかったステートを記録
          next                                  #■
        end
      end
      if rand(100) < state_probability(i) # 確率判定
        add_state(i)                      # ステートを付加
        @added_states.push(i)             # 付加したステートを記録
      end
    end
    for i in minus                        # ステート変化 (-)
      next unless state?(i)               # 付加されていない？
      remove_state(i)                     # ステートを解除
      @removed_states.push(i)             # 解除したステートを記録する
    end
    for i in @added_states & @removed_states
      @added_states.delete(i)             # 付加と解除の両方に記録されている
      @removed_states.delete(i)           # ステートがあれば両方削除する
    end
  end
  #--------------------------------------------------------------------------
  # ● ステートの付加　　■エイリアス
  #     state_id : ステート ID
  #--------------------------------------------------------------------------
  alias genei_add_state add_state
  def add_state(state_id)
    if FF11GENEI::GENEI_ID.include?(state_id)
      return if genei_update(state_id) == false
    end 
    genei_add_state(state_id)# 従来の処理
    for i in 0..FF11GENEI::GENEI_ID.size
      if state_id == FF11GENEI::GENEI_ID[i]
        @genei_var = FF11GENEI::GENEI_PRO[i][0]
        @genei_mes = i
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 通常攻撃の効果適用　　■再定義
  #     attacker : 攻撃者
  #--------------------------------------------------------------------------
  def attack_effect(attacker)
    clear_action_results
    unless attack_effective?(attacker)
      @skipped = true
      return
    end
    if rand(100) >= calc_hit(attacker)            # 命中判定
      @missed = true
      return
    end
    if rand(100) < calc_eva(attacker)             # 回避判定
      @evaded = true
      return
    else # 命中ミスも素の回避もしなかった場合に幻影判定■■■
      genei_value
      return if @genei == true
    end
    make_attack_damage_value(attacker)            # ダメージ計算
    execute_damage(attacker)                      # ダメージ反映
    if @hp_damage == 0                            # 物理ノーダメージ判定
      return                                    
    end
    apply_state_changes(attacker)                 # ステート変化
  end
  #--------------------------------------------------------------------------
  # ● スキルの効果適用　　■再定義
  #     user  : スキルの使用者
  #     skill : スキル
  #--------------------------------------------------------------------------
  def skill_effect(user, skill)
    clear_action_results
    unless skill_effective?(user, skill)
      @skipped = true
      return
    end
    if rand(100) >= calc_hit(user, skill)         # 命中判定
      @missed = true
      return
    end
    if rand(100) < calc_eva(user, skill)          # 回避判定
      @evaded = true
      return
    else  # 命中ミスも素の回避もしなかった場合に幻影判定■■■
      genei_value_skill(skill)
      return if @genei == true # 幻影判定ONのままの時のみ↓のダメージ計算飛ばす
    end
    make_obj_damage_value(user, skill)            # ダメージ計算
    make_obj_absorb_effect(user, skill)           # 吸収効果計算
    execute_damage(user)                          # ダメージ反映
    if skill.physical_attack and @hp_damage == 0  # 物理ノーダメージ判定
      return                                    
    end
    apply_state_changes(skill)                    # ステート変化
  end
end

class Scene_Battle < Scene_Base
  #--------------------------------------------------------------------------
  # ○ 開始時の幻影枚数セット
  #--------------------------------------------------------------------------
  def genei_start_set
    for actor in $game_party.members
      kazu = actor.genei_check
      if kazu != false
        actor.genei_var = FF11GENEI::GENEI_PRO[kazu[1]][0]
      end
    end
    for actor in $game_troop.members
      kazu = actor.genei_check
      if kazu != false
        actor.genei_var = FF11GENEI::GENEI_PRO[kazu[1]][0]
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 戦闘開始の処理　　■エイリアス
  #--------------------------------------------------------------------------
  alias genei_process_battle_start process_battle_start
  def process_battle_start
    genei_start_set
    genei_process_battle_start
  end
  #--------------------------------------------------------------------------
  # ● ダメージの表示　　■再定義
  #     target : 対象者
  #     obj    : スキルまたはアイテム
  #--------------------------------------------------------------------------
  def display_damage(target, obj = nil)
    if target.missed
      display_miss(target, obj)
    elsif target.evaded
      display_evasion(target, obj)
    elsif target.genei  # 幻影が発動しているかどうか(■■■追加)
      display_semi(target, obj)
    else
      display_hp_damage(target, obj)
      display_mp_damage(target, obj)
      if target.genei_end
        text = sprintf("%sは、分身の効果がきれた。", target.name)
        @message_window.add_instant_text(text)
        wait(30)
      end
    end
  end
  #--------------------------------------------------------------------------
  # ○ 幻影回避の表示
  #     target : 対象者
  #     obj    : スキルまたはアイテム
  #--------------------------------------------------------------------------
  def display_semi(target, obj = nil)
    text = sprintf(FF11GENEI::GENEI_PRO[target.genei_mes][3], target.name)
    Sound.play_evasion
    @message_window.add_instant_text(text)
    wait(30)
    if target.genei_end
      text = sprintf("%sは、分身の効果がきれた。", target.name)
      @message_window.add_instant_text(text)
      wait(30)
    end
  end
end