From 15e70fa67e64260499c5fdb1f9179e331d526193 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Tue, 22 Feb 2022 22:34:28 +0000 Subject: [PATCH] Added a battle transition for Team Rocket Grunts --- Data/Scripts/009_Scenes/001_Transitions.rb | 88 +++++++++++++++ .../002_Overworld_BattleIntroAnim.rb | 103 ++++++++++++------ 2 files changed, 158 insertions(+), 33 deletions(-) diff --git a/Data/Scripts/009_Scenes/001_Transitions.rb b/Data/Scripts/009_Scenes/001_Transitions.rb index f8a620b48..d67c913a1 100644 --- a/Data/Scripts/009_Scenes/001_Transitions.rb +++ b/Data/Scripts/009_Scenes/001_Transitions.rb @@ -82,6 +82,7 @@ module Graphics when "wavythreeballup" then @@transition = Transitions::WavyThreeBallUp.new(duration) when "wavyspinball" then @@transition = Transitions::WavySpinBall.new(duration) when "fourballburst" then @@transition = Transitions::FourBallBurst.new(duration) + when "rocketgrunt" then @@transition = Transitions::RocketGrunt.new(duration) # Graphic transitions when "fadetoblack" then @@transition = Transitions::FadeToBlack.new(duration) when "fadefromblack" then @@transition = Transitions::FadeFromBlack.new(duration) @@ -1224,4 +1225,91 @@ module Transitions end end end + + #============================================================================= + # HGSS Rocket Grunt trainer(s) + #============================================================================= + class RocketGrunt < Transition_Base + DURATION = 1.6 + ROCKET_X = [ 1.5, -0.5, -0.5, 0.75, 1.5, -0.5] # * Graphics.width + ROCKET_Y = [-0.5, 1.0, -0.5, 1.5, 0.5, 0.75] # * Graphics.height + ROCKET_ANGLE = [ 1, 0.5, -1.5, -1, -1.5, 0.5] # * 360 * sprite.zoom_x + + def initialize_bitmaps + @black_1_bitmap = RPG::Cache.transition("black_wedge_1") + @black_2_bitmap = RPG::Cache.transition("black_wedge_2") + @black_3_bitmap = RPG::Cache.transition("black_wedge_3") + @black_4_bitmap = RPG::Cache.transition("black_wedge_4") + @rocket_bitmap = RPG::Cache.transition("rocket_logo") + dispose if !@black_1_bitmap || !@black_2_bitmap || !@black_3_bitmap || + !@black_4_bitmap || !@rocket_bitmap + end + + def initialize_sprites + # Rocket sprites + @rocket_sprites = [] + ROCKET_X.length.times do |i| + @rocket_sprites[i] = new_sprite( + ROCKET_X[i] * Graphics.width, ROCKET_Y[i] * Graphics.height, + @rocket_bitmap, @rocket_bitmap.width / 2, @rocket_bitmap.height / 2 + ) + end + # Black wedges + 4.times do |i| + b = [@black_1_bitmap, @black_2_bitmap, @black_3_bitmap, @black_4_bitmap][i] + @sprites[i] = new_sprite((i == 1) ? 0 : Graphics.width / 2, (i == 2) ? 0 : Graphics.height / 2, b, + (i.even?) ? b.width / 2 : 0, (i.even?) ? 0 : b.height / 2) + @sprites[i].zoom_x = 0.0 if i.even? + @sprites[i].zoom_y = 0.0 if i.odd? + @sprites[i].visible = false + end + end + + def set_up_timings + @rocket_appear_end = @duration * 0.75 + @rocket_appear_delay = 1.0 / (ROCKET_X.length + 1) + @rocket_appear_time = @rocket_appear_delay * 2 # 2 logos on screen at once + end + + def dispose_all + # Dispose sprites + @rocket_sprites.each { |s| s&.dispose } + @rocket_sprites.clear + # Dispose bitmaps + @black_1_bitmap&.dispose + @black_2_bitmap&.dispose + @black_3_bitmap&.dispose + @black_4_bitmap&.dispose + @rocket_bitmap&.dispose + end + + def update_anim + if @timer <= @rocket_appear_end + # Rocket logos fly in from edges of screen + proportion = @timer / @rocket_appear_end + @rocket_sprites.each_with_index do |sprite, i| + next if !sprite.visible + start_time = i * @rocket_appear_delay + next if proportion < start_time + single_proportion = (proportion - start_time) / @rocket_appear_time + sqrt_single_proportion = Math.sqrt(single_proportion) + sprite.x = (ROCKET_X[i] + (0.5 - ROCKET_X[i]) * sqrt_single_proportion) * Graphics.width + sprite.y = (ROCKET_Y[i] + (0.5 - ROCKET_Y[i]) * sqrt_single_proportion) * Graphics.height + sprite.zoom_x = 2.5 * (1 - single_proportion) + sprite.zoom_y = sprite.zoom_x + sprite.angle = sprite.zoom_x * ROCKET_ANGLE[i] * 360 + sprite.visible = false if sprite.zoom_x <= 0 + end + else + @rocket_sprites.last.visible = false + # Black wedges expand to fill screen + proportion = (@timer - @rocket_appear_end) / (@duration - @rocket_appear_end) + @sprites.each_with_index do |sprite, i| + sprite.visible = true + sprite.zoom_x = proportion if i.even? + sprite.zoom_y = proportion if i.odd? + end + end + end + end end diff --git a/Data/Scripts/012_Overworld/002_Battle triggering/002_Overworld_BattleIntroAnim.rb b/Data/Scripts/012_Overworld/002_Battle triggering/002_Overworld_BattleIntroAnim.rb index f43000f3a..7e4c88527 100644 --- a/Data/Scripts/012_Overworld/002_Battle triggering/002_Overworld_BattleIntroAnim.rb +++ b/Data/Scripts/012_Overworld/002_Battle triggering/002_Overworld_BattleIntroAnim.rb @@ -58,27 +58,28 @@ def pbBattleAnimation(bgm = nil, battletype = 0, foe = nil) # Play battle music bgm = pbGetWildBattleBGM([]) if !bgm pbBGMPlay(bgm) + # Determine location of battle + location = 0 # 0=outside, 1=inside, 2=cave, 3=water + if $PokemonGlobal.surfing || $PokemonGlobal.diving + location = 3 + elsif $game_temp.encounter_type && + GameData::EncounterType.get($game_temp.encounter_type).type == :fishing + location = 3 + elsif $PokemonEncounters.has_cave_encounters? + location = 2 + elsif !$game_map.metadata&.outdoor_map + location = 1 + end # Check for custom battle intro animations handled = false SpecialBattleIntroAnimations.each do |name, priority, condition, animation| - next if !condition.call(battletype, foe) - animation.call(viewport, battletype, foe) + next if !condition.call(battletype, foe, location) + animation.call(viewport, battletype, foe, location) handled = true end # Default battle intro animation if !handled # Determine which animation is played - location = 0 # 0=outside, 1=inside, 2=cave, 3=water - if $PokemonGlobal.surfing || $PokemonGlobal.diving - location = 3 - elsif $game_temp.encounter_type && - GameData::EncounterType.get($game_temp.encounter_type).type == :fishing - location = 3 - elsif $PokemonEncounters.has_cave_encounters? - location = 2 - elsif !$game_map.metadata&.outdoor_map - location = 1 - end anim = "" if PBDayNight.isDay? case battletype @@ -100,23 +101,21 @@ def pbBattleAnimation(bgm = nil, battletype = 0, foe = nil) end end # Initial screen flashing - if location == 2 || PBDayNight.isNight? - viewport.color = Color.new(0, 0, 0) # Fade to black a few times - else - viewport.color = Color.new(255, 255, 255) # Fade to white a few times - end - halfFlashTime = Graphics.frame_rate * 2 / 10 # 0.2 seconds, 8 frames - alphaDiff = (255.0 / halfFlashTime).ceil - 2.times do - viewport.color.alpha = 0 - (halfFlashTime * 2).times do |i| - if i < halfFlashTime - viewport.color.alpha += alphaDiff + c = (location == 2 || PBDayNight.isNight?) ? 0 : 255 # Dark=black, light=white + viewport.color = Color.new(c, c, c) # Fade to black/white a few times + half_flash_time = 0.2 # seconds + 2.times do # 2 flashes + timer = 0.0 + loop do + if timer < half_flash_time + viewport.color.alpha = 255 * timer / half_flash_time else - viewport.color.alpha -= alphaDiff + viewport.color.alpha = 255 * (2 - (timer / half_flash_time)) end + timer += Graphics.delta_s Graphics.update pbUpdateSceneMap + break if timer >= half_flash_time * 2 end end # Take screenshot of game, for use in some animations @@ -127,11 +126,7 @@ def pbBattleAnimation(bgm = nil, battletype = 0, foe = nil) viewport.color = Color.new(0, 0, 0, 255) # Ensure screen is black Graphics.transition(25, "Graphics/Transitions/" + anim) # Slight pause after animation before starting up the battle scene - (Graphics.frame_rate / 10).times do - Graphics.update - Input.update - pbUpdateSceneMap - end + pbWait(Graphics.frame_rate / 10) end pbPushFade # Yield to the battle scene @@ -180,7 +175,7 @@ end ##### VS. animation, by Luka S.J. ##### ##### Tweaked by Maruno ##### SpecialBattleIntroAnimations.register("vs_animation", 50, # Priority 50 - proc { |battle_type, foe| # Condition + proc { |battle_type, foe, location| # Condition next false unless [1, 3].include?(battle_type) && foe.length == 1 # Only if a single trainer tr_type = foe[0].trainer_type next false if !tr_type @@ -189,7 +184,7 @@ SpecialBattleIntroAnimations.register("vs_animation", 50, # Priority 50 next pbResolveBitmap("Graphics/Transitions/" + trainer_bar_graphic) && pbResolveBitmap("Graphics/Transitions/" + trainer_graphic) }, - proc { |viewport, battle_type, foe| # Animation + proc { |viewport, battle_type, foe, location| # Animation # Determine filenames of graphics to be used tr_type = foe[0].trainer_type trainer_bar_graphic = sprintf("vsBar_%s", tr_type.to_s) rescue nil @@ -334,3 +329,45 @@ SpecialBattleIntroAnimations.register("vs_animation", 50, # Priority 50 viewport.color = Color.new(0, 0, 0, 255) } ) + +#=============================================================================== +# Play the "RocketGrunt" transition animation for any trainer battle involving a +# Team Rocket Grunt. Is lower priority than the Vs. animation above. +#=============================================================================== +SpecialBattleIntroAnimations.register("rocket_grunt_animation", 40, # Priority 40 + proc { |battle_type, foe, location| # Condition + next false unless [1, 3].include?(battle_type) # Only if a trainer battle + trainer_types = [:TEAMROCKET_M, :TEAMROCKET_F] + next foe.any? { |f| trainer_types.include?(f.trainer_type) } + }, + proc { |viewport, battle_type, foe, location| # Animation + anim = "RocketGrunt" + # Initial screen flashing + c = (location == 2 || PBDayNight.isNight?) ? 0 : 255 # Dark=black, light=white + viewport.color = Color.new(c, c, c) # Fade to black/white a few times + half_flash_time = 0.2 # seconds + 2.times do # 2 flashes + timer = 0.0 + loop do + if timer < half_flash_time + viewport.color.alpha = 255 * timer / half_flash_time + else + viewport.color.alpha = 255 * (2 - (timer / half_flash_time)) + end + timer += Graphics.delta_s + Graphics.update + pbUpdateSceneMap + break if timer >= half_flash_time * 2 + end + end + # Take screenshot of game, for use in some animations + $game_temp.background_bitmap&.dispose + $game_temp.background_bitmap = Graphics.snap_to_bitmap + # Play main animation + Graphics.freeze + viewport.color = Color.new(0, 0, 0, 255) # Ensure screen is black + Graphics.transition(25, "Graphics/Transitions/" + anim) + # Slight pause after animation before starting up the battle scene + pbWait(Graphics.frame_rate / 10) + } +)