VX 스크립트

적캐릭터나 아군이 피해를 받을 시에 반격을 사용하게끔 만들어주는 스크립트입니다.

찾아봤는데 아방스에 없는 것 같아서 가져왔습니다. 

 

무기 방어구 상태 적 캐릭터 의 데이터베이스 화면에서 MEMO란에

<COUNTER>
</COUNTER>

라고 쓰고 이 두 줄 사이에 조건을 설정하면 됩니다. 조건을 설정하지 않을 경우 모든 공격과 스킬에 대해 무조건 반격을

실시하게 됩니다.(보스 캐릭터에 넣으면 딱 좋죠... 때리기 겁나는 보스...)

조건은

KIND A (KIND A,G,S,I)  : A는 모든 공격에 대해 반격(안 적으셔도 됩니다.) G는 가드시에, S는 스킬, I는 아이템 사용 시 반격입니다.

PHYSICAL_ATTACK  물리 공격에 대한 반격을 실시합니다.

MAGICAL_ATTACK  마법 공격에 대한 반격을 실시합니다.

ELEMENT   뒤에 해당 속성의 번호를 적으시면 반격할 시 해당 속성으로 반격합니다.

ATK_F       F 뒤에 1~100까지의 숫자를 입력하시면 됩니다. 반격할 시 타격관계도를 나타냅니다.

SPI_F           위와 마찬가지! 정신관계도를 나타냅니다.

REMAIN_HP(MP) xx OVER(UNDER) HP가 몇 퍼센트 이상(이하)일 때 반격기가 나가는 지를 설정합니다.

IGNORE_TARGET  공격 대상에 관계없이 반격을 실시합니다. (적이 가드 중일 때 반격을 넣으려면 써야한답니다.)

인터럽트 기능은... 저도 잘 모르겠군요... 반격 성공이나 실패 시 상태 변경을 추가하는 것 같은데... 굳이 필요가....

 

또한 반격을 할 확률을 정해주고 싶으시면 맨 윗 줄의 <COUNTER> 를  <COUNTER 50%> 이런 식으로 고쳐 주시면 됩니다.

이렇게 하면 50% 확률로 반격을 실시하지요...

 

17번째 줄의 RESTRICT_COUNTER = true 를  true에서 false로 고치시면

공격 횟수 별로 반격을 실시합니다. true일 경우 상대가 연속 공격을 하더라도 한 번만 반격하고, false 일 경우 2회 3회건 모두 반격합니다.

(true로 하십시오;  false로 하고 게임하면 뭔가 이상합니다; 어? 너 나 두 대 때렸어? 나도 두 대 때릴래!.............. 그래 때려 맞아줄게! 잇힝

같은 기분입니다.....)

 

EX)

<COUNTER 50%>
PHYSICAL_ATTACK
</COUNTER>

물리 공격(스킬도 타격 관계 스킬일 경우 포함)에 대해 50%의 확률로 반격합니다.

 

<COUNTER>
MAGICAL_ATTACK

</COUNTER>

마법 공격에 대해 100%확률로 반격합니다.

 

<COUNTER>

ELEMENT10
</COUNTER>

모든 공격에 대해 100%확률로 반격하며 반격 시 ID 10번 속성으로 공격합니다.

 

<COUNTER 75%>
PHYSICAL_ATTACK

ELEMENT8
REMEIN_HP 40 OVER
</COUNTER>

사용자의 체력이 40% 이상 남아 있을 때 물리 공격으로 피해를 받을 시 75%확률로 8번 속성의 공격으로 반격합니다.

 

등등..... 만들기는 쉽습니다.

아 참! KIND 조건을 설정할 경우 S나 I의 조건에 :(IDxx) 를 붙여서 해당 스킬이나 아이템에만 반격하도록 설정할 수도 있습니다.

(그런데 뭐하러 굳이.....그런 설정을....)

이상입니다.

 

이 아래부터 스크립트입니다.

#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/    ◆ カウンター - KGC_Counter ◆ VX ◆
#_/    ◇ Last update : 2009/09/13 ◇
#_/----------------------------------------------------------------------------
#_/  特定の行動に対するカウンターを作成します。
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

#==============================================================================
# ★ カスタマイズ項目 - Customize BEGIN ★
#==============================================================================

module KGC
module Counter
  # ◆ カウンター回数を制限する
  #  true  : カウンターは 1 回のアクションにつき 1 回のみ。
  #  false : 条件を満たした数だけカウンター発動。
  RESTRICT_COUNTER = true

  # ◆ 通常攻撃カウンターのメッセージ
  #  %s : 攻撃者の名前
  VOCAB_COUNTER_ATTACK = "%s의 반격!"

  # ◆ 割り込みカウンターのメッセージ
  #   \N : 行動者の名前
  #   \C : カウンター発動者の名前
  #   \A : 割り込む行動の名前
  #  '~' で指定する場合、 は一つで OK。
  #  カウンター定義内で指定した場合は、そちらを優先。
  VOCAB_INTERRUPT_COUNTER = 'CisNfuck!'
end
end

#==============================================================================
# ☆ カスタマイズ項目終了 - Customize END ☆
#==============================================================================

$imported = {} if $imported == nil
$imported["Counter"] = true

module KGC
module Counter
  module Regexp
    # カウンター定義開始
    BEGIN_COUNTER = /<(?:COUNTER|カウンター)s*([ASI])?(s*:s*d+)?
                     (s+d+[%%])?(s*/)?>/ix
    # カウンター定義終了
    END_COUNTER = /</(?:COUNTER|カウンター)>/i

    # ~ カウンター条件 ~
    # 行動種別
    KIND = /^s*(?:KIND|種別)s*([AGSI])(s*:s*d+(?:s*,s*d+)*)?/i
    # 攻撃タイプ
    ATTACK_TYPE = /^s*(PHYSICAL|MAGICAL|物理|魔法)(?:_ATTACK|攻撃)/i
    # 属性
    ELEMENT = /^s*(?:ELEMENT|属性)s*(d+(?:s*,s*d+)*)/i
    # 打撃関係度
    ATK_F = /^s*(?:ATK_F|打撃関係度)s*(d+)(?:s*以上)?/i
    # 精神関係度
    SPI_F = /^s*(?:SPI_F|精神関係度)s*(d+)(?:s*以上)?/i
    # 残存 HP/MP
    REMAIN_HPMP = /^s*(?:REMAIN_|残存)?(HP|MP)s*(d+)(?:s*[%%]s*)
                   (OVER|UNDER|以上|以下)/ix
    # ターゲット無視
    IGNORE_TARGET = /^s*(?:IGNORE_TARGET|ターゲット無視)/i
    # 行動割り込み
    INTERRUPT = /^s*(?:ACTION_|行動)?(?:INTERRUPT|割り?込み)s*$/i

    # ~ メッセージ ~
    INTERRUPT_MESSAGE = /^s*(?:INTERRUPT_MESSAGE|割り?込みメッセージ)s*"
                         ([^"]*)(")?/ix
  end

  KIND_ALL   = -1  # 種別 : ALL
  KIND_BASIC =  0  # 種別 : 基本
  KIND_SKILL =  1  # 種別 : スキル
  KIND_ITEM  =  2  # 種別 : アイテム

  BASIC_ATTACK = 0  # 基本行動 : 攻撃
  BASIC_GUARD  = 1  # 基本行動 : 防御

  TYPE_ALL      = -1  # 攻撃タイプ : ALL
  TYPE_PHYSICAL =  0  # 攻撃タイプ : 物理
  TYPE_MAGICAL  =  1  # 攻撃タイプ : 魔法

  REMAIN_TYPE_OVER  = 0  # 残存 : x 以上
  REMAIN_TYPE_UNDER = 1  # 残存 : x 以下

  # 種別変換表
  COUNTER_KINDS = {
    "A" => KIND_BASIC,
    "G" => KIND_BASIC,
    "S" => KIND_SKILL,
    "I" => KIND_ITEM,
  }

  # 基本行動変換表
  COUNTER_BASIC = {
    "A" => BASIC_ATTACK,
    "G" => BASIC_GUARD
  }

  # 攻撃タイプ変換表
  COUNTER_TYPES = {
    "PHYSICAL" => TYPE_PHYSICAL,
    "物理"     => TYPE_PHYSICAL,
    "MAGICAL"  => TYPE_MAGICAL,
    "魔法"     => TYPE_MAGICAL
  }

  #--------------------------------------------------------------------------
  # ○ カウンター行動リストの作成
  #     note : メモ欄
  #--------------------------------------------------------------------------
  def self.create_counter_action_list(note)
    result = []

    counter_flag = false
    action = nil

    interrupt_message = ""
    define_interrupt_message = false
    note.each_line { |line|
      if line =~ KGC::Counter::Regexp::BEGIN_COUNTER
        match = $~.clone
        # カウンター定義開始
        action = Game_CounterAction.new
        if match[1] != nil
          action.kind = COUNTER_KINDS[match[1].upcase]
        end
        case action.kind
        when KIND_SKILL
          next if match[2] == nil
          action.skill_id = match[2][/d+/].to_i
        when KIND_ITEM
          next if match[2] == nil
          action.item_id = match[2][/d+/].to_i
        end
        if match[3] != nil
          action.execute_prob = match[3][/d+/].to_i
        end
        counter_flag = true
        if match[4] != nil
          # そのまま定義終了
          result << action
          counter_flag = false
        end
      end

      next unless counter_flag

      # 割り込みメッセージ定義中
      if define_interrupt_message
        if line =~ /s*([^"]*)(")?/
          action.interrupt_message += $1.chomp
          define_interrupt_message = ($2 == nil)
        end
        next
      end

      case line
      when KGC::Counter::Regexp::END_COUNTER
        # カウンター定義終了
        result << action
        counter_flag = false

      when KGC::Counter::Regexp::KIND
        # 行動種別
        match = $~.clone
        action.condition.kind = COUNTER_KINDS[match[1].upcase]
        if action.condition.kind == KIND_BASIC
          action.condition.basic = COUNTER_BASIC[match[1].upcase]
          if action.condition.basic == nil
            action.condition.basic = KGC::Counter::BASIC_ATTACK
          end
        end
        if match[2] != nil
          ids = []
          match[2].scan(/d+/).each { |num| ids << num.to_i }
          case action.condition.kind
          when KIND_SKILL
            action.condition.skill_ids = ids
          when KIND_ITEM
            action.condition.item_ids = ids
          end
        end

      when KGC::Counter::Regexp::ATTACK_TYPE
        # 攻撃タイプ
        action.condition.type = COUNTER_TYPES[$1.upcase]

      when KGC::Counter::Regexp::ELEMENT
        # 属性
        elements = []
        $1.scan(/d+/).each { |num| elements << num.to_i }
        action.condition.element_set |= elements

      when KGC::Counter::Regexp::ATK_F
        # 打撃関係度
        action.condition.atk_f = $1.to_i

      when KGC::Counter::Regexp::SPI_F
        # 精神関係度
        action.condition.spi_f = $1.to_i

      when KGC::Counter::Regexp::REMAIN_HPMP
        type = REMAIN_TYPE_OVER
        case $3.upcase
        when "UNDER", "以下"
          type = REMAIN_TYPE_UNDER
        end
        case $1.upcase
        when "HP"  # 残存 HP
          action.condition.remain_hp = $2.to_i
          action.condition.remain_hp_type = type
        when "MP"  # 残存 MP
          action.condition.remain_mp = $2.to_i
          action.condition.remain_mp_type = type
        end

      when KGC::Counter::Regexp::IGNORE_TARGET
        # ターゲット無視
        action.condition.ignore_target = true

      when KGC::Counter::Regexp::INTERRUPT
        # 行動割り込み
        action.condition.interrupt = true

      when KGC::Counter::Regexp::INTERRUPT_MESSAGE
        # 割り込みメッセージ
        define_interrupt_message = true
        action.interrupt_message += $1.chomp
        define_interrupt_message = ($2 == nil)
      end
    }
    return result
  end
end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ Vocab
#==============================================================================

module Vocab
  # カウンター関連メッセージ
  CounterAttack = KGC::Counter::VOCAB_COUNTER_ATTACK
  InterruptCounter = KGC::Counter::VOCAB_INTERRUPT_COUNTER
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ RPG::BaseItem
#==============================================================================

class RPG::BaseItem
  #--------------------------------------------------------------------------
  # ○ カウンター行動リスト
  #--------------------------------------------------------------------------
  def counter_actions
    if @__counter_actions == nil
      @__counter_actions = KGC::Counter.create_counter_action_list(self.note)
    end
    return @__counter_actions
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ RPG::Enemy
#==============================================================================

class RPG::Enemy
  #--------------------------------------------------------------------------
  # ○ カウンター行動リスト
  #--------------------------------------------------------------------------
  def counter_actions
    if @__counter_actions == nil
      @__counter_actions = KGC::Counter.create_counter_action_list(self.note)
    end
    return @__counter_actions
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ RPG::State
#==============================================================================

class RPG::State
  #--------------------------------------------------------------------------
  # ○ カウンター行動リスト
  #--------------------------------------------------------------------------
  def counter_actions
    if @__counter_actions == nil
      @__counter_actions = KGC::Counter.create_counter_action_list(self.note)
    end
    return @__counter_actions
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ Game_BattleAction
#==============================================================================

class Game_BattleAction
  #--------------------------------------------------------------------------
  # ○ 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_accessor :made_targets             # 作成済みターゲット
  #--------------------------------------------------------------------------
  # ● ターゲットの配列作成
  #--------------------------------------------------------------------------
  alias make_targets_KGC_Counter make_targets
  def make_targets
    if @made_targets == nil
      @made_targets = make_targets_KGC_Counter
    end
    return @made_targets
  end
  #--------------------------------------------------------------------------
  # ○ アクション名
  #--------------------------------------------------------------------------
  def action_name
    case kind
    when 0  # 基本
      case basic
      when 0  # 攻撃
        return Vocab.attack
      when 1  # 防御
        return Vocab.guard
      when 2  # 逃走
        return Vocab.escape
      when 3  # 待機
        return Vocab.wait
      end
    when 1  # スキル
      return skill.name
    when 2  # アイテム
      return item.name
    end
    return ""
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# □ Game_CounterAction
#------------------------------------------------------------------------------
#   カウンター行動を扱うクラスです。
#==============================================================================

class Game_CounterAction
  #--------------------------------------------------------------------------
  # ○ 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_accessor :kind                     # 種別 (基本 / スキル / アイテム)
  attr_accessor :basic                    # 基本 (攻撃 / 防御 / 逃走 / 待機)
  attr_accessor :skill_id                 # スキル ID
  attr_accessor :item_id                  # アイテム ID
  attr_accessor :execute_prob             # 発動確率
  attr_accessor :condition                # 発動条件
  attr_accessor :interrupt_message        # 割り込みメッセージ
  #--------------------------------------------------------------------------
  # ○ オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize
    clear
  end
  #--------------------------------------------------------------------------
  # ○ クリア
  #--------------------------------------------------------------------------
  def clear
    @kind              = KGC::Counter::KIND_BASIC
    @basic             = KGC::Counter::BASIC_ATTACK
    @skill_id          = 0
    @item_id           = 0
    @execute_prob      = 100
    @condition         = Game_CounterCondition.new
    @interrupt_message = ""
  end
  #--------------------------------------------------------------------------
  # ○ 有効判定
  #     attacker : 攻撃者
  #     defender : 被攻撃者
  #--------------------------------------------------------------------------
  def valid?(attacker, defender)
    return false unless attacker.actor? ^ defender.actor?  # 相手が味方

    return condition.valid?(attacker, defender)
  end
  #--------------------------------------------------------------------------
  # ○ 発動判定
  #--------------------------------------------------------------------------
  def exec?
    return (execute_prob > rand(100))
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# □ Game_CounterCondition
#------------------------------------------------------------------------------
#   カウンター条件を扱うクラスです。
#==============================================================================

class Game_CounterCondition
  #--------------------------------------------------------------------------
  # ○ 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_accessor :kind                     # 種別 (ALL / 基本 / スキル / アイテム)
  attr_accessor :basic                    # 基本 (攻撃 / 防御 / 逃走 / 待機)
  attr_accessor :skill_ids                # スキル ID リスト
  attr_accessor :item_ids                 # アイテム ID リスト
  attr_accessor :type                     # 攻撃タイプ (ALL / 物理 / 魔法)
  attr_accessor :element_set              # 属性
  attr_accessor :atk_f                    # 打撃関係度
  attr_accessor :spi_f                    # 精神関係度
  attr_accessor :remain_hp                # 残存 HP
  attr_accessor :remain_hp_type           # 残存 HP の形式 (以上 / 以下)
  attr_accessor :remain_mp                # 残存 MP
  attr_accessor :remain_mp_type           # 残存 MP の形式 (以上 / 以下)
  attr_accessor :ignore_target            # ターゲット無視
  attr_accessor :interrupt                # 行動割り込み
  #--------------------------------------------------------------------------
  # ○ オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize
    clear
  end
  #--------------------------------------------------------------------------
  # ○ クリア
  #--------------------------------------------------------------------------
  def clear
    @kind           = KGC::Counter::KIND_ALL
    @basic          = KGC::Counter::BASIC_ATTACK
    @skill_ids      = []
    @item_ids       = []
    @type           = KGC::Counter::TYPE_ALL
    @element_set    = []
    @atk_f          = 0
    @spi_f          = 0
    @remain_hp      = 0
    @remain_hp_type = KGC::Counter::REMAIN_TYPE_OVER
    @remain_mp      = 0
    @remain_mp_type = KGC::Counter::REMAIN_TYPE_OVER
    @ignore_target  = false
    @interrupt      = false
  end
  #--------------------------------------------------------------------------
  # ○ 有効判定
  #     attacker : 攻撃者
  #     defender : 被攻撃者
  #--------------------------------------------------------------------------
  def valid?(attacker, defender)
    obj = nil
    if attacker.action.skill?
      obj = attacker.action.skill
    elsif attacker.action.item?
      obj = attacker.action.item
    end

    return false unless kind_valid?(attacker, defender, obj)
    return false unless attack_type_valid?(attacker, defender, obj)
    return false unless element_valid?(attacker, defender, obj)
    return false unless atk_f_valid?(attacker, defender, obj)
    return false unless spi_f_valid?(attacker, defender, obj)
    return false unless remain_hpmp_valid?(attacker, defender, obj)

    return true
  end
  #--------------------------------------------------------------------------
  # ○ 種別有効判定
  #     attacker : 攻撃者
  #     defender : 被攻撃者
  #     obj      : スキルまたはアイテム
  #--------------------------------------------------------------------------
  def kind_valid?(attacker, defender, obj)
    return true  if @kind == KGC::Counter::KIND_ALL
    return false if @kind != attacker.action.kind

    case @kind
    when KGC::Counter::KIND_BASIC
      return (@basic == attacker.action.basic)
    when KGC::Counter::KIND_SKILL
      # スキル ID 判定
      return true if @skill_ids.empty?
      @skill_ids.each { |sid|
        return true if sid == attacker.action.skill_id
      }
      return false
    when KGC::Counter::KIND_ITEM
      # アイテム ID 判定
      return true if @item_ids.empty?
      @item_ids.each { |iid|
        return true if iid == attacker.action.item_id
      }
      return false
    end
    return false
  end
  #--------------------------------------------------------------------------
  # ○ 攻撃タイプ有効判定
  #     attacker : 攻撃者
  #     defender : 被攻撃者
  #     obj      : スキルまたはアイテム
  #--------------------------------------------------------------------------
  def attack_type_valid?(attacker, defender, obj)
    return true if @type == KGC::Counter::TYPE_ALL

    if obj == nil
      # 物理カウンターでない
      return false if @type != KGC::Counter::TYPE_PHYSICAL
    else
      # [物理攻撃] なら物理、そうでなければ魔法カウンター判定
      if @type != (obj.physical_attack ?
          KGC::Counter::TYPE_PHYSICAL : KGC::Counter::TYPE_MAGICAL)
        return false
      end
    end
    return true
  end
  #--------------------------------------------------------------------------
  # ○ 属性有効判定
  #     attacker : 攻撃者
  #     defender : 被攻撃者
  #     obj      : スキルまたはアイテム
  #--------------------------------------------------------------------------
  def element_valid?(attacker, defender, obj)
    return true if @element_set.empty?

    if attacker.action.attack?
      elements = attacker.element_set
    else
      return false if obj == nil
      # 属性リスト取得
      if $imported["SetAttackElement"]
        elements = defender.get_inherited_element_set(attacker, obj)
      else
        elements = obj.element_set
      end
    end
    return !(@element_set & elements).empty?
  end
  #--------------------------------------------------------------------------
  # ○ 打撃関係度有効判定
  #     attacker : 攻撃者
  #     defender : 被攻撃者
  #     obj      : スキルまたはアイテム
  #--------------------------------------------------------------------------
  def atk_f_valid?(attacker, defender, obj)
    return true if @atk_f == 0

    n = (attacker.action.attack? ? 100 : (obj != nil ? obj.atk_f : 0) )
    return (@atk_f <= n)
  end
  #--------------------------------------------------------------------------
  # ○ 精神関係度有効判定
  #     attacker : 攻撃者
  #     defender : 被攻撃者
  #     obj      : スキルまたはアイテム
  #--------------------------------------------------------------------------
  def spi_f_valid?(attacker, defender, obj)
    return true if @spi_f == 0

    n = (attacker.action.attack? ? 0 : (obj != nil ? obj.spi_f : 0) )
    return (@spi_f <= n)
  end
  #--------------------------------------------------------------------------
  # ○ 残存 HP/MP 有効判定
  #     attacker : 攻撃者
  #     defender : 被攻撃者
  #     obj      : スキルまたはアイテム
  #--------------------------------------------------------------------------
  def remain_hpmp_valid?(attacker, defender, obj)
    hp_rate = defender.hp * 100 / defender.maxhp
    case @remain_hp_type
    when KGC::Counter::REMAIN_TYPE_OVER
      return false unless (hp_rate >= @remain_hp)
    when KGC::Counter::REMAIN_TYPE_UNDER
      return false unless (hp_rate <= @remain_hp)
    end

    mp_rate = defender.mp * 100 / [defender.maxmp, 1].max
    case @remain_mp_type
    when KGC::Counter::REMAIN_TYPE_OVER
      return false unless (mp_rate >= @remain_mp)
    when KGC::Counter::REMAIN_TYPE_UNDER
      return false unless (mp_rate <= @remain_mp)
    end

    return true
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# □ Game_CounterInfo
#------------------------------------------------------------------------------
#   カウンター情報を扱うクラスです。
#==============================================================================

class Game_CounterInfo
  #--------------------------------------------------------------------------
  # ○ 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_accessor :battler                  # 行動者
  attr_accessor :action                   # カウンター行動
  attr_accessor :target_index             # 対象インデックス
  #--------------------------------------------------------------------------
  # ○ オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize
    @battler      = nil
    @action       = nil
    @target_index = 0
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ Game_Battler
#==============================================================================

class Game_Battler
  #--------------------------------------------------------------------------
  # ○ カウンター行動リストの取得
  #--------------------------------------------------------------------------
  def counter_actions
    result = []
    states.each { |state| result += state.counter_actions }
    return result
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ Game_Actor
#==============================================================================

class Game_Actor < Game_Battler
  #--------------------------------------------------------------------------
  # ○ カウンター行動リストの取得
  #--------------------------------------------------------------------------
  def counter_actions
    result = super
    equips.compact.each { |item| result += item.counter_actions }
    return result
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ Game_Enemy
#==============================================================================

class Game_Enemy < Game_Battler
  #--------------------------------------------------------------------------
  # ○ カウンター行動リストの取得
  #--------------------------------------------------------------------------
  def counter_actions
    return (super + enemy.counter_actions)
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ Scene_Battle
#==============================================================================

class Scene_Battle < Scene_Base
  #--------------------------------------------------------------------------
  # ● 開始処理
  #--------------------------------------------------------------------------
  alias start_KGC_Counter start
  def start
    start_KGC_Counter

    @counter_added = false
    @counter_infos = []
  end
  #--------------------------------------------------------------------------
  # ● 戦闘行動の処理
  #--------------------------------------------------------------------------
  alias process_action_KGC_Counter process_action
  def process_action
    process_action_KGC_Counter

    register_ignore_target_counter_action
    unset_counter_action
  end
  #--------------------------------------------------------------------------
  # ○ カウンター行動の解除
  #--------------------------------------------------------------------------
  def unset_counter_action
    return unless @counter_exec

    # 行動を元に戻す
    @active_battler.action.forcing      = @former_action.forcing
    @active_battler.action.kind         = @former_action.kind
    @active_battler.action.basic        = @former_action.basic
    @active_battler.action.skill_id     = @former_action.skill_id
    @active_battler.action.item_id      = @former_action.item_id
    @active_battler.action.target_index = @former_action.target_index
    @active_battler.action.made_targets = nil
    @active_battler.action.make_targets

    @former_action     = nil
    @counter_exec      = false
    @counter_interrupt = false
  end
  #--------------------------------------------------------------------------
  # ● 次に行動するべきバトラーの設定
  #--------------------------------------------------------------------------
  alias set_next_active_battler_KGC_Counter set_next_active_battler
  def set_next_active_battler
    set_counter_action

    unless @counter_exec
      set_next_active_battler_KGC_Counter
    end
  end
  #--------------------------------------------------------------------------
  # ○ カウンター行動の作成
  #--------------------------------------------------------------------------
  def set_counter_action
    @former_action     = nil
    @counter_exec      = false
    @counter_added     = false
    @counter_interrupt = false
    counter = @counter_infos.shift  # <-- Game_CounterInfo
    return if counter == nil

    last_active_battler = @active_battler
    @active_battler     = counter.battler
    # 元の行動を退避
    @former_action = @active_battler.action.clone
    @counter_exec  = true
    # カウンター行動を設定
    @active_battler.action.kind     = counter.action.kind
    @active_battler.action.basic    = counter.action.basic
    @active_battler.action.skill_id = counter.action.skill_id
    @active_battler.action.item_id  = counter.action.item_id

    # カウンター対象を設定
    target_index = counter.target_index
    # 対象が味方なら自分に対して発動
    if @active_battler.action.for_friend?
      target_index = @active_battler.index
    end
    @active_battler.action.target_index = target_index
    @active_battler.action.made_targets = nil
    @active_battler.action.make_targets

    unless @active_battler.action.valid?
      # カウンター発動不能ならキャンセル
      unset_counter_action
      @active_battler = last_active_battler
    else
      @active_battler.action.forcing = true
    end
  end
  #--------------------------------------------------------------------------
  # ● 戦闘行動の実行
  #--------------------------------------------------------------------------
  alias execute_action_KGC_Counter execute_action
  def execute_action
    unless @counter_exec
      register_interrupt_counter_action
    end

    if @counter_interrupt
      execute_interrupt_counter
    else
      execute_action_KGC_Counter
    end
    unset_counter_action
    @active_battler.action.made_targets = nil
  end
  #--------------------------------------------------------------------------
  # ● 戦闘行動の実行 : 攻撃
  #--------------------------------------------------------------------------
  alias execute_action_attack_KGC_Counter execute_action_attack
  def execute_action_attack
    if @counter_exec
      # 攻撃時メッセージを無理矢理書き換える
      old_DoAttack = Vocab::DoAttack
      Vocab.const_set(:DoAttack, Vocab::CounterAttack)
    end

    execute_action_attack_KGC_Counter

    if @counter_exec
      # 後始末
      Vocab.const_set(:DoAttack, old_DoAttack)
    end
  end
  #--------------------------------------------------------------------------
  # ● 行動結果の表示
  #     target : 対象者
  #     obj    : スキルまたはアイテム
  #--------------------------------------------------------------------------
  alias display_action_effects_KGC_Counter display_action_effects
  def display_action_effects(target, obj = nil)
    display_action_effects_KGC_Counter(target, obj)

    unless target.skipped
      register_counter_action(target)
    end
  end
  #--------------------------------------------------------------------------
  # ○ カウンター行動の登録
  #     target    : 被攻撃者
  #     interrupt : 割り込みフラグ
  #--------------------------------------------------------------------------
  def register_counter_action(target, interrupt = false)
    return unless can_counter?(target)

    # 有効なカウンター行動をセット
    target.counter_actions.each { |counter|
      break if counter_added?
      next  if counter.condition.ignore_target
      next  if counter.condition.interrupt ^ interrupt  # <-- if x != y
      judge_counter_action(@active_battler, target, counter)
    }
  end
  #--------------------------------------------------------------------------
  # ○ カウンター可否
  #     target : 被攻撃者
  #--------------------------------------------------------------------------
  def can_counter?(target = nil)
    return false if @counter_exec   # カウンターに対するカウンターは行わない
    return false if counter_added?  # カウンター済み
    if target != nil
      return false unless target.movable?  # 行動不能
    end

    if $imported["CooperationSkill"]
      # 連係スキルにはカウンターを適用しない
      return false if @active_battler.is_a?(Game_CooperationBattler)
    end

    return true
  end
  #--------------------------------------------------------------------------
  # ○ カウンター登録済み判定
  #--------------------------------------------------------------------------
  def counter_added?
    return (KGC::Counter::RESTRICT_COUNTER && @counter_added)
  end
  #--------------------------------------------------------------------------
  # ○ カウンター判定
  #     attacker : 攻撃者
  #     target   : 被攻撃者
  #     counter  : カウンター行動
  #--------------------------------------------------------------------------
  def judge_counter_action(attacker, target, counter)
    return unless counter.valid?(attacker, target)
    return unless counter.exec?

    info = Game_CounterInfo.new
    info.battler = target
    info.action  = counter
    info.target_index = attacker.index
    @counter_infos << info
    @counter_added = true
  end
  #--------------------------------------------------------------------------
  # ○ ターゲット無視のカウンター行動の登録
  #     interrupt : 割り込み判定
  #--------------------------------------------------------------------------
  def register_ignore_target_counter_action(interrupt = false)
    return unless can_counter?
    return if @active_battler.nil?

    target_unit = (@active_battler.actor? ? $game_troop : $game_party).members
    target_unit.each { |battler|
      next unless can_counter?(battler)
      battler.counter_actions.each { |counter|
        break if counter_added?
        next  unless counter.condition.ignore_target
        next  if counter.condition.interrupt ^ interrupt  # <-- if x != y
        judge_counter_action(@active_battler, battler, counter)
      }
    }
  end
  #--------------------------------------------------------------------------
  # ○ 割り込みカウンター行動の登録
  #--------------------------------------------------------------------------
  def register_interrupt_counter_action
    return unless can_counter?

    # 自分が対象
    targets = @active_battler.action.make_targets
    if targets != nil
      targets.each { |t|
        break if counter_added?
        register_counter_action(t, true)
      }
    end

    # ターゲット無視
    register_ignore_target_counter_action(true) unless counter_added?

    @counter_interrupt = counter_added?
  end
  #--------------------------------------------------------------------------
  # ○ 割り込みカウンターの実行
  #--------------------------------------------------------------------------
  def execute_interrupt_counter
    counter = @counter_infos[0]
    text = counter.action.interrupt_message.clone
    text = Vocab::InterruptCounter.clone if text.empty?

    text.gsub!(/\\/, "\")
    text.gsub!(/\N([^[]|$)/i) { "#{@active_battler.name}#{$1}" }
    text.gsub!(/\C([^[]|$)/i) { "#{counter.battler.name}#{$1}" }
    text.gsub!(/\A([^[]|$)/i) { "#{@active_battler.action.action_name}#{$1}" }
    @message_window.add_instant_text(text)
    wait(45)
  end
end

Comment '4'
  • ?
    Evangelista 2011.04.06 21:36

    추가하자면 모험자의 관 사이드뷰 배틀 스크립트랑 호환 안됩니다.

    아방스에선 실질적으로 쓸모없을걸요 다들 프론트뷰를 탄압해서

  • ?
    샤민니유아 2011.05.31 15:34

    감사합니다 ^^;ㅋ

  • ?
    소방 2011.06.05 00:22

    적용해보고 싶은 스크립트네요~ 잘 봤습니다.

  • ?
    드림스 2011.11.02 09:14

    Evangelista//괜찮습니다 저는 프론트뷰 사랑해요 ㅋ


List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
공지 스크립트 자료 게시물 작성시 주의사항 3 습작 2012.12.24 5455
130 기타 Gamepad Extender VX 습작 2015.01.02 676
129 기타 장애물을 피하고 다가오게 하는 스크립트 5 file 박력남 2014.02.25 1896
128 기타 Resize and Scale by OriginalWij 1 습작 2013.05.13 1354
127 기타 reijubv - New Balloon Command (VXA에서도 작동) 1 file 혜인 2013.04.08 1333
126 기타 MSX - XP Characters on VX/VX Ace 2 Alkaid 2013.01.26 1349
125 기타 Fullscreen++ by Zeus81 (VX/VXA) 2 Alkaid 2012.09.01 2233
124 기타 Etude87_GAGA_Chat 4 습작 2012.06.14 1918
123 기타 Etude87_Hangul_utf8_List 습작 2012.06.04 1668
122 기타 078656577er님의 스크립트를 개조한, 사격용 스크립트 1 file 타코 2012.03.16 2520
121 기타 멥 이름 띄우기 10 신규회원 2012.02.24 3630
120 기타 화면 해상도(640 X 480) 스크립트 6 file 쿠쿠밥솥 2012.01.10 3977
119 기타 아이디를 띄우기 20 12345678 2011.11.07 4629
118 기타 Kylock1.2+(RMDude-Kylock1.5) Time System Script 4 file communnn 2011.10.20 2597
117 기타 [XP / VX 공용] rand() 함수 확장 스크립트 4 허걱 2011.09.13 2365
116 기타 여러스크립트(목적은 포인트) 12 file 인생은 힘들다. 2011.08.26 3090
115 기타 요리 시스템을 도입하는 스크립트입니다. 9 file 스페나로츠 2011.08.18 3148
114 기타 화면 확대 스크립트 12 file 에돌이 2011.07.22 3065
113 기타 해상도 변경 스크립트 11 카리스 2011.07.19 2727
» 기타 KGC counter 스크립트. 반격기 추가스크립트입니다. 4 우켈킁 2011.03.31 1814
111 기타 IEX - Script Library 1.0 by IceDragon 8 Alkaid 2011.01.11 2627
Board Pagination Prev 1 2 3 4 5 6 7 Next
/ 7