mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-08 13:44:59 +00:00
Added canvas to new animation editor (isn't interactive yet), improved example animations
This commit is contained in:
@@ -135,7 +135,7 @@ module Compiler
|
||||
case particle[:name]
|
||||
when "User" then particle[:focus] = :user
|
||||
when "Target" then particle[:focus] = :target
|
||||
else particle[:focus] = :screen
|
||||
else particle[:focus] = GameData::Animation::PARTICLE_DEFAULT_VALUES[:focus]
|
||||
end
|
||||
end
|
||||
# Ensure user/target particles have a default graphic if not given
|
||||
@@ -145,9 +145,11 @@ module Compiler
|
||||
when "Target" then particle[:graphic] = "TARGET"
|
||||
end
|
||||
end
|
||||
# TODO: Ensure that particles don't have a focus involving a user if the
|
||||
# animation itself doesn't involve a user.
|
||||
# Ensure that particles don't have a focus involving a target if the
|
||||
# animation itself doesn't involve a target
|
||||
if hash[:no_target] && [:target, :user_and_target].include?(particle[:focus])
|
||||
if hash[:no_target] && 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
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# TODO: OppMove animations have their user and target swapped, and will need
|
||||
# them swapping back.
|
||||
|
||||
module AnimationConverter
|
||||
module_function
|
||||
|
||||
@@ -50,6 +53,7 @@ module AnimationConverter
|
||||
}
|
||||
|
||||
add_frames_to_new_anim_hash(anim, new_anim)
|
||||
add_bg_fg_commands_to_new_anim_hash(anim, new_anim)
|
||||
add_se_commands_to_new_anim_hash(anim, new_anim)
|
||||
|
||||
new_anim[:particles].compact!
|
||||
@@ -60,6 +64,9 @@ module AnimationConverter
|
||||
end
|
||||
|
||||
def add_frames_to_new_anim_hash(anim, hash)
|
||||
# Lookup array for particle index using cel index
|
||||
index_lookup = []
|
||||
max_index = -1
|
||||
# Set up previous frame's values
|
||||
default_frame = []
|
||||
default_frame[AnimFrame::X] = -999
|
||||
@@ -77,30 +84,70 @@ module AnimationConverter
|
||||
default_frame[AnimFrame::TONEGREEN] = 0
|
||||
default_frame[AnimFrame::TONEBLUE] = 0
|
||||
default_frame[AnimFrame::TONEGRAY] = 0
|
||||
default_frame[AnimFrame::PATTERN] = 0
|
||||
default_frame[AnimFrame::PRIORITY] = 0 # 0=back, 1=front, 2=behind focus, 3=before focus
|
||||
|
||||
default_frame[AnimFrame::VISIBLE] = 1 # Boolean
|
||||
default_frame[AnimFrame::MIRROR] = 0 # Boolean
|
||||
|
||||
default_frame[AnimFrame::FOCUS] = 4 # 1=target, 2=user, 3=user and target, 4=screen
|
||||
|
||||
default_frame[99] = anim.graphic
|
||||
|
||||
last_frame_values = []
|
||||
# Go through each frame
|
||||
anim.length.times do |frame_num|
|
||||
frame = anim[frame_num]
|
||||
had_particles = []
|
||||
changed_particles = []
|
||||
frame.each_with_index do |cel, i|
|
||||
next if !cel
|
||||
# If the particle from the previous frame for this cel had a different
|
||||
# focus, start a new particle.
|
||||
if i > 1 && frame_num > 0 && index_lookup[i] && index_lookup[i] >= 0 &&
|
||||
last_frame_values[index_lookup[i]]
|
||||
this_graphic = (cel[AnimFrame::PATTERN] == -1) ? "USER" : (cel[AnimFrame::PATTERN] == -2) ? "TARGET" : anim.graphic
|
||||
if last_frame_values[index_lookup[i]][AnimFrame::FOCUS] != cel[AnimFrame::FOCUS] ||
|
||||
last_frame_values[index_lookup[i]][99] != this_graphic # Graphic
|
||||
index_lookup[i] = -1
|
||||
end
|
||||
end
|
||||
# Get the particle index for this cel
|
||||
if !index_lookup[i] || index_lookup[i] < 0
|
||||
max_index += 1
|
||||
index_lookup[i] = max_index
|
||||
end
|
||||
idx = index_lookup[i]
|
||||
had_particles.push(idx)
|
||||
# i=0 for "User", i=1 for "Target"
|
||||
hash[:particles][i] ||= {
|
||||
:name => "Particle #{i}"
|
||||
}
|
||||
particle = hash[:particles][i]
|
||||
if i == 0
|
||||
hash[:particles][idx] ||= { :name => "Particle #{idx}" }
|
||||
particle = hash[:particles][idx]
|
||||
last_frame = last_frame_values[idx] || default_frame.clone
|
||||
# User and target particles have specific names
|
||||
if idx == 0
|
||||
particle[:name] = "User"
|
||||
elsif i == 1
|
||||
elsif idx == 1
|
||||
particle[:name] = "Target"
|
||||
else
|
||||
# Set graphic
|
||||
case cel[AnimFrame::PATTERN]
|
||||
when -1 # User's sprite
|
||||
particle[:graphic] = "USER"
|
||||
last_frame[99] = "USER"
|
||||
when -2 # Target's sprite
|
||||
particle[:graphic] = "TARGET"
|
||||
last_frame[99] = "TARGET"
|
||||
else
|
||||
particle[:graphic] = anim.graphic
|
||||
last_frame[99] = anim.graphic
|
||||
end
|
||||
end
|
||||
# Set focus for non-User/non-Target
|
||||
if idx > 1
|
||||
particle[:focus] = [:foreground, :target, :user, :user_and_target, :foreground][cel[AnimFrame::FOCUS]]
|
||||
last_frame[AnimFrame::FOCUS] = cel[AnimFrame::FOCUS]
|
||||
end
|
||||
|
||||
last_frame = last_frame_values[i] || default_frame.clone
|
||||
# Copy commands across
|
||||
[
|
||||
[AnimFrame::X, :x],
|
||||
@@ -118,25 +165,182 @@ module AnimationConverter
|
||||
[AnimFrame::TONEGREEN, :tone_green],
|
||||
[AnimFrame::TONEBLUE, :tone_blue],
|
||||
[AnimFrame::TONEGRAY, :tone_gray],
|
||||
[AnimFrame::PATTERN, :frame],
|
||||
[AnimFrame::PRIORITY, :z],
|
||||
[AnimFrame::VISIBLE, :visible], # Boolean
|
||||
[AnimFrame::MIRROR, :flip], # Boolean
|
||||
].each do |property|
|
||||
next if cel[property[0]] == last_frame[property[0]]
|
||||
particle[property[1]] ||= []
|
||||
val = cel[property[0]].to_i
|
||||
val = (val == 1) if [:visible, :flip].include?(property[1])
|
||||
case property[1]
|
||||
when :x
|
||||
# TODO: What if the animation is an OppMove one? I think this should
|
||||
# be the other way around.
|
||||
if particle[:focus] == :user_and_target
|
||||
fraction = (val - Battle::Scene::FOCUSUSER_X).to_f / (Battle::Scene::FOCUSTARGET_X - Battle::Scene::FOCUSUSER_X)
|
||||
val = (fraction * GameData::Animation::USER_AND_TARGET_SEPARATION[0]).to_i
|
||||
end
|
||||
when :y
|
||||
# TODO: What if the animation is an OppMove one? I think this should
|
||||
# be the other way around.
|
||||
if particle[:focus] == :user_and_target
|
||||
fraction = (val - Battle::Scene::FOCUSUSER_Y).to_f / (Battle::Scene::FOCUSTARGET_Y - Battle::Scene::FOCUSUSER_Y)
|
||||
val = (fraction * GameData::Animation::USER_AND_TARGET_SEPARATION[1]).to_i
|
||||
end
|
||||
when :visible, :flip
|
||||
val = (val == 1) # Boolean
|
||||
when :z
|
||||
next if idx <= 1 # User or target
|
||||
case val
|
||||
when 0 then val = -50 + i # Back
|
||||
when 1 then val = 25 + i # Front
|
||||
when 2 then val = -25 + i # Behind focus
|
||||
when 3 then val = i # Before focus
|
||||
end
|
||||
when :frame
|
||||
next if val < 0 # -1 is user, -2 is target
|
||||
end
|
||||
# TODO: Come up with a better way to set a particle's graphic being
|
||||
# the user or target. Probably can't, due to overlapping cel
|
||||
# numbers and user/target being the :graphic property which
|
||||
# doesn't change.
|
||||
particle[property[1]].push([frame_num, 0, val])
|
||||
last_frame[property[0]] = cel[property[0]]
|
||||
end
|
||||
# Set graphic
|
||||
particle[:graphic] = anim.graphic
|
||||
# Set focus for non-User/non-Target
|
||||
if i > 1
|
||||
particle[:focus] = [:screen, :target, :user, :user_and_target, :screen][cel[AnimFrame::FOCUS]]
|
||||
changed_particles.push(idx) if !changed_particles.include?(idx)
|
||||
end
|
||||
# Remember this cel's values at this frame
|
||||
last_frame_values[i] = last_frame
|
||||
last_frame_values[idx] = last_frame
|
||||
end
|
||||
# End every particle lifetime that didn't have a corresponding cel this
|
||||
# frame
|
||||
hash[:particles].each_with_index do |particle, idx|
|
||||
next if !particle || had_particles.include?(idx)
|
||||
next if ["User", "Target"].include?(particle[:name])
|
||||
if last_frame_values[idx][AnimFrame::VISIBLE] == 1
|
||||
particle[:visible] ||= []
|
||||
particle[:visible].push([frame_num, 0, false])
|
||||
changed_particles.push(idx) if !changed_particles.include?(idx)
|
||||
end
|
||||
last_frame_values[idx][AnimFrame::VISIBLE] = 0
|
||||
next if !index_lookup.include?(idx)
|
||||
lookup_idx = index_lookup.index(idx)
|
||||
index_lookup[lookup_idx] = -1
|
||||
end
|
||||
# Add a dummy command to the user particle in the last frame if that frame
|
||||
# doesn't have any commands
|
||||
if frame_num == anim.length - 1 && changed_particles.empty?
|
||||
hash[:particles].each_with_index do |particle, idx|
|
||||
next if !particle || idx <= 1 # User or target
|
||||
# TODO: Making all non-user non-target particles invisible in the last
|
||||
# frame isn't a perfect solution, but it's good enough to get
|
||||
# example animation data.
|
||||
next if last_frame_values[idx][AnimFrame::VISIBLE] == 0
|
||||
particle[:visible] ||= []
|
||||
particle[:visible].push([frame_num + 1, 0, false])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hash[:particles][0][:focus] = :user
|
||||
hash[:particles][1][:focus] = :target
|
||||
|
||||
# Adjust all x/y positions based on particle[:focus]
|
||||
hash[:particles].each do |particle|
|
||||
next if !particle
|
||||
offset_x = 0
|
||||
offset_y = 0
|
||||
case particle[:focus]
|
||||
when :user
|
||||
offset_x = -Battle::Scene::FOCUSUSER_X
|
||||
offset_y = -Battle::Scene::FOCUSUSER_Y
|
||||
when :target
|
||||
offset_x = -Battle::Scene::FOCUSTARGET_X
|
||||
offset_y = -Battle::Scene::FOCUSTARGET_Y
|
||||
when :user_and_target
|
||||
# NOTE: No change, done above.
|
||||
end
|
||||
next if offset_x == 0 && offset_y == 0
|
||||
particle[:x].each { |cmd| cmd[2] += offset_x }
|
||||
particle[:y].each { |cmd| cmd[2] += offset_y }
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: Haven't tested this as no Essentials animations use them.
|
||||
def add_bg_fg_commands_to_new_anim_hash(anim, new_anim)
|
||||
bg_particle = { :name => "Background", :focus => :background }
|
||||
fg_particle = { :name => "Foreground", :focus => :foreground }
|
||||
first_bg_frame = 999
|
||||
first_fg_frame = 999
|
||||
anim.timing.each do |cmd|
|
||||
case cmd.timingType
|
||||
when 1, 2, 3, 4 # BG graphic (set, move/recolour), FG graphic (set, move/recolour)
|
||||
is_bg = (cmd.timingType <= 2)
|
||||
particle = (is_bg) ? bg_particle : fg_particle
|
||||
duration = (cmd.timingType == 2) ? cmd.duration : 0
|
||||
added = false
|
||||
if cmd.name && cmd.name != ""
|
||||
particle[:graphic] ||= []
|
||||
particle[:graphic].push([cmd.frame, duration, cmd.name])
|
||||
added = true
|
||||
end
|
||||
if cmd.colorRed
|
||||
particle[:color_red] ||= []
|
||||
particle[:color_red].push([cmd.frame, duration, cmd.colorRed])
|
||||
added = true
|
||||
end
|
||||
if cmd.colorGreen
|
||||
particle[:color_green] ||= []
|
||||
particle[:color_green].push([cmd.frame, duration, cmd.colorGreen])
|
||||
added = true
|
||||
end
|
||||
if cmd.colorBlue
|
||||
particle[:color_blue] ||= []
|
||||
particle[:color_blue].push([cmd.frame, duration, cmd.colorBlue])
|
||||
added = true
|
||||
end
|
||||
if cmd.colorAlpha
|
||||
particle[:color_alpha] ||= []
|
||||
particle[:color_alpha].push([cmd.frame, duration, cmd.colorAlpha])
|
||||
added = true
|
||||
end
|
||||
if cmd.opacity
|
||||
particle[:opacity] ||= []
|
||||
particle[:opacity].push([cmd.frame, duration, cmd.opacity])
|
||||
added = true
|
||||
end
|
||||
if cmd.bgX
|
||||
particle[:x] ||= []
|
||||
particle[:x].push([cmd.frame, duration, cmd.bgX])
|
||||
added = true
|
||||
end
|
||||
if cmd.bgY
|
||||
particle[:y] ||= []
|
||||
particle[:y].push([cmd.frame, duration, cmd.bgY])
|
||||
added = true
|
||||
end
|
||||
if added
|
||||
if is_bg
|
||||
first_bg_frame = [first_bg_frame, cmd.frame].min
|
||||
else
|
||||
first_fg_frame = [first_fg_frame, cmd.frame].min
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if bg_particle.keys.length > 2
|
||||
if !bg_particle[:graphic]
|
||||
particle[:graphic] ||= []
|
||||
particle[:graphic].push([first_bg_frame, 0, "black_screen"])
|
||||
end
|
||||
new_anim[:particles].push(bg_particle)
|
||||
end
|
||||
if fg_particle.keys.length > 2
|
||||
if !fg_particle[:graphic]
|
||||
particle[:graphic] ||= []
|
||||
particle[:graphic].push([first_fg_frame, 0, "black_screen"])
|
||||
end
|
||||
new_anim[:particles].push(fg_particle)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user