#==============================================================================
# ** Sprite_Battler
#
# This sprite is used to display the battler.It observes the Game_Character
# class and automatically changes sprite conditions.
#==============================================================================
class Sprite_Battler < RPG::Sprite
#
# * Object Initialization
# viewport : viewport
# battler : battler (Game_Battler)
#
def initialize(viewport, battler = nil)
super(viewport)
@battler = battler
@battler_visible = false
if @battler != nil
@pose = @battler.pose
end
@frame = 0
@frame_height = 0
@count = Graphics.frame_count
@frames = []
@moving = false
@move_speed = 10
@hold_pose = -1
make_sprite_sheet
end
#
# * Frame Update
#
def update
super
# If battler is nil
if @battler == nil
self.bitmap = nil
loop_animation(nil)
return
end
# If file name or hue are different than current ones
if @battler.battler_name != @battler_name or
@battler.battler_hue != @battler_hue
# Get and set bitmap
@battler_name = @battler.battler_name
@battler_hue = @battler.battler_hue
if @battler.animated
make_sprite_sheet
self.bitmap = @sprite_sheet
self.ox = @frame_height / 2
self.oy = @frame_height
@battler.height = @battler.width = @frame_height
else
self.bitmap = RPG::Cache.battler(@battler_name, @battler_hue)
@width = bitmap.width
@height = bitmap.height
self.ox = @width / 2
self.oy = @height
@battler.height = @height
@battler.width = @width
end
# Change opacity level to 0 when dead or hidden
if @battler.dead? or @battler.hidden
self.opacity = 0
end
end
# animation stuff
# if the battler's pose has changed
if @battler.pose != @pose and @hold_pose == -1
if @pose == $BATTLEOPEN
@hold_pose = @battler.pose
else
@frame = 0
@pose = @battler.pose
end
end
if Graphics.frame_count - @count >= 10 and !@animation_stop and @battler.animated
@count = Graphics.frame_count
self.src_rect = Rect.new(@frame * @frame_height, @pose * @frame_height, @frame_height, @frame_height)
@frame = @frame + 1
# if we've reached the end of the frames for this pose
if @frame == @frames[@pose]
if @pose == $VICTORY and
[email protected]_victory
@animation_stop = true
end
if @hold_pose != -1
@pose = @hold_pose
@hold_pose = -1
end
if @battler.loop == false
@battler.set_pose(@battler.base_pose)
end
@frame = 0
end
end
# end animation stuff
# If the battler needs to move somewhere
if @battler.target_x != @battler.actual_x or @battler.target_y != @battler.actual_y
@moving = true
slope = (@battler.target_y.to_f - @battler.actual_y.to_f) / (@battler.target_x.to_f - @battler.actual_x.to_f)
if slope < 0
slope = -slope
end
@move_x = Math.sqrt((@move_speed * @move_speed) / (slope * slope + 1))
@move_y = slope * @move_x
end
# If animation ID is different than current one
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
# If invisible
unless @battler_visible
# Appear
if not @battler.hidden and not @battler.dead? and
(@battler.damage == nil or @battler.damage_pop)
appear
@battler_visible = true
end
end
# If visible
if @battler_visible
# Escape
if @battler.hidden
$game_system.se_play($data_system.escape_se)
escape
@battler_visible = false
end
# Animation
if @battler.animation_id != 0
animation = $data_animations[@battler.animation_id]
animation(animation, @battler.animation_hit)
@battler.animation_id = 0
end
# Damage
if @battler.damage_pop
damage(@battler.damage, @battler.critical)
@battler.damage = nil
@battler.critical = false
@battler.damage_pop = false
end
# Collapse
if @battler.damage == nil and @battler.dead?
if @battler.is_a?(Game_Enemy)
$game_system.se_play($data_system.enemy_collapse_se)
@battler_visible = false
collapse
elsif @pose != $DEAD
$game_system.se_play($data_system.actor_collapse_se)
@battler.set_pose($DEAD)
end
end
end
# Set sprite coordinates
if @moving
if @battler.actual_x < @battler.target_x
#battler is to the left of the target
@battler.actual_x += @move_x
if @battler.actual_x > @battler.target_x
@battler.actual_x = @battler.target_x
end
else
# battler is to the right of the target
@battler.actual_x -= @move_x
if @battler.actual_x < @battler.target_x
@battler.actual_x = @battler.target_x
end
end
if @battler.actual_y < @battler.target_y
# battler is above the target
@battler.actual_y += @move_y
if @battler.actual_y > @battler.target_y
@battler.actual_y = @battler.target_y
end
else
# battler is below the target
@battler.actual_y -= @move_y
if @battler.actual_y < @battler.target_y
@battler.actual_y = @battler.target_y
end
end
self.x = @battler.actual_x
self.y = @battler.actual_y
if self.x == @battler.target_x and self.y == @battler.target_y
@moving = false
end
else
self.x = @battler.actual_x
self.y = @battler.actual_y
end
self.z = @battler.screen_z
end
def make_sprite_sheet
if @battler == nil
@spritesheet = Bitmap.new(1, 1)
return
end
if @battler.is_a?(Game_Actor)
@game_actor = true
weapon = $data_weapons[@battler.weapon_id]
if weapon != nil
begin
RPG::Cache.battler(@battler.battler_name + "_attack_" + weapon.name.sub(" ", "_"), @battler.battler_hue)
@pose_names = ["_ready", "_guard", "_hit", "_miss", "_skill_default",
"_attack_" + weapon.name.sub(" ", "_"), "_lowhp",
"_moveto", "_movefrom", "_dead", "_battle_open", "_item"]
rescue
@pose_names = ["_ready", "_guard", "_hit", "_miss", "_skill_default",
"_attack_default", "_lowhp", "_moveto", "_movefrom",
"_dead", "_battle_open", "_item"]
end
else
@pose_names = ["_ready", "_guard", "_hit", "_miss", "_skill_default",
"_attack_default", "_lowhp", "_moveto", "_movefrom",
"_dead", "_battle_open", "_item"]
end
# if we have two victory animations, pick the second at a 25% chance
begin
RPG::Cache.battler(@battler.battler_name + "_victory2.png", @battler.battler_hue)
r = rand(100)
if r <= 25
@pose_names.push("_victory2")
else
@pose_names.push("_victory1")
end
rescue # only one victory animation, get it
@pose_names.push("_victory")
end
index = $VICTORY + 1
# Status Effects
for i in $STATES_ANIMATED
@pose_names.push("_state_" + $data_states
.name.sub(" ", "_"))
index += 1
end
# Now for the tricky part, skills
if $USING_INDIV_SKILL_ANIM
@battler.skill_hash = Hash.new($SKILL) # default skill animation
for skill in @battler.skills
filename = "_skill_" + $data_skills[skill].name.sub(" ", "_")
# first, see if a animation for that particular skill exists
begin
RPG::Cache.battler(@battler.battler_name + filename, @battler.battler_hue)
@pose_names.push(filename)
@battler.skill_hash[$data_skills[skill].name] = index
index += 1
rescue
# animation does not exist for skill, check skill type
for i in 0...$SKILL_KINDS.size
if $data_skills[skill].element_set.include?($SKILL_OFFSET + i)
filename = "_skill_" + $SKILL_KINDS.sub("_", " ")
begin
RPG::Cache.battler(@battler.battler_name + filename, @battler.battler_hue)
@pose_names.push(filename)
@battler.skill_hash[$data_skills[skill].name] = index
index += 1
break
rescue
# do nothing
end
end
end
end
end
else # skill animations by type
@battler.skill_type_hash = Hash.new($SKILL) # default skill animation
for skill in $SKILL_KINDS
filesuffix = "_skill_" + skill.sub(" ", "_")
begin
RPG::Cache.battler(@battler.battler_name + filesuffix, @battler.battler_hue)
@pose_names.push(filesuffix)
@battler.skill_type_hash[skill] = index
index += 1
rescue
# do nothing
end
end
end
# If we're using visible weapons, better get that, too
if $USING_VISIBLE_WEAPONS and weapon != nil
weapon_poses = []
weapon_name = weapon.name.sub(" ", "_")
for string in @pose_names
weapon_poses.push("_" + weapon_name + string)
end
end
else # the battler is an enemy. Much simpler.
if [email protected]
return
end
@pose_names = ["_ready", "_guard", "_hit", "_miss", "_skill", "_attack",
"_lowhp", "_moveto", "_movefrom"]
end
bitmaps = []
height = width = 0
@frame_height = 0
@frames = []
weapon_bitmaps = []
dummy_image = Bitmap.new(1, 1)
for i in 0...@pose_names.size
begin
RPG::Cache.battler(@battler.battler_name + @pose_names, @battler.battler_hue)
bitmaps = RPG::Cache.battler(@battler.battler_name + @pose_names, @battler.battler_hue)
height += bitmaps.height
width = [width, bitmaps.width].max
@frames = bitmaps.width / bitmaps.height
@frame_height = bitmaps.height
if $USING_VISIBLE_WEAPONS and @game_actor
begin
weapon_bitmaps = RPG::Cache.battler(@battler.battler_name + weapon_poses, @battler.battler_hue)
rescue
weapon_bitmaps = dummy_image
end
end
if @pose_names.include?("attack")
@battler.attack_frames = @frames
end
rescue
bitmaps = nil
height += @frame_height
@frames = 0
end
end
@sprite_sheet = Bitmap.new(width, height)
mark = 0
for i in 0..bitmaps.size
if bitmaps != nil
if $USING_VISIBLE_WEAPONS and @game_actor
@sprite_sheet.blt(0, mark, bitmaps, bitmaps.rect)
@sprite_sheet.blt(0, mark, weapon_bitmaps, weapon_bitmaps.rect)
else
@sprite_sheet.blt(0, mark, bitmaps, bitmaps.rect)
end
end
mark += @frame_height
end
end
end