隊列概念 カスタム



・射程外の相手に対する結果を変更できるように変更
・隊列を無視して攻撃が可能な設定の追加
・隊列を乱す、隊列を維持する設定の追加
・エネミーの隊列も属性からパラメータに変更
・後列にいるエネミーほど小さく、暗く表示
・エネミーのうち前衛がいなくなったら中衛、後衛を移動させて常に前衛に誰かしら存在するように変更

変更点
まだなし

#----------------------------------------------------------------------------
# 隊列概念 貪藻矢射妥←カスタム by 貪藻矢射妥←
#----------------------------------------------------------------------------
# 原作:     ◆ 隊列概念 - KGC_RankConception ◆
#           ◇ Last update : 2008/05/11 ◇
# 原作者:   TOMY様
# HP:       Kamesoft
# アドレス: http://ytomy.sakura.ne.jp/
#
# 改造内容:
# ・射程外の相手に対する結果を変更できるように変更
# ・隊列を無視して攻撃が可能な設定の追加
# ・隊列を乱す、隊列を維持する設定の追加
# ・エネミーの隊列も属性からパラメータに変更
# ・後列にいるエネミーほど小さく、暗く表示
# ・エネミーのうち前衛がいなくなったら中衛、後衛を移動させて常に前衛に誰かしら
#  存在するように変更
# 
#============================================================================
# 変更点
# まだなし

#==============================================================================
# ★ カスタマイズ項目 ★
#==============================================================================

module KGC
  # ◆隊列概念モード
  # 0:射程外の相手にはミス
  # 1:射程外の相手には威力減
  RC_OUT_RANGE_MODE = 1
  
  # ◆射程未設定時の射程距離
  RC_DEFAULT_RANGE = 1

  # ◆隊列用画像
  #  "Graphics/Pictures" から読み込む。拡張子省略可。
  RC_RANK_IMAGE = "position"
  # ◆隊列画像表示位置補正値
  #  通常は 120。
  #  ≪多人数パーティ≫などを併用する時は微調整。
  RC_RANK_OFFSET = 120
  
  # ◆隊列未設定時のデフォルト値
  RC_DEFAULT_POS = 0
  
  # ◆隊列によらず攻撃可能な属性の名称
  RC_OVER_RANGE     = "隊列無視"
  # ◆隊列を乱す属性の名称
  RC_BREAK_POSITION = "隊列破壊"
  # ◆隊列乱しを防御するステート名称
  RC_BREAK_POS_GARD = "隊列維持"
  
  # ◆隊列によるエネミーの表示倍率
  RC_POS_RATE = [1, 0.8, 0.7]
  # ◆隊列によるエネミーの影色
  RC_POS_TONE = [Tone.new(   0,    0,    0),
                 Tone.new( -30,  -30,  -30),
                 Tone.new(-100, -100, -100)]
  
  # RC_OUT_RANGE_MODEが1の場合に使います。
  # ◆隊列によるダメージ補正
  # 前衛、中衛、後衛の補正倍率の設定
  RC_POS_DAMAGE_F = [1.0, 0.8, 0.6]
end

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

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

if $game_special_elements == nil
  $game_special_elements = {}
  $data_system = load_data("Data/System.rxdata")
end
if $game_special_states == nil
  $game_special_states = {}
  $data_states = load_data("Data/States.rxdata")
end

# 射程属性
$game_special_elements["range"] = /射程(\d)/
# 隊列移動属性
$game_special_elements["move_rank"] = /(前|中|後)衛移動/
# 隊列破壊無視
state = $data_states.compact.find { |s| s.name == KGC::RC_BREAK_POS_GARD }
$game_special_states["b_pos_gd"]    = (state != nil ? state.id : 0)
#==============================================================================
# ■ Game_Battler
#==============================================================================

class Game_Battler
  #--------------------------------------------------------------------------
  # ● 隊列の設定
  #--------------------------------------------------------------------------
  def position=(p)
    @position = p
  end
end

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

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

class Game_Actor < Game_Battler
  #--------------------------------------------------------------------------
  # ● セットアップ
  #     actor_id : アクター ID
  #--------------------------------------------------------------------------
  alias setup_KGC_RankConception setup
  def setup(actor_id)
    setup_KGC_RankConception(actor_id)

    # 隊列を初期化
    @position = $data_classes[@class_id].position
  end
  #--------------------------------------------------------------------------
  # ● 隊列の取得
  #--------------------------------------------------------------------------
  def position
    @position = $data_classes[@class_id].position if @position == nil
    return @position
  end
end

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

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

class Game_Enemy < Game_Battler
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #     troop_id     : トループ ID
  #     member_index : トループメンバーのインデックス
  #--------------------------------------------------------------------------
  alias initialize_KGC_RankConception initialize
  def initialize(troop_id, member_index)
    initialize_KGC_RankConception(troop_id, member_index)
    
    # 隊列を初期化
    @position = KGC::RC_DEFAULT_POS
  end
  #--------------------------------------------------------------------------
  # ● 隊列の取得
  #--------------------------------------------------------------------------
  def position
    @position = KGC::RC_DEFAULT_POS if @position == nil
    return @position
  end
  #--------------------------------------------------------------------------
  # ● 隊列による倍率とトーンの取得
  #--------------------------------------------------------------------------
  def zoom_tone_by_position
    if self.position != nil
      rate = KGC::RC_POS_RATE[self.position]
      tone = KGC::RC_POS_TONE[self.position]
    else
      rate = KGC::RC_POS_RATE[0]
      tone = KGC::RC_POS_TONE[0]
    end
    return [rate, tone]
  end
end

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


#==============================================================================
# ■ Game_Battler (分割定義 2)
#==============================================================================

class Game_Battler
  #--------------------------------------------------------------------------
  # ● 射程有効判定
  #     attacker : 攻撃者
  #     action   : 処理行動
  #--------------------------------------------------------------------------
  def within_range?(attacker, action = nil)
    # 射程を取得
    if action != nil
      for element in action.element_set.compact
        element_name = $data_system.elements[element]
        # 射程属性を持っている場合
        if $game_special_elements["range"] =~ element_name
          range = $1.to_i if $1 != nil
          break
        end
      end
    end
    # 射程が無い場合
    if action == nil || range == nil
      range = KGC::RC_DEFAULT_RANGE
    end
    # 攻撃者の隊列を取得
    a_pos = attacker.position
    # 攻撃対象の隊列を取得
    t_pos = self.position
    # 有効射程を判定
    return a_pos + t_pos <= range
  end
  #--------------------------------------------------------------------------
  # ● 隊列乱し判定
  #     action   : 処理行動
  #--------------------------------------------------------------------------
  def range_break?(action = nil)
    # 処理行動から属性セットを取得
    if action != nil
      for element in action.element_set.compact
        element_name = $data_system.elements[element]
        # 隊列を乱す属性の場合
        if KGC::RC_BREAK_POSITION == element_name
          return true
        end
      end
    end
    # ここまで来て何もなければfalse
    return false
  end
  #--------------------------------------------------------------------------
  # ● 隊列無視判定
  #     action   : 処理行動
  #--------------------------------------------------------------------------
  def over_range?(action = nil)
    # 射程を取得
    if action != nil
      for element in action.element_set.compact
        element_name = $data_system.elements[element]
        # 隊列によらない攻撃が可能な場合
        if KGC::RC_OVER_RANGE == element_name
          return true
        end
      end
    end
    # 有効射程を判定
    return false
  end
  #--------------------------------------------------------------------------
  # ● 隊列によるダメージ補正
  #     attacker : 攻撃者
  #     action   : 処理行動
  #--------------------------------------------------------------------------
  def damage_by_range(attacker, action = nil)
    # 射程を取得
    if action != nil
      for element in action.element_set.compact
        element_name = $data_system.elements[element]
        # 射程属性を持っている場合
        if $game_special_elements["range"] =~ element_name
          range = $1.to_i if $1 != nil
          break
        end
      end
    end
    # 射程が無い場合
    if action == nil || range == nil
      range = KGC::RC_DEFAULT_RANGE
    end
    
    case range
    when 1
      # 前衛 to 前衛 : 等倍
      # 前衛 to 中衛 : 減衰A
      # 中衛 to 前衛 : 減衰A
      # それ以外     : 減衰B
      if attacker.position + self.position == 0
        return KGC::RC_POS_DAMAGE_F[0]
      elsif attacker.position + self.position == 1
        return KGC::RC_POS_DAMAGE_F[1]
      else
        return KGC::RC_POS_DAMAGE_F[2]
      end
    when 2
      # 前衛/中衛 to 前衛 : 等倍
      # 前衛 to 前衛/中衛 : 等倍
      # それ以外          : 減衰
      if attacker.position + self.position <= 1
        return KGC::RC_POS_DAMAGE_F[0]
      else
        return KGC::RC_POS_DAMAGE_F[1]
      end
    when 4
      # 全部 : 等倍
      return KGC::RC_POS_DAMAGE_F[0]
    end
  end
end

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

#==============================================================================
# ■ Game_Battler (分割定義 3)
#==============================================================================

class Game_Battler
  #--------------------------------------------------------------------------
  # ● 通常攻撃の効果適用
  #     attacker : 攻撃者 (バトラー)
  #--------------------------------------------------------------------------
  def attack_effect(attacker)
    # クリティカルフラグをクリア
    self.critical = false
    
if $imported["RankConception"]
    # 射程外の場合
    action = attacker.is_a?(Game_Actor) ? ($imported["EquipExtension"] ? 
      $data_weapons[attacker.weapon_id(attacker.attack_count)] :
      $data_weapons[attacker.weapon_id]) : nil
    if KGC::RC_OUT_RANGE_MODE == 0 && !self.within_range?(attacker, action) && 
      !self.over_range?(action)
      # ダメージに "Miss" を設定
      self.damage = Vocab::MISS_WORD
      # 偽を返す
      return false
    end
end # $imported["RankConception"]
    
    # 第一命中判定
    hit_result = (rand(100) < 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
        # クリティカル修正
        if rand(100) < 4 * attacker.dex / self.agi
          self.damage *= 2
          self.critical = true
        end
        # 防御修正
        if self.guarding?
          self.damage /= 2
        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
      hit = self.damage < 0 ? 100 : 100 - eva
      hit = self.cant_evade? ? 100 : hit
      hit_result = (rand(100) < hit)
    end
    
if $imported["RankConception"]
    # 隊列によるダメージ補正
    if KGC::RC_OUT_RANGE_MODE == 1 && !self.over_range?(action)
      self.damage *= damage_by_range(attacker, action)
      self.damage = Integer(self.damage)
    end
end # $imported["RankConception"]
    
    # 命中の場合
    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 = Vocab::MISS_WORD
      # クリティカルフラグをクリア
      self.critical = false
    end
    # メソッド終了
    return true
  end
  #--------------------------------------------------------------------------
  # ● スキルの効果適用
  #     user  : スキルの使用者 (バトラー)
  #     skill : スキル
  #--------------------------------------------------------------------------
  def skill_effect(user, skill)
    # クリティカルフラグをクリア
    self.critical = false
    
if $imported["SkillReflection"]
    # 反射できる場合は戻る
    if user != self && self.reflection?(skill)
      return false
    end
end #$imported["SkillReflection"]
    
if $imported["RankConception"]
    # 射程外の場合
    if KGC::RC_OUT_RANGE_MODE== 0 && !self.within_range?(user, skill) && 
      !self.over_range?(skill)
      # ダメージに "Miss" を設定
      self.damage = Vocab::MISS_WORD
      # 偽を返す
      return false
    end
    
    # 隊列乱し判定
    break_position = self.range_break?(skill)
    
    # 隊列移動属性判定
    for element in skill.element_set.compact
      element_name = $data_system.elements[element]
      # 射程属性を持っている場合
      if $game_special_elements["move_rank"] =~ element_name
        move_position = $1
        break
      end
    end
end # $imported["RankConception"]
    
    # スキルの効果範囲が 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
    hit_result = (rand(100) < hit)
    # 不確実なスキルの場合は有効フラグをセット
    effective |= hit < 100
    
    # 命中の場合、かつ隊列移動属性を持っていない場合
    if hit_result == true && move_position == nil && break_position == false
      # 威力を計算
      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
        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
      hit = self.damage < 0 ? 100 : 100 - eva * skill.eva_f / 100
      hit = self.cant_evade? ? 100 : hit
      hit_result = (rand(100) < hit)
      # 不確実なスキルの場合は有効フラグをセット
      effective |= hit < 100
      
if $imported["RankConception"]
      # 隊列によるダメージ補正
      if KGC::RC_OUT_RANGE_MODE == 1 && !self.over_range?(skill)
        self.damage *= damage_by_range(user, skill)
        self.damage = Integer(self.damage)
      end
end # $imported["RankConception"]
    end
    # 命中の場合、かつ隊列移動属性を持っていない場合
    
    # 命中の場合
    if hit_result == true
      # 隊列移動属性を持っていない場合
      if move_position == nil && break_position == false
        # 威力 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
      end
      # 隊列移動属性を持っていない場合
      
      # ステート変化
      @state_changed = false
      effective |= states_plus(skill.plus_state_set)
      effective |= states_minus(skill.minus_state_set)
      
if $imported["RankConception"]
      if break_position
        # 隊列維持かどうか
        if @states.include?($game_special_states["b_pos_gd"])
          # ダメージにの設定
          self.damage = "Position Keep!!" if self.damage == nil
          # ステート変化(隊列維持の解除)
          states_minus([$game_special_states["b_pos_gd"]])
          @state_changed = true
          effective = true
          # 戻る
          return false
        else
          # 隊列を乱す場合
          if self.range_break?(skill)
            pos_list = [2, 1, 0]
            self.position = pos_list[self.position]
            # ダメージの設定
            self.damage = "Position Bresk!!" if self.damage == nil
            # 戻る
            return true
          end
        end
      end
      
      if move_position != nil
        # 指定位置に移動
        case move_position
        when "前"
          self.position = 0
        when "中"
          self.position = 1
        when "後"
          self.position = 2
        end
        # 戻る
        return true
      end
end # $imported["RankConception"]
      
      # 威力が 0 の場合
      if skill.power == 0
        # ダメージに空文字列を設定
        self.damage = ""
        # ステートに変化がない場合
        unless @state_changed
          # ダメージに "Miss" を設定
          self.damage = Vocab::MISS_WORD
        end
      end
    # ミスの場合
    else
      # ダメージに "Miss" を設定
      self.damage = Vocab::MISS_WORD
    end
    # 戦闘中でない場合
    unless $game_temp.in_battle
      # ダメージに nil を設定
      self.damage = nil
    end
    # メソッド終了
    return effective
  end
end

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

#==============================================================================
# ■ Window_BattleStatus
#==============================================================================

class Window_BattleStatus < Window_Base
  #--------------------------------------------------------------------------
  # ● 名前の描画
  #--------------------------------------------------------------------------
  alias draw_actor_name_KGC_RankConception draw_actor_name unless $@
  def draw_actor_name(actor, x, y)
    draw_actor_name_KGC_RankConception(actor, x, y)

    draw_actor_position(actor, x, y, KGC::RC_RANK_OFFSET)
  end
  #--------------------------------------------------------------------------
  # ● 隊列の描画
  #--------------------------------------------------------------------------
  def draw_actor_position(actor, x, y, width)
    image = RPG::Cache.picture(KGC::RC_RANK_IMAGE)
    src_rect = Rect.new(actor.position * 32, 0, 32, 32)
    self.contents.blt(x + width - 32, y, image, src_rect)
  end
end

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

#==============================================================================
# ■ Sprite_Battler
#==============================================================================

class Sprite_Battler < RPG::Sprite
  #--------------------------------------------------------------------------
  # ● フレーム更新
  #--------------------------------------------------------------------------
  alias update_KGC_RankConception update
  def update
    # 元の処理を実行
    update_KGC_RankConception

    return if @battler == nil
    if @battler.is_a?(Game_Enemy)
      # トーン調整
      self.tone   = @battler.zoom_tone_by_position[1]
      # 倍率調整
      self.zoom_x = @battler.zoom_tone_by_position[0]
      self.zoom_y = @battler.zoom_tone_by_position[0]
    end
  end
end

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

#==============================================================================
# ■ Scene_Battle (分割定義 4)
#==============================================================================

class Scene_Battle
  #--------------------------------------------------------------------------
  # ● フレーム更新 (メインフェーズ ステップ 6 : リフレッシュ)
  #--------------------------------------------------------------------------
  alias update_phase4_step6_KGC_RankConception update_phase4_step6
  def update_phase4_step6
    # 存在するエネミーの確認
    pos0_list = []
    pos1_list = []
    pos2_list = []
    for enemy in $game_troop.enemies
      if enemy.exist?
        if enemy.position == 0
          pos0_list.push(enemy)
        elsif enemy.position == 1
          pos1_list.push(enemy)
        else
          pos2_list.push(enemy)
        end
      end
    end
    
    # 前衛/中衛がいない場合、後衛を前衛に移動
    if pos0_list.size == 0 && pos1_list.size == 0
      for enemy in pos2_list
        enemy.position = 0
      end
    end
    # 前衛がいない場合、中衛を前衛に、後衛を中衛に移動
    if pos0_list.size == 0
      for enemy in pos1_list
        enemy.position = 0
      end
      if pos2_list.size != 0
        for enemy in pos2_list
          enemy.position = 1
        end
      end
    end
    
    # 元の処理を実行
    update_phase4_step6_KGC_RankConception
  end

end

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

class Interpreter
  #--------------------------------------------------------------------------
  # ● エネミーの隊列設定
  #     e_no : トループの中のエネミーの番号
  #     pos  : 隊列
  #--------------------------------------------------------------------------
  def set_position(e_no, pos)
    if e_no.is_a?(Numeric) && pos.is_a?(Numeric)
      if $game_troop.enemies[e_no - 1] != nil
        if pos < 0 || pos > 2
          p "無効な隊列が設定されました"
        else
          $game_troop.enemies[e_no - 1].position = pos
          end
      end
    else
      p "数値以外が設定されました。"
    end
  end
end
■とり(あえず)説(明) 隊列によって、距離が次のように決まります。  前衛: 0 中衛: 1 後衛: 2 アクターの場合は、クラスで指定した隊列を使用します。 エネミーの場合は新たに隊列のパラメータを使用します。 ◆隊列から導いた距離による攻撃結果の変動 隊列概念モードによって攻撃結果が変わります。 〇射程外の相手への攻撃は失敗 RC_OUT_RANGE_MODE = 0 攻撃者と攻撃対象の距離を加算し、それが射程内なら攻撃判定、射程外なら失敗判定 例) 攻撃者が前衛、攻撃対象が後衛の場合、両者の距離は 0 + 2 = 2となり 射程が2以上の攻撃しか届きません。 〇射程外の相手への攻撃は威力減 RC_OUT_RANGE_MODE = 1 攻撃者と攻撃対象の距離を加算し、それが射程内なら等倍ダメージ、射程外なら威力減 例) 攻撃者が前衛、攻撃対象が後衛の場合、両者の距離は 0 + 2 = 2となり 射程が2以上の場合のみ等倍ダメージ、それ以外は威力が減ります なお、属性『隊列無視』が設定されている場合、距離を無視して攻撃、等倍ダメージが 可能になります。 ◆隊列の移動 隊列は、(前|中|後)衛移動という属性をセットしたスキルによって変更できます。 例えば前衛移動属性をセットしたスキルの場合、使用すると対象を前衛へ移動させます。 エネミーの場合は上記スキルに加えてスクリプトでの変更も可能です。 set_position(エネミー番号, 隊列) エネミー番号はインデックスではないので -1 する必要はありません。 なお、属性『隊列破壊』が設定されいるスキルを使用された場合、隊列を乱されます。 前衛が後衛に、後衛が前衛に。 ※中衛は変動なし ただし、『隊列維持』のステートにかかっている場合は一度だけ防ぐことができます 現在の隊列は、戦闘ステータスの名前右側の隊列記号から判別できます。 隊列記号用の画像は、TOMY様サイトのものを使用してください。 左から順に「前衛」「中衛」「後衛」を表します。 画像を自作する場合は、32x32を横に三つ並べて作成してください。 ↓ひとまず作ってみた

戻る