From 5495bf565c6ac68f42908b0d620017c8c0409ad0 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sat, 11 May 2024 00:33:56 +0100 Subject: [PATCH] Anim Editor: Added smart angle property to particles --- .../902_Anim GameData/001_Animation.rb | 13 +- .../903_Anim Compiler/001_Anim compiler.rb | 8 ++ .../003_AnimationEditor_side_panes.rb | 22 +++ .../Anim Editor elements/001_Canvas.rb | 18 ++- .../905_Anim player/001_Anim player.rb | 11 ++ .../905_Anim player/002_ParticleSprite.rb | 26 +++- .../905_Anim player/003_AnimPlayerHelper.rb | 44 +++++- PBS/Animations/Bug/Twineedle.txt | 84 +++++++++++ .../Example anims/Move/MACHPUNCH.txt | 80 ----------- .../Example anims/Move/TWINEEDLE.txt | 135 ------------------ PBS/Animations/Fighting/Mach Punch.txt | 107 ++++++++++++++ 11 files changed, 329 insertions(+), 219 deletions(-) create mode 100644 PBS/Animations/Bug/Twineedle.txt delete mode 100644 PBS/Animations/Example anims/Move/MACHPUNCH.txt delete mode 100644 PBS/Animations/Example anims/Move/TWINEEDLE.txt create mode 100644 PBS/Animations/Fighting/Mach Punch.txt diff --git a/Data/Scripts/902_Anim GameData/001_Animation.rb b/Data/Scripts/902_Anim GameData/001_Animation.rb index d0cc4320b..47bd02983 100644 --- a/Data/Scripts/902_Anim GameData/001_Animation.rb +++ b/Data/Scripts/902_Anim GameData/001_Animation.rb @@ -50,6 +50,11 @@ module GameData "RandomDirectionGravity" => :random_direction_gravity, "RandomUpDirectionGravity" => :random_up_direction_gravity } + ANGLE_OVERRIDES = { + "None" => :none, + "InitialAngleToFocus" => :initial_angle_to_focus, + "AlwaysPointAtFocus" => :always_point_at_focus + } # Properties that apply to the animation in general, not to individual # particles. They don't change during the animation. @@ -76,6 +81,7 @@ module GameData "Spawner" => [:spawner, "e", SPAWNER_TYPES], "SpawnQuantity" => [:spawn_quantity, "v"], "RandomFrameMax" => [:random_frame_max, "u"], + "AngleOverride" => [:angle_override, "e", ANGLE_OVERRIDES], # 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" @@ -129,7 +135,8 @@ module GameData :foe_flip => false, :spawner => :none, :spawn_quantity => 1, - :random_frame_max => 0 + :random_frame_max => 0, + :angle_override => :none } # NOTE: Particles are invisible until their first command, and automatically @@ -335,6 +342,10 @@ module GameData ret = nil if ret && ret <= 1 when "RandomFrameMax" ret = nil if ret == 0 + when "AngleOverride" + ret = nil if ret == :none + ret = nil if !FOCUS_TYPES_WITH_USER.include?(@particles[index][:focus]) && + !FOCUS_TYPES_WITH_TARGET.include?(@particles[index][:focus]) when "AllCommands" # Get translations of all properties to their names as seen in PBS # animation files diff --git a/Data/Scripts/903_Anim Compiler/001_Anim compiler.rb b/Data/Scripts/903_Anim Compiler/001_Anim compiler.rb index 5a6a1c053..efbe5f5a6 100644 --- a/Data/Scripts/903_Anim Compiler/001_Anim compiler.rb +++ b/Data/Scripts/903_Anim Compiler/001_Anim compiler.rb @@ -203,6 +203,14 @@ module Compiler particle[:name]) + "\n" + FileLineData.linereport end end + # Ensure that only particles that have an entity as a focus can have a + # smart angle + if (particle[:angle_override] || :none) != :none && + !GameData::Animation::FOCUS_TYPES_WITH_USER.include?(particle[:focus]) && + !GameData::Animation::FOCUS_TYPES_WITH_TARGET.include?(particle[:focus]) + raise _INTL("Particle \"{1}\" can't set \"AngleOverride\" if its focus isn't a specific thing(s).", + particle[:name]) + "\n" + FileLineData.linereport + 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]) && 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 43baad314..74814ba43 100644 --- a/Data/Scripts/904_Anim Editor/003_AnimationEditor_side_panes.rb +++ b/Data/Scripts/904_Anim Editor/003_AnimationEditor_side_panes.rb @@ -562,6 +562,28 @@ AnimationEditor::SidePanes.add_property(:particle_pane, :spawn_quantity, { } }) +AnimationEditor::SidePanes.add_property(:particle_pane, :angle_override, { + :new => proc { |pane, editor| + values = { + :none => _INTL("None"), + :initial_angle_to_focus => _INTL("Initial angle to focus"), + :always_point_at_focus => _INTL("Always point at focus") + } + pane.add_labelled_dropdown_list(:angle_override, _INTL("Smart angle"), values, :none) + }, + :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) + editor.anim[:particles][editor.particle_index][:angle_override] = :none + control.value = :none + control.disable + else + control.enable + end + } +}) + AnimationEditor::SidePanes.add_property(:particle_pane, :opposing_label, { :new => proc { |pane, editor| pane.add_label(:opposing_label, _INTL("If on opposing side...")) 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 921043987..d38645e59 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 @@ -497,7 +497,23 @@ class AnimationEditor::Canvas < Sprite # Set various other properties spr.zoom_x = values[:zoom_x] / 100.0 spr.zoom_y = values[:zoom_y] / 100.0 - spr.angle = values[:angle] + case particle[:angle_override] + when :initial_angle_to_focus + target_x = (focus_xy.length == 2) ? focus_xy[1][0] : focus_xy[0][0] + target_x += offset_xy[0] + target_y = (focus_xy.length == 2) ? focus_xy[1][1] : focus_xy[0][1] + target_y += offset_xy[1] + spr.angle = AnimationPlayer::Helper.initial_angle_between(particle, focus_xy, offset_xy) + when :always_point_at_focus + target_x = (focus_xy.length == 2) ? focus_xy[1][0] : focus_xy[0][0] + target_x += offset_xy[0] + target_y = (focus_xy.length == 2) ? focus_xy[1][1] : focus_xy[0][1] + target_y += offset_xy[1] + spr.angle = AnimationPlayer::Helper.angle_between(spr.x, spr.y, target_x, target_y) + else + spr.angle = 0 + end + 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] diff --git a/Data/Scripts/905_Anim player/001_Anim player.rb b/Data/Scripts/905_Anim player/001_Anim player.rb index 04e65b005..8d55a0e9e 100644 --- a/Data/Scripts/905_Anim player/001_Anim player.rb +++ b/Data/Scripts/905_Anim player/001_Anim player.rb @@ -127,6 +127,17 @@ class AnimationPlayer particle_sprite.foe_invert_y = particle[:foe_invert_y] particle_sprite.foe_flip = particle[:foe_flip] end + particle_sprite.base_angle = 0 + case particle[:angle_override] + when :initial_angle_to_focus + target_x = (focus_xy.length == 2) ? focus_xy[1][0] : focus_xy[0][0] + target_x += offset_xy[0] + target_y = (focus_xy.length == 2) ? focus_xy[1][1] : focus_xy[0][1] + target_y += offset_xy[1] + particle_sprite.base_angle = AnimationPlayer::Helper.initial_angle_between(particle, focus_xy, offset_xy) + when :always_point_at_focus + particle_sprite.angle_override = particle[:angle_override] if relative_to_index >= 0 + end # Find earliest command and add a "make visible" command then delay = AnimationPlayer::Helper.get_particle_delay(particle, instance) if sprite && !particle_sprite.battler_sprite? diff --git a/Data/Scripts/905_Anim player/002_ParticleSprite.rb b/Data/Scripts/905_Anim player/002_ParticleSprite.rb index 486b0847d..4dd90206f 100644 --- a/Data/Scripts/905_Anim player/002_ParticleSprite.rb +++ b/Data/Scripts/905_Anim player/002_ParticleSprite.rb @@ -5,6 +5,7 @@ class AnimationPlayer::ParticleSprite attr_accessor :sprite attr_accessor :focus_xy, :offset_xy, :focus_z + attr_accessor :base_angle, :angle_override attr_accessor :foe_invert_x, :foe_invert_y, :foe_flip FRAMES_PER_SECOND = 20.0 @@ -109,16 +110,24 @@ class AnimationPlayer::ParticleSprite value *= -1 if @foe_invert_x AnimationPlayer::Helper.apply_xy_focus_to_sprite(@sprite, :x, value, @focus_xy) @sprite.x += @offset_xy[0] + update_angle_pointing_at_focus when :y value = value.round value *= -1 if @foe_invert_y AnimationPlayer::Helper.apply_xy_focus_to_sprite(@sprite, :y, value, @focus_xy) @sprite.y += @offset_xy[1] + update_angle_pointing_at_focus when :z AnimationPlayer::Helper.apply_z_focus_to_sprite(@sprite, value, @focus_z) when :zoom_x then @sprite.zoom_x = value / 100.0 when :zoom_y then @sprite.zoom_y = value / 100.0 - when :angle then @sprite.angle = value + when :angle + if @angle_override == :always_point_at_focus + update_angle_pointing_at_focus + @sprite.angle += value + else + @sprite.angle = value + (@base_angle || 0) + end when :visible then @sprite.visible = value when :opacity then @sprite.opacity = value when :color_red then @sprite.color.red = value @@ -132,6 +141,21 @@ class AnimationPlayer::ParticleSprite end end + # This assumes vertically up is an angle of 0, and the angle increases + # anticlockwise. + def update_angle_pointing_at_focus + return if @angle_override != :always_point_at_focus + # Get coordinates + sprite_x = @sprite.x + sprite_y = @sprite.y + target_x = (@focus_xy.length == 2) ? @focus_xy[1][0] : @focus_xy[0][0] + target_x += @offset_xy[0] + target_y = (@focus_xy.length == 2) ? @focus_xy[1][1] : @focus_xy[0][1] + target_y += @offset_xy[1] + @sprite.angle = AnimationPlayer::Helper.angle_between(sprite_x, sprite_y, target_x, target_y) + @sprite.angle += (@base_angle || 0) + end + def update(elapsed_time) frame = (elapsed_time * FRAMES_PER_SECOND).floor changed_properties = [] diff --git a/Data/Scripts/905_Anim player/003_AnimPlayerHelper.rb b/Data/Scripts/905_Anim player/003_AnimPlayerHelper.rb index 74283bc5f..3c2f2854b 100644 --- a/Data/Scripts/905_Anim player/003_AnimPlayerHelper.rb +++ b/Data/Scripts/905_Anim player/003_AnimPlayerHelper.rb @@ -77,7 +77,7 @@ module AnimationPlayer::Helper when :user_side_foreground, :user_side_background ret = [Battle::Scene.pbBattlerPosition(user_index)] when :target_side_foreground, :target_side_background - ret = [Battle::Scene.pbBattlerPosition(target_idx)] + ret = [Battle::Scene.pbBattlerPosition(target_index)] end return ret end @@ -168,6 +168,48 @@ module AnimationPlayer::Helper #----------------------------------------------------------------------------- + def angle_between(x1, y1, x2, y2) + diff_x = x1 - x2 + diff_y = y1 - y2 + ret = Math.atan(diff_x.to_f / diff_y) * 180 / Math::PI + ret += 180 if diff_y < 0 + return ret + end + + def initial_angle_between(particle, focus, offset) + x1 = 0 + y1 = 0 + x2 = (focus.length == 2) ? focus[1][0] : focus[0][0] + y2 = (focus.length == 2) ? focus[1][1] : focus[0][1] + [:x, :y].each do |property| + next if !particle[property] + particle[property].each do |cmd| + break if cmd[1] > 0 + if property == :x + x1 = cmd[2] + else + y1 = cmd[2] + end + break + end + end + if focus + if focus.length == 2 + distance = GameData::Animation::USER_AND_TARGET_SEPARATION + x1 = focus[0][0] + ((x1.to_f / distance[0]) * (focus[1][0] - focus[0][0])).to_i + y1 = focus[0][1] + ((y1.to_f / distance[1]) * (focus[1][1] - focus[0][1])).to_i + else + x1 += focus[0][0] + y1 += focus[0][1] + end + end + x1 += offset[0] + y1 += offset[1] + return angle_between(x1, y1, x2, y2) + end + + #----------------------------------------------------------------------------- + # user_sprites, target_sprites = [front sprite, back sprite] def set_bitmap_and_origin(particle, sprite, user_index, target_index, user_sprites, target_sprites) return if sprite&.is_a?(Battle::Scene::BattlerSprite) diff --git a/PBS/Animations/Bug/Twineedle.txt b/PBS/Animations/Bug/Twineedle.txt new file mode 100644 index 000000000..9222b44bc --- /dev/null +++ b/PBS/Animations/Bug/Twineedle.txt @@ -0,0 +1,84 @@ +# See the documentation on the wiki to learn how to edit this file. +#------------------------------- +[Move,TWINEEDLE] +Name = Essentials + + FoeInvertX = true + FoeInvertY = true + MoveX = 0,1,28 + MoveY = 0,1,-16 + MoveX = 3,1,0 + MoveY = 3,1,0 + + FoeInvertX = true + MoveX = 9,1,-2 + MoveColorRed = 9,8,160 + MoveColorGreen = 9,8,32 + MoveColorBlue = 9,8,248 + MoveColorAlpha = 9,8,160 + MoveX = 10,2,2 + MoveX = 12,2,-2 + MoveX = 14,2,2 + MoveX = 16,1,0 + MoveColorRed = 19,6,0 + MoveColorGreen = 19,6,0 + MoveColorBlue = 19,6,0 + MoveColorAlpha = 19,6,0 + + Graphic = Bug/Twineedle needle + Focus = UserAndTarget + AngleOverride = InitialAngleToFocus + SetZ = 4,-50 + SetZoomX = 4,50 + SetZoomY = 4,80 + SetColorRed = 4,160 + SetColorGreen = 4,32 + SetColorBlue = 4,192 + SetColorAlpha = 4,128 + MoveX = 4,7,200 + MoveY = 4,7,-180 + SetVisible = 11,false + + Graphic = Bug/Twineedle hit + Focus = Target + SetY = 11,16 + SetZ = 11,10 + SetZoomX = 11,0 + SetZoomY = 11,0 + MoveZoomX = 11,3,50 + MoveZoomY = 11,3,50 + SetColorRed = 13,248 + SetColorBlue = 13,248 + SetColorAlpha = 13,255 + MoveOpacity = 13,3,0 + SetVisible = 16,false + + Graphic = Bug/Twineedle needle + Focus = UserAndTarget + AngleOverride = InitialAngleToFocus + SetZ = 7,-50 + SetZoomX = 7,50 + SetZoomY = 7,80 + SetColorRed = 7,160 + SetColorGreen = 7,32 + SetColorBlue = 7,192 + SetColorAlpha = 7,128 + MoveX = 7,6,200 + MoveY = 7,6,-200 + SetVisible = 13,false + + Graphic = Bug/Twineedle hit + Focus = Target + SetX = 13,-8 + SetZ = 13,10 + SetZoomX = 13,0 + SetZoomY = 13,0 + MoveZoomX = 13,3,50 + MoveZoomY = 13,3,50 + SetColorRed = 15,248 + SetColorBlue = 15,248 + SetColorAlpha = 15,255 + MoveOpacity = 15,3,0 + SetVisible = 18,false + + Play = 0,Bug/Twineedle diff --git a/PBS/Animations/Example anims/Move/MACHPUNCH.txt b/PBS/Animations/Example anims/Move/MACHPUNCH.txt deleted file mode 100644 index fd434ee84..000000000 --- a/PBS/Animations/Example anims/Move/MACHPUNCH.txt +++ /dev/null @@ -1,80 +0,0 @@ -# See the documentation on the wiki to learn how to edit this file. -#------------------------------- -[Move,MACHPUNCH] -Name = Example anim - - SetX = 0,0 - SetY = 0,0 - - SetX = 0,0 - SetY = 0,0 - - Graphic = Examples/punches - Focus = Target - SetFrame = 2,5 - SetX = 2,15 - SetY = 2,-1 - SetZ = 2,28 - SetVisible = 3,false - - Graphic = Examples/punches - Focus = Target - SetFrame = 0,5 - SetX = 0,19 - SetY = 0,1 - SetZ = 0,27 - SetZoomX = 0,80 - SetZoomY = 0,80 - SetX = 1,16 - SetY = 1,0 - SetZoomX = 1,90 - SetZoomY = 1,90 - SetFrame = 2,7 - SetX = 2,4 - SetY = 2,-6 - SetZoomX = 2,100 - SetZoomY = 2,100 - SetFrame = 3,5 - SetX = 3,19 - SetY = 3,-1 - SetZoomX = 3,110 - SetZoomY = 3,110 - SetY = 4,-4 - SetZoomX = 4,120 - SetZoomY = 4,120 - SetX = 5,18 - SetZoomX = 5,130 - SetZoomY = 5,130 - SetX = 6,20 - SetY = 6,-6 - SetZoomX = 6,140 - SetZoomY = 6,140 - SetX = 7,17 - SetY = 7,-8 - SetZoomX = 7,160 - SetZoomY = 7,160 - SetX = 8,15 - SetZoomX = 8,170 - SetZoomY = 8,170 - SetX = 9,17 - SetY = 9,-11 - SetZoomX = 9,180 - SetZoomY = 9,180 - SetOpacity = 9,220 - SetY = 10,-7 - SetZoomX = 10,190 - SetZoomY = 10,190 - SetOpacity = 10,200 - SetX = 11,22 - SetY = 11,-6 - SetZoomX = 11,220 - SetZoomY = 11,220 - SetOpacity = 11,130 - SetX = 12,31 - SetY = 12,0 - SetZoomX = 12,250 - SetZoomY = 12,250 - SetOpacity = 12,100 - SetVisible = 13,false - - Play = 0,Mega Punch,100,94 diff --git a/PBS/Animations/Example anims/Move/TWINEEDLE.txt b/PBS/Animations/Example anims/Move/TWINEEDLE.txt deleted file mode 100644 index 050e156ed..000000000 --- a/PBS/Animations/Example anims/Move/TWINEEDLE.txt +++ /dev/null @@ -1,135 +0,0 @@ -# See the documentation on the wiki to learn how to edit this file. -#------------------------------- -[Move,TWINEEDLE] -Name = Example anim - - SetX = 0,0 - SetY = 0,0 - - SetX = 0,0 - SetY = 0,0 - - Graphic = Examples/poison3 - Focus = UserAndTarget - SetFrame = 4,14 - SetX = 4,184 - SetY = 4,-187 - SetZ = 4,29 - SetOpacity = 4,50 - SetX = 5,209 - SetY = 5,-168 - SetVisible = 6,false - - Graphic = Examples/poison3 - Focus = UserAndTarget - SetX = 0,0 - SetY = 0,-50 - SetZ = 0,27 - SetX = 1,44 - SetY = 1,-79 - SetX = 2,100 - SetY = 2,-109 - SetX = 3,134 - SetY = 3,-148 - SetX = 4,179 - SetY = 4,-168 - SetX = 5,204 - SetY = 5,-148 - SetFrame = 6,14 - SetX = 6,209 - SetY = 6,-168 - SetZoomX = 6,125 - SetZoomY = 6,125 - SetOpacity = 6,50 - SetVisible = 7,false - - Graphic = Examples/poison3 - Focus = UserAndTarget - SetX = 1,44 - SetY = 1,-10 - SetZ = 1,28 - SetX = 2,100 - SetY = 2,-40 - SetX = 3,139 - SetY = 3,-79 - SetX = 4,184 - SetY = 4,-109 - SetFrame = 5,14 - SetX = 5,189 - SetY = 5,-187 - SetZoomX = 5,125 - SetZoomY = 5,125 - SetOpacity = 5,50 - SetVisible = 6,false - - Play = 0,throw,80 - Play = 2,throw,80 - Play = 4,Slash10,80 - Play = 6,Slash10,80 -#------------------------------- -[Move,TWINEEDLE,1] -Name = Example anim - - SetX = 0,0 - SetY = 0,0 - - SetX = 0,0 - SetY = 0,0 - - Graphic = Examples/poison3 - Focus = UserAndTarget - SetX = 1,44 - SetY = 1,-10 - SetZ = 1,28 - SetX = 2,100 - SetY = 2,-40 - SetX = 3,139 - SetY = 3,-79 - SetX = 4,184 - SetY = 4,-109 - SetFrame = 5,14 - SetX = 5,189 - SetY = 5,-187 - SetZoomX = 5,125 - SetZoomY = 5,125 - SetOpacity = 5,50 - SetVisible = 6,false - - Graphic = Examples/poison3 - Focus = UserAndTarget - SetFrame = 4,14 - SetX = 4,184 - SetY = 4,-187 - SetZ = 4,29 - SetOpacity = 4,50 - SetX = 5,209 - SetY = 5,-168 - SetVisible = 6,false - - Graphic = Examples/poison3 - Focus = UserAndTarget - SetX = 0,0 - SetY = 0,-50 - SetZ = 0,27 - SetX = 1,44 - SetY = 1,-79 - SetX = 2,100 - SetY = 2,-109 - SetX = 3,134 - SetY = 3,-148 - SetX = 4,179 - SetY = 4,-168 - SetX = 5,204 - SetY = 5,-148 - SetFrame = 6,14 - SetX = 6,209 - SetY = 6,-168 - SetZoomX = 6,125 - SetZoomY = 6,125 - SetOpacity = 6,50 - SetVisible = 7,false - - Play = 0,throw,80 - Play = 2,throw,80 - Play = 4,Slash10,80 - Play = 6,Slash10,80 diff --git a/PBS/Animations/Fighting/Mach Punch.txt b/PBS/Animations/Fighting/Mach Punch.txt new file mode 100644 index 000000000..ce0bcdb6e --- /dev/null +++ b/PBS/Animations/Fighting/Mach Punch.txt @@ -0,0 +1,107 @@ +# See the documentation on the wiki to learn how to edit this file. +#------------------------------- +[Move,MACHPUNCH] +Name = Essentials +NoUser = true + + FoeInvertX = true + MoveX = 14,1,-2 + MoveX = 15,2,2 + MoveX = 17,2,-2 + MoveX = 19,2,2 + MoveX = 21,1,0 + + Graphic = Fighting/Mach Punch fist + Focus = Target + SetZ = 0,30 + SetZoomX = 0,600 + SetZoomY = 0,600 + MoveZoomX = 0,4,150 + MoveZoomY = 0,4,150 + MoveAngle = 0,4,30 + SetVisible = 4,false + + Graphic = Fighting/Mach Punch fist + Focus = Target + SetZ = 0,15 + SetZoomX = 0,600 + SetZoomY = 0,600 + SetColorRed = 0,192 + SetColorBlue = 0,128 + SetColorAlpha = 0,128 + MoveZoomX = 0,5,500 + MoveZoomY = 0,5,500 + MoveOpacity = 0,5,0 + MoveColorRed = 0,5,0 + MoveColorBlue = 0,5,0 + SetVisible = 5,false + + Graphic = Fighting/Mach Punch fist + Focus = Target + SetZ = 0,20 + SetZoomX = 0,450 + SetZoomY = 0,450 + SetColorRed = 0,144 + SetColorBlue = 0,96 + SetColorAlpha = 0,128 + MoveZoomX = 0,7,325 + MoveZoomY = 0,7,325 + MoveOpacity = 0,7,0 + MoveColorRed = 1,6,0 + MoveColorBlue = 1,6,0 + SetVisible = 7,false + + Graphic = Fighting/Mach Punch fist + Focus = Target + SetZ = 0,25 + SetZoomX = 0,300 + SetZoomY = 0,300 + SetColorRed = 0,96 + SetColorBlue = 0,64 + SetColorAlpha = 0,128 + MoveZoomX = 0,8,150 + MoveZoomY = 0,8,150 + MoveOpacity = 0,8,0 + MoveColorRed = 2,6,0 + MoveColorBlue = 2,6,0 + SetVisible = 8,false + + Graphic = Fighting/Mach Punch hit + Focus = Target + SetZ = 4,5 + SetZoomX = 4,60 + SetZoomY = 4,60 + SetColorRed = 4,128 + SetColorGreen = 4,128 + SetColorBlue = 4,248 + SetColorAlpha = 4,128 + MoveZoomX = 4,4,150 + MoveZoomY = 4,4,150 + MoveOpacity = 6,2,0 + SetVisible = 8,false + + Graphic = Fighting/Mach Punch hit + Focus = Target + SetZ = 4,10 + SetZoomX = 4,50 + SetZoomY = 4,50 + MoveZoomX = 4,4,130 + MoveZoomY = 4,4,130 + MoveOpacity = 6,2,0 + SetVisible = 8,false + + Graphic = Fighting/Mach Punch spark + Focus = Target + Spawner = RandomDirection + SpawnQuantity = 12 + SetZ = 5,4 + SetZoomX = 5,50 + SetZoomY = 5,50 + SetOpacity = 5,0 + MoveOpacity = 5,1,255 + SetFrame = 7,1 + MoveZoomX = 9,6,0 + MoveZoomY = 9,6,0 + SetVisible = 15,false + + Play = 0,Fighting/Mach Punch