设为首页收藏本站同能贴吧 切换语言 繁体中文
开启辅助访问 切换到窄版
搜索附件  

击破回复.rar

 

仿FGO式多血条New:
我说,多血条是好文明(,你还在因为平衡不了伤害导致玩家过于强大秒掉你多阶段又机制美的BOSS么?你还在为大后期设计的BOSS血条已经亿万起步而发愁?这个东西或许能解决燃眉之急(大概)

FGO玩多了试着做着玩下,脚本什么的大部分靠AI帮助,有些多余代码也在所难免…………(比如CP 走条是因为测试时用的《XRXS_BP 1. CP半即时》脚本)

功能:敌人HP为0时会立即满血,就算是“即死”状态也要走破条流程,同时减少1个“生命击破”,待“生命击破”全部失去即可击败敌人,在每个“生命击破”时可以设置机制

注意:由于敌人HP为0时会立即满血,如果事件页设置类似[敌人的HP 5%以下]可能会由于玩家伤害过高的原因无法触发。
[Ruby] 纯文本查看 复制代码
#==============================================================================
# ■ FGO 多血条系统 (RPG Maker XP / RGSS1)
#    全部整合在 Window_Help 文件内
#==============================================================================
#可自由转载或使用 萝x婭
#--------------------------------------------------------------------------
# ● 配置区
#--------------------------------------------------------------------------
module FGO_MULTI_HP
  DEFAULT_BARS = 1   # 没配置到的默认 1 管血(即无击破条)
=begin
  HP_BARS = {
  
#++++++++++++++++++++
    #设置ID为33敌人队伍的血管
    33 => {
      1 => 10,   # 1号位敌人 9 管血
      2 => 2,   # 1号位敌人 1 管血
    },
   
   
  #设置ID为34敌人队伍的血管
  34 => {
      1 => 2,   # 1号位敌人 1 管血
      2 => 5,    # 2号位敌人 4 管血
  },
    # 其他战斗继续加,troop_id 去数据库「队伍」页看
#++++++++++++++++++++

  }


  BREAK_ACTIONS = {
  
  #++++++++++++++++++++
  #设置ID为33敌人队伍的破条机制
      33 => {
      1 => [
        proc { |enemy|
        
        $game_party.lose_item(67,9999) #67物品-9999个
        $scene.start_break_image if $scene.respond_to?(:start_break_image)

        },   # 1号位第1管击破
        proc { |enemy|
        
        $game_switches[33] = true #开关打开
        $scene.start_break_image if $scene.respond_to?(:start_break_image)

        },   # 1号位第2管击破
      ],
        2 => [
        proc { |enemy|
        
        $game_party.gain_item(67,9999) #67物品+9999个
        $scene.start_break_image if $scene.respond_to?(:start_break_image)

        },   # 2号位第1管击破
      ],
    },
    #设置ID为34敌人队伍的破条机制
      34 => {
      1 => [
        proc { |enemy|
        
        $game_switches[33] = true #开关打开
        $scene.start_break_image if $scene.respond_to?(:start_break_image)

        },   # 1号位第1管击破
        proc { |enemy|
        
        $scene.start_break_image if $scene.respond_to?(:start_break_image)

        },   # 1号位第2管击破
      ],
        2 => [
        proc { |enemy|
        
        $game_party.gain_item(67,9999) #67物品+9999个
        $scene.start_break_image if $scene.respond_to?(:start_break_image)

        },   # 2号位第1管击破
      ],
    },
  #++++++++++++++++++++
  }
=end


  HP_BARS = {
  
#++++++++++++++++++++
    #设置ID为1敌人队伍的血管
    1 => {
      1 => 10,   # 1号位敌人 9 管血
      2 => 2,   # 1号位敌人 1 管血
    },
   
   
  #设置ID为2敌人队伍的血管
  2 => {
      1 => 2,   # 1号位敌人 1 管血
      2 => 5,    # 2号位敌人 4 管血
  },
    # 其他战斗继续加,troop_id 去数据库「队伍」页看
#++++++++++++++++++++

  }


  BREAK_ACTIONS = {
  
  #++++++++++++++++++++
  #设置ID为1敌人队伍的破条机制
      1 => {
      1 => [
        proc { |enemy|
        
        $game_party.lose_item(67,9999) #67物品-9999个
        $scene.start_break_image if $scene.respond_to?(:start_break_image)

        },   # 1号位第1管击破
        proc { |enemy|
        
        $game_switches[33] = true #开关打开
        $scene.start_break_image if $scene.respond_to?(:start_break_image)

        },   # 1号位第2管击破
      ],
        2 => [
        proc { |enemy|
        
        $game_party.gain_item(67,9999) #67物品+9999个
        $scene.start_break_image if $scene.respond_to?(:start_break_image)

        },   # 2号位第1管击破
      ],
    },
    #设置ID为2敌人队伍的破条机制
      2 => {
      1 => [
        proc { |enemy|
        
        $game_switches[33] = true #开关打开
        $scene.start_break_image if $scene.respond_to?(:start_break_image)

        },   # 1号位第1管击破
        proc { |enemy|
        
        $scene.start_break_image if $scene.respond_to?(:start_break_image)

        },   # 1号位第2管击破
      ],
        2 => [
        proc { |enemy|
        
        $game_party.gain_item(67,9999) #67物品+9999个
        $scene.start_break_image if $scene.respond_to?(:start_break_image)

        },   # 2号位第1管击破
      ],
    },
  #++++++++++++++++++++
  }
  
  REFILL_HP = true
end
#--------------------------------------------------------------------------
# ● Game_Enemy 扩展:多血条逻辑
#--------------------------------------------------------------------------
class Game_Enemy < Game_Battler
  attr_reader :hp_bars
  attr_reader :max_hp_bars
  attr_reader :fgo_position   # ← 新增

  alias_method :fgo_multi_hp_initialize, :initialize
  def initialize(index, enemy_id)
    fgo_multi_hp_initialize(index, enemy_id)
    @fgo_position = index + 1
    @fgo_troop_id = 0
    @max_hp_bars  = FGO_MULTI_HP::DEFAULT_BARS
    @hp_bars      = @max_hp_bars
  end

  # 由 Game_Troop#setup 调用,传入真实的 troop_id 和位置
  def setup_multi_hp(troop_id, position)
    @fgo_troop_id = troop_id
    @fgo_position = position
    troop_bars = FGO_MULTI_HP::HP_BARS[troop_id]
    @max_hp_bars = (troop_bars && troop_bars[position]) ||
                   FGO_MULTI_HP::DEFAULT_BARS
    @hp_bars = @max_hp_bars
  end

alias_method :fgo_original_hp_eq, :hp=
  def hp=(value)
    if value <= 0 && @hp_bars > 1
      @hp_bars -= 1
      self.fgo_original_hp_eq(FGO_MULTI_HP::REFILL_HP ? maxhp : 1)
      ($fgo_break_queue ||= []) << { :enemy => self, :remain => @hp_bars - 1 }
      run_break_action
    else
      self.fgo_original_hp_eq(value)
    end
  end
  
  #--------------------------------------------------------------------------
  # ● 附加状态:即死类走多血条流程,不直接杀死敌人
  #--------------------------------------------------------------------------
  alias_method :fgo_multi_hp_add_state, :add_state
  def add_state(state_id, force = false)
    st = $data_states[state_id]
    if st && st.zero_hp && @hp_bars > 1
      # 判断这个状态能不能真的附加上(已有该状态 / 被抗性挡住 → 不能)
      can_add = force
      unless can_add
        can_add = !@states.include?(state_id)
        if can_add
          # 兼容不同引擎版本的方法名
          if respond_to?(:state_guard?)
            can_add = !state_guard?(state_id)
          elsif respond_to?(:state_guard)
            can_add = !state_guard(state_id)
          end
          # 两个方法都不存在 → 不检查抗性,直接当能加上
        end
      end

      if can_add
        # 不调原版 add_state(它会 @hp = 0 / self.hp = 0 直接杀死敌人)
        # 改为走一次多血条击破:血条 -1、回满、入队
        @hp_bars -= 1
        self.fgo_original_hp_eq(FGO_MULTI_HP::REFILL_HP ? maxhp : 1)
        ($fgo_break_queue ||= []) << { :enemy => self, :remain => @hp_bars - 1 }
        run_break_action
        return
      end
    end
    fgo_multi_hp_add_state(state_id, force)
  end

  def broken_count
    @max_hp_bars - @hp_bars
  end

  def run_break_action
    troop_actions = FGO_MULTI_HP::BREAK_ACTIONS[@fgo_troop_id]
    return unless troop_actions
    actions = troop_actions[@fgo_position]
    return unless actions
    action = actions[broken_count - 1]
    action.call(self) if action
  end
end

#==============================================================================
# ■ Window_Help
#==============================================================================
class Window_Help < Window_Base
   attr_reader :fgo_enemy
  def fgo_showing_enemy?
    @fgo_showing_enemy == true
  end
  def fgo_force_refresh
    @fgo_last_key = nil
  end
  #--------------------------------------------------------------------------
  # ● 强制指定某个敌人显示的 HP(击破动画期间显示 0)
  #--------------------------------------------------------------------------
  def set_hp_override(enemy, value)
    return if @fgo_hp_override_enemy == enemy && @fgo_hp_override_value == value
    @fgo_hp_override_enemy = enemy
    @fgo_hp_override_value = value
    @fgo_last_key = nil
    # 如果当前正在显示敌人,立刻按 override 值重绘
    if @fgo_showing_enemy && @fgo_enemy
      set_enemy(@fgo_enemy)
    end
  end
  #--------------------------------------------------------------------------
  # ● 显示敌人信息(光标选中敌人时调用)
  #--------------------------------------------------------------------------
  def set_enemy(actor)
    if $scene.is_a?(Scene_Battle)
      st     = $scene.instance_variable_get(:@break_state)
      target = $scene.instance_variable_get(:@break_target)
      q      = $fgo_break_queue || []
      ew     = $scene.instance_variable_get(:@enemy_window)

      if st && target
        # 击破流程进行中 → 锁在正在被击破的敌人身上
        return if actor != target
      elsif !q.empty?
        # 队列非空但还没开始播 → 锁到队列里下一个要播的敌人
        pending = q.min_by { |it|
          [it[:enemy].fgo_position.to_i, -it[:remain].to_i]
        }
        return if pending && actor != pending[:enemy]
      elsif $scene.instance_variable_get(:@phase) != 3
        # 不在 phase3(选敌人/输入指令阶段)→ 不显示窗口
        self.visible = false
        @fgo_showing_enemy = false
        return
      end
    end

    @fgo_showing_enemy = true
    @fgo_enemy = actor
    self.contents.clear
    draw_actor_name(actor, 4, 0)
    draw_actor_state(actor, 140, 0)
    carol3_draw_hp_bar(actor, 284, 0)
    carol3_draw_sp_bar(actor, 460, 0)
    @text = nil
    self.visible = true
  end
  #--------------------------------------------------------------------------
  # ● 拦截标准 set_text(显示技能/物品描述时走这里)
  #--------------------------------------------------------------------------
  alias_method :fgo_original_set_text, :set_text
  def set_text(*args)
    @fgo_showing_enemy = false
    fgo_original_set_text(*args)   # 原封不动把所有参数传下去
  end
  #--------------------------------------------------------------------------
  # ● 绘制 HP 条
  #--------------------------------------------------------------------------
  def carol3_draw_hp_bar(actor, x, y, width = 128)
    # 显示值:默认用真实 HP;如果被 override 就按 override 画
    hp_value = actor.hp
    if @fgo_hp_override_enemy && @fgo_hp_override_enemy == actor
      hp_value = @fgo_hp_override_value
    end

    self.contents.font.color = system_color
    w = width * hp_value / [actor.maxhp, 1].max
    if actor.maxhp != 0
      rate = hp_value.to_f / actor.maxhp
    else
      rate = 0
    end
    color1 = Color.new(240 - 72 * rate, 240 * rate, 62 * rate, 150)
    self.contents.fill_rect(x+1, y+15, width+2, 1, Color.new(0, 0, 0, 255))
    self.contents.fill_rect(x+1, y+16, width+2, 1, Color.new(255, 255, 192, 192))
    self.contents.fill_rect(x+1, y+17, w, 6, color1)
    self.contents.fill_rect(x+1, y+23, width+2, 1, Color.new(255, 255, 192, 192))
    self.contents.fill_rect(x+1, y+24, width+2, 1, Color.new(0, 0, 0, 255))
    self.contents.fill_rect(x, y+16, 1, 8, Color.new(255, 255, 192, 192))
    self.contents.fill_rect(x-1, y+15, 1, 10, Color.new(0, 0, 0, 255))
    self.contents.fill_rect(x+129, y+16, 1, 8, Color.new(255, 255, 192, 192))
    self.contents.fill_rect(x+130, y+15, 1, 10, Color.new(0, 0, 0, 255))
    self.contents.draw_text(x-53, y, 128, 32, $data_system.words.hp, 1)
    if hp_value > actor.maxhp / 3
      self.contents.font.color = Color.new(255, 255, 255, 250)
    end
    if hp_value >= actor.maxhp / 6 and actor.maxhp / 3 > hp_value
      self.contents.font.color = Color.new(200, 200, 0, 255)
    end
    if actor.maxhp / 6 > hp_value
      self.contents.font.color = Color.new(200, 0, 0, 255)
    end
    self.contents.draw_text(x+47, y, 128, 32, hp_value.to_s, 1)
  end
  #--------------------------------------------------------------------------
  # ● 绘制 SP 条
  #--------------------------------------------------------------------------
  def carol3_draw_sp_bar(actor, x, y, width = 128)
    self.contents.font.color = system_color
    if actor.maxsp != 0
      rate = actor.sp.to_f / actor.maxsp
    else
      rate = 0
    end
    color2 = Color.new(62 * rate, 240 - 72 * rate, 240 * rate, 192)
    w = width * actor.sp / [actor.maxsp,1].max
    self.contents.fill_rect(x+1, y+15, width+2,1, Color.new(0, 0, 0, 255))
    self.contents.fill_rect(x+1, y+16, width+2,1, Color.new(255, 255, 192, 192))
    self.contents.fill_rect(x+1, y+17, w,6,color2)
    self.contents.fill_rect(x+1, y+23, width+2,1, Color.new(255, 255, 192, 192))
    self.contents.fill_rect(x+1, y+24, width+2,1, Color.new(0, 0, 0, 255))
    self.contents.fill_rect(x, y+16, 1,8, Color.new(255, 255, 192, 192))
    self.contents.fill_rect(x-1, y+15, 1,10, Color.new(0, 0, 0, 255))
    self.contents.fill_rect(x+129, y+16, 1,8, Color.new(255, 255, 192, 192))
    self.contents.fill_rect(x+130, y+15, 1,10, Color.new(0, 0, 0, 255))
    self.contents.draw_text(x-53,y,128,32,$data_system.words.sp,1)
    if actor.hp>actor.maxsp/3
      self.contents.font.color = Color.new(255, 255, 255, 250)
    end
    if actor.hp>=actor.maxsp/6 and actor.maxsp/3>actor.sp
      self.contents.font.color = Color.new(200, 200, 0, 255)
    end
    if actor.maxsp/6>actor.sp
      self.contents.font.color = Color.new(200, 0, 0, 255)
    end
    self.contents.draw_text(x+47,y,128,32,actor.sp.to_s,1)
  end

  #--------------------------------------------------------------------------
  # ● 战斗中自动刷新(只在“正在显示敌人”且数据变化时重绘)
  #--------------------------------------------------------------------------
  def refresh_enemy
    return unless @fgo_showing_enemy   # 不在显示敌人时,什么都不做
    return unless @fgo_enemy
    e = @fgo_enemy
    return unless e.respond_to?(:hp)
    key = [e.hp, e.sp, (e.respond_to?(:hp_bars) ? e.hp_bars : 0)]
    return if @fgo_last_key == key
    @fgo_last_key = key
    set_enemy(e)
  end
end

class Scene_Battle
  BREAK_WINDOW_HOLD = 40   # 击破动画结束后,窗口再显示多少帧(0=立即隐藏)

  #--------------------------------------------------------------------------
  # ● 一轮行动完全结束时,才允许处理击破队列
  #--------------------------------------------------------------------------
  alias_method :fgo_original_update_phase4_step1, :update_phase4_step1
  def update_phase4_step1
    # 队列里还有击破没播完 / 正在播 → 不重置标志,等全部播完再交给下一轮
    queue_busy = ($fgo_break_queue && !$fgo_break_queue.empty?) ||
                 @break_state == :playing || @break_state == :hold
    @break_can_process = false unless queue_busy
    fgo_original_update_phase4_step1
  end
  alias_method :fgo_original_update_phase4_step6, :update_phase4_step6
  def update_phase4_step6
    fgo_original_update_phase4_step6
    @break_can_process = true
  end
  #--------------------------------------------------------------------------
  # ● 检测战斗中是否还有技能/物品动画在播放
  #--------------------------------------------------------------------------
  def animation_playing?
    return false unless @spriteset
    es = @spriteset.instance_variable_get(:@enemy_sprites) || []
    as = @spriteset.instance_variable_get(:@actor_sprites) || []
    (es + as).any? { |s| s.respond_to?(:animation?) && s.animation? }
  end
  
  
  alias_method :fgo_multi_hp_update, :update
  def update
    update_break_cp_control

    fgo_multi_hp_update

    # 队列里有内容 → 本帧刚发生击破,先跳过刷新,等 override 生效
    queue_pending = $fgo_break_queue && !$fgo_break_queue.empty?

    if @help_window && @help_window.respond_to?(:refresh_enemy) &&
       !@break_freeze_help && !queue_pending
      @help_window.refresh_enemy
    end

    update_break_icons
    update_break_window_hide

    update_break_cp_control

    if @help_window && @break_hide_timer && @break_hide_timer > 0
      @help_window.visible = true
    end
  end

  
  #--------------------------------------------------------------------------
  # ● 击破动画播放期间,暂停战斗流程(phase4 不推进)
  #--------------------------------------------------------------------------
  alias_method :fgo_original_update_phase4, :update_phase4
  def update_phase4
    # 只判断「正在播 / 刚播完保持中」;队列非空不算 busy,
    # 让 phase4 走完当前轮,step6 里设 @break_can_process = true
    busy = @break_state || (@break_hide_timer && @break_hide_timer > 0)
    return if busy
    fgo_original_update_phase4
  end
  #--------------------------------------------------------------------------
  # ● 击破动画期间暂停 CP 走条,结束后恢复原状态
  #    注意:XRXS_BP 的 Scene_Battle_CP#stop 是会 join 线程的方法,
  #    不能用 @cp_thread.stop 去读/写,只能直接操作内部变量 @stop
  #--------------------------------------------------------------------------
  def update_break_cp_control
    return unless @cp_thread

    if @break_state == :playing ||
       @break_state == :recover ||
       (@break_hide_timer && @break_hide_timer > 0)
      unless @break_cp_stopped
        # 记录进入时的原状态,避免和 XRXS_BP 自己的暂停冲突
        @break_cp_prev_stop = @cp_thread.instance_variable_get(:@stop)
        @break_cp_stopped   = true
      end
      @cp_thread.instance_variable_set(:@stop, true)
    elsif @break_cp_stopped
      @cp_thread.instance_variable_set(:@stop, @break_cp_prev_stop)
      @break_cp_stopped = false
    end
  end

  #--------------------------------------------------------------------------
  # ● 击破动画结束后:保持窗口显示一段时间,然后隐藏
  #--------------------------------------------------------------------------
  def update_break_window_hide
    return unless @break_hide_timer && @break_hide_timer > 0
    @break_hide_timer -= 1
    if @break_hide_timer <= 0
      @break_hide_timer = nil
      @break_state     = nil
      # 队列里还有没播的击破 → 不隐藏,接着播下一个
      if $fgo_break_queue && !$fgo_break_queue.empty?
        return
      end
      @help_window.visible = false if @help_window
      @break_icons.each { |s| s.visible = false } if @break_icons
    end
  end

  #--------------------------------------------------------------------------
  # ● 击破图标:播放中 / 常驻显示
  #--------------------------------------------------------------------------
  def update_break_icons
    @break_icons ||= []
    @break_anim  ||= {}
    $fgo_break_queue ||= []

    #开始一个新的击破动画
    if @break_state.nil? && !$fgo_break_queue.empty? && @break_can_process
      # 排序:先按敌人位置(1号位→2号位→3号位…),同位置按 remain 降序(先被击破的先播)
      $fgo_break_queue.sort! { |a, b|
        pa = a[:enemy].fgo_position.to_i
        pb = b[:enemy].fgo_position.to_i
        if pa == pb
          b[:remain] <=> a[:remain]
        else
          pa <=> pb
        end
      }
      item      = $fgo_break_queue.shift
      enemy     = item[:enemy]
      anim_idx  = item[:remain]      # ← 这次击破要闪的图标索引(固定值)

      @break_target      = enemy
      @break_remain      = item[:remain]   # ← 固定住这次击破后的剩余数
      @break_state       = :playing
      @break_freeze_help = true

      if @help_window
        @help_window.set_enemy(enemy)
        @help_window.visible = true
      end

      @break_icons.each { |s| s.visible = false; s.tone = Tone.new(0,0,0,0) }
      @break_anim.clear

      total = enemy.max_hp_bars - 1
      while @break_icons.size < total
        spr = Sprite.new
        begin
          spr.bitmap = Bitmap.new("Graphics/Pictures/生命击破")
        rescue
          spr.dispose
          return
        end
        spr.z = 9999
        spr.visible = false
        @break_icons << spr
      end

      if anim_idx >= 0 && @break_icons[anim_idx]
        @break_icons[anim_idx].visible = true
        @break_icons[anim_idx].tone = Tone.new(255, 0, 0, 0)
        @break_anim[anim_idx] = { :phase => 0, :timer => 0 }
      end
    end

    # 击破动画播放中 → 窗口显示 0 血
    # 全部播完后 → 从 0 逐渐回复到满
    if @help_window && @help_window.respond_to?(:set_hp_override)
      case @break_state
      when :playing
        @help_window.set_hp_override(@break_target, 0)
      when :hold
        if @break_keep_zero
          @help_window.set_hp_override(@break_target, 0)
        else
          @help_window.set_hp_override(nil, nil)
        end
      when :recover
        @help_window.set_hp_override(@break_target, @break_recover_hp)
      else
        @help_window.set_hp_override(nil, nil)
      end
    end
   
    # 动画中强制窗口可见
    if @break_state == :playing && @help_window
      @help_window.visible = true
    end

    # ============================================================
    # 分支 A:不在播放 → 常驻显示(跟随帮助窗口当前显示的敌人)
    # ============================================================
    if @break_state.nil?
      # 帮助窗口没在显示敌人(选技能/物品/按 Esc)→ 全部隐藏
      unless @help_window &&
             @help_window.visible &&
             @help_window.respond_to?(:fgo_showing_enemy?) &&
             @help_window.fgo_showing_enemy?
        @break_icons.each { |s| s.visible = false }
        return
      end

      enemy = @help_window.fgo_enemy
      unless enemy && enemy.respond_to?(:max_hp_bars) && enemy.max_hp_bars > 1
        @break_icons.each { |s| s.visible = false }
        return
      end

      total  = enemy.max_hp_bars - 1
      remain = enemy.hp_bars - 1

      while @break_icons.size < total
        spr = Sprite.new
        begin
          spr.bitmap = Bitmap.new("Graphics/Pictures/生命击破")
        rescue
          spr.dispose
          return
        end
        spr.z = 9999
        spr.visible = false
        @break_icons << spr
      end

      base_x = 0
      base_y = 65
      gap    = 2

      @break_icons.each_with_index do |spr, i|
        if i < remain
          spr.visible = true
          spr.tone = Tone.new(0, 0, 0, 0)
          spr.x = base_x + i * (spr.bitmap.width + gap)
          spr.y = base_y
        else
          spr.visible = false
        end
      end
      return
    end

    # ============================================================
    # 分支 B:播放动画中
    # ============================================================
    enemy  = @break_target
    total  = enemy.max_hp_bars - 1
    remain = @break_remain     # ← 用这次击破时固定下来的值

    base_x = 0
    base_y = 65
    gap    = 2

    @break_icons.each_with_index do |spr, i|
      anim = @break_anim

      if anim
        spr.visible = true
        anim[:timer] += 1
        if anim[:timer] >= 10
          anim[:timer] = 0
          anim[:phase] += 1
          case anim[:phase]
          when 1, 3, 5
            spr.tone = Tone.new(0, 0, 0, 0)       # 暗
          when 2, 4
            spr.tone = Tone.new(255, 0, 0, 0)     # 红
          when 6
            Audio.se_play("Audio/SE/玻璃碎-L", 80, 100)
            spr.tone = Tone.new(0, 0, 0, 0)
            spr.visible = false
            @break_anim.delete(i)
          end
        end
      elsif i < remain
        spr.visible = true
        spr.tone = Tone.new(0, 0, 0, 0)
      else
        spr.visible = false
      end

      if spr.visible
        spr.x = base_x + i * (spr.bitmap.width + gap)
        spr.y = base_y
      end
    end
    # 动画结束 → 一律进入 recover,让当前敌人 HP 从 0 涨满
    if @break_state == :playing && @break_anim.empty?
      @break_state        = :recover
      @break_freeze_help  = false
      @break_keep_zero    = false
      @break_recover_hp   = 0
      @break_recover_step = [(@break_target.maxhp / 30.0).ceil, 1].max
      Audio.se_play("Audio/SE/紫技回3", 80, 100)   # ← 新增:回血前播一次
      if @help_window
        @help_window.visible = true
        @help_window.fgo_force_refresh if @help_window.respond_to?(:fgo_force_refresh)
        @help_window.refresh_enemy    if @help_window.respond_to?(:refresh_enemy)
      end
    end

    # recover 阶段:每帧把 HP 往上加
    if @break_state == :recover && @break_target
      @break_recover_hp += @break_recover_step
      if @break_recover_hp >= @break_target.maxhp
        @break_recover_hp = @break_target.maxhp
        if $fgo_break_queue && !$fgo_break_queue.empty?
          # 队列还有下一个敌人 → 短暂 hold 后立即处理
          @break_state      = :hold
          @break_keep_zero  = false
          @break_hide_timer = BREAK_WINDOW_HOLD
        else
          # 全部播完 → 进入最终 hold,窗口保持一段时间再隐藏
          @break_state      = :hold
          @break_keep_zero  = false
          @break_hide_timer = BREAK_WINDOW_HOLD
        end
      end
    end
    # 队列和动画都清空后,复位标志,等下个 step6 再开启
    if $fgo_break_queue.empty? && @break_state.nil? && @break_anim.empty?
      @break_can_process = false
    end
  end
end

class Game_Troop
  alias_method :fgo_multi_hp_setup, :setup
  def setup(troop_id)
    fgo_multi_hp_setup(troop_id)
    # 此时 @troop_id 和 @enemies 都已就绪
    @enemies.each_with_index do |enemy, i|
      enemy.setup_multi_hp(troop_id, i + 1)
    end
  end
end
#==============================================================================
# 本脚本来自www.66RPG.com,使用和转载请保留此信息
#==============================================================================


            本帖来自P1论坛作者1103123301,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg. blue/forum.php?mod=viewthread&tid=499336  若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
简体中文
繁體中文
English(英语)
日本語(日语)
Deutsch(德语)
Русский язык(俄语)
بالعربية(阿拉伯语)
Türkçe(土耳其语)
Português(葡萄牙语)
ภาษาไทย(泰国语)
한어(朝鲜语/韩语)
Français(法语)
关闭

幸运抽奖

社区每日抽奖来袭,快来试试你是欧皇还是非酋~

立即查看

Loading...

QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

GMT+8, 2026-10-15 19:15 , Processed in 0.101740 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.