mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
Anim Editor: added FoeFlip property, Space to play, S to swap sides, P to show/hide property lines for selected particle
This commit is contained in:
@@ -24,6 +24,8 @@ class UIControls::BaseControl < BitmapSprite
|
||||
invalidate
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def width
|
||||
return self.bitmap.width
|
||||
end
|
||||
@@ -32,6 +34,8 @@ class UIControls::BaseControl < BitmapSprite
|
||||
return self.bitmap.height
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def mouse_pos
|
||||
mouse_coords = Mouse.getMousePos
|
||||
return nil, nil if !mouse_coords
|
||||
@@ -40,10 +44,6 @@ class UIControls::BaseControl < BitmapSprite
|
||||
return ret_x, ret_y
|
||||
end
|
||||
|
||||
def set_interactive_rects
|
||||
@interactions = {}
|
||||
end
|
||||
|
||||
def mouse_in_control?
|
||||
return false if !@interactions || @interactions.empty?
|
||||
mouse_x, mouse_y = mouse_pos
|
||||
@@ -51,8 +51,6 @@ class UIControls::BaseControl < BitmapSprite
|
||||
return @interactions.any? { |area, rect| rect.contains?(mouse_x, mouse_y) }
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def disabled?
|
||||
return @disabled
|
||||
end
|
||||
@@ -102,6 +100,12 @@ class UIControls::BaseControl < BitmapSprite
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def set_interactive_rects
|
||||
@interactions = {}
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def draw_text(this_bitmap, text_x, text_y, this_text)
|
||||
text_size = this_bitmap.text_size(this_text)
|
||||
this_bitmap.draw_text(text_x, text_y, text_size.width, text_size.height, this_text, 0)
|
||||
|
||||
@@ -10,6 +10,8 @@ class UIControls::Label < UIControls::BaseControl
|
||||
@header = false
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def text=(value)
|
||||
@text = value
|
||||
refresh
|
||||
@@ -24,6 +26,8 @@ class UIControls::Label < UIControls::BaseControl
|
||||
return self.bitmap.text_size(@text).width
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def refresh
|
||||
super
|
||||
if @header
|
||||
|
||||
@@ -6,7 +6,6 @@ class UIControls::Checkbox < UIControls::BaseControl
|
||||
CHECKBOX_WIDTH = 40
|
||||
CHECKBOX_HEIGHT = 24
|
||||
CHECKBOX_FILL_SIZE = CHECKBOX_HEIGHT - 4
|
||||
|
||||
UNCHECKED_COLOR = Color.gray
|
||||
CHECKED_COLOR = Color.new(48, 192, 48) # Darkish green
|
||||
|
||||
@@ -15,12 +14,16 @@ class UIControls::Checkbox < UIControls::BaseControl
|
||||
@value = value
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def value=(new_value)
|
||||
return if @value == new_value
|
||||
@value = new_value
|
||||
invalidate
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def set_interactive_rects
|
||||
@checkbox_rect = Rect.new(CHECKBOX_X, (height - CHECKBOX_HEIGHT) / 2,
|
||||
CHECKBOX_WIDTH, CHECKBOX_HEIGHT)
|
||||
|
||||
@@ -20,6 +20,8 @@ class UIControls::TextBox < UIControls::BaseControl
|
||||
@blacklist = []
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def value
|
||||
return @value.dup
|
||||
end
|
||||
@@ -60,36 +62,6 @@ class UIControls::TextBox < UIControls::BaseControl
|
||||
invalidate
|
||||
end
|
||||
|
||||
def set_interactive_rects
|
||||
@text_box_rect = Rect.new(TEXT_BOX_X, (height - TEXT_BOX_HEIGHT) / 2,
|
||||
[@box_width, width - (TEXT_BOX_X * 2)].min, TEXT_BOX_HEIGHT)
|
||||
@interactions = {
|
||||
:text_box => @text_box_rect
|
||||
}
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def disabled?
|
||||
val = (@value.respond_to?("strip!")) ? @value.strip : @value
|
||||
return true if @blacklist.include?(val)
|
||||
return super
|
||||
end
|
||||
|
||||
def busy?
|
||||
return @cursor_pos >= 0 if @captured_area == :text_box
|
||||
return super
|
||||
end
|
||||
|
||||
def reset_interaction
|
||||
@cursor_pos = -1
|
||||
@display_pos = 0
|
||||
@cursor_timer = nil
|
||||
@initial_value = nil
|
||||
Input.text_input = false
|
||||
invalidate
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def get_cursor_index_from_mouse_position
|
||||
@@ -107,6 +79,36 @@ class UIControls::TextBox < UIControls::BaseControl
|
||||
return @value.to_s.length
|
||||
end
|
||||
|
||||
def disabled?
|
||||
val = (@value.respond_to?("strip!")) ? @value.strip : @value
|
||||
return true if @blacklist.include?(val)
|
||||
return super
|
||||
end
|
||||
|
||||
def busy?
|
||||
return @cursor_pos >= 0 if @captured_area == :text_box
|
||||
return super
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def set_interactive_rects
|
||||
@text_box_rect = Rect.new(TEXT_BOX_X, (height - TEXT_BOX_HEIGHT) / 2,
|
||||
[@box_width, width - (TEXT_BOX_X * 2)].min, TEXT_BOX_HEIGHT)
|
||||
@interactions = {
|
||||
:text_box => @text_box_rect
|
||||
}
|
||||
end
|
||||
|
||||
def reset_interaction
|
||||
@cursor_pos = -1
|
||||
@display_pos = 0
|
||||
@cursor_timer = nil
|
||||
@initial_value = nil
|
||||
Input.text_input = false
|
||||
invalidate
|
||||
end
|
||||
|
||||
def reset_display_pos
|
||||
box_width = @text_box_rect.width - (TEXT_BOX_PADDING * 2)
|
||||
char_widths = []
|
||||
|
||||
@@ -7,7 +7,6 @@ class UIControls::NumberSlider < UIControls::BaseControl
|
||||
|
||||
PLUS_MINUS_SIZE = 16
|
||||
SLIDER_PADDING = 6 # Gap between sides of interactive area for slider and drawn slider bar
|
||||
|
||||
MINUS_X = 0
|
||||
SLIDER_X = MINUS_X + PLUS_MINUS_SIZE + SLIDER_PADDING
|
||||
SLIDER_LENGTH = 128
|
||||
@@ -21,6 +20,8 @@ class UIControls::NumberSlider < UIControls::BaseControl
|
||||
self.value = value
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def value=(new_value)
|
||||
old_val = @value
|
||||
@value = new_value.to_i.clamp(self.min_value, self.max_value)
|
||||
@@ -41,6 +42,8 @@ class UIControls::NumberSlider < UIControls::BaseControl
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def set_interactive_rects
|
||||
@slider_rect = Rect.new(SLIDER_X - SLIDER_PADDING, (self.height - PLUS_MINUS_SIZE) / 2, SLIDER_LENGTH + (SLIDER_PADDING * 2), PLUS_MINUS_SIZE)
|
||||
@minus_rect = Rect.new(MINUS_X, (self.height - PLUS_MINUS_SIZE) / 2, PLUS_MINUS_SIZE, PLUS_MINUS_SIZE)
|
||||
|
||||
@@ -7,7 +7,6 @@ class UIControls::NumberTextBox < UIControls::TextBox
|
||||
|
||||
PLUS_MINUS_SIZE = 16
|
||||
CONTROL_PADDING = 2 # Gap between buttons and text box
|
||||
|
||||
MINUS_X = 0
|
||||
TEXT_BOX_X = MINUS_X + PLUS_MINUS_SIZE + CONTROL_PADDING
|
||||
TEXT_BOX_WIDTH = 64
|
||||
@@ -21,6 +20,8 @@ class UIControls::NumberTextBox < UIControls::TextBox
|
||||
self.value = value
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def value=(new_value)
|
||||
old_val = @value.to_i
|
||||
@value = new_value.to_i.clamp(self.min_value, self.max_value)
|
||||
@@ -49,6 +50,8 @@ class UIControls::NumberTextBox < UIControls::TextBox
|
||||
invalidate
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def set_interactive_rects
|
||||
@text_box_rect = Rect.new(TEXT_BOX_X, (height - TEXT_BOX_HEIGHT) / 2,
|
||||
TEXT_BOX_WIDTH, TEXT_BOX_HEIGHT)
|
||||
@@ -61,8 +64,6 @@ class UIControls::NumberTextBox < UIControls::TextBox
|
||||
}
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def reset_interaction
|
||||
super
|
||||
self.value = @value # Turn value back into a number and clamp it
|
||||
|
||||
@@ -16,21 +16,12 @@ class UIControls::Button < UIControls::BaseControl
|
||||
@highlight = false
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def set_fixed_size
|
||||
@fixed_size = true
|
||||
end
|
||||
|
||||
def set_interactive_rects
|
||||
@interactions&.clear
|
||||
button_width = (@fixed_size) ? width - (BUTTON_X * 2) : self.bitmap.text_size(@text).width + (BUTTON_PADDING * 2)
|
||||
button_height = (@fixed_size) ? height - (2 * BUTTON_Y) : BUTTON_HEIGHT
|
||||
button_height = [button_height, height - (2 * BUTTON_Y)].min
|
||||
@button_rect = Rect.new(BUTTON_X, (height - button_height) / 2, button_width, button_height)
|
||||
@interactions = {
|
||||
:button => @button_rect
|
||||
}
|
||||
end
|
||||
|
||||
def set_text(val)
|
||||
return if @text == val
|
||||
@text = val
|
||||
@@ -38,6 +29,8 @@ class UIControls::Button < UIControls::BaseControl
|
||||
invalidate
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def disabled?
|
||||
return highlighted? || super
|
||||
end
|
||||
@@ -70,6 +63,19 @@ class UIControls::Button < UIControls::BaseControl
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def set_interactive_rects
|
||||
@interactions&.clear
|
||||
button_width = (@fixed_size) ? width - (BUTTON_X * 2) : self.bitmap.text_size(@text).width + (BUTTON_PADDING * 2)
|
||||
button_height = (@fixed_size) ? height - (2 * BUTTON_Y) : BUTTON_HEIGHT
|
||||
button_height = [button_height, height - (2 * BUTTON_Y)].min
|
||||
@button_rect = Rect.new(BUTTON_X, (height - button_height) / 2, button_width, button_height)
|
||||
@interactions = {
|
||||
:button => @button_rect
|
||||
}
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def refresh
|
||||
super
|
||||
if highlighted?
|
||||
|
||||
@@ -12,6 +12,8 @@ class UIControls::BitmapButton < UIControls::Button
|
||||
@disabled_bitmap = disabled_bitmap
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def set_interactive_rects
|
||||
@interactions&.clear
|
||||
@button_rect = Rect.new(0, 0, width, height)
|
||||
|
||||
@@ -6,7 +6,6 @@ class UIControls::List < UIControls::BaseControl
|
||||
ROW_HEIGHT = 24
|
||||
TEXT_PADDING_X = 4
|
||||
TEXT_OFFSET_Y = 3
|
||||
|
||||
SELECTED_ROW_COLOR = Color.new(216, 192, 32) # Dark yellow
|
||||
|
||||
def initialize(width, height, viewport, values = [])
|
||||
@@ -30,6 +29,8 @@ class UIControls::List < UIControls::BaseControl
|
||||
super
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def x=(new_val)
|
||||
super(new_val)
|
||||
@scrollbar.x = new_val + width - UIControls::Scrollbar::SLIDER_WIDTH - BORDER_THICKNESS
|
||||
@@ -64,6 +65,17 @@ class UIControls::List < UIControls::BaseControl
|
||||
invalidate
|
||||
end
|
||||
|
||||
# Returns the ID of the selected row.
|
||||
def value
|
||||
return nil if @selected < 0
|
||||
if @values.is_a?(Array)
|
||||
return (@values[@selected].is_a?(Array)) ? @values[@selected][0] : @selected
|
||||
elsif @values.is_a?(Hash)
|
||||
return @values.keys[@selected]
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
def top_row=(val)
|
||||
old_val = @top_row
|
||||
@top_row = val
|
||||
@@ -81,16 +93,7 @@ class UIControls::List < UIControls::BaseControl
|
||||
invalidate
|
||||
end
|
||||
|
||||
# Returns the ID of the selected row.
|
||||
def value
|
||||
return nil if @selected < 0
|
||||
if @values.is_a?(Array)
|
||||
return (@values[@selected].is_a?(Array)) ? @values[@selected][0] : @selected
|
||||
elsif @values.is_a?(Hash)
|
||||
return @values.keys[@selected]
|
||||
end
|
||||
return nil
|
||||
end
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def mouse_in_control?
|
||||
mouse_x, mouse_y = mouse_pos
|
||||
@@ -100,6 +103,12 @@ class UIControls::List < UIControls::BaseControl
|
||||
return false
|
||||
end
|
||||
|
||||
def busy?
|
||||
return !@captured_area.nil?
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def set_interactive_rects
|
||||
@interactions = {}
|
||||
@values.length.times do |i|
|
||||
@@ -112,12 +121,6 @@ class UIControls::List < UIControls::BaseControl
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def busy?
|
||||
return !@captured_area.nil?
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def draw_area_highlight
|
||||
# If a row is captured, it will automatically be selected and the selection
|
||||
# colour will be drawn over the highlight. There's no point drawing a
|
||||
|
||||
@@ -26,23 +26,17 @@ class UIControls::DropdownList < UIControls::BaseControl
|
||||
super
|
||||
end
|
||||
|
||||
def value=(new_value)
|
||||
return if @value == new_value
|
||||
@value = new_value
|
||||
invalidate
|
||||
end
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def values=(new_vals)
|
||||
@options = new_vals
|
||||
@dropdown_menu.values = @options if @dropdown_menu
|
||||
end
|
||||
|
||||
def set_interactive_rects
|
||||
@button_rect = Rect.new(TEXT_BOX_X, (height - TEXT_BOX_HEIGHT) / 2,
|
||||
[@box_width, width - (TEXT_BOX_X * 2)].min, TEXT_BOX_HEIGHT)
|
||||
@interactions = {
|
||||
:button => @button_rect
|
||||
}
|
||||
def value=(new_value)
|
||||
return if @value == new_value
|
||||
@value = new_value
|
||||
invalidate
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
@@ -54,6 +48,14 @@ class UIControls::DropdownList < UIControls::BaseControl
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def set_interactive_rects
|
||||
@button_rect = Rect.new(TEXT_BOX_X, (height - TEXT_BOX_HEIGHT) / 2,
|
||||
[@box_width, width - (TEXT_BOX_X * 2)].min, TEXT_BOX_HEIGHT)
|
||||
@interactions = {
|
||||
:button => @button_rect
|
||||
}
|
||||
end
|
||||
|
||||
def make_dropdown_menu
|
||||
menu_height = (UIControls::List::ROW_HEIGHT * [@options.length, @max_rows].min) + (UIControls::List::BORDER_THICKNESS * 2)
|
||||
# Draw menu's background
|
||||
|
||||
@@ -26,21 +26,13 @@ class UIControls::TextBoxDropdownList < UIControls::TextBox
|
||||
super
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def values=(new_vals)
|
||||
@options = new_vals
|
||||
@dropdown_menu.values = @options if @dropdown_menu
|
||||
end
|
||||
|
||||
def set_interactive_rects
|
||||
@text_box_rect = Rect.new(TEXT_BOX_X, (height - TEXT_BOX_HEIGHT) / 2,
|
||||
[@box_width, width - (TEXT_BOX_X * 2) - BUTTON_WIDTH].min, TEXT_BOX_HEIGHT)
|
||||
@button_rect = Rect.new(BUTTON_X, @text_box_rect.y, BUTTON_WIDTH, BUTTON_HEIGHT)
|
||||
@interactions = {
|
||||
:text_box => @text_box_rect,
|
||||
:button => @button_rect
|
||||
}
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def busy?
|
||||
@@ -50,6 +42,16 @@ class UIControls::TextBoxDropdownList < UIControls::TextBox
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def set_interactive_rects
|
||||
@text_box_rect = Rect.new(TEXT_BOX_X, (height - TEXT_BOX_HEIGHT) / 2,
|
||||
[@box_width, width - (TEXT_BOX_X * 2) - BUTTON_WIDTH].min, TEXT_BOX_HEIGHT)
|
||||
@button_rect = Rect.new(BUTTON_X, @text_box_rect.y, BUTTON_WIDTH, BUTTON_HEIGHT)
|
||||
@interactions = {
|
||||
:text_box => @text_box_rect,
|
||||
:button => @button_rect
|
||||
}
|
||||
end
|
||||
|
||||
def make_dropdown_menu
|
||||
menu_height = (UIControls::List::ROW_HEIGHT * [@options.length, @max_rows].min) + (UIControls::List::BORDER_THICKNESS * 2)
|
||||
# Draw menu's background
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#
|
||||
#===============================================================================
|
||||
class UIControls::Scrollbar < UIControls::BaseControl
|
||||
attr_reader :slider_top
|
||||
|
||||
SLIDER_WIDTH = 16
|
||||
WIDTH_PADDING = 0
|
||||
SCROLL_DISTANCE = 16
|
||||
@@ -9,8 +11,6 @@ class UIControls::Scrollbar < UIControls::BaseControl
|
||||
SLIDER_COLOR = Color.black
|
||||
GRAB_COLOR = HOVER_COLOR # Cyan
|
||||
|
||||
attr_reader :slider_top
|
||||
|
||||
def initialize(x, y, size, viewport, horizontal = false, always_visible = false)
|
||||
if horizontal
|
||||
super(size, SLIDER_WIDTH, viewport)
|
||||
@@ -28,18 +28,7 @@ class UIControls::Scrollbar < UIControls::BaseControl
|
||||
self.visible = @always_visible
|
||||
end
|
||||
|
||||
def position
|
||||
return 0 if @range <= @tray_size
|
||||
return (@range - @tray_size) * @slider_top / (@tray_size - @slider_size)
|
||||
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
|
||||
# show part of.
|
||||
@@ -68,6 +57,21 @@ class UIControls::Scrollbar < UIControls::BaseControl
|
||||
invalidate if @slider_top != old_val
|
||||
end
|
||||
|
||||
def position
|
||||
return 0 if @range <= @tray_size
|
||||
return (@range - @tray_size) * @slider_top / (@tray_size - @slider_size)
|
||||
end
|
||||
|
||||
def minimum?
|
||||
return @slider_top <= 0
|
||||
end
|
||||
|
||||
def maximum?
|
||||
return @slider_top >= @tray_size - @slider_size
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def set_interactive_rects
|
||||
@interactions = {}
|
||||
if @horizontal
|
||||
|
||||
@@ -66,6 +66,7 @@ module GameData
|
||||
"Focus" => [:focus, "e", FOCUS_TYPES],
|
||||
"FoeInvertX" => [:foe_invert_x, "b"],
|
||||
"FoeInvertY" => [:foe_invert_y, "b"],
|
||||
"FoeFlip" => [:foe_flip, "b"],
|
||||
# All properties below are "SetXYZ" or "MoveXYZ". "SetXYZ" has the
|
||||
# keyframe and the value, and "MoveXYZ" has the keyframe, duration and the
|
||||
# value. All have "^" in their schema. "SetXYZ" is turned into "MoveXYZ"
|
||||
@@ -115,7 +116,8 @@ module GameData
|
||||
:graphic => "",
|
||||
:focus => :foreground,
|
||||
:foe_invert_x => false,
|
||||
:foe_invert_y => false
|
||||
:foe_invert_y => false,
|
||||
:foe_flip => false
|
||||
}
|
||||
# NOTE: Particles are invisible until their first command, and automatically
|
||||
# become visible then. "User" and "Target" are visible from the start,
|
||||
|
||||
@@ -198,6 +198,19 @@ module Compiler
|
||||
raise _INTL("Particle \"{1}\" can't set \"FoeInvertY\" if its focus isn't exactly 1 thing.",
|
||||
particle[:name]) + "\n" + FileLineData.linereport
|
||||
end
|
||||
if particle[:foe_flip]
|
||||
raise _INTL("Particle \"{1}\" can't set \"FoeFlip\" if its focus isn't exactly 1 thing.",
|
||||
particle[:name]) + "\n" + FileLineData.linereport
|
||||
end
|
||||
end
|
||||
# Ensure that a particle with a user's/target's graphic doesn't have any
|
||||
# :frame commands
|
||||
if !["User", "Target", "SE"].include?(particle[:name]) &&
|
||||
["USER", "USER_OPP", "USER_FRONT", "USER_BACK",
|
||||
"TARGET", "TARGET_OPP", "TARGET_FRONT", "TARGET_BACK"].include?(particle[:graphic]) &&
|
||||
particle[:frame] && !particle[:frame].empty?
|
||||
raise _INTL("Particle \"{1}\" can't have any \"Frame\" commands if its graphic is a Pokémon's sprite.",
|
||||
particle[:name]) + "\n" + FileLineData.linereport
|
||||
end
|
||||
# Ensure that the same SE isn't played twice in the same frame
|
||||
if particle[:name] == "SE"
|
||||
|
||||
@@ -457,6 +457,7 @@ class AnimationEditor
|
||||
break
|
||||
end
|
||||
end
|
||||
break if Input.triggerex?(:SPACE)
|
||||
break if anim_player.finished?
|
||||
end
|
||||
anim_player.dispose
|
||||
@@ -741,6 +742,15 @@ class AnimationEditor
|
||||
end
|
||||
end
|
||||
|
||||
def update_input
|
||||
if Input.triggerex?(:S)
|
||||
@settings[:user_opposes] = !@settings[:user_opposes]
|
||||
refresh
|
||||
elsif Input.triggerex?(:SPACE)
|
||||
@ready_to_play = true
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
old_keyframe = keyframe
|
||||
old_particle_index = particle_index
|
||||
@@ -769,6 +779,7 @@ class AnimationEditor
|
||||
break
|
||||
end
|
||||
end
|
||||
update_input
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
@@ -58,7 +58,7 @@ class AnimationEditor
|
||||
ret = btn[0]
|
||||
break
|
||||
end
|
||||
ret = :cancel if Input.trigger?(Input::BACK)
|
||||
ret = :cancel if Input.triggerex?(:ESCAPE)
|
||||
break if ret
|
||||
buttons.each { |btn| btn[1].repaint }
|
||||
end
|
||||
@@ -110,7 +110,7 @@ class AnimationEditor
|
||||
end
|
||||
anim_properties.clear_changed
|
||||
end
|
||||
break if !anim_properties.busy? && Input.trigger?(Input::BACK)
|
||||
break if !anim_properties.busy? && Input.triggerex?(:ESCAPE)
|
||||
anim_properties.repaint
|
||||
end
|
||||
# Dispose and return
|
||||
@@ -242,10 +242,13 @@ class AnimationEditor
|
||||
end
|
||||
graphic_chooser.clear_changed
|
||||
end
|
||||
ret = selected if !graphic_chooser.busy? && Input.trigger?(Input::BACK)
|
||||
break if ret
|
||||
graphic_chooser.repaint
|
||||
end
|
||||
if !graphic_chooser.busy? && Input.triggerex?(:ESCAPE)
|
||||
ret = selected
|
||||
break
|
||||
end
|
||||
end
|
||||
# Dispose and return
|
||||
bg_bitmap.dispose
|
||||
@@ -315,13 +318,14 @@ class AnimationEditor
|
||||
end
|
||||
audio_chooser.clear_changed
|
||||
end
|
||||
if !audio_chooser.busy? && Input.trigger?(Input::BACK)
|
||||
ret = selected
|
||||
cance = true
|
||||
end
|
||||
break if ret
|
||||
audio_chooser.repaint
|
||||
end
|
||||
if !audio_chooser.busy? && Input.triggerex?(:ESCAPE)
|
||||
ret = selected
|
||||
cancel = true
|
||||
break
|
||||
end
|
||||
end
|
||||
vol = (cancel) ? volume : audio_chooser.get_control(:volume).value
|
||||
ptch = (cancel) ? pitch : audio_chooser.get_control(:pitch).value
|
||||
@@ -332,5 +336,4 @@ class AnimationEditor
|
||||
audio_chooser.visible = false
|
||||
return [ret, vol, ptch]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -480,6 +480,12 @@ AnimationEditor::SidePanes.add_property(:particle_pane, :graphic, {
|
||||
new_file = editor.choose_graphic_file(editor.anim[:particles][p_index][:graphic])
|
||||
if editor.anim[:particles][p_index][:graphic] != new_file
|
||||
editor.anim[:particles][p_index][:graphic] = new_file
|
||||
if ["USER", "USER_BACK", "USER_FRONT", "USER_OPP",
|
||||
"TARGET", "TARGET_FRONT", "TARGET_BACK", "TARGET_OPP"].include?(new_file)
|
||||
editor.anim[:particles][p_index].delete(:frame)
|
||||
editor.components[:particle_list].set_particles(editor.anim[:particles])
|
||||
editor.refresh_component(:particle_list)
|
||||
end
|
||||
editor.refresh_component(:particle_pane)
|
||||
editor.refresh_component(:canvas)
|
||||
end
|
||||
@@ -552,6 +558,20 @@ AnimationEditor::SidePanes.add_property(:particle_pane, :foe_invert_y, {
|
||||
}
|
||||
})
|
||||
|
||||
AnimationEditor::SidePanes.add_property(:particle_pane, :foe_flip, {
|
||||
:new => proc { |pane, editor|
|
||||
pane.add_labelled_checkbox(:foe_flip, _INTL("Flip Sprite"), false)
|
||||
},
|
||||
:refresh_value => proc { |control, editor|
|
||||
focus = editor.anim[:particles][editor.particle_index][:focus]
|
||||
if GameData::Animation::FOCUS_TYPES_WITH_USER.include?(focus) == GameData::Animation::FOCUS_TYPES_WITH_TARGET.include?(focus)
|
||||
control.disable
|
||||
else
|
||||
control.enable
|
||||
end
|
||||
}
|
||||
})
|
||||
|
||||
AnimationEditor::SidePanes.add_property(:particle_pane, :duplicate, {
|
||||
:new => proc { |pane, editor|
|
||||
pane.add_button(:duplicate, _INTL("Duplicate this particle"))
|
||||
|
||||
@@ -194,7 +194,7 @@ class AnimationEditor::AnimationSelector
|
||||
ret = btn[0]
|
||||
break
|
||||
end
|
||||
ret = :cancel if Input.trigger?(Input::BACK)
|
||||
ret = :cancel if Input.triggerex?(:ESCAPE)
|
||||
break if ret
|
||||
buttons.each { |btn| btn[1].repaint }
|
||||
end
|
||||
|
||||
@@ -475,6 +475,7 @@ class AnimationEditor::Canvas < Sprite
|
||||
spr.zoom_y = values[:zoom_y] / 100.0
|
||||
spr.angle = values[:angle]
|
||||
spr.mirror = values[:flip]
|
||||
spr.mirror = !spr.mirror if relative_to_index >= 0 && relative_to_index.odd? && particle[:foe_flip]
|
||||
spr.blend_type = values[:blending]
|
||||
# Set color and tone
|
||||
spr.color.set(values[:color_red], values[:color_green], values[:color_blue], values[:color_alpha])
|
||||
|
||||
@@ -5,9 +5,9 @@ class AnimationEditor::PlayControls < UIControls::ControlsContainer
|
||||
attr_reader :slowdown, :looping
|
||||
|
||||
ROW_HEIGHT = 28
|
||||
PLAY_BUTTON_X = 241
|
||||
PLAY_BUTTON_Y = 13
|
||||
PLAY_BUTTON_SIZE = 22
|
||||
PLAY_BUTTON_X = 231
|
||||
PLAY_BUTTON_Y = 3
|
||||
PLAY_BUTTON_SIZE = 42
|
||||
LOOP_BUTTON_X = PLAY_BUTTON_X + PLAY_BUTTON_SIZE + 12
|
||||
LOOP_BUTTON_Y = 16
|
||||
LOOP_BUTTON_SIZE = 16
|
||||
@@ -34,7 +34,8 @@ class AnimationEditor::PlayControls < UIControls::ControlsContainer
|
||||
end
|
||||
|
||||
def dispose
|
||||
@bitmaps.each { |b| b&.dispose }
|
||||
@bitmaps.each_value { |b| b&.dispose }
|
||||
@bitmaps.clear
|
||||
super
|
||||
end
|
||||
|
||||
@@ -43,12 +44,12 @@ class AnimationEditor::PlayControls < UIControls::ControlsContainer
|
||||
def generate_button_bitmaps
|
||||
@bitmaps = {}
|
||||
play_button = Bitmap.new(PLAY_BUTTON_SIZE, PLAY_BUTTON_SIZE)
|
||||
(PLAY_BUTTON_SIZE - 2).times do |j|
|
||||
play_button.fill_rect(PLAY_BUTTON_SIZE / 4, j + 1, (j >= (PLAY_BUTTON_SIZE - 2) / 2) ? PLAY_BUTTON_SIZE - j : j + 3, 1, ICON_COLOR)
|
||||
(PLAY_BUTTON_SIZE - 10).times do |j|
|
||||
play_button.fill_rect(11, j + 5, (j >= (PLAY_BUTTON_SIZE - 10) / 2) ? PLAY_BUTTON_SIZE - j - 4 : j + 7, 1, ICON_COLOR)
|
||||
end
|
||||
@bitmaps[:play_button] = play_button
|
||||
stop_button = Bitmap.new(PLAY_BUTTON_SIZE, PLAY_BUTTON_SIZE)
|
||||
stop_button.fill_rect(4, 4, PLAY_BUTTON_SIZE - 8, PLAY_BUTTON_SIZE - 8, ICON_COLOR)
|
||||
stop_button.fill_rect(8, 8, PLAY_BUTTON_SIZE - 16, PLAY_BUTTON_SIZE - 16, ICON_COLOR)
|
||||
@bitmaps[:stop_button] = stop_button
|
||||
# Loop button
|
||||
play_once_button = Bitmap.new(LOOP_BUTTON_SIZE, LOOP_BUTTON_SIZE)
|
||||
@@ -79,6 +80,22 @@ class AnimationEditor::PlayControls < UIControls::ControlsContainer
|
||||
end
|
||||
|
||||
def add_play_controls
|
||||
# Slowdown label
|
||||
duration_label = UIControls::Label.new(200, ROW_HEIGHT, self.viewport, _INTL("Slowdown factor"))
|
||||
duration_label.x = SLOWDOWN_BUTTON_X + (SLOWDOWN_FACTORS.length * (SLOWDOWN_BUTTON_WIDTH + SLOWDOWN_BUTTON_SPACING) / 2)
|
||||
duration_label.x -= (duration_label.text_width / 2) + 5
|
||||
duration_label.y = SLOWDOWN_LABEL_Y
|
||||
@controls.push([:slowdown_label, duration_label])
|
||||
# Slowdown factor buttons
|
||||
SLOWDOWN_FACTORS.each_with_index do |value, i|
|
||||
button = UIControls::Button.new(SLOWDOWN_BUTTON_WIDTH, ROW_HEIGHT, self.viewport, value.to_s)
|
||||
button.set_fixed_size
|
||||
button.x = SLOWDOWN_BUTTON_X + ((SLOWDOWN_BUTTON_WIDTH + SLOWDOWN_BUTTON_SPACING) * i)
|
||||
button.y = SLOWDOWN_BUTTON_Y
|
||||
button.set_interactive_rects
|
||||
button.set_highlighted if value == @slowdown
|
||||
@controls.push([("slowdown" + value.to_s).to_sym, button])
|
||||
end
|
||||
# Play button
|
||||
play_button = UIControls::BitmapButton.new(PLAY_BUTTON_X, PLAY_BUTTON_Y, self.viewport, @bitmaps[:play_button])
|
||||
play_button.set_interactive_rects
|
||||
@@ -98,22 +115,6 @@ class AnimationEditor::PlayControls < UIControls::ControlsContainer
|
||||
unloop_button.set_interactive_rects
|
||||
unloop_button.visible = false if !@looping
|
||||
@controls.push([:unloop, unloop_button])
|
||||
# Slowdown label
|
||||
duration_label = UIControls::Label.new(200, ROW_HEIGHT, self.viewport, _INTL("Slowdown factor"))
|
||||
duration_label.x = SLOWDOWN_BUTTON_X + (SLOWDOWN_FACTORS.length * (SLOWDOWN_BUTTON_WIDTH + SLOWDOWN_BUTTON_SPACING) / 2)
|
||||
duration_label.x -= (duration_label.text_width / 2) + 5
|
||||
duration_label.y = SLOWDOWN_LABEL_Y
|
||||
@controls.push([:slowdown_label, duration_label])
|
||||
# Slowdown factor buttons
|
||||
SLOWDOWN_FACTORS.each_with_index do |value, i|
|
||||
button = UIControls::Button.new(SLOWDOWN_BUTTON_WIDTH, ROW_HEIGHT, self.viewport, value.to_s)
|
||||
button.set_fixed_size
|
||||
button.x = SLOWDOWN_BUTTON_X + ((SLOWDOWN_BUTTON_WIDTH + SLOWDOWN_BUTTON_SPACING) * i)
|
||||
button.y = SLOWDOWN_BUTTON_Y
|
||||
button.set_interactive_rects
|
||||
button.set_highlighted if value == @slowdown
|
||||
@controls.push([("slowdown" + value.to_s).to_sym, button])
|
||||
end
|
||||
# Duration label
|
||||
duration_label = UIControls::Label.new(200, ROW_HEIGHT, self.viewport, _INTL("Duration"))
|
||||
duration_label.x = DURATION_TEXT_X - (duration_label.text_width / 2)
|
||||
|
||||
@@ -175,7 +175,8 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
||||
@particle_line_sprite.dispose
|
||||
@controls.each { |c| c[1].dispose }
|
||||
@controls.clear
|
||||
@bitmaps.each { |b| b&.dispose }
|
||||
@bitmaps.each_value { |b| b&.dispose }
|
||||
@bitmaps.clear
|
||||
dispose_listed_sprites
|
||||
@list_viewport.dispose
|
||||
@commands_bg_viewport.dispose
|
||||
@@ -433,16 +434,16 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def calculate_duration
|
||||
@duration = AnimationPlayer::Helper.get_duration(@particles)
|
||||
@duration += DURATION_BUFFER
|
||||
end
|
||||
|
||||
def calculate_all_commands_and_durations
|
||||
calculate_duration
|
||||
calculate_all_commands
|
||||
end
|
||||
|
||||
def calculate_duration
|
||||
@duration = AnimationPlayer::Helper.get_duration(@particles)
|
||||
@duration += DURATION_BUFFER
|
||||
end
|
||||
|
||||
def calculate_all_commands
|
||||
@commands = {}
|
||||
@particles.each_with_index do |particle, index|
|
||||
@@ -1024,13 +1025,13 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
||||
|
||||
def update_input
|
||||
# Left/right to change current keyframe
|
||||
if Input.repeat?(Input::LEFT)
|
||||
if Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT)
|
||||
if @keyframe > 0
|
||||
@keyframe -= 1
|
||||
scroll_to_keyframe(@keyframe)
|
||||
set_changed
|
||||
end
|
||||
elsif Input.repeat?(Input::RIGHT)
|
||||
elsif Input.triggerex?(:RIGHT) || Input.repeatex?(:RIGHT)
|
||||
if @keyframe < @duration - 1
|
||||
@keyframe += 1
|
||||
scroll_to_keyframe(@keyframe)
|
||||
@@ -1038,7 +1039,7 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
||||
end
|
||||
end
|
||||
# Up/down to change selected particle
|
||||
if Input.repeat?(Input::UP)
|
||||
if Input.triggerex?(:UP) || Input.repeatex?(:UP)
|
||||
if @row_index > 0
|
||||
loop do
|
||||
@row_index -= 1
|
||||
@@ -1047,7 +1048,7 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
||||
scroll_to_row(@row_index)
|
||||
set_changed
|
||||
end
|
||||
elsif Input.repeat?(Input::DOWN)
|
||||
elsif Input.triggerex?(:DOWN) || Input.repeatex?(:DOWN)
|
||||
if @row_index < @particle_list.length - 1
|
||||
old_row_index = @row_index
|
||||
loop do
|
||||
@@ -1064,6 +1065,18 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
||||
end
|
||||
end
|
||||
end
|
||||
if Input.triggerex?(:P)
|
||||
idx_particle = @particle_list[@row_index]
|
||||
idx_particle = idx_particle[0] if idx_particle.is_a?(Array)
|
||||
if @row_index >= 0 && @particles[idx_particle][:name] != "SE"
|
||||
if @expanded_particles.include?(idx_particle) # Contract
|
||||
@expanded_particles.delete(idx_particle)
|
||||
else # Expand
|
||||
@expanded_particles.push(idx_particle)
|
||||
end
|
||||
set_particles(@particles)
|
||||
end
|
||||
end
|
||||
# Mouse scroll wheel
|
||||
mouse_x, mouse_y = mouse_pos
|
||||
if mouse_x && mouse_y
|
||||
|
||||
@@ -124,6 +124,7 @@ class AnimationPlayer
|
||||
if relative_to_index >= 0 && relative_to_index.odd? && particle[:focus] != :user_and_target
|
||||
particle_sprite.foe_invert_x = particle[:foe_invert_x]
|
||||
particle_sprite.foe_invert_y = particle[:foe_invert_y]
|
||||
particle_sprite.foe_flip = particle[:foe_flip]
|
||||
end
|
||||
# Find earliest command and add a "make visible" command then
|
||||
if sprite && !particle_sprite.battler_sprite?
|
||||
@@ -231,7 +232,7 @@ class AnimationPlayer
|
||||
# Update all particles/sprites
|
||||
@anim_sprites.each { |particle| particle.update(elapsed) }
|
||||
# Finish or loop the animation
|
||||
if elapsed >= @duration
|
||||
if elapsed >= @duration * @slowdown
|
||||
if looping
|
||||
@need_reset = true
|
||||
else
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
class AnimationPlayer::ParticleSprite
|
||||
attr_accessor :sprite
|
||||
attr_accessor :focus_xy, :offset_xy, :focus_z
|
||||
attr_accessor :foe_invert_x, :foe_invert_y
|
||||
attr_accessor :foe_invert_x, :foe_invert_y, :foe_flip
|
||||
|
||||
FRAMES_PER_SECOND = 20.0
|
||||
|
||||
@@ -97,7 +97,9 @@ class AnimationPlayer::ParticleSprite
|
||||
case property
|
||||
when :frame then @sprite.src_rect.x = value.floor * @sprite.src_rect.width
|
||||
when :blending then @sprite.blend_type = value
|
||||
when :flip then @sprite.mirror = value
|
||||
when :flip
|
||||
@sprite.mirror = value
|
||||
@sprite.mirror = !@sprite.mirror if @foe_flip
|
||||
when :x
|
||||
value = value.round
|
||||
value *= -1 if @foe_invert_x
|
||||
|
||||
Reference in New Issue
Block a user