VX to XP詰め合わせセット



VXの以下の標準機能をXPで再現します。

・逆効果と相殺
・クスリの知識
・強力防御
・クリティカル多

変更点
2011:07:01
・それぞれ、複数の効果をもつ場合に対応

2011:09:04
・Silfeed Arks様の『敵の行動に対して発動させるスキル』が紛れていたので除外

2011:12:08
・VX風Vocab対応

2016:03:01
・外部フラグ追加
・武器による命中精度対応
・各種ステートID配列をハッシュから生成するように変更

#==============================================================================
# VX to XP詰め合わせせっと by 貪藻矢射妥←
#------------------------------------------------------------------------------
# VXの以下の標準機能をXPで再現します。
# 
# ・逆効果と相殺
# ・クスリの知識
# ・強力防御
# ・クリティカル多
# 
#==============================================================================
# 変更点
# 
# 2011:07:01
# ・それぞれ、複数の効果をもつ場合に対応
# 
# 2011:09:04
# ・Silfeed Arks様の『敵の行動に対して発動させるスキル』が紛れていたので除外
# 
# 2011:12:08
# ・VX風Vocab対応
# 
# 2016:03:01
# ・外部フラグ追加
# ・武器による命中精度対応
# ・各種ステートID配列をハッシュから生成するように変更

module VX_TO_XP
  # 逆効果と相殺の属性ID
  SIE = 31
  
  # クリティカルの変動値。
  # クリティカル頻発によって通常の何倍になるのか?
  #                ステートID => 倍数
  CRITICAL_RATE = {201=>3, 291=>4}
  
  # 強力防御の変動値。
  # 強力防御によって通常の何倍になるのか?
  #                ステートID => 倍数
  GUARD_RATE    = {199=>2, 289=>3}
  
  # 薬の知識の変動値。
  # 薬の知識によって通常の何倍になるのか?
  #                ステートID => 倍数
  DRUG_RATE     = {200=>2, 290=>3}
  
  # クリティカルの増幅値。
  # クリティカルによってダメージが通常の何倍になるのか?
  # 参考:
  # XP 2倍
  # VX 3倍
  CRITICAL_BST  = 3
  
  # ステートID配列 ※自動生成、通常は気にしない
  # 強力防御
  SUPER_GUARD   = GUARD_RATE.keys
  # クスリの知識
  DRUG_KNOWN    = DRUG_RATE.keys
  # クリティカル多
  CRITICAL_MOST = CRITICAL_RATE.keys
  
end

$OuterFlgs = {} if $OuterFlgs == nil
$OuterFlgs["VX_2_XP"] = true

class Game_Battler
  include Vocab
  #--------------------------------------------------------------------------
  # ● ステートの付加
  #     state_id : ステート ID
  #     force    : 強制付加フラグ (オートステートの処理で使用)
  #--------------------------------------------------------------------------
  def add_state(state_id, force = false)
    # 無効なステートの場合
    if $data_states[state_id] == nil
      # メソッド終了
      return
    end
    # 強制付加ではない場合
    unless force
      # 既存のステートのループ
      for i in @states
        # 新しいステートが既存のステートのステート変化 (-) に含まれており、
        # そのステートが新しいステートのステート変化 (-) には含まれない場合
        # (ex : 戦闘不能のときに毒を付加しようとした場合)
        if $data_states[i].minus_state_set.include?(state_id) and
           not $data_states[state_id].minus_state_set.include?(i)
          # メソッド終了
          return
        end
      end
    end
    # このステートが付加されていない場合
    unless state?(state_id)
      # 逆位相で相殺機能Offの場合
      unless state_offset?(state_id)
        # ステート ID を @states 配列に追加
        @states.push(state_id)
      end
      # オプション [HP 0 の状態とみなす] が有効の場合
      if $data_states[state_id].zero_hp
        # HP を 0 に変更
        @hp = 0
      end
      # 全ステートのループ
      for i in 1...$data_states.size
        # ステート変化 (+) 処理
        if $data_states[state_id].plus_state_set.include?(i)
          add_state(i)
        end
        # ステート変化 (-) 処理
        if $data_states[state_id].minus_state_set.include?(i)
          remove_state(i)
        end
      end
      # レーティングの大きい順 (同値の場合は制約の強い順) に並び替え
      @states.sort! do |a, b|
        state_a = $data_states[a]
        state_b = $data_states[b]
        if state_a.rating > state_b.rating
          -1
        elsif state_a.rating < state_b.rating
          +1
        elsif state_a.restriction > state_b.restriction
          -1
        elsif state_a.restriction < state_b.restriction
          +1
        else
          a <=> b
        end
      end
    end
    # 強制付加の場合
    if force
      # 自然解除の最低ターン数を -1 (無効) に設定
      @states_turn[state_id] = -1
    end
    # 強制付加ではない場合
    unless  @states_turn[state_id] == -1
      # 自然解除の最低ターン数を設定
      @states_turn[state_id] = $data_states[state_id].hold_turn
    end
    # 行動不能の場合
    unless movable?
      # アクションをクリア
      @current_action.clear
    end
    # HP および SP の最大値チェック
    @hp = [@hp, self.maxhp].min
    @sp = [@sp, self.maxsp].min
  end
  #--------------------------------------------------------------------------
  # ● 相殺するべきステートかどうかの判定
  #     state_id : ステート ID
  #
  # 新しく追加しようとするステートの属性防御に『逆効果と相殺』が含まれていて、
  # 付加しようとするステートのマイナスセットに現在付加されているステートの
  # 少なくともひとつが含まれている場合はステートを解除するだけで、ステートの
  # 追加を行わず、それ以外の場合にステートの付加を行う。
  #--------------------------------------------------------------------------
  def state_offset?(state_id)
    return false unless $data_states[state_id].guard_element_set.include?(VX_TO_XP::SIE)
    for i in @states
      return true if $data_states[state_id].minus_state_set.include?(i)
    end
    return false
  end
  
  #--------------------------------------------------------------------------
  # ● 通常攻撃の効果適用
  #     attacker : 攻撃者 (バトラー)
  #--------------------------------------------------------------------------
  def attack_effect(attacker)
    # クリティカルフラグをクリア
    self.critical = false
    @m_hit = false
    # 第一命中判定
    
    if $OuterFlgs["Weapon_HitRate"]
      base_hitrate = get_hitrate_base(attacker)
    else
      base_hitrate = 100
    end
    
    hit_result = (rand(base_hitrate) < attacker.hit)
    # 命中の場合
    if hit_result == true
      # 基本ダメージを計算
      atk = [attacker.atk - self.pdef / 2, 0].max
      self.damage = atk * (20 + attacker.str) / 20
      # 属性修正
      self.damage *= elements_correct(attacker.element_set)
      self.damage /= 100
      # ダメージの符号が正の場合
      if self.damage > 0
        # クリティカル修正
        critical_rate = 100
        if $OuterFlgs["VX_2_XP"]
          for st_id in VX_TO_XP::CRITICAL_MOST
            if attacker.states.include?(st_id)
              critical_rate /= VX_TO_XP::CRITICAL_RATE[st_id]
            end
          end
        end
        if rand(critical_rate) < 4 * attacker.dex / self.agi
          # アクターの場合 必殺技スキル発動チェック
          if attacker.is_a?(Game_Actor)
            if attacker.critical_skill != nil
              self.critical_skill_flg = true
              return true
            end
          end
          if $OuterFlgs["VX_2_XP"]
            self.damage *= VX_TO_XP::CRITICAL_BST
          else
            self.damage *= 2
          end
          self.critical = true
        end
        # 防御修正
        if self.guarding?
          self.damage /= 2
          if $OuterFlgs["VX_2_XP"]
            for st_id in VX_TO_XP::SUPER_GUARD
              if self.states.include?(st_id)
                self.damage /= VX_TO_XP::GUARD_RATE[st_id]
              end
            end
          end
        end
      end
      # 分散
      if self.damage.abs > 0
        amp = [self.damage.abs * 15 / 100, 1].max
        self.damage += rand(amp+1) + rand(amp+1) - amp
      end
      # 第二命中判定
      eva = 8 * self.agi / attacker.dex + self.eva / 80.0
      hit = self.damage < 0 ? 100 : 100 - eva
      
      # Luk補正
      if MINTO::RGSS["parameter_addition"] and attacker.is_a?(Game_Enemy)
        hit = [hit - self.luk / 40.0, 5].max
      end
      
      hit = self.cant_evade? ? 100 : hit
      hit_result = (rand(base_hitrate) < hit)
    end
    
    if $SilfeedArks["Special_Attack"]
      # ダメージ吸収の場合、符号反転
      if @counter[0] == 1 and @counter[6]
        self.damage *= -1 
      end
      # スキルキャンセルの場合ダメージを空白して終了
      if @counter[4] and @counter[6]
        self.damage = nil
        return true
      end
    end
    
    # 命中の場合
    if hit_result == true
      # ステート衝撃解除
      remove_states_shock
      # HP からダメージを減算
      self.hp -= self.damage
      # ステート変化
      @state_changed = false
      states_plus(attacker.plus_state_set)
      states_minus(attacker.minus_state_set)
    # ミスの場合
    else
      # ダメージに "Miss" を設定
      self.damage = MISS_WORD
      # クリティカルフラグをクリア
      self.critical = false
    end
    # メソッド終了
    return true
  end
  #--------------------------------------------------------------------------
  # ● スキルの効果適用
  #     user  : スキルの使用者 (バトラー)
  #     skill : スキル
  #--------------------------------------------------------------------------
  def skill_effect(user, skill)
    # クリティカルフラグをクリア
    self.critical = false
    # スキルの効果範囲が HP 1 以上の味方で、自分の HP が 0、
    # またはスキルの効果範囲が HP 0 の味方で、自分の HP が 1 以上の場合
    if ((skill.scope == 3 or skill.scope == 4) and self.hp == 0) or
       ((skill.scope == 5 or skill.scope == 6) and self.hp >= 1)
      # メソッド終了
      return false
    end
    # 有効フラグをクリア
    effective = false
    # コモンイベント ID が有効の場合は有効フラグをセット
    effective |= skill.common_event_id > 0
    # 第一命中判定
    hit = skill.hit
    if skill.atk_f > 0
      hit *= user.hit / 100
    end
    
    if $OuterFlgs["Weapon_HitRate"]
      base_hitrate = get_hitrate_base(user)
    else
      base_hitrate = 100
    end
    
    hit_result = (rand(base_hitrate) < hit)
    # 不確実なスキルの場合は有効フラグをセット
    effective |= hit < 100
    # 命中の場合
    if hit_result == true
      # 威力を計算
      power = skill.power + user.atk * skill.atk_f / 100
      if power > 0
        power -= self.pdef * skill.pdef_f / 200
        power -= self.mdef * skill.mdef_f / 200
        power = [power, 0].max
      end
      # 倍率を計算
      rate = 20
      rate += (user.str * skill.str_f / 100)
      rate += (user.dex * skill.dex_f / 100)
      rate += (user.agi * skill.agi_f / 100)
      rate += (user.int * skill.int_f / 100)
      # 基本ダメージを計算
      self.damage = power * rate / 20
      # 属性修正
      self.damage *= elements_correct(skill.element_set)
      self.damage /= 100
      # ダメージの符号が正の場合
      if self.damage > 0
        # 防御修正
        if self.guarding?
          self.damage /= 2
          if $OuterFlgs["VX_2_XP"]
            for st_id in VX_TO_XP::SUPER_GUARD
              if self.states.include?(st_id)
                self.damage /= VX_TO_XP::GUARD_RATE[st_id]
              end
            end
          end
        end
      end
      # 分散
      if skill.variance > 0 and self.damage.abs > 0
        amp = [self.damage.abs * skill.variance / 100, 1].max
        self.damage += rand(amp+1) + rand(amp+1) - amp
      end
      # 第二命中判定
      eva = 8 * self.agi / user.dex + self.eva / 80.0
      hit = self.damage < 0 ? 100 : 100 - eva * skill.eva_f / 100
      
      # Luk補正
      if MINTO::RGSS["parameter_addition"] and user.is_a?(Game_Enemy)
        hit = [hit - self.luk / 40.0, 5].max
      end
      
      hit = self.cant_evade? ? 100 : hit
      hit_result = (rand(base_hitrate) < hit)
      # 不確実なスキルの場合は有効フラグをセット
      effective |= hit < 100
    end
    
    if $SilfeedArks["Special_Attack"]
      # 当身ダメージ吸収の場合、符号反転
      if @counter[0] == 1 and @counter[6]
        self.damage *= -1 
      end
      # 当身SP吸収の場合、SP回復
      if @counter[0] == 2 and @counter[6]
        self.sp += skill.sp_cost
      end
      # スキルキャンセルの場合ダメージを空白して終了
      if @counter[4] and @counter[6]
        self.damage = nil
        return effective
      end
    end
    
    # 命中の場合
    if hit_result == true
      # 威力 0 以外の物理攻撃の場合
      if skill.power != 0 and skill.atk_f > 0
        # ステート衝撃解除
        remove_states_shock
        # 有効フラグをセット
        effective = true
      end
      # HP からダメージを減算
      last_hp = self.hp
      self.hp -= self.damage
      effective |= self.hp != last_hp
      # ステート変化
      @state_changed = false
      effective |= states_plus(skill.plus_state_set)
      effective |= states_minus(skill.minus_state_set)
      # 威力が 0 の場合
      if skill.power == 0
        # ダメージに空文字列を設定
        self.damage = ""
        # ステートに変化がない場合
        unless @state_changed
          # ダメージに "Miss" を設定
          self.damage = MISS_WORD
        end
      end
    # ミスの場合
    else
      # ダメージに "Miss" を設定
      self.damage = MISS_WORD
    end
    # 戦闘中でない場合
    unless $game_temp.in_battle
      # ダメージに nil を設定
      self.damage = nil
    end
    # メソッド終了
    return effective
  end
  #--------------------------------------------------------------------------
  # ● アイテムの効果適用
  #     item : アイテム
  #--------------------------------------------------------------------------
  def item_effect(item)
    # クリティカルフラグをクリア
    self.critical = false
    # アイテムの効果範囲が HP 1 以上の味方で、自分の HP が 0、
    # またはアイテムの効果範囲が HP 0 の味方で、自分の HP が 1 以上の場合
    if ((item.scope == 3 or item.scope == 4) and self.hp == 0) or
       ((item.scope == 5 or item.scope == 6) and self.hp >= 1)
      # メソッド終了
      return false
    end
    # 有効フラグをクリア
    effective = false
    # コモンイベント ID が有効の場合は有効フラグをセット
    effective |= item.common_event_id > 0
    # 命中判定
    
    if $OuterFlgs["Weapon_HitRate"]
      base_hitrate = get_hitrate_base(self, false)
    else
      base_hitrate = 100
    end
    
    hit_result = (rand(base_hitrate) < item.hit)
    # 不確実なスキルの場合は有効フラグをセット
    effective |= item.hit < 100
    # 命中の場合
    if hit_result == true
      # 回復量を計算
      recover_hp = maxhp * item.recover_hp_rate / 100 + item.recover_hp
      recover_sp = maxsp * item.recover_sp_rate / 100 + item.recover_sp
      if recover_hp < 0
        recover_hp += self.pdef * item.pdef_f / 20
        recover_hp += self.mdef * item.mdef_f / 20
        recover_hp = [recover_hp, 0].min
      end
      # 属性修正
      recover_hp *= elements_correct(item.element_set)
      recover_hp /= 100
      recover_sp *= elements_correct(item.element_set)
      recover_sp /= 100
      if $OuterFlgs["VX_2_XP"]
        for st_id in VX_TO_XP::DRUG_KNOWN
          if self.states.include?(st_id)
            recover_hp *= VX_TO_XP::DRUG_RATE[st_id]
            recover_sp *= VX_TO_XP::DRUG_RATE[st_id]
          end
        end
      end
      # 分散
      if item.variance > 0 and recover_hp.abs > 0
        amp = [recover_hp.abs * item.variance / 100, 1].max
        recover_hp += rand(amp+1) + rand(amp+1) - amp
      end
      if item.variance > 0 and recover_sp.abs > 0
        amp = [recover_sp.abs * item.variance / 100, 1].max
        recover_sp += rand(amp+1) + rand(amp+1) - amp
      end
      # 回復量の符号が負の場合
      if recover_hp < 0
        # 防御修正
        if self.guarding?
          recover_hp /= 2
          if $OuterFlgs["VX_2_XP"]
            for st_id in VX_TO_XP::SUPER_GUARD
              if self.states.include?(st_id)
                self.damage /= VX_TO_XP::GUARD_RATE[st_id]
              end
            end
          end
        end
      end
      # HP 回復量の符号を反転し、ダメージの値に設定
      self.damage = -recover_hp
      # HP および SP を回復
      last_hp = self.hp
      last_sp = self.sp
      self.hp += recover_hp
      self.sp += recover_sp
      effective |= self.hp != last_hp
      effective |= self.sp != last_sp
      # ステート変化
      @state_changed = false
      effective |= states_plus(item.plus_state_set)
      effective |= states_minus(item.minus_state_set)
      # パラメータ上昇値が有効の場合
      if item.parameter_type > 0 and item.parameter_points != 0
        # パラメータで分岐
        case item.parameter_type
        when 1  # MaxHP
          @maxhp_plus += item.parameter_points
        when 2  # MaxSP
          @maxsp_plus += item.parameter_points
        when 3  # 腕力
          @str_plus += item.parameter_points
        when 4  # 器用さ
          @dex_plus += item.parameter_points
        when 5  # 素早さ
          @agi_plus += item.parameter_points
        when 6  # 魔力
          @int_plus += item.parameter_points
        end
        # 有効フラグをセット
        effective = true
      end
      # HP 回復率と回復量が 0 の場合
      if item.recover_hp_rate == 0 and item.recover_hp == 0
        # ダメージに空文字列を設定
        self.damage = ""
        # SP 回復率と回復量が 0、パラメータ上昇値が無効の場合
        if item.recover_sp_rate == 0 and item.recover_sp == 0 and
           (item.parameter_type == 0 or item.parameter_points == 0)
          # ステートに変化がない場合
          unless @state_changed
            # ダメージに "Miss" を設定
            self.damage = MISS_WORD
          end
        end
      end
    # ミスの場合
    else
      # ダメージに "Miss" を設定
      self.damage = MISS_WORD
    end
    # 戦闘中でない場合
    unless $game_temp.in_battle
      # ダメージに nil を設定
      self.damage = nil
    end
    # メソッド終了
    return effective
  end
end
カスタマイズポイントについて
SUPER_GUARD 強力防御のステートID配列
DRUG_KNOWN 薬の知識のステートID配列
CRITICAL_MOST クリティカル多のステートID配列
SIE 逆効果で相殺の属性ID
CRITICAL_RATE クリティカルの変動値ハッシュ クリティカル頻発によってクリティカル派生値が通常の何倍になるのか? {ID => 倍率, ...} ※IDはCRITICAL_MOSTで設定したものを使ってください
GUARD_RATE 強力防御の変動値ハッシュ 強力防御によって防御時の防御が通常の何倍になるのか? {ID => 倍率, ...} ※IDはSUPER_GUARDで設定したものを使ってください
DRUG_RATE 薬の知識の変動値ハッシュ 薬の知識によってアイテム使用時の効果が通常の何倍になるのか? {ID => 倍率, ...} ※IDはDRUG_KNOWNで設定したものを使ってください
CRITICAL_BST クリティカルの増幅値。 クリティカルによってダメージが通常の何倍になるのか?
※逆効果で相殺だけステートじゃなく、属性IDを使用します。

戻る