mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-08 05:34:58 +00:00
Anim Editor: polishing, refactoring, ensuring data
This commit is contained in:
@@ -33,6 +33,14 @@ class UIControls::Scrollbar < UIControls::BaseControl
|
|||||||
return (@range - @tray_size) * @slider_top / (@tray_size - @slider_size)
|
return (@range - @tray_size) * @slider_top / (@tray_size - @slider_size)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def minimum?
|
||||||
|
return @slider_top <= 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def maximum?
|
||||||
|
return @slider_top >= @tray_size - @slider_size
|
||||||
|
end
|
||||||
|
|
||||||
# Range is the total size of the large area that the scrollbar is able to
|
# Range is the total size of the large area that the scrollbar is able to
|
||||||
# show part of.
|
# show part of.
|
||||||
def range=(new_val)
|
def range=(new_val)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ module Compiler
|
|||||||
elsif line[/^\s*(\w+)\s*=\s*(.*)$/]
|
elsif line[/^\s*(\w+)\s*=\s*(.*)$/]
|
||||||
# XXX=YYY lines
|
# XXX=YYY lines
|
||||||
if !data_hash
|
if !data_hash
|
||||||
raise _INTL("Expected a section at the beginning of the file.\n{1}", FileLineData.linereport)
|
raise _INTL("Expected a section at the beginning of the file.") + "\n" + FileLineData.linereport
|
||||||
end
|
end
|
||||||
key = $~[1]
|
key = $~[1]
|
||||||
if schema[key] # Property of the animation
|
if schema[key] # Property of the animation
|
||||||
@@ -62,7 +62,7 @@ module Compiler
|
|||||||
end
|
end
|
||||||
elsif sub_schema[key] # Property of a particle
|
elsif sub_schema[key] # Property of a particle
|
||||||
if !current_particle
|
if !current_particle
|
||||||
raise _INTL("Particle hasn't been defined yet!\n{1}", FileLineData.linereport)
|
raise _INTL("Particle hasn't been defined yet!") + "\n" + FileLineData.linereport
|
||||||
end
|
end
|
||||||
value = get_csv_record($~[2], sub_schema[key])
|
value = get_csv_record($~[2], sub_schema[key])
|
||||||
if sub_schema[key][1][0] == "^"
|
if sub_schema[key][1][0] == "^"
|
||||||
@@ -154,20 +154,51 @@ module Compiler
|
|||||||
when "Target" then particle[:graphic] = "TARGET"
|
when "Target" then particle[:graphic] = "TARGET"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Ensure that particles don't have a focus involving a user if the
|
# Ensure that particles don't have a focus involving a user, and the
|
||||||
# animation itself doesn't involve a user
|
# animation doesn't play a user's cry, if the animation itself doesn't
|
||||||
if hash[:no_user] && GameData::Animation::FOCUS_TYPES_WITH_USER.include?(particle[:focus])
|
# involve a user
|
||||||
raise _INTL("Particle \"{1}\" can't have a \"Focus\" that involves a user if property \"NoUser\" is set to true.",
|
if hash[:no_user]
|
||||||
particle[:name]) + "\n" + FileLineData.linereport
|
if GameData::Animation::FOCUS_TYPES_WITH_USER.include?(particle[:focus])
|
||||||
|
raise _INTL("Particle \"{1}\" can't have a \"Focus\" that involves a user if property \"NoUser\" is set to true.",
|
||||||
|
particle[:name]) + "\n" + FileLineData.linereport
|
||||||
|
end
|
||||||
|
if particle[:name] == "SE" && particle[:user_cry] && !particle[:user_cry].empty?
|
||||||
|
raise _INTL("Animation can't play the user's cry if property \"NoUser\" is set to true.") + "\n" + FileLineData.linereport
|
||||||
|
end
|
||||||
end
|
end
|
||||||
# Ensure that particles don't have a focus involving a target if the
|
# Ensure that particles don't have a focus involving a target, and the
|
||||||
# animation itself doesn't involve a target
|
# animation doesn't play a target's cry, if the animation itself doesn't
|
||||||
if hash[:no_target] && GameData::Animation::FOCUS_TYPES_WITH_TARGET.include?(particle[:focus])
|
# involve a target
|
||||||
raise _INTL("Particle \"{1}\" can't have a \"Focus\" that involves a target if property \"NoTarget\" is set to true.",
|
if hash[:no_target]
|
||||||
particle[:name]) + "\n" + FileLineData.linereport
|
if GameData::Animation::FOCUS_TYPES_WITH_TARGET.include?(particle[:focus])
|
||||||
|
raise _INTL("Particle \"{1}\" can't have a \"Focus\" that involves a target if property \"NoTarget\" is set to true.",
|
||||||
|
particle[:name]) + "\n" + FileLineData.linereport
|
||||||
|
end
|
||||||
|
if particle[:name] == "SE" && particle[:target_cry] && !particle[:target_cry].empty?
|
||||||
|
raise _INTL("Animation can't play the target's cry if property \"NoTarget\" is set to true.") + "\n" + FileLineData.linereport
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Ensure that the same SE isn't played twice in the same frame
|
||||||
|
if particle[:name] == "SE"
|
||||||
|
[:se, :user_cry, :target_cry].each do |property|
|
||||||
|
next if !particle[property]
|
||||||
|
files_played = []
|
||||||
|
particle[property].each do |play|
|
||||||
|
files_played[play[0]] ||= []
|
||||||
|
if files_played[play[0]].include?(play[1])
|
||||||
|
case property
|
||||||
|
when :se
|
||||||
|
raise _INTL("SE \"{1}\" should not play twice in the same frame ({2}).", play[1], play[0]) + "\n" + FileLineData.linereport
|
||||||
|
when :user_cry
|
||||||
|
raise _INTL("User's cry should not play twice in the same frame ({1}).", play[0]) + "\n" + FileLineData.linereport
|
||||||
|
when :target_cry
|
||||||
|
raise _INTL("Target's cry should not play twice in the same frame ({1}).", play[0]) + "\n" + FileLineData.linereport
|
||||||
|
end
|
||||||
|
end
|
||||||
|
files_played[play[0]].push(play[1])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
# TODO: For SE particle, ensure that it doesn't play two instances of the
|
|
||||||
# same file in the same frame.
|
|
||||||
# Convert all "SetXYZ" particle commands to "MoveXYZ" by giving them a
|
# Convert all "SetXYZ" particle commands to "MoveXYZ" by giving them a
|
||||||
# duration of 0 (even ones that can't have a "MoveXYZ" command)
|
# duration of 0 (even ones that can't have a "MoveXYZ" command)
|
||||||
GameData::Animation::PARTICLE_KEYFRAME_DEFAULT_VALUES.keys.each do |prop|
|
GameData::Animation::PARTICLE_KEYFRAME_DEFAULT_VALUES.keys.each do |prop|
|
||||||
@@ -293,6 +324,7 @@ module Compiler
|
|||||||
rescue SystemCallError
|
rescue SystemCallError
|
||||||
end
|
end
|
||||||
raise Reset.new if e.is_a?(Hangup)
|
raise Reset.new if e.is_a?(Hangup)
|
||||||
|
raise SystemExit.new if e.is_a?(RuntimeError)
|
||||||
raise "Unknown exception when compiling animations."
|
raise "Unknown exception when compiling animations."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -711,7 +711,7 @@ class AnimationEditor
|
|||||||
# Disable the "move particle up/down" buttons if the selected particle
|
# Disable the "move particle up/down" buttons if the selected particle
|
||||||
# can't move that way (or there is no selected particle)
|
# can't move that way (or there is no selected particle)
|
||||||
cur_index = particle_index
|
cur_index = particle_index
|
||||||
if cur_index < 1
|
if cur_index < 1 || @anim[:particles][cur_index][:name] == "SE"
|
||||||
component.get_control(:move_particle_up).disable
|
component.get_control(:move_particle_up).disable
|
||||||
else
|
else
|
||||||
component.get_control(:move_particle_up).enable
|
component.get_control(:move_particle_up).enable
|
||||||
@@ -847,12 +847,14 @@ class AnimationEditor
|
|||||||
end
|
end
|
||||||
when :duplicate
|
when :duplicate
|
||||||
AnimationEditor::ParticleDataHelper.duplicate_particle(@anim[:particles], particle_index)
|
AnimationEditor::ParticleDataHelper.duplicate_particle(@anim[:particles], particle_index)
|
||||||
|
@components[:particle_list].add_particle(particle_index + 1)
|
||||||
@components[:particle_list].set_particles(@anim[:particles])
|
@components[:particle_list].set_particles(@anim[:particles])
|
||||||
@components[:particle_list].particle_index = particle_index + 1
|
@components[:particle_list].particle_index = particle_index + 1
|
||||||
refresh
|
refresh
|
||||||
when :delete
|
when :delete
|
||||||
if confirm_message(_INTL("Are you sure you want to delete this particle?"))
|
if confirm_message(_INTL("Are you sure you want to delete this particle?"))
|
||||||
AnimationEditor::ParticleDataHelper.delete_particle(@anim[:particles], particle_index)
|
AnimationEditor::ParticleDataHelper.delete_particle(@anim[:particles], particle_index)
|
||||||
|
@components[:particle_list].delete_particle(particle_index)
|
||||||
@components[:particle_list].set_particles(@anim[:particles])
|
@components[:particle_list].set_particles(@anim[:particles])
|
||||||
@components[:particle_list].keyframe = 0 if @anim[:particles][particle_index][:name] == "SE"
|
@components[:particle_list].keyframe = 0 if @anim[:particles][particle_index][:name] == "SE"
|
||||||
refresh
|
refresh
|
||||||
@@ -875,6 +877,7 @@ class AnimationEditor
|
|||||||
new_idx = @anim[:particles].length - 1 if new_idx == 0 || new_idx >= @anim[:particles].length
|
new_idx = @anim[:particles].length - 1 if new_idx == 0 || new_idx >= @anim[:particles].length
|
||||||
end
|
end
|
||||||
AnimationEditor::ParticleDataHelper.add_particle(@anim[:particles], new_idx)
|
AnimationEditor::ParticleDataHelper.add_particle(@anim[:particles], new_idx)
|
||||||
|
@components[:particle_list].add_particle(new_idx)
|
||||||
@components[:particle_list].set_particles(@anim[:particles])
|
@components[:particle_list].set_particles(@anim[:particles])
|
||||||
@components[:particle_list].particle_index = (new_idx >= 0) ? new_idx : @anim[:particles].length - 2
|
@components[:particle_list].particle_index = (new_idx >= 0) ? new_idx : @anim[:particles].length - 2
|
||||||
@components[:particle_list].keyframe = -1
|
@components[:particle_list].keyframe = -1
|
||||||
@@ -883,6 +886,7 @@ class AnimationEditor
|
|||||||
idx1 = particle_index
|
idx1 = particle_index
|
||||||
idx2 = idx1 - 1
|
idx2 = idx1 - 1
|
||||||
AnimationEditor::ParticleDataHelper.swap_particles(@anim[:particles], idx1, idx2)
|
AnimationEditor::ParticleDataHelper.swap_particles(@anim[:particles], idx1, idx2)
|
||||||
|
@components[:particle_list].swap_particles(idx1, idx2)
|
||||||
@components[:particle_list].set_particles(@anim[:particles])
|
@components[:particle_list].set_particles(@anim[:particles])
|
||||||
@components[:particle_list].particle_index = idx2
|
@components[:particle_list].particle_index = idx2
|
||||||
refresh
|
refresh
|
||||||
@@ -890,6 +894,7 @@ class AnimationEditor
|
|||||||
idx1 = particle_index
|
idx1 = particle_index
|
||||||
idx2 = idx1 + 1
|
idx2 = idx1 + 1
|
||||||
AnimationEditor::ParticleDataHelper.swap_particles(@anim[:particles], idx1, idx2)
|
AnimationEditor::ParticleDataHelper.swap_particles(@anim[:particles], idx1, idx2)
|
||||||
|
@components[:particle_list].swap_particles(idx1, idx2)
|
||||||
@components[:particle_list].set_particles(@anim[:particles])
|
@components[:particle_list].set_particles(@anim[:particles])
|
||||||
@components[:particle_list].particle_index = idx2
|
@components[:particle_list].particle_index = idx2
|
||||||
refresh
|
refresh
|
||||||
@@ -932,16 +937,48 @@ class AnimationEditor
|
|||||||
@anim[property] = txt
|
@anim[property] = txt
|
||||||
when :has_user
|
when :has_user
|
||||||
@anim[:no_user] = !value
|
@anim[:no_user] = !value
|
||||||
# TODO: Add/delete the "User" particle accordingly, and change the foci
|
if @anim[:no_user]
|
||||||
# of any other particle involving a user. Then refresh a lot of
|
@anim[:particles].delete_if { |particle| particle[:name] == "User" }
|
||||||
# components.
|
@anim[:particles].each do |particle|
|
||||||
refresh_component(:canvas)
|
if ["USER", "USER_OPP", "USER_FRONT", "USER_BACK"].include?(particle[:graphic])
|
||||||
|
particle[:graphic] = GameData::Animation::PARTICLE_DEFAULT_VALUES[:graphic]
|
||||||
|
end
|
||||||
|
if GameData::Animation::FOCUS_TYPES_WITH_USER.include?(particle[:focus])
|
||||||
|
particle[:focus] = GameData::Animation::PARTICLE_DEFAULT_VALUES[:focus]
|
||||||
|
end
|
||||||
|
particle[:user_cry] = nil if particle[:name] == "SE"
|
||||||
|
end
|
||||||
|
@components[:particle_list].delete_particle(0)
|
||||||
|
elsif @anim[:particles].none? { |particle| particle[:name] == "User" }
|
||||||
|
@anim[:particles].insert(0, {
|
||||||
|
:name => "User", :focus => :user, :graphic => "USER"
|
||||||
|
})
|
||||||
|
@components[:particle_list].add_particle(0)
|
||||||
|
end
|
||||||
|
@components[:particle_list].set_particles(@anim[:particles])
|
||||||
|
refresh
|
||||||
when :has_target
|
when :has_target
|
||||||
@anim[:no_target] = !value
|
@anim[:no_target] = !value
|
||||||
# TODO: Add/delete the "Target" particle accordingly, and change the
|
if @anim[:no_target]
|
||||||
# foci of any other particle involving a target. Then refresh a
|
@anim[:particles].delete_if { |particle| particle[:name] == "Target" }
|
||||||
# lot of components.
|
@anim[:particles].each do |particle|
|
||||||
refresh_component(:canvas)
|
if ["TARGET", "TARGET_OPP", "TARGET_FRONT", "TARGET_BACK"].include?(particle[:graphic])
|
||||||
|
particle[:graphic] = GameData::Animation::PARTICLE_DEFAULT_VALUES[:graphic]
|
||||||
|
end
|
||||||
|
if GameData::Animation::FOCUS_TYPES_WITH_TARGET.include?(particle[:focus])
|
||||||
|
particle[:focus] = GameData::Animation::PARTICLE_DEFAULT_VALUES[:focus]
|
||||||
|
end
|
||||||
|
particle[:target_cry] = nil if particle[:name] == "SE"
|
||||||
|
end
|
||||||
|
@components[:particle_list].delete_particle(@anim[:no_user] ? 0 : 1)
|
||||||
|
elsif @anim[:particles].none? { |particle| particle[:name] == "Target" }
|
||||||
|
@anim[:particles].insert((@anim[:no_user] ? 0 : 1), {
|
||||||
|
:name => "Target", :focus => :target, :graphic => "TARGET"
|
||||||
|
})
|
||||||
|
@components[:particle_list].add_particle((@anim[:no_user] ? 0 : 1))
|
||||||
|
end
|
||||||
|
@components[:particle_list].set_particles(@anim[:particles])
|
||||||
|
refresh
|
||||||
when :usable
|
when :usable
|
||||||
@anim[:ignore] = !value
|
@anim[:ignore] = !value
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -321,25 +321,25 @@ class AnimationEditor::Canvas < Sprite
|
|||||||
spr.bitmap = @user_bitmap_back
|
spr.bitmap = @user_bitmap_back
|
||||||
when "TARGET"
|
when "TARGET"
|
||||||
if target_idx < 0
|
if target_idx < 0
|
||||||
raise _INTL("Particle {1} was given a graphic of \"TARGET\" but its focus doesn't include a target.",
|
raise _INTL("Particle \"{1}\" was given a graphic of \"TARGET\" but its focus doesn't include a target.",
|
||||||
particle[:name])
|
particle[:name])
|
||||||
end
|
end
|
||||||
spr.bitmap = (target_idx.even?) ? @target_bitmap_back : @target_bitmap_front
|
spr.bitmap = (target_idx.even?) ? @target_bitmap_back : @target_bitmap_front
|
||||||
when "TARGET_OPP"
|
when "TARGET_OPP"
|
||||||
if target_idx < 0
|
if target_idx < 0
|
||||||
raise _INTL("Particle {1} was given a graphic of \"TARGET_OPP\" but its focus doesn't include a target.",
|
raise _INTL("Particle \"{1}\" was given a graphic of \"TARGET_OPP\" but its focus doesn't include a target.",
|
||||||
particle[:name])
|
particle[:name])
|
||||||
end
|
end
|
||||||
spr.bitmap = (target_idx.even?) ? @target_bitmap_front : @target_bitmap_back
|
spr.bitmap = (target_idx.even?) ? @target_bitmap_front : @target_bitmap_back
|
||||||
when "TARGET_FRONT"
|
when "TARGET_FRONT"
|
||||||
if target_idx < 0
|
if target_idx < 0
|
||||||
raise _INTL("Particle {1} was given a graphic of \"TARGET_FRONT\" but its focus doesn't include a target.",
|
raise _INTL("Particle \"{1}\" was given a graphic of \"TARGET_FRONT\" but its focus doesn't include a target.",
|
||||||
particle[:name])
|
particle[:name])
|
||||||
end
|
end
|
||||||
spr.bitmap = @target_bitmap_front
|
spr.bitmap = @target_bitmap_front
|
||||||
when "TARGET_BACK"
|
when "TARGET_BACK"
|
||||||
if target_idx < 0
|
if target_idx < 0
|
||||||
raise _INTL("Particle {1} was given a graphic of \"TARGET_BACK\" but its focus doesn't include a target.",
|
raise _INTL("Particle \"{1}\" was given a graphic of \"TARGET_BACK\" but its focus doesn't include a target.",
|
||||||
particle[:name])
|
particle[:name])
|
||||||
end
|
end
|
||||||
spr.bitmap = @target_bitmap_back
|
spr.bitmap = @target_bitmap_back
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: The Add/Up/Down buttons don't get captured, and don't prevent anything
|
#
|
||||||
# else in this control highlighting when hovered over, and vice versa.
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class AnimationEditor::ParticleList < UIControls::BaseControl
|
class AnimationEditor::ParticleList < UIControls::BaseControl
|
||||||
VIEWPORT_SPACING = 1
|
VIEWPORT_SPACING = 1
|
||||||
@@ -48,66 +47,11 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
|||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
draw_control_background
|
draw_control_background
|
||||||
# Create viewports
|
initialize_viewports
|
||||||
@list_viewport = Viewport.new(
|
initialize_scrollbars
|
||||||
x + LIST_X, y + LIST_Y, LIST_WIDTH, height - LIST_Y - UIControls::Scrollbar::SLIDER_WIDTH - VIEWPORT_SPACING
|
initialize_timeline_bitmaps
|
||||||
)
|
initialize_selection_bitmaps
|
||||||
@list_viewport.z = self.viewport.z + 1
|
initialize_controls
|
||||||
@commands_bg_viewport = Viewport.new(
|
|
||||||
x + COMMANDS_X, y + COMMANDS_Y,
|
|
||||||
width - COMMANDS_X - UIControls::Scrollbar::SLIDER_WIDTH - VIEWPORT_SPACING, @list_viewport.rect.height
|
|
||||||
)
|
|
||||||
@commands_bg_viewport.z = self.viewport.z + 1
|
|
||||||
@position_viewport = Viewport.new(@commands_bg_viewport.rect.x, y, @commands_bg_viewport.rect.width, height)
|
|
||||||
@position_viewport.z = self.viewport.z + 2
|
|
||||||
@commands_viewport = Viewport.new(@commands_bg_viewport.rect.x, @commands_bg_viewport.rect.y,
|
|
||||||
@commands_bg_viewport.rect.width, @commands_bg_viewport.rect.height)
|
|
||||||
@commands_viewport.z = self.viewport.z + 3
|
|
||||||
# Create scrollbars
|
|
||||||
@list_scrollbar = UIControls::Scrollbar.new(
|
|
||||||
x + width - UIControls::Scrollbar::SLIDER_WIDTH, @commands_bg_viewport.rect.y,
|
|
||||||
@commands_bg_viewport.rect.height, self.viewport, false, true
|
|
||||||
)
|
|
||||||
@list_scrollbar.set_interactive_rects
|
|
||||||
@time_scrollbar = UIControls::Scrollbar.new(
|
|
||||||
@commands_bg_viewport.rect.x, y + height - UIControls::Scrollbar::SLIDER_WIDTH,
|
|
||||||
@commands_bg_viewport.rect.width, self.viewport, true, true
|
|
||||||
)
|
|
||||||
@time_scrollbar.set_interactive_rects
|
|
||||||
# Time background bitmap sprite
|
|
||||||
@time_bg_sprite = BitmapSprite.new(
|
|
||||||
@commands_viewport.rect.width,
|
|
||||||
TIMELINE_HEIGHT + VIEWPORT_SPACING + @list_viewport.rect.height, self.viewport
|
|
||||||
)
|
|
||||||
@time_bg_sprite.x = @commands_viewport.rect.x
|
|
||||||
@time_bg_sprite.y = self.y
|
|
||||||
# Timeline bitmap sprite
|
|
||||||
@timeline_sprite = BitmapSprite.new(@commands_viewport.rect.width, TIMELINE_HEIGHT, self.viewport)
|
|
||||||
@timeline_sprite.x = @commands_viewport.rect.x
|
|
||||||
@timeline_sprite.y = self.y
|
|
||||||
@timeline_sprite.bitmap.font.color = TEXT_COLOR
|
|
||||||
@timeline_sprite.bitmap.font.size = TIMELINE_TEXT_SIZE
|
|
||||||
# Position line sprite
|
|
||||||
@position_sprite = BitmapSprite.new(3, height - UIControls::Scrollbar::SLIDER_WIDTH - VIEWPORT_SPACING, @position_viewport)
|
|
||||||
@position_sprite.ox = @position_sprite.width / 2
|
|
||||||
@position_sprite.bitmap.fill_rect(0, 0, @position_sprite.bitmap.width, @position_sprite.bitmap.height, Color.red)
|
|
||||||
# Selected particle line sprite
|
|
||||||
@particle_line_sprite = BitmapSprite.new(@position_viewport.rect.width, 3, @commands_viewport)
|
|
||||||
@particle_line_sprite.z = -10
|
|
||||||
@particle_line_sprite.oy = @particle_line_sprite.height / 2
|
|
||||||
@particle_line_sprite.bitmap.fill_rect(0, 0, @particle_line_sprite.bitmap.width, @particle_line_sprite.bitmap.height, Color.red)
|
|
||||||
# Buttons and button bitmaps
|
|
||||||
initialize_button_bitmaps
|
|
||||||
@controls = []
|
|
||||||
add_particle_button = UIControls::BitmapButton.new(x + 1, y + 1, viewport, @add_button_bitmap)
|
|
||||||
add_particle_button.set_interactive_rects
|
|
||||||
@controls.push([:add_particle, add_particle_button])
|
|
||||||
up_particle_button = UIControls::BitmapButton.new(x + 22, y + 1, viewport, @up_button_bitmap)
|
|
||||||
up_particle_button.set_interactive_rects
|
|
||||||
@controls.push([:move_particle_up, up_particle_button])
|
|
||||||
down_particle_button = UIControls::BitmapButton.new(x + 43, y + 1, viewport, @down_button_bitmap)
|
|
||||||
down_particle_button.set_interactive_rects
|
|
||||||
@controls.push([:move_particle_down, down_particle_button])
|
|
||||||
# List sprites and commands sprites
|
# List sprites and commands sprites
|
||||||
@list_sprites = []
|
@list_sprites = []
|
||||||
@commands_bg_sprites = []
|
@commands_bg_sprites = []
|
||||||
@@ -127,7 +71,81 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
|||||||
@commands = {}
|
@commands = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize_button_bitmaps
|
def initialize_viewports
|
||||||
|
@list_viewport = Viewport.new(
|
||||||
|
x + LIST_X, y + LIST_Y, LIST_WIDTH, height - LIST_Y - UIControls::Scrollbar::SLIDER_WIDTH - VIEWPORT_SPACING
|
||||||
|
)
|
||||||
|
@list_viewport.z = self.viewport.z + 1
|
||||||
|
@commands_bg_viewport = Viewport.new(
|
||||||
|
x + COMMANDS_X, y + COMMANDS_Y,
|
||||||
|
width - COMMANDS_X - UIControls::Scrollbar::SLIDER_WIDTH - VIEWPORT_SPACING, @list_viewport.rect.height
|
||||||
|
)
|
||||||
|
@commands_bg_viewport.z = self.viewport.z + 1
|
||||||
|
@position_viewport = Viewport.new(@commands_bg_viewport.rect.x, y, @commands_bg_viewport.rect.width, height)
|
||||||
|
@position_viewport.z = self.viewport.z + 2
|
||||||
|
@commands_viewport = Viewport.new(@commands_bg_viewport.rect.x, @commands_bg_viewport.rect.y,
|
||||||
|
@commands_bg_viewport.rect.width, @commands_bg_viewport.rect.height)
|
||||||
|
@commands_viewport.z = self.viewport.z + 3
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_scrollbars
|
||||||
|
# Vertical scrollbar
|
||||||
|
@list_scrollbar = UIControls::Scrollbar.new(
|
||||||
|
x + width - UIControls::Scrollbar::SLIDER_WIDTH, @commands_bg_viewport.rect.y,
|
||||||
|
@commands_bg_viewport.rect.height, self.viewport, false, true
|
||||||
|
)
|
||||||
|
@list_scrollbar.set_interactive_rects
|
||||||
|
# Horizontal scrollbar
|
||||||
|
@time_scrollbar = UIControls::Scrollbar.new(
|
||||||
|
@commands_bg_viewport.rect.x, y + height - UIControls::Scrollbar::SLIDER_WIDTH,
|
||||||
|
@commands_bg_viewport.rect.width, self.viewport, true, true
|
||||||
|
)
|
||||||
|
@time_scrollbar.set_interactive_rects
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_timeline_bitmaps
|
||||||
|
# Time background bitmap sprite
|
||||||
|
@time_bg_sprite = BitmapSprite.new(
|
||||||
|
@commands_viewport.rect.width,
|
||||||
|
TIMELINE_HEIGHT + VIEWPORT_SPACING + @list_viewport.rect.height, self.viewport
|
||||||
|
)
|
||||||
|
@time_bg_sprite.x = @commands_viewport.rect.x
|
||||||
|
@time_bg_sprite.y = self.y
|
||||||
|
# Timeline bitmap sprite
|
||||||
|
@timeline_sprite = BitmapSprite.new(@commands_viewport.rect.width, TIMELINE_HEIGHT, self.viewport)
|
||||||
|
@timeline_sprite.x = @commands_viewport.rect.x
|
||||||
|
@timeline_sprite.y = self.y
|
||||||
|
@timeline_sprite.bitmap.font.color = TEXT_COLOR
|
||||||
|
@timeline_sprite.bitmap.font.size = TIMELINE_TEXT_SIZE
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_selection_bitmaps
|
||||||
|
# Position line sprite
|
||||||
|
@position_sprite = BitmapSprite.new(3, height - UIControls::Scrollbar::SLIDER_WIDTH - VIEWPORT_SPACING, @position_viewport)
|
||||||
|
@position_sprite.ox = @position_sprite.width / 2
|
||||||
|
@position_sprite.bitmap.fill_rect(0, 0, @position_sprite.bitmap.width, @position_sprite.bitmap.height, Color.red)
|
||||||
|
# Selected particle line sprite
|
||||||
|
@particle_line_sprite = BitmapSprite.new(@position_viewport.rect.width, 3, @commands_viewport)
|
||||||
|
@particle_line_sprite.z = -10
|
||||||
|
@particle_line_sprite.oy = @particle_line_sprite.height / 2
|
||||||
|
@particle_line_sprite.bitmap.fill_rect(0, 0, @particle_line_sprite.bitmap.width, @particle_line_sprite.bitmap.height, Color.red)
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_controls
|
||||||
|
generate_button_bitmaps
|
||||||
|
@controls = []
|
||||||
|
add_particle_button = UIControls::BitmapButton.new(x + 1, y + 1, viewport, @add_button_bitmap)
|
||||||
|
add_particle_button.set_interactive_rects
|
||||||
|
@controls.push([:add_particle, add_particle_button])
|
||||||
|
up_particle_button = UIControls::BitmapButton.new(x + 22, y + 1, viewport, @up_button_bitmap)
|
||||||
|
up_particle_button.set_interactive_rects
|
||||||
|
@controls.push([:move_particle_up, up_particle_button])
|
||||||
|
down_particle_button = UIControls::BitmapButton.new(x + 43, y + 1, viewport, @down_button_bitmap)
|
||||||
|
down_particle_button.set_interactive_rects
|
||||||
|
@controls.push([:move_particle_down, down_particle_button])
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_button_bitmaps
|
||||||
@add_button_bitmap = Bitmap.new(12, 12)
|
@add_button_bitmap = Bitmap.new(12, 12)
|
||||||
@add_button_bitmap.fill_rect(1, 5, 10, 2, TEXT_COLOR)
|
@add_button_bitmap.fill_rect(1, 5, 10, 2, TEXT_COLOR)
|
||||||
@add_button_bitmap.fill_rect(5, 1, 2, 10, TEXT_COLOR)
|
@add_button_bitmap.fill_rect(5, 1, 2, 10, TEXT_COLOR)
|
||||||
@@ -143,24 +161,6 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw_control_background
|
|
||||||
self.bitmap.clear
|
|
||||||
# Separator lines
|
|
||||||
self.bitmap.fill_rect(0, TIMELINE_HEIGHT, width, VIEWPORT_SPACING, Color.black)
|
|
||||||
self.bitmap.fill_rect(LIST_WIDTH, 0, VIEWPORT_SPACING, height, Color.black)
|
|
||||||
self.bitmap.fill_rect(0, height - UIControls::Scrollbar::SLIDER_WIDTH - VIEWPORT_SPACING, width, VIEWPORT_SPACING, Color.black)
|
|
||||||
self.bitmap.fill_rect(width - UIControls::Scrollbar::SLIDER_WIDTH - VIEWPORT_SPACING, 0, VIEWPORT_SPACING, height, Color.black)
|
|
||||||
end
|
|
||||||
|
|
||||||
def dispose_listed_sprites
|
|
||||||
@list_sprites.each { |p| p&.dispose }
|
|
||||||
@list_sprites.clear
|
|
||||||
@commands_bg_sprites.each { |p| p&.dispose }
|
|
||||||
@commands_bg_sprites.clear
|
|
||||||
@commands_sprites.each { |p| p&.dispose }
|
|
||||||
@commands_sprites.clear
|
|
||||||
end
|
|
||||||
|
|
||||||
def dispose
|
def dispose
|
||||||
@list_scrollbar.dispose
|
@list_scrollbar.dispose
|
||||||
@time_scrollbar.dispose
|
@time_scrollbar.dispose
|
||||||
@@ -179,6 +179,17 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
|||||||
@commands_viewport.dispose
|
@commands_viewport.dispose
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def dispose_listed_sprites
|
||||||
|
@list_sprites.each { |p| p&.dispose }
|
||||||
|
@list_sprites.clear
|
||||||
|
@commands_bg_sprites.each { |p| p&.dispose }
|
||||||
|
@commands_bg_sprites.clear
|
||||||
|
@commands_sprites.each { |p| p&.dispose }
|
||||||
|
@commands_sprites.clear
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
def duration
|
def duration
|
||||||
return [@duration - DURATION_BUFFER, 0].max
|
return [@duration - DURATION_BUFFER, 0].max
|
||||||
end
|
end
|
||||||
@@ -236,6 +247,71 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def scroll_to_row(new_row)
|
||||||
|
if new_row * ROW_HEIGHT < @top_pos
|
||||||
|
# Scroll up
|
||||||
|
new_pos = new_row * ROW_HEIGHT
|
||||||
|
loop do
|
||||||
|
@list_scrollbar.slider_top -= 1
|
||||||
|
break if @list_scrollbar.position <= new_pos || @list_scrollbar.minimum?
|
||||||
|
end
|
||||||
|
elsif new_row * ROW_HEIGHT > @top_pos + @list_viewport.rect.height - ROW_HEIGHT
|
||||||
|
# Scroll down
|
||||||
|
new_pos = (new_row * ROW_HEIGHT) - @list_viewport.rect.height + ROW_HEIGHT
|
||||||
|
loop do
|
||||||
|
@list_scrollbar.slider_top += 1
|
||||||
|
break if @list_scrollbar.position >= new_pos || @list_scrollbar.maximum?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def scroll_to_keyframe(new_keyframe)
|
||||||
|
if TIMELINE_LEFT_BUFFER + (new_keyframe * KEYFRAME_SPACING) - (KEYFRAME_SPACING / 2) < @left_pos
|
||||||
|
# Scroll left
|
||||||
|
new_pos = TIMELINE_LEFT_BUFFER + (new_keyframe * KEYFRAME_SPACING) - (KEYFRAME_SPACING / 2)
|
||||||
|
loop do
|
||||||
|
@time_scrollbar.slider_top -= 1
|
||||||
|
break if @time_scrollbar.position <= new_pos || @time_scrollbar.minimum?
|
||||||
|
end
|
||||||
|
elsif TIMELINE_LEFT_BUFFER + (new_keyframe * KEYFRAME_SPACING) + (KEYFRAME_SPACING / 2) > @left_pos + @commands_bg_viewport.rect.width
|
||||||
|
# Scroll right
|
||||||
|
new_pos = TIMELINE_LEFT_BUFFER + (new_keyframe * KEYFRAME_SPACING) + (KEYFRAME_SPACING / 2) - @commands_bg_viewport.rect.width
|
||||||
|
loop do
|
||||||
|
@time_scrollbar.slider_top += 1
|
||||||
|
break if @time_scrollbar.position >= new_pos || @time_scrollbar.maximum?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Ensures that the array of which particle rows have been expanded ends up
|
||||||
|
# with the same particles having expanded rows after adding a particle.
|
||||||
|
def add_particle(index)
|
||||||
|
@expanded_particles.each_with_index do |idx, i|
|
||||||
|
@expanded_particles[i] += 1 if idx >= index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Ensures that the array of which particle rows have been expanded ends up
|
||||||
|
# with the same particles having expanded rows after deleting a particle.
|
||||||
|
def delete_particle(index)
|
||||||
|
@expanded_particles.delete(index)
|
||||||
|
@expanded_particles.each_with_index do |idx, i|
|
||||||
|
@expanded_particles[i] -= 1 if idx > index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Ensures that the array of which particle rows have been expanded ends up
|
||||||
|
# with the same particles having expanded rows after the swap.
|
||||||
|
def swap_particles(idx1, idx2)
|
||||||
|
if @expanded_particles.include?(idx1) && !@expanded_particles.include?(idx2)
|
||||||
|
@expanded_particles.delete(idx1)
|
||||||
|
@expanded_particles.push(idx2)
|
||||||
|
elsif @expanded_particles.include?(idx2) && !@expanded_particles.include?(idx1)
|
||||||
|
@expanded_particles.delete(idx2)
|
||||||
|
@expanded_particles.push(idx1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def set_particles(particles)
|
def set_particles(particles)
|
||||||
@particles = particles
|
@particles = particles
|
||||||
calculate_all_commands_and_durations
|
calculate_all_commands_and_durations
|
||||||
@@ -449,9 +525,6 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
|||||||
invalidate_rows
|
invalidate_rows
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: Methods that will show/hide individual property rows for a given
|
|
||||||
# @particles index.
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
def each_visible_keyframe(early_start = false)
|
def each_visible_keyframe(early_start = false)
|
||||||
@@ -478,6 +551,17 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
|||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def draw_control_background
|
||||||
|
self.bitmap.clear
|
||||||
|
# Separator lines
|
||||||
|
self.bitmap.fill_rect(0, TIMELINE_HEIGHT, width, VIEWPORT_SPACING, Color.black)
|
||||||
|
self.bitmap.fill_rect(LIST_WIDTH, 0, VIEWPORT_SPACING, height, Color.black)
|
||||||
|
self.bitmap.fill_rect(0, height - UIControls::Scrollbar::SLIDER_WIDTH - VIEWPORT_SPACING, width, VIEWPORT_SPACING, Color.black)
|
||||||
|
self.bitmap.fill_rect(width - UIControls::Scrollbar::SLIDER_WIDTH - VIEWPORT_SPACING, 0, VIEWPORT_SPACING, height, Color.black)
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
def repaint
|
def repaint
|
||||||
@list_scrollbar.repaint if @list_scrollbar.invalid?
|
@list_scrollbar.repaint if @list_scrollbar.invalid?
|
||||||
@time_scrollbar.repaint if @time_scrollbar.invalid?
|
@time_scrollbar.repaint if @time_scrollbar.invalid?
|
||||||
@@ -850,14 +934,16 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
|||||||
else
|
else
|
||||||
case @captured_row_button
|
case @captured_row_button
|
||||||
when :expand
|
when :expand
|
||||||
particle_index = @particle_list[@captured_row]
|
old_row_idx_particle = @particle_list[@row_index]
|
||||||
particle_index = particle_index[0] if particle_index.is_a?(Array)
|
idx_particle = @particle_list[@captured_row]
|
||||||
if @expanded_particles.include?(particle_index) # Contract
|
idx_particle = idx_particle[0] if idx_particle.is_a?(Array)
|
||||||
@expanded_particles.delete(particle_index)
|
if @expanded_particles.include?(idx_particle) # Contract
|
||||||
else # Expand
|
@expanded_particles.delete(idx_particle)
|
||||||
@expanded_particles.push(particle_index)
|
else # Expand
|
||||||
|
@expanded_particles.push(idx_particle)
|
||||||
end
|
end
|
||||||
set_particles(@particles)
|
set_particles(@particles)
|
||||||
|
@row_index = @particle_list.index(old_row_idx_particle)
|
||||||
else # :row button or somewhere in the commands area or timeline, just change selection
|
else # :row button or somewhere in the commands area or timeline, just change selection
|
||||||
if @captured_row && @particle_list[@captured_row].is_a?(Array)
|
if @captured_row && @particle_list[@captured_row].is_a?(Array)
|
||||||
@captured_row = @particle_list.index(@particle_list[@captured_row][0])
|
@captured_row = @particle_list.index(@particle_list[@captured_row][0])
|
||||||
@@ -877,11 +963,6 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
|||||||
super # Make this control not busy again
|
super # Make this control not busy again
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_right_mouse_release
|
|
||||||
# TODO: Toggle interpolation line at mouse's position. Should this also have
|
|
||||||
# a def on_right_mouse_press and @right_captured_whatever?
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_hover_highlight
|
def update_hover_highlight
|
||||||
# Remove the hover highlight if there are no interactions for this control
|
# Remove the hover highlight if there are no interactions for this control
|
||||||
# or if the mouse is off-screen
|
# or if the mouse is off-screen
|
||||||
@@ -938,6 +1019,59 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_input
|
||||||
|
# Left/right to change current keyframe
|
||||||
|
if Input.repeat?(Input::LEFT)
|
||||||
|
if @keyframe > 0
|
||||||
|
@keyframe -= 1
|
||||||
|
scroll_to_keyframe(@keyframe)
|
||||||
|
set_changed
|
||||||
|
end
|
||||||
|
elsif Input.repeat?(Input::RIGHT)
|
||||||
|
if @keyframe < @duration - 1
|
||||||
|
@keyframe += 1
|
||||||
|
scroll_to_keyframe(@keyframe)
|
||||||
|
set_changed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Up/down to change selected particle
|
||||||
|
if Input.repeat?(Input::UP)
|
||||||
|
if @row_index > 0
|
||||||
|
loop do
|
||||||
|
@row_index -= 1
|
||||||
|
break if !@particle_list[@row_index].is_a?(Array)
|
||||||
|
end
|
||||||
|
scroll_to_row(@row_index)
|
||||||
|
set_changed
|
||||||
|
end
|
||||||
|
elsif Input.repeat?(Input::DOWN)
|
||||||
|
if @row_index < @particle_list.length - 1
|
||||||
|
loop do
|
||||||
|
@row_index += 1
|
||||||
|
break if !@particle_list[@row_index].is_a?(Array)
|
||||||
|
end
|
||||||
|
@keyframe = 0 if @row_index >= @particle_list.length - 1 && @keyframe < 0
|
||||||
|
scroll_to_row(@row_index)
|
||||||
|
set_changed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Mouse scroll wheel
|
||||||
|
mouse_x, mouse_y = mouse_pos
|
||||||
|
if mouse_x && mouse_y
|
||||||
|
if @interactions[:list].contains?(mouse_x, mouse_y) ||
|
||||||
|
@interactions[:commands].contains?(mouse_x, mouse_y)
|
||||||
|
wheel_v = Input.scroll_v
|
||||||
|
if wheel_v > 0 # Scroll up
|
||||||
|
@list_scrollbar.slider_top -= UIControls::Scrollbar::SCROLL_DISTANCE
|
||||||
|
self.top_pos = @list_scrollbar.position
|
||||||
|
elsif wheel_v < 0 # Scroll down
|
||||||
|
@list_scrollbar.slider_top += UIControls::Scrollbar::SCROLL_DISTANCE
|
||||||
|
self.top_pos = @list_scrollbar.position
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
return if !self.visible
|
return if !self.visible
|
||||||
@list_scrollbar.update
|
@list_scrollbar.update
|
||||||
@@ -949,9 +1083,8 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
|||||||
# Refresh sprites if a scrollbar has been moved
|
# Refresh sprites if a scrollbar has been moved
|
||||||
self.top_pos = @list_scrollbar.position
|
self.top_pos = @list_scrollbar.position
|
||||||
self.left_pos = @time_scrollbar.position
|
self.left_pos = @time_scrollbar.position
|
||||||
# Update the current keyframe line's position
|
# Update the positions of the selected particle/keyframe lines
|
||||||
refresh_position_line
|
refresh_position_line
|
||||||
# Update the selected particle line's position
|
|
||||||
refresh_particle_line
|
refresh_particle_line
|
||||||
# Add/move particle buttons
|
# Add/move particle buttons
|
||||||
@controls.each do |c|
|
@controls.each do |c|
|
||||||
@@ -960,55 +1093,7 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
|||||||
@values[c[0]] = true
|
@values[c[0]] = true
|
||||||
c[1].clear_changed
|
c[1].clear_changed
|
||||||
end
|
end
|
||||||
|
# Up/down/left/right navigation, and mouse scroll wheel
|
||||||
if Input.release?(Input::MOUSERIGHT)
|
update_input
|
||||||
on_right_mouse_release
|
|
||||||
end
|
|
||||||
|
|
||||||
# TODO: This is testing code, and should be replaced by clicking on the
|
|
||||||
# timeline or a command sprite. Maybe keep it after all? If so,
|
|
||||||
# probably change left/right to <>, and also move the scrollbar(s) to
|
|
||||||
# keep the "cursor" on-screen.
|
|
||||||
if Input.repeat?(Input::LEFT)
|
|
||||||
if @keyframe > 0
|
|
||||||
@keyframe -= 1
|
|
||||||
set_changed
|
|
||||||
end
|
|
||||||
elsif Input.repeat?(Input::RIGHT)
|
|
||||||
if @keyframe < @duration - 1
|
|
||||||
@keyframe += 1
|
|
||||||
set_changed
|
|
||||||
end
|
|
||||||
# TODO: If this is to be kept, @row_index should be changed by potentially
|
|
||||||
# more than 1, so that @particle_list[@row_index] is an integer and
|
|
||||||
# not an array.
|
|
||||||
# elsif Input.repeat?(Input::UP)
|
|
||||||
# if @row_index > 0
|
|
||||||
# @row_index -= 1
|
|
||||||
# set_changed
|
|
||||||
# end
|
|
||||||
# elsif Input.repeat?(Input::DOWN)
|
|
||||||
# if @row_index < @particles.length - 1
|
|
||||||
# @row_index += 1
|
|
||||||
# set_changed
|
|
||||||
# end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Mouse scroll wheel
|
|
||||||
mouse_x, mouse_y = mouse_pos
|
|
||||||
if mouse_x && mouse_y
|
|
||||||
if @interactions[:list].contains?(mouse_x, mouse_y) ||
|
|
||||||
@interactions[:commands].contains?(mouse_x, mouse_y)
|
|
||||||
wheel_v = Input.scroll_v
|
|
||||||
if wheel_v > 0 # Scroll up
|
|
||||||
@list_scrollbar.slider_top -= UIControls::Scrollbar::SCROLL_DISTANCE
|
|
||||||
self.top_pos = @list_scrollbar.position
|
|
||||||
elsif wheel_v < 0 # Scroll down
|
|
||||||
@list_scrollbar.slider_top += UIControls::Scrollbar::SCROLL_DISTANCE
|
|
||||||
self.top_pos = @list_scrollbar.position
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -236,7 +236,6 @@ Name = ABSORB
|
|||||||
SetY = 12,-50
|
SetY = 12,-50
|
||||||
SetVisible = 13,false
|
SetVisible = 13,false
|
||||||
<SE>
|
<SE>
|
||||||
Play = 0,Absorb2,80
|
|
||||||
Play = 0,Absorb2,80
|
Play = 0,Absorb2,80
|
||||||
Play = 2,Absorb2,80
|
Play = 2,Absorb2,80
|
||||||
Play = 5,Absorb2,80
|
Play = 5,Absorb2,80
|
||||||
|
|||||||
@@ -166,5 +166,4 @@ Name = MAGICCOAT
|
|||||||
SetVisible = 9,false
|
SetVisible = 9,false
|
||||||
<SE>
|
<SE>
|
||||||
Play = 0,Sword2,80
|
Play = 0,Sword2,80
|
||||||
Play = 0,Sword2,80,101
|
|
||||||
Play = 4,Sword2,80
|
Play = 4,Sword2,80
|
||||||
|
|||||||
Reference in New Issue
Block a user