#==============================================================================
# ■ 战斗动画增强 v1.0 by SailCat
#------------------------------------------------------------------------------
# 方法:本脚本插入到Main之前使用
# 版本:v1.0 (Build 171125)
# 效果:
# 1. 允许战斗者在一个主回合中连续播放多个动画并显示多个伤害值
# 2. 在所有动画和伤害值显示完毕以前,战斗者不会倒下
# 配置:关于时间间隔的若干配置项
# 冲突:其他动画增强脚本
# 说明:
# 每当需要让战斗者连续显示动画时,使用
# battler.pend_animation(动画ID, 伤害, 会心一击标志) # 追加到动画的队尾
# battler.insert_animation(动画ID, 伤害, 会心一击标志) # 在当前动画后切入
# 后两个参数可以省略,取自己的当前值,此外,还可使用
# battler.animation_id = 动画ID # 立即切入,队列顺延
#==============================================================================
#==============================================================================
# ■ SailCat's 插件公用
#==============================================================================
module SailCat
$sailcat_import ||= {}
#--------------------------------------------------------------------------
# ● 植入
#--------------------------------------------------------------------------
$sailcat_import[:BattleAnimation] = 1.0
#--------------------------------------------------------------------------
# ● 脚本配置区
#--------------------------------------------------------------------------
module BattleAnimation_Config
AWAIT_HIT_INTERVAL = 0 # 每两次动画之间的间隔帧数
AWAIT_DAMAGE_INTERVAL = 8 # 每一击显示伤害的等待时间帧数
AWAIT_DAMAGE_FINAL = 8 # 播放完所有动画后的等待时间帧数
end
end
#==============================================================================
# ■ Game_Battler
#==============================================================================
class Game_Battler
#--------------------------------------------------------------------------
# ● 定义实例变量
#--------------------------------------------------------------------------
attr_reader :pending_animations # 缓存的动画
#--------------------------------------------------------------------------
# ● 方法重定义
#--------------------------------------------------------------------------
unless method_defined? :sailcat_battleani_initialize
alias sailcat_battleani_initialize initialize
end
#--------------------------------------------------------------------------
# ● 初期化
#--------------------------------------------------------------------------
def initialize
sailcat_battleani_initialize
@pending_animations = []
end
#--------------------------------------------------------------------------
# ● 立即切入动画
# value : 新的动画ID
#--------------------------------------------------------------------------
def animation_id=(value)
# 当前动画未处理,又要播放新动画时
insert_animation(@animation_id) if value > 0 and @animation_id > 0
@animation_id = value
end
#--------------------------------------------------------------------------
# ● 缓存动画(在前)
# ani_id : 动画ID
# damage : 伤害
# critical: 会心一击标志
#--------------------------------------------------------------------------
def insert_animation(ani_id, damage = self.damage, critical = self.critical)
# 追加到动画序列的开头
@pending_animations.shift([ani_id, damage, critical])
end
#--------------------------------------------------------------------------
# ● 缓存动画(在后)
# ani_id : 动画ID
# damage : 伤害
# critical: 会心一击标志
#--------------------------------------------------------------------------
def pend_animation(ani_id, damage = self.damage, critical = self.critical)
# 追加到动画序列的末尾
@pending_animations.push([ani_id, damage, critical])
end
#--------------------------------------------------------------------------
# ● 动画等待判定
#--------------------------------------------------------------------------
def animation_pending?
not @pending_animations.empty?
end
#--------------------------------------------------------------------------
# ● 执行下一动画
#--------------------------------------------------------------------------
def next_animation
# 没有动画的情况下返回
return unless animation_pending?
# 动画没播放完的情况下返回
return if @animation_id > 0
animation = @pending_animations.shift
@animation_id = animation[0]
@damage = animation[1]
@critical = animation[2]
@animation_hit = @damage != "Miss"
end
end
#==============================================================================
# ■ Sprite_Battler
#==============================================================================
class Sprite_Battler < RPG::Sprite
include SailCat::BattleAnimation_Config
#--------------------------------------------------------------------------
# ● 效果中判定
#--------------------------------------------------------------------------
def effect?
@_whiten_duration > 0 or
@_appear_duration > 0 or
@_escape_duration > 0 or
@_animation_duration > 0 or
@_collapse_duration > 0 or
@_damage_duration > ($scene.phase4_step == 6 ? 0 : 40 - AWAIT_HIT_INTERVAL)
end
#--------------------------------------------------------------------------
# ● 刷新画面
#--------------------------------------------------------------------------
def update
super
# 战斗者为 nil 的情况下
if @battler == nil
self.bitmap = nil
loop_animation(nil)
return
end
# 总是更新
update_battler_change
update_battler_loop_animation
update_battler_main_phase
update_battler_blink
update_battler_appear
# 可见时更新
if @battler_visible
update_battler_escape
update_battler_whiten
update_battler_animation
update_battler_damage
update_battler_collapse
end
# 设置活动块的坐标
self.x = @battler.screen_x
self.y = @battler.screen_y
self.z = @battler.screen_z
end
#--------------------------------------------------------------------------
# ● 更新画面差异
#--------------------------------------------------------------------------
def update_battler_change
# 文件名和色相与当前情况有差异的情况下
if @battler.battler_name != @battler_name or
@battler.battler_hue != @battler_hue
# 获取、设置位图
@battler_name = @battler.battler_name
@battler_hue = @battler.battler_hue
self.bitmap = RPG::Cache.battler(@battler_name, @battler_hue)
@width = bitmap.width
@height = bitmap.height
self.ox = @width / 2
self.oy = @height
# 如果是战斗不能或者是隐藏状态就把透明度设置成 0
if @battler.dead? or @battler.hidden
self.opacity = 0
end
end
end
#--------------------------------------------------------------------------
# ● 更新状态动画
#--------------------------------------------------------------------------
def update_battler_loop_animation
# 动画 ID 与当前的情况有差异的情况下
if @battler.damage == nil and
@battler.state_animation_id != @state_animation_id
@state_animation_id = @battler.state_animation_id
loop_animation($data_animations[@state_animation_id])
end
end
#--------------------------------------------------------------------------
# ● 更新显示效果
#--------------------------------------------------------------------------
def update_battler_main_phase
# 应该被显示的角色的情况下
if @battler.is_a?(Game_Actor) and @battler_visible
# 不是主状态的时候稍稍降低点透明度
if $game_temp.battle_main_phase
self.opacity += 3 if self.opacity < 255
else
self.opacity -= 3 if self.opacity > 207
end
end
end
#--------------------------------------------------------------------------
# ● 更新明灭
#--------------------------------------------------------------------------
def update_battler_blink
if @battler.blink
blink_on
else
blink_off
end
end
#--------------------------------------------------------------------------
# ● 更新出现
#--------------------------------------------------------------------------
def update_battler_appear
# 不可见的情况下
unless @battler_visible
# 出现
if not @battler.hidden and not @battler.dead? and
(@battler.damage == nil or @battler.damage_pop)
appear
@battler_visible = true
end
end
end
#--------------------------------------------------------------------------
# ● 更新逃跑
#--------------------------------------------------------------------------
def update_battler_escape
if @battler.hidden
$game_system.se_play($data_system.escape_se)
escape
@battler_visible = false
end
end
#--------------------------------------------------------------------------
# ● 更新白色闪烁
#--------------------------------------------------------------------------
def update_battler_whiten
if @battler.white_flash
whiten
@battler.white_flash = false
end
end
#--------------------------------------------------------------------------
# ● 更新动画
#--------------------------------------------------------------------------
def update_battler_animation
if @battler.animation_id != 0
animation = $data_animations[@battler.animation_id]
animation(animation, @battler.animation_hit)
@battler.animation_id = 0
end
end
#--------------------------------------------------------------------------
# ● 更新伤害
#--------------------------------------------------------------------------
def update_battler_damage
if @battler.damage_pop
damage(@battler.damage, @battler.critical)
@battler.damage = nil
@battler.critical = false
@battler.damage_pop = false
end
end
#--------------------------------------------------------------------------
# ● 更新死亡
#--------------------------------------------------------------------------
def update_battler_collapse
# 如果动画没有播放完,不执行死亡效果
return if @battler.animation_pending?
if @battler.damage == nil and @battler.dead?
if @battler.is_a?(Game_Enemy)
$game_system.se_play($data_system.enemy_collapse_se)
else
$game_system.se_play($data_system.actor_collapse_se)
end
collapse
@battler_visible = false
end
end
end
#==============================================================================
# ■ Scene_Battle
#==============================================================================
class Scene_Battle
include SailCat::BattleAnimation_Config
#--------------------------------------------------------------------------
# ● 定义实例变量
#--------------------------------------------------------------------------
attr_accessor :animation1_id
attr_accessor :animation2_id
attr_reader :phase4_step
#--------------------------------------------------------------------------
# ● 刷新画面 (主回合步骤 3 : 行动方动画)
#--------------------------------------------------------------------------
def update_phase4_step3
# 行动方动画 (ID 为 0 的情况下是白色闪烁)
@pending = false
if @animation1_id == 0
@active_battler.white_flash = true
else
# 如果行动者没有设置缓存动画,则设置默认的动画
unless @active_battler.animation_pending?
@active_battler.animation_id = @animation1_id
@active_battler.animation_hit = true
# 如果已经设置了缓存动画,则播放下一个缓存动画
else
@active_battler.next_animation
@pending |= @active_battler.animation_pending?
end
end
# 行动方动画没有播完的情况下,返回
return if @pending
# 为对像方准备默认动画的缓存(如果没有设置)
for target in @target_battlers
target.pend_animation(@animation2_id) unless target.animation_pending?
end
# 移至步骤 4
@phase4_step = 4
end
#--------------------------------------------------------------------------
# ● 刷新画面 (主回合步骤 4 : 对像方动画)
#--------------------------------------------------------------------------
def update_phase4_step4
# 对像方动画
@pending = false
for target in @target_battlers
# 战斗者显示下一动画
target.next_animation if target.animation_pending?
# 仍有动画没显示完的情况下,设置标志
@pending |= target.animation_pending?
end
# 弹出伤害的等待时间
@wait_count = @pending ? AWAIT_DAMAGE_INTERVAL : AWAIT_DAMAGE_FINAL
# 移至步骤 5
@phase4_step = 5
end
#--------------------------------------------------------------------------
# ● 刷新画面 (主回合步骤 5 : 显示伤害)
#--------------------------------------------------------------------------
def update_phase4_step5
# 隐藏帮助窗口
@help_window.visible = false
# 刷新状态窗口
@status_window.refresh
# 显示伤害
@target_battlers.each {|t| t.damage_pop = true if t.damage}
# 仍然有待播放缓存动画的情况下,移至步骤4,否则移到步骤6
@phase4_step = @pending ? 4 : 6
end
end