From 4480def33c06090047ab2824ab59eb9f6897694a Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Thu, 18 Apr 2024 22:35:15 +0100 Subject: [PATCH] Anim Editor: added FoeFlip property, Space to play, S to swap sides, P to show/hide property lines for selected particle --- .../Control elements/001_BaseControl.rb | 16 +++-- .../Control elements/002_Label.rb | 4 ++ .../Control elements/003_Checkbox.rb | 9 ++- .../Control elements/004_TextBox.rb | 62 ++++++++++--------- .../Control elements/005_NumberSlider.rb | 15 +++-- .../Control elements/006_NumberTextBox.rb | 7 ++- .../Control elements/007_Button.rb | 28 +++++---- .../Control elements/008_BitmapButton.rb | 2 + .../Control elements/009_List.rb | 45 +++++++------- .../Control elements/010_DropdownList.rb | 24 +++---- .../011_TextBoxDropdownList.rb | 22 ++++--- .../Control elements/101_Scrollbar.rb | 32 +++++----- .../902_Anim GameData/001_Animation.rb | 4 +- .../903_Anim Compiler/001_Anim compiler.rb | 13 ++++ .../904_Anim Editor/001_AnimationEditor.rb | 11 ++++ .../002_AnimationEditor_popups.rb | 19 +++--- .../003_AnimationEditor_side_panes.rb | 20 ++++++ .../904_Anim Editor/010_AnimationSelector.rb | 2 +- .../Anim Editor elements/001_Canvas.rb | 1 + .../Anim Editor elements/002_PlayControls.rb | 47 +++++++------- .../Anim Editor elements/003_ParticleList.rb | 33 +++++++--- .../905_Anim player/001_Anim player.rb | 3 +- .../905_Anim player/002_ParticleSprite.rb | 6 +- 23 files changed, 264 insertions(+), 161 deletions(-) diff --git a/Data/Scripts/801_UI controls/Control elements/001_BaseControl.rb b/Data/Scripts/801_UI controls/Control elements/001_BaseControl.rb index f60962048..da56d8662 100644 --- a/Data/Scripts/801_UI controls/Control elements/001_BaseControl.rb +++ b/Data/Scripts/801_UI controls/Control elements/001_BaseControl.rb @@ -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) diff --git a/Data/Scripts/801_UI controls/Control elements/002_Label.rb b/Data/Scripts/801_UI controls/Control elements/002_Label.rb index 8d6d429fc..7f5695547 100644 --- a/Data/Scripts/801_UI controls/Control elements/002_Label.rb +++ b/Data/Scripts/801_UI controls/Control elements/002_Label.rb @@ -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 diff --git a/Data/Scripts/801_UI controls/Control elements/003_Checkbox.rb b/Data/Scripts/801_UI controls/Control elements/003_Checkbox.rb index 7d574992d..a4252cd75 100644 --- a/Data/Scripts/801_UI controls/Control elements/003_Checkbox.rb +++ b/Data/Scripts/801_UI controls/Control elements/003_Checkbox.rb @@ -6,21 +6,24 @@ 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 + UNCHECKED_COLOR = Color.gray + CHECKED_COLOR = Color.new(48, 192, 48) # Darkish green def initialize(width, height, viewport, value = false) super(width, height, viewport) @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) diff --git a/Data/Scripts/801_UI controls/Control elements/004_TextBox.rb b/Data/Scripts/801_UI controls/Control elements/004_TextBox.rb index fb2e3a227..773e7c15d 100644 --- a/Data/Scripts/801_UI controls/Control elements/004_TextBox.rb +++ b/Data/Scripts/801_UI controls/Control elements/004_TextBox.rb @@ -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 = [] diff --git a/Data/Scripts/801_UI controls/Control elements/005_NumberSlider.rb b/Data/Scripts/801_UI controls/Control elements/005_NumberSlider.rb index 4201f20a5..595a13d1a 100644 --- a/Data/Scripts/801_UI controls/Control elements/005_NumberSlider.rb +++ b/Data/Scripts/801_UI controls/Control elements/005_NumberSlider.rb @@ -7,12 +7,11 @@ 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 - PLUS_X = SLIDER_X + SLIDER_LENGTH + SLIDER_PADDING - VALUE_X = PLUS_X + PLUS_MINUS_SIZE + 5 + MINUS_X = 0 + SLIDER_X = MINUS_X + PLUS_MINUS_SIZE + SLIDER_PADDING + SLIDER_LENGTH = 128 + PLUS_X = SLIDER_X + SLIDER_LENGTH + SLIDER_PADDING + VALUE_X = PLUS_X + PLUS_MINUS_SIZE + 5 def initialize(width, height, viewport, min_value, max_value, value) super(width, height, viewport) @@ -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) diff --git a/Data/Scripts/801_UI controls/Control elements/006_NumberTextBox.rb b/Data/Scripts/801_UI controls/Control elements/006_NumberTextBox.rb index de62d92f6..4b75c06a1 100644 --- a/Data/Scripts/801_UI controls/Control elements/006_NumberTextBox.rb +++ b/Data/Scripts/801_UI controls/Control elements/006_NumberTextBox.rb @@ -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 diff --git a/Data/Scripts/801_UI controls/Control elements/007_Button.rb b/Data/Scripts/801_UI controls/Control elements/007_Button.rb index ffdc8dbfc..847737d32 100644 --- a/Data/Scripts/801_UI controls/Control elements/007_Button.rb +++ b/Data/Scripts/801_UI controls/Control elements/007_Button.rb @@ -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? diff --git a/Data/Scripts/801_UI controls/Control elements/008_BitmapButton.rb b/Data/Scripts/801_UI controls/Control elements/008_BitmapButton.rb index 443590016..5f72a3f12 100644 --- a/Data/Scripts/801_UI controls/Control elements/008_BitmapButton.rb +++ b/Data/Scripts/801_UI controls/Control elements/008_BitmapButton.rb @@ -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) diff --git a/Data/Scripts/801_UI controls/Control elements/009_List.rb b/Data/Scripts/801_UI controls/Control elements/009_List.rb index 6359e2a32..2662cd511 100644 --- a/Data/Scripts/801_UI controls/Control elements/009_List.rb +++ b/Data/Scripts/801_UI controls/Control elements/009_List.rb @@ -2,11 +2,10 @@ # #=============================================================================== class UIControls::List < UIControls::BaseControl - BORDER_THICKNESS = 2 - ROW_HEIGHT = 24 - TEXT_PADDING_X = 4 - TEXT_OFFSET_Y = 3 - + BORDER_THICKNESS = 2 + 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 diff --git a/Data/Scripts/801_UI controls/Control elements/010_DropdownList.rb b/Data/Scripts/801_UI controls/Control elements/010_DropdownList.rb index 0c165dd78..d4d7cc983 100644 --- a/Data/Scripts/801_UI controls/Control elements/010_DropdownList.rb +++ b/Data/Scripts/801_UI controls/Control elements/010_DropdownList.rb @@ -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 diff --git a/Data/Scripts/801_UI controls/Control elements/011_TextBoxDropdownList.rb b/Data/Scripts/801_UI controls/Control elements/011_TextBoxDropdownList.rb index 4971d33ce..112a11abd 100644 --- a/Data/Scripts/801_UI controls/Control elements/011_TextBoxDropdownList.rb +++ b/Data/Scripts/801_UI controls/Control elements/011_TextBoxDropdownList.rb @@ -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 diff --git a/Data/Scripts/801_UI controls/Control elements/101_Scrollbar.rb b/Data/Scripts/801_UI controls/Control elements/101_Scrollbar.rb index b91de8dac..14a954bdd 100644 --- a/Data/Scripts/801_UI controls/Control elements/101_Scrollbar.rb +++ b/Data/Scripts/801_UI controls/Control elements/101_Scrollbar.rb @@ -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 diff --git a/Data/Scripts/902_Anim GameData/001_Animation.rb b/Data/Scripts/902_Anim GameData/001_Animation.rb index de7e4ec70..7409726f8 100644 --- a/Data/Scripts/902_Anim GameData/001_Animation.rb +++ b/Data/Scripts/902_Anim GameData/001_Animation.rb @@ -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, diff --git a/Data/Scripts/903_Anim Compiler/001_Anim compiler.rb b/Data/Scripts/903_Anim Compiler/001_Anim compiler.rb index e5ba0189b..5a6a1c053 100644 --- a/Data/Scripts/903_Anim Compiler/001_Anim compiler.rb +++ b/Data/Scripts/903_Anim Compiler/001_Anim compiler.rb @@ -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" diff --git a/Data/Scripts/904_Anim Editor/001_AnimationEditor.rb b/Data/Scripts/904_Anim Editor/001_AnimationEditor.rb index 3fd4000b5..4c900b1f1 100644 --- a/Data/Scripts/904_Anim Editor/001_AnimationEditor.rb +++ b/Data/Scripts/904_Anim Editor/001_AnimationEditor.rb @@ -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 #----------------------------------------------------------------------------- diff --git a/Data/Scripts/904_Anim Editor/002_AnimationEditor_popups.rb b/Data/Scripts/904_Anim Editor/002_AnimationEditor_popups.rb index d94e6be61..7c01be061 100644 --- a/Data/Scripts/904_Anim Editor/002_AnimationEditor_popups.rb +++ b/Data/Scripts/904_Anim Editor/002_AnimationEditor_popups.rb @@ -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 diff --git a/Data/Scripts/904_Anim Editor/003_AnimationEditor_side_panes.rb b/Data/Scripts/904_Anim Editor/003_AnimationEditor_side_panes.rb index 02cdfb481..eff548ee2 100644 --- a/Data/Scripts/904_Anim Editor/003_AnimationEditor_side_panes.rb +++ b/Data/Scripts/904_Anim Editor/003_AnimationEditor_side_panes.rb @@ -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")) diff --git a/Data/Scripts/904_Anim Editor/010_AnimationSelector.rb b/Data/Scripts/904_Anim Editor/010_AnimationSelector.rb index 584fdfab7..c794560f1 100644 --- a/Data/Scripts/904_Anim Editor/010_AnimationSelector.rb +++ b/Data/Scripts/904_Anim Editor/010_AnimationSelector.rb @@ -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 diff --git a/Data/Scripts/904_Anim Editor/Anim Editor elements/001_Canvas.rb b/Data/Scripts/904_Anim Editor/Anim Editor elements/001_Canvas.rb index 70bb97c5f..280d05b5a 100644 --- a/Data/Scripts/904_Anim Editor/Anim Editor elements/001_Canvas.rb +++ b/Data/Scripts/904_Anim Editor/Anim Editor elements/001_Canvas.rb @@ -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]) diff --git a/Data/Scripts/904_Anim Editor/Anim Editor elements/002_PlayControls.rb b/Data/Scripts/904_Anim Editor/Anim Editor elements/002_PlayControls.rb index ffef45cd4..36ee380eb 100644 --- a/Data/Scripts/904_Anim Editor/Anim Editor elements/002_PlayControls.rb +++ b/Data/Scripts/904_Anim Editor/Anim Editor elements/002_PlayControls.rb @@ -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) diff --git a/Data/Scripts/904_Anim Editor/Anim Editor elements/003_ParticleList.rb b/Data/Scripts/904_Anim Editor/Anim Editor elements/003_ParticleList.rb index e38ccd6a3..2dce84454 100644 --- a/Data/Scripts/904_Anim Editor/Anim Editor elements/003_ParticleList.rb +++ b/Data/Scripts/904_Anim Editor/Anim Editor elements/003_ParticleList.rb @@ -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 diff --git a/Data/Scripts/905_Anim player/001_Anim player.rb b/Data/Scripts/905_Anim player/001_Anim player.rb index ae9d7b67e..14b651197 100644 --- a/Data/Scripts/905_Anim player/001_Anim player.rb +++ b/Data/Scripts/905_Anim player/001_Anim player.rb @@ -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 diff --git a/Data/Scripts/905_Anim player/002_ParticleSprite.rb b/Data/Scripts/905_Anim player/002_ParticleSprite.rb index 90b7b3160..e97efce82 100644 --- a/Data/Scripts/905_Anim player/002_ParticleSprite.rb +++ b/Data/Scripts/905_Anim player/002_ParticleSprite.rb @@ -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