mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
Made New/Copy/Delete buttons in animation selector screen work, split animations compiler into its own compiler
This commit is contained in:
@@ -159,6 +159,25 @@ module GameData
|
|||||||
DATA[(id_num >= 0) ? id_num : DATA.keys.length] = self.new(hash)
|
DATA[(id_num >= 0) ? id_num : DATA.keys.length] = self.new(hash)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.new_hash(anim_type = 0, move = nil)
|
||||||
|
ret = {}
|
||||||
|
ret[:type] = (anim_type == 0) ? :move : :common
|
||||||
|
ret[:move] = (anim_type == 0) ? "STRUGGLE" : "Shiny"
|
||||||
|
ret[:move] = move if !move.nil?
|
||||||
|
ret[:version] = 0
|
||||||
|
ret[:name] = _INTL("New animation")
|
||||||
|
ret[:no_target] = false
|
||||||
|
ret[:ignore] = false
|
||||||
|
ret[:particles] = [
|
||||||
|
{:name => "User", :focus => :user, :graphic => "USER"},
|
||||||
|
{:name => "Target", :focus => :target, :graphic => "TARGET"},
|
||||||
|
{:name => "SE"}
|
||||||
|
]
|
||||||
|
ret[:flags] = []
|
||||||
|
ret[:pbs_path] = "New animation"
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(hash)
|
def initialize(hash)
|
||||||
# NOTE: hash has an :id entry, but it's unused here.
|
# NOTE: hash has an :id entry, but it's unused here.
|
||||||
@type = hash[:type]
|
@type = hash[:type]
|
||||||
@@ -180,6 +199,8 @@ module GameData
|
|||||||
ret[:move] = @move
|
ret[:move] = @move
|
||||||
ret[:version] = @version
|
ret[:version] = @version
|
||||||
ret[:name] = @name
|
ret[:name] = @name
|
||||||
|
ret[:no_target] = @no_target
|
||||||
|
ret[:ignore] = @ignore
|
||||||
ret[:particles] = [] # Clone the @particles array, which is nested hashes and arrays
|
ret[:particles] = [] # Clone the @particles array, which is nested hashes and arrays
|
||||||
@particles.each do |particle|
|
@particles.each do |particle|
|
||||||
new_p = {}
|
new_p = {}
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ end
|
|||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# Hook into the regular Compiler to also compile animation PBS files.
|
# Hook into the regular Compiler to also compile animation PBS files.
|
||||||
|
# This is a separate Compiler that runs after the regular one.
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
module Compiler
|
module Compiler
|
||||||
module_function
|
module_function
|
||||||
@@ -215,24 +216,69 @@ module Compiler
|
|||||||
end
|
end
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
if !method_defined?(:__new_anims__get_all_pbs_files_to_compile)
|
if !method_defined?(:__new_anims_main)
|
||||||
alias_method :__new_anims__get_all_pbs_files_to_compile, :get_all_pbs_files_to_compile
|
alias_method :__new_anims_main, :main
|
||||||
end
|
|
||||||
if !method_defined?(:__new_anims__compile_pbs_files)
|
|
||||||
alias_method :__new_anims__compile_pbs_files, :compile_pbs_files
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_all_pbs_files_to_compile
|
def main
|
||||||
ret = __new_anims__get_all_pbs_files_to_compile
|
__new_anims_main
|
||||||
extra = get_animation_pbs_files_to_compile
|
return if !$DEBUG
|
||||||
ret[:Animation] = [nil, extra]
|
begin
|
||||||
return ret
|
Console.echo_h1(_INTL("Checking new animations data"))
|
||||||
end
|
must_compile = false
|
||||||
|
data_file = "animations.dat"
|
||||||
def compile_pbs_files
|
|
||||||
__new_anims__compile_pbs_files
|
|
||||||
text_files = get_animation_pbs_files_to_compile
|
text_files = get_animation_pbs_files_to_compile
|
||||||
|
latest_data_time = 0
|
||||||
|
latest_text_time = 0
|
||||||
|
# Check data file for its latest modify time
|
||||||
|
if FileTest.exist?("Data/" + data_file)
|
||||||
|
begin
|
||||||
|
File.open("Data/#{data_file}") do |file|
|
||||||
|
latest_data_time = [latest_data_time, file.mtime.to_i].max
|
||||||
|
end
|
||||||
|
rescue SystemCallError
|
||||||
|
must_compile = true
|
||||||
|
end
|
||||||
|
else
|
||||||
|
must_compile = true if text_files.length > 0
|
||||||
|
end
|
||||||
|
# Check PBS files for their latest modify time
|
||||||
|
text_files.each do |filepath|
|
||||||
|
begin
|
||||||
|
File.open(filepath) do |file|
|
||||||
|
latest_text_time = [latest_text_time, file.mtime.to_i].max
|
||||||
|
end
|
||||||
|
rescue SystemCallError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Decide to compile if a PBS file was edited more recently than the .dat file
|
||||||
|
must_compile |= (latest_text_time >= latest_data_time)
|
||||||
|
# Should recompile if holding Ctrl
|
||||||
|
Input.update
|
||||||
|
must_compile = true if $full_compile || Input.press?(Input::CTRL)
|
||||||
|
# Delete old data file in preparation for recompiling
|
||||||
|
if must_compile
|
||||||
|
begin
|
||||||
|
File.delete("Data/#{data_file}") if FileTest.exist?("Data/#{data_file}")
|
||||||
|
rescue SystemCallError
|
||||||
|
end
|
||||||
|
# Recompile all data
|
||||||
compile_battle_animations(*text_files)
|
compile_battle_animations(*text_files)
|
||||||
|
else
|
||||||
|
Console.echoln_li(_INTL("New animations data were not compiled"))
|
||||||
|
end
|
||||||
|
echoln ""
|
||||||
|
rescue Exception
|
||||||
|
e = $!
|
||||||
|
raise e if e.class.to_s == "Reset" || e.is_a?(Reset) || e.is_a?(SystemExit)
|
||||||
|
pbPrintException(e)
|
||||||
|
begin
|
||||||
|
File.delete("Data/#{data_file}") if FileTest.exist?("Data/#{data_file}")
|
||||||
|
rescue SystemCallError
|
||||||
|
end
|
||||||
|
raise Reset.new if e.is_a?(Hangup)
|
||||||
|
raise "Unknown exception when compiling animations."
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
#
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class AnimationEditor::AnimationSelector
|
class AnimationEditor::AnimationSelector
|
||||||
|
BORDER_THICKNESS = 4
|
||||||
|
|
||||||
QUIT_BUTTON_WIDTH = 80
|
QUIT_BUTTON_WIDTH = 80
|
||||||
QUIT_BUTTON_HEIGHT = 30
|
QUIT_BUTTON_HEIGHT = 30
|
||||||
|
|
||||||
@@ -25,11 +27,23 @@ class AnimationEditor::AnimationSelector
|
|||||||
ACTION_BUTTON_X = ANIMATIONS_LIST_X + ANIMATIONS_LIST_WIDTH + 4
|
ACTION_BUTTON_X = ANIMATIONS_LIST_X + ANIMATIONS_LIST_WIDTH + 4
|
||||||
ACTION_BUTTON_Y = TYPE_BUTTONS_Y + ((ANIMATIONS_LIST_HEIGHT - (ACTION_BUTTON_HEIGHT * 3)) / 2) + 4
|
ACTION_BUTTON_Y = TYPE_BUTTONS_Y + ((ANIMATIONS_LIST_HEIGHT - (ACTION_BUTTON_HEIGHT * 3)) / 2) + 4
|
||||||
|
|
||||||
|
# Pop-up window
|
||||||
|
MESSAGE_BOX_WIDTH = AnimationEditor::WINDOW_WIDTH * 3 / 4
|
||||||
|
MESSAGE_BOX_HEIGHT = 160
|
||||||
|
MESSAGE_BOX_BUTTON_WIDTH = 150
|
||||||
|
MESSAGE_BOX_BUTTON_HEIGHT = 32
|
||||||
|
MESSAGE_BOX_SPACING = 16
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
generate_lists
|
generate_lists
|
||||||
@viewport = Viewport.new(0, 0, AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT)
|
@viewport = Viewport.new(0, 0, AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT)
|
||||||
@viewport.z = 99999
|
@viewport.z = 99999
|
||||||
|
@pop_up_viewport = Viewport.new(0, 0, AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT)
|
||||||
|
@pop_up_viewport.z = @viewport.z + 50
|
||||||
@screen_bitmap = BitmapSprite.new(AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT, @viewport)
|
@screen_bitmap = BitmapSprite.new(AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT, @viewport)
|
||||||
|
@pop_up_bg_bitmap = BitmapSprite.new(AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT, @pop_up_viewport)
|
||||||
|
@pop_up_bg_bitmap.z = -100
|
||||||
|
@pop_up_bg_bitmap.visible = false
|
||||||
draw_editor_background
|
draw_editor_background
|
||||||
@animation_type = 0 # 0=move, 1=common
|
@animation_type = 0 # 0=move, 1=common
|
||||||
@quit = false
|
@quit = false
|
||||||
@@ -39,8 +53,10 @@ class AnimationEditor::AnimationSelector
|
|||||||
|
|
||||||
def dispose
|
def dispose
|
||||||
@screen_bitmap.dispose
|
@screen_bitmap.dispose
|
||||||
|
@pop_up_bg_bitmap.dispose
|
||||||
@components.dispose
|
@components.dispose
|
||||||
@viewport.dispose
|
@viewport.dispose
|
||||||
|
@pop_up_viewport.dispose
|
||||||
end
|
end
|
||||||
|
|
||||||
LABEL_OFFSET_X = -4
|
LABEL_OFFSET_X = -4
|
||||||
@@ -108,6 +124,80 @@ class AnimationEditor::AnimationSelector
|
|||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def create_pop_up_window(width, height)
|
||||||
|
ret = BitmapSprite.new(width + (BORDER_THICKNESS * 2),
|
||||||
|
height + (BORDER_THICKNESS * 2), @pop_up_viewport)
|
||||||
|
ret.x = (AnimationEditor::WINDOW_WIDTH - ret.width) / 2
|
||||||
|
ret.y = (AnimationEditor::WINDOW_HEIGHT - ret.height) / 2
|
||||||
|
ret.z = -1
|
||||||
|
ret.bitmap.font.color = Color.black
|
||||||
|
ret.bitmap.font.size = 18
|
||||||
|
# Draw pop-up box border
|
||||||
|
ret.bitmap.border_rect(BORDER_THICKNESS, BORDER_THICKNESS, width, height,
|
||||||
|
BORDER_THICKNESS, Color.white, Color.black)
|
||||||
|
# Fill pop-up box with white
|
||||||
|
ret.bitmap.fill_rect(BORDER_THICKNESS, BORDER_THICKNESS, width, height, Color.white)
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def message(text, *options)
|
||||||
|
@pop_up_bg_bitmap.visible = true
|
||||||
|
msg_bitmap = create_pop_up_window(MESSAGE_BOX_WIDTH, MESSAGE_BOX_HEIGHT)
|
||||||
|
# Draw text
|
||||||
|
text_size = msg_bitmap.bitmap.text_size(text)
|
||||||
|
msg_bitmap.bitmap.draw_text(0, (msg_bitmap.height / 2) - MESSAGE_BOX_BUTTON_HEIGHT,
|
||||||
|
msg_bitmap.width, text_size.height, text, 1)
|
||||||
|
# Create buttons
|
||||||
|
buttons = []
|
||||||
|
options.each_with_index do |option, i|
|
||||||
|
btn = UIControls::Button.new(MESSAGE_BOX_BUTTON_WIDTH, MESSAGE_BOX_BUTTON_HEIGHT, @pop_up_viewport, option[1])
|
||||||
|
btn.x = msg_bitmap.x + (msg_bitmap.width - (MESSAGE_BOX_BUTTON_WIDTH * options.length)) / 2
|
||||||
|
btn.x += MESSAGE_BOX_BUTTON_WIDTH * i
|
||||||
|
btn.y = msg_bitmap.y + msg_bitmap.height - MESSAGE_BOX_BUTTON_HEIGHT - MESSAGE_BOX_SPACING
|
||||||
|
btn.set_fixed_size
|
||||||
|
btn.set_interactive_rects
|
||||||
|
buttons.push([option[0], btn])
|
||||||
|
end
|
||||||
|
# Interaction loop
|
||||||
|
ret = nil
|
||||||
|
captured = nil
|
||||||
|
loop do
|
||||||
|
Graphics.update
|
||||||
|
Input.update
|
||||||
|
if captured
|
||||||
|
captured.update
|
||||||
|
captured = nil if !captured.busy?
|
||||||
|
else
|
||||||
|
buttons.each do |btn|
|
||||||
|
btn[1].update
|
||||||
|
captured = btn[1] if btn[1].busy?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
buttons.each do |btn|
|
||||||
|
next if !btn[1].changed?
|
||||||
|
ret = btn[0]
|
||||||
|
break
|
||||||
|
end
|
||||||
|
ret = :cancel if Input.trigger?(Input::BACK)
|
||||||
|
break if ret
|
||||||
|
buttons.each { |btn| btn[1].repaint }
|
||||||
|
end
|
||||||
|
# Dispose and return
|
||||||
|
buttons.each { |btn| btn[1].dispose }
|
||||||
|
buttons.clear
|
||||||
|
msg_bitmap.dispose
|
||||||
|
@pop_up_bg_bitmap.visible = false
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
def confirm_message(text)
|
||||||
|
return message(text, [:yes, _INTL("Yes")], [:no, _INTL("No")]) == :yes
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
def generate_lists
|
def generate_lists
|
||||||
@move_list = []
|
@move_list = []
|
||||||
@common_list = []
|
@common_list = []
|
||||||
@@ -190,11 +280,11 @@ class AnimationEditor::AnimationSelector
|
|||||||
@quit = true
|
@quit = true
|
||||||
return # Don't need to refresh the screen
|
return # Don't need to refresh the screen
|
||||||
when :new
|
when :new
|
||||||
# TODO: New animation. Create a new animation hash with some default
|
new_anim = GameData::Animation.new_hash(@animation_type, @components.get_control(:moves_list).value)
|
||||||
# contents, go into the edit screen and immediately open the
|
new_id = GameData::Animation.keys.max + 1
|
||||||
# animation properties pop-up window. Use the first available ID
|
screen = AnimationEditor.new(new_id, new_anim)
|
||||||
# number from GameData::Animation for it. Don't register the
|
screen.run
|
||||||
# animation hash here, though.
|
generate_lists
|
||||||
when :moves
|
when :moves
|
||||||
@animation_type = 0
|
@animation_type = 0
|
||||||
@components.get_control(:moves_list).selected = -1
|
@components.get_control(:moves_list).selected = -1
|
||||||
@@ -213,12 +303,24 @@ class AnimationEditor::AnimationSelector
|
|||||||
when :copy
|
when :copy
|
||||||
anim_id = selected_animation_id
|
anim_id = selected_animation_id
|
||||||
if anim_id
|
if anim_id
|
||||||
# TODO: Copy animation. Append "(copy)" to its name.
|
new_anim = GameData::Animation.get(anim_id).clone_as_hash
|
||||||
|
new_anim[:name] += " " + _INTL("(copy)") if !nil_or_empty?(new_anim[:name])
|
||||||
|
new_id = GameData::Animation.keys.max + 1
|
||||||
|
screen = AnimationEditor.new(new_id, new_anim)
|
||||||
|
screen.run
|
||||||
|
generate_lists
|
||||||
end
|
end
|
||||||
when :delete
|
when :delete
|
||||||
anim_id = selected_animation_id
|
anim_id = selected_animation_id
|
||||||
if anim_id
|
if anim_id && confirm_message(_INTL("Are you sure you want to delete this animation?"))
|
||||||
# TODO: Delete animation. Ask the user if they're sure.
|
pbs_path = GameData::Animation.get(anim_id).pbs_path
|
||||||
|
GameData::Animation::DATA.delete(anim_id)
|
||||||
|
if GameData::Animation::DATA.any? { |_key, anim| anim.pbs_path == pbs_path }
|
||||||
|
Compiler.write_battle_animation_file(pbs_path)
|
||||||
|
elsif FileTest.exist?("PBS/Animations/" + pbs_path + ".txt")
|
||||||
|
File.delete("PBS/Animations/" + pbs_path + ".txt")
|
||||||
|
end
|
||||||
|
generate_lists
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
refresh
|
refresh
|
||||||
|
|||||||
Reference in New Issue
Block a user