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 5398
557 VX 주석액알 PR코더즈의ABS보다 않좋다고생각할수있지만 더좋음 34 배군 2008.08.17 5145
556 배틀할때 몬스터의 HP표시 !! 5 file 미카엘 2008.08.17 7517
555 타이틀/게임오버 맨처음 시작할때 타이틀에 게임로드칸 없애기 7 미카엘 2008.08.20 2819
554 ((대박!)) 게임상의 모든 글자에 효과 주기.. 33 미카엘 2008.08.20 5582
553 키입력 입력 기능 확장 스크립트 추가. [전체키 스크립트] 22 아방스 2008.08.25 3772
552 전투 돌아가는 전투 메뉴 시스템 33 아방스 2008.08.29 5083
551 체력 게이지바 스크립트 30 아방스 2008.09.01 5829
550 맵/타일 RPG 만들기 VX 로 구현한 3D~ 42 아방스 2008.09.02 8405
549 맵/타일 월드맵 스크립트 49 아방스 2008.09.07 6123
548 레벨업 할경우 hp/mp 등을 채워주는 스크립트 49 아방스 2008.09.09 4473
547 파티 전에 아방스님이 올린 '파티 변경 시스템'을 한글화 했습니다. 17 file 아리엘 2008.09.16 3589
546 전투 지형에 따른 전투배경화면 표시 스크립트!! 30 file 레오 2008.09.17 5855
545 스킬 합성샾 스크립트 ^^ [동영상 포함] 6 file 아방스 2008.09.23 6038
544 Path Finding 6 Man... 2008.10.08 1530
543 AntiLag_1.2h 23 file RPGbooster 2008.10.08 2283
542 빠른 스킬사용 6 file RPGbooster 2008.10.08 2814
541 타이틀/게임오버 랜덤 타이틀화면 8 file RPGbooster 2008.10.08 2832
540 깔끔한 링메뉴 45 file RPGbooster 2008.10.08 5000
539 탈것을 소환 12 file RPGbooster 2008.10.08 2713
538 심플하게 메뉴 띄우기 25 file RPGbooster 2008.10.08 3864
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 32 Next
/ 32