#==============================================================================
# ■ Action Counter vol.2.70β(CAS_Ex vol.1.30より下に挿入)
#------------------------------------------------------------------------------
# カウンター行動を行う
# 12/07/15
#==============================================================================
#==============================================================================
# ■ Scene_Battle
#==============================================================================
class Game_Battler
  include CAS_Ex
  attr_accessor :counter                  # カウンター効果
  attr_accessor :user_attacker            # 攻撃してくる相手を取得
  attr_accessor :counter_actions          # 通常のアクションを格納
  attr_accessor :counter_count            # カウンター回数
  attr_accessor :counter_states           # 全カウンター効果を格納
  #--------------------------------------------------------------------------
  # ■ オブジェクト初期化
  #--------------------------------------------------------------------------
  if !$@;alias hidesp_counter_initialize initialize;end
  def initialize
    # □元の処理を呼び出し
    hidesp_counter_initialize
    # □カウンターの全初期化
    counter_clear
  end
  #--------------------------------------------------------------------------
  # ■ カウンターの初期化
  # ["表示"] nil=全て表示  0=行動アニメ/ヘルプ無し 2=行動アニメ無し 3=ヘルプ無し
  # ["条件"] # 0=全てのダメージ 1=物理ダメージ(攻撃力F>魔力F) 2=(スキルダメージ攻撃力F<魔力F)
  #--------------------------------------------------------------------------
  def counter_clear1
    @counter = {}
    @counter["名前"] = ""      # カウンターステート名を格納
    @counter["確率"] = 0       # カウンター発生確率
    @counter["発生"] = false   # カウンター発生フラグ
    @counter["発動"] = false   # カウンター発動フラグ
    @counter["表示"] = nil     # 行動アニメ/ヘルプを表示しない場合
    @counter["種類"] = 0       # アクションの種類(0=通常攻撃 1=スキル 2=アイテム)
    @counter["ID"] = 0         # スキル/アイテムのID
    @counter["消費"] = nil     # スキル/アイテムの消費判定フラグ
    @counter["対象"] = nil     # ターゲット変更したバトラーを取得
    @counter["条件"] = 0       # カウンター発生条件
    @counter["残HP"] = nil     # 残りHP(%)条件を取得
    @counter["貫通"] = []      # カウンターを無効化する属性
    @counter["反応"] = []      # 指定した属性のみに反応するカウンター
    @counter["効果"] = nil     # 受けるはずのダメージを格納
    @counter["威力"] = 100     # カウンターが発動した場合のダメージ増加率(与える)
    @counter["失敗"] = 100     # カウンターが失敗した場合のダメージ増加率(受ける)
    @counter["HP減"] = 0       # ダメージの軽減率と許可フラグ(0=無し 0>有り)
    @counter["反射"] = false   # 受けるはずのダメージに変更フラグ
    @counter["死亡"] = false   # 戦闘不能になるダメージを受けたか？
    @counter["説明"] = nil     # カウンターが発生した場合に表示するヘルプウィンドウの文字
    @counter["文字"] = nil     # カウンターが発生した場合に表示するダメージ文字
    @counter["演出"] = nil     # カウンターが発生した場合に表示するアニメーションID
    @counter["回数"] = nil     # カウンターが発生する回数(nil = 無限)
    @counter["解除"] = nil     # 解除するカウンターステートを格納
  end
  #--------------------------------------------------------------------------
  # ■ カウンターの全初期化
  #--------------------------------------------------------------------------
  def counter_clear
    counter_clear1
    @counter_actions = nil     # カウンターアクションを格納
    @user_attacker = nil       # 攻撃してくる相手を取得
    @counter_count = nil       # カウンター回数を格納
    @counter_states = []       # カウンターステートを格納
  end
  #--------------------------------------------------------------------------
  # ■ 通常攻撃の効果適用
  #--------------------------------------------------------------------------
  if !$@;alias hidesp_counter_attack_effect attack_effect;end
  def attack_effect(attacker)
    if attacker.counter["発動"]
      self.user_attacker = attacker
    # □行動できない場合は無効
    elsif self == attacker or self.restriction == 4
      self.user_attacker = nil
    else
      self.user_attacker = attacker
    end
    # □元の処理を呼び出し
    hidesp_counter_attack_effect(attacker)
  end
  #--------------------------------------------------------------------------
  # ■ スキルの効果適用
  #--------------------------------------------------------------------------
  if !$@;alias hidesp_counter_skill_effect skill_effect;end
  def skill_effect(user, skill)
    if user.counter["発動"]
      self.user_attacker = user
    # □全体攻撃は無効/行動できない場合は無効
    elsif self == user or skill.scope == 2 or 
      skill.scope == 4 or skill.scope == 6 or self.restriction == 4
      self.user_attacker = nil
    else
      self.user_attacker = user
    end
    # □元の処理を呼び出し
    hidesp_counter_skill_effect(user, skill)
  end
  #--------------------------------------------------------------------------
  # ■ ステート衝撃解除 (物理ダメージごとに呼び出し)
  #  [カウンター]発動条件の確認
  #--------------------------------------------------------------------------
  if !$@;alias hidesp_counter_remove_states_shock remove_states_shock;end
  def remove_states_shock
    @seen = 0
    counter_damage_effect?(@seen)
    # □元の処理を呼び出し
    hidesp_counter_remove_states_shock
  end
  #--------------------------------------------------------------------------
  # ■ ダメージ処理の取得
  #--------------------------------------------------------------------------
  def damage_effect?
    counter_damage_effect?(1)
  end
  #--------------------------------------------------------------------------
  # ■ ダメージカウンター発生条件
  #--------------------------------------------------------------------------
  def counter_damage_effect?(seen)
    if @seen == nil
      @seen = seen
    end
    #…………………………………………………………………………………………………
    # ■カウンター発動中の効果
    #…………………………………………………………………………………………………
    if self.user_attacker != nil
      if self.user_attacker.counter["発動"]
        counter_attacker_effect(self.user_attacker)
        return
      end
    else
      # □[死亡]フラグがONの場合(対象が自分の場合)
      if self.counter["死亡"]
        self.user_attacker = self
      end
      # □カウンター発生フラグをOFF
      self.counter["発生"] = false
      return
    end
    #…………………………………………………………………………………………………
    # ■カウンター発生の確認
    #…………………………………………………………………………………………………
    if counter_effect?
      ses = []
      for i in 0...self.counter_states.size
        if self.counter_states[i]["発生"]
          
          if CAS_Ex::DEBUG
            debug = $data_states[CAS_Ex::Ex.index(self.counter_states[i]["名前"])]
            p debug.id.to_s + debug.name
          end
          ses.push(self.counter_states[i])
        end
      end
      # □カウンターステートを格納
      self.counter_states = ses.dup
      if ses != []
        self.counter_count = self.counter_states.size - 1
        self.counter = self.counter_states[self.counter_count]
      else
        self.counter_count = nil
      end
    else
      self.user_attacker = nil
    end
    @seen = nil
  end
  #--------------------------------------------------------------------------
  # ■ カウンター発動中の効果
  #--------------------------------------------------------------------------
  def counter_attacker_effect(user)
    if user != nil
      #…………………………………………………………………………………………………
      # ■反射ダメージの場合、受けるはずのダメージを返す
      #…………………………………………………………………………………………………
      if user.counter["反射"] && self.damage > 0
        self.damage = user.counter["効果"]
      end
      #…………………………………………………………………………………………………
      # ■ダメージ増加率
      #…………………………………………………………………………………………………
      if user.counter["威力"] > 0 && self.damage > 0
        self.damage = [self.damage * (user.counter["威力"] / 100),1].max
      end
    end
  end
  #--------------------------------------------------------------------------
  # ■ [カウンター]発生条件の取得
  #--------------------------------------------------------------------------
  def counter_effect?
    counter_ok = false
    unless self.user_attacker.counter["発動"] && self.user_attacker.counter["発生"]
      #…………………………………………………………………………………………………
      # ■自分自身に攻撃の場合、分岐の終了
      #…………………………………………………………………………………………………
      if self.user_attacker == self or self.user_attacker == nil
        return false
      end
      #…………………………………………………………………………………………………
      # ■ダメージが0の場合、分岐の終了
      #…………………………………………………………………………………………………
      if self.damage.is_a?(Numeric)
        if self.damage <= 0
          return false
        end
      end
      #…………………………………………………………………………………………………
      # ■[防御]の場合、分岐の終了
      #…………………………………………………………………………………………………
      if self.guarding?
        return false
      end
      #…………………………………………………………………………………………………
      # ■カウンターステートの取得
      #…………………………………………………………………………………………………
      counter_states = []
      self.counter_states = []
      for a in self.states
        if CAS_Ex::Ex[a] != nil
          counter_states.push(a)
        end
      end
      #…………………………………………………………………………………………………
      # ■カウンターステートが無いの場合、分岐の終了
      #…………………………………………………………………………………………………
      if counter_states == []
        self.counter_clear
        return false
      end
      #…………………………………………………………………………………………………
      # ■カウンターステートを配列に格納
      #…………………………………………………………………………………………………
      self.counter_states = []
      counter_states = counter_states.dup.reverse!
      for a in counter_states
        
        self. counter_clear1
        act_data = nil
        if CAS_Ex::Ex[a] != nil
          scan = CAS_Ex::Ex[a]
          self.counter["名前"] = scan
          #…………………………………………………………………………………………………
          # ■ カウンター発生確率の取得
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Pp])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □指定がない場合は、100%実行(条件が揃っている場合)
          if sc1 == nil && sc2 == nil
            self.counter["確率"] = 100
          elsif (/[Pp]/.match(sc1)) && sc2 != nil
            self.counter["確率"] = sc2.to_i
          end
          #…………………………………………………………………………………………………
          # ■ カウンター発生回数の取得
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Vv])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □指定がない場合は無限
          if sc1 == nil && sc2 == nil
            self.counter["回数"] = nil
          elsif (/[Vv]/.match(sc1)) && sc2 != nil
            unless self.counter["回数"].is_a?(Numeric)
              self.counter["回数"] = sc2.to_i
            end
            self.counter["解除"] = a
          end
          #…………………………………………………………………………………………………
          # ■ [スキル]カウンターの場合
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([SsIi])([0-9]+)/) ; sc1,sc2 = $1,$2
          if (/[Ss]/.match(sc1)) && $data_skills[sc2.to_i] != nil
            act_data = $data_skills[sc2.to_i]
            counter_ok = true
            # □スキルIDを取得
            self.counter["種類"] = 1
            self.counter["ID"] = sc2.to_i
            # □スキルSP消費の判定
            if (/[Cc]/.match(scan))
              counter_ok = self.skill_can_use?(self.counter["ID"])
              self.counter["消費"] = self.skill_can_use?(self.counter["ID"])
            end
          #…………………………………………………………………………………………………
          # ■ [アイテム]カウンターの場合
          #…………………………………………………………………………………………………
          elsif (/[Ii]/.match(sc1)) && $data_items[sc2.to_i] != nil
            act_data = $data_items[sc2.to_i]
            counter_ok = true
            # □アイテムIDを取得
            self.counter["種類"] = 2
            self.counter["ID"] = sc2.to_i
            # □アイテム消費の判定
            if self.is_a?(Game_Actor) && (/[Cc]/.match(scan))
              counter_ok = $game_party.item_can_use?(self.counter["ID"])
              self.counter["消費"] = $game_party.item_can_use?(self.counter["ID"])
            end
          #…………………………………………………………………………………………………
          # ■ 存在しない[スキル/アイテム]IDを設定した場合
          #…………………………………………………………………………………………………
          elsif ((/[Ss]/.match(sc1)) && $data_skills[sc2.to_i] == nil) or 
            ((/[Ii]/.match(sc1)) && $data_items[sc2.to_i] == nil)
            p "存在しないIDはエラー!" ;Error!
          end
          #…………………………………………………………………………………………………
          # ■ [通常攻撃]カウンターの場合
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Aa])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □数値の指定が有る場合、行動を指定
          if (/[Aa]/.match(sc1)) && sc2 != nil
            counter_ok = true
            case sc2.to_i
            when 0 #攻撃
              self.counter["種類"] = 0
            when 1 #防御
              self.counter["種類"] = 9
            when 2 #逃げる(エネミー専用)
              self.counter["種類"] = 10
            when 3 #何もしない
              self.counter["種類"] = 11
            end
          elsif (/[Aa]/.match(scan))
            counter_ok = true
            self.counter["種類"] = 0
          end
          #…………………………………………………………………………………………………
          # ■ [回避]行動(カウンター無し)
          #…………………………………………………………………………………………………
          if (/[Gg]/.match(scan))
            counter_ok = true
            self.counter["種類"] = 6
          end
          #…………………………………………………………………………………………………
          # ■ [コピー]カウンター
          #…………………………………………………………………………………………………
          if (/[Rr]/.match(scan))
            counter_ok = true
            # □スキル/アイテム消費の判定
            if (/[Cc]/.match(scan))
              self.counter["消費"] = true
            end
            self.counter["種類"] = 7
          end
          #…………………………………………………………………………………………………
          # ■ 反射カウンター
          #…………………………………………………………………………………………………
          if (/[Mm]/.match(scan))
            self.counter["反射"] = true
          end
          #…………………………………………………………………………………………………
          # ■ 行動アニメの表示タイプ
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Ff])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □数値の指定が有る場合、行動を指定
          if (/[Ff]/.match(sc1)) && sc2 != nil
            self.counter["表示"] = sc2.to_i
          # □数値の指定がない
          elsif (/[Ff]/.match(scan))
            self.counter["表示"] = 0
          end
          #…………………………………………………………………………………………………
          # ■ カウンター発生時に表示するヘルプ文字
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Ll])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □数値の指定が有る場合、行動を指定
          if (/[Ll]/.match(sc1)) && sc2 != nil
            self.counter["解説"] = CAS_Ex::HELP[sc2.to_i]
          # □数値の指定がない
          elsif (/[Ll]/.match(scan))
            self.counter["解説"] = nil
          end
          #…………………………………………………………………………………………………
          # ■ カウンター発生時に表示するダメージ文字
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Kk])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □数値の指定が有る場合、行動を指定
          if (/[Kk]/.match(sc1)) && sc2 != nil
            self.counter["文字"] = CAS_Ex::TEXT[sc2.to_i]
          # □数値の指定がない
          elsif (/[Kk]/.match(scan))
            self.counter["文字"] = nil
          end
          #…………………………………………………………………………………………………
          # ■ カウンター発生時に表示するアニメーションID
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Qq])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □数値の指定が有る場合、行動を指定
          if (/[Qq]/.match(sc1)) && sc2 != nil
            self.counter["演出"] = CAS_Ex::ANIMATION[sc2.to_i]
          # □数値の指定がない
          elsif (/[Qq]/.match(scan))
            self.counter["演出"] = nil
          end
          #…………………………………………………………………………………………………
          # ■ ダメージの判定(0=無し 0>有り)
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Dd])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □数値の指定が有る場合、ダメージ(数値)%
          if (/[Dd]/.match(sc1)) && sc2 != nil
            self.counter["HP減"] = sc2.to_i
          # □数値の指定がない場合、ダメージ100%
          elsif (/[Dd]/.match(scan))
            self.counter["HP減"] = 100
          else
            self.counter["HP減"] = 0
          end
          #…………………………………………………………………………………………………
          # ■ 失敗時のダメージ増加率
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Bb])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □数値の指定が有る場合、ダメージ(数値)%
          if (/[Bb]/.match(sc1)) && sc2 != nil
            self.counter["失敗"] = sc2.to_i
          # □数値の指定がない場合、ダメージ100%
          elsif (/[Bb]/.match(scan))
            self.counter["失敗"] = 100
          end
          #…………………………………………………………………………………………………
          # ■ 発動時のダメージ増加率
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Ww])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □数値の指定が有る場合、ダメージ(数値)%
          if (/[Ww]/.match(sc1)) && sc2 != nil
            self.counter["威力"] = sc2.to_i
          # □数値の指定がない場合、ダメージ100%
          elsif (/[Ww]/.match(scan))
            self.counter["威力"] = 100
          end
          #…………………………………………………………………………………………………
          # ■ 反応属性の取得
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Zz])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □数値の指定が有る場合、ダメージ(数値)%
          if (/[Zz]/.match(sc1)) && sc2 != nil
            self.counter["反応"] = CAS_Ex::ELE_OK[sc2.to_i]
          end
          #…………………………………………………………………………………………………
          # ■ 貫通属性の取得
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Nn])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □数値の指定が有る場合、ダメージ(数値)%
          if (/[Nn]/.match(sc1)) && sc2 != nil
            self.counter["貫通"] = CAS_Ex::ELE_NO[sc2.to_i]
          end
          #…………………………………………………………………………………………………
          # ■ 残りHP(%)条件の取得
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Hh])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □数値の指定が有る場合、残りHP(数値)%
          if (/[Hh]/.match(sc1)) && sc2 != nil
            self.counter["残HP"] = sc2.to_i
            if self.counter["種類"] == 0
              self.counter["種類"] = 3
            elsif self.counter["種類"] == 1
              self.counter["種類"] = 4
            elsif self.counter["種類"] == 2
              self.counter["種類"] = 5
            elsif self.counter["種類"] == 6 && self.counter["残HP"] == 0
              self.counter["種類"] = 8
            end
          end
          #…………………………………………………………………………………………………
          # ■ 発生条件の取得
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([Jj])([0-9]+)/) ; sc1,sc2 = $1,$2
          # □指定がない場合、全てのダメージに反応
          if (/[Jj]/.match(sc1)) && sc2 != nil
            self.counter["条件"] = sc2.to_i
          end
          #…………………………………………………………………………………………………
          # ■ ターゲットを格納(Game_Enemy)
          #…………………………………………………………………………………………………
          CAS_Ex::Ex[a].scan(/([EeOoUuTt])([XxYy0-9]+)/) ; sc1,sc2 = $1,$2
          
          
          CAS_Ex::Ex[a].scan(/[EeOoUuTt][XxYy]([0-9]+)/) ; sc3 = $1.to_i
          # □ターゲットを使用者に変更
          if (/[Tt]/.match(scan))
            self.is_a?(Game_Actor) ? sc1 = "U" : sc1 = "E"
          # □ターゲットを逆転する
          elsif (/[Oo]/.match(scan))
            self.is_a?(Game_Actor) ? sc1 = "E" : sc1 = "U"
          end
          # □除外するターゲットの取得
          if (/[Oo]/.match(scan)) && (/[Yy]/.match(sc2))
            # 攻撃してくる相手
            del_user = self.user_attacker
          else
            # 自分以外
            del_user = self
          end
          # □指定がない場合、攻撃してくる相手を取得
          if sc1 == nil && sc2 == nil
            self.counter["対象"] = self.user_attacker
          # □sc2=0の場合、自分自身を代入
          elsif ((/[Uu]/.match(sc1)) or (/[Ee]/.match(sc1))) && sc2 == "0"
            self.counter["対象"] = self
          # □sc2=Xの場合、ランダムに対象を決定
          elsif (/[Uu]/.match(sc1)) && (/[Xx]/.match(sc2))
            self.counter["対象"] = random_target(nil,$game_party.actors,act_data,sc3)
          elsif (/[Ee]/.match(sc1)) && (/[Xx]/.match(sc2))
            self.counter["対象"] = random_target(nil,$game_troop.enemies,act_data,sc3)
          # □sc2=Yの場合、ランダムに対象を決定(除外するターゲット)
          elsif (/[Uu]/.match(sc1)) && (/[Yy]/.match(sc2))
            self.counter["対象"] = random_target(del_user,$game_party.actors,act_data,sc3)
          elsif (/[Ee]/.match(sc1)) && (/[Yy]/.match(sc2))
            self.counter["対象"] = random_target(del_user,$game_troop.enemies,act_data,sc3)
          # □sc2=0以外の場合、直接指定した数値の対象を決定
          elsif (/[Uu]/.match(sc1)) && $game_party.actors[sc2.to_i-1] != nil
            self.counter["対象"] = $game_party.actors[sc2.to_i-1]
          elsif (/[Ee]/.match(sc1)) && $game_troop.enemies[sc2.to_i-1] != nil
            self.counter["対象"] = $game_troop.enemies[sc2.to_i-1]
          # □無効なIDの場合、カウンターアクション無し
          else
            counter_ok = false
          end
          # □無効な対象の場合、カウンターアクション無し
          if self.counter["対象"] == nil
            counter_ok = false
          end
          # □[カウンター]発生条件の取得
          if counter_ok
            # □物理(攻撃力F>魔力F)/スキル(攻撃力F<魔力F)の判別
            type = self.counter["条件"]
            case @seen
            when 0 # 物理攻撃
              if type == 0 or type == 1
                counter_effect_start
              end
            when 1 # スキル攻撃
              if type == 0 or type == 2
                counter_effect_start
              end
            end
          end
        end
        #…………………………………………………………………………………………………
        # ■ 反撃ステートを配列に追加
        #…………………………………………………………………………………………………
        self.counter_states.push(self.counter.dup)
      end
      unless self.counter_states != []
        counter_ok = false
      end
    end
    return counter_ok
  end
  #--------------------------------------------------------------------------
  # ■ ランダムに対象を決定
  #--------------------------------------------------------------------------
  def random_target(user,group,data,id = nil,hp0 = false)
    if data != nil && hp0 == false
      if data.scope == 5
        hp0 = true
      end
    end
    target = []
    # □自分を除外したグループを取得
    if user != nil
      for i in group
        if user != i && ((! hp0 && i.exist?) or (hp0 && i.hp0?))
          # □ターゲットがidステートの場合
          if id != nil or id != 0
            if i.state?(id)
              target.push(i)
            end
          else
            target.push(i)
          end
        end
      end
    # □グループを取得
    else
      for i in group
        if (! hp0 && i.exist?) or (hp0 && i.hp0?)
          # □ターゲットがidステートの場合
          if id != nil or id != 0
            if i.state?(id)
              target.push(i)
            end
          else
            target.push(i)
          end
        end
      end
    end
    return target[rand(target.size)]
  end
  #--------------------------------------------------------------------------
  # ■属性が付加されているか判別[true/false]
  #--------------------------------------------------------------------------
  def element?(data,name)
    if data.is_a?(RPG::Skill) or data.is_a?(RPG::Item) or 
      data.is_a?(RPG::Weapon) or data.is_a?(Game_Actor) or data.is_a?(Game_Enemy)
      return data.element_set.include?($data_system.elements.index(name))
    elsif data.is_a?(RPG::Armor)
      return data.guard_element_set.include?($data_system.elements.index(name))
    end
    return false
  end
  #--------------------------------------------------------------------------
  # ■全防具に同一の属性が含まれているか判別して個数を返す
  #--------------------------------------------------------------------------
  def element_all?(a,name)
    if a.is_a?(Game_Enemy)
      return 0
    end
    n = 0
    for i in [a.armor1_id,a.armor2_id,a.armor3_id,a.armor4_id]
      if element?($data_armors[i],name)
        n += 1
      end
    end
    return n
  end
  #--------------------------------------------------------------------------
  # ■ ダメージカウンター発生条件
  #--------------------------------------------------------------------------
  def counter_effect_start
    #…………………………………………………………………………………………………
    # ■ [カウンター]発生の場合(カウンターにカウンターは無効)
    #…………………………………………………………………………………………………
    user = self.user_attacker
    unless user.counter["発動"]
      #…………………………………………………………………………………………………
      # ■ [カウンター]発生率の基本値を取得
      #…………………………………………………………………………………………………
      counter_rata = self.counter["確率"]
      # □受けるダメージを格納
      dup_damage = self.damage
      #…………………………………………………………………………………………………
      # ■ 装備品補正
      # 反撃ステートと同じ名前の防御属性(防具)の場合、カウンター発生率UP!
      #…………………………………………………………………………………………………
      counter_rata += element_all?(self,self.counter["名前"]) * 10
      counter_rata += element_all?(self,"反撃UP") * 10
      #…………………………………………………………………………………………………
      # ■ 属性の取得
      #…………………………………………………………………………………………………
      e_case = true
      act = nil
      case user.current_action.kind
      when 0
        act = user
      when 1
        act = $data_skills[user.current_action.skill_id]
      when 2
        act = $data_items[user.current_action.item_id]
      end
      #…………………………………………………………………………………………………
      # ■ カウンターの反応判定
      #…………………………………………………………………………………………………
      if self.counter["反応"] != []
        if act != nil
          el_ok = act.element_set & self.counter["反応"]
          if act.element_set & self.counter["反応"] != []
            e_case = true
          else
            e_case = false
          end
        end
      end
      #…………………………………………………………………………………………………
      # ■ カウンターの貫通判定
      #…………………………………………………………………………………………………
      if self.counter["貫通"] != []
        if act != nil
          el_no = act.element_set & self.counter["貫通"]
          if el_no != []
            e_case = false
          else
            e_case = true
          end
        end
      end
      #…………………………………………………………………………………………………
      # ■ コピーカウンターの消費判定
      #…………………………………………………………………………………………………
      if self.counter["種類"] == 7
        #…………………………………………………………………………………………………
        # ■ スキルの消費判定
        #…………………………………………………………………………………………………
        if self.counter["消費"] && act != nil
          unless self.skill_can_use?(act.id)
            self.counter["消費"] = false
            e_case = false
          end
        end
        #…………………………………………………………………………………………………
        # ■ アイテムの消費判定
        #…………………………………………………………………………………………………
        if self.counter["消費"] && act != nil
          unless $game_party.item_can_use?(act.id)
            self.counter["消費"] = false
            e_case = false
          end
        end
      end
      #…………………………………………………………………………………………………
      # ■ [カウンター]発生率による成功判定
      #…………………………………………………………………………………………………
      if rand(100) < counter_rata && e_case == true
        self.counter["効果"] = self.damage
        # □カウンター発生フラグをON
        self.counter["発生"] = true
        #…………………………………………………………………………………………………
        # ■ ダメージ有りの場合、仮計算
        #…………………………………………………………………………………………………
        if self.counter["HP減"] != 0 && self.counter["HP減"] != nil
          self.damage = [self.damage * (self.counter["HP減"] / 100),1].max
          # □受けるダメージを格納
          dup_damage = self.damage
          self.counter["効果"] = self.damage
        else
          self.damage = 0
        end
        #…………………………………………………………………………………………………
        # ■ [死亡]カウンターの条件を確認
        #…………………………………………………………………………………………………
        if self.counter["残HP"] == 0
          if self.damage >= self.hp
            # □残りHPが1の場合『ガッツ』は発動しない
            if self.counter["種類"] == 8 && self.hp == 1
              # □カウンター発生フラグをOFF
              self.counter["発生"] = false
            else
              self.counter["死亡"] = true
              # □受けるダメージを格納
              self.counter["効果"] = self.damage
              self.damage = 0
            end
          else
            # □カウンター発生フラグをOFF
            self.counter["発生"] = false
          end
        #…………………………………………………………………………………………………
        # ■ HPが0になるダメージの場合
        #…………………………………………………………………………………………………
        elsif self.counter["HP減"] != 0 && self.counter["HP減"] != nil
          if self.damage >= self.hp
            # □カウンター発生フラグをOFF
            self.counter["発生"] = false
          end
        end
        #…………………………………………………………………………………………………
        # ■ 残りHPの条件を確認
        #…………………………………………………………………………………………………
        unless self.counter["死亡"]
          # □HPが0の場合
          if self.counter["残HP"] == 0
            # □カウンター発生フラグをOFF
            self.counter["発生"] = false
          # □HPが**％以上の場合、無効
          elsif self.counter["残HP"] != 0 && self.counter["残HP"] != nil
            if self.hp - self.damage > (self.maxhp * self.counter["残HP"] / 100)
              # □カウンター発生フラグをOFF
              self.counter["発生"] = false
            end
          end
        end
        #…………………………………………………………………………………………………
        # ■ 条件がそろわない場合、失敗
        #…………………………………………………………………………………………………
        unless self.counter["発生"]
          self.damage = dup_damage
          # □受けるダメージを戻す
          self.counter["効果"] = self.damage
        end
      #…………………………………………………………………………………………………
      # ■ [カウンター]失敗の場合
      #…………………………………………………………………………………………………
      else
        if self.counter["失敗"] > 0 && self.damage > 0
          # □[カウンター]攻撃を受けるダメージ
          self.damage = [self.damage * (self.counter["失敗"] / 100),1].max
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # ■ カウンター発生時に表示するダメージ文字の設定
  #--------------------------------------------------------------------------
  if !$@;alias hidesp_counter_states_plus states_plus;end
  def states_plus(plus_state_set)
    if self.counter["発生"] 
      if counter["HP減"] == 0 or self.counter["死亡"]
        # クリティカルフラグをクリア
        self.critical = false
        #…………………………………………………………………………………………………
        # ■[カウンター]発生時に表示する文字
        #…………………………………………………………………………………………………
        self.damage = CAS_Ex::TEXT[1]
        case self.counter["種類"]
        when 3,4,5
          if self.counter["死亡"]
            # □死亡カウンター
            self.damage = CAS_Ex::TEXT[6]
          end
        when 6 # □回避
          self.damage = CAS_Ex::TEXT[2]
        when 7 # □受けた行動
          self.damage = CAS_Ex::TEXT[3]
        when 8 # □死亡回避
          self.damage = CAS_Ex::TEXT[4]
          self.hp = 1
        when 0,1,2
          if self.counter["反射"]
            # □ダメージ返し
            self.damage = CAS_Ex::TEXT[5]
          end
        end
        if self.counter["文字"] != nil
          self.damage = self.counter["文字"]
        end
      end
    end
    # □元の処理を呼び出し
    hidesp_counter_states_plus(plus_state_set)
  end
end
#==============================================================================
# ■ Window_Help
#==============================================================================
class Window_Help < Window_Base
  include CAS_Ex
  #--------------------------------------------------------------------------
  # ■ テキスト設定
  #--------------------------------------------------------------------------
  def set_text_action(text, align = 0)
    # □テキストとアラインメントの少なくとも一方が前回と違っている場合
    if text != @text or align != @align
      # □テキストを再描画
      self.contents.clear
      self.contents.font.color = normal_color
      if CAS_Ex::ICON_NAME
        self.contents.draw_cache_text(4, 0, self.width - 40, 32, text, align)
      else
        self.contents.draw_text(4, 0, self.width - 40, 32, text, align)
      end
      @text = text
      @align = align
      @actor = nil
    end
    self.visible = true
  end
end
#==============================================================================
# ■ Scene_Battle
#==============================================================================
class Scene_Battle
  include CAS_Ex
  #--------------------------------------------------------------------------
  # ■[カウンター]が発生した場合のアニメ
  #--------------------------------------------------------------------------
  def counter_action?(target)
    if target.counter["発生"] && ! target.counter["発動"]
      # □行動者もしくは対象が死亡している場合は無効
      unless @active_battler.exist? or target.exist?
        # □[カウンター]フラグを全初期化
        @active_battler.counter_clear
        return
      end
      # □[カウンター]発生アニメの表示
      @active_battler.damage_pop = true
      case target.counter["種類"]
      when 0,3 #□物理カウンター
        target.animation_id = CAS_Ex::ANIMATION[0]
      when 1,4 #□魔法カウンター
        target.animation_id = CAS_Ex::ANIMATION[2]
      when 2,5 #□アイテムカウンター
        target.animation_id = CAS_Ex::ANIMATION[2]
      when 6,8 #□回避カウンター
        target.animation_id = CAS_Ex::ANIMATION[1]
      else
        target.animation_id = CAS_Ex::ANIMATION[0]
      end
      if target.counter["演出"] != nil
        target.animation_id = target.counter["演出"]
      end
      # □アニメの保管
      if target.counter["種類"] == 7
        @animation2_id = target.user_attacker.animation2_id
      end
      @wait_count = 16
      target.animation_hit = (target.damage != "Miss")
      target.damage_pop = true
      #--------------------------------------------------------------------------
      # ■ヘルプウィンドウにカウンターを表示
      #--------------------------------------------------------------------------
      if target.restriction != 4 && ! target.current_action.forcing
        # □対象側バトラーを設定(回避カウンター/防御/逃げる/何もしないはターゲット無効)
        case target.counter["種類"]
        when 6,8,9,10,11
          # □行動ヘルプを表示するかの判定
          if target.counter["表示"] != 0 && target.counter["表示"] != 1 && target.counter["表示"] != 3
            @help_window.visible = false
            @wait_count = 8
            # □ウェイトが完了するまで待つ
            while @wait_count > 0
              Graphics.update
              @wait_count -= 1
            end
            case target.counter["種類"]
            when 9 # 防御
              # □ヘルプウィンドウにカウンターを表示
              if target.counter["解説"] != nil
                @help_window.set_text_action(target.counter["解説"], 1)
              else
                @help_window.set_text_action($data_system.words.guard, 1)
              end
            when 10 # 逃げる
              if target.is_a?(Game_Enemy)
                # □ヘルプウィンドウにカウンターを表示
                if target.counter["解説"] != nil
                  @help_window.set_text_action(target.counter["解説"], 1)
                else
                  @help_window.set_text_action("逃げる", 1)
                end
                # □[カウンター]フラグを全初期化
                target.counter_clear
                target.escape
                return
              end
            when 11 # 何もしない
              # □ヘルプウィンドウにカウンターを表示
              if target.counter["解説"] != nil
                @help_window.set_text_action(target.counter["解説"], 1)
              end
            else
              # □ヘルプウィンドウにカウンターを表示
              if target.counter["解説"] != nil
                @help_window.set_text_action(target.counter["解説"], 1)
              else
                @help_window.set_text_action(CAS_Ex::HELP[1], 1)
              end
            end
          end
        end
      end
      # □[カウンター]発生フラグをOFF
      target.counter["発生"] = false
      # □アクションを格納
      target.counter_actions = target.current_action.dup
      # □行動者をtargetに変更
      @active_battler = target
      # [カウンター]発動フラグをON
      @active_battler.counter["発動"] = true
      # □カウンター攻撃を代入！
      counter_action_select?(@active_battler)
      # □ターゲットを行動者に変更
      if target.counter["対象"] != nil
        target.user_attacker = target.counter["対象"]
      else
        # □カウンター発生フラグをOFF
        @active_battler.counter["発動"] = false
      end
    end
  end
  #--------------------------------------------------------------------------
  # ■ スキルまたはアイテムの対象側バトラー設定
  #--------------------------------------------------------------------------
  def counter_battlers?(user,scope)
    if user.is_a?(Game_Actor)
      battlers = $game_party.actors
    elsif user.is_a?(Game_Enemy)
      battlers = $game_troop.enemies
    end
    case scope
    when 2,4
      for i in battlers
        if i.exist?
          @target_battlers.push(i)
        end
      end
    when 6
      for i in battlers
        if i != nil && i.hp0?
          @target_battlers.push(i)
        end
      end
    when 1,3,7,0
      if user.exist?
        @target_battlers = [user]
      end
    when 5
      if user != nil && user.hp0?
        @target_battlers = [user]
      end
    else
      @target_battlers = []
    end
  end
  #--------------------------------------------------------------------------
  # ■ フレーム更新 (メインフェーズ ステップ 2 : アクション開始)
  #--------------------------------------------------------------------------
  if !$@;alias hidesp_counter_update_p4_s2 update_phase4_step2;end
  def update_phase4_step2
    
    
    #--------------------------------------------------------------------------
    # ■[カウンター]が発動した場合のアクション
    #--------------------------------------------------------------------------
    if @active_battler.counter["発動"] && @active_battler.restriction != 4 && 
      ! @active_battler.current_action.forcing
      
      user = @active_battler
      # 対象バトラーをクリア
      @target_battlers = []
      # アクションの種別で分岐
      case user.current_action.kind
      #…………………………………………………………………………………………………
      # ■ 基本アクション (カウンター攻撃)
      #…………………………………………………………………………………………………
      when 0
        # □対象側バトラーを設定(回避カウンター/何もしないはターゲット無効)
        if user.counter["種類"] != 6 && user.counter["種類"] != 8 && 
          user.counter["種類"] != 9 && user.counter["種類"] != 11
          counter_battlers?(user.user_attacker,0)
        end
        if @target_battlers != []
          # □行動ヘルプを表示するかの判定
          if user.counter["表示"] != 0 && user.counter["表示"] != 1 && user.counter["表示"] != 3
            # □ヘルプウィンドウにカウンターを表示
            if user.counter["解説"] != nil
              @help_window.set_text_action(user.counter["解説"], 1)
            else
              @help_window.set_text_action(CAS_Ex::HELP[1], 1)
            end
          end
          # アニメーション ID を設定
          @animation1_id = user.animation1_id
          if user.counter["種類"] != 7
            @animation2_id = user.animation2_id
          end
          # □対象の決定
          for target in @target_battlers
            target.attack_effect(user)
          end
        else
          # □ターゲットが無効の場合
          @phase4_step = 4
          return
        end
      #…………………………………………………………………………………………………
      # ■ スキルアクション(カウンタースキル)
      #…………………………………………………………………………………………………
      when 1  # スキル
        # スキルを取得
        @skill = $data_skills[user.current_action.skill_id]
        # □SP消費の判定
        if user.counter["消費"] && @skill != nil
          user.sp -= @skill.sp_cost
          # ステータスウィンドウをリフレッシュ
          @status_window.refresh
        end
        # □対象側バトラーを設定(回避カウンターはターゲット無効)
        if @skill != nil && user.counter["種類"] != 6 && 
          user.counter["種類"] != 8 && user.counter["消費"] != false
          counter_battlers?(user.user_attacker,@skill.scope)
        end
        if @target_battlers != []
          # □行動ヘルプを表示するかの判定
          if user.counter["表示"] != 0 && user.counter["表示"] != 1 && user.counter["表示"] != 3
            # □ヘルプウィンドウにスキル名を表示
            if user.counter["解説"] != nil
              @help_window.set_text_action(user.counter["解説"], 1)
            else
              if CAS_Ex::ICON_NAME
                @help_window.set_text_action("\\icon[#{@skill.icon_name}]" + @skill.name, 1)
              else
                @help_window.set_text_action(@skill.name, 1)
              end
            end
          end
          # アニメーション ID を設定
          @animation1_id = @skill.animation1_id
          @animation2_id = @skill.animation2_id
          # コモンイベント ID を設定
          @common_event_id = @skill.common_event_id
          # □対象の決定
          for target in @target_battlers
            target.skill_effect(user, @skill)
          end
        else
          # □ターゲットが無効の場合
          @phase4_step = 4
          return
        end
      #…………………………………………………………………………………………………
      # ■ アイテムアクション(カウンターアイテム)
      #…………………………………………………………………………………………………
      when 2  # アイテム
        # アイテムを取得
        @item = $data_items[user.current_action.item_id]
        # □アイテム消費の判定(消費無しアイテムも消費無し)
        if user.counter["消費"] && @item != nil
          if @item.consumable 
            $game_party.lose_item(@item.id, 1)
          end
        end
        # □対象側バトラーを設定(回避カウンターはターゲット無効)
        if @item != nil && user.counter["種類"] != 6 && 
          user.counter["種類"] != 8 && user.counter["消費"] != false
          counter_battlers?(user.user_attacker,@item.scope)
        end
        if @target_battlers != []
          # □行動ヘルプを表示するかの判定
          if user.counter["表示"] != 0 && user.counter["表示"] != 1 && user.counter["表示"] != 3
            # □ヘルプウィンドウにアイテム名を表示
            if user.counter["解説"] != nil
              @help_window.set_text_action(user.counter["解説"], 1)
            else
              if CAS_Ex::ICON_NAME
                @help_window.set_text_action("\\icon[#{@item.icon_name}]" + @item.name, 1)
              else
                @help_window.set_text_action(@item.name, 1)
              end
            end
          end
          # アニメーション ID を設定
          @animation1_id = @item.animation1_id
          @animation2_id = @item.animation2_id
          # コモンイベント ID を設定
          @common_event_id = @item.common_event_id
          # □対象の決定
          for target in @target_battlers
            target.item_effect(@item)
          end
        else
          # □ターゲットが無効の場合
          @phase4_step = 4
          return
        end
      end
      #…………………………………………………………………………………………………
      # ■ 行動アニメを表示するかの判定
      #…………………………………………………………………………………………………
      if @phase4_step == 2
        if user.counter["表示"] != 0 && user.counter["表示"] != 1 && user.counter["表示"] != 2
          @phase4_step = 3
        else
          @phase4_step = 4
        end
      end
    else
      # □元の処理を呼び出し
      hidesp_counter_update_p4_s2
    end
  end
  #--------------------------------------------------------------------------
  # ■ フレーム更新 (メインフェーズ ステップ 5 : ダメージ表示)
  #--------------------------------------------------------------------------
  if !$@;alias hidesp_counter_update_p4s5 update_phase4_step5;end
  def update_phase4_step5
    #…………………………………………………………………………………………………
    # ■[カウンター]全体攻撃は無効
    #…………………………………………………………………………………………………
    if @target_battlers.size != 1
      # □[カウンター]の終了処理
      counter_action_end?(@active_battler,@target_battlers[0])
      # □元の処理を呼び出し
      hidesp_counter_update_p4s5
      return
    end
    target = @target_battlers[0]
    
    #…………………………………………………………………………………………………
    # ■[カウンター]条件を満たす場合
    #…………………………………………………………………………………………………
    
    if (target.counter["発生"] && 
      ! target.counter["発動"]) or @active_battler.counter["発動"]
      # □ヘルプウィンドウを隠す
      @help_window.visible = false
      # □ステータスウィンドウをリフレッシュ
      @status_window.refresh
      # □[カウンター]の確認/終了処理
      counter_action_end?(@active_battler,target)
      # □行動者をターゲットに変更
      counter_action?(target)
      target.damage_pop = true
      # □追加アクションの処理
      plus_counter_action?
      # □[カウンター]の開始
      if @active_battler.counter["発動"] 
        if @active_battler.counter["回数"] == nil
          @phase4_step = 2
          return
        end
        # □[カウンター]の回数条件
        if @active_battler.counter["回数"] > 0
          @active_battler.counter["回数"] -= 1
          if @active_battler.counter["回数"] == 0
            @active_battler.remove_state(@active_battler.counter["解除"])
          end
          @phase4_step = 2
          return
        end
        if @active_battler.counter["回数"] == 0
          @active_battler.remove_state(@active_battler.counter["解除"])
        end
      end
      # ステップ 6 に移行
      @phase4_step = 6
    else
      # □元の処理を呼び出し
      hidesp_counter_update_p4s5
      return
    end
  end
  #--------------------------------------------------------------------------
  # ■[カウンター]が発動した場合
  #--------------------------------------------------------------------------
  def counter_action_end?(user,target)
    if user.counter["発動"]
      dup_damage = user.counter["効果"]
      #…………………………………………………………………………………………………
      # ■ [死亡]カウンターの発動処理を実行
      #…………………………………………………………………………………………………
      if user.counter["死亡"] && user.counter["種類"] != 8
        user.damage_pop = true
        user.damage = user.counter["効果"]
        @wait_count = 16
        # □[戦闘不能]を付加
        user.add_state(1)
        # ステータスウィンドウをリフレッシュ
        @status_window.refresh
      end
      #…………………………………………………………………………………………………
      # ■カウンターカウントが残っている場合
      #…………………………………………………………………………………………………
      if user.counter_count != nil
        if user.counter_count > 0
          user.counter_count -= 1
          user.counter = user.counter_states[user.counter_count]
          # □カウンター攻撃を代入！
           counter_action_select?(user)
          user.counter["発動"] = true
          user.counter["効果"] = dup_damage
          # □行動者が死亡している場合は無効
          if user.exist?
            @phase4_step = 2
            return
          end
        end
      end
      #…………………………………………………………………………………………………
      # ■アクションを戻す
      #…………………………………………………………………………………………………
      user.current_action.kind = user.counter_actions.kind
      user.current_action.basic = user.counter_actions.basic
      user.current_action.target_index = user.counter_actions.target_index
      user.current_action.skill_id = user.counter_actions.skill_id
      user.current_action.item_id = user.counter_actions.item_id
      #…………………………………………………………………………………………………
      # ■[カウンター]フラグを全初期化
      #…………………………………………………………………………………………………
      n_c = user.counter["回数"]
      user.counter_clear
      user.counter["回数"] = n_c
    else
      #…………………………………………………………………………………………………
      # ■カウンターカウントが残っている場合
      #…………………………………………………………………………………………………
      if user.counter_count != nil
        if user.counter_count > 0
          user.counter_count -= 1
          user.counter = user.counter_states[user.counter_count]
          # □カウンター攻撃を代入！
          counter_action_select?(user)
          user.counter["発動"] = true
          user.counter["効果"] = dup_damage
          # □行動者が死亡している場合は無効
          if user.exist?
            @phase4_step = 2
            return
          end
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # ■ [カウンター]の種類
  #--------------------------------------------------------------------------
  def counter_action_select?(user)
    user.current_action.basic = 0
    user.current_action.skill_id = 0
    user.current_action.item_id = 0
    case user.counter["種類"]
    when 0,3 # 通常攻撃
      user.current_action.kind = 0
    when 1,4 # スキル
      user.current_action.skill_id = user.counter["ID"]
      user.current_action.kind = 1
    when 2,5 # アイテム
      user.current_action.item_id = user.counter["ID"]
      user.current_action.kind = 2
    when 6,8 # カウンター行動無し(回避)
      user.current_action.basic = 3
    when 7 # コピーカウンター(受けた攻撃と同じ)
      user.current_action.kind = user.user_attacker.current_action.kind
      user.current_action.skill_id = user.user_attacker.current_action.skill_id
      user.current_action.item_id = user.user_attacker.current_action.item_id
    when 9 # 防御
      user.current_action.basic = 1
    when 10 # 逃げる
      if user.is_a?(Game_Enemy)
        user.current_action.basic = 2
      end
    when 11 # 何もしない
      user.current_action.basic = 3
    end
  end
  #--------------------------------------------------------------------------
  # ■[カウンター]が発動した場合追加アクションの処理
  #--------------------------------------------------------------------------
  def plus_counter_action?
  end
end